OpenWrt – Blame information for rev 4
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
4 | office | 1 | From: Christian Lamparter <chunkeey@googlemail.com> |
2 | Subject: BUS: add MSM_BUS |
||
3 | --- a/drivers/bus/Makefile |
||
4 | +++ b/drivers/bus/Makefile |
||
5 | @@ -11,6 +11,7 @@ obj-$(CONFIG_BRCMSTB_GISB_ARB) += brcmst |
||
6 | obj-$(CONFIG_IMX_WEIM) += imx-weim.o |
||
7 | obj-$(CONFIG_MIPS_CDMM) += mips_cdmm.o |
||
8 | obj-$(CONFIG_MVEBU_MBUS) += mvebu-mbus.o |
||
9 | +obj-$(CONFIG_BUS_TOPOLOGY_ADHOC)+= msm_bus/ |
||
10 | |||
11 | # Interconnect bus driver for OMAP SoCs. |
||
12 | obj-$(CONFIG_OMAP_INTERCONNECT) += omap_l3_smx.o omap_l3_noc.o |
||
13 | --- a/drivers/bus/Kconfig |
||
14 | +++ b/drivers/bus/Kconfig |
||
15 | @@ -93,6 +93,8 @@ config MVEBU_MBUS |
||
16 | Driver needed for the MBus configuration on Marvell EBU SoCs |
||
17 | (Kirkwood, Dove, Orion5x, MV78XX0 and Armada 370/XP). |
||
18 | |||
19 | +source "drivers/bus/msm_bus/Kconfig" |
||
20 | + |
||
21 | config OMAP_INTERCONNECT |
||
22 | tristate "OMAP INTERCONNECT DRIVER" |
||
23 | depends on ARCH_OMAP2PLUS |
||
24 | --- /dev/null |
||
25 | +++ b/include/dt-bindings/msm/msm-bus-ids.h |
||
26 | @@ -0,0 +1,869 @@ |
||
27 | +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. |
||
28 | + * |
||
29 | + * This program is free software; you can redistribute it and/or modify |
||
30 | + * it under the terms of the GNU General Public License version 2 and |
||
31 | + * only version 2 as published by the Free Software Foundation. |
||
32 | + * |
||
33 | + * This program is distributed in the hope that it will be useful, |
||
34 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
35 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
36 | + * GNU General Public License for more details. |
||
37 | + */ |
||
38 | + |
||
39 | +#ifndef __MSM_BUS_IDS_H |
||
40 | +#define __MSM_BUS_IDS_H |
||
41 | + |
||
42 | +/* Topology related enums */ |
||
43 | +#define MSM_BUS_FAB_DEFAULT 0 |
||
44 | +#define MSM_BUS_FAB_APPSS 0 |
||
45 | +#define MSM_BUS_FAB_SYSTEM 1024 |
||
46 | +#define MSM_BUS_FAB_MMSS 2048 |
||
47 | +#define MSM_BUS_FAB_SYSTEM_FPB 3072 |
||
48 | +#define MSM_BUS_FAB_CPSS_FPB 4096 |
||
49 | + |
||
50 | +#define MSM_BUS_FAB_BIMC 0 |
||
51 | +#define MSM_BUS_FAB_SYS_NOC 1024 |
||
52 | +#define MSM_BUS_FAB_MMSS_NOC 2048 |
||
53 | +#define MSM_BUS_FAB_OCMEM_NOC 3072 |
||
54 | +#define MSM_BUS_FAB_PERIPH_NOC 4096 |
||
55 | +#define MSM_BUS_FAB_CONFIG_NOC 5120 |
||
56 | +#define MSM_BUS_FAB_OCMEM_VNOC 6144 |
||
57 | +#define MSM_BUS_FAB_MMSS_AHB 2049 |
||
58 | +#define MSM_BUS_FAB_A0_NOC 6145 |
||
59 | +#define MSM_BUS_FAB_A1_NOC 6146 |
||
60 | +#define MSM_BUS_FAB_A2_NOC 6147 |
||
61 | + |
||
62 | +#define MSM_BUS_MASTER_FIRST 1 |
||
63 | +#define MSM_BUS_MASTER_AMPSS_M0 1 |
||
64 | +#define MSM_BUS_MASTER_AMPSS_M1 2 |
||
65 | +#define MSM_BUS_APPSS_MASTER_FAB_MMSS 3 |
||
66 | +#define MSM_BUS_APPSS_MASTER_FAB_SYSTEM 4 |
||
67 | +#define MSM_BUS_SYSTEM_MASTER_FAB_APPSS 5 |
||
68 | +#define MSM_BUS_MASTER_SPS 6 |
||
69 | +#define MSM_BUS_MASTER_ADM_PORT0 7 |
||
70 | +#define MSM_BUS_MASTER_ADM_PORT1 8 |
||
71 | +#define MSM_BUS_SYSTEM_MASTER_ADM1_PORT0 9 |
||
72 | +#define MSM_BUS_MASTER_ADM1_PORT1 10 |
||
73 | +#define MSM_BUS_MASTER_LPASS_PROC 11 |
||
74 | +#define MSM_BUS_MASTER_MSS_PROCI 12 |
||
75 | +#define MSM_BUS_MASTER_MSS_PROCD 13 |
||
76 | +#define MSM_BUS_MASTER_MSS_MDM_PORT0 14 |
||
77 | +#define MSM_BUS_MASTER_LPASS 15 |
||
78 | +#define MSM_BUS_SYSTEM_MASTER_CPSS_FPB 16 |
||
79 | +#define MSM_BUS_SYSTEM_MASTER_SYSTEM_FPB 17 |
||
80 | +#define MSM_BUS_SYSTEM_MASTER_MMSS_FPB 18 |
||
81 | +#define MSM_BUS_MASTER_ADM1_CI 19 |
||
82 | +#define MSM_BUS_MASTER_ADM0_CI 20 |
||
83 | +#define MSM_BUS_MASTER_MSS_MDM_PORT1 21 |
||
84 | +#define MSM_BUS_MASTER_MDP_PORT0 22 |
||
85 | +#define MSM_BUS_MASTER_MDP_PORT1 23 |
||
86 | +#define MSM_BUS_MMSS_MASTER_ADM1_PORT0 24 |
||
87 | +#define MSM_BUS_MASTER_ROTATOR 25 |
||
88 | +#define MSM_BUS_MASTER_GRAPHICS_3D 26 |
||
89 | +#define MSM_BUS_MASTER_JPEG_DEC 27 |
||
90 | +#define MSM_BUS_MASTER_GRAPHICS_2D_CORE0 28 |
||
91 | +#define MSM_BUS_MASTER_VFE 29 |
||
92 | +#define MSM_BUS_MASTER_VPE 30 |
||
93 | +#define MSM_BUS_MASTER_JPEG_ENC 31 |
||
94 | +#define MSM_BUS_MASTER_GRAPHICS_2D_CORE1 32 |
||
95 | +#define MSM_BUS_MMSS_MASTER_APPS_FAB 33 |
||
96 | +#define MSM_BUS_MASTER_HD_CODEC_PORT0 34 |
||
97 | +#define MSM_BUS_MASTER_HD_CODEC_PORT1 35 |
||
98 | +#define MSM_BUS_MASTER_SPDM 36 |
||
99 | +#define MSM_BUS_MASTER_RPM 37 |
||
100 | +#define MSM_BUS_MASTER_MSS 38 |
||
101 | +#define MSM_BUS_MASTER_RIVA 39 |
||
102 | +#define MSM_BUS_MASTER_SNOC_VMEM 40 |
||
103 | +#define MSM_BUS_MASTER_MSS_SW_PROC 41 |
||
104 | +#define MSM_BUS_MASTER_MSS_FW_PROC 42 |
||
105 | +#define MSM_BUS_MASTER_HMSS 43 |
||
106 | +#define MSM_BUS_MASTER_GSS_NAV 44 |
||
107 | +#define MSM_BUS_MASTER_PCIE 45 |
||
108 | +#define MSM_BUS_MASTER_SATA 46 |
||
109 | +#define MSM_BUS_MASTER_CRYPTO 47 |
||
110 | +#define MSM_BUS_MASTER_VIDEO_CAP 48 |
||
111 | +#define MSM_BUS_MASTER_GRAPHICS_3D_PORT1 49 |
||
112 | +#define MSM_BUS_MASTER_VIDEO_ENC 50 |
||
113 | +#define MSM_BUS_MASTER_VIDEO_DEC 51 |
||
114 | +#define MSM_BUS_MASTER_LPASS_AHB 52 |
||
115 | +#define MSM_BUS_MASTER_QDSS_BAM 53 |
||
116 | +#define MSM_BUS_MASTER_SNOC_CFG 54 |
||
117 | +#define MSM_BUS_MASTER_CRYPTO_CORE0 55 |
||
118 | +#define MSM_BUS_MASTER_CRYPTO_CORE1 56 |
||
119 | +#define MSM_BUS_MASTER_MSS_NAV 57 |
||
120 | +#define MSM_BUS_MASTER_OCMEM_DMA 58 |
||
121 | +#define MSM_BUS_MASTER_WCSS 59 |
||
122 | +#define MSM_BUS_MASTER_QDSS_ETR 60 |
||
123 | +#define MSM_BUS_MASTER_USB3 61 |
||
124 | +#define MSM_BUS_MASTER_JPEG 62 |
||
125 | +#define MSM_BUS_MASTER_VIDEO_P0 63 |
||
126 | +#define MSM_BUS_MASTER_VIDEO_P1 64 |
||
127 | +#define MSM_BUS_MASTER_MSS_PROC 65 |
||
128 | +#define MSM_BUS_MASTER_JPEG_OCMEM 66 |
||
129 | +#define MSM_BUS_MASTER_MDP_OCMEM 67 |
||
130 | +#define MSM_BUS_MASTER_VIDEO_P0_OCMEM 68 |
||
131 | +#define MSM_BUS_MASTER_VIDEO_P1_OCMEM 69 |
||
132 | +#define MSM_BUS_MASTER_VFE_OCMEM 70 |
||
133 | +#define MSM_BUS_MASTER_CNOC_ONOC_CFG 71 |
||
134 | +#define MSM_BUS_MASTER_RPM_INST 72 |
||
135 | +#define MSM_BUS_MASTER_RPM_DATA 73 |
||
136 | +#define MSM_BUS_MASTER_RPM_SYS 74 |
||
137 | +#define MSM_BUS_MASTER_DEHR 75 |
||
138 | +#define MSM_BUS_MASTER_QDSS_DAP 76 |
||
139 | +#define MSM_BUS_MASTER_TIC 77 |
||
140 | +#define MSM_BUS_MASTER_SDCC_1 78 |
||
141 | +#define MSM_BUS_MASTER_SDCC_3 79 |
||
142 | +#define MSM_BUS_MASTER_SDCC_4 80 |
||
143 | +#define MSM_BUS_MASTER_SDCC_2 81 |
||
144 | +#define MSM_BUS_MASTER_TSIF 82 |
||
145 | +#define MSM_BUS_MASTER_BAM_DMA 83 |
||
146 | +#define MSM_BUS_MASTER_BLSP_2 84 |
||
147 | +#define MSM_BUS_MASTER_USB_HSIC 85 |
||
148 | +#define MSM_BUS_MASTER_BLSP_1 86 |
||
149 | +#define MSM_BUS_MASTER_USB_HS 87 |
||
150 | +#define MSM_BUS_MASTER_PNOC_CFG 88 |
||
151 | +#define MSM_BUS_MASTER_V_OCMEM_GFX3D 89 |
||
152 | +#define MSM_BUS_MASTER_IPA 90 |
||
153 | +#define MSM_BUS_MASTER_QPIC 91 |
||
154 | +#define MSM_BUS_MASTER_MDPE 92 |
||
155 | +#define MSM_BUS_MASTER_USB_HS2 93 |
||
156 | +#define MSM_BUS_MASTER_VPU 94 |
||
157 | +#define MSM_BUS_MASTER_UFS 95 |
||
158 | +#define MSM_BUS_MASTER_BCAST 96 |
||
159 | +#define MSM_BUS_MASTER_CRYPTO_CORE2 97 |
||
160 | +#define MSM_BUS_MASTER_EMAC 98 |
||
161 | +#define MSM_BUS_MASTER_VPU_1 99 |
||
162 | +#define MSM_BUS_MASTER_PCIE_1 100 |
||
163 | +#define MSM_BUS_MASTER_USB3_1 101 |
||
164 | +#define MSM_BUS_MASTER_CNOC_MNOC_MMSS_CFG 102 |
||
165 | +#define MSM_BUS_MASTER_CNOC_MNOC_CFG 103 |
||
166 | +#define MSM_BUS_MASTER_TCU_0 104 |
||
167 | +#define MSM_BUS_MASTER_TCU_1 105 |
||
168 | +#define MSM_BUS_MASTER_CPP 106 |
||
169 | +#define MSM_BUS_MASTER_AUDIO 107 |
||
170 | +#define MSM_BUS_MASTER_PCIE_2 108 |
||
171 | +#define MSM_BUS_MASTER_BLSP_BAM 109 |
||
172 | +#define MSM_BUS_MASTER_USB2_BAM 110 |
||
173 | +#define MSM_BUS_MASTER_ADDS_DMA0 111 |
||
174 | +#define MSM_BUS_MASTER_ADDS_DMA1 112 |
||
175 | +#define MSM_BUS_MASTER_ADDS_DMA2 113 |
||
176 | +#define MSM_BUS_MASTER_ADDS_DMA3 114 |
||
177 | +#define MSM_BUS_MASTER_QPIC_BAM 115 |
||
178 | +#define MSM_BUS_MASTER_SDCC_BAM 116 |
||
179 | +#define MSM_BUS_MASTER_DDRC_SNOC 117 |
||
180 | +#define MSM_BUS_MASTER_WSS_0 118 |
||
181 | +#define MSM_BUS_MASTER_WSS_1 119 |
||
182 | +#define MSM_BUS_MASTER_ESS 120 |
||
183 | +#define MSM_BUS_MASTER_QDSS_BAMNDP 121 |
||
184 | +#define MSM_BUS_MASTER_QDSS_SNOC_CFG 122 |
||
185 | +#define MSM_BUS_MASTER_LAST 130 |
||
186 | + |
||
187 | +#define MSM_BUS_SYSTEM_FPB_MASTER_SYSTEM MSM_BUS_SYSTEM_MASTER_SYSTEM_FPB |
||
188 | +#define MSM_BUS_CPSS_FPB_MASTER_SYSTEM MSM_BUS_SYSTEM_MASTER_CPSS_FPB |
||
189 | + |
||
190 | +#define MSM_BUS_SNOC_MM_INT_0 10000 |
||
191 | +#define MSM_BUS_SNOC_MM_INT_1 10001 |
||
192 | +#define MSM_BUS_SNOC_MM_INT_2 10002 |
||
193 | +#define MSM_BUS_SNOC_MM_INT_BIMC 10003 |
||
194 | +#define MSM_BUS_SNOC_INT_0 10004 |
||
195 | +#define MSM_BUS_SNOC_INT_1 10005 |
||
196 | +#define MSM_BUS_SNOC_INT_BIMC 10006 |
||
197 | +#define MSM_BUS_SNOC_BIMC_0_MAS 10007 |
||
198 | +#define MSM_BUS_SNOC_BIMC_1_MAS 10008 |
||
199 | +#define MSM_BUS_SNOC_QDSS_INT 10009 |
||
200 | +#define MSM_BUS_PNOC_SNOC_MAS 10010 |
||
201 | +#define MSM_BUS_PNOC_SNOC_SLV 10011 |
||
202 | +#define MSM_BUS_PNOC_INT_0 10012 |
||
203 | +#define MSM_BUS_PNOC_INT_1 10013 |
||
204 | +#define MSM_BUS_PNOC_M_0 10014 |
||
205 | +#define MSM_BUS_PNOC_M_1 10015 |
||
206 | +#define MSM_BUS_BIMC_SNOC_MAS 10016 |
||
207 | +#define MSM_BUS_BIMC_SNOC_SLV 10017 |
||
208 | +#define MSM_BUS_PNOC_SLV_0 10018 |
||
209 | +#define MSM_BUS_PNOC_SLV_1 10019 |
||
210 | +#define MSM_BUS_PNOC_SLV_2 10020 |
||
211 | +#define MSM_BUS_PNOC_SLV_3 10021 |
||
212 | +#define MSM_BUS_PNOC_SLV_4 10022 |
||
213 | +#define MSM_BUS_PNOC_SLV_8 10023 |
||
214 | +#define MSM_BUS_PNOC_SLV_9 10024 |
||
215 | +#define MSM_BUS_SNOC_BIMC_0_SLV 10025 |
||
216 | +#define MSM_BUS_SNOC_BIMC_1_SLV 10026 |
||
217 | +#define MSM_BUS_MNOC_BIMC_MAS 10027 |
||
218 | +#define MSM_BUS_MNOC_BIMC_SLV 10028 |
||
219 | +#define MSM_BUS_BIMC_MNOC_MAS 10029 |
||
220 | +#define MSM_BUS_BIMC_MNOC_SLV 10030 |
||
221 | +#define MSM_BUS_SNOC_BIMC_MAS 10031 |
||
222 | +#define MSM_BUS_SNOC_BIMC_SLV 10032 |
||
223 | +#define MSM_BUS_CNOC_SNOC_MAS 10033 |
||
224 | +#define MSM_BUS_CNOC_SNOC_SLV 10034 |
||
225 | +#define MSM_BUS_SNOC_CNOC_MAS 10035 |
||
226 | +#define MSM_BUS_SNOC_CNOC_SLV 10036 |
||
227 | +#define MSM_BUS_OVNOC_SNOC_MAS 10037 |
||
228 | +#define MSM_BUS_OVNOC_SNOC_SLV 10038 |
||
229 | +#define MSM_BUS_SNOC_OVNOC_MAS 10039 |
||
230 | +#define MSM_BUS_SNOC_OVNOC_SLV 10040 |
||
231 | +#define MSM_BUS_SNOC_PNOC_MAS 10041 |
||
232 | +#define MSM_BUS_SNOC_PNOC_SLV 10042 |
||
233 | +#define MSM_BUS_BIMC_INT_APPS_EBI 10043 |
||
234 | +#define MSM_BUS_BIMC_INT_APPS_SNOC 10044 |
||
235 | +#define MSM_BUS_SNOC_BIMC_2_MAS 10045 |
||
236 | +#define MSM_BUS_SNOC_BIMC_2_SLV 10046 |
||
237 | +#define MSM_BUS_PNOC_SLV_5 10047 |
||
238 | +#define MSM_BUS_PNOC_SLV_6 10048 |
||
239 | +#define MSM_BUS_PNOC_INT_2 10049 |
||
240 | +#define MSM_BUS_PNOC_INT_3 10050 |
||
241 | +#define MSM_BUS_PNOC_INT_4 10051 |
||
242 | +#define MSM_BUS_PNOC_INT_5 10052 |
||
243 | +#define MSM_BUS_PNOC_INT_6 10053 |
||
244 | +#define MSM_BUS_PNOC_INT_7 10054 |
||
245 | +#define MSM_BUS_BIMC_SNOC_1_MAS 10055 |
||
246 | +#define MSM_BUS_BIMC_SNOC_1_SLV 10056 |
||
247 | +#define MSM_BUS_PNOC_A1NOC_MAS 10057 |
||
248 | +#define MSM_BUS_PNOC_A1NOC_SLV 10058 |
||
249 | +#define MSM_BUS_CNOC_A1NOC_MAS 10059 |
||
250 | +#define MSM_BUS_A0NOC_SNOC_MAS 10060 |
||
251 | +#define MSM_BUS_A0NOC_SNOC_SLV 10061 |
||
252 | +#define MSM_BUS_A1NOC_SNOC_SLV 10062 |
||
253 | +#define MSM_BUS_A1NOC_SNOC_MAS 10063 |
||
254 | +#define MSM_BUS_A2NOC_SNOC_MAS 10064 |
||
255 | +#define MSM_BUS_A2NOC_SNOC_SLV 10065 |
||
256 | +#define MSM_BUS_PNOC_SLV_7 10066 |
||
257 | +#define MSM_BUS_INT_LAST 10067 |
||
258 | + |
||
259 | +#define MSM_BUS_SLAVE_FIRST 512 |
||
260 | +#define MSM_BUS_SLAVE_EBI_CH0 512 |
||
261 | +#define MSM_BUS_SLAVE_EBI_CH1 513 |
||
262 | +#define MSM_BUS_SLAVE_AMPSS_L2 514 |
||
263 | +#define MSM_BUS_APPSS_SLAVE_FAB_MMSS 515 |
||
264 | +#define MSM_BUS_APPSS_SLAVE_FAB_SYSTEM 516 |
||
265 | +#define MSM_BUS_SYSTEM_SLAVE_FAB_APPS 517 |
||
266 | +#define MSM_BUS_SLAVE_SPS 518 |
||
267 | +#define MSM_BUS_SLAVE_SYSTEM_IMEM 519 |
||
268 | +#define MSM_BUS_SLAVE_AMPSS 520 |
||
269 | +#define MSM_BUS_SLAVE_MSS 521 |
||
270 | +#define MSM_BUS_SLAVE_LPASS 522 |
||
271 | +#define MSM_BUS_SYSTEM_SLAVE_CPSS_FPB 523 |
||
272 | +#define MSM_BUS_SYSTEM_SLAVE_SYSTEM_FPB 524 |
||
273 | +#define MSM_BUS_SYSTEM_SLAVE_MMSS_FPB 525 |
||
274 | +#define MSM_BUS_SLAVE_CORESIGHT 526 |
||
275 | +#define MSM_BUS_SLAVE_RIVA 527 |
||
276 | +#define MSM_BUS_SLAVE_SMI 528 |
||
277 | +#define MSM_BUS_MMSS_SLAVE_FAB_APPS 529 |
||
278 | +#define MSM_BUS_MMSS_SLAVE_FAB_APPS_1 530 |
||
279 | +#define MSM_BUS_SLAVE_MM_IMEM 531 |
||
280 | +#define MSM_BUS_SLAVE_CRYPTO 532 |
||
281 | +#define MSM_BUS_SLAVE_SPDM 533 |
||
282 | +#define MSM_BUS_SLAVE_RPM 534 |
||
283 | +#define MSM_BUS_SLAVE_RPM_MSG_RAM 535 |
||
284 | +#define MSM_BUS_SLAVE_MPM 536 |
||
285 | +#define MSM_BUS_SLAVE_PMIC1_SSBI1_A 537 |
||
286 | +#define MSM_BUS_SLAVE_PMIC1_SSBI1_B 538 |
||
287 | +#define MSM_BUS_SLAVE_PMIC1_SSBI1_C 539 |
||
288 | +#define MSM_BUS_SLAVE_PMIC2_SSBI2_A 540 |
||
289 | +#define MSM_BUS_SLAVE_PMIC2_SSBI2_B 541 |
||
290 | +#define MSM_BUS_SLAVE_GSBI1_UART 542 |
||
291 | +#define MSM_BUS_SLAVE_GSBI2_UART 543 |
||
292 | +#define MSM_BUS_SLAVE_GSBI3_UART 544 |
||
293 | +#define MSM_BUS_SLAVE_GSBI4_UART 545 |
||
294 | +#define MSM_BUS_SLAVE_GSBI5_UART 546 |
||
295 | +#define MSM_BUS_SLAVE_GSBI6_UART 547 |
||
296 | +#define MSM_BUS_SLAVE_GSBI7_UART 548 |
||
297 | +#define MSM_BUS_SLAVE_GSBI8_UART 549 |
||
298 | +#define MSM_BUS_SLAVE_GSBI9_UART 550 |
||
299 | +#define MSM_BUS_SLAVE_GSBI10_UART 551 |
||
300 | +#define MSM_BUS_SLAVE_GSBI11_UART 552 |
||
301 | +#define MSM_BUS_SLAVE_GSBI12_UART 553 |
||
302 | +#define MSM_BUS_SLAVE_GSBI1_QUP 554 |
||
303 | +#define MSM_BUS_SLAVE_GSBI2_QUP 555 |
||
304 | +#define MSM_BUS_SLAVE_GSBI3_QUP 556 |
||
305 | +#define MSM_BUS_SLAVE_GSBI4_QUP 557 |
||
306 | +#define MSM_BUS_SLAVE_GSBI5_QUP 558 |
||
307 | +#define MSM_BUS_SLAVE_GSBI6_QUP 559 |
||
308 | +#define MSM_BUS_SLAVE_GSBI7_QUP 560 |
||
309 | +#define MSM_BUS_SLAVE_GSBI8_QUP 561 |
||
310 | +#define MSM_BUS_SLAVE_GSBI9_QUP 562 |
||
311 | +#define MSM_BUS_SLAVE_GSBI10_QUP 563 |
||
312 | +#define MSM_BUS_SLAVE_GSBI11_QUP 564 |
||
313 | +#define MSM_BUS_SLAVE_GSBI12_QUP 565 |
||
314 | +#define MSM_BUS_SLAVE_EBI2_NAND 566 |
||
315 | +#define MSM_BUS_SLAVE_EBI2_CS0 567 |
||
316 | +#define MSM_BUS_SLAVE_EBI2_CS1 568 |
||
317 | +#define MSM_BUS_SLAVE_EBI2_CS2 569 |
||
318 | +#define MSM_BUS_SLAVE_EBI2_CS3 570 |
||
319 | +#define MSM_BUS_SLAVE_EBI2_CS4 571 |
||
320 | +#define MSM_BUS_SLAVE_EBI2_CS5 572 |
||
321 | +#define MSM_BUS_SLAVE_USB_FS1 573 |
||
322 | +#define MSM_BUS_SLAVE_USB_FS2 574 |
||
323 | +#define MSM_BUS_SLAVE_TSIF 575 |
||
324 | +#define MSM_BUS_SLAVE_MSM_TSSC 576 |
||
325 | +#define MSM_BUS_SLAVE_MSM_PDM 577 |
||
326 | +#define MSM_BUS_SLAVE_MSM_DIMEM 578 |
||
327 | +#define MSM_BUS_SLAVE_MSM_TCSR 579 |
||
328 | +#define MSM_BUS_SLAVE_MSM_PRNG 580 |
||
329 | +#define MSM_BUS_SLAVE_GSS 581 |
||
330 | +#define MSM_BUS_SLAVE_SATA 582 |
||
331 | +#define MSM_BUS_SLAVE_USB3 583 |
||
332 | +#define MSM_BUS_SLAVE_WCSS 584 |
||
333 | +#define MSM_BUS_SLAVE_OCIMEM 585 |
||
334 | +#define MSM_BUS_SLAVE_SNOC_OCMEM 586 |
||
335 | +#define MSM_BUS_SLAVE_SERVICE_SNOC 587 |
||
336 | +#define MSM_BUS_SLAVE_QDSS_STM 588 |
||
337 | +#define MSM_BUS_SLAVE_CAMERA_CFG 589 |
||
338 | +#define MSM_BUS_SLAVE_DISPLAY_CFG 590 |
||
339 | +#define MSM_BUS_SLAVE_OCMEM_CFG 591 |
||
340 | +#define MSM_BUS_SLAVE_CPR_CFG 592 |
||
341 | +#define MSM_BUS_SLAVE_CPR_XPU_CFG 593 |
||
342 | +#define MSM_BUS_SLAVE_MISC_CFG 594 |
||
343 | +#define MSM_BUS_SLAVE_MISC_XPU_CFG 595 |
||
344 | +#define MSM_BUS_SLAVE_VENUS_CFG 596 |
||
345 | +#define MSM_BUS_SLAVE_MISC_VENUS_CFG 597 |
||
346 | +#define MSM_BUS_SLAVE_GRAPHICS_3D_CFG 598 |
||
347 | +#define MSM_BUS_SLAVE_MMSS_CLK_CFG 599 |
||
348 | +#define MSM_BUS_SLAVE_MMSS_CLK_XPU_CFG 600 |
||
349 | +#define MSM_BUS_SLAVE_MNOC_MPU_CFG 601 |
||
350 | +#define MSM_BUS_SLAVE_ONOC_MPU_CFG 602 |
||
351 | +#define MSM_BUS_SLAVE_SERVICE_MNOC 603 |
||
352 | +#define MSM_BUS_SLAVE_OCMEM 604 |
||
353 | +#define MSM_BUS_SLAVE_SERVICE_ONOC 605 |
||
354 | +#define MSM_BUS_SLAVE_SDCC_1 606 |
||
355 | +#define MSM_BUS_SLAVE_SDCC_3 607 |
||
356 | +#define MSM_BUS_SLAVE_SDCC_2 608 |
||
357 | +#define MSM_BUS_SLAVE_SDCC_4 609 |
||
358 | +#define MSM_BUS_SLAVE_BAM_DMA 610 |
||
359 | +#define MSM_BUS_SLAVE_BLSP_2 611 |
||
360 | +#define MSM_BUS_SLAVE_USB_HSIC 612 |
||
361 | +#define MSM_BUS_SLAVE_BLSP_1 613 |
||
362 | +#define MSM_BUS_SLAVE_USB_HS 614 |
||
363 | +#define MSM_BUS_SLAVE_PDM 615 |
||
364 | +#define MSM_BUS_SLAVE_PERIPH_APU_CFG 616 |
||
365 | +#define MSM_BUS_SLAVE_PNOC_MPU_CFG 617 |
||
366 | +#define MSM_BUS_SLAVE_PRNG 618 |
||
367 | +#define MSM_BUS_SLAVE_SERVICE_PNOC 619 |
||
368 | +#define MSM_BUS_SLAVE_CLK_CTL 620 |
||
369 | +#define MSM_BUS_SLAVE_CNOC_MSS 621 |
||
370 | +#define MSM_BUS_SLAVE_SECURITY 622 |
||
371 | +#define MSM_BUS_SLAVE_TCSR 623 |
||
372 | +#define MSM_BUS_SLAVE_TLMM 624 |
||
373 | +#define MSM_BUS_SLAVE_CRYPTO_0_CFG 625 |
||
374 | +#define MSM_BUS_SLAVE_CRYPTO_1_CFG 626 |
||
375 | +#define MSM_BUS_SLAVE_IMEM_CFG 627 |
||
376 | +#define MSM_BUS_SLAVE_MESSAGE_RAM 628 |
||
377 | +#define MSM_BUS_SLAVE_BIMC_CFG 629 |
||
378 | +#define MSM_BUS_SLAVE_BOOT_ROM 630 |
||
379 | +#define MSM_BUS_SLAVE_CNOC_MNOC_MMSS_CFG 631 |
||
380 | +#define MSM_BUS_SLAVE_PMIC_ARB 632 |
||
381 | +#define MSM_BUS_SLAVE_SPDM_WRAPPER 633 |
||
382 | +#define MSM_BUS_SLAVE_DEHR_CFG 634 |
||
383 | +#define MSM_BUS_SLAVE_QDSS_CFG 635 |
||
384 | +#define MSM_BUS_SLAVE_RBCPR_CFG 636 |
||
385 | +#define MSM_BUS_SLAVE_RBCPR_QDSS_APU_CFG 637 |
||
386 | +#define MSM_BUS_SLAVE_SNOC_MPU_CFG 638 |
||
387 | +#define MSM_BUS_SLAVE_CNOC_ONOC_CFG 639 |
||
388 | +#define MSM_BUS_SLAVE_CNOC_MNOC_CFG 640 |
||
389 | +#define MSM_BUS_SLAVE_PNOC_CFG 641 |
||
390 | +#define MSM_BUS_SLAVE_SNOC_CFG 642 |
||
391 | +#define MSM_BUS_SLAVE_EBI1_DLL_CFG 643 |
||
392 | +#define MSM_BUS_SLAVE_PHY_APU_CFG 644 |
||
393 | +#define MSM_BUS_SLAVE_EBI1_PHY_CFG 645 |
||
394 | +#define MSM_BUS_SLAVE_SERVICE_CNOC 646 |
||
395 | +#define MSM_BUS_SLAVE_IPS_CFG 647 |
||
396 | +#define MSM_BUS_SLAVE_QPIC 648 |
||
397 | +#define MSM_BUS_SLAVE_DSI_CFG 649 |
||
398 | +#define MSM_BUS_SLAVE_UFS_CFG 650 |
||
399 | +#define MSM_BUS_SLAVE_RBCPR_CX_CFG 651 |
||
400 | +#define MSM_BUS_SLAVE_RBCPR_MX_CFG 652 |
||
401 | +#define MSM_BUS_SLAVE_PCIE_CFG 653 |
||
402 | +#define MSM_BUS_SLAVE_USB_PHYS_CFG 654 |
||
403 | +#define MSM_BUS_SLAVE_VIDEO_CAP_CFG 655 |
||
404 | +#define MSM_BUS_SLAVE_AVSYNC_CFG 656 |
||
405 | +#define MSM_BUS_SLAVE_CRYPTO_2_CFG 657 |
||
406 | +#define MSM_BUS_SLAVE_VPU_CFG 658 |
||
407 | +#define MSM_BUS_SLAVE_BCAST_CFG 659 |
||
408 | +#define MSM_BUS_SLAVE_KLM_CFG 660 |
||
409 | +#define MSM_BUS_SLAVE_GENI_IR_CFG 661 |
||
410 | +#define MSM_BUS_SLAVE_OCMEM_GFX 662 |
||
411 | +#define MSM_BUS_SLAVE_CATS_128 663 |
||
412 | +#define MSM_BUS_SLAVE_OCMEM_64 664 |
||
413 | +#define MSM_BUS_SLAVE_PCIE_0 665 |
||
414 | +#define MSM_BUS_SLAVE_PCIE_1 666 |
||
415 | +#define MSM_BUS_SLAVE_PCIE_0_CFG 667 |
||
416 | +#define MSM_BUS_SLAVE_PCIE_1_CFG 668 |
||
417 | +#define MSM_BUS_SLAVE_SRVC_MNOC 669 |
||
418 | +#define MSM_BUS_SLAVE_USB_HS2 670 |
||
419 | +#define MSM_BUS_SLAVE_AUDIO 671 |
||
420 | +#define MSM_BUS_SLAVE_TCU 672 |
||
421 | +#define MSM_BUS_SLAVE_APPSS 673 |
||
422 | +#define MSM_BUS_SLAVE_PCIE_PARF 674 |
||
423 | +#define MSM_BUS_SLAVE_USB3_PHY_CFG 675 |
||
424 | +#define MSM_BUS_SLAVE_IPA_CFG 676 |
||
425 | +#define MSM_BUS_SLAVE_A0NOC_SNOC 677 |
||
426 | +#define MSM_BUS_SLAVE_A1NOC_SNOC 678 |
||
427 | +#define MSM_BUS_SLAVE_A2NOC_SNOC 679 |
||
428 | +#define MSM_BUS_SLAVE_HMSS_L3 680 |
||
429 | +#define MSM_BUS_SLAVE_PIMEM_CFG 681 |
||
430 | +#define MSM_BUS_SLAVE_DCC_CFG 682 |
||
431 | +#define MSM_BUS_SLAVE_QDSS_RBCPR_APU_CFG 683 |
||
432 | +#define MSM_BUS_SLAVE_PCIE_2_CFG 684 |
||
433 | +#define MSM_BUS_SLAVE_PCIE20_AHB2PHY 685 |
||
434 | +#define MSM_BUS_SLAVE_A0NOC_CFG 686 |
||
435 | +#define MSM_BUS_SLAVE_A1NOC_CFG 687 |
||
436 | +#define MSM_BUS_SLAVE_A2NOC_CFG 688 |
||
437 | +#define MSM_BUS_SLAVE_A1NOC_MPU_CFG 689 |
||
438 | +#define MSM_BUS_SLAVE_A2NOC_MPU_CFG 690 |
||
439 | +#define MSM_BUS_SLAVE_A0NOC_SMMU_CFG 691 |
||
440 | +#define MSM_BUS_SLAVE_A1NOC_SMMU_CFG 692 |
||
441 | +#define MSM_BUS_SLAVE_A2NOC_SMMU_CFG 693 |
||
442 | +#define MSM_BUS_SLAVE_LPASS_SMMU_CFG 694 |
||
443 | +#define MSM_BUS_SLAVE_MMAGIC_CFG 695 |
||
444 | +#define MSM_BUS_SLAVE_VENUS_THROTTLE_CFG 696 |
||
445 | +#define MSM_BUS_SLAVE_SSC_CFG 697 |
||
446 | +#define MSM_BUS_SLAVE_DSA_CFG 698 |
||
447 | +#define MSM_BUS_SLAVE_DSA_MPU_CFG 699 |
||
448 | +#define MSM_BUS_SLAVE_DISPLAY_THROTTLE_CFG 700 |
||
449 | +#define MSM_BUS_SLAVE_SMMU_CPP_CFG 701 |
||
450 | +#define MSM_BUS_SLAVE_SMMU_JPEG_CFG 702 |
||
451 | +#define MSM_BUS_SLAVE_SMMU_MDP_CFG 703 |
||
452 | +#define MSM_BUS_SLAVE_SMMU_ROTATOR_CFG 704 |
||
453 | +#define MSM_BUS_SLAVE_SMMU_VENUS_CFG 705 |
||
454 | +#define MSM_BUS_SLAVE_SMMU_VFE_CFG 706 |
||
455 | +#define MSM_BUS_SLAVE_A0NOC_MPU_CFG 707 |
||
456 | +#define MSM_BUS_SLAVE_VMEM_CFG 708 |
||
457 | +#define MSM_BUS_SLAVE_CAMERA_THROTTLE_CFG 700 |
||
458 | +#define MSM_BUS_SLAVE_VMEM 709 |
||
459 | +#define MSM_BUS_SLAVE_AHB2PHY 710 |
||
460 | +#define MSM_BUS_SLAVE_PIMEM 711 |
||
461 | +#define MSM_BUS_SLAVE_SNOC_VMEM 712 |
||
462 | +#define MSM_BUS_SLAVE_PCIE_2 713 |
||
463 | +#define MSM_BUS_SLAVE_RBCPR_MX 714 |
||
464 | +#define MSM_BUS_SLAVE_RBCPR_CX 715 |
||
465 | +#define MSM_BUS_SLAVE_PRNG_APU_CFG 716 |
||
466 | +#define MSM_BUS_SLAVE_PERIPH_MPU_CFG 717 |
||
467 | +#define MSM_BUS_SLAVE_GCNT 718 |
||
468 | +#define MSM_BUS_SLAVE_ADSS_CFG 719 |
||
469 | +#define MSM_BUS_SLAVE_ADSS_VMIDMT_CFG 720 |
||
470 | +#define MSM_BUS_SLAVE_QHSS_APU_CFG 721 |
||
471 | +#define MSM_BUS_SLAVE_MDIO 722 |
||
472 | +#define MSM_BUS_SLAVE_FEPHY_CFG 723 |
||
473 | +#define MSM_BUS_SLAVE_SRIF 724 |
||
474 | +#define MSM_BUS_SLAVE_LAST 730 |
||
475 | +#define MSM_BUS_SLAVE_DDRC_CFG 731 |
||
476 | +#define MSM_BUS_SLAVE_DDRC_APU_CFG 732 |
||
477 | +#define MSM_BUS_SLAVE_MPU0_CFG 733 |
||
478 | +#define MSM_BUS_SLAVE_MPU1_CFG 734 |
||
479 | +#define MSM_BUS_SLAVE_MPU2_CFG 734 |
||
480 | +#define MSM_BUS_SLAVE_ESS_VMIDMT_CFG 735 |
||
481 | +#define MSM_BUS_SLAVE_ESS_APU_CFG 736 |
||
482 | +#define MSM_BUS_SLAVE_USB2_CFG 737 |
||
483 | +#define MSM_BUS_SLAVE_BLSP_CFG 738 |
||
484 | +#define MSM_BUS_SLAVE_QPIC_CFG 739 |
||
485 | +#define MSM_BUS_SLAVE_SDCC_CFG 740 |
||
486 | +#define MSM_BUS_SLAVE_WSS0_VMIDMT_CFG 741 |
||
487 | +#define MSM_BUS_SLAVE_WSS0_APU_CFG 742 |
||
488 | +#define MSM_BUS_SLAVE_WSS1_VMIDMT_CFG 743 |
||
489 | +#define MSM_BUS_SLAVE_WSS1_APU_CFG 744 |
||
490 | +#define MSM_BUS_SLAVE_SRVC_PCNOC 745 |
||
491 | +#define MSM_BUS_SLAVE_SNOC_DDRC 746 |
||
492 | +#define MSM_BUS_SLAVE_A7SS 747 |
||
493 | +#define MSM_BUS_SLAVE_WSS0_CFG 748 |
||
494 | +#define MSM_BUS_SLAVE_WSS1_CFG 749 |
||
495 | +#define MSM_BUS_SLAVE_PCIE 750 |
||
496 | +#define MSM_BUS_SLAVE_USB3_CFG 751 |
||
497 | +#define MSM_BUS_SLAVE_CRYPTO_CFG 752 |
||
498 | +#define MSM_BUS_SLAVE_ESS_CFG 753 |
||
499 | +#define MSM_BUS_SLAVE_SRVC_SNOC 754 |
||
500 | + |
||
501 | +#define MSM_BUS_SYSTEM_FPB_SLAVE_SYSTEM MSM_BUS_SYSTEM_SLAVE_SYSTEM_FPB |
||
502 | +#define MSM_BUS_CPSS_FPB_SLAVE_SYSTEM MSM_BUS_SYSTEM_SLAVE_CPSS_FPB |
||
503 | + |
||
504 | +/* |
||
505 | + * ID's used in RPM messages |
||
506 | + */ |
||
507 | +#define ICBID_MASTER_APPSS_PROC 0 |
||
508 | +#define ICBID_MASTER_MSS_PROC 1 |
||
509 | +#define ICBID_MASTER_MNOC_BIMC 2 |
||
510 | +#define ICBID_MASTER_SNOC_BIMC 3 |
||
511 | +#define ICBID_MASTER_SNOC_BIMC_0 ICBID_MASTER_SNOC_BIMC |
||
512 | +#define ICBID_MASTER_CNOC_MNOC_MMSS_CFG 4 |
||
513 | +#define ICBID_MASTER_CNOC_MNOC_CFG 5 |
||
514 | +#define ICBID_MASTER_GFX3D 6 |
||
515 | +#define ICBID_MASTER_JPEG 7 |
||
516 | +#define ICBID_MASTER_MDP 8 |
||
517 | +#define ICBID_MASTER_MDP0 ICBID_MASTER_MDP |
||
518 | +#define ICBID_MASTER_MDPS ICBID_MASTER_MDP |
||
519 | +#define ICBID_MASTER_VIDEO 9 |
||
520 | +#define ICBID_MASTER_VIDEO_P0 ICBID_MASTER_VIDEO |
||
521 | +#define ICBID_MASTER_VIDEO_P1 10 |
||
522 | +#define ICBID_MASTER_VFE 11 |
||
523 | +#define ICBID_MASTER_CNOC_ONOC_CFG 12 |
||
524 | +#define ICBID_MASTER_JPEG_OCMEM 13 |
||
525 | +#define ICBID_MASTER_MDP_OCMEM 14 |
||
526 | +#define ICBID_MASTER_VIDEO_P0_OCMEM 15 |
||
527 | +#define ICBID_MASTER_VIDEO_P1_OCMEM 16 |
||
528 | +#define ICBID_MASTER_VFE_OCMEM 17 |
||
529 | +#define ICBID_MASTER_LPASS_AHB 18 |
||
530 | +#define ICBID_MASTER_QDSS_BAM 19 |
||
531 | +#define ICBID_MASTER_SNOC_CFG 20 |
||
532 | +#define ICBID_MASTER_BIMC_SNOC 21 |
||
533 | +#define ICBID_MASTER_CNOC_SNOC 22 |
||
534 | +#define ICBID_MASTER_CRYPTO 23 |
||
535 | +#define ICBID_MASTER_CRYPTO_CORE0 ICBID_MASTER_CRYPTO |
||
536 | +#define ICBID_MASTER_CRYPTO_CORE1 24 |
||
537 | +#define ICBID_MASTER_LPASS_PROC 25 |
||
538 | +#define ICBID_MASTER_MSS 26 |
||
539 | +#define ICBID_MASTER_MSS_NAV 27 |
||
540 | +#define ICBID_MASTER_OCMEM_DMA 28 |
||
541 | +#define ICBID_MASTER_PNOC_SNOC 29 |
||
542 | +#define ICBID_MASTER_WCSS 30 |
||
543 | +#define ICBID_MASTER_QDSS_ETR 31 |
||
544 | +#define ICBID_MASTER_USB3 32 |
||
545 | +#define ICBID_MASTER_USB3_0 ICBID_MASTER_USB3 |
||
546 | +#define ICBID_MASTER_SDCC_1 33 |
||
547 | +#define ICBID_MASTER_SDCC_3 34 |
||
548 | +#define ICBID_MASTER_SDCC_2 35 |
||
549 | +#define ICBID_MASTER_SDCC_4 36 |
||
550 | +#define ICBID_MASTER_TSIF 37 |
||
551 | +#define ICBID_MASTER_BAM_DMA 38 |
||
552 | +#define ICBID_MASTER_BLSP_2 39 |
||
553 | +#define ICBID_MASTER_USB_HSIC 40 |
||
554 | +#define ICBID_MASTER_BLSP_1 41 |
||
555 | +#define ICBID_MASTER_USB_HS 42 |
||
556 | +#define ICBID_MASTER_USB_HS1 ICBID_MASTER_USB_HS |
||
557 | +#define ICBID_MASTER_PNOC_CFG 43 |
||
558 | +#define ICBID_MASTER_SNOC_PNOC 44 |
||
559 | +#define ICBID_MASTER_RPM_INST 45 |
||
560 | +#define ICBID_MASTER_RPM_DATA 46 |
||
561 | +#define ICBID_MASTER_RPM_SYS 47 |
||
562 | +#define ICBID_MASTER_DEHR 48 |
||
563 | +#define ICBID_MASTER_QDSS_DAP 49 |
||
564 | +#define ICBID_MASTER_SPDM 50 |
||
565 | +#define ICBID_MASTER_TIC 51 |
||
566 | +#define ICBID_MASTER_SNOC_CNOC 52 |
||
567 | +#define ICBID_MASTER_GFX3D_OCMEM 53 |
||
568 | +#define ICBID_MASTER_GFX3D_GMEM ICBID_MASTER_GFX3D_OCMEM |
||
569 | +#define ICBID_MASTER_OVIRT_SNOC 54 |
||
570 | +#define ICBID_MASTER_SNOC_OVIRT 55 |
||
571 | +#define ICBID_MASTER_SNOC_GVIRT ICBID_MASTER_SNOC_OVIRT |
||
572 | +#define ICBID_MASTER_ONOC_OVIRT 56 |
||
573 | +#define ICBID_MASTER_USB_HS2 57 |
||
574 | +#define ICBID_MASTER_QPIC 58 |
||
575 | +#define ICBID_MASTER_IPA 59 |
||
576 | +#define ICBID_MASTER_DSI 60 |
||
577 | +#define ICBID_MASTER_MDP1 61 |
||
578 | +#define ICBID_MASTER_MDPE ICBID_MASTER_MDP1 |
||
579 | +#define ICBID_MASTER_VPU_PROC 62 |
||
580 | +#define ICBID_MASTER_VPU 63 |
||
581 | +#define ICBID_MASTER_VPU0 ICBID_MASTER_VPU |
||
582 | +#define ICBID_MASTER_CRYPTO_CORE2 64 |
||
583 | +#define ICBID_MASTER_PCIE_0 65 |
||
584 | +#define ICBID_MASTER_PCIE_1 66 |
||
585 | +#define ICBID_MASTER_SATA 67 |
||
586 | +#define ICBID_MASTER_UFS 68 |
||
587 | +#define ICBID_MASTER_USB3_1 69 |
||
588 | +#define ICBID_MASTER_VIDEO_OCMEM 70 |
||
589 | +#define ICBID_MASTER_VPU1 71 |
||
590 | +#define ICBID_MASTER_VCAP 72 |
||
591 | +#define ICBID_MASTER_EMAC 73 |
||
592 | +#define ICBID_MASTER_BCAST 74 |
||
593 | +#define ICBID_MASTER_MMSS_PROC 75 |
||
594 | +#define ICBID_MASTER_SNOC_BIMC_1 76 |
||
595 | +#define ICBID_MASTER_SNOC_PCNOC 77 |
||
596 | +#define ICBID_MASTER_AUDIO 78 |
||
597 | +#define ICBID_MASTER_MM_INT_0 79 |
||
598 | +#define ICBID_MASTER_MM_INT_1 80 |
||
599 | +#define ICBID_MASTER_MM_INT_2 81 |
||
600 | +#define ICBID_MASTER_MM_INT_BIMC 82 |
||
601 | +#define ICBID_MASTER_MSS_INT 83 |
||
602 | +#define ICBID_MASTER_PCNOC_CFG 84 |
||
603 | +#define ICBID_MASTER_PCNOC_INT_0 85 |
||
604 | +#define ICBID_MASTER_PCNOC_INT_1 86 |
||
605 | +#define ICBID_MASTER_PCNOC_M_0 87 |
||
606 | +#define ICBID_MASTER_PCNOC_M_1 88 |
||
607 | +#define ICBID_MASTER_PCNOC_S_0 89 |
||
608 | +#define ICBID_MASTER_PCNOC_S_1 90 |
||
609 | +#define ICBID_MASTER_PCNOC_S_2 91 |
||
610 | +#define ICBID_MASTER_PCNOC_S_3 92 |
||
611 | +#define ICBID_MASTER_PCNOC_S_4 93 |
||
612 | +#define ICBID_MASTER_PCNOC_S_6 94 |
||
613 | +#define ICBID_MASTER_PCNOC_S_7 95 |
||
614 | +#define ICBID_MASTER_PCNOC_S_8 96 |
||
615 | +#define ICBID_MASTER_PCNOC_S_9 97 |
||
616 | +#define ICBID_MASTER_QDSS_INT 98 |
||
617 | +#define ICBID_MASTER_SNOC_INT_0 99 |
||
618 | +#define ICBID_MASTER_SNOC_INT_1 100 |
||
619 | +#define ICBID_MASTER_SNOC_INT_BIMC 101 |
||
620 | +#define ICBID_MASTER_TCU_0 102 |
||
621 | +#define ICBID_MASTER_TCU_1 103 |
||
622 | +#define ICBID_MASTER_BIMC_INT_0 104 |
||
623 | +#define ICBID_MASTER_BIMC_INT_1 105 |
||
624 | +#define ICBID_MASTER_CAMERA 106 |
||
625 | +#define ICBID_MASTER_RICA 107 |
||
626 | +#define ICBID_MASTER_PCNOC_S_5 129 |
||
627 | +#define ICBID_MASTER_PCNOC_INT_2 124 |
||
628 | +#define ICBID_MASTER_PCNOC_INT_3 125 |
||
629 | +#define ICBID_MASTER_PCNOC_INT_4 126 |
||
630 | +#define ICBID_MASTER_PCNOC_INT_5 127 |
||
631 | +#define ICBID_MASTER_PCNOC_INT_6 128 |
||
632 | +#define ICBID_MASTER_PCIE_2 119 |
||
633 | +#define ICBID_MASTER_MASTER_CNOC_A1NOC 116 |
||
634 | +#define ICBID_MASTER_A0NOC_SNOC 110 |
||
635 | +#define ICBID_MASTER_A1NOC_SNOC 111 |
||
636 | +#define ICBID_MASTER_A2NOC_SNOC 112 |
||
637 | +#define ICBID_MASTER_PNOC_A1NOC 117 |
||
638 | +#define ICBID_MASTER_ROTATOR 120 |
||
639 | +#define ICBID_MASTER_SNOC_VMEM 114 |
||
640 | +#define ICBID_MASTER_VENUS_VMEM 121 |
||
641 | +#define ICBID_MASTER_HMSS 118 |
||
642 | +#define ICBID_MASTER_BIMC_SNOC_1 109 |
||
643 | +#define ICBID_MASTER_CNOC_A1NOC 116 |
||
644 | +#define ICBID_MASTER_CPP 115 |
||
645 | +#define ICBID_MASTER_BLSP_BAM 130 |
||
646 | +#define ICBID_MASTER_USB2_BAM 131 |
||
647 | +#define ICBID_MASTER_ADSS_DMA0 132 |
||
648 | +#define ICBID_MASTER_ADSS_DMA1 133 |
||
649 | +#define ICBID_MASTER_ADSS_DMA2 134 |
||
650 | +#define ICBID_MASTER_ADSS_DMA3 135 |
||
651 | +#define ICBID_MASTER_QPIC_BAM 136 |
||
652 | +#define ICBID_MASTER_SDCC_BAM 137 |
||
653 | +#define ICBID_MASTER_DDRC_SNOC 138 |
||
654 | +#define ICBID_MASTER_WSS_0 139 |
||
655 | +#define ICBID_MASTER_WSS_1 140 |
||
656 | +#define ICBID_MASTER_ESS 141 |
||
657 | +#define ICBID_MASTER_PCIE 142 |
||
658 | +#define ICBID_MASTER_QDSS_BAMNDP 143 |
||
659 | +#define ICBID_MASTER_QDSS_SNOC_CFG 144 |
||
660 | + |
||
661 | +#define ICBID_SLAVE_EBI1 0 |
||
662 | +#define ICBID_SLAVE_APPSS_L2 1 |
||
663 | +#define ICBID_SLAVE_BIMC_SNOC 2 |
||
664 | +#define ICBID_SLAVE_CAMERA_CFG 3 |
||
665 | +#define ICBID_SLAVE_DISPLAY_CFG 4 |
||
666 | +#define ICBID_SLAVE_OCMEM_CFG 5 |
||
667 | +#define ICBID_SLAVE_CPR_CFG 6 |
||
668 | +#define ICBID_SLAVE_CPR_XPU_CFG 7 |
||
669 | +#define ICBID_SLAVE_MISC_CFG 8 |
||
670 | +#define ICBID_SLAVE_MISC_XPU_CFG 9 |
||
671 | +#define ICBID_SLAVE_VENUS_CFG 10 |
||
672 | +#define ICBID_SLAVE_GFX3D_CFG 11 |
||
673 | +#define ICBID_SLAVE_MMSS_CLK_CFG 12 |
||
674 | +#define ICBID_SLAVE_MMSS_CLK_XPU_CFG 13 |
||
675 | +#define ICBID_SLAVE_MNOC_MPU_CFG 14 |
||
676 | +#define ICBID_SLAVE_ONOC_MPU_CFG 15 |
||
677 | +#define ICBID_SLAVE_MNOC_BIMC 16 |
||
678 | +#define ICBID_SLAVE_SERVICE_MNOC 17 |
||
679 | +#define ICBID_SLAVE_OCMEM 18 |
||
680 | +#define ICBID_SLAVE_GMEM ICBID_SLAVE_OCMEM |
||
681 | +#define ICBID_SLAVE_SERVICE_ONOC 19 |
||
682 | +#define ICBID_SLAVE_APPSS 20 |
||
683 | +#define ICBID_SLAVE_LPASS 21 |
||
684 | +#define ICBID_SLAVE_USB3 22 |
||
685 | +#define ICBID_SLAVE_USB3_0 ICBID_SLAVE_USB3 |
||
686 | +#define ICBID_SLAVE_WCSS 23 |
||
687 | +#define ICBID_SLAVE_SNOC_BIMC 24 |
||
688 | +#define ICBID_SLAVE_SNOC_BIMC_0 ICBID_SLAVE_SNOC_BIMC |
||
689 | +#define ICBID_SLAVE_SNOC_CNOC 25 |
||
690 | +#define ICBID_SLAVE_IMEM 26 |
||
691 | +#define ICBID_SLAVE_OCIMEM ICBID_SLAVE_IMEM |
||
692 | +#define ICBID_SLAVE_SNOC_OVIRT 27 |
||
693 | +#define ICBID_SLAVE_SNOC_GVIRT ICBID_SLAVE_SNOC_OVIRT |
||
694 | +#define ICBID_SLAVE_SNOC_PNOC 28 |
||
695 | +#define ICBID_SLAVE_SNOC_PCNOC ICBID_SLAVE_SNOC_PNOC |
||
696 | +#define ICBID_SLAVE_SERVICE_SNOC 29 |
||
697 | +#define ICBID_SLAVE_QDSS_STM 30 |
||
698 | +#define ICBID_SLAVE_SDCC_1 31 |
||
699 | +#define ICBID_SLAVE_SDCC_3 32 |
||
700 | +#define ICBID_SLAVE_SDCC_2 33 |
||
701 | +#define ICBID_SLAVE_SDCC_4 34 |
||
702 | +#define ICBID_SLAVE_TSIF 35 |
||
703 | +#define ICBID_SLAVE_BAM_DMA 36 |
||
704 | +#define ICBID_SLAVE_BLSP_2 37 |
||
705 | +#define ICBID_SLAVE_USB_HSIC 38 |
||
706 | +#define ICBID_SLAVE_BLSP_1 39 |
||
707 | +#define ICBID_SLAVE_USB_HS 40 |
||
708 | +#define ICBID_SLAVE_USB_HS1 ICBID_SLAVE_USB_HS |
||
709 | +#define ICBID_SLAVE_PDM 41 |
||
710 | +#define ICBID_SLAVE_PERIPH_APU_CFG 42 |
||
711 | +#define ICBID_SLAVE_PNOC_MPU_CFG 43 |
||
712 | +#define ICBID_SLAVE_PRNG 44 |
||
713 | +#define ICBID_SLAVE_PNOC_SNOC 45 |
||
714 | +#define ICBID_SLAVE_PCNOC_SNOC ICBID_SLAVE_PNOC_SNOC |
||
715 | +#define ICBID_SLAVE_SERVICE_PNOC 46 |
||
716 | +#define ICBID_SLAVE_CLK_CTL 47 |
||
717 | +#define ICBID_SLAVE_CNOC_MSS 48 |
||
718 | +#define ICBID_SLAVE_PCNOC_MSS ICBID_SLAVE_CNOC_MSS |
||
719 | +#define ICBID_SLAVE_SECURITY 49 |
||
720 | +#define ICBID_SLAVE_TCSR 50 |
||
721 | +#define ICBID_SLAVE_TLMM 51 |
||
722 | +#define ICBID_SLAVE_CRYPTO_0_CFG 52 |
||
723 | +#define ICBID_SLAVE_CRYPTO_1_CFG 53 |
||
724 | +#define ICBID_SLAVE_IMEM_CFG 54 |
||
725 | +#define ICBID_SLAVE_MESSAGE_RAM 55 |
||
726 | +#define ICBID_SLAVE_BIMC_CFG 56 |
||
727 | +#define ICBID_SLAVE_BOOT_ROM 57 |
||
728 | +#define ICBID_SLAVE_CNOC_MNOC_MMSS_CFG 58 |
||
729 | +#define ICBID_SLAVE_PMIC_ARB 59 |
||
730 | +#define ICBID_SLAVE_SPDM_WRAPPER 60 |
||
731 | +#define ICBID_SLAVE_DEHR_CFG 61 |
||
732 | +#define ICBID_SLAVE_MPM 62 |
||
733 | +#define ICBID_SLAVE_QDSS_CFG 63 |
||
734 | +#define ICBID_SLAVE_RBCPR_CFG 64 |
||
735 | +#define ICBID_SLAVE_RBCPR_CX_CFG ICBID_SLAVE_RBCPR_CFG |
||
736 | +#define ICBID_SLAVE_RBCPR_QDSS_APU_CFG 65 |
||
737 | +#define ICBID_SLAVE_CNOC_MNOC_CFG 66 |
||
738 | +#define ICBID_SLAVE_SNOC_MPU_CFG 67 |
||
739 | +#define ICBID_SLAVE_CNOC_ONOC_CFG 68 |
||
740 | +#define ICBID_SLAVE_PNOC_CFG 69 |
||
741 | +#define ICBID_SLAVE_SNOC_CFG 70 |
||
742 | +#define ICBID_SLAVE_EBI1_DLL_CFG 71 |
||
743 | +#define ICBID_SLAVE_PHY_APU_CFG 72 |
||
744 | +#define ICBID_SLAVE_EBI1_PHY_CFG 73 |
||
745 | +#define ICBID_SLAVE_RPM 74 |
||
746 | +#define ICBID_SLAVE_CNOC_SNOC 75 |
||
747 | +#define ICBID_SLAVE_SERVICE_CNOC 76 |
||
748 | +#define ICBID_SLAVE_OVIRT_SNOC 77 |
||
749 | +#define ICBID_SLAVE_OVIRT_OCMEM 78 |
||
750 | +#define ICBID_SLAVE_USB_HS2 79 |
||
751 | +#define ICBID_SLAVE_QPIC 80 |
||
752 | +#define ICBID_SLAVE_IPS_CFG 81 |
||
753 | +#define ICBID_SLAVE_DSI_CFG 82 |
||
754 | +#define ICBID_SLAVE_USB3_1 83 |
||
755 | +#define ICBID_SLAVE_PCIE_0 84 |
||
756 | +#define ICBID_SLAVE_PCIE_1 85 |
||
757 | +#define ICBID_SLAVE_PSS_SMMU_CFG 86 |
||
758 | +#define ICBID_SLAVE_CRYPTO_2_CFG 87 |
||
759 | +#define ICBID_SLAVE_PCIE_0_CFG 88 |
||
760 | +#define ICBID_SLAVE_PCIE_1_CFG 89 |
||
761 | +#define ICBID_SLAVE_SATA_CFG 90 |
||
762 | +#define ICBID_SLAVE_SPSS_GENI_IR 91 |
||
763 | +#define ICBID_SLAVE_UFS_CFG 92 |
||
764 | +#define ICBID_SLAVE_AVSYNC_CFG 93 |
||
765 | +#define ICBID_SLAVE_VPU_CFG 94 |
||
766 | +#define ICBID_SLAVE_USB_PHY_CFG 95 |
||
767 | +#define ICBID_SLAVE_RBCPR_MX_CFG 96 |
||
768 | +#define ICBID_SLAVE_PCIE_PARF 97 |
||
769 | +#define ICBID_SLAVE_VCAP_CFG 98 |
||
770 | +#define ICBID_SLAVE_EMAC_CFG 99 |
||
771 | +#define ICBID_SLAVE_BCAST_CFG 100 |
||
772 | +#define ICBID_SLAVE_KLM_CFG 101 |
||
773 | +#define ICBID_SLAVE_DISPLAY_PWM 102 |
||
774 | +#define ICBID_SLAVE_GENI 103 |
||
775 | +#define ICBID_SLAVE_SNOC_BIMC_1 104 |
||
776 | +#define ICBID_SLAVE_AUDIO 105 |
||
777 | +#define ICBID_SLAVE_CATS_0 106 |
||
778 | +#define ICBID_SLAVE_CATS_1 107 |
||
779 | +#define ICBID_SLAVE_MM_INT_0 108 |
||
780 | +#define ICBID_SLAVE_MM_INT_1 109 |
||
781 | +#define ICBID_SLAVE_MM_INT_2 110 |
||
782 | +#define ICBID_SLAVE_MM_INT_BIMC 111 |
||
783 | +#define ICBID_SLAVE_MMU_MODEM_XPU_CFG 112 |
||
784 | +#define ICBID_SLAVE_MSS_INT 113 |
||
785 | +#define ICBID_SLAVE_PCNOC_INT_0 114 |
||
786 | +#define ICBID_SLAVE_PCNOC_INT_1 115 |
||
787 | +#define ICBID_SLAVE_PCNOC_M_0 116 |
||
788 | +#define ICBID_SLAVE_PCNOC_M_1 117 |
||
789 | +#define ICBID_SLAVE_PCNOC_S_0 118 |
||
790 | +#define ICBID_SLAVE_PCNOC_S_1 119 |
||
791 | +#define ICBID_SLAVE_PCNOC_S_2 120 |
||
792 | +#define ICBID_SLAVE_PCNOC_S_3 121 |
||
793 | +#define ICBID_SLAVE_PCNOC_S_4 122 |
||
794 | +#define ICBID_SLAVE_PCNOC_S_6 123 |
||
795 | +#define ICBID_SLAVE_PCNOC_S_7 124 |
||
796 | +#define ICBID_SLAVE_PCNOC_S_8 125 |
||
797 | +#define ICBID_SLAVE_PCNOC_S_9 126 |
||
798 | +#define ICBID_SLAVE_PRNG_XPU_CFG 127 |
||
799 | +#define ICBID_SLAVE_QDSS_INT 128 |
||
800 | +#define ICBID_SLAVE_RPM_XPU_CFG 129 |
||
801 | +#define ICBID_SLAVE_SNOC_INT_0 130 |
||
802 | +#define ICBID_SLAVE_SNOC_INT_1 131 |
||
803 | +#define ICBID_SLAVE_SNOC_INT_BIMC 132 |
||
804 | +#define ICBID_SLAVE_TCU 133 |
||
805 | +#define ICBID_SLAVE_BIMC_INT_0 134 |
||
806 | +#define ICBID_SLAVE_BIMC_INT_1 135 |
||
807 | +#define ICBID_SLAVE_RICA_CFG 136 |
||
808 | +#define ICBID_SLAVE_PCNOC_S_5 189 |
||
809 | +#define ICBID_SLAVE_PCNOC_S_7 124 |
||
810 | +#define ICBID_SLAVE_PCNOC_INT_2 184 |
||
811 | +#define ICBID_SLAVE_PCNOC_INT_3 185 |
||
812 | +#define ICBID_SLAVE_PCNOC_INT_4 186 |
||
813 | +#define ICBID_SLAVE_PCNOC_INT_5 187 |
||
814 | +#define ICBID_SLAVE_PCNOC_INT_6 188 |
||
815 | +#define ICBID_SLAVE_USB3_PHY_CFG 182 |
||
816 | +#define ICBID_SLAVE_IPA_CFG 183 |
||
817 | + |
||
818 | +#define ICBID_SLAVE_A0NOC_SNOC 141 |
||
819 | +#define ICBID_SLAVE_A1NOC_SNOC 142 |
||
820 | +#define ICBID_SLAVE_A2NOC_SNOC 143 |
||
821 | +#define ICBID_SLAVE_BIMC_SNOC_1 138 |
||
822 | +#define ICBID_SLAVE_PIMEM 167 |
||
823 | +#define ICBID_SLAVE_PIMEM_CFG 168 |
||
824 | +#define ICBID_SLAVE_DCC_CFG 155 |
||
825 | +#define ICBID_SLAVE_QDSS_RBCPR_APU_CFG 168 |
||
826 | +#define ICBID_SLAVE_A0NOC_CFG 144 |
||
827 | +#define ICBID_SLAVE_PCIE_2_CFG 165 |
||
828 | +#define ICBID_SLAVE_PCIE20_AHB2PHY 163 |
||
829 | +#define ICBID_SLAVE_PCIE_2 164 |
||
830 | +#define ICBID_SLAVE_A1NOC_CFG 147 |
||
831 | +#define ICBID_SLAVE_A1NOC_MPU_CFG 148 |
||
832 | +#define ICBID_SLAVE_A1NOC_SMMU_CFG 149 |
||
833 | +#define ICBID_SLAVE_A2NOC_CFG 150 |
||
834 | +#define ICBID_SLAVE_A2NOC_MPU_CFG 151 |
||
835 | +#define ICBID_SLAVE_A2NOC_SMMU_CFG 152 |
||
836 | +#define ICBID_SLAVE_AHB2PHY 153 |
||
837 | +#define ICBID_SLAVE_HMSS_L3 161 |
||
838 | +#define ICBID_SLAVE_LPASS_SMMU_CFG 161 |
||
839 | +#define ICBID_SLAVE_MMAGIC_CFG 162 |
||
840 | +#define ICBID_SLAVE_SSC_CFG 177 |
||
841 | +#define ICBID_SLAVE_VENUS_THROTTLE_CFG 178 |
||
842 | +#define ICBID_SLAVE_DISPLAY_THROTTLE_CFG 156 |
||
843 | +#define ICBID_SLAVE_CAMERA_THROTTLE_CFG 154 |
||
844 | +#define ICBID_SLAVE_DSA_CFG 157 |
||
845 | +#define ICBID_SLAVE_DSA_MPU_CFG 158 |
||
846 | +#define ICBID_SLAVE_SMMU_CPP_CFG 171 |
||
847 | +#define ICBID_SLAVE_SMMU_JPEG_CFG 172 |
||
848 | +#define ICBID_SLAVE_SMMU_MDP_CFG 173 |
||
849 | +#define ICBID_SLAVE_SMMU_ROTATOR_CFG 174 |
||
850 | +#define ICBID_SLAVE_SMMU_VENUS_CFG 175 |
||
851 | +#define ICBID_SLAVE_SMMU_VFE_CFG 176 |
||
852 | +#define ICBID_SLAVE_A0NOC_MPU_CFG 145 |
||
853 | +#define ICBID_SLAVE_A0NOC_SMMU_CFG 146 |
||
854 | +#define ICBID_SLAVE_VMEM_CFG 180 |
||
855 | +#define ICBID_SLAVE_VMEM 179 |
||
856 | +#define ICBID_SLAVE_PNOC_A1NOC 139 |
||
857 | +#define ICBID_SLAVE_SNOC_VMEM 140 |
||
858 | +#define ICBID_SLAVE_RBCPR_MX 170 |
||
859 | +#define ICBID_SLAVE_RBCPR_CX 169 |
||
860 | +#define ICBID_SLAVE_PRNG_APU_CFG 190 |
||
861 | +#define ICBID_SLAVE_PERIPH_MPU_CFG 191 |
||
862 | +#define ICBID_SLAVE_GCNT 192 |
||
863 | +#define ICBID_SLAVE_ADSS_CFG 193 |
||
864 | +#define ICBID_SLAVE_ADSS_APU 194 |
||
865 | +#define ICBID_SLAVE_ADSS_VMIDMT_CFG 195 |
||
866 | +#define ICBID_SLAVE_QHSS_APU_CFG 196 |
||
867 | +#define ICBID_SLAVE_MDIO 197 |
||
868 | +#define ICBID_SLAVE_FEPHY_CFG 198 |
||
869 | +#define ICBID_SLAVE_SRIF 199 |
||
870 | +#define ICBID_SLAVE_DDRC_CFG 200 |
||
871 | +#define ICBID_SLAVE_DDRC_APU_CFG 201 |
||
872 | +#define ICBID_SLAVE_DDRC_MPU0_CFG 202 |
||
873 | +#define ICBID_SLAVE_DDRC_MPU1_CFG 203 |
||
874 | +#define ICBID_SLAVE_DDRC_MPU2_CFG 210 |
||
875 | +#define ICBID_SLAVE_ESS_VMIDMT_CFG 211 |
||
876 | +#define ICBID_SLAVE_ESS_APU_CFG 212 |
||
877 | +#define ICBID_SLAVE_USB2_CFG 213 |
||
878 | +#define ICBID_SLAVE_BLSP_CFG 214 |
||
879 | +#define ICBID_SLAVE_QPIC_CFG 215 |
||
880 | +#define ICBID_SLAVE_SDCC_CFG 216 |
||
881 | +#define ICBID_SLAVE_WSS0_VMIDMT_CFG 217 |
||
882 | +#define ICBID_SLAVE_WSS0_APU_CFG 218 |
||
883 | +#define ICBID_SLAVE_WSS1_VMIDMT_CFG 219 |
||
884 | +#define ICBID_SLAVE_WSS1_APU_CFG 220 |
||
885 | +#define ICBID_SLAVE_SRVC_PCNOC 221 |
||
886 | +#define ICBID_SLAVE_SNOC_DDRC 222 |
||
887 | +#define ICBID_SLAVE_A7SS 223 |
||
888 | +#define ICBID_SLAVE_WSS0_CFG 224 |
||
889 | +#define ICBID_SLAVE_WSS1_CFG 225 |
||
890 | +#define ICBID_SLAVE_PCIE 226 |
||
891 | +#define ICBID_SLAVE_USB3_CFG 227 |
||
892 | +#define ICBID_SLAVE_CRYPTO_CFG 228 |
||
893 | +#define ICBID_SLAVE_ESS_CFG 229 |
||
894 | +#define ICBID_SLAVE_SRVC_SNOC 230 |
||
895 | +#endif |
||
896 | --- /dev/null |
||
897 | +++ b/include/dt-bindings/msm/msm-bus-rule-ops.h |
||
898 | @@ -0,0 +1,32 @@ |
||
899 | +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. |
||
900 | + * |
||
901 | + * This program is free software; you can redistribute it and/or modify |
||
902 | + * it under the terms of the GNU General Public License version 2 and |
||
903 | + * only version 2 as published by the Free Software Foundation. |
||
904 | + * |
||
905 | + * This program is distributed in the hope that it will be useful, |
||
906 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
907 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
908 | + * GNU General Public License for more details. |
||
909 | + */ |
||
910 | + |
||
911 | +#ifndef __MSM_BUS_RULE_OPS_H |
||
912 | +#define __MSM_BUS_RULE_OPS_H |
||
913 | + |
||
914 | +#define FLD_IB 0 |
||
915 | +#define FLD_AB 1 |
||
916 | +#define FLD_CLK 2 |
||
917 | + |
||
918 | +#define OP_LE 0 |
||
919 | +#define OP_LT 1 |
||
920 | +#define OP_GE 2 |
||
921 | +#define OP_GT 3 |
||
922 | +#define OP_NOOP 4 |
||
923 | + |
||
924 | +#define RULE_STATE_NOT_APPLIED 0 |
||
925 | +#define RULE_STATE_APPLIED 1 |
||
926 | + |
||
927 | +#define THROTTLE_ON 0 |
||
928 | +#define THROTTLE_OFF 1 |
||
929 | + |
||
930 | +#endif |
||
931 | --- /dev/null |
||
932 | +++ b/drivers/bus/msm_bus/Kconfig |
||
933 | @@ -0,0 +1,19 @@ |
||
934 | +config BUS_TOPOLOGY_ADHOC |
||
935 | + bool "ad-hoc bus scaling topology" |
||
936 | + depends on ARCH_QCOM |
||
937 | + default n |
||
938 | + help |
||
939 | + This option enables a driver that can handle adhoc bus topologies. |
||
940 | + Adhoc bus topology driver allows one to many connections and maintains |
||
941 | + directionality of connections by explicitly listing device connections |
||
942 | + thus avoiding illegal routes. |
||
943 | + |
||
944 | +config MSM_BUS_SCALING |
||
945 | + bool "Bus scaling driver" |
||
946 | + depends on BUS_TOPOLOGY_ADHOC |
||
947 | + default n |
||
948 | + help |
||
949 | + This option enables bus scaling on MSM devices. Bus scaling |
||
950 | + allows devices to request the clocks be set to rates sufficient |
||
951 | + for the active devices needs without keeping the clocks at max |
||
952 | + frequency when a slower speed is sufficient. |
||
953 | --- /dev/null |
||
954 | +++ b/drivers/bus/msm_bus/Makefile |
||
955 | @@ -0,0 +1,12 @@ |
||
956 | +# |
||
957 | +# Makefile for msm-bus driver specific files |
||
958 | +# |
||
959 | +obj-y += msm_bus_bimc.o msm_bus_noc.o msm_bus_core.o msm_bus_client_api.o \ |
||
960 | + msm_bus_id.o |
||
961 | +obj-$(CONFIG_OF) += msm_bus_of.o |
||
962 | + |
||
963 | +obj-y += msm_bus_fabric_adhoc.o msm_bus_arb_adhoc.o msm_bus_rules.o |
||
964 | +obj-$(CONFIG_OF) += msm_bus_of_adhoc.o |
||
965 | +obj-$(CONFIG_CORESIGHT) += msm_buspm_coresight_adhoc.o |
||
966 | + |
||
967 | +obj-$(CONFIG_DEBUG_FS) += msm_bus_dbg.o |
||
968 | --- /dev/null |
||
969 | +++ b/drivers/bus/msm_bus/msm-bus-board.h |
||
970 | @@ -0,0 +1,198 @@ |
||
971 | +/* Copyright (c) 2010-2014, The Linux Foundation. All rights reserved. |
||
972 | + * |
||
973 | + * This program is free software; you can redistribute it and/or modify |
||
974 | + * it under the terms of the GNU General Public License version 2 and |
||
975 | + * only version 2 as published by the Free Software Foundation. |
||
976 | + * |
||
977 | + * This program is distributed in the hope that it will be useful, |
||
978 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
979 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
980 | + * GNU General Public License for more details. |
||
981 | + */ |
||
982 | + |
||
983 | +#ifndef __ASM_ARCH_MSM_BUS_BOARD_H |
||
984 | +#define __ASM_ARCH_MSM_BUS_BOARD_H |
||
985 | + |
||
986 | +#include <linux/types.h> |
||
987 | +#include <linux/input.h> |
||
988 | + |
||
989 | +enum context { |
||
990 | + DUAL_CTX, |
||
991 | + ACTIVE_CTX, |
||
992 | + NUM_CTX |
||
993 | +}; |
||
994 | + |
||
995 | +struct msm_bus_fabric_registration { |
||
996 | + unsigned int id; |
||
997 | + const char *name; |
||
998 | + struct msm_bus_node_info *info; |
||
999 | + unsigned int len; |
||
1000 | + int ahb; |
||
1001 | + const char *fabclk[NUM_CTX]; |
||
1002 | + const char *iface_clk; |
||
1003 | + unsigned int offset; |
||
1004 | + unsigned int haltid; |
||
1005 | + unsigned int rpm_enabled; |
||
1006 | + unsigned int nmasters; |
||
1007 | + unsigned int nslaves; |
||
1008 | + unsigned int ntieredslaves; |
||
1009 | + bool il_flag; |
||
1010 | + const struct msm_bus_board_algorithm *board_algo; |
||
1011 | + int hw_sel; |
||
1012 | + void *hw_data; |
||
1013 | + uint32_t qos_freq; |
||
1014 | + uint32_t qos_baseoffset; |
||
1015 | + u64 nr_lim_thresh; |
||
1016 | + uint32_t eff_fact; |
||
1017 | + uint32_t qos_delta; |
||
1018 | + bool virt; |
||
1019 | +}; |
||
1020 | + |
||
1021 | +struct msm_bus_device_node_registration { |
||
1022 | + struct msm_bus_node_device_type *info; |
||
1023 | + unsigned int num_devices; |
||
1024 | + bool virt; |
||
1025 | +}; |
||
1026 | + |
||
1027 | +enum msm_bus_bw_tier_type { |
||
1028 | + MSM_BUS_BW_TIER1 = 1, |
||
1029 | + MSM_BUS_BW_TIER2, |
||
1030 | + MSM_BUS_BW_COUNT, |
||
1031 | + MSM_BUS_BW_SIZE = 0x7FFFFFFF, |
||
1032 | +}; |
||
1033 | + |
||
1034 | +struct msm_bus_halt_vector { |
||
1035 | + uint32_t haltval; |
||
1036 | + uint32_t haltmask; |
||
1037 | +}; |
||
1038 | + |
||
1039 | +extern struct msm_bus_fabric_registration msm_bus_apps_fabric_pdata; |
||
1040 | +extern struct msm_bus_fabric_registration msm_bus_sys_fabric_pdata; |
||
1041 | +extern struct msm_bus_fabric_registration msm_bus_mm_fabric_pdata; |
||
1042 | +extern struct msm_bus_fabric_registration msm_bus_sys_fpb_pdata; |
||
1043 | +extern struct msm_bus_fabric_registration msm_bus_cpss_fpb_pdata; |
||
1044 | +extern struct msm_bus_fabric_registration msm_bus_def_fab_pdata; |
||
1045 | + |
||
1046 | +extern struct msm_bus_fabric_registration msm_bus_8960_apps_fabric_pdata; |
||
1047 | +extern struct msm_bus_fabric_registration msm_bus_8960_sys_fabric_pdata; |
||
1048 | +extern struct msm_bus_fabric_registration msm_bus_8960_mm_fabric_pdata; |
||
1049 | +extern struct msm_bus_fabric_registration msm_bus_8960_sg_mm_fabric_pdata; |
||
1050 | +extern struct msm_bus_fabric_registration msm_bus_8960_sys_fpb_pdata; |
||
1051 | +extern struct msm_bus_fabric_registration msm_bus_8960_cpss_fpb_pdata; |
||
1052 | + |
||
1053 | +extern struct msm_bus_fabric_registration msm_bus_8064_apps_fabric_pdata; |
||
1054 | +extern struct msm_bus_fabric_registration msm_bus_8064_sys_fabric_pdata; |
||
1055 | +extern struct msm_bus_fabric_registration msm_bus_8064_mm_fabric_pdata; |
||
1056 | +extern struct msm_bus_fabric_registration msm_bus_8064_sys_fpb_pdata; |
||
1057 | +extern struct msm_bus_fabric_registration msm_bus_8064_cpss_fpb_pdata; |
||
1058 | + |
||
1059 | +extern struct msm_bus_fabric_registration msm_bus_9615_sys_fabric_pdata; |
||
1060 | +extern struct msm_bus_fabric_registration msm_bus_9615_def_fab_pdata; |
||
1061 | + |
||
1062 | +extern struct msm_bus_fabric_registration msm_bus_8930_apps_fabric_pdata; |
||
1063 | +extern struct msm_bus_fabric_registration msm_bus_8930_sys_fabric_pdata; |
||
1064 | +extern struct msm_bus_fabric_registration msm_bus_8930_mm_fabric_pdata; |
||
1065 | +extern struct msm_bus_fabric_registration msm_bus_8930_sys_fpb_pdata; |
||
1066 | +extern struct msm_bus_fabric_registration msm_bus_8930_cpss_fpb_pdata; |
||
1067 | + |
||
1068 | +extern struct msm_bus_fabric_registration msm_bus_8974_sys_noc_pdata; |
||
1069 | +extern struct msm_bus_fabric_registration msm_bus_8974_mmss_noc_pdata; |
||
1070 | +extern struct msm_bus_fabric_registration msm_bus_8974_bimc_pdata; |
||
1071 | +extern struct msm_bus_fabric_registration msm_bus_8974_ocmem_noc_pdata; |
||
1072 | +extern struct msm_bus_fabric_registration msm_bus_8974_periph_noc_pdata; |
||
1073 | +extern struct msm_bus_fabric_registration msm_bus_8974_config_noc_pdata; |
||
1074 | +extern struct msm_bus_fabric_registration msm_bus_8974_ocmem_vnoc_pdata; |
||
1075 | + |
||
1076 | +extern struct msm_bus_fabric_registration msm_bus_9625_sys_noc_pdata; |
||
1077 | +extern struct msm_bus_fabric_registration msm_bus_9625_bimc_pdata; |
||
1078 | +extern struct msm_bus_fabric_registration msm_bus_9625_periph_noc_pdata; |
||
1079 | +extern struct msm_bus_fabric_registration msm_bus_9625_config_noc_pdata; |
||
1080 | + |
||
1081 | +extern int msm_bus_device_match_adhoc(struct device *dev, void *id); |
||
1082 | + |
||
1083 | +void msm_bus_rpm_set_mt_mask(void); |
||
1084 | +int msm_bus_board_rpm_get_il_ids(uint16_t *id); |
||
1085 | +int msm_bus_board_get_iid(int id); |
||
1086 | + |
||
1087 | +#define NFAB_MSM8226 6 |
||
1088 | +#define NFAB_MSM8610 5 |
||
1089 | + |
||
1090 | +/* |
||
1091 | + * These macros specify the convention followed for allocating |
||
1092 | + * ids to fabrics, masters and slaves for 8x60. |
||
1093 | + * |
||
1094 | + * A node can be identified as a master/slave/fabric by using |
||
1095 | + * these ids. |
||
1096 | + */ |
||
1097 | +#define FABRIC_ID_KEY 1024 |
||
1098 | +#define SLAVE_ID_KEY ((FABRIC_ID_KEY) >> 1) |
||
1099 | +#define MAX_FAB_KEY 7168 /* OR(All fabric ids) */ |
||
1100 | +#define INT_NODE_START 10000 |
||
1101 | + |
||
1102 | +#define GET_FABID(id) ((id) & MAX_FAB_KEY) |
||
1103 | + |
||
1104 | +#define NODE_ID(id) ((id) & (FABRIC_ID_KEY - 1)) |
||
1105 | +#define IS_SLAVE(id) ((NODE_ID(id)) >= SLAVE_ID_KEY ? 1 : 0) |
||
1106 | +#define CHECK_ID(iid, id) (((iid & id) != id) ? -ENXIO : iid) |
||
1107 | + |
||
1108 | +/* |
||
1109 | + * The following macros are used to format the data for port halt |
||
1110 | + * and unhalt requests. |
||
1111 | + */ |
||
1112 | +#define MSM_BUS_CLK_HALT 0x1 |
||
1113 | +#define MSM_BUS_CLK_HALT_MASK 0x1 |
||
1114 | +#define MSM_BUS_CLK_HALT_FIELDSIZE 0x1 |
||
1115 | +#define MSM_BUS_CLK_UNHALT 0x0 |
||
1116 | + |
||
1117 | +#define MSM_BUS_MASTER_SHIFT(master, fieldsize) \ |
||
1118 | + ((master) * (fieldsize)) |
||
1119 | + |
||
1120 | +#define MSM_BUS_SET_BITFIELD(word, fieldmask, fieldvalue) \ |
||
1121 | + { \ |
||
1122 | + (word) &= ~(fieldmask); \ |
||
1123 | + (word) |= (fieldvalue); \ |
||
1124 | + } |
||
1125 | + |
||
1126 | + |
||
1127 | +#define MSM_BUS_MASTER_HALT(u32haltmask, u32haltval, master) \ |
||
1128 | + MSM_BUS_SET_BITFIELD(u32haltmask, \ |
||
1129 | + MSM_BUS_CLK_HALT_MASK<<MSM_BUS_MASTER_SHIFT((master),\ |
||
1130 | + MSM_BUS_CLK_HALT_FIELDSIZE), \ |
||
1131 | + MSM_BUS_CLK_HALT_MASK<<MSM_BUS_MASTER_SHIFT((master),\ |
||
1132 | + MSM_BUS_CLK_HALT_FIELDSIZE))\ |
||
1133 | + MSM_BUS_SET_BITFIELD(u32haltval, \ |
||
1134 | + MSM_BUS_CLK_HALT_MASK<<MSM_BUS_MASTER_SHIFT((master),\ |
||
1135 | + MSM_BUS_CLK_HALT_FIELDSIZE), \ |
||
1136 | + MSM_BUS_CLK_HALT<<MSM_BUS_MASTER_SHIFT((master),\ |
||
1137 | + MSM_BUS_CLK_HALT_FIELDSIZE))\ |
||
1138 | + |
||
1139 | +#define MSM_BUS_MASTER_UNHALT(u32haltmask, u32haltval, master) \ |
||
1140 | + MSM_BUS_SET_BITFIELD(u32haltmask, \ |
||
1141 | + MSM_BUS_CLK_HALT_MASK<<MSM_BUS_MASTER_SHIFT((master),\ |
||
1142 | + MSM_BUS_CLK_HALT_FIELDSIZE), \ |
||
1143 | + MSM_BUS_CLK_HALT_MASK<<MSM_BUS_MASTER_SHIFT((master),\ |
||
1144 | + MSM_BUS_CLK_HALT_FIELDSIZE))\ |
||
1145 | + MSM_BUS_SET_BITFIELD(u32haltval, \ |
||
1146 | + MSM_BUS_CLK_HALT_MASK<<MSM_BUS_MASTER_SHIFT((master),\ |
||
1147 | + MSM_BUS_CLK_HALT_FIELDSIZE), \ |
||
1148 | + MSM_BUS_CLK_UNHALT<<MSM_BUS_MASTER_SHIFT((master),\ |
||
1149 | + MSM_BUS_CLK_HALT_FIELDSIZE))\ |
||
1150 | + |
||
1151 | +#define RPM_BUS_SLAVE_REQ 0x766c7362 |
||
1152 | +#define RPM_BUS_MASTER_REQ 0x73616d62 |
||
1153 | + |
||
1154 | +enum msm_bus_rpm_slave_field_type { |
||
1155 | + RPM_SLAVE_FIELD_BW = 0x00007762, |
||
1156 | +}; |
||
1157 | + |
||
1158 | +enum msm_bus_rpm_mas_field_type { |
||
1159 | + RPM_MASTER_FIELD_BW = 0x00007762, |
||
1160 | + RPM_MASTER_FIELD_BW_T0 = 0x30747762, |
||
1161 | + RPM_MASTER_FIELD_BW_T1 = 0x31747762, |
||
1162 | + RPM_MASTER_FIELD_BW_T2 = 0x32747762, |
||
1163 | +}; |
||
1164 | + |
||
1165 | +#include <dt-bindings/msm/msm-bus-ids.h> |
||
1166 | + |
||
1167 | + |
||
1168 | +#endif /*__ASM_ARCH_MSM_BUS_BOARD_H */ |
||
1169 | --- /dev/null |
||
1170 | +++ b/drivers/bus/msm_bus/msm-bus.h |
||
1171 | @@ -0,0 +1,139 @@ |
||
1172 | +/* Copyright (c) 2010-2014, The Linux Foundation. All rights reserved. |
||
1173 | + * |
||
1174 | + * This program is free software; you can redistribute it and/or modify |
||
1175 | + * it under the terms of the GNU General Public License version 2 and |
||
1176 | + * only version 2 as published by the Free Software Foundation. |
||
1177 | + * |
||
1178 | + * This program is distributed in the hope that it will be useful, |
||
1179 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
1180 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
1181 | + * GNU General Public License for more details. |
||
1182 | + */ |
||
1183 | + |
||
1184 | +#ifndef _ARCH_ARM_MACH_MSM_BUS_H |
||
1185 | +#define _ARCH_ARM_MACH_MSM_BUS_H |
||
1186 | + |
||
1187 | +#include <linux/types.h> |
||
1188 | +#include <linux/input.h> |
||
1189 | +#include <linux/platform_device.h> |
||
1190 | + |
||
1191 | +/* |
||
1192 | + * Macros for clients to convert their data to ib and ab |
||
1193 | + * Ws : Time window over which to transfer the data in SECONDS |
||
1194 | + * Bs : Size of the data block in bytes |
||
1195 | + * Per : Recurrence period |
||
1196 | + * Tb : Throughput bandwidth to prevent stalling |
||
1197 | + * R : Ratio of actual bandwidth used to Tb |
||
1198 | + * Ib : Instantaneous bandwidth |
||
1199 | + * Ab : Arbitrated bandwidth |
||
1200 | + * |
||
1201 | + * IB_RECURRBLOCK and AB_RECURRBLOCK: |
||
1202 | + * These are used if the requirement is to transfer a |
||
1203 | + * recurring block of data over a known time window. |
||
1204 | + * |
||
1205 | + * IB_THROUGHPUTBW and AB_THROUGHPUTBW: |
||
1206 | + * These are used for CPU style masters. Here the requirement |
||
1207 | + * is to have minimum throughput bandwidth available to avoid |
||
1208 | + * stalling. |
||
1209 | + */ |
||
1210 | +#define IB_RECURRBLOCK(Ws, Bs) ((Ws) == 0 ? 0 : ((Bs)/(Ws))) |
||
1211 | +#define AB_RECURRBLOCK(Ws, Per) ((Ws) == 0 ? 0 : ((Bs)/(Per))) |
||
1212 | +#define IB_THROUGHPUTBW(Tb) (Tb) |
||
1213 | +#define AB_THROUGHPUTBW(Tb, R) ((Tb) * (R)) |
||
1214 | + |
||
1215 | +struct msm_bus_vectors { |
||
1216 | + int src; /* Master */ |
||
1217 | + int dst; /* Slave */ |
||
1218 | + uint64_t ab; /* Arbitrated bandwidth */ |
||
1219 | + uint64_t ib; /* Instantaneous bandwidth */ |
||
1220 | +}; |
||
1221 | + |
||
1222 | +struct msm_bus_paths { |
||
1223 | + int num_paths; |
||
1224 | + struct msm_bus_vectors *vectors; |
||
1225 | +}; |
||
1226 | + |
||
1227 | +struct msm_bus_scale_pdata { |
||
1228 | + struct msm_bus_paths *usecase; |
||
1229 | + int num_usecases; |
||
1230 | + const char *name; |
||
1231 | + /* |
||
1232 | + * If the active_only flag is set to 1, the BW request is applied |
||
1233 | + * only when at least one CPU is active (powered on). If the flag |
||
1234 | + * is set to 0, then the BW request is always applied irrespective |
||
1235 | + * of the CPU state. |
||
1236 | + */ |
||
1237 | + unsigned int active_only; |
||
1238 | +}; |
||
1239 | + |
||
1240 | +/* Scaling APIs */ |
||
1241 | + |
||
1242 | +/* |
||
1243 | + * This function returns a handle to the client. This should be used to |
||
1244 | + * call msm_bus_scale_client_update_request. |
||
1245 | + * The function returns 0 if bus driver is unable to register a client |
||
1246 | + */ |
||
1247 | + |
||
1248 | +#if (defined(CONFIG_MSM_BUS_SCALING) || defined(CONFIG_BUS_TOPOLOGY_ADHOC)) |
||
1249 | +int __init msm_bus_fabric_init_driver(void); |
||
1250 | +uint32_t msm_bus_scale_register_client(struct msm_bus_scale_pdata *pdata); |
||
1251 | +int msm_bus_scale_client_update_request(uint32_t cl, unsigned int index); |
||
1252 | +void msm_bus_scale_unregister_client(uint32_t cl); |
||
1253 | +/* AXI Port configuration APIs */ |
||
1254 | +int msm_bus_axi_porthalt(int master_port); |
||
1255 | +int msm_bus_axi_portunhalt(int master_port); |
||
1256 | + |
||
1257 | +#else |
||
1258 | +static inline int __init msm_bus_fabric_init_driver(void) { return 0; } |
||
1259 | + |
||
1260 | +static inline uint32_t |
||
1261 | +msm_bus_scale_register_client(struct msm_bus_scale_pdata *pdata) |
||
1262 | +{ |
||
1263 | + return 1; |
||
1264 | +} |
||
1265 | + |
||
1266 | +static inline int |
||
1267 | +msm_bus_scale_client_update_request(uint32_t cl, unsigned int index) |
||
1268 | +{ |
||
1269 | + return 0; |
||
1270 | +} |
||
1271 | + |
||
1272 | +static inline void |
||
1273 | +msm_bus_scale_unregister_client(uint32_t cl) |
||
1274 | +{ |
||
1275 | +} |
||
1276 | + |
||
1277 | +static inline int msm_bus_axi_porthalt(int master_port) |
||
1278 | +{ |
||
1279 | + return 0; |
||
1280 | +} |
||
1281 | + |
||
1282 | +static inline int msm_bus_axi_portunhalt(int master_port) |
||
1283 | +{ |
||
1284 | + return 0; |
||
1285 | +} |
||
1286 | +#endif |
||
1287 | + |
||
1288 | +#if defined(CONFIG_OF) && defined(CONFIG_MSM_BUS_SCALING) |
||
1289 | +struct msm_bus_scale_pdata *msm_bus_pdata_from_node( |
||
1290 | + struct platform_device *pdev, struct device_node *of_node); |
||
1291 | +struct msm_bus_scale_pdata *msm_bus_cl_get_pdata(struct platform_device *pdev); |
||
1292 | +void msm_bus_cl_clear_pdata(struct msm_bus_scale_pdata *pdata); |
||
1293 | +#else |
||
1294 | +static inline struct msm_bus_scale_pdata |
||
1295 | +*msm_bus_cl_get_pdata(struct platform_device *pdev) |
||
1296 | +{ |
||
1297 | + return NULL; |
||
1298 | +} |
||
1299 | + |
||
1300 | +static inline struct msm_bus_scale_pdata *msm_bus_pdata_from_node( |
||
1301 | + struct platform_device *pdev, struct device_node *of_node) |
||
1302 | +{ |
||
1303 | + return NULL; |
||
1304 | +} |
||
1305 | + |
||
1306 | +static inline void msm_bus_cl_clear_pdata(struct msm_bus_scale_pdata *pdata) |
||
1307 | +{ |
||
1308 | +} |
||
1309 | +#endif |
||
1310 | +#endif /*_ARCH_ARM_MACH_MSM_BUS_H*/ |
||
1311 | --- /dev/null |
||
1312 | +++ b/drivers/bus/msm_bus/msm_bus_adhoc.h |
||
1313 | @@ -0,0 +1,141 @@ |
||
1314 | +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. |
||
1315 | + * |
||
1316 | + * This program is free software; you can redistribute it and/or modify |
||
1317 | + * it under the terms of the GNU General Public License version 2 and |
||
1318 | + * only version 2 as published by the Free Software Foundation. |
||
1319 | + * |
||
1320 | + * This program is distributed in the hope that it will be useful, |
||
1321 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
1322 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
1323 | + * GNU General Public License for more details. |
||
1324 | + */ |
||
1325 | + |
||
1326 | +#ifndef _ARCH_ARM_MACH_MSM_BUS_ADHOC_H |
||
1327 | +#define _ARCH_ARM_MACH_MSM_BUS_ADHOC_H |
||
1328 | + |
||
1329 | +#include <linux/types.h> |
||
1330 | +#include <linux/device.h> |
||
1331 | +#include "msm-bus-board.h" |
||
1332 | +#include "msm-bus.h" |
||
1333 | +#include "msm_bus_rules.h" |
||
1334 | +#include "msm_bus_core.h" |
||
1335 | + |
||
1336 | +struct msm_bus_node_device_type; |
||
1337 | +struct link_node { |
||
1338 | + uint64_t lnode_ib[NUM_CTX]; |
||
1339 | + uint64_t lnode_ab[NUM_CTX]; |
||
1340 | + int next; |
||
1341 | + struct device *next_dev; |
||
1342 | + struct list_head link; |
||
1343 | + uint32_t in_use; |
||
1344 | +}; |
||
1345 | + |
||
1346 | +/* New types introduced for adhoc topology */ |
||
1347 | +struct msm_bus_noc_ops { |
||
1348 | + int (*qos_init)(struct msm_bus_node_device_type *dev, |
||
1349 | + void __iomem *qos_base, uint32_t qos_off, |
||
1350 | + uint32_t qos_delta, uint32_t qos_freq); |
||
1351 | + int (*set_bw)(struct msm_bus_node_device_type *dev, |
||
1352 | + void __iomem *qos_base, uint32_t qos_off, |
||
1353 | + uint32_t qos_delta, uint32_t qos_freq); |
||
1354 | + int (*limit_mport)(struct msm_bus_node_device_type *dev, |
||
1355 | + void __iomem *qos_base, uint32_t qos_off, |
||
1356 | + uint32_t qos_delta, uint32_t qos_freq, bool enable_lim, |
||
1357 | + uint64_t lim_bw); |
||
1358 | + bool (*update_bw_reg)(int mode); |
||
1359 | +}; |
||
1360 | + |
||
1361 | +struct nodebw { |
||
1362 | + uint64_t ab[NUM_CTX]; |
||
1363 | + bool dirty; |
||
1364 | +}; |
||
1365 | + |
||
1366 | +struct msm_bus_fab_device_type { |
||
1367 | + void __iomem *qos_base; |
||
1368 | + phys_addr_t pqos_base; |
||
1369 | + size_t qos_range; |
||
1370 | + uint32_t base_offset; |
||
1371 | + uint32_t qos_freq; |
||
1372 | + uint32_t qos_off; |
||
1373 | + uint32_t util_fact; |
||
1374 | + uint32_t vrail_comp; |
||
1375 | + struct msm_bus_noc_ops noc_ops; |
||
1376 | + enum msm_bus_hw_sel bus_type; |
||
1377 | + bool bypass_qos_prg; |
||
1378 | +}; |
||
1379 | + |
||
1380 | +struct qos_params_type { |
||
1381 | + int mode; |
||
1382 | + unsigned int prio_lvl; |
||
1383 | + unsigned int prio_rd; |
||
1384 | + unsigned int prio_wr; |
||
1385 | + unsigned int prio1; |
||
1386 | + unsigned int prio0; |
||
1387 | + unsigned int gp; |
||
1388 | + unsigned int thmp; |
||
1389 | + unsigned int ws; |
||
1390 | + int cur_mode; |
||
1391 | + u64 bw_buffer; |
||
1392 | +}; |
||
1393 | + |
||
1394 | +struct msm_bus_node_info_type { |
||
1395 | + const char *name; |
||
1396 | + unsigned int id; |
||
1397 | + int mas_rpm_id; |
||
1398 | + int slv_rpm_id; |
||
1399 | + int num_ports; |
||
1400 | + int num_qports; |
||
1401 | + int *qport; |
||
1402 | + struct qos_params_type qos_params; |
||
1403 | + unsigned int num_connections; |
||
1404 | + unsigned int num_blist; |
||
1405 | + bool is_fab_dev; |
||
1406 | + bool virt_dev; |
||
1407 | + bool is_traversed; |
||
1408 | + unsigned int *connections; |
||
1409 | + unsigned int *black_listed_connections; |
||
1410 | + struct device **dev_connections; |
||
1411 | + struct device **black_connections; |
||
1412 | + unsigned int bus_device_id; |
||
1413 | + struct device *bus_device; |
||
1414 | + unsigned int buswidth; |
||
1415 | + struct rule_update_path_info rule; |
||
1416 | + uint64_t lim_bw; |
||
1417 | + uint32_t util_fact; |
||
1418 | + uint32_t vrail_comp; |
||
1419 | +}; |
||
1420 | + |
||
1421 | +struct msm_bus_node_device_type { |
||
1422 | + struct msm_bus_node_info_type *node_info; |
||
1423 | + struct msm_bus_fab_device_type *fabdev; |
||
1424 | + int num_lnodes; |
||
1425 | + struct link_node *lnode_list; |
||
1426 | + uint64_t cur_clk_hz[NUM_CTX]; |
||
1427 | + struct nodebw node_ab; |
||
1428 | + struct list_head link; |
||
1429 | + unsigned int ap_owned; |
||
1430 | + struct nodeclk clk[NUM_CTX]; |
||
1431 | + struct nodeclk qos_clk; |
||
1432 | +}; |
||
1433 | + |
||
1434 | +int msm_bus_enable_limiter(struct msm_bus_node_device_type *nodedev, |
||
1435 | + bool throttle_en, uint64_t lim_bw); |
||
1436 | +int msm_bus_update_clks(struct msm_bus_node_device_type *nodedev, |
||
1437 | + int ctx, int **dirty_nodes, int *num_dirty); |
||
1438 | +int msm_bus_commit_data(int *dirty_nodes, int ctx, int num_dirty); |
||
1439 | +int msm_bus_update_bw(struct msm_bus_node_device_type *nodedev, int ctx, |
||
1440 | + int64_t add_bw, int **dirty_nodes, int *num_dirty); |
||
1441 | +void *msm_bus_realloc_devmem(struct device *dev, void *p, size_t old_size, |
||
1442 | + size_t new_size, gfp_t flags); |
||
1443 | + |
||
1444 | +extern struct msm_bus_device_node_registration |
||
1445 | + *msm_bus_of_to_pdata(struct platform_device *pdev); |
||
1446 | +extern void msm_bus_arb_setops_adhoc(struct msm_bus_arb_ops *arb_ops); |
||
1447 | +extern int msm_bus_bimc_set_ops(struct msm_bus_node_device_type *bus_dev); |
||
1448 | +extern int msm_bus_noc_set_ops(struct msm_bus_node_device_type *bus_dev); |
||
1449 | +extern int msm_bus_of_get_static_rules(struct platform_device *pdev, |
||
1450 | + struct bus_rule_type **static_rule); |
||
1451 | +extern int msm_rules_update_path(struct list_head *input_list, |
||
1452 | + struct list_head *output_list); |
||
1453 | +extern void print_all_rules(void); |
||
1454 | +#endif /* _ARCH_ARM_MACH_MSM_BUS_ADHOC_H */ |
||
1455 | --- /dev/null |
||
1456 | +++ b/drivers/bus/msm_bus/msm_bus_arb_adhoc.c |
||
1457 | @@ -0,0 +1,998 @@ |
||
1458 | +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. |
||
1459 | + * |
||
1460 | + * This program is Mree software; you can redistribute it and/or modify |
||
1461 | + * it under the terms of the GNU General Public License version 2 and |
||
1462 | + * only version 2 as published by the Free Software Foundation. |
||
1463 | + * |
||
1464 | + * This program is distributed in the hope that it will be useful, |
||
1465 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
1466 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
1467 | + * GNU General Public License for more details. |
||
1468 | + */ |
||
1469 | +#include <linux/kernel.h> |
||
1470 | +#include <linux/init.h> |
||
1471 | +#include <linux/list.h> |
||
1472 | +#include <linux/module.h> |
||
1473 | +#include <linux/slab.h> |
||
1474 | +#include <linux/mutex.h> |
||
1475 | +#include <linux/clk.h> |
||
1476 | +#include "msm-bus.h" |
||
1477 | +#include "msm_bus_core.h" |
||
1478 | +#include "msm_bus_adhoc.h" |
||
1479 | + |
||
1480 | +#define NUM_CL_HANDLES 50 |
||
1481 | +#define NUM_LNODES 3 |
||
1482 | + |
||
1483 | +struct bus_search_type { |
||
1484 | + struct list_head link; |
||
1485 | + struct list_head node_list; |
||
1486 | +}; |
||
1487 | + |
||
1488 | +struct handle_type { |
||
1489 | + int num_entries; |
||
1490 | + struct msm_bus_client **cl_list; |
||
1491 | +}; |
||
1492 | + |
||
1493 | +static struct handle_type handle_list; |
||
1494 | +struct list_head input_list; |
||
1495 | +struct list_head apply_list; |
||
1496 | + |
||
1497 | +DEFINE_MUTEX(msm_bus_adhoc_lock); |
||
1498 | + |
||
1499 | +static bool chk_bl_list(struct list_head *black_list, unsigned int id) |
||
1500 | +{ |
||
1501 | + struct msm_bus_node_device_type *bus_node = NULL; |
||
1502 | + |
||
1503 | + list_for_each_entry(bus_node, black_list, link) { |
||
1504 | + if (bus_node->node_info->id == id) |
||
1505 | + return true; |
||
1506 | + } |
||
1507 | + return false; |
||
1508 | +} |
||
1509 | + |
||
1510 | +static void copy_remaining_nodes(struct list_head *edge_list, struct list_head |
||
1511 | + *traverse_list, struct list_head *route_list) |
||
1512 | +{ |
||
1513 | + struct bus_search_type *search_node; |
||
1514 | + |
||
1515 | + if (list_empty(edge_list) && list_empty(traverse_list)) |
||
1516 | + return; |
||
1517 | + |
||
1518 | + search_node = kzalloc(sizeof(struct bus_search_type), GFP_KERNEL); |
||
1519 | + INIT_LIST_HEAD(&search_node->node_list); |
||
1520 | + list_splice_init(edge_list, traverse_list); |
||
1521 | + list_splice_init(traverse_list, &search_node->node_list); |
||
1522 | + list_add_tail(&search_node->link, route_list); |
||
1523 | +} |
||
1524 | + |
||
1525 | +/* |
||
1526 | + * Duplicate instantiaion from msm_bus_arb.c. Todo there needs to be a |
||
1527 | + * "util" file for these common func/macros. |
||
1528 | + * |
||
1529 | + * */ |
||
1530 | +uint64_t msm_bus_div64(unsigned int w, uint64_t bw) |
||
1531 | +{ |
||
1532 | + uint64_t *b = &bw; |
||
1533 | + |
||
1534 | + if ((bw > 0) && (bw < w)) |
||
1535 | + return 1; |
||
1536 | + |
||
1537 | + switch (w) { |
||
1538 | + case 0: |
||
1539 | + WARN(1, "AXI: Divide by 0 attempted\n"); |
||
1540 | + case 1: return bw; |
||
1541 | + case 2: return (bw >> 1); |
||
1542 | + case 4: return (bw >> 2); |
||
1543 | + case 8: return (bw >> 3); |
||
1544 | + case 16: return (bw >> 4); |
||
1545 | + case 32: return (bw >> 5); |
||
1546 | + } |
||
1547 | + |
||
1548 | + do_div(*b, w); |
||
1549 | + return *b; |
||
1550 | +} |
||
1551 | + |
||
1552 | +int msm_bus_device_match_adhoc(struct device *dev, void *id) |
||
1553 | +{ |
||
1554 | + int ret = 0; |
||
1555 | + struct msm_bus_node_device_type *bnode = dev->platform_data; |
||
1556 | + |
||
1557 | + if (bnode) |
||
1558 | + ret = (bnode->node_info->id == *(unsigned int *)id); |
||
1559 | + else |
||
1560 | + ret = 0; |
||
1561 | + |
||
1562 | + return ret; |
||
1563 | +} |
||
1564 | + |
||
1565 | +static int gen_lnode(struct device *dev, |
||
1566 | + int next_hop, int prev_idx) |
||
1567 | +{ |
||
1568 | + struct link_node *lnode; |
||
1569 | + struct msm_bus_node_device_type *cur_dev = NULL; |
||
1570 | + int lnode_idx = -1; |
||
1571 | + |
||
1572 | + if (!dev) |
||
1573 | + goto exit_gen_lnode; |
||
1574 | + |
||
1575 | + cur_dev = dev->platform_data; |
||
1576 | + if (!cur_dev) { |
||
1577 | + MSM_BUS_ERR("%s: Null device ptr", __func__); |
||
1578 | + goto exit_gen_lnode; |
||
1579 | + } |
||
1580 | + |
||
1581 | + if (!cur_dev->num_lnodes) { |
||
1582 | + cur_dev->lnode_list = devm_kzalloc(dev, |
||
1583 | + sizeof(struct link_node) * NUM_LNODES, |
||
1584 | + GFP_KERNEL); |
||
1585 | + if (!cur_dev->lnode_list) |
||
1586 | + goto exit_gen_lnode; |
||
1587 | + |
||
1588 | + lnode = cur_dev->lnode_list; |
||
1589 | + cur_dev->num_lnodes = NUM_LNODES; |
||
1590 | + lnode_idx = 0; |
||
1591 | + } else { |
||
1592 | + int i; |
||
1593 | + for (i = 0; i < cur_dev->num_lnodes; i++) { |
||
1594 | + if (!cur_dev->lnode_list[i].in_use) |
||
1595 | + break; |
||
1596 | + } |
||
1597 | + |
||
1598 | + if (i < cur_dev->num_lnodes) { |
||
1599 | + lnode = &cur_dev->lnode_list[i]; |
||
1600 | + lnode_idx = i; |
||
1601 | + } else { |
||
1602 | + struct link_node *realloc_list; |
||
1603 | + size_t cur_size = sizeof(struct link_node) * |
||
1604 | + cur_dev->num_lnodes; |
||
1605 | + |
||
1606 | + cur_dev->num_lnodes += NUM_LNODES; |
||
1607 | + realloc_list = msm_bus_realloc_devmem( |
||
1608 | + dev, |
||
1609 | + cur_dev->lnode_list, |
||
1610 | + cur_size, |
||
1611 | + sizeof(struct link_node) * |
||
1612 | + cur_dev->num_lnodes, GFP_KERNEL); |
||
1613 | + |
||
1614 | + if (!realloc_list) |
||
1615 | + goto exit_gen_lnode; |
||
1616 | + |
||
1617 | + cur_dev->lnode_list = realloc_list; |
||
1618 | + lnode = &cur_dev->lnode_list[i]; |
||
1619 | + lnode_idx = i; |
||
1620 | + } |
||
1621 | + } |
||
1622 | + |
||
1623 | + lnode->in_use = 1; |
||
1624 | + if (next_hop == cur_dev->node_info->id) { |
||
1625 | + lnode->next = -1; |
||
1626 | + lnode->next_dev = NULL; |
||
1627 | + } else { |
||
1628 | + lnode->next = prev_idx; |
||
1629 | + lnode->next_dev = bus_find_device(&msm_bus_type, NULL, |
||
1630 | + (void *) &next_hop, |
||
1631 | + msm_bus_device_match_adhoc); |
||
1632 | + } |
||
1633 | + |
||
1634 | + memset(lnode->lnode_ib, 0, sizeof(uint64_t) * NUM_CTX); |
||
1635 | + memset(lnode->lnode_ab, 0, sizeof(uint64_t) * NUM_CTX); |
||
1636 | + |
||
1637 | +exit_gen_lnode: |
||
1638 | + return lnode_idx; |
||
1639 | +} |
||
1640 | + |
||
1641 | +static int remove_lnode(struct msm_bus_node_device_type *cur_dev, |
||
1642 | + int lnode_idx) |
||
1643 | +{ |
||
1644 | + int ret = 0; |
||
1645 | + |
||
1646 | + if (!cur_dev) { |
||
1647 | + MSM_BUS_ERR("%s: Null device ptr", __func__); |
||
1648 | + ret = -ENODEV; |
||
1649 | + goto exit_remove_lnode; |
||
1650 | + } |
||
1651 | + |
||
1652 | + if (lnode_idx != -1) { |
||
1653 | + if (!cur_dev->num_lnodes || |
||
1654 | + (lnode_idx > (cur_dev->num_lnodes - 1))) { |
||
1655 | + MSM_BUS_ERR("%s: Invalid Idx %d, num_lnodes %d", |
||
1656 | + __func__, lnode_idx, cur_dev->num_lnodes); |
||
1657 | + ret = -ENODEV; |
||
1658 | + goto exit_remove_lnode; |
||
1659 | + } |
||
1660 | + |
||
1661 | + cur_dev->lnode_list[lnode_idx].next = -1; |
||
1662 | + cur_dev->lnode_list[lnode_idx].next_dev = NULL; |
||
1663 | + cur_dev->lnode_list[lnode_idx].in_use = 0; |
||
1664 | + } |
||
1665 | + |
||
1666 | +exit_remove_lnode: |
||
1667 | + return ret; |
||
1668 | +} |
||
1669 | + |
||
1670 | +static int prune_path(struct list_head *route_list, int dest, int src, |
||
1671 | + struct list_head *black_list, int found) |
||
1672 | +{ |
||
1673 | + struct bus_search_type *search_node, *temp_search_node; |
||
1674 | + struct msm_bus_node_device_type *bus_node; |
||
1675 | + struct list_head *bl_list; |
||
1676 | + struct list_head *temp_bl_list; |
||
1677 | + int search_dev_id = dest; |
||
1678 | + struct device *dest_dev = bus_find_device(&msm_bus_type, NULL, |
||
1679 | + (void *) &dest, |
||
1680 | + msm_bus_device_match_adhoc); |
||
1681 | + int lnode_hop = -1; |
||
1682 | + |
||
1683 | + if (!found) |
||
1684 | + goto reset_links; |
||
1685 | + |
||
1686 | + if (!dest_dev) { |
||
1687 | + MSM_BUS_ERR("%s: Can't find dest dev %d", __func__, dest); |
||
1688 | + goto exit_prune_path; |
||
1689 | + } |
||
1690 | + |
||
1691 | + lnode_hop = gen_lnode(dest_dev, search_dev_id, lnode_hop); |
||
1692 | + |
||
1693 | + list_for_each_entry_reverse(search_node, route_list, link) { |
||
1694 | + list_for_each_entry(bus_node, &search_node->node_list, link) { |
||
1695 | + unsigned int i; |
||
1696 | + for (i = 0; i < bus_node->node_info->num_connections; |
||
1697 | + i++) { |
||
1698 | + if (bus_node->node_info->connections[i] == |
||
1699 | + search_dev_id) { |
||
1700 | + dest_dev = bus_find_device( |
||
1701 | + &msm_bus_type, |
||
1702 | + NULL, |
||
1703 | + (void *) |
||
1704 | + &bus_node->node_info-> |
||
1705 | + id, |
||
1706 | + msm_bus_device_match_adhoc); |
||
1707 | + |
||
1708 | + if (!dest_dev) { |
||
1709 | + lnode_hop = -1; |
||
1710 | + goto reset_links; |
||
1711 | + } |
||
1712 | + |
||
1713 | + lnode_hop = gen_lnode(dest_dev, |
||
1714 | + search_dev_id, |
||
1715 | + lnode_hop); |
||
1716 | + search_dev_id = |
||
1717 | + bus_node->node_info->id; |
||
1718 | + break; |
||
1719 | + } |
||
1720 | + } |
||
1721 | + } |
||
1722 | + } |
||
1723 | +reset_links: |
||
1724 | + list_for_each_entry_safe(search_node, temp_search_node, route_list, |
||
1725 | + link) { |
||
1726 | + list_for_each_entry(bus_node, &search_node->node_list, |
||
1727 | + link) |
||
1728 | + bus_node->node_info->is_traversed = false; |
||
1729 | + |
||
1730 | + list_del(&search_node->link); |
||
1731 | + kfree(search_node); |
||
1732 | + } |
||
1733 | + |
||
1734 | + list_for_each_safe(bl_list, temp_bl_list, black_list) |
||
1735 | + list_del(bl_list); |
||
1736 | + |
||
1737 | +exit_prune_path: |
||
1738 | + return lnode_hop; |
||
1739 | +} |
||
1740 | + |
||
1741 | +static void setup_bl_list(struct msm_bus_node_device_type *node, |
||
1742 | + struct list_head *black_list) |
||
1743 | +{ |
||
1744 | + unsigned int i; |
||
1745 | + |
||
1746 | + for (i = 0; i < node->node_info->num_blist; i++) { |
||
1747 | + struct msm_bus_node_device_type *bdev; |
||
1748 | + bdev = node->node_info->black_connections[i]->platform_data; |
||
1749 | + list_add_tail(&bdev->link, black_list); |
||
1750 | + } |
||
1751 | +} |
||
1752 | + |
||
1753 | +static int getpath(int src, int dest) |
||
1754 | +{ |
||
1755 | + struct list_head traverse_list; |
||
1756 | + struct list_head edge_list; |
||
1757 | + struct list_head route_list; |
||
1758 | + struct list_head black_list; |
||
1759 | + struct device *src_dev = bus_find_device(&msm_bus_type, NULL, |
||
1760 | + (void *) &src, |
||
1761 | + msm_bus_device_match_adhoc); |
||
1762 | + struct msm_bus_node_device_type *src_node; |
||
1763 | + struct bus_search_type *search_node; |
||
1764 | + int found = 0; |
||
1765 | + int depth_index = 0; |
||
1766 | + int first_hop = -1; |
||
1767 | + |
||
1768 | + INIT_LIST_HEAD(&traverse_list); |
||
1769 | + INIT_LIST_HEAD(&edge_list); |
||
1770 | + INIT_LIST_HEAD(&route_list); |
||
1771 | + INIT_LIST_HEAD(&black_list); |
||
1772 | + |
||
1773 | + if (!src_dev) { |
||
1774 | + MSM_BUS_ERR("%s: Cannot locate src dev %d", __func__, src); |
||
1775 | + goto exit_getpath; |
||
1776 | + } |
||
1777 | + |
||
1778 | + src_node = src_dev->platform_data; |
||
1779 | + if (!src_node) { |
||
1780 | + MSM_BUS_ERR("%s:Fatal, Source dev %d not found", __func__, src); |
||
1781 | + goto exit_getpath; |
||
1782 | + } |
||
1783 | + list_add_tail(&src_node->link, &traverse_list); |
||
1784 | + |
||
1785 | + while ((!found && !list_empty(&traverse_list))) { |
||
1786 | + struct msm_bus_node_device_type *bus_node = NULL; |
||
1787 | + /* Locate dest_id in the traverse list */ |
||
1788 | + list_for_each_entry(bus_node, &traverse_list, link) { |
||
1789 | + if (bus_node->node_info->id == dest) { |
||
1790 | + found = 1; |
||
1791 | + break; |
||
1792 | + } |
||
1793 | + } |
||
1794 | + |
||
1795 | + if (!found) { |
||
1796 | + unsigned int i; |
||
1797 | + /* Setup the new edge list */ |
||
1798 | + list_for_each_entry(bus_node, &traverse_list, link) { |
||
1799 | + /* Setup list of black-listed nodes */ |
||
1800 | + setup_bl_list(bus_node, &black_list); |
||
1801 | + |
||
1802 | + for (i = 0; i < bus_node->node_info-> |
||
1803 | + num_connections; i++) { |
||
1804 | + bool skip; |
||
1805 | + struct msm_bus_node_device_type |
||
1806 | + *node_conn; |
||
1807 | + node_conn = bus_node->node_info-> |
||
1808 | + dev_connections[i]-> |
||
1809 | + platform_data; |
||
1810 | + if (node_conn->node_info-> |
||
1811 | + is_traversed) { |
||
1812 | + MSM_BUS_ERR("Circ Path %d\n", |
||
1813 | + node_conn->node_info->id); |
||
1814 | + goto reset_traversed; |
||
1815 | + } |
||
1816 | + skip = chk_bl_list(&black_list, |
||
1817 | + bus_node->node_info-> |
||
1818 | + connections[i]); |
||
1819 | + if (!skip) { |
||
1820 | + list_add_tail(&node_conn->link, |
||
1821 | + &edge_list); |
||
1822 | + node_conn->node_info-> |
||
1823 | + is_traversed = true; |
||
1824 | + } |
||
1825 | + } |
||
1826 | + } |
||
1827 | + |
||
1828 | + /* Keep tabs of the previous search list */ |
||
1829 | + search_node = kzalloc(sizeof(struct bus_search_type), |
||
1830 | + GFP_KERNEL); |
||
1831 | + INIT_LIST_HEAD(&search_node->node_list); |
||
1832 | + list_splice_init(&traverse_list, |
||
1833 | + &search_node->node_list); |
||
1834 | + /* Add the previous search list to a route list */ |
||
1835 | + list_add_tail(&search_node->link, &route_list); |
||
1836 | + /* Advancing the list depth */ |
||
1837 | + depth_index++; |
||
1838 | + list_splice_init(&edge_list, &traverse_list); |
||
1839 | + } |
||
1840 | + } |
||
1841 | +reset_traversed: |
||
1842 | + copy_remaining_nodes(&edge_list, &traverse_list, &route_list); |
||
1843 | + first_hop = prune_path(&route_list, dest, src, &black_list, found); |
||
1844 | + |
||
1845 | +exit_getpath: |
||
1846 | + return first_hop; |
||
1847 | +} |
||
1848 | + |
||
1849 | +static uint64_t arbitrate_bus_req(struct msm_bus_node_device_type *bus_dev, |
||
1850 | + int ctx) |
||
1851 | +{ |
||
1852 | + int i; |
||
1853 | + uint64_t max_ib = 0; |
||
1854 | + uint64_t sum_ab = 0; |
||
1855 | + uint64_t bw_max_hz; |
||
1856 | + struct msm_bus_node_device_type *fab_dev = NULL; |
||
1857 | + uint32_t util_fact = 0; |
||
1858 | + uint32_t vrail_comp = 0; |
||
1859 | + |
||
1860 | + /* Find max ib */ |
||
1861 | + for (i = 0; i < bus_dev->num_lnodes; i++) { |
||
1862 | + max_ib = max(max_ib, bus_dev->lnode_list[i].lnode_ib[ctx]); |
||
1863 | + sum_ab += bus_dev->lnode_list[i].lnode_ab[ctx]; |
||
1864 | + } |
||
1865 | + /* |
||
1866 | + * Account for Util factor and vrail comp. The new aggregation |
||
1867 | + * formula is: |
||
1868 | + * Freq_hz = max((sum(ab) * util_fact)/num_chan, max(ib)/vrail_comp) |
||
1869 | + * / bus-width |
||
1870 | + * util_fact and vrail comp are obtained from fabric/Node's dts |
||
1871 | + * properties. |
||
1872 | + * They default to 100 if absent. |
||
1873 | + */ |
||
1874 | + fab_dev = bus_dev->node_info->bus_device->platform_data; |
||
1875 | + /* Don't do this for virtual fabrics */ |
||
1876 | + if (fab_dev && fab_dev->fabdev) { |
||
1877 | + util_fact = bus_dev->node_info->util_fact ? |
||
1878 | + bus_dev->node_info->util_fact : |
||
1879 | + fab_dev->fabdev->util_fact; |
||
1880 | + vrail_comp = bus_dev->node_info->vrail_comp ? |
||
1881 | + bus_dev->node_info->vrail_comp : |
||
1882 | + fab_dev->fabdev->vrail_comp; |
||
1883 | + sum_ab *= util_fact; |
||
1884 | + sum_ab = msm_bus_div64(100, sum_ab); |
||
1885 | + max_ib *= 100; |
||
1886 | + max_ib = msm_bus_div64(vrail_comp, max_ib); |
||
1887 | + } |
||
1888 | + |
||
1889 | + /* Account for multiple channels if any */ |
||
1890 | + if (bus_dev->node_info->num_qports > 1) |
||
1891 | + sum_ab = msm_bus_div64(bus_dev->node_info->num_qports, |
||
1892 | + sum_ab); |
||
1893 | + |
||
1894 | + if (!bus_dev->node_info->buswidth) { |
||
1895 | + MSM_BUS_WARN("No bus width found for %d. Using default\n", |
||
1896 | + bus_dev->node_info->id); |
||
1897 | + bus_dev->node_info->buswidth = 8; |
||
1898 | + } |
||
1899 | + |
||
1900 | + bw_max_hz = max(max_ib, sum_ab); |
||
1901 | + bw_max_hz = msm_bus_div64(bus_dev->node_info->buswidth, |
||
1902 | + bw_max_hz); |
||
1903 | + |
||
1904 | + return bw_max_hz; |
||
1905 | +} |
||
1906 | + |
||
1907 | +static void del_inp_list(struct list_head *list) |
||
1908 | +{ |
||
1909 | + struct rule_update_path_info *rule_node; |
||
1910 | + struct rule_update_path_info *rule_node_tmp; |
||
1911 | + |
||
1912 | + list_for_each_entry_safe(rule_node, rule_node_tmp, list, link) |
||
1913 | + list_del(&rule_node->link); |
||
1914 | +} |
||
1915 | + |
||
1916 | +static void del_op_list(struct list_head *list) |
||
1917 | +{ |
||
1918 | + struct rule_apply_rcm_info *rule; |
||
1919 | + struct rule_apply_rcm_info *rule_tmp; |
||
1920 | + |
||
1921 | + list_for_each_entry_safe(rule, rule_tmp, list, link) |
||
1922 | + list_del(&rule->link); |
||
1923 | +} |
||
1924 | + |
||
1925 | +static int msm_bus_apply_rules(struct list_head *list, bool after_clk_commit) |
||
1926 | +{ |
||
1927 | + struct rule_apply_rcm_info *rule; |
||
1928 | + struct device *dev = NULL; |
||
1929 | + struct msm_bus_node_device_type *dev_info = NULL; |
||
1930 | + int ret = 0; |
||
1931 | + bool throttle_en = false; |
||
1932 | + |
||
1933 | + list_for_each_entry(rule, list, link) { |
||
1934 | + if (!rule) |
||
1935 | + break; |
||
1936 | + |
||
1937 | + if (rule && (rule->after_clk_commit != after_clk_commit)) |
||
1938 | + continue; |
||
1939 | + |
||
1940 | + dev = bus_find_device(&msm_bus_type, NULL, |
||
1941 | + (void *) &rule->id, |
||
1942 | + msm_bus_device_match_adhoc); |
||
1943 | + |
||
1944 | + if (!dev) { |
||
1945 | + MSM_BUS_ERR("Can't find dev node for %d", rule->id); |
||
1946 | + continue; |
||
1947 | + } |
||
1948 | + dev_info = dev->platform_data; |
||
1949 | + |
||
1950 | + throttle_en = ((rule->throttle == THROTTLE_ON) ? true : false); |
||
1951 | + ret = msm_bus_enable_limiter(dev_info, throttle_en, |
||
1952 | + rule->lim_bw); |
||
1953 | + if (ret) |
||
1954 | + MSM_BUS_ERR("Failed to set limiter for %d", rule->id); |
||
1955 | + } |
||
1956 | + |
||
1957 | + return ret; |
||
1958 | +} |
||
1959 | + |
||
1960 | +static uint64_t get_node_aggab(struct msm_bus_node_device_type *bus_dev) |
||
1961 | +{ |
||
1962 | + int i; |
||
1963 | + int ctx; |
||
1964 | + uint64_t max_agg_ab = 0; |
||
1965 | + uint64_t agg_ab = 0; |
||
1966 | + |
||
1967 | + for (ctx = 0; ctx < NUM_CTX; ctx++) { |
||
1968 | + for (i = 0; i < bus_dev->num_lnodes; i++) |
||
1969 | + agg_ab += bus_dev->lnode_list[i].lnode_ab[ctx]; |
||
1970 | + |
||
1971 | + if (bus_dev->node_info->num_qports > 1) |
||
1972 | + agg_ab = msm_bus_div64(bus_dev->node_info->num_qports, |
||
1973 | + agg_ab); |
||
1974 | + |
||
1975 | + max_agg_ab = max(max_agg_ab, agg_ab); |
||
1976 | + } |
||
1977 | + |
||
1978 | + return max_agg_ab; |
||
1979 | +} |
||
1980 | + |
||
1981 | +static uint64_t get_node_ib(struct msm_bus_node_device_type *bus_dev) |
||
1982 | +{ |
||
1983 | + int i; |
||
1984 | + int ctx; |
||
1985 | + uint64_t max_ib = 0; |
||
1986 | + |
||
1987 | + for (ctx = 0; ctx < NUM_CTX; ctx++) { |
||
1988 | + for (i = 0; i < bus_dev->num_lnodes; i++) |
||
1989 | + max_ib = max(max_ib, |
||
1990 | + bus_dev->lnode_list[i].lnode_ib[ctx]); |
||
1991 | + } |
||
1992 | + return max_ib; |
||
1993 | +} |
||
1994 | + |
||
1995 | +static int update_path(int src, int dest, uint64_t req_ib, uint64_t req_bw, |
||
1996 | + uint64_t cur_ib, uint64_t cur_bw, int src_idx, int ctx) |
||
1997 | +{ |
||
1998 | + struct device *src_dev = NULL; |
||
1999 | + struct device *next_dev = NULL; |
||
2000 | + struct link_node *lnode = NULL; |
||
2001 | + struct msm_bus_node_device_type *dev_info = NULL; |
||
2002 | + int curr_idx; |
||
2003 | + int ret = 0; |
||
2004 | + int *dirty_nodes = NULL; |
||
2005 | + int num_dirty = 0; |
||
2006 | + struct rule_update_path_info *rule_node; |
||
2007 | + bool rules_registered = msm_rule_are_rules_registered(); |
||
2008 | + |
||
2009 | + src_dev = bus_find_device(&msm_bus_type, NULL, |
||
2010 | + (void *) &src, |
||
2011 | + msm_bus_device_match_adhoc); |
||
2012 | + |
||
2013 | + if (!src_dev) { |
||
2014 | + MSM_BUS_ERR("%s: Can't find source device %d", __func__, src); |
||
2015 | + ret = -ENODEV; |
||
2016 | + goto exit_update_path; |
||
2017 | + } |
||
2018 | + |
||
2019 | + next_dev = src_dev; |
||
2020 | + |
||
2021 | + if (src_idx < 0) { |
||
2022 | + MSM_BUS_ERR("%s: Invalid lnode idx %d", __func__, src_idx); |
||
2023 | + ret = -ENXIO; |
||
2024 | + goto exit_update_path; |
||
2025 | + } |
||
2026 | + curr_idx = src_idx; |
||
2027 | + |
||
2028 | + INIT_LIST_HEAD(&input_list); |
||
2029 | + INIT_LIST_HEAD(&apply_list); |
||
2030 | + |
||
2031 | + while (next_dev) { |
||
2032 | + dev_info = next_dev->platform_data; |
||
2033 | + |
||
2034 | + if (curr_idx >= dev_info->num_lnodes) { |
||
2035 | + MSM_BUS_ERR("%s: Invalid lnode Idx %d num lnodes %d", |
||
2036 | + __func__, curr_idx, dev_info->num_lnodes); |
||
2037 | + ret = -ENXIO; |
||
2038 | + goto exit_update_path; |
||
2039 | + } |
||
2040 | + |
||
2041 | + lnode = &dev_info->lnode_list[curr_idx]; |
||
2042 | + lnode->lnode_ib[ctx] = req_ib; |
||
2043 | + lnode->lnode_ab[ctx] = req_bw; |
||
2044 | + |
||
2045 | + dev_info->cur_clk_hz[ctx] = arbitrate_bus_req(dev_info, ctx); |
||
2046 | + |
||
2047 | + /* Start updating the clocks at the first hop. |
||
2048 | + * Its ok to figure out the aggregated |
||
2049 | + * request at this node. |
||
2050 | + */ |
||
2051 | + if (src_dev != next_dev) { |
||
2052 | + ret = msm_bus_update_clks(dev_info, ctx, &dirty_nodes, |
||
2053 | + &num_dirty); |
||
2054 | + if (ret) { |
||
2055 | + MSM_BUS_ERR("%s: Failed to update clks dev %d", |
||
2056 | + __func__, dev_info->node_info->id); |
||
2057 | + goto exit_update_path; |
||
2058 | + } |
||
2059 | + } |
||
2060 | + |
||
2061 | + ret = msm_bus_update_bw(dev_info, ctx, req_bw, &dirty_nodes, |
||
2062 | + &num_dirty); |
||
2063 | + if (ret) { |
||
2064 | + MSM_BUS_ERR("%s: Failed to update bw dev %d", |
||
2065 | + __func__, dev_info->node_info->id); |
||
2066 | + goto exit_update_path; |
||
2067 | + } |
||
2068 | + |
||
2069 | + if (rules_registered) { |
||
2070 | + rule_node = &dev_info->node_info->rule; |
||
2071 | + rule_node->id = dev_info->node_info->id; |
||
2072 | + rule_node->ib = get_node_ib(dev_info); |
||
2073 | + rule_node->ab = get_node_aggab(dev_info); |
||
2074 | + rule_node->clk = max(dev_info->cur_clk_hz[ACTIVE_CTX], |
||
2075 | + dev_info->cur_clk_hz[DUAL_CTX]); |
||
2076 | + list_add_tail(&rule_node->link, &input_list); |
||
2077 | + } |
||
2078 | + |
||
2079 | + next_dev = lnode->next_dev; |
||
2080 | + curr_idx = lnode->next; |
||
2081 | + } |
||
2082 | + |
||
2083 | + if (rules_registered) { |
||
2084 | + msm_rules_update_path(&input_list, &apply_list); |
||
2085 | + msm_bus_apply_rules(&apply_list, false); |
||
2086 | + } |
||
2087 | + |
||
2088 | + msm_bus_commit_data(dirty_nodes, ctx, num_dirty); |
||
2089 | + |
||
2090 | + if (rules_registered) { |
||
2091 | + msm_bus_apply_rules(&apply_list, true); |
||
2092 | + del_inp_list(&input_list); |
||
2093 | + del_op_list(&apply_list); |
||
2094 | + } |
||
2095 | +exit_update_path: |
||
2096 | + return ret; |
||
2097 | +} |
||
2098 | + |
||
2099 | +static int remove_path(int src, int dst, uint64_t cur_ib, uint64_t cur_ab, |
||
2100 | + int src_idx, int active_only) |
||
2101 | +{ |
||
2102 | + struct device *src_dev = NULL; |
||
2103 | + struct device *next_dev = NULL; |
||
2104 | + struct link_node *lnode = NULL; |
||
2105 | + struct msm_bus_node_device_type *dev_info = NULL; |
||
2106 | + int ret = 0; |
||
2107 | + int cur_idx = src_idx; |
||
2108 | + int next_idx; |
||
2109 | + |
||
2110 | + /* Update the current path to zero out all request from |
||
2111 | + * this cient on all paths |
||
2112 | + */ |
||
2113 | + |
||
2114 | + ret = update_path(src, dst, 0, 0, cur_ib, cur_ab, src_idx, |
||
2115 | + active_only); |
||
2116 | + if (ret) { |
||
2117 | + MSM_BUS_ERR("%s: Error zeroing out path ctx %d", |
||
2118 | + __func__, ACTIVE_CTX); |
||
2119 | + goto exit_remove_path; |
||
2120 | + } |
||
2121 | + |
||
2122 | + src_dev = bus_find_device(&msm_bus_type, NULL, |
||
2123 | + (void *) &src, |
||
2124 | + msm_bus_device_match_adhoc); |
||
2125 | + if (!src_dev) { |
||
2126 | + MSM_BUS_ERR("%s: Can't find source device %d", __func__, src); |
||
2127 | + ret = -ENODEV; |
||
2128 | + goto exit_remove_path; |
||
2129 | + } |
||
2130 | + |
||
2131 | + next_dev = src_dev; |
||
2132 | + |
||
2133 | + while (next_dev) { |
||
2134 | + dev_info = next_dev->platform_data; |
||
2135 | + lnode = &dev_info->lnode_list[cur_idx]; |
||
2136 | + next_idx = lnode->next; |
||
2137 | + next_dev = lnode->next_dev; |
||
2138 | + remove_lnode(dev_info, cur_idx); |
||
2139 | + cur_idx = next_idx; |
||
2140 | + } |
||
2141 | + |
||
2142 | +exit_remove_path: |
||
2143 | + return ret; |
||
2144 | +} |
||
2145 | + |
||
2146 | +static void getpath_debug(int src, int curr, int active_only) |
||
2147 | +{ |
||
2148 | + struct device *dev_node; |
||
2149 | + struct device *dev_it; |
||
2150 | + unsigned int hop = 1; |
||
2151 | + int idx; |
||
2152 | + struct msm_bus_node_device_type *devinfo; |
||
2153 | + int i; |
||
2154 | + |
||
2155 | + dev_node = bus_find_device(&msm_bus_type, NULL, |
||
2156 | + (void *) &src, |
||
2157 | + msm_bus_device_match_adhoc); |
||
2158 | + |
||
2159 | + if (!dev_node) { |
||
2160 | + MSM_BUS_ERR("SRC NOT FOUND %d", src); |
||
2161 | + return; |
||
2162 | + } |
||
2163 | + |
||
2164 | + idx = curr; |
||
2165 | + devinfo = dev_node->platform_data; |
||
2166 | + dev_it = dev_node; |
||
2167 | + |
||
2168 | + MSM_BUS_ERR("Route list Src %d", src); |
||
2169 | + while (dev_it) { |
||
2170 | + struct msm_bus_node_device_type *busdev = |
||
2171 | + devinfo->node_info->bus_device->platform_data; |
||
2172 | + |
||
2173 | + MSM_BUS_ERR("Hop[%d] at Device %d ctx %d", hop, |
||
2174 | + devinfo->node_info->id, active_only); |
||
2175 | + |
||
2176 | + for (i = 0; i < NUM_CTX; i++) { |
||
2177 | + MSM_BUS_ERR("dev info sel ib %llu", |
||
2178 | + devinfo->cur_clk_hz[i]); |
||
2179 | + MSM_BUS_ERR("dev info sel ab %llu", |
||
2180 | + devinfo->node_ab.ab[i]); |
||
2181 | + } |
||
2182 | + |
||
2183 | + dev_it = devinfo->lnode_list[idx].next_dev; |
||
2184 | + idx = devinfo->lnode_list[idx].next; |
||
2185 | + if (dev_it) |
||
2186 | + devinfo = dev_it->platform_data; |
||
2187 | + |
||
2188 | + MSM_BUS_ERR("Bus Device %d", busdev->node_info->id); |
||
2189 | + MSM_BUS_ERR("Bus Clock %llu", busdev->clk[active_only].rate); |
||
2190 | + |
||
2191 | + if (idx < 0) |
||
2192 | + break; |
||
2193 | + hop++; |
||
2194 | + } |
||
2195 | +} |
||
2196 | + |
||
2197 | +static void unregister_client_adhoc(uint32_t cl) |
||
2198 | +{ |
||
2199 | + int i; |
||
2200 | + struct msm_bus_scale_pdata *pdata; |
||
2201 | + int lnode, src, curr, dest; |
||
2202 | + uint64_t cur_clk, cur_bw; |
||
2203 | + struct msm_bus_client *client; |
||
2204 | + |
||
2205 | + mutex_lock(&msm_bus_adhoc_lock); |
||
2206 | + if (!cl) { |
||
2207 | + MSM_BUS_ERR("%s: Null cl handle passed unregister\n", |
||
2208 | + __func__); |
||
2209 | + goto exit_unregister_client; |
||
2210 | + } |
||
2211 | + client = handle_list.cl_list[cl]; |
||
2212 | + pdata = client->pdata; |
||
2213 | + if (!pdata) { |
||
2214 | + MSM_BUS_ERR("%s: Null pdata passed to unregister\n", |
||
2215 | + __func__); |
||
2216 | + goto exit_unregister_client; |
||
2217 | + } |
||
2218 | + |
||
2219 | + curr = client->curr; |
||
2220 | + if (curr >= pdata->num_usecases) { |
||
2221 | + MSM_BUS_ERR("Invalid index Defaulting curr to 0"); |
||
2222 | + curr = 0; |
||
2223 | + } |
||
2224 | + |
||
2225 | + MSM_BUS_DBG("%s: Unregistering client %p", __func__, client); |
||
2226 | + |
||
2227 | + for (i = 0; i < pdata->usecase->num_paths; i++) { |
||
2228 | + src = client->pdata->usecase[curr].vectors[i].src; |
||
2229 | + dest = client->pdata->usecase[curr].vectors[i].dst; |
||
2230 | + |
||
2231 | + lnode = client->src_pnode[i]; |
||
2232 | + cur_clk = client->pdata->usecase[curr].vectors[i].ib; |
||
2233 | + cur_bw = client->pdata->usecase[curr].vectors[i].ab; |
||
2234 | + remove_path(src, dest, cur_clk, cur_bw, lnode, |
||
2235 | + pdata->active_only); |
||
2236 | + } |
||
2237 | + msm_bus_dbg_client_data(client->pdata, MSM_BUS_DBG_UNREGISTER, cl); |
||
2238 | + kfree(client->src_pnode); |
||
2239 | + kfree(client); |
||
2240 | + handle_list.cl_list[cl] = NULL; |
||
2241 | +exit_unregister_client: |
||
2242 | + mutex_unlock(&msm_bus_adhoc_lock); |
||
2243 | + return; |
||
2244 | +} |
||
2245 | + |
||
2246 | +static int alloc_handle_lst(int size) |
||
2247 | +{ |
||
2248 | + int ret = 0; |
||
2249 | + struct msm_bus_client **t_cl_list; |
||
2250 | + |
||
2251 | + if (!handle_list.num_entries) { |
||
2252 | + t_cl_list = kzalloc(sizeof(struct msm_bus_client *) |
||
2253 | + * NUM_CL_HANDLES, GFP_KERNEL); |
||
2254 | + if (ZERO_OR_NULL_PTR(t_cl_list)) { |
||
2255 | + ret = -ENOMEM; |
||
2256 | + MSM_BUS_ERR("%s: Failed to allocate handles list", |
||
2257 | + __func__); |
||
2258 | + goto exit_alloc_handle_lst; |
||
2259 | + } |
||
2260 | + handle_list.cl_list = t_cl_list; |
||
2261 | + handle_list.num_entries += NUM_CL_HANDLES; |
||
2262 | + } else { |
||
2263 | + t_cl_list = krealloc(handle_list.cl_list, |
||
2264 | + sizeof(struct msm_bus_client *) * |
||
2265 | + handle_list.num_entries + NUM_CL_HANDLES, |
||
2266 | + GFP_KERNEL); |
||
2267 | + if (ZERO_OR_NULL_PTR(t_cl_list)) { |
||
2268 | + ret = -ENOMEM; |
||
2269 | + MSM_BUS_ERR("%s: Failed to allocate handles list", |
||
2270 | + __func__); |
||
2271 | + goto exit_alloc_handle_lst; |
||
2272 | + } |
||
2273 | + |
||
2274 | + memset(&handle_list.cl_list[handle_list.num_entries], 0, |
||
2275 | + NUM_CL_HANDLES * sizeof(struct msm_bus_client *)); |
||
2276 | + handle_list.num_entries += NUM_CL_HANDLES; |
||
2277 | + handle_list.cl_list = t_cl_list; |
||
2278 | + } |
||
2279 | +exit_alloc_handle_lst: |
||
2280 | + return ret; |
||
2281 | +} |
||
2282 | + |
||
2283 | +static uint32_t gen_handle(struct msm_bus_client *client) |
||
2284 | +{ |
||
2285 | + uint32_t handle = 0; |
||
2286 | + int i; |
||
2287 | + int ret = 0; |
||
2288 | + |
||
2289 | + for (i = 0; i < handle_list.num_entries; i++) { |
||
2290 | + if (i && !handle_list.cl_list[i]) { |
||
2291 | + handle = i; |
||
2292 | + break; |
||
2293 | + } |
||
2294 | + } |
||
2295 | + |
||
2296 | + if (!handle) { |
||
2297 | + ret = alloc_handle_lst(NUM_CL_HANDLES); |
||
2298 | + |
||
2299 | + if (ret) { |
||
2300 | + MSM_BUS_ERR("%s: Failed to allocate handle list", |
||
2301 | + __func__); |
||
2302 | + goto exit_gen_handle; |
||
2303 | + } |
||
2304 | + handle = i + 1; |
||
2305 | + } |
||
2306 | + handle_list.cl_list[handle] = client; |
||
2307 | +exit_gen_handle: |
||
2308 | + return handle; |
||
2309 | +} |
||
2310 | + |
||
2311 | +static uint32_t register_client_adhoc(struct msm_bus_scale_pdata *pdata) |
||
2312 | +{ |
||
2313 | + int src, dest; |
||
2314 | + int i; |
||
2315 | + struct msm_bus_client *client = NULL; |
||
2316 | + int *lnode; |
||
2317 | + uint32_t handle = 0; |
||
2318 | + |
||
2319 | + mutex_lock(&msm_bus_adhoc_lock); |
||
2320 | + client = kzalloc(sizeof(struct msm_bus_client), GFP_KERNEL); |
||
2321 | + if (!client) { |
||
2322 | + MSM_BUS_ERR("%s: Error allocating client data", __func__); |
||
2323 | + goto exit_register_client; |
||
2324 | + } |
||
2325 | + client->pdata = pdata; |
||
2326 | + |
||
2327 | + lnode = kzalloc(pdata->usecase->num_paths * sizeof(int), GFP_KERNEL); |
||
2328 | + if (ZERO_OR_NULL_PTR(lnode)) { |
||
2329 | + MSM_BUS_ERR("%s: Error allocating pathnode ptr!", __func__); |
||
2330 | + goto exit_register_client; |
||
2331 | + } |
||
2332 | + client->src_pnode = lnode; |
||
2333 | + |
||
2334 | + for (i = 0; i < pdata->usecase->num_paths; i++) { |
||
2335 | + src = pdata->usecase->vectors[i].src; |
||
2336 | + dest = pdata->usecase->vectors[i].dst; |
||
2337 | + |
||
2338 | + if ((src < 0) || (dest < 0)) { |
||
2339 | + MSM_BUS_ERR("%s:Invalid src/dst.src %d dest %d", |
||
2340 | + __func__, src, dest); |
||
2341 | + goto exit_register_client; |
||
2342 | + } |
||
2343 | + |
||
2344 | + lnode[i] = getpath(src, dest); |
||
2345 | + if (lnode[i] < 0) { |
||
2346 | + MSM_BUS_ERR("%s:Failed to find path.src %d dest %d", |
||
2347 | + __func__, src, dest); |
||
2348 | + goto exit_register_client; |
||
2349 | + } |
||
2350 | + } |
||
2351 | + |
||
2352 | + handle = gen_handle(client); |
||
2353 | + msm_bus_dbg_client_data(client->pdata, MSM_BUS_DBG_REGISTER, |
||
2354 | + handle); |
||
2355 | + MSM_BUS_DBG("%s:Client handle %d %s", __func__, handle, |
||
2356 | + client->pdata->name); |
||
2357 | +exit_register_client: |
||
2358 | + mutex_unlock(&msm_bus_adhoc_lock); |
||
2359 | + return handle; |
||
2360 | +} |
||
2361 | + |
||
2362 | +static int update_request_adhoc(uint32_t cl, unsigned int index) |
||
2363 | +{ |
||
2364 | + int i, ret = 0; |
||
2365 | + struct msm_bus_scale_pdata *pdata; |
||
2366 | + int lnode, src, curr, dest; |
||
2367 | + uint64_t req_clk, req_bw, curr_clk, curr_bw; |
||
2368 | + struct msm_bus_client *client; |
||
2369 | + const char *test_cl = "Null"; |
||
2370 | + bool log_transaction = false; |
||
2371 | + |
||
2372 | + mutex_lock(&msm_bus_adhoc_lock); |
||
2373 | + |
||
2374 | + if (!cl) { |
||
2375 | + MSM_BUS_ERR("%s: Invalid client handle %d", __func__, cl); |
||
2376 | + ret = -ENXIO; |
||
2377 | + goto exit_update_request; |
||
2378 | + } |
||
2379 | + |
||
2380 | + client = handle_list.cl_list[cl]; |
||
2381 | + pdata = client->pdata; |
||
2382 | + if (!pdata) { |
||
2383 | + MSM_BUS_ERR("%s: Client data Null.[client didn't register]", |
||
2384 | + __func__); |
||
2385 | + ret = -ENXIO; |
||
2386 | + goto exit_update_request; |
||
2387 | + } |
||
2388 | + |
||
2389 | + if (index >= pdata->num_usecases) { |
||
2390 | + MSM_BUS_ERR("Client %u passed invalid index: %d\n", |
||
2391 | + cl, index); |
||
2392 | + ret = -ENXIO; |
||
2393 | + goto exit_update_request; |
||
2394 | + } |
||
2395 | + |
||
2396 | + if (client->curr == index) { |
||
2397 | + MSM_BUS_DBG("%s: Not updating client request idx %d unchanged", |
||
2398 | + __func__, index); |
||
2399 | + goto exit_update_request; |
||
2400 | + } |
||
2401 | + |
||
2402 | + curr = client->curr; |
||
2403 | + client->curr = index; |
||
2404 | + |
||
2405 | + if (!strcmp(test_cl, pdata->name)) |
||
2406 | + log_transaction = true; |
||
2407 | + |
||
2408 | + MSM_BUS_DBG("%s: cl: %u index: %d curr: %d num_paths: %d\n", __func__, |
||
2409 | + cl, index, client->curr, client->pdata->usecase->num_paths); |
||
2410 | + |
||
2411 | + for (i = 0; i < pdata->usecase->num_paths; i++) { |
||
2412 | + src = client->pdata->usecase[index].vectors[i].src; |
||
2413 | + dest = client->pdata->usecase[index].vectors[i].dst; |
||
2414 | + |
||
2415 | + lnode = client->src_pnode[i]; |
||
2416 | + req_clk = client->pdata->usecase[index].vectors[i].ib; |
||
2417 | + req_bw = client->pdata->usecase[index].vectors[i].ab; |
||
2418 | + if (curr < 0) { |
||
2419 | + curr_clk = 0; |
||
2420 | + curr_bw = 0; |
||
2421 | + } else { |
||
2422 | + curr_clk = client->pdata->usecase[curr].vectors[i].ib; |
||
2423 | + curr_bw = client->pdata->usecase[curr].vectors[i].ab; |
||
2424 | + MSM_BUS_DBG("%s:ab: %llu ib: %llu\n", __func__, |
||
2425 | + curr_bw, curr_clk); |
||
2426 | + } |
||
2427 | + |
||
2428 | + ret = update_path(src, dest, req_clk, req_bw, |
||
2429 | + curr_clk, curr_bw, lnode, pdata->active_only); |
||
2430 | + |
||
2431 | + if (ret) { |
||
2432 | + MSM_BUS_ERR("%s: Update path failed! %d ctx %d\n", |
||
2433 | + __func__, ret, ACTIVE_CTX); |
||
2434 | + goto exit_update_request; |
||
2435 | + } |
||
2436 | + |
||
2437 | + if (log_transaction) |
||
2438 | + getpath_debug(src, lnode, pdata->active_only); |
||
2439 | + } |
||
2440 | + msm_bus_dbg_client_data(client->pdata, index , cl); |
||
2441 | +exit_update_request: |
||
2442 | + mutex_unlock(&msm_bus_adhoc_lock); |
||
2443 | + return ret; |
||
2444 | +} |
||
2445 | + |
||
2446 | +/** |
||
2447 | + * msm_bus_arb_setops_adhoc() : Setup the bus arbitration ops |
||
2448 | + * @ arb_ops: pointer to the arb ops. |
||
2449 | + */ |
||
2450 | +void msm_bus_arb_setops_adhoc(struct msm_bus_arb_ops *arb_ops) |
||
2451 | +{ |
||
2452 | + arb_ops->register_client = register_client_adhoc; |
||
2453 | + arb_ops->update_request = update_request_adhoc; |
||
2454 | + arb_ops->unregister_client = unregister_client_adhoc; |
||
2455 | +} |
||
2456 | --- /dev/null |
||
2457 | +++ b/drivers/bus/msm_bus/msm_bus_bimc.c |
||
2458 | @@ -0,0 +1,2112 @@ |
||
2459 | +/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. |
||
2460 | + * |
||
2461 | + * This program is free software; you can redistribute it and/or modify |
||
2462 | + * it under the terms of the GNU General Public License version 2 and |
||
2463 | + * only version 2 as published by the Free Software Foundation. |
||
2464 | + * |
||
2465 | + * This program is distributed in the hope that it will be useful, |
||
2466 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
2467 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
2468 | + * GNU General Public License for more details. |
||
2469 | + */ |
||
2470 | + |
||
2471 | +#define pr_fmt(fmt) "AXI: BIMC: %s(): " fmt, __func__ |
||
2472 | + |
||
2473 | +#include <linux/slab.h> |
||
2474 | +#include <linux/io.h> |
||
2475 | +#include "msm-bus-board.h" |
||
2476 | +#include "msm_bus_core.h" |
||
2477 | +#include "msm_bus_bimc.h" |
||
2478 | +#include "msm_bus_adhoc.h" |
||
2479 | +#include <trace/events/trace_msm_bus.h> |
||
2480 | + |
||
2481 | +enum msm_bus_bimc_slave_block { |
||
2482 | + SLAVE_BLOCK_RESERVED = 0, |
||
2483 | + SLAVE_BLOCK_SLAVE_WAY, |
||
2484 | + SLAVE_BLOCK_XPU, |
||
2485 | + SLAVE_BLOCK_ARBITER, |
||
2486 | + SLAVE_BLOCK_SCMO, |
||
2487 | +}; |
||
2488 | + |
||
2489 | +enum bke_sw { |
||
2490 | + BKE_OFF = 0, |
||
2491 | + BKE_ON = 1, |
||
2492 | +}; |
||
2493 | + |
||
2494 | +/* M_Generic */ |
||
2495 | + |
||
2496 | +#define M_REG_BASE(b) ((b) + 0x00008000) |
||
2497 | + |
||
2498 | +#define M_COMPONENT_INFO_ADDR(b, n) \ |
||
2499 | + (M_REG_BASE(b) + (0x4000 * (n)) + 0x00000000) |
||
2500 | +enum bimc_m_component_info { |
||
2501 | + M_COMPONENT_INFO_RMSK = 0xffffff, |
||
2502 | + M_COMPONENT_INFO_INSTANCE_BMSK = 0xff0000, |
||
2503 | + M_COMPONENT_INFO_INSTANCE_SHFT = 0x10, |
||
2504 | + M_COMPONENT_INFO_SUB_TYPE_BMSK = 0xff00, |
||
2505 | + M_COMPONENT_INFO_SUB_TYPE_SHFT = 0x8, |
||
2506 | + M_COMPONENT_INFO_TYPE_BMSK = 0xff, |
||
2507 | + M_COMPONENT_INFO_TYPE_SHFT = 0x0, |
||
2508 | +}; |
||
2509 | + |
||
2510 | +#define M_CONFIG_INFO_0_ADDR(b, n) \ |
||
2511 | + (M_REG_BASE(b) + (0x4000 * (n)) + 0x00000020) |
||
2512 | +enum bimc_m_config_info_0 { |
||
2513 | + M_CONFIG_INFO_0_RMSK = 0xff00ffff, |
||
2514 | + M_CONFIG_INFO_0_SYNC_MODE_BMSK = 0xff000000, |
||
2515 | + M_CONFIG_INFO_0_SYNC_MODE_SHFT = 0x18, |
||
2516 | + M_CONFIG_INFO_0_CONNECTION_TYPE_BMSK = 0xff00, |
||
2517 | + M_CONFIG_INFO_0_CONNECTION_TYPE_SHFT = 0x8, |
||
2518 | + M_CONFIG_INFO_0_FUNC_BMSK = 0xff, |
||
2519 | + M_CONFIG_INFO_0_FUNC_SHFT = 0x0, |
||
2520 | +}; |
||
2521 | + |
||
2522 | +#define M_CONFIG_INFO_1_ADDR(b, n) \ |
||
2523 | + (M_REG_BASE(b) + (0x4000 * (n)) + 0x00000030) |
||
2524 | +enum bimc_m_config_info_1 { |
||
2525 | + M_CONFIG_INFO_1_RMSK = 0xffffffff, |
||
2526 | + M_CONFIG_INFO_1_SWAY_CONNECTIVITY_BMSK = 0xffffffff, |
||
2527 | + M_CONFIG_INFO_1_SWAY_CONNECTIVITY_SHFT = 0x0, |
||
2528 | +}; |
||
2529 | + |
||
2530 | +#define M_CONFIG_INFO_2_ADDR(b, n) \ |
||
2531 | + (M_REG_BASE(b) + (0x4000 * (n)) + 0x00000040) |
||
2532 | +enum bimc_m_config_info_2 { |
||
2533 | + M_CONFIG_INFO_2_RMSK = 0xffffffff, |
||
2534 | + M_CONFIG_INFO_2_M_DATA_WIDTH_BMSK = 0xffff0000, |
||
2535 | + M_CONFIG_INFO_2_M_DATA_WIDTH_SHFT = 0x10, |
||
2536 | + M_CONFIG_INFO_2_M_TID_WIDTH_BMSK = 0xff00, |
||
2537 | + M_CONFIG_INFO_2_M_TID_WIDTH_SHFT = 0x8, |
||
2538 | + M_CONFIG_INFO_2_M_MID_WIDTH_BMSK = 0xff, |
||
2539 | + M_CONFIG_INFO_2_M_MID_WIDTH_SHFT = 0x0, |
||
2540 | +}; |
||
2541 | + |
||
2542 | +#define M_CONFIG_INFO_3_ADDR(b, n) \ |
||
2543 | + (M_REG_BASE(b) + (0x4000 * (n)) + 0x00000050) |
||
2544 | +enum bimc_m_config_info_3 { |
||
2545 | + M_CONFIG_INFO_3_RMSK = 0xffffffff, |
||
2546 | + M_CONFIG_INFO_3_RCH_DEPTH_BMSK = 0xff000000, |
||
2547 | + M_CONFIG_INFO_3_RCH_DEPTH_SHFT = 0x18, |
||
2548 | + M_CONFIG_INFO_3_BCH_DEPTH_BMSK = 0xff0000, |
||
2549 | + M_CONFIG_INFO_3_BCH_DEPTH_SHFT = 0x10, |
||
2550 | + M_CONFIG_INFO_3_WCH_DEPTH_BMSK = 0xff00, |
||
2551 | + M_CONFIG_INFO_3_WCH_DEPTH_SHFT = 0x8, |
||
2552 | + M_CONFIG_INFO_3_ACH_DEPTH_BMSK = 0xff, |
||
2553 | + M_CONFIG_INFO_3_ACH_DEPTH_SHFT = 0x0, |
||
2554 | +}; |
||
2555 | + |
||
2556 | +#define M_CONFIG_INFO_4_ADDR(b, n) \ |
||
2557 | + (M_REG_BASE(b) + (0x4000 * (n)) + 0x00000060) |
||
2558 | +enum bimc_m_config_info_4 { |
||
2559 | + M_CONFIG_INFO_4_RMSK = 0xffff, |
||
2560 | + M_CONFIG_INFO_4_REORDER_BUF_DEPTH_BMSK = 0xff00, |
||
2561 | + M_CONFIG_INFO_4_REORDER_BUF_DEPTH_SHFT = 0x8, |
||
2562 | + M_CONFIG_INFO_4_REORDER_TABLE_DEPTH_BMSK = 0xff, |
||
2563 | + M_CONFIG_INFO_4_REORDER_TABLE_DEPTH_SHFT = 0x0, |
||
2564 | +}; |
||
2565 | + |
||
2566 | +#define M_CONFIG_INFO_5_ADDR(b, n) \ |
||
2567 | + (M_REG_BASE(b) + (0x4000 * (n)) + 0x00000070) |
||
2568 | +enum bimc_m_config_info_5 { |
||
2569 | + M_CONFIG_INFO_5_RMSK = 0x111, |
||
2570 | + M_CONFIG_INFO_5_MP2ARB_PIPELINE_EN_BMSK = 0x100, |
||
2571 | + M_CONFIG_INFO_5_MP2ARB_PIPELINE_EN_SHFT = 0x8, |
||
2572 | + M_CONFIG_INFO_5_MPBUF_PIPELINE_EN_BMSK = 0x10, |
||
2573 | + M_CONFIG_INFO_5_MPBUF_PIPELINE_EN_SHFT = 0x4, |
||
2574 | + M_CONFIG_INFO_5_M2MP_PIPELINE_EN_BMSK = 0x1, |
||
2575 | + M_CONFIG_INFO_5_M2MP_PIPELINE_EN_SHFT = 0x0, |
||
2576 | +}; |
||
2577 | + |
||
2578 | +#define M_INT_STATUS_ADDR(b, n) \ |
||
2579 | + (M_REG_BASE(b) + (0x4000 * (n)) + 0x00000100) |
||
2580 | +enum bimc_m_int_status { |
||
2581 | + M_INT_STATUS_RMSK = 0x3, |
||
2582 | +}; |
||
2583 | + |
||
2584 | +#define M_INT_CLR_ADDR(b, n) \ |
||
2585 | + (M_REG_BASE(b) + (0x4000 * (n)) + 0x00000108) |
||
2586 | +enum bimc_m_int_clr { |
||
2587 | + M_INT_CLR_RMSK = 0x3, |
||
2588 | +}; |
||
2589 | + |
||
2590 | +#define M_INT_EN_ADDR(b, n) \ |
||
2591 | + (M_REG_BASE(b) + (0x4000 * (n)) + 0x0000010c) |
||
2592 | +enum bimc_m_int_en { |
||
2593 | + M_INT_EN_RMSK = 0x3, |
||
2594 | +}; |
||
2595 | + |
||
2596 | +#define M_CLK_CTRL_ADDR(b, n) \ |
||
2597 | + (M_REG_BASE(b) + (0x4000 * (n)) + 0x00000200) |
||
2598 | +enum bimc_m_clk_ctrl { |
||
2599 | + M_CLK_CTRL_RMSK = 0x3, |
||
2600 | + M_CLK_CTRL_MAS_CLK_GATING_EN_BMSK = 0x2, |
||
2601 | + M_CLK_CTRL_MAS_CLK_GATING_EN_SHFT = 0x1, |
||
2602 | + M_CLK_CTRL_CORE_CLK_GATING_EN_BMSK = 0x1, |
||
2603 | + M_CLK_CTRL_CORE_CLK_GATING_EN_SHFT = 0x0, |
||
2604 | +}; |
||
2605 | + |
||
2606 | +#define M_MODE_ADDR(b, n) \ |
||
2607 | + (M_REG_BASE(b) + (0x4000 * (n)) + 0x00000210) |
||
2608 | +enum bimc_m_mode { |
||
2609 | + M_MODE_RMSK = 0xf0000011, |
||
2610 | + M_MODE_WR_GATHER_BEATS_BMSK = 0xf0000000, |
||
2611 | + M_MODE_WR_GATHER_BEATS_SHFT = 0x1c, |
||
2612 | + M_MODE_NARROW_WR_BMSK = 0x10, |
||
2613 | + M_MODE_NARROW_WR_SHFT = 0x4, |
||
2614 | + M_MODE_ORDERING_MODEL_BMSK = 0x1, |
||
2615 | + M_MODE_ORDERING_MODEL_SHFT = 0x0, |
||
2616 | +}; |
||
2617 | + |
||
2618 | +#define M_PRIOLVL_OVERRIDE_ADDR(b, n) \ |
||
2619 | + (M_REG_BASE(b) + (0x4000 * (n)) + 0x00000230) |
||
2620 | +enum bimc_m_priolvl_override { |
||
2621 | + M_PRIOLVL_OVERRIDE_RMSK = 0x301, |
||
2622 | + M_PRIOLVL_OVERRIDE_BMSK = 0x300, |
||
2623 | + M_PRIOLVL_OVERRIDE_SHFT = 0x8, |
||
2624 | + M_PRIOLVL_OVERRIDE_OVERRIDE_PRIOLVL_BMSK = 0x1, |
||
2625 | + M_PRIOLVL_OVERRIDE_OVERRIDE_PRIOLVL_SHFT = 0x0, |
||
2626 | +}; |
||
2627 | + |
||
2628 | +#define M_RD_CMD_OVERRIDE_ADDR(b, n) \ |
||
2629 | + (M_REG_BASE(b) + (0x4000 * (n)) + 0x00000240) |
||
2630 | +enum bimc_m_read_command_override { |
||
2631 | + M_RD_CMD_OVERRIDE_RMSK = 0x3071f7f, |
||
2632 | + M_RD_CMD_OVERRIDE_AREQPRIO_BMSK = 0x3000000, |
||
2633 | + M_RD_CMD_OVERRIDE_AREQPRIO_SHFT = 0x18, |
||
2634 | + M_RD_CMD_OVERRIDE_AMEMTYPE_BMSK = 0x70000, |
||
2635 | + M_RD_CMD_OVERRIDE_AMEMTYPE_SHFT = 0x10, |
||
2636 | + M_RD_CMD_OVERRIDE_ATRANSIENT_BMSK = 0x1000, |
||
2637 | + M_RD_CMD_OVERRIDE_ATRANSIENT_SHFT = 0xc, |
||
2638 | + M_RD_CMD_OVERRIDE_ASHARED_BMSK = 0x800, |
||
2639 | + M_RD_CMD_OVERRIDE_ASHARED_SHFT = 0xb, |
||
2640 | + M_RD_CMD_OVERRIDE_AREDIRECT_BMSK = 0x400, |
||
2641 | + M_RD_CMD_OVERRIDE_AREDIRECT_SHFT = 0xa, |
||
2642 | + M_RD_CMD_OVERRIDE_AOOO_BMSK = 0x200, |
||
2643 | + M_RD_CMD_OVERRIDE_AOOO_SHFT = 0x9, |
||
2644 | + M_RD_CMD_OVERRIDE_AINNERSHARED_BMSK = 0x100, |
||
2645 | + M_RD_CMD_OVERRIDE_AINNERSHARED_SHFT = 0x8, |
||
2646 | + M_RD_CMD_OVERRIDE_OVERRIDE_AREQPRIO_BMSK = 0x40, |
||
2647 | + M_RD_CMD_OVERRIDE_OVERRIDE_AREQPRIO_SHFT = 0x6, |
||
2648 | + M_RD_CMD_OVERRIDE_OVERRIDE_ATRANSIENT_BMSK = 0x20, |
||
2649 | + M_RD_CMD_OVERRIDE_OVERRIDE_ATRANSIENT_SHFT = 0x5, |
||
2650 | + M_RD_CMD_OVERRIDE_OVERRIDE_AMEMTYPE_BMSK = 0x10, |
||
2651 | + M_RD_CMD_OVERRIDE_OVERRIDE_AMEMTYPE_SHFT = 0x4, |
||
2652 | + M_RD_CMD_OVERRIDE_OVERRIDE_ASHARED_BMSK = 0x8, |
||
2653 | + M_RD_CMD_OVERRIDE_OVERRIDE_ASHARED_SHFT = 0x3, |
||
2654 | + M_RD_CMD_OVERRIDE_OVERRIDE_AREDIRECT_BMSK = 0x4, |
||
2655 | + M_RD_CMD_OVERRIDE_OVERRIDE_AREDIRECT_SHFT = 0x2, |
||
2656 | + M_RD_CMD_OVERRIDE_OVERRIDE_AOOO_BMSK = 0x2, |
||
2657 | + M_RD_CMD_OVERRIDE_OVERRIDE_AOOO_SHFT = 0x1, |
||
2658 | + M_RD_CMD_OVERRIDE_OVERRIDE_AINNERSHARED_BMSK = 0x1, |
||
2659 | + M_RD_CMD_OVERRIDE_OVERRIDE_AINNERSHARED_SHFT = 0x0, |
||
2660 | +}; |
||
2661 | + |
||
2662 | +#define M_WR_CMD_OVERRIDE_ADDR(b, n) \ |
||
2663 | + (M_REG_BASE(b) + (0x4000 * (n)) + 0x00000250) |
||
2664 | +enum bimc_m_write_command_override { |
||
2665 | + M_WR_CMD_OVERRIDE_RMSK = 0x3071f7f, |
||
2666 | + M_WR_CMD_OVERRIDE_AREQPRIO_BMSK = 0x3000000, |
||
2667 | + M_WR_CMD_OVERRIDE_AREQPRIO_SHFT = 0x18, |
||
2668 | + M_WR_CMD_OVERRIDE_AMEMTYPE_BMSK = 0x70000, |
||
2669 | + M_WR_CMD_OVERRIDE_AMEMTYPE_SHFT = 0x10, |
||
2670 | + M_WR_CMD_OVERRIDE_ATRANSIENT_BMSK = 0x1000, |
||
2671 | + M_WR_CMD_OVERRIDE_ATRANSIENT_SHFT = 0xc, |
||
2672 | + M_WR_CMD_OVERRIDE_ASHARED_BMSK = 0x800, |
||
2673 | + M_WR_CMD_OVERRIDE_ASHARED_SHFT = 0xb, |
||
2674 | + M_WR_CMD_OVERRIDE_AREDIRECT_BMSK = 0x400, |
||
2675 | + M_WR_CMD_OVERRIDE_AREDIRECT_SHFT = 0xa, |
||
2676 | + M_WR_CMD_OVERRIDE_AOOO_BMSK = 0x200, |
||
2677 | + M_WR_CMD_OVERRIDE_AOOO_SHFT = 0x9, |
||
2678 | + M_WR_CMD_OVERRIDE_AINNERSHARED_BMSK = 0x100, |
||
2679 | + M_WR_CMD_OVERRIDE_AINNERSHARED_SHFT = 0x8, |
||
2680 | + M_WR_CMD_OVERRIDE_OVERRIDE_AREQPRIO_BMSK = 0x40, |
||
2681 | + M_WR_CMD_OVERRIDE_OVERRIDE_AREQPRIO_SHFT = 0x6, |
||
2682 | + M_WR_CMD_OVERRIDE_OVERRIDE_ATRANSIENT_BMSK = 0x20, |
||
2683 | + M_WR_CMD_OVERRIDE_OVERRIDE_ATRANSIENT_SHFT = 0x5, |
||
2684 | + M_WR_CMD_OVERRIDE_OVERRIDE_AMEMTYPE_BMSK = 0x10, |
||
2685 | + M_WR_CMD_OVERRIDE_OVERRIDE_AMEMTYPE_SHFT = 0x4, |
||
2686 | + M_WR_CMD_OVERRIDE_OVERRIDE_ASHARED_BMSK = 0x8, |
||
2687 | + M_WR_CMD_OVERRIDE_OVERRIDE_ASHARED_SHFT = 0x3, |
||
2688 | + M_WR_CMD_OVERRIDE_OVERRIDE_AREDIRECT_BMSK = 0x4, |
||
2689 | + M_WR_CMD_OVERRIDE_OVERRIDE_AREDIRECT_SHFT = 0x2, |
||
2690 | + M_WR_CMD_OVERRIDE_OVERRIDE_AOOO_BMSK = 0x2, |
||
2691 | + M_WR_CMD_OVERRIDE_OVERRIDE_AOOO_SHFT = 0x1, |
||
2692 | + M_WR_CMD_OVERRIDE_OVERRIDE_AINNERSHARED_BMSK = 0x1, |
||
2693 | + M_WR_CMD_OVERRIDE_OVERRIDE_AINNERSHARED_SHFT = 0x0, |
||
2694 | +}; |
||
2695 | + |
||
2696 | +#define M_BKE_EN_ADDR(b, n) \ |
||
2697 | + (M_REG_BASE(b) + (0x4000 * (n)) + 0x00000300) |
||
2698 | +enum bimc_m_bke_en { |
||
2699 | + M_BKE_EN_RMSK = 0x1, |
||
2700 | + M_BKE_EN_EN_BMSK = 0x1, |
||
2701 | + M_BKE_EN_EN_SHFT = 0x0, |
||
2702 | +}; |
||
2703 | + |
||
2704 | +/* Grant Period registers */ |
||
2705 | +#define M_BKE_GP_ADDR(b, n) \ |
||
2706 | + (M_REG_BASE(b) + (0x4000 * (n)) + 0x00000304) |
||
2707 | +enum bimc_m_bke_grant_period { |
||
2708 | + M_BKE_GP_RMSK = 0x3ff, |
||
2709 | + M_BKE_GP_GP_BMSK = 0x3ff, |
||
2710 | + M_BKE_GP_GP_SHFT = 0x0, |
||
2711 | +}; |
||
2712 | + |
||
2713 | +/* Grant count register. |
||
2714 | + * The Grant count register represents a signed 16 bit |
||
2715 | + * value, range 0-0x7fff |
||
2716 | + */ |
||
2717 | +#define M_BKE_GC_ADDR(b, n) \ |
||
2718 | + (M_REG_BASE(b) + (0x4000 * (n)) + 0x00000308) |
||
2719 | +enum bimc_m_bke_grant_count { |
||
2720 | + M_BKE_GC_RMSK = 0xffff, |
||
2721 | + M_BKE_GC_GC_BMSK = 0xffff, |
||
2722 | + M_BKE_GC_GC_SHFT = 0x0, |
||
2723 | +}; |
||
2724 | + |
||
2725 | +/* Threshold High Registers */ |
||
2726 | +#define M_BKE_THH_ADDR(b, n) \ |
||
2727 | + (M_REG_BASE(b) + (0x4000 * (n)) + 0x00000320) |
||
2728 | +enum bimc_m_bke_thresh_high { |
||
2729 | + M_BKE_THH_RMSK = 0xffff, |
||
2730 | + M_BKE_THH_THRESH_BMSK = 0xffff, |
||
2731 | + M_BKE_THH_THRESH_SHFT = 0x0, |
||
2732 | +}; |
||
2733 | + |
||
2734 | +/* Threshold Medium Registers */ |
||
2735 | +#define M_BKE_THM_ADDR(b, n) \ |
||
2736 | + (M_REG_BASE(b) + (0x4000 * (n)) + 0x00000324) |
||
2737 | +enum bimc_m_bke_thresh_medium { |
||
2738 | + M_BKE_THM_RMSK = 0xffff, |
||
2739 | + M_BKE_THM_THRESH_BMSK = 0xffff, |
||
2740 | + M_BKE_THM_THRESH_SHFT = 0x0, |
||
2741 | +}; |
||
2742 | + |
||
2743 | +/* Threshold Low Registers */ |
||
2744 | +#define M_BKE_THL_ADDR(b, n) \ |
||
2745 | + (M_REG_BASE(b) + (0x4000 * (n)) + 0x00000328) |
||
2746 | +enum bimc_m_bke_thresh_low { |
||
2747 | + M_BKE_THL_RMSK = 0xffff, |
||
2748 | + M_BKE_THL_THRESH_BMSK = 0xffff, |
||
2749 | + M_BKE_THL_THRESH_SHFT = 0x0, |
||
2750 | +}; |
||
2751 | + |
||
2752 | +#define M_BKE_HEALTH_0_CONFIG_ADDR(b, n) \ |
||
2753 | + (M_REG_BASE(b) + (0x4000 * (n)) + 0x00000340) |
||
2754 | +enum bimc_m_bke_health_0 { |
||
2755 | + M_BKE_HEALTH_0_CONFIG_RMSK = 0x80000303, |
||
2756 | + M_BKE_HEALTH_0_CONFIG_LIMIT_CMDS_BMSK = 0x80000000, |
||
2757 | + M_BKE_HEALTH_0_CONFIG_LIMIT_CMDS_SHFT = 0x1f, |
||
2758 | + M_BKE_HEALTH_0_CONFIG_AREQPRIO_BMSK = 0x300, |
||
2759 | + M_BKE_HEALTH_0_CONFIG_AREQPRIO_SHFT = 0x8, |
||
2760 | + M_BKE_HEALTH_0_CONFIG_PRIOLVL_BMSK = 0x3, |
||
2761 | + M_BKE_HEALTH_0_CONFIG_PRIOLVL_SHFT = 0x0, |
||
2762 | +}; |
||
2763 | + |
||
2764 | +#define M_BKE_HEALTH_1_CONFIG_ADDR(b, n) \ |
||
2765 | + (M_REG_BASE(b) + (0x4000 * (n)) + 0x00000344) |
||
2766 | +enum bimc_m_bke_health_1 { |
||
2767 | + M_BKE_HEALTH_1_CONFIG_RMSK = 0x80000303, |
||
2768 | + M_BKE_HEALTH_1_CONFIG_LIMIT_CMDS_BMSK = 0x80000000, |
||
2769 | + M_BKE_HEALTH_1_CONFIG_LIMIT_CMDS_SHFT = 0x1f, |
||
2770 | + M_BKE_HEALTH_1_CONFIG_AREQPRIO_BMSK = 0x300, |
||
2771 | + M_BKE_HEALTH_1_CONFIG_AREQPRIO_SHFT = 0x8, |
||
2772 | + M_BKE_HEALTH_1_CONFIG_PRIOLVL_BMSK = 0x3, |
||
2773 | + M_BKE_HEALTH_1_CONFIG_PRIOLVL_SHFT = 0x0, |
||
2774 | +}; |
||
2775 | + |
||
2776 | +#define M_BKE_HEALTH_2_CONFIG_ADDR(b, n) \ |
||
2777 | + (M_REG_BASE(b) + (0x4000 * (n)) + 0x00000348) |
||
2778 | +enum bimc_m_bke_health_2 { |
||
2779 | + M_BKE_HEALTH_2_CONFIG_RMSK = 0x80000303, |
||
2780 | + M_BKE_HEALTH_2_CONFIG_LIMIT_CMDS_BMSK = 0x80000000, |
||
2781 | + M_BKE_HEALTH_2_CONFIG_LIMIT_CMDS_SHFT = 0x1f, |
||
2782 | + M_BKE_HEALTH_2_CONFIG_AREQPRIO_BMSK = 0x300, |
||
2783 | + M_BKE_HEALTH_2_CONFIG_AREQPRIO_SHFT = 0x8, |
||
2784 | + M_BKE_HEALTH_2_CONFIG_PRIOLVL_BMSK = 0x3, |
||
2785 | + M_BKE_HEALTH_2_CONFIG_PRIOLVL_SHFT = 0x0, |
||
2786 | +}; |
||
2787 | + |
||
2788 | +#define M_BKE_HEALTH_3_CONFIG_ADDR(b, n) \ |
||
2789 | + (M_REG_BASE(b) + (0x4000 * (n)) + 0x0000034c) |
||
2790 | +enum bimc_m_bke_health_3 { |
||
2791 | + M_BKE_HEALTH_3_CONFIG_RMSK = 0x303, |
||
2792 | + M_BKE_HEALTH_3_CONFIG_AREQPRIO_BMSK = 0x300, |
||
2793 | + M_BKE_HEALTH_3_CONFIG_AREQPRIO_SHFT = 0x8, |
||
2794 | + M_BKE_HEALTH_3_CONFIG_PRIOLVL_BMSK = 0x3, |
||
2795 | + M_BKE_HEALTH_3_CONFIG_PRIOLVL_SHFT = 0x0, |
||
2796 | +}; |
||
2797 | + |
||
2798 | +#define M_BUF_STATUS_ADDR(b, n) \ |
||
2799 | + (M_REG_BASE(b) + (0x4000 * (n)) + 0x00000400) |
||
2800 | +enum bimc_m_buf_status { |
||
2801 | + M_BUF_STATUS_RMSK = 0xf03f030, |
||
2802 | + M_BUF_STATUS_RCH_DATA_WR_FULL_BMSK = 0x8000000, |
||
2803 | + M_BUF_STATUS_RCH_DATA_WR_FULL_SHFT = 0x1b, |
||
2804 | + M_BUF_STATUS_RCH_DATA_WR_EMPTY_BMSK = 0x4000000, |
||
2805 | + M_BUF_STATUS_RCH_DATA_WR_EMPTY_SHFT = 0x1a, |
||
2806 | + M_BUF_STATUS_RCH_CTRL_WR_FULL_BMSK = 0x2000000, |
||
2807 | + M_BUF_STATUS_RCH_CTRL_WR_FULL_SHFT = 0x19, |
||
2808 | + M_BUF_STATUS_RCH_CTRL_WR_EMPTY_BMSK = 0x1000000, |
||
2809 | + M_BUF_STATUS_RCH_CTRL_WR_EMPTY_SHFT = 0x18, |
||
2810 | + M_BUF_STATUS_BCH_WR_FULL_BMSK = 0x20000, |
||
2811 | + M_BUF_STATUS_BCH_WR_FULL_SHFT = 0x11, |
||
2812 | + M_BUF_STATUS_BCH_WR_EMPTY_BMSK = 0x10000, |
||
2813 | + M_BUF_STATUS_BCH_WR_EMPTY_SHFT = 0x10, |
||
2814 | + M_BUF_STATUS_WCH_DATA_RD_FULL_BMSK = 0x8000, |
||
2815 | + M_BUF_STATUS_WCH_DATA_RD_FULL_SHFT = 0xf, |
||
2816 | + M_BUF_STATUS_WCH_DATA_RD_EMPTY_BMSK = 0x4000, |
||
2817 | + M_BUF_STATUS_WCH_DATA_RD_EMPTY_SHFT = 0xe, |
||
2818 | + M_BUF_STATUS_WCH_CTRL_RD_FULL_BMSK = 0x2000, |
||
2819 | + M_BUF_STATUS_WCH_CTRL_RD_FULL_SHFT = 0xd, |
||
2820 | + M_BUF_STATUS_WCH_CTRL_RD_EMPTY_BMSK = 0x1000, |
||
2821 | + M_BUF_STATUS_WCH_CTRL_RD_EMPTY_SHFT = 0xc, |
||
2822 | + M_BUF_STATUS_ACH_RD_FULL_BMSK = 0x20, |
||
2823 | + M_BUF_STATUS_ACH_RD_FULL_SHFT = 0x5, |
||
2824 | + M_BUF_STATUS_ACH_RD_EMPTY_BMSK = 0x10, |
||
2825 | + M_BUF_STATUS_ACH_RD_EMPTY_SHFT = 0x4, |
||
2826 | +}; |
||
2827 | +/*BIMC Generic */ |
||
2828 | + |
||
2829 | +#define S_REG_BASE(b) ((b) + 0x00048000) |
||
2830 | + |
||
2831 | +#define S_COMPONENT_INFO_ADDR(b, n) \ |
||
2832 | + (S_REG_BASE(b) + (0x8000 * (n)) + 0x00000000) |
||
2833 | +enum bimc_s_component_info { |
||
2834 | + S_COMPONENT_INFO_RMSK = 0xffffff, |
||
2835 | + S_COMPONENT_INFO_INSTANCE_BMSK = 0xff0000, |
||
2836 | + S_COMPONENT_INFO_INSTANCE_SHFT = 0x10, |
||
2837 | + S_COMPONENT_INFO_SUB_TYPE_BMSK = 0xff00, |
||
2838 | + S_COMPONENT_INFO_SUB_TYPE_SHFT = 0x8, |
||
2839 | + S_COMPONENT_INFO_TYPE_BMSK = 0xff, |
||
2840 | + S_COMPONENT_INFO_TYPE_SHFT = 0x0, |
||
2841 | +}; |
||
2842 | + |
||
2843 | +#define S_HW_INFO_ADDR(b, n) \ |
||
2844 | + (S_REG_BASE(b) + (0x80000 * (n)) + 0x00000010) |
||
2845 | +enum bimc_s_hw_info { |
||
2846 | + S_HW_INFO_RMSK = 0xffffffff, |
||
2847 | + S_HW_INFO_MAJOR_BMSK = 0xff000000, |
||
2848 | + S_HW_INFO_MAJOR_SHFT = 0x18, |
||
2849 | + S_HW_INFO_BRANCH_BMSK = 0xff0000, |
||
2850 | + S_HW_INFO_BRANCH_SHFT = 0x10, |
||
2851 | + S_HW_INFO_MINOR_BMSK = 0xff00, |
||
2852 | + S_HW_INFO_MINOR_SHFT = 0x8, |
||
2853 | + S_HW_INFO_ECO_BMSK = 0xff, |
||
2854 | + S_HW_INFO_ECO_SHFT = 0x0, |
||
2855 | +}; |
||
2856 | + |
||
2857 | + |
||
2858 | +/* S_SCMO_GENERIC */ |
||
2859 | + |
||
2860 | +#define S_SCMO_REG_BASE(b) ((b) + 0x00048000) |
||
2861 | + |
||
2862 | +#define S_SCMO_CONFIG_INFO_0_ADDR(b, n) \ |
||
2863 | + (S_SCMO_REG_BASE(b) + (0x8000 * (n)) + 0x00000020) |
||
2864 | +enum bimc_s_scmo_config_info_0 { |
||
2865 | + S_SCMO_CONFIG_INFO_0_RMSK = 0xffffffff, |
||
2866 | + S_SCMO_CONFIG_INFO_0_DATA_WIDTH_BMSK = 0xffff0000, |
||
2867 | + S_SCMO_CONFIG_INFO_0_DATA_WIDTH_SHFT = 0x10, |
||
2868 | + S_SCMO_CONFIG_INFO_0_TID_WIDTH_BMSK = 0xff00, |
||
2869 | + S_SCMO_CONFIG_INFO_0_TID_WIDTH_SHFT = 0x8, |
||
2870 | + S_SCMO_CONFIG_INFO_0_MID_WIDTH_BMSK = 0xff, |
||
2871 | + S_SCMO_CONFIG_INFO_0_MID_WIDTH_SHFT = 0x0, |
||
2872 | +}; |
||
2873 | + |
||
2874 | +#define S_SCMO_CONFIG_INFO_1_ADDR(b, n) \ |
||
2875 | + (S_SCMO_REG_BASE(b) + (0x8000 * (n)) + 0x00000030) |
||
2876 | +enum bimc_s_scmo_config_info_1 { |
||
2877 | + S_SCMO_CONFIG_INFO_1_RMSK = 0xffffffff, |
||
2878 | + S_SCMO_CONFIG_INFO_1_MPORT_CONNECTIVITY_BMSK = 0xffffffff, |
||
2879 | + S_SCMO_CONFIG_INFO_1_MPORT_CONNECTIVITY_SHFT = 0x0, |
||
2880 | +}; |
||
2881 | + |
||
2882 | +#define S_SCMO_CONFIG_INFO_2_ADDR(b, n) \ |
||
2883 | + (S_SCMO_REG_BASE(b) + (0x8000 * (n)) + 0x00000040) |
||
2884 | +enum bimc_s_scmo_config_info_2 { |
||
2885 | + S_SCMO_CONFIG_INFO_2_RMSK = 0xff00ff, |
||
2886 | + S_SCMO_CONFIG_INFO_2_NUM_GLOBAL_MONS_BMSK = 0xff0000, |
||
2887 | + S_SCMO_CONFIG_INFO_2_NUM_GLOBAL_MONS_SHFT = 0x10, |
||
2888 | + S_SCMO_CONFIG_INFO_2_VMID_WIDTH_BMSK = 0xff, |
||
2889 | + S_SCMO_CONFIG_INFO_2_VMID_WIDTH_SHFT = 0x0, |
||
2890 | +}; |
||
2891 | + |
||
2892 | +#define S_SCMO_CONFIG_INFO_3_ADDR(b, n) \ |
||
2893 | + (S_SCMO_REG_BASE(b) + (0x8000 * (n)) + 0x00000050) |
||
2894 | +enum bimc_s_scmo_config_info_3 { |
||
2895 | + S_SCMO_CONFIG_INFO_3_RMSK = 0xffffffff, |
||
2896 | + S_SCMO_CONFIG_INFO_3_RCH0_CTRL_DEPTH_BMSK = 0xff000000, |
||
2897 | + S_SCMO_CONFIG_INFO_3_RCH0_CTRL_DEPTH_SHFT = 0x18, |
||
2898 | + S_SCMO_CONFIG_INFO_3_RCH0_DEPTH_BMSK = 0xff0000, |
||
2899 | + S_SCMO_CONFIG_INFO_3_RCH0_DEPTH_SHFT = 0x10, |
||
2900 | + S_SCMO_CONFIG_INFO_3_BCH_DEPTH_BMSK = 0xff00, |
||
2901 | + S_SCMO_CONFIG_INFO_3_BCH_DEPTH_SHFT = 0x8, |
||
2902 | + S_SCMO_CONFIG_INFO_3_WCH_DEPTH_BMSK = 0xff, |
||
2903 | + S_SCMO_CONFIG_INFO_3_WCH_DEPTH_SHFT = 0x0, |
||
2904 | +}; |
||
2905 | + |
||
2906 | +#define S_SCMO_CONFIG_INFO_4_ADDR(b, n) \ |
||
2907 | + (S_SCMO_REG_BASE(b) + (0x8000 * (n)) + 0x00000060) |
||
2908 | +enum bimc_s_scmo_config_info_4 { |
||
2909 | + S_SCMO_CONFIG_INFO_4_RMSK = 0xffff, |
||
2910 | + S_SCMO_CONFIG_INFO_4_RCH1_CTRL_DEPTH_BMSK = 0xff00, |
||
2911 | + S_SCMO_CONFIG_INFO_4_RCH1_CTRL_DEPTH_SHFT = 0x8, |
||
2912 | + S_SCMO_CONFIG_INFO_4_RCH1_DEPTH_BMSK = 0xff, |
||
2913 | + S_SCMO_CONFIG_INFO_4_RCH1_DEPTH_SHFT = 0x0, |
||
2914 | +}; |
||
2915 | + |
||
2916 | +#define S_SCMO_CONFIG_INFO_5_ADDR(b, n) \ |
||
2917 | + (S_SCMO_REG_BASE(b) + (0x8000 * (n)) + 0x00000070) |
||
2918 | +enum bimc_s_scmo_config_info_5 { |
||
2919 | + S_SCMO_CONFIG_INFO_5_RMSK = 0xffff, |
||
2920 | + S_SCMO_CONFIG_INFO_5_DPE_CQ_DEPTH_BMSK = 0xff00, |
||
2921 | + S_SCMO_CONFIG_INFO_5_DPE_CQ_DEPTH_SHFT = 0x8, |
||
2922 | + S_SCMO_CONFIG_INFO_5_DDR_BUS_WIDTH_BMSK = 0xff, |
||
2923 | + S_SCMO_CONFIG_INFO_5_DDR_BUS_WIDTH_SHFT = 0x0, |
||
2924 | +}; |
||
2925 | + |
||
2926 | +#define S_SCMO_CONFIG_INFO_6_ADDR(b, n) \ |
||
2927 | + (S_SCMO_REG_BASE(b) + (0x8000 * (n)) + 0x00000080) |
||
2928 | +enum bimc_s_scmo_config_info_6 { |
||
2929 | + S_SCMO_CONFIG_INFO_6_RMSK = 0x1111, |
||
2930 | + S_SCMO_CONFIG_INFO_6_WBUFC_PIPE_BMSK = 0x1000, |
||
2931 | + S_SCMO_CONFIG_INFO_6_WBUFC_PIPE_SHFT = 0xc, |
||
2932 | + S_SCMO_CONFIG_INFO_6_RDOPT_PIPE_BMSK = 0x100, |
||
2933 | + S_SCMO_CONFIG_INFO_6_RDOPT_PIPE_SHFT = 0x8, |
||
2934 | + S_SCMO_CONFIG_INFO_6_ACHAN_INTF_PIPE_BMSK = 0x10, |
||
2935 | + S_SCMO_CONFIG_INFO_6_ACHAN_INTF_PIPE_SHFT = 0x4, |
||
2936 | + S_SCMO_CONFIG_INFO_6_ADDR_DECODE_HT_BMSK = 0x1, |
||
2937 | + S_SCMO_CONFIG_INFO_6_ADDR_DECODE_HT_SHFT = 0x0, |
||
2938 | +}; |
||
2939 | + |
||
2940 | +#define S_SCMO_INT_STATUS_ADDR(b, n) \ |
||
2941 | + (S_SCMO_REG_BASE(b) + (0x8000 * (n)) + 0x00000100) |
||
2942 | +enum bimc_s_scmo_int_status { |
||
2943 | + S_SCMO_INT_STATUS_RMSK = 0x1, |
||
2944 | + S_SCMO_INT_STATUS_ERR_OCCURED_BMSK = 0x1, |
||
2945 | + S_SCMO_INT_STATUS_ERR_OCCURED_SHFT = 0x0, |
||
2946 | +}; |
||
2947 | + |
||
2948 | +#define S_SCMO_INT_CLR_ADDR(b, n) \ |
||
2949 | + (S_SCMO_REG_BASE(b) + (0x8000 * (n)) + 0x00000108) |
||
2950 | +enum bimc_s_scmo_int_clr { |
||
2951 | + S_SCMO_INT_CLR_RMSK = 0x1, |
||
2952 | + S_SCMO_INT_CLR_IRQ_CLR_BMSK = 0x1, |
||
2953 | + S_SCMO_INT_CLR_IRQ_CLR_SHFT = 0x0, |
||
2954 | +}; |
||
2955 | + |
||
2956 | +#define S_SCMO_INT_EN_ADDR(b, n) \ |
||
2957 | + (S_SCMO_REG_BASE(b) + (0x8000 * (n)) + 0x0000010c) |
||
2958 | +enum bimc_s_scmo_int_en { |
||
2959 | + S_SCMO_INT_EN_RMSK = 0x1, |
||
2960 | + S_SCMO_INT_EN_IRQ_EN_BMSK = 0x1, |
||
2961 | + S_SCMO_INT_EN_IRQ_EN_SHFT = 0x0, |
||
2962 | +}; |
||
2963 | + |
||
2964 | +#define S_SCMO_ESYN_ADDR_ADDR(b, n) \ |
||
2965 | + (S_SCMO_REG_BASE(b) + (0x8000 * (n)) + 0x00000120) |
||
2966 | +enum bimc_s_scmo_esyn_addr { |
||
2967 | + S_SCMO_ESYN_ADDR_RMSK = 0xffffffff, |
||
2968 | + S_SCMO_ESYN_ADDR_ESYN_ADDR_ERR_ADDR_BMSK = 0xffffffff, |
||
2969 | + S_SCMO_ESYN_ADDR_ESYN_ADDR_ERR_ADDR_SHFT = 0x0, |
||
2970 | +}; |
||
2971 | + |
||
2972 | +#define S_SCMO_ESYN_APACKET_0_ADDR(b, n) \ |
||
2973 | + (S_SCMO_REG_BASE(b) + (0x8000 * (n)) + 0x00000128) |
||
2974 | +enum bimc_s_scmo_esyn_apacket_0 { |
||
2975 | + S_SCMO_ESYN_APACKET_0_RMSK = 0xff1fffff, |
||
2976 | + S_SCMO_ESYN_APACKET_0_ERR_ATID_BMSK = 0xff000000, |
||
2977 | + S_SCMO_ESYN_APACKET_0_ERR_ATID_SHFT = 0x18, |
||
2978 | + S_SCMO_ESYN_APACKET_0_ERR_AVMID_BMSK = 0x1f0000, |
||
2979 | + S_SCMO_ESYN_APACKET_0_ERR_AVMID_SHFT = 0x10, |
||
2980 | + S_SCMO_ESYN_APACKET_0_ERR_AMID_BMSK = 0xffff, |
||
2981 | + S_SCMO_ESYN_APACKET_0_ERR_AMID_SHFT = 0x0, |
||
2982 | +}; |
||
2983 | + |
||
2984 | +#define S_SCMO_ESYN_APACKET_1_ADDR(b, n) \ |
||
2985 | + (S_SCMO_REG_BASE(b) + (0x8000 * (n)) + 0x0000012c) |
||
2986 | +enum bimc_s_scmo_esyn_apacket_1 { |
||
2987 | + S_SCMO_ESYN_APACKET_1_RMSK = 0x10ff117, |
||
2988 | + S_SCMO_ESYN_APACKET_1_ERR_CODE_BMSK = 0x1000000, |
||
2989 | + S_SCMO_ESYN_APACKET_1_ERR_CODE_SHFT = 0x18, |
||
2990 | + S_SCMO_ESYN_APACKET_1_ERR_ALEN_BMSK = 0xf0000, |
||
2991 | + S_SCMO_ESYN_APACKET_1_ERR_ALEN_SHFT = 0x10, |
||
2992 | + S_SCMO_ESYN_APACKET_1_ERR_ASIZE_BMSK = 0xe000, |
||
2993 | + S_SCMO_ESYN_APACKET_1_ERR_ASIZE_SHFT = 0xd, |
||
2994 | + S_SCMO_ESYN_APACKET_1_ERR_ABURST_BMSK = 0x1000, |
||
2995 | + S_SCMO_ESYN_APACKET_1_ERR_ABURST_SHFT = 0xc, |
||
2996 | + S_SCMO_ESYN_APACKET_1_ERR_AEXCLUSIVE_BMSK = 0x100, |
||
2997 | + S_SCMO_ESYN_APACKET_1_ERR_AEXCLUSIVE_SHFT = 0x8, |
||
2998 | + S_SCMO_ESYN_APACKET_1_ERR_APRONTS_BMSK = 0x10, |
||
2999 | + S_SCMO_ESYN_APACKET_1_ERR_APRONTS_SHFT = 0x4, |
||
3000 | + S_SCMO_ESYN_APACKET_1_ERR_AOOORD_BMSK = 0x4, |
||
3001 | + S_SCMO_ESYN_APACKET_1_ERR_AOOORD_SHFT = 0x2, |
||
3002 | + S_SCMO_ESYN_APACKET_1_ERR_AOOOWR_BMSK = 0x2, |
||
3003 | + S_SCMO_ESYN_APACKET_1_ERR_AOOOWR_SHFT = 0x1, |
||
3004 | + S_SCMO_ESYN_APACKET_1_ERR_AWRITE_BMSK = 0x1, |
||
3005 | + S_SCMO_ESYN_APACKET_1_ERR_AWRITE_SHFT = 0x0, |
||
3006 | +}; |
||
3007 | + |
||
3008 | +#define S_SCMO_CLK_CTRL_ADDR(b, n) \ |
||
3009 | + (S_SCMO_REG_BASE(b) + (0x8000 * (n)) + 0x00000200) |
||
3010 | +enum bimc_s_scmo_clk_ctrl { |
||
3011 | + S_SCMO_CLK_CTRL_RMSK = 0xffff1111, |
||
3012 | + S_SCMO_CLK_CTRL_PEN_CMD_CG_EN_BMSK = 0x10000, |
||
3013 | + S_SCMO_CLK_CTRL_PEN_CMD_CG_EN_SHFT = 0x10, |
||
3014 | + S_SCMO_CLK_CTRL_RCH_CG_EN_BMSK = 0x1000, |
||
3015 | + S_SCMO_CLK_CTRL_RCH_CG_EN_SHFT = 0xc, |
||
3016 | + S_SCMO_CLK_CTRL_FLUSH_CG_EN_BMSK = 0x100, |
||
3017 | + S_SCMO_CLK_CTRL_FLUSH_CG_EN_SHFT = 0x8, |
||
3018 | + S_SCMO_CLK_CTRL_WCH_CG_EN_BMSK = 0x10, |
||
3019 | + S_SCMO_CLK_CTRL_WCH_CG_EN_SHFT = 0x4, |
||
3020 | + S_SCMO_CLK_CTRL_ACH_CG_EN_BMSK = 0x1, |
||
3021 | + S_SCMO_CLK_CTRL_ACH_CG_EN_SHFT = 0x0, |
||
3022 | +}; |
||
3023 | + |
||
3024 | +#define S_SCMO_SLV_INTERLEAVE_CFG_ADDR(b, n) \ |
||
3025 | + (S_SCMO_REG_BASE(b) + (0x8000 * (n)) + 0x00000400) |
||
3026 | +enum bimc_s_scmo_slv_interleave_cfg { |
||
3027 | + S_SCMO_SLV_INTERLEAVE_CFG_RMSK = 0xff, |
||
3028 | + S_SCMO_SLV_INTERLEAVE_CFG_INTERLEAVE_CS1_BMSK = 0x10, |
||
3029 | + S_SCMO_SLV_INTERLEAVE_CFG_INTERLEAVE_CS1_SHFT = 0x4, |
||
3030 | + S_SCMO_SLV_INTERLEAVE_CFG_INTERLEAVE_CS0_BMSK = 0x1, |
||
3031 | + S_SCMO_SLV_INTERLEAVE_CFG_INTERLEAVE_CS0_SHFT = 0x0, |
||
3032 | +}; |
||
3033 | + |
||
3034 | +#define S_SCMO_ADDR_BASE_CSn_ADDR(b, n, o) \ |
||
3035 | + (S_SCMO_REG_BASE(b) + (0x8000 * (n)) + 0x00000410 + 0x4 * (o)) |
||
3036 | +enum bimc_s_scmo_addr_base_csn { |
||
3037 | + S_SCMO_ADDR_BASE_CSn_RMSK = 0xffff, |
||
3038 | + S_SCMO_ADDR_BASE_CSn_MAXn = 1, |
||
3039 | + S_SCMO_ADDR_BASE_CSn_ADDR_BASE_BMSK = 0xfc, |
||
3040 | + S_SCMO_ADDR_BASE_CSn_ADDR_BASE_SHFT = 0x2, |
||
3041 | +}; |
||
3042 | + |
||
3043 | +#define S_SCMO_ADDR_MAP_CSn_ADDR(b, n, o) \ |
||
3044 | + (S_SCMO_REG_BASE(b) + (0x8000 * (n)) + 0x00000420 + 0x4 * (o)) |
||
3045 | +enum bimc_s_scmo_addr_map_csn { |
||
3046 | + S_SCMO_ADDR_MAP_CSn_RMSK = 0xffff, |
||
3047 | + S_SCMO_ADDR_MAP_CSn_MAXn = 1, |
||
3048 | + S_SCMO_ADDR_MAP_CSn_RANK_EN_BMSK = 0x8000, |
||
3049 | + S_SCMO_ADDR_MAP_CSn_RANK_EN_SHFT = 0xf, |
||
3050 | + S_SCMO_ADDR_MAP_CSn_ADDR_MODE_BMSK = 0x1000, |
||
3051 | + S_SCMO_ADDR_MAP_CSn_ADDR_MODE_SHFT = 0xc, |
||
3052 | + S_SCMO_ADDR_MAP_CSn_BANK_SIZE_BMSK = 0x100, |
||
3053 | + S_SCMO_ADDR_MAP_CSn_BANK_SIZE_SHFT = 0x8, |
||
3054 | + S_SCMO_ADDR_MAP_CSn_ROW_SIZE_BMSK = 0x30, |
||
3055 | + S_SCMO_ADDR_MAP_CSn_ROW_SIZE_SHFT = 0x4, |
||
3056 | + S_SCMO_ADDR_MAP_CSn_COL_SIZE_BMSK = 0x3, |
||
3057 | + S_SCMO_ADDR_MAP_CSn_COL_SIZE_SHFT = 0x0, |
||
3058 | +}; |
||
3059 | + |
||
3060 | +#define S_SCMO_ADDR_MASK_CSn_ADDR(b, n, o) \ |
||
3061 | + (S_SCMO_REG_BASE(b) + (0x8000 * (n)) + 0x00000430 + 0x4 * (0)) |
||
3062 | +enum bimc_s_scmo_addr_mask_csn { |
||
3063 | + S_SCMO_ADDR_MASK_CSn_RMSK = 0xffff, |
||
3064 | + S_SCMO_ADDR_MASK_CSn_MAXn = 1, |
||
3065 | + S_SCMO_ADDR_MASK_CSn_ADDR_MASK_BMSK = 0xfc, |
||
3066 | + S_SCMO_ADDR_MASK_CSn_ADDR_MASK_SHFT = 0x2, |
||
3067 | +}; |
||
3068 | + |
||
3069 | +#define S_SCMO_SLV_STATUS_ADDR(b, n) \ |
||
3070 | + (S_SCMO_REG_BASE(b) + (0x8000 * (n)) + 0x00000450) |
||
3071 | +enum bimc_s_scmo_slv_status { |
||
3072 | + S_SCMO_SLV_STATUS_RMSK = 0xff3, |
||
3073 | + S_SCMO_SLV_STATUS_GLOBAL_MONS_IN_USE_BMSK = 0xff0, |
||
3074 | + S_SCMO_SLV_STATUS_GLOBAL_MONS_IN_USE_SHFT = 0x4, |
||
3075 | + S_SCMO_SLV_STATUS_SLAVE_IDLE_BMSK = 0x3, |
||
3076 | + S_SCMO_SLV_STATUS_SLAVE_IDLE_SHFT = 0x0, |
||
3077 | +}; |
||
3078 | + |
||
3079 | +#define S_SCMO_CMD_BUF_CFG_ADDR(b, n) \ |
||
3080 | + (S_SCMO_REG_BASE(b) + (0x8000 * (n)) + 0x00000500) |
||
3081 | +enum bimc_s_scmo_cmd_buf_cfg { |
||
3082 | + S_SCMO_CMD_BUF_CFG_RMSK = 0xf1f, |
||
3083 | + S_SCMO_CMD_BUF_CFG_CMD_ORDERING_BMSK = 0x300, |
||
3084 | + S_SCMO_CMD_BUF_CFG_CMD_ORDERING_SHFT = 0x8, |
||
3085 | + S_SCMO_CMD_BUF_CFG_HP_CMD_AREQPRIO_MAP_BMSK = 0x10, |
||
3086 | + S_SCMO_CMD_BUF_CFG_HP_CMD_AREQPRIO_MAP_SHFT = 0x4, |
||
3087 | + S_SCMO_CMD_BUF_CFG_HP_CMD_Q_DEPTH_BMSK = 0x7, |
||
3088 | + S_SCMO_CMD_BUF_CFG_HP_CMD_Q_DEPTH_SHFT = 0x0, |
||
3089 | +}; |
||
3090 | + |
||
3091 | +#define S_SCM_CMD_BUF_STATUS_ADDR(b, n) \ |
||
3092 | + (S_SCMO_REG_BASE(b) + (0x8000 * (n)) + 0x00000520) |
||
3093 | +enum bimc_s_scm_cmd_buf_status { |
||
3094 | + S_SCMO_CMD_BUF_STATUS_RMSK = 0x77, |
||
3095 | + S_SCMO_CMD_BUF_STATUS_HP_CMD_BUF_ENTRIES_IN_USE_BMSK = 0x70, |
||
3096 | + S_SCMO_CMD_BUF_STATUS_HP_CMD_BUF_ENTRIES_IN_USE_SHFT = 0x4, |
||
3097 | + S_SCMO_CMD_BUF_STATUS_LP_CMD_BUF_ENTRIES_IN_USE_BMSK = 0x7, |
||
3098 | + S_SCMO_CMD_BUF_STATUS_LP_CMD_BUF_ENTRIES_IN_USE_SHFT = 0x0, |
||
3099 | +}; |
||
3100 | + |
||
3101 | +#define S_SCMO_RCH_SEL_ADDR(b, n) \ |
||
3102 | + (S_SCMO_REG_BASE(b) + (0x8000 * (n)) + 0x00000540) |
||
3103 | +enum bimc_s_scmo_rch_sel { |
||
3104 | + S_SCMO_RCH_SEL_RMSK = 0xffffffff, |
||
3105 | + S_SCMO_CMD_BUF_STATUS_RCH_PORTS_BMSK = 0xffffffff, |
||
3106 | + S_SCMO_CMD_BUF_STATUS_RCH_PORTS_SHFT = 0x0, |
||
3107 | +}; |
||
3108 | + |
||
3109 | +#define S_SCMO_RCH_BKPR_CFG_ADDR(b, n) \ |
||
3110 | + (S_SCMO_REG_BASE(b) + (0x8000 * (n)) + 0x00000544) |
||
3111 | +enum bimc_s_scmo_rch_bkpr_cfg { |
||
3112 | + S_SCMO_RCH_BKPR_CFG_RMSK = 0xffffffff, |
||
3113 | + S_SCMO_RCH_BKPR_CFG_RCH1_FIFO_BKPR_HI_TH_BMSK = 0x3f000000, |
||
3114 | + S_SCMO_RCH_BKPR_CFG_RCH1_FIFO_BKPR_HI_TH_SHFT = 0x18, |
||
3115 | + S_SCMO_RCH_BKPR_CFG_RCH1_FIFO_BKPR_LO_TH_BMSK = 0x3f0000, |
||
3116 | + S_SCMO_RCH_BKPR_CFG_RCH1_FIFO_BKPR_LO_TH_SHFT = 0x10, |
||
3117 | + S_SCMO_RCH_BKPR_CFG_RCH0_FIFO_BKPR_HI_TH_BMSK = 0x3f00, |
||
3118 | + S_SCMO_RCH_BKPR_CFG_RCH0_FIFO_BKPR_HI_TH_SHFT = 0x8, |
||
3119 | + S_SCMO_RCH_BKPR_CFG_RCH0_FIFO_BKPR_LO_TH_BMSK = 0x3f, |
||
3120 | + S_SCMO_RCH_BKPR_CFG_RCH0_FIFO_BKPR_LO_TH_SHFT = 0x0, |
||
3121 | +}; |
||
3122 | + |
||
3123 | +#define S_SCMO_RCH_STATUS_ADDR(b, n) \ |
||
3124 | + (S_SCMO_REG_BASE(b) + (0x8000 * (n)) + 0x00000560) |
||
3125 | +enum bimc_s_scmo_rch_status { |
||
3126 | + S_SCMO_RCH_STATUS_RMSK = 0x33333, |
||
3127 | + S_SCMO_RCH_STATUS_PRQ_FIFO_FULL_BMSK = 0x20000, |
||
3128 | + S_SCMO_RCH_STATUS_PRQ_FIFO_FULL_SHFT = 0x11, |
||
3129 | + S_SCMO_RCH_STATUS_PRQ_FIFO_EMPTY_BMSK = 0x10000, |
||
3130 | + S_SCMO_RCH_STATUS_PRQ_FIFO_EMPTY_SHFT = 0x10, |
||
3131 | + S_SCMO_RCH_STATUS_RCH1_QUAL_FIFO_FULL_BMSK = 0x2000, |
||
3132 | + S_SCMO_RCH_STATUS_RCH1_QUAL_FIFO_FULL_SHFT = 0xd, |
||
3133 | + S_SCMO_RCH_STATUS_RCH1_QUAL_FIFO_EMPTY_BMSK = 0x1000, |
||
3134 | + S_SCMO_RCH_STATUS_RCH1_QUAL_FIFO_EMPTY_SHFT = 0xc, |
||
3135 | + S_SCMO_RCH_STATUS_RCH1_DATA_FIFO_FULL_BMSK = 0x200, |
||
3136 | + S_SCMO_RCH_STATUS_RCH1_DATA_FIFO_FULL_SHFT = 0x9, |
||
3137 | + S_SCMO_RCH_STATUS_RCH1_DATA_FIFO_EMPTY_BMSK = 0x100, |
||
3138 | + S_SCMO_RCH_STATUS_RCH1_DATA_FIFO_EMPTY_SHFT = 0x8, |
||
3139 | + S_SCMO_RCH_STATUS_RCH0_QUAL_FIFO_FULL_BMSK = 0x20, |
||
3140 | + S_SCMO_RCH_STATUS_RCH0_QUAL_FIFO_FULL_SHFT = 0x5, |
||
3141 | + S_SCMO_RCH_STATUS_RCH0_QUAL_FIFO_EMPTY_BMSK = 0x10, |
||
3142 | + S_SCMO_RCH_STATUS_RCH0_QUAL_FIFO_EMPTY_SHFT = 0x4, |
||
3143 | + S_SCMO_RCH_STATUS_RCH0_DATA_FIFO_FULL_BMSK = 0x2, |
||
3144 | + S_SCMO_RCH_STATUS_RCH0_DATA_FIFO_FULL_SHFT = 0x1, |
||
3145 | + S_SCMO_RCH_STATUS_RCH0_DATA_FIFO_EMPTY_BMSK = 0x1, |
||
3146 | + S_SCMO_RCH_STATUS_RCH0_DATA_FIFO_EMPTY_SHFT = 0x0, |
||
3147 | +}; |
||
3148 | + |
||
3149 | +#define S_SCMO_WCH_BUF_CFG_ADDR(b, n) \ |
||
3150 | + (S_SCMO_REG_BASE(b) + (0x8000 * (n)) + 0x00000580) |
||
3151 | +enum bimc_s_scmo_wch_buf_cfg { |
||
3152 | + S_SCMO_WCH_BUF_CFG_RMSK = 0xff, |
||
3153 | + S_SCMO_WCH_BUF_CFG_WRITE_BLOCK_READ_BMSK = 0x10, |
||
3154 | + S_SCMO_WCH_BUF_CFG_WRITE_BLOCK_READ_SHFT = 0x4, |
||
3155 | + S_SCMO_WCH_BUF_CFG_COALESCE_EN_BMSK = 0x1, |
||
3156 | + S_SCMO_WCH_BUF_CFG_COALESCE_EN_SHFT = 0x0, |
||
3157 | +}; |
||
3158 | + |
||
3159 | +#define S_SCMO_WCH_STATUS_ADDR(b, n) \ |
||
3160 | + (S_SCMO_REG_BASE(b) + (0x8000 * (n)) + 0x000005a0) |
||
3161 | +enum bimc_s_scmo_wch_status { |
||
3162 | + S_SCMO_WCH_STATUS_RMSK = 0x333, |
||
3163 | + S_SCMO_WCH_STATUS_BRESP_FIFO_FULL_BMSK = 0x200, |
||
3164 | + S_SCMO_WCH_STATUS_BRESP_FIFO_FULL_SHFT = 0x9, |
||
3165 | + S_SCMO_WCH_STATUS_BRESP_FIFO_EMPTY_BMSK = 0x100, |
||
3166 | + S_SCMO_WCH_STATUS_BRESP_FIFO_EMPTY_SHFT = 0x8, |
||
3167 | + S_SCMO_WCH_STATUS_WDATA_FIFO_FULL_BMSK = 0x20, |
||
3168 | + S_SCMO_WCH_STATUS_WDATA_FIFO_FULL_SHFT = 0x5, |
||
3169 | + S_SCMO_WCH_STATUS_WDATA_FIFO_EMPTY_BMSK = 0x10, |
||
3170 | + S_SCMO_WCH_STATUS_WDATA_FIFO_EMPTY_SHFT = 0x4, |
||
3171 | + S_SCMO_WCH_STATUS_WBUF_FULL_BMSK = 0x2, |
||
3172 | + S_SCMO_WCH_STATUS_WBUF_FULL_SHFT = 0x1, |
||
3173 | + S_SCMO_WCH_STATUS_WBUF_EMPTY_BMSK = 0x1, |
||
3174 | + S_SCMO_WCH_STATUS_WBUF_EMPTY_SHFT = 0x0, |
||
3175 | +}; |
||
3176 | + |
||
3177 | +#define S_SCMO_FLUSH_CFG_ADDR(b, n) \ |
||
3178 | + (S_SCMO_REG_BASE(b) + (0x8000 * (n)) + 0x000005c0) |
||
3179 | +enum bimc_s_scmo_flush_cfg { |
||
3180 | + S_SCMO_FLUSH_CFG_RMSK = 0xffffffff, |
||
3181 | + S_SCMO_FLUSH_CFG_FLUSH_IN_ORDER_BMSK = 0x10000000, |
||
3182 | + S_SCMO_FLUSH_CFG_FLUSH_IN_ORDER_SHFT = 0x1c, |
||
3183 | + S_SCMO_FLUSH_CFG_FLUSH_IDLE_DELAY_BMSK = 0x3ff0000, |
||
3184 | + S_SCMO_FLUSH_CFG_FLUSH_IDLE_DELAY_SHFT = 0x10, |
||
3185 | + S_SCMO_FLUSH_CFG_FLUSH_UPPER_LIMIT_BMSK = 0xf00, |
||
3186 | + S_SCMO_FLUSH_CFG_FLUSH_UPPER_LIMIT_SHFT = 0x8, |
||
3187 | + S_SCMO_FLUSH_CFG_FLUSH_LOWER_LIMIT_BMSK = 0xf, |
||
3188 | + S_SCMO_FLUSH_CFG_FLUSH_LOWER_LIMIT_SHFT = 0x0, |
||
3189 | +}; |
||
3190 | + |
||
3191 | +#define S_SCMO_FLUSH_CMD_ADDR(b, n) \ |
||
3192 | + (S_SCMO_REG_BASE(b) + (0x8000 * (n)) + 0x000005c4) |
||
3193 | +enum bimc_s_scmo_flush_cmd { |
||
3194 | + S_SCMO_FLUSH_CMD_RMSK = 0xf, |
||
3195 | + S_SCMO_FLUSH_CMD_FLUSH_ALL_BUF_BMSK = 0x3, |
||
3196 | + S_SCMO_FLUSH_CMD_FLUSH_ALL_BUF_SHFT = 0x0, |
||
3197 | +}; |
||
3198 | + |
||
3199 | +#define S_SCMO_CMD_OPT_CFG0_ADDR(b, n) \ |
||
3200 | + (S_SCM0_REG_BASE(b) + (0x8000 * (n)) + 0x00000700) |
||
3201 | +enum bimc_s_scmo_cmd_opt_cfg0 { |
||
3202 | + S_SCMO_CMD_OPT_CFG0_RMSK = 0xffffff, |
||
3203 | + S_SCMO_CMD_OPT_CFG0_IGNORE_BANK_UNAVL_BMSK = 0x100000, |
||
3204 | + S_SCMO_CMD_OPT_CFG0_IGNORE_BANK_UNAVL_SHFT = 0x14, |
||
3205 | + S_SCMO_CMD_OPT_CFG0_MASK_CMDOUT_PRI_BMSK = 0x10000, |
||
3206 | + S_SCMO_CMD_OPT_CFG0_MASK_CMDOUT_PRI_SHFT = 0x10, |
||
3207 | + S_SCMO_CMD_OPT_CFG0_DPE_CMD_REORDERING_BMSK = 0x1000, |
||
3208 | + S_SCMO_CMD_OPT_CFG0_DPE_CMD_REORDERING_SHFT = 0xc, |
||
3209 | + S_SCMO_CMD_OPT_CFG0_WR_OPT_EN_BMSK = 0x100, |
||
3210 | + S_SCMO_CMD_OPT_CFG0_WR_OPT_EN_SHFT = 0x8, |
||
3211 | + S_SCMO_CMD_OPT_CFG0_RD_OPT_EN_BMSK = 0x10, |
||
3212 | + S_SCMO_CMD_OPT_CFG0_RD_OPT_EN_SHFT = 0x4, |
||
3213 | + S_SCMO_CMD_OPT_CFG0_PAGE_MGMT_POLICY_BMSK = 0x1, |
||
3214 | + S_SCMO_CMD_OPT_CFG0_PAGE_MGMT_POLICY_SHFT = 0x0, |
||
3215 | +}; |
||
3216 | + |
||
3217 | +#define S_SCMO_CMD_OPT_CFG1_ADDR(b, n) \ |
||
3218 | + (S_SCMO_REG_BASE(b) + (0x8000 * (n)) + 0x00000704) |
||
3219 | +enum bimc_s_scmo_cmd_opt_cfg1 { |
||
3220 | + S_SCMO_CMD_OPT_CFG1_RMSK = 0xffffffff, |
||
3221 | + S_SCMO_CMD_OPT_CFG1_HSTP_CMD_TIMEOUT_BMSK = 0x1f000000, |
||
3222 | + S_SCMO_CMD_OPT_CFG1_HSTP_CMD_TIMEOUT_SHFT = 0x18, |
||
3223 | + S_SCMO_CMD_OPT_CFG1_HP_CMD_TIMEOUT_BMSK = 0x1f0000, |
||
3224 | + S_SCMO_CMD_OPT_CFG1_HP_CMD_TIMEOUT_SHFT = 0x10, |
||
3225 | + S_SCMO_CMD_OPT_CFG1_MP_CMD_TIMEOUT_BMSK = 0x1f00, |
||
3226 | + S_SCMO_CMD_OPT_CFG1_MP_CMD_TIMEOUT_SHFT = 0x8, |
||
3227 | + S_SCMO_CMD_OPT_CFG1_LP_CMD_TIMEOUT_BMSK = 0x1f, |
||
3228 | + S_SCMO_CMD_OPT_CFG1_LP_CMD_TIMEOUT_SHFT = 0x0, |
||
3229 | +}; |
||
3230 | + |
||
3231 | +#define S_SCMO_CMD_OPT_CFG2_ADDR(b, n) \ |
||
3232 | + (S_SCMO_REG_BASE(b) + (0x8000 * (n)) + 0x00000708) |
||
3233 | +enum bimc_s_scmo_cmd_opt_cfg2 { |
||
3234 | + S_SCMO_CMD_OPT_CFG2_RMSK = 0xff, |
||
3235 | + S_SCMO_CMD_OPT_CFG2_RWOPT_CMD_TIMEOUT_BMSK = 0xf, |
||
3236 | + S_SCMO_CMD_OPT_CFG2_RWOPT_CMD_TIMEOUT_SHFT = 0x0, |
||
3237 | +}; |
||
3238 | + |
||
3239 | +#define S_SCMO_CMD_OPT_CFG3_ADDR(b, n) \ |
||
3240 | + (S_SCMO_REG_BASE(b) + (0x8000 * (n)) + 0x0000070c) |
||
3241 | +enum bimc_s_scmo_cmd_opt_cfg3 { |
||
3242 | + S_SCMO_CMD_OPT_CFG3_RMSK = 0xff, |
||
3243 | + S_SCMO_CMD_OPT_CFG3_FLUSH_CMD_TIMEOUT_BMSK = 0xf, |
||
3244 | + S_SCMO_CMD_OPT_CFG3_FLUSH_CMD_TIMEOUT_SHFT = 0x0, |
||
3245 | +}; |
||
3246 | + |
||
3247 | +/* S_SWAY_GENERIC */ |
||
3248 | +#define S_SWAY_REG_BASE(b) ((b) + 0x00048000) |
||
3249 | + |
||
3250 | +#define S_SWAY_CONFIG_INFO_0_ADDR(b, n) \ |
||
3251 | + (S_SWAY_REG_BASE(b) + (0x8000 * (n)) + 0x00000020) |
||
3252 | +enum bimc_s_sway_config_info_0 { |
||
3253 | + S_SWAY_CONFIG_INFO_0_RMSK = 0xff0000ff, |
||
3254 | + S_SWAY_CONFIG_INFO_0_SYNC_MODE_BMSK = 0xff000000, |
||
3255 | + S_SWAY_CONFIG_INFO_0_SYNC_MODE_SHFT = 0x18, |
||
3256 | + S_SWAY_CONFIG_INFO_0_FUNC_BMSK = 0xff, |
||
3257 | + S_SWAY_CONFIG_INFO_0_FUNC_SHFT = 0x0, |
||
3258 | +}; |
||
3259 | + |
||
3260 | +#define S_SWAY_CONFIG_INFO_1_ADDR(b, n) \ |
||
3261 | + (S_SWAY_REG_BASE(b) + (0x8000 * (n)) + 0x00000030) |
||
3262 | +enum bimc_s_sway_config_info_1 { |
||
3263 | + S_SWAY_CONFIG_INFO_1_RMSK = 0xffffffff, |
||
3264 | + S_SWAY_CONFIG_INFO_1_MPORT_CONNECTIVITY_BMSK = 0xffffffff, |
||
3265 | + S_SWAY_CONFIG_INFO_1_MPORT_CONNECTIVITY_SHFT = 0x0, |
||
3266 | +}; |
||
3267 | + |
||
3268 | +#define S_SWAY_CONFIG_INFO_2_ADDR(b, n) \ |
||
3269 | + (S_SWAY_REG_BASE(b) + (0x8000 * (n)) + 0x00000040) |
||
3270 | +enum bimc_s_sway_config_info_2 { |
||
3271 | + S_SWAY_CONFIG_INFO_2_RMSK = 0xffff0000, |
||
3272 | + S_SWAY_CONFIG_INFO_2_MPORT_CONNECTIVITY_BMSK = 0xffff0000, |
||
3273 | + S_SWAY_CONFIG_INFO_2_MPORT_CONNECTIVITY_SHFT = 0x10, |
||
3274 | +}; |
||
3275 | + |
||
3276 | +#define S_SWAY_CONFIG_INFO_3_ADDR(b, n) \ |
||
3277 | + (S_SWAY_REG_BASE(b) + (0x8000 * (n)) + 0x00000050) |
||
3278 | +enum bimc_s_sway_config_info_3 { |
||
3279 | + S_SWAY_CONFIG_INFO_3_RMSK = 0xffffffff, |
||
3280 | + S_SWAY_CONFIG_INFO_3_RCH0_DEPTH_BMSK = 0xff000000, |
||
3281 | + S_SWAY_CONFIG_INFO_3_RCH0_DEPTH_SHFT = 0x18, |
||
3282 | + S_SWAY_CONFIG_INFO_3_BCH_DEPTH_BMSK = 0xff0000, |
||
3283 | + S_SWAY_CONFIG_INFO_3_BCH_DEPTH_SHFT = 0x10, |
||
3284 | + S_SWAY_CONFIG_INFO_3_WCH_DEPTH_BMSK = 0xff, |
||
3285 | + S_SWAY_CONFIG_INFO_3_WCH_DEPTH_SHFT = 0x0, |
||
3286 | +}; |
||
3287 | + |
||
3288 | +#define S_SWAY_CONFIG_INFO_4_ADDR(b, n) \ |
||
3289 | + (S_SWAY_REG_BASE(b) + (0x8000 * (n)) + 0x00000060) |
||
3290 | +enum bimc_s_sway_config_info_4 { |
||
3291 | + S_SWAY_CONFIG_INFO_4_RMSK = 0x800000ff, |
||
3292 | + S_SWAY_CONFIG_INFO_4_DUAL_RCH_EN_BMSK = 0x80000000, |
||
3293 | + S_SWAY_CONFIG_INFO_4_DUAL_RCH_EN_SHFT = 0x1f, |
||
3294 | + S_SWAY_CONFIG_INFO_4_RCH1_DEPTH_BMSK = 0xff, |
||
3295 | + S_SWAY_CONFIG_INFO_4_RCH1_DEPTH_SHFT = 0x0, |
||
3296 | +}; |
||
3297 | + |
||
3298 | +#define S_SWAY_CONFIG_INFO_5_ADDR(b, n) \ |
||
3299 | + (S_SWAY_REG_BASE(b) + (0x8000 * (n)) + 0x00000070) |
||
3300 | +enum bimc_s_sway_config_info_5 { |
||
3301 | + S_SWAY_CONFIG_INFO_5_RMSK = 0x800000ff, |
||
3302 | + S_SWAY_CONFIG_INFO_5_QCH_EN_BMSK = 0x80000000, |
||
3303 | + S_SWAY_CONFIG_INFO_5_QCH_EN_SHFT = 0x1f, |
||
3304 | + S_SWAY_CONFIG_INFO_5_QCH_DEPTH_BMSK = 0xff, |
||
3305 | + S_SWAY_CONFIG_INFO_5_QCH_DEPTH_SHFT = 0x0, |
||
3306 | +}; |
||
3307 | + |
||
3308 | +#define S_SWAY_CONFIG_INFO_6_ADDR(b, n) \ |
||
3309 | + (S_SWAY_REG_BASE(b) + (0x8000 * (n)) + 0x00000080) |
||
3310 | +enum bimc_s_sway_config_info_6 { |
||
3311 | + S_SWAY_CONFIG_INFO_6_RMSK = 0x1, |
||
3312 | + S_SWAY_CONFIG_INFO_6_S2SW_PIPELINE_EN_BMSK = 0x1, |
||
3313 | + S_SWAY_CONFIG_INFO_6_S2SW_PIPELINE_EN_SHFT = 0x0, |
||
3314 | +}; |
||
3315 | + |
||
3316 | +#define S_SWAY_INT_STATUS_ADDR(b, n) \ |
||
3317 | + (S_SWAY_REG_BASE(b) + (0x8000 * (n)) + 0x00000100) |
||
3318 | +enum bimc_s_sway_int_status { |
||
3319 | + S_SWAY_INT_STATUS_RMSK = 0x3, |
||
3320 | + S_SWAY_INT_STATUS_RFU_BMSK = 0x3, |
||
3321 | + S_SWAY_INT_STATUS_RFU_SHFT = 0x0, |
||
3322 | +}; |
||
3323 | + |
||
3324 | +#define S_SWAY_INT_CLR_ADDR(b, n) \ |
||
3325 | + (S_SWAY_REG_BASE(b) + (0x8000 * (n)) + 0x00000108) |
||
3326 | +enum bimc_s_sway_int_clr { |
||
3327 | + S_SWAY_INT_CLR_RMSK = 0x3, |
||
3328 | + S_SWAY_INT_CLR_RFU_BMSK = 0x3, |
||
3329 | + S_SWAY_INT_CLR_RFU_SHFT = 0x0, |
||
3330 | +}; |
||
3331 | + |
||
3332 | + |
||
3333 | +#define S_SWAY_INT_EN_ADDR(b, n) \ |
||
3334 | + (S_SWAY_REG_BASE(b) + (0x8000 * (n)) + 0x0000010c) |
||
3335 | +enum bimc_s_sway_int_en { |
||
3336 | + S_SWAY_INT_EN_RMSK = 0x3, |
||
3337 | + S_SWAY_INT_EN_RFU_BMSK = 0x3, |
||
3338 | + S_SWAY_INT_EN_RFU_SHFT = 0x0, |
||
3339 | +}; |
||
3340 | + |
||
3341 | +#define S_SWAY_CLK_CTRL_ADDR(b, n) \ |
||
3342 | + (S_SWAY_REG_BASE(b) + (0x8000 * (n)) + 0x00000200) |
||
3343 | +enum bimc_s_sway_clk_ctrl { |
||
3344 | + S_SWAY_CLK_CTRL_RMSK = 0x3, |
||
3345 | + S_SWAY_CLK_CTRL_SLAVE_CLK_GATING_EN_BMSK = 0x2, |
||
3346 | + S_SWAY_CLK_CTRL_SLAVE_CLK_GATING_EN_SHFT = 0x1, |
||
3347 | + S_SWAY_CLK_CTRL_CORE_CLK_GATING_EN_BMSK = 0x1, |
||
3348 | + S_SWAY_CLK_CTRL_CORE_CLK_GATING_EN_SHFT = 0x0, |
||
3349 | +}; |
||
3350 | + |
||
3351 | +#define S_SWAY_RCH_SEL_ADDR(b, n) \ |
||
3352 | + (S_SWAY_REG_BASE(b) + (0x8000 * (n)) + 0x00000210) |
||
3353 | +enum bimc_s_sway_rch_sel { |
||
3354 | + S_SWAY_RCH_SEL_RMSK = 0x7f, |
||
3355 | + S_SWAY_RCH_SEL_UNUSED_BMSK = 0x7f, |
||
3356 | + S_SWAY_RCH_SEL_UNUSED_SHFT = 0x0, |
||
3357 | +}; |
||
3358 | + |
||
3359 | + |
||
3360 | +#define S_SWAY_MAX_OUTSTANDING_REQS_ADDR(b, n) \ |
||
3361 | + (S_SWAY_REG_BASE(b) + (0x8000 * (n)) + 0x00000220) |
||
3362 | +enum bimc_s_sway_max_outstanding_reqs { |
||
3363 | + S_SWAY_MAX_OUTSTANDING_REQS_RMSK = 0xffff, |
||
3364 | + S_SWAY_MAX_OUTSTANDING_REQS_WRITE_BMSK = 0xff00, |
||
3365 | + S_SWAY_MAX_OUTSTANDING_REQS_WRITE_SHFT = 0x8, |
||
3366 | + S_SWAY_MAX_OUTSTANDING_REQS_READ_BMSK = 0xff, |
||
3367 | + S_SWAY_MAX_OUTSTANDING_REQS_READ_SHFT = 0x0, |
||
3368 | +}; |
||
3369 | + |
||
3370 | + |
||
3371 | +#define S_SWAY_BUF_STATUS_0_ADDR(b, n) \ |
||
3372 | + (S_SWAY_REG_BASE(b) + (0x8000 * (n)) + 0x00000400) |
||
3373 | +enum bimc_s_sway_buf_status_0 { |
||
3374 | + S_SWAY_BUF_STATUS_0_RMSK = 0xf0300f03, |
||
3375 | + S_SWAY_BUF_STATUS_0_RCH0_DATA_RD_FULL_BMSK = 0x80000000, |
||
3376 | + S_SWAY_BUF_STATUS_0_RCH0_DATA_RD_FULL_SHFT = 0x1f, |
||
3377 | + S_SWAY_BUF_STATUS_0_RCH0_DATA_RD_EMPTY_BMSK = 0x40000000, |
||
3378 | + S_SWAY_BUF_STATUS_0_RCH0_DATA_RD_EMPTY_SHFT = 0x1e, |
||
3379 | + S_SWAY_BUF_STATUS_0_RCH0_CTRL_RD_FULL_BMSK = 0x20000000, |
||
3380 | + S_SWAY_BUF_STATUS_0_RCH0_CTRL_RD_FULL_SHFT = 0x1d, |
||
3381 | + S_SWAY_BUF_STATUS_0_RCH0_CTRL_RD_EMPTY_BMSK = 0x10000000, |
||
3382 | + S_SWAY_BUF_STATUS_0_RCH0_CTRL_RD_EMPTY_SHFT = 0x1c, |
||
3383 | + S_SWAY_BUF_STATUS_0_BCH_RD_FULL_BMSK = 0x200000, |
||
3384 | + S_SWAY_BUF_STATUS_0_BCH_RD_FULL_SHFT = 0x15, |
||
3385 | + S_SWAY_BUF_STATUS_0_BCH_RD_EMPTY_BMSK = 0x100000, |
||
3386 | + S_SWAY_BUF_STATUS_0_BCH_RD_EMPTY_SHFT = 0x14, |
||
3387 | + S_SWAY_BUF_STATUS_0_WCH_DATA_WR_FULL_BMSK = 0x800, |
||
3388 | + S_SWAY_BUF_STATUS_0_WCH_DATA_WR_FULL_SHFT = 0xb, |
||
3389 | + S_SWAY_BUF_STATUS_0_WCH_DATA_WR_EMPTY_BMSK = 0x400, |
||
3390 | + S_SWAY_BUF_STATUS_0_WCH_DATA_WR_EMPTY_SHFT = 0xa, |
||
3391 | + S_SWAY_BUF_STATUS_0_WCH_CTRL_WR_FULL_BMSK = 0x200, |
||
3392 | + S_SWAY_BUF_STATUS_0_WCH_CTRL_WR_FULL_SHFT = 0x9, |
||
3393 | + S_SWAY_BUF_STATUS_0_WCH_CTRL_WR_EMPTY_BMSK = 0x100, |
||
3394 | + S_SWAY_BUF_STATUS_0_WCH_CTRL_WR_EMPTY_SHFT = 0x8, |
||
3395 | + S_SWAY_BUF_STATUS_0_ACH_WR_FULL_BMSK = 0x2, |
||
3396 | + S_SWAY_BUF_STATUS_0_ACH_WR_FULL_SHFT = 0x1, |
||
3397 | + S_SWAY_BUF_STATUS_0_ACH_WR_EMPTY_BMSK = 0x1, |
||
3398 | + S_SWAY_BUF_STATUS_0_ACH_WR_EMPTY_SHFT = 0x0, |
||
3399 | +}; |
||
3400 | + |
||
3401 | +#define S_SWAY_BUF_STATUS_1_ADDR(b, n) \ |
||
3402 | + (S_SWAY_REG_BASE(b) + (0x8000 * (n)) + 0x00000410) |
||
3403 | +enum bimc_s_sway_buf_status_1 { |
||
3404 | + S_SWAY_BUF_STATUS_1_RMSK = 0xf0, |
||
3405 | + S_SWAY_BUF_STATUS_1_RCH1_DATA_RD_FULL_BMSK = 0x80, |
||
3406 | + S_SWAY_BUF_STATUS_1_RCH1_DATA_RD_FULL_SHFT = 0x7, |
||
3407 | + S_SWAY_BUF_STATUS_1_RCH1_DATA_RD_EMPTY_BMSK = 0x40, |
||
3408 | + S_SWAY_BUF_STATUS_1_RCH1_DATA_RD_EMPTY_SHFT = 0x6, |
||
3409 | + S_SWAY_BUF_STATUS_1_RCH1_CTRL_RD_FULL_BMSK = 0x20, |
||
3410 | + S_SWAY_BUF_STATUS_1_RCH1_CTRL_RD_FULL_SHFT = 0x5, |
||
3411 | + S_SWAY_BUF_STATUS_1_RCH1_CTRL_RD_EMPTY_BMSK = 0x10, |
||
3412 | + S_SWAY_BUF_STATUS_1_RCH1_CTRL_RD_EMPTY_SHFT = 0x4, |
||
3413 | +}; |
||
3414 | + |
||
3415 | +#define S_SWAY_BUF_STATUS_2_ADDR(b, n) \ |
||
3416 | + (S_SWAY_REG_BASE(b) + (0x8000 * (n)) + 0x00000420) |
||
3417 | +enum bimc_s_sway_buf_status_2 { |
||
3418 | + S_SWAY_BUF_STATUS_2_RMSK = 0x30, |
||
3419 | + S_SWAY_BUF_STATUS_2_QCH_RD_FULL_BMSK = 0x20, |
||
3420 | + S_SWAY_BUF_STATUS_2_QCH_RD_FULL_SHFT = 0x5, |
||
3421 | + S_SWAY_BUF_STATUS_2_QCH_RD_EMPTY_BMSK = 0x10, |
||
3422 | + S_SWAY_BUF_STATUS_2_QCH_RD_EMPTY_SHFT = 0x4, |
||
3423 | +}; |
||
3424 | + |
||
3425 | +/* S_ARB_GENERIC */ |
||
3426 | + |
||
3427 | +#define S_ARB_REG_BASE(b) ((b) + 0x00049000) |
||
3428 | + |
||
3429 | +#define S_ARB_COMPONENT_INFO_ADDR(b, n) \ |
||
3430 | + (S_SWAY_REG_BASE(b) + (0x8000 * (n)) + 0x00000000) |
||
3431 | +enum bimc_s_arb_component_info { |
||
3432 | + S_ARB_COMPONENT_INFO_RMSK = 0xffffff, |
||
3433 | + S_ARB_COMPONENT_INFO_INSTANCE_BMSK = 0xff0000, |
||
3434 | + S_ARB_COMPONENT_INFO_INSTANCE_SHFT = 0x10, |
||
3435 | + S_ARB_COMPONENT_INFO_SUB_TYPE_BMSK = 0xff00, |
||
3436 | + S_ARB_COMPONENT_INFO_SUB_TYPE_SHFT = 0x8, |
||
3437 | + S_ARB_COMPONENT_INFO_TYPE_BMSK = 0xff, |
||
3438 | + S_ARB_COMPONENT_INFO_TYPE_SHFT = 0x0, |
||
3439 | +}; |
||
3440 | + |
||
3441 | +#define S_ARB_CONFIG_INFO_0_ADDR(b, n) \ |
||
3442 | + (S_ARB_REG_BASE(b) + (0x8000 * (n)) + 0x00000020) |
||
3443 | +enum bimc_s_arb_config_info_0 { |
||
3444 | + S_ARB_CONFIG_INFO_0_RMSK = 0x800000ff, |
||
3445 | + S_ARB_CONFIG_INFO_0_ARB2SW_PIPELINE_EN_BMSK = 0x80000000, |
||
3446 | + S_ARB_CONFIG_INFO_0_ARB2SW_PIPELINE_EN_SHFT = 0x1f, |
||
3447 | + S_ARB_CONFIG_INFO_0_FUNC_BMSK = 0xff, |
||
3448 | + S_ARB_CONFIG_INFO_0_FUNC_SHFT = 0x0, |
||
3449 | +}; |
||
3450 | + |
||
3451 | +#define S_ARB_CONFIG_INFO_1_ADDR(b, n) \ |
||
3452 | + (S_ARB_REG_BASE(b) + (0x8000 * (n)) + 0x00000030) |
||
3453 | +enum bimc_s_arb_config_info_1 { |
||
3454 | + S_ARB_CONFIG_INFO_1_RMSK = 0xffffffff, |
||
3455 | + S_ARB_CONFIG_INFO_1_MPORT_CONNECTIVITY_BMSK = 0xffffffff, |
||
3456 | + S_ARB_CONFIG_INFO_1_MPORT_CONNECTIVITY_SHFT = 0x0, |
||
3457 | +}; |
||
3458 | + |
||
3459 | +#define S_ARB_CLK_CTRL_ADDR(b) \ |
||
3460 | + (S_ARB_REG_BASE(b) + (0x8000 * (n)) + 0x00000200) |
||
3461 | +enum bimc_s_arb_clk_ctrl { |
||
3462 | + S_ARB_CLK_CTRL_RMSK = 0x1, |
||
3463 | + S_ARB_CLK_CTRL_SLAVE_CLK_GATING_EN_BMSK = 0x2, |
||
3464 | + S_ARB_CLK_CTRL_SLAVE_CLK_GATING_EN_SHFT = 0x1, |
||
3465 | + S_ARB_CLK_CTRL_CORE_CLK_GATING_EN_BMSK = 0x1, |
||
3466 | + S_ARB_CLK_CTRL_CORE_CLK_GATING_EN_SHFT = 0x0, |
||
3467 | + S_ARB_CLK_CTRL_CLK_GATING_EN_BMSK = 0x1, |
||
3468 | + S_ARB_CLK_CTRL_CLK_GATING_EN_SHFT = 0x0, |
||
3469 | +}; |
||
3470 | + |
||
3471 | +#define S_ARB_MODE_ADDR(b, n) \ |
||
3472 | + (S_ARB_REG_BASE(b) + (0x8000 * (n)) + 0x00000210) |
||
3473 | +enum bimc_s_arb_mode { |
||
3474 | + S_ARB_MODE_RMSK = 0xf0000001, |
||
3475 | + S_ARB_MODE_WR_GRANTS_AHEAD_BMSK = 0xf0000000, |
||
3476 | + S_ARB_MODE_WR_GRANTS_AHEAD_SHFT = 0x1c, |
||
3477 | + S_ARB_MODE_PRIO_RR_EN_BMSK = 0x1, |
||
3478 | + S_ARB_MODE_PRIO_RR_EN_SHFT = 0x0, |
||
3479 | +}; |
||
3480 | + |
||
3481 | +#define BKE_HEALTH_MASK \ |
||
3482 | + (M_BKE_HEALTH_0_CONFIG_LIMIT_CMDS_BMSK |\ |
||
3483 | + M_BKE_HEALTH_0_CONFIG_AREQPRIO_BMSK |\ |
||
3484 | + M_BKE_HEALTH_0_CONFIG_PRIOLVL_BMSK) |
||
3485 | + |
||
3486 | +#define BKE_HEALTH_VAL(limit, areq, plvl) \ |
||
3487 | + ((((limit) << M_BKE_HEALTH_0_CONFIG_LIMIT_CMDS_SHFT) & \ |
||
3488 | + M_BKE_HEALTH_0_CONFIG_LIMIT_CMDS_BMSK) | \ |
||
3489 | + (((areq) << M_BKE_HEALTH_0_CONFIG_AREQPRIO_SHFT) & \ |
||
3490 | + M_BKE_HEALTH_0_CONFIG_AREQPRIO_BMSK) | \ |
||
3491 | + (((plvl) << M_BKE_HEALTH_0_CONFIG_PRIOLVL_SHFT) & \ |
||
3492 | + M_BKE_HEALTH_0_CONFIG_PRIOLVL_BMSK)) |
||
3493 | + |
||
3494 | +#define MAX_GRANT_PERIOD \ |
||
3495 | + (M_BKE_GP_GP_BMSK >> \ |
||
3496 | + M_BKE_GP_GP_SHFT) |
||
3497 | + |
||
3498 | +#define MAX_GC \ |
||
3499 | + (M_BKE_GC_GC_BMSK >> \ |
||
3500 | + (M_BKE_GC_GC_SHFT + 1)) |
||
3501 | + |
||
3502 | +static int bimc_div(int64_t *a, uint32_t b) |
||
3503 | +{ |
||
3504 | + if ((*a > 0) && (*a < b)) { |
||
3505 | + *a = 0; |
||
3506 | + return 1; |
||
3507 | + } else { |
||
3508 | + return do_div(*a, b); |
||
3509 | + } |
||
3510 | +} |
||
3511 | + |
||
3512 | +#define ENABLE(val) ((val) == 1 ? 1 : 0) |
||
3513 | +void msm_bus_bimc_set_mas_clk_gate(struct msm_bus_bimc_info *binfo, |
||
3514 | + uint32_t mas_index, struct msm_bus_bimc_clk_gate *bgate) |
||
3515 | +{ |
||
3516 | + uint32_t val, mask, reg_val; |
||
3517 | + void __iomem *addr; |
||
3518 | + |
||
3519 | + reg_val = readl_relaxed(M_CLK_CTRL_ADDR(binfo->base, |
||
3520 | + mas_index)) & M_CLK_CTRL_RMSK; |
||
3521 | + addr = M_CLK_CTRL_ADDR(binfo->base, mas_index); |
||
3522 | + mask = (M_CLK_CTRL_MAS_CLK_GATING_EN_BMSK | |
||
3523 | + M_CLK_CTRL_CORE_CLK_GATING_EN_BMSK); |
||
3524 | + val = (bgate->core_clk_gate_en << |
||
3525 | + M_CLK_CTRL_MAS_CLK_GATING_EN_SHFT) | |
||
3526 | + bgate->port_clk_gate_en; |
||
3527 | + writel_relaxed(((reg_val & (~mask)) | (val & mask)), addr); |
||
3528 | + /* Ensure clock gating enable mask is set before exiting */ |
||
3529 | + wmb(); |
||
3530 | +} |
||
3531 | + |
||
3532 | +void msm_bus_bimc_arb_en(struct msm_bus_bimc_info *binfo, |
||
3533 | + uint32_t slv_index, bool en) |
||
3534 | +{ |
||
3535 | + uint32_t reg_val, reg_mask_val, enable, val; |
||
3536 | + |
||
3537 | + reg_mask_val = (readl_relaxed(S_ARB_CONFIG_INFO_0_ADDR(binfo-> |
||
3538 | + base, slv_index)) & S_ARB_CONFIG_INFO_0_FUNC_BMSK) |
||
3539 | + >> S_ARB_CONFIG_INFO_0_FUNC_SHFT; |
||
3540 | + enable = ENABLE(en); |
||
3541 | + val = enable << S_ARB_MODE_PRIO_RR_EN_SHFT; |
||
3542 | + if (reg_mask_val == BIMC_ARB_MODE_PRIORITY_RR) { |
||
3543 | + reg_val = readl_relaxed(S_ARB_CONFIG_INFO_0_ADDR(binfo-> |
||
3544 | + base, slv_index)) & S_ARB_MODE_RMSK; |
||
3545 | + writel_relaxed(((reg_val & (~(S_ARB_MODE_PRIO_RR_EN_BMSK))) | |
||
3546 | + (val & S_ARB_MODE_PRIO_RR_EN_BMSK)), |
||
3547 | + S_ARB_MODE_ADDR(binfo->base, slv_index)); |
||
3548 | + /* Ensure arbitration mode is set before returning */ |
||
3549 | + wmb(); |
||
3550 | + } |
||
3551 | +} |
||
3552 | + |
||
3553 | +static void set_qos_mode(void __iomem *baddr, uint32_t index, uint32_t val0, |
||
3554 | + uint32_t val1, uint32_t val2) |
||
3555 | +{ |
||
3556 | + uint32_t reg_val, val; |
||
3557 | + |
||
3558 | + reg_val = readl_relaxed(M_PRIOLVL_OVERRIDE_ADDR(baddr, |
||
3559 | + index)) & M_PRIOLVL_OVERRIDE_RMSK; |
||
3560 | + val = val0 << M_PRIOLVL_OVERRIDE_OVERRIDE_PRIOLVL_SHFT; |
||
3561 | + writel_relaxed(((reg_val & ~(M_PRIOLVL_OVERRIDE_OVERRIDE_PRIOLVL_BMSK)) |
||
3562 | + | (val & M_PRIOLVL_OVERRIDE_OVERRIDE_PRIOLVL_BMSK)), |
||
3563 | + M_PRIOLVL_OVERRIDE_ADDR(baddr, index)); |
||
3564 | + reg_val = readl_relaxed(M_RD_CMD_OVERRIDE_ADDR(baddr, index)) & |
||
3565 | + M_RD_CMD_OVERRIDE_RMSK; |
||
3566 | + val = val1 << M_RD_CMD_OVERRIDE_OVERRIDE_AREQPRIO_SHFT; |
||
3567 | + writel_relaxed(((reg_val & ~(M_RD_CMD_OVERRIDE_OVERRIDE_AREQPRIO_BMSK |
||
3568 | + )) | (val & M_RD_CMD_OVERRIDE_OVERRIDE_AREQPRIO_BMSK)), |
||
3569 | + M_RD_CMD_OVERRIDE_ADDR(baddr, index)); |
||
3570 | + reg_val = readl_relaxed(M_WR_CMD_OVERRIDE_ADDR(baddr, index)) & |
||
3571 | + M_WR_CMD_OVERRIDE_RMSK; |
||
3572 | + val = val2 << M_WR_CMD_OVERRIDE_OVERRIDE_AREQPRIO_SHFT; |
||
3573 | + writel_relaxed(((reg_val & ~(M_WR_CMD_OVERRIDE_OVERRIDE_AREQPRIO_BMSK |
||
3574 | + )) | (val & M_WR_CMD_OVERRIDE_OVERRIDE_AREQPRIO_BMSK)), |
||
3575 | + M_WR_CMD_OVERRIDE_ADDR(baddr, index)); |
||
3576 | + /* Ensure the priority register writes go through */ |
||
3577 | + wmb(); |
||
3578 | +} |
||
3579 | + |
||
3580 | +static void msm_bus_bimc_set_qos_mode(void __iomem *base, |
||
3581 | + uint32_t mas_index, uint8_t qmode_sel) |
||
3582 | +{ |
||
3583 | + uint32_t reg_val, val; |
||
3584 | + |
||
3585 | + switch (qmode_sel) { |
||
3586 | + case BIMC_QOS_MODE_FIXED: |
||
3587 | + reg_val = readl_relaxed(M_BKE_EN_ADDR(base, |
||
3588 | + mas_index)); |
||
3589 | + writel_relaxed((reg_val & (~M_BKE_EN_EN_BMSK)), |
||
3590 | + M_BKE_EN_ADDR(base, mas_index)); |
||
3591 | + /* Ensure that the book-keeping register writes |
||
3592 | + * go through before setting QoS mode. |
||
3593 | + * QoS mode registers might write beyond 1K |
||
3594 | + * boundary in future |
||
3595 | + */ |
||
3596 | + wmb(); |
||
3597 | + set_qos_mode(base, mas_index, 1, 1, 1); |
||
3598 | + break; |
||
3599 | + |
||
3600 | + case BIMC_QOS_MODE_BYPASS: |
||
3601 | + reg_val = readl_relaxed(M_BKE_EN_ADDR(base, |
||
3602 | + mas_index)); |
||
3603 | + writel_relaxed((reg_val & (~M_BKE_EN_EN_BMSK)), |
||
3604 | + M_BKE_EN_ADDR(base, mas_index)); |
||
3605 | + /* Ensure that the book-keeping register writes |
||
3606 | + * go through before setting QoS mode. |
||
3607 | + * QoS mode registers might write beyond 1K |
||
3608 | + * boundary in future |
||
3609 | + */ |
||
3610 | + wmb(); |
||
3611 | + set_qos_mode(base, mas_index, 0, 0, 0); |
||
3612 | + break; |
||
3613 | + |
||
3614 | + case BIMC_QOS_MODE_REGULATOR: |
||
3615 | + case BIMC_QOS_MODE_LIMITER: |
||
3616 | + set_qos_mode(base, mas_index, 0, 0, 0); |
||
3617 | + reg_val = readl_relaxed(M_BKE_EN_ADDR(base, |
||
3618 | + mas_index)); |
||
3619 | + val = 1 << M_BKE_EN_EN_SHFT; |
||
3620 | + /* Ensure that the book-keeping register writes |
||
3621 | + * go through before setting QoS mode. |
||
3622 | + * QoS mode registers might write beyond 1K |
||
3623 | + * boundary in future |
||
3624 | + */ |
||
3625 | + wmb(); |
||
3626 | + writel_relaxed(((reg_val & (~M_BKE_EN_EN_BMSK)) | (val & |
||
3627 | + M_BKE_EN_EN_BMSK)), M_BKE_EN_ADDR(base, |
||
3628 | + mas_index)); |
||
3629 | + break; |
||
3630 | + default: |
||
3631 | + break; |
||
3632 | + } |
||
3633 | +} |
||
3634 | + |
||
3635 | +static void set_qos_prio_rl(void __iomem *addr, uint32_t rmsk, |
||
3636 | + uint8_t index, struct msm_bus_bimc_qos_mode *qmode) |
||
3637 | +{ |
||
3638 | + uint32_t reg_val, val0, val; |
||
3639 | + |
||
3640 | + /* Note, addr is already passed with right mas_index */ |
||
3641 | + reg_val = readl_relaxed(addr) & rmsk; |
||
3642 | + val0 = BKE_HEALTH_VAL(qmode->rl.qhealth[index].limit_commands, |
||
3643 | + qmode->rl.qhealth[index].areq_prio, |
||
3644 | + qmode->rl.qhealth[index].prio_level); |
||
3645 | + val = ((reg_val & (~(BKE_HEALTH_MASK))) | (val0 & BKE_HEALTH_MASK)); |
||
3646 | + writel_relaxed(val, addr); |
||
3647 | + /* Ensure that priority for regulator/limiter modes are |
||
3648 | + * set before returning |
||
3649 | + */ |
||
3650 | + wmb(); |
||
3651 | + |
||
3652 | +} |
||
3653 | + |
||
3654 | +static void msm_bus_bimc_set_qos_prio(void __iomem *base, |
||
3655 | + uint32_t mas_index, uint8_t qmode_sel, |
||
3656 | + struct msm_bus_bimc_qos_mode *qmode) |
||
3657 | +{ |
||
3658 | + uint32_t reg_val, val; |
||
3659 | + |
||
3660 | + switch (qmode_sel) { |
||
3661 | + case BIMC_QOS_MODE_FIXED: |
||
3662 | + reg_val = readl_relaxed(M_PRIOLVL_OVERRIDE_ADDR( |
||
3663 | + base, mas_index)) & M_PRIOLVL_OVERRIDE_RMSK; |
||
3664 | + val = qmode->fixed.prio_level << |
||
3665 | + M_PRIOLVL_OVERRIDE_SHFT; |
||
3666 | + writel_relaxed(((reg_val & |
||
3667 | + ~(M_PRIOLVL_OVERRIDE_BMSK)) | (val |
||
3668 | + & M_PRIOLVL_OVERRIDE_BMSK)), |
||
3669 | + M_PRIOLVL_OVERRIDE_ADDR(base, mas_index)); |
||
3670 | + |
||
3671 | + reg_val = readl_relaxed(M_RD_CMD_OVERRIDE_ADDR( |
||
3672 | + base, mas_index)) & M_RD_CMD_OVERRIDE_RMSK; |
||
3673 | + val = qmode->fixed.areq_prio_rd << |
||
3674 | + M_RD_CMD_OVERRIDE_AREQPRIO_SHFT; |
||
3675 | + writel_relaxed(((reg_val & ~(M_RD_CMD_OVERRIDE_AREQPRIO_BMSK)) |
||
3676 | + | (val & M_RD_CMD_OVERRIDE_AREQPRIO_BMSK)), |
||
3677 | + M_RD_CMD_OVERRIDE_ADDR(base, mas_index)); |
||
3678 | + |
||
3679 | + reg_val = readl_relaxed(M_WR_CMD_OVERRIDE_ADDR( |
||
3680 | + base, mas_index)) & M_WR_CMD_OVERRIDE_RMSK; |
||
3681 | + val = qmode->fixed.areq_prio_wr << |
||
3682 | + M_WR_CMD_OVERRIDE_AREQPRIO_SHFT; |
||
3683 | + writel_relaxed(((reg_val & ~(M_WR_CMD_OVERRIDE_AREQPRIO_BMSK)) |
||
3684 | + | (val & M_WR_CMD_OVERRIDE_AREQPRIO_BMSK)), |
||
3685 | + M_WR_CMD_OVERRIDE_ADDR(base, mas_index)); |
||
3686 | + /* Ensure that fixed mode register writes go through |
||
3687 | + * before returning |
||
3688 | + */ |
||
3689 | + wmb(); |
||
3690 | + break; |
||
3691 | + |
||
3692 | + case BIMC_QOS_MODE_REGULATOR: |
||
3693 | + case BIMC_QOS_MODE_LIMITER: |
||
3694 | + set_qos_prio_rl(M_BKE_HEALTH_3_CONFIG_ADDR(base, |
||
3695 | + mas_index), M_BKE_HEALTH_3_CONFIG_RMSK, 3, qmode); |
||
3696 | + set_qos_prio_rl(M_BKE_HEALTH_2_CONFIG_ADDR(base, |
||
3697 | + mas_index), M_BKE_HEALTH_2_CONFIG_RMSK, 2, qmode); |
||
3698 | + set_qos_prio_rl(M_BKE_HEALTH_1_CONFIG_ADDR(base, |
||
3699 | + mas_index), M_BKE_HEALTH_1_CONFIG_RMSK, 1, qmode); |
||
3700 | + set_qos_prio_rl(M_BKE_HEALTH_0_CONFIG_ADDR(base, |
||
3701 | + mas_index), M_BKE_HEALTH_0_CONFIG_RMSK, 0 , qmode); |
||
3702 | + break; |
||
3703 | + case BIMC_QOS_MODE_BYPASS: |
||
3704 | + default: |
||
3705 | + break; |
||
3706 | + } |
||
3707 | +} |
||
3708 | + |
||
3709 | +static void set_qos_bw_regs(void __iomem *baddr, uint32_t mas_index, |
||
3710 | + int32_t th, int32_t tm, int32_t tl, uint32_t gp, |
||
3711 | + uint32_t gc) |
||
3712 | +{ |
||
3713 | + int32_t reg_val, val; |
||
3714 | + int32_t bke_reg_val; |
||
3715 | + int16_t val2; |
||
3716 | + |
||
3717 | + /* Disable BKE before writing to registers as per spec */ |
||
3718 | + bke_reg_val = readl_relaxed(M_BKE_EN_ADDR(baddr, mas_index)); |
||
3719 | + writel_relaxed((bke_reg_val & ~(M_BKE_EN_EN_BMSK)), |
||
3720 | + M_BKE_EN_ADDR(baddr, mas_index)); |
||
3721 | + |
||
3722 | + /* Write values of registers calculated */ |
||
3723 | + reg_val = readl_relaxed(M_BKE_GP_ADDR(baddr, mas_index)) |
||
3724 | + & M_BKE_GP_RMSK; |
||
3725 | + val = gp << M_BKE_GP_GP_SHFT; |
||
3726 | + writel_relaxed(((reg_val & ~(M_BKE_GP_GP_BMSK)) | (val & |
||
3727 | + M_BKE_GP_GP_BMSK)), M_BKE_GP_ADDR(baddr, mas_index)); |
||
3728 | + |
||
3729 | + reg_val = readl_relaxed(M_BKE_GC_ADDR(baddr, mas_index)) & |
||
3730 | + M_BKE_GC_RMSK; |
||
3731 | + val = gc << M_BKE_GC_GC_SHFT; |
||
3732 | + writel_relaxed(((reg_val & ~(M_BKE_GC_GC_BMSK)) | (val & |
||
3733 | + M_BKE_GC_GC_BMSK)), M_BKE_GC_ADDR(baddr, mas_index)); |
||
3734 | + |
||
3735 | + reg_val = readl_relaxed(M_BKE_THH_ADDR(baddr, mas_index)) & |
||
3736 | + M_BKE_THH_RMSK; |
||
3737 | + val = th << M_BKE_THH_THRESH_SHFT; |
||
3738 | + writel_relaxed(((reg_val & ~(M_BKE_THH_THRESH_BMSK)) | (val & |
||
3739 | + M_BKE_THH_THRESH_BMSK)), M_BKE_THH_ADDR(baddr, mas_index)); |
||
3740 | + |
||
3741 | + reg_val = readl_relaxed(M_BKE_THM_ADDR(baddr, mas_index)) & |
||
3742 | + M_BKE_THM_RMSK; |
||
3743 | + val2 = tm << M_BKE_THM_THRESH_SHFT; |
||
3744 | + writel_relaxed(((reg_val & ~(M_BKE_THM_THRESH_BMSK)) | (val2 & |
||
3745 | + M_BKE_THM_THRESH_BMSK)), M_BKE_THM_ADDR(baddr, mas_index)); |
||
3746 | + |
||
3747 | + reg_val = readl_relaxed(M_BKE_THL_ADDR(baddr, mas_index)) & |
||
3748 | + M_BKE_THL_RMSK; |
||
3749 | + val2 = tl << M_BKE_THL_THRESH_SHFT; |
||
3750 | + writel_relaxed(((reg_val & ~(M_BKE_THL_THRESH_BMSK)) | |
||
3751 | + (val2 & M_BKE_THL_THRESH_BMSK)), M_BKE_THL_ADDR(baddr, |
||
3752 | + mas_index)); |
||
3753 | + |
||
3754 | + /* Ensure that all bandwidth register writes have completed |
||
3755 | + * before returning |
||
3756 | + */ |
||
3757 | + wmb(); |
||
3758 | +} |
||
3759 | + |
||
3760 | +static void msm_bus_bimc_set_qos_bw(void __iomem *base, uint32_t qos_freq, |
||
3761 | + uint32_t mas_index, struct msm_bus_bimc_qos_bw *qbw) |
||
3762 | +{ |
||
3763 | + uint32_t bke_en; |
||
3764 | + |
||
3765 | + /* Validate QOS Frequency */ |
||
3766 | + if (qos_freq == 0) { |
||
3767 | + MSM_BUS_DBG("Zero frequency\n"); |
||
3768 | + return; |
||
3769 | + } |
||
3770 | + |
||
3771 | + /* Get enable bit for BKE before programming the period */ |
||
3772 | + bke_en = (readl_relaxed(M_BKE_EN_ADDR(base, mas_index)) & |
||
3773 | + M_BKE_EN_EN_BMSK) >> M_BKE_EN_EN_SHFT; |
||
3774 | + |
||
3775 | + /* Only calculate if there's a requested bandwidth and window */ |
||
3776 | + if (qbw->bw && qbw->ws) { |
||
3777 | + int64_t th, tm, tl; |
||
3778 | + uint32_t gp, gc; |
||
3779 | + int64_t gp_nominal, gp_required, gp_calc, data, temp; |
||
3780 | + int64_t win = qbw->ws * qos_freq; |
||
3781 | + temp = win; |
||
3782 | + /* |
||
3783 | + * Calculate nominal grant period defined by requested |
||
3784 | + * window size. |
||
3785 | + * Ceil this value to max grant period. |
||
3786 | + */ |
||
3787 | + bimc_div(&temp, 1000000); |
||
3788 | + gp_nominal = min_t(uint64_t, MAX_GRANT_PERIOD, temp); |
||
3789 | + /* |
||
3790 | + * Calculate max window size, defined by bw request. |
||
3791 | + * Units: (KHz, MB/s) |
||
3792 | + */ |
||
3793 | + gp_calc = MAX_GC * qos_freq * 1000; |
||
3794 | + gp_required = gp_calc; |
||
3795 | + bimc_div(&gp_required, qbw->bw); |
||
3796 | + |
||
3797 | + /* User min of two grant periods */ |
||
3798 | + gp = min_t(int64_t, gp_nominal, gp_required); |
||
3799 | + |
||
3800 | + /* Calculate bandwith in grants and ceil. */ |
||
3801 | + temp = qbw->bw * gp; |
||
3802 | + data = qos_freq * 1000; |
||
3803 | + bimc_div(&temp, data); |
||
3804 | + gc = min_t(int64_t, MAX_GC, temp); |
||
3805 | + |
||
3806 | + /* Calculate thresholds */ |
||
3807 | + th = qbw->bw - qbw->thh; |
||
3808 | + tm = qbw->bw - qbw->thm; |
||
3809 | + tl = qbw->bw - qbw->thl; |
||
3810 | + |
||
3811 | + th = th * gp; |
||
3812 | + bimc_div(&th, data); |
||
3813 | + tm = tm * gp; |
||
3814 | + bimc_div(&tm, data); |
||
3815 | + tl = tl * gp; |
||
3816 | + bimc_div(&tl, data); |
||
3817 | + |
||
3818 | + MSM_BUS_DBG("BIMC: BW: mas_index: %d, th: %llu tm: %llu\n", |
||
3819 | + mas_index, th, tm); |
||
3820 | + MSM_BUS_DBG("BIMC: tl: %llu gp:%u gc: %u bke_en: %u\n", |
||
3821 | + tl, gp, gc, bke_en); |
||
3822 | + set_qos_bw_regs(base, mas_index, th, tm, tl, gp, gc); |
||
3823 | + } else |
||
3824 | + /* Clear bandwidth registers */ |
||
3825 | + set_qos_bw_regs(base, mas_index, 0, 0, 0, 0, 0); |
||
3826 | +} |
||
3827 | + |
||
3828 | +static int msm_bus_bimc_allocate_commit_data(struct msm_bus_fabric_registration |
||
3829 | + *fab_pdata, void **cdata, int ctx) |
||
3830 | +{ |
||
3831 | + struct msm_bus_bimc_commit **cd = (struct msm_bus_bimc_commit **)cdata; |
||
3832 | + struct msm_bus_bimc_info *binfo = |
||
3833 | + (struct msm_bus_bimc_info *)fab_pdata->hw_data; |
||
3834 | + |
||
3835 | + MSM_BUS_DBG("Allocating BIMC commit data\n"); |
||
3836 | + *cd = kzalloc(sizeof(struct msm_bus_bimc_commit), GFP_KERNEL); |
||
3837 | + if (!*cd) { |
||
3838 | + MSM_BUS_DBG("Couldn't alloc mem for cdata\n"); |
||
3839 | + return -ENOMEM; |
||
3840 | + } |
||
3841 | + |
||
3842 | + (*cd)->mas = binfo->cdata[ctx].mas; |
||
3843 | + (*cd)->slv = binfo->cdata[ctx].slv; |
||
3844 | + |
||
3845 | + return 0; |
||
3846 | +} |
||
3847 | + |
||
3848 | +static void *msm_bus_bimc_allocate_bimc_data(struct platform_device *pdev, |
||
3849 | + struct msm_bus_fabric_registration *fab_pdata) |
||
3850 | +{ |
||
3851 | + struct resource *bimc_mem; |
||
3852 | + struct resource *bimc_io; |
||
3853 | + struct msm_bus_bimc_info *binfo; |
||
3854 | + int i; |
||
3855 | + |
||
3856 | + MSM_BUS_DBG("Allocating BIMC data\n"); |
||
3857 | + binfo = kzalloc(sizeof(struct msm_bus_bimc_info), GFP_KERNEL); |
||
3858 | + if (!binfo) { |
||
3859 | + WARN(!binfo, "Couldn't alloc mem for bimc_info\n"); |
||
3860 | + return NULL; |
||
3861 | + } |
||
3862 | + |
||
3863 | + binfo->qos_freq = fab_pdata->qos_freq; |
||
3864 | + |
||
3865 | + binfo->params.nmasters = fab_pdata->nmasters; |
||
3866 | + binfo->params.nslaves = fab_pdata->nslaves; |
||
3867 | + binfo->params.bus_id = fab_pdata->id; |
||
3868 | + |
||
3869 | + for (i = 0; i < NUM_CTX; i++) { |
||
3870 | + binfo->cdata[i].mas = kzalloc(sizeof(struct |
||
3871 | + msm_bus_node_hw_info) * fab_pdata->nmasters * 2, |
||
3872 | + GFP_KERNEL); |
||
3873 | + if (!binfo->cdata[i].mas) { |
||
3874 | + MSM_BUS_ERR("Couldn't alloc mem for bimc master hw\n"); |
||
3875 | + kfree(binfo); |
||
3876 | + return NULL; |
||
3877 | + } |
||
3878 | + |
||
3879 | + binfo->cdata[i].slv = kzalloc(sizeof(struct |
||
3880 | + msm_bus_node_hw_info) * fab_pdata->nslaves * 2, |
||
3881 | + GFP_KERNEL); |
||
3882 | + if (!binfo->cdata[i].slv) { |
||
3883 | + MSM_BUS_DBG("Couldn't alloc mem for bimc slave hw\n"); |
||
3884 | + kfree(binfo->cdata[i].mas); |
||
3885 | + kfree(binfo); |
||
3886 | + return NULL; |
||
3887 | + } |
||
3888 | + } |
||
3889 | + |
||
3890 | + if (fab_pdata->virt) { |
||
3891 | + MSM_BUS_DBG("Don't get memory regions for virtual fabric\n"); |
||
3892 | + goto skip_mem; |
||
3893 | + } |
||
3894 | + |
||
3895 | + bimc_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
||
3896 | + if (!bimc_mem) { |
||
3897 | + MSM_BUS_ERR("Cannot get BIMC Base address\n"); |
||
3898 | + kfree(binfo); |
||
3899 | + return NULL; |
||
3900 | + } |
||
3901 | + |
||
3902 | + bimc_io = request_mem_region(bimc_mem->start, |
||
3903 | + resource_size(bimc_mem), pdev->name); |
||
3904 | + if (!bimc_io) { |
||
3905 | + MSM_BUS_ERR("BIMC memory unavailable\n"); |
||
3906 | + kfree(binfo); |
||
3907 | + return NULL; |
||
3908 | + } |
||
3909 | + |
||
3910 | + binfo->base = ioremap(bimc_mem->start, resource_size(bimc_mem)); |
||
3911 | + if (!binfo->base) { |
||
3912 | + MSM_BUS_ERR("IOremap failed for BIMC!\n"); |
||
3913 | + release_mem_region(bimc_mem->start, resource_size(bimc_mem)); |
||
3914 | + kfree(binfo); |
||
3915 | + return NULL; |
||
3916 | + } |
||
3917 | + |
||
3918 | +skip_mem: |
||
3919 | + fab_pdata->hw_data = (void *)binfo; |
||
3920 | + return (void *)binfo; |
||
3921 | +} |
||
3922 | + |
||
3923 | +static void free_commit_data(void *cdata) |
||
3924 | +{ |
||
3925 | + struct msm_bus_bimc_commit *cd = (struct msm_bus_bimc_commit *)cdata; |
||
3926 | + |
||
3927 | + kfree(cd->mas); |
||
3928 | + kfree(cd->slv); |
||
3929 | + kfree(cd); |
||
3930 | +} |
||
3931 | + |
||
3932 | +static void bke_switch( |
||
3933 | + void __iomem *baddr, uint32_t mas_index, bool req, int mode) |
||
3934 | +{ |
||
3935 | + uint32_t reg_val, val, cur_val; |
||
3936 | + |
||
3937 | + val = req << M_BKE_EN_EN_SHFT; |
||
3938 | + reg_val = readl_relaxed(M_BKE_EN_ADDR(baddr, mas_index)); |
||
3939 | + cur_val = reg_val & M_BKE_EN_RMSK; |
||
3940 | + if (val == cur_val) |
||
3941 | + return; |
||
3942 | + |
||
3943 | + if (!req && mode == BIMC_QOS_MODE_FIXED) |
||
3944 | + set_qos_mode(baddr, mas_index, 1, 1, 1); |
||
3945 | + |
||
3946 | + writel_relaxed(((reg_val & ~(M_BKE_EN_EN_BMSK)) | (val & |
||
3947 | + M_BKE_EN_EN_BMSK)), M_BKE_EN_ADDR(baddr, mas_index)); |
||
3948 | + /* Make sure BKE on/off goes through before changing priorities */ |
||
3949 | + wmb(); |
||
3950 | + |
||
3951 | + if (req) |
||
3952 | + set_qos_mode(baddr, mas_index, 0, 0, 0); |
||
3953 | +} |
||
3954 | + |
||
3955 | +static void bimc_set_static_qos_bw(void __iomem *base, unsigned int qos_freq, |
||
3956 | + int mport, struct msm_bus_bimc_qos_bw *qbw) |
||
3957 | +{ |
||
3958 | + int32_t bw_mbps, thh = 0, thm, thl, gc; |
||
3959 | + int32_t gp; |
||
3960 | + u64 temp; |
||
3961 | + |
||
3962 | + if (qos_freq == 0) { |
||
3963 | + MSM_BUS_DBG("No QoS Frequency.\n"); |
||
3964 | + return; |
||
3965 | + } |
||
3966 | + |
||
3967 | + if (!(qbw->bw && qbw->gp)) { |
||
3968 | + MSM_BUS_DBG("No QoS Bandwidth or Window size\n"); |
||
3969 | + return; |
||
3970 | + } |
||
3971 | + |
||
3972 | + /* Convert bandwidth to MBPS */ |
||
3973 | + temp = qbw->bw; |
||
3974 | + bimc_div(&temp, 1000000); |
||
3975 | + bw_mbps = temp; |
||
3976 | + |
||
3977 | + /* Grant period in clock cycles |
||
3978 | + * Grant period from bandwidth structure |
||
3979 | + * is in nano seconds, QoS freq is in KHz. |
||
3980 | + * Divide by 1000 to get clock cycles. |
||
3981 | + */ |
||
3982 | + gp = (qos_freq * qbw->gp) / (1000 * NSEC_PER_USEC); |
||
3983 | + |
||
3984 | + /* Grant count = BW in MBps * Grant period |
||
3985 | + * in micro seconds |
||
3986 | + */ |
||
3987 | + gc = bw_mbps * (qbw->gp / NSEC_PER_USEC); |
||
3988 | + gc = min(gc, MAX_GC); |
||
3989 | + |
||
3990 | + /* Medium threshold = -((Medium Threshold percentage * |
||
3991 | + * Grant count) / 100) |
||
3992 | + */ |
||
3993 | + thm = -((qbw->thmp * gc) / 100); |
||
3994 | + qbw->thm = thm; |
||
3995 | + |
||
3996 | + /* Low threshold = -(Grant count) */ |
||
3997 | + thl = -gc; |
||
3998 | + qbw->thl = thl; |
||
3999 | + |
||
4000 | + MSM_BUS_DBG("%s: BKE parameters: gp %d, gc %d, thm %d thl %d thh %d", |
||
4001 | + __func__, gp, gc, thm, thl, thh); |
||
4002 | + |
||
4003 | + trace_bus_bke_params(gc, gp, thl, thm, thl); |
||
4004 | + set_qos_bw_regs(base, mport, thh, thm, thl, gp, gc); |
||
4005 | +} |
||
4006 | + |
||
4007 | +static void msm_bus_bimc_config_master( |
||
4008 | + struct msm_bus_fabric_registration *fab_pdata, |
||
4009 | + struct msm_bus_inode_info *info, |
||
4010 | + uint64_t req_clk, uint64_t req_bw) |
||
4011 | +{ |
||
4012 | + int mode, i, ports; |
||
4013 | + struct msm_bus_bimc_info *binfo; |
||
4014 | + uint64_t bw = 0; |
||
4015 | + |
||
4016 | + binfo = (struct msm_bus_bimc_info *)fab_pdata->hw_data; |
||
4017 | + ports = info->node_info->num_mports; |
||
4018 | + |
||
4019 | + /** |
||
4020 | + * Here check the details of dual configuration. |
||
4021 | + * Take actions based on different modes. |
||
4022 | + * Check for threshold if limiter mode, etc. |
||
4023 | + */ |
||
4024 | + |
||
4025 | + if (req_clk <= info->node_info->th[0]) { |
||
4026 | + mode = info->node_info->mode; |
||
4027 | + bw = info->node_info->bimc_bw[0]; |
||
4028 | + } else if ((info->node_info->num_thresh > 1) && |
||
4029 | + (req_clk <= info->node_info->th[1])) { |
||
4030 | + mode = info->node_info->mode; |
||
4031 | + bw = info->node_info->bimc_bw[1]; |
||
4032 | + } else |
||
4033 | + mode = info->node_info->mode_thresh; |
||
4034 | + |
||
4035 | + switch (mode) { |
||
4036 | + case BIMC_QOS_MODE_BYPASS: |
||
4037 | + case BIMC_QOS_MODE_FIXED: |
||
4038 | + for (i = 0; i < ports; i++) |
||
4039 | + bke_switch(binfo->base, info->node_info->qport[i], |
||
4040 | + BKE_OFF, mode); |
||
4041 | + break; |
||
4042 | + case BIMC_QOS_MODE_REGULATOR: |
||
4043 | + case BIMC_QOS_MODE_LIMITER: |
||
4044 | + for (i = 0; i < ports; i++) { |
||
4045 | + /* If not in fixed mode, update bandwidth */ |
||
4046 | + if ((info->node_info->cur_lim_bw != bw) |
||
4047 | + && (mode != BIMC_QOS_MODE_FIXED)) { |
||
4048 | + struct msm_bus_bimc_qos_bw qbw; |
||
4049 | + qbw.ws = info->node_info->ws; |
||
4050 | + qbw.bw = bw; |
||
4051 | + qbw.gp = info->node_info->bimc_gp; |
||
4052 | + qbw.thmp = info->node_info->bimc_thmp; |
||
4053 | + bimc_set_static_qos_bw(binfo->base, |
||
4054 | + binfo->qos_freq, |
||
4055 | + info->node_info->qport[i], &qbw); |
||
4056 | + info->node_info->cur_lim_bw = bw; |
||
4057 | + MSM_BUS_DBG("%s: Qos is %d reqclk %llu bw %llu", |
||
4058 | + __func__, mode, req_clk, bw); |
||
4059 | + } |
||
4060 | + bke_switch(binfo->base, info->node_info->qport[i], |
||
4061 | + BKE_ON, mode); |
||
4062 | + } |
||
4063 | + break; |
||
4064 | + default: |
||
4065 | + break; |
||
4066 | + } |
||
4067 | +} |
||
4068 | + |
||
4069 | +static void msm_bus_bimc_update_bw(struct msm_bus_inode_info *hop, |
||
4070 | + struct msm_bus_inode_info *info, |
||
4071 | + struct msm_bus_fabric_registration *fab_pdata, |
||
4072 | + void *sel_cdata, int *master_tiers, |
||
4073 | + int64_t add_bw) |
||
4074 | +{ |
||
4075 | + struct msm_bus_bimc_info *binfo; |
||
4076 | + struct msm_bus_bimc_qos_bw qbw; |
||
4077 | + int i; |
||
4078 | + int64_t bw; |
||
4079 | + int ports = info->node_info->num_mports; |
||
4080 | + struct msm_bus_bimc_commit *sel_cd = |
||
4081 | + (struct msm_bus_bimc_commit *)sel_cdata; |
||
4082 | + |
||
4083 | + MSM_BUS_DBG("BIMC: Update bw for ID %d, with IID: %d: %lld\n", |
||
4084 | + info->node_info->id, info->node_info->priv_id, add_bw); |
||
4085 | + |
||
4086 | + binfo = (struct msm_bus_bimc_info *)fab_pdata->hw_data; |
||
4087 | + |
||
4088 | + if (info->node_info->num_mports == 0) { |
||
4089 | + MSM_BUS_DBG("BIMC: Skip Master BW\n"); |
||
4090 | + goto skip_mas_bw; |
||
4091 | + } |
||
4092 | + |
||
4093 | + ports = info->node_info->num_mports; |
||
4094 | + bw = INTERLEAVED_BW(fab_pdata, add_bw, ports); |
||
4095 | + |
||
4096 | + for (i = 0; i < ports; i++) { |
||
4097 | + sel_cd->mas[info->node_info->masterp[i]].bw += bw; |
||
4098 | + sel_cd->mas[info->node_info->masterp[i]].hw_id = |
||
4099 | + info->node_info->mas_hw_id; |
||
4100 | + MSM_BUS_DBG("BIMC: Update mas_bw for ID: %d -> %llu\n", |
||
4101 | + info->node_info->priv_id, |
||
4102 | + sel_cd->mas[info->node_info->masterp[i]].bw); |
||
4103 | + if (info->node_info->hw_sel == MSM_BUS_RPM) |
||
4104 | + sel_cd->mas[info->node_info->masterp[i]].dirty = 1; |
||
4105 | + else { |
||
4106 | + if (!info->node_info->qport) { |
||
4107 | + MSM_BUS_DBG("No qos ports to update!\n"); |
||
4108 | + break; |
||
4109 | + } |
||
4110 | + if (!(info->node_info->mode == BIMC_QOS_MODE_REGULATOR) |
||
4111 | + || (info->node_info->mode == |
||
4112 | + BIMC_QOS_MODE_LIMITER)) { |
||
4113 | + MSM_BUS_DBG("Skip QoS reg programming\n"); |
||
4114 | + break; |
||
4115 | + } |
||
4116 | + |
||
4117 | + MSM_BUS_DBG("qport: %d\n", info->node_info->qport[i]); |
||
4118 | + qbw.bw = sel_cd->mas[info->node_info->masterp[i]].bw; |
||
4119 | + qbw.ws = info->node_info->ws; |
||
4120 | + /* Threshold low = 90% of bw */ |
||
4121 | + qbw.thl = div_s64((90 * bw), 100); |
||
4122 | + /* Threshold medium = bw */ |
||
4123 | + qbw.thm = bw; |
||
4124 | + /* Threshold high = 10% more than bw */ |
||
4125 | + qbw.thh = div_s64((110 * bw), 100); |
||
4126 | + /* Check if info is a shared master. |
||
4127 | + * If it is, mark it dirty |
||
4128 | + * If it isn't, then set QOS Bandwidth. |
||
4129 | + * Also if dual-conf is set, don't program bw regs. |
||
4130 | + **/ |
||
4131 | + if (!info->node_info->dual_conf && |
||
4132 | + ((info->node_info->mode == BIMC_QOS_MODE_LIMITER) || |
||
4133 | + (info->node_info->mode == BIMC_QOS_MODE_REGULATOR))) |
||
4134 | + msm_bus_bimc_set_qos_bw(binfo->base, |
||
4135 | + binfo->qos_freq, |
||
4136 | + info->node_info->qport[i], &qbw); |
||
4137 | + } |
||
4138 | + } |
||
4139 | + |
||
4140 | +skip_mas_bw: |
||
4141 | + ports = hop->node_info->num_sports; |
||
4142 | + MSM_BUS_DBG("BIMC: ID: %d, Sports: %d\n", hop->node_info->priv_id, |
||
4143 | + ports); |
||
4144 | + |
||
4145 | + for (i = 0; i < ports; i++) { |
||
4146 | + sel_cd->slv[hop->node_info->slavep[i]].bw += add_bw; |
||
4147 | + sel_cd->slv[hop->node_info->slavep[i]].hw_id = |
||
4148 | + hop->node_info->slv_hw_id; |
||
4149 | + MSM_BUS_DBG("BIMC: Update slave_bw: ID: %d -> %llu\n", |
||
4150 | + hop->node_info->priv_id, |
||
4151 | + sel_cd->slv[hop->node_info->slavep[i]].bw); |
||
4152 | + MSM_BUS_DBG("BIMC: Update slave_bw: index: %d\n", |
||
4153 | + hop->node_info->slavep[i]); |
||
4154 | + /* Check if hop is a shared slave. |
||
4155 | + * If it is, mark it dirty |
||
4156 | + * If it isn't, then nothing to be done as the |
||
4157 | + * slaves are in bypass mode. |
||
4158 | + **/ |
||
4159 | + if (hop->node_info->hw_sel == MSM_BUS_RPM) { |
||
4160 | + MSM_BUS_DBG("Slave dirty: %d, slavep: %d\n", |
||
4161 | + hop->node_info->priv_id, |
||
4162 | + hop->node_info->slavep[i]); |
||
4163 | + sel_cd->slv[hop->node_info->slavep[i]].dirty = 1; |
||
4164 | + } |
||
4165 | + } |
||
4166 | +} |
||
4167 | + |
||
4168 | +static int msm_bus_bimc_commit(struct msm_bus_fabric_registration |
||
4169 | + *fab_pdata, void *hw_data, void **cdata) |
||
4170 | +{ |
||
4171 | + MSM_BUS_DBG("\nReached BIMC Commit\n"); |
||
4172 | + msm_bus_remote_hw_commit(fab_pdata, hw_data, cdata); |
||
4173 | + return 0; |
||
4174 | +} |
||
4175 | + |
||
4176 | +static void msm_bus_bimc_config_limiter( |
||
4177 | + struct msm_bus_fabric_registration *fab_pdata, |
||
4178 | + struct msm_bus_inode_info *info) |
||
4179 | +{ |
||
4180 | + struct msm_bus_bimc_info *binfo; |
||
4181 | + int mode, i, ports; |
||
4182 | + |
||
4183 | + binfo = (struct msm_bus_bimc_info *)fab_pdata->hw_data; |
||
4184 | + ports = info->node_info->num_mports; |
||
4185 | + |
||
4186 | + if (!info->node_info->qport) { |
||
4187 | + MSM_BUS_DBG("No QoS Ports to init\n"); |
||
4188 | + return; |
||
4189 | + } |
||
4190 | + |
||
4191 | + if (info->cur_lim_bw) |
||
4192 | + mode = BIMC_QOS_MODE_LIMITER; |
||
4193 | + else |
||
4194 | + mode = info->node_info->mode; |
||
4195 | + |
||
4196 | + switch (mode) { |
||
4197 | + case BIMC_QOS_MODE_BYPASS: |
||
4198 | + case BIMC_QOS_MODE_FIXED: |
||
4199 | + for (i = 0; i < ports; i++) |
||
4200 | + bke_switch(binfo->base, info->node_info->qport[i], |
||
4201 | + BKE_OFF, mode); |
||
4202 | + break; |
||
4203 | + case BIMC_QOS_MODE_REGULATOR: |
||
4204 | + case BIMC_QOS_MODE_LIMITER: |
||
4205 | + if (info->cur_lim_bw != info->cur_prg_bw) { |
||
4206 | + MSM_BUS_DBG("Enabled BKE throttling node %d to %llu\n", |
||
4207 | + info->node_info->id, info->cur_lim_bw); |
||
4208 | + trace_bus_bimc_config_limiter(info->node_info->id, |
||
4209 | + info->cur_lim_bw); |
||
4210 | + for (i = 0; i < ports; i++) { |
||
4211 | + /* If not in fixed mode, update bandwidth */ |
||
4212 | + struct msm_bus_bimc_qos_bw qbw; |
||
4213 | + |
||
4214 | + qbw.ws = info->node_info->ws; |
||
4215 | + qbw.bw = info->cur_lim_bw; |
||
4216 | + qbw.gp = info->node_info->bimc_gp; |
||
4217 | + qbw.thmp = info->node_info->bimc_thmp; |
||
4218 | + bimc_set_static_qos_bw(binfo->base, |
||
4219 | + binfo->qos_freq, |
||
4220 | + info->node_info->qport[i], &qbw); |
||
4221 | + bke_switch(binfo->base, |
||
4222 | + info->node_info->qport[i], |
||
4223 | + BKE_ON, mode); |
||
4224 | + info->cur_prg_bw = qbw.bw; |
||
4225 | + } |
||
4226 | + } |
||
4227 | + break; |
||
4228 | + default: |
||
4229 | + break; |
||
4230 | + } |
||
4231 | +} |
||
4232 | + |
||
4233 | +static void bimc_init_mas_reg(struct msm_bus_bimc_info *binfo, |
||
4234 | + struct msm_bus_inode_info *info, |
||
4235 | + struct msm_bus_bimc_qos_mode *qmode, int mode) |
||
4236 | +{ |
||
4237 | + int i; |
||
4238 | + |
||
4239 | + switch (mode) { |
||
4240 | + case BIMC_QOS_MODE_FIXED: |
||
4241 | + qmode->fixed.prio_level = info->node_info->prio_lvl; |
||
4242 | + qmode->fixed.areq_prio_rd = info->node_info->prio_rd; |
||
4243 | + qmode->fixed.areq_prio_wr = info->node_info->prio_wr; |
||
4244 | + break; |
||
4245 | + case BIMC_QOS_MODE_LIMITER: |
||
4246 | + qmode->rl.qhealth[0].limit_commands = 1; |
||
4247 | + qmode->rl.qhealth[1].limit_commands = 0; |
||
4248 | + qmode->rl.qhealth[2].limit_commands = 0; |
||
4249 | + qmode->rl.qhealth[3].limit_commands = 0; |
||
4250 | + break; |
||
4251 | + default: |
||
4252 | + break; |
||
4253 | + } |
||
4254 | + |
||
4255 | + if (!info->node_info->qport) { |
||
4256 | + MSM_BUS_DBG("No QoS Ports to init\n"); |
||
4257 | + return; |
||
4258 | + } |
||
4259 | + |
||
4260 | + for (i = 0; i < info->node_info->num_mports; i++) { |
||
4261 | + /* If not in bypass mode, update priority */ |
||
4262 | + if (mode != BIMC_QOS_MODE_BYPASS) { |
||
4263 | + msm_bus_bimc_set_qos_prio(binfo->base, |
||
4264 | + info->node_info-> |
||
4265 | + qport[i], mode, qmode); |
||
4266 | + |
||
4267 | + /* If not in fixed mode, update bandwidth */ |
||
4268 | + if (mode != BIMC_QOS_MODE_FIXED) { |
||
4269 | + struct msm_bus_bimc_qos_bw qbw; |
||
4270 | + qbw.ws = info->node_info->ws; |
||
4271 | + qbw.bw = info->node_info->bimc_bw[0]; |
||
4272 | + qbw.gp = info->node_info->bimc_gp; |
||
4273 | + qbw.thmp = info->node_info->bimc_thmp; |
||
4274 | + bimc_set_static_qos_bw(binfo->base, |
||
4275 | + binfo->qos_freq, |
||
4276 | + info->node_info->qport[i], &qbw); |
||
4277 | + } |
||
4278 | + } |
||
4279 | + |
||
4280 | + /* set mode */ |
||
4281 | + msm_bus_bimc_set_qos_mode(binfo->base, |
||
4282 | + info->node_info->qport[i], |
||
4283 | + mode); |
||
4284 | + } |
||
4285 | +} |
||
4286 | + |
||
4287 | +static void init_health_regs(struct msm_bus_bimc_info *binfo, |
||
4288 | + struct msm_bus_inode_info *info, |
||
4289 | + struct msm_bus_bimc_qos_mode *qmode, |
||
4290 | + int mode) |
||
4291 | +{ |
||
4292 | + int i; |
||
4293 | + |
||
4294 | + if (mode == BIMC_QOS_MODE_LIMITER) { |
||
4295 | + qmode->rl.qhealth[0].limit_commands = 1; |
||
4296 | + qmode->rl.qhealth[1].limit_commands = 0; |
||
4297 | + qmode->rl.qhealth[2].limit_commands = 0; |
||
4298 | + qmode->rl.qhealth[3].limit_commands = 0; |
||
4299 | + |
||
4300 | + if (!info->node_info->qport) { |
||
4301 | + MSM_BUS_DBG("No QoS Ports to init\n"); |
||
4302 | + return; |
||
4303 | + } |
||
4304 | + |
||
4305 | + for (i = 0; i < info->node_info->num_mports; i++) { |
||
4306 | + /* If not in bypass mode, update priority */ |
||
4307 | + if (mode != BIMC_QOS_MODE_BYPASS) |
||
4308 | + msm_bus_bimc_set_qos_prio(binfo->base, |
||
4309 | + info->node_info->qport[i], mode, qmode); |
||
4310 | + } |
||
4311 | + } |
||
4312 | +} |
||
4313 | + |
||
4314 | + |
||
4315 | +static int msm_bus_bimc_mas_init(struct msm_bus_bimc_info *binfo, |
||
4316 | + struct msm_bus_inode_info *info) |
||
4317 | +{ |
||
4318 | + struct msm_bus_bimc_qos_mode *qmode; |
||
4319 | + qmode = kzalloc(sizeof(struct msm_bus_bimc_qos_mode), |
||
4320 | + GFP_KERNEL); |
||
4321 | + if (!qmode) { |
||
4322 | + MSM_BUS_WARN("Couldn't alloc prio data for node: %d\n", |
||
4323 | + info->node_info->id); |
||
4324 | + return -ENOMEM; |
||
4325 | + } |
||
4326 | + |
||
4327 | + info->hw_data = (void *)qmode; |
||
4328 | + |
||
4329 | + /** |
||
4330 | + * If the master supports dual configuration, |
||
4331 | + * configure registers for both modes |
||
4332 | + */ |
||
4333 | + if (info->node_info->dual_conf) |
||
4334 | + bimc_init_mas_reg(binfo, info, qmode, |
||
4335 | + info->node_info->mode_thresh); |
||
4336 | + else if (info->node_info->nr_lim) |
||
4337 | + init_health_regs(binfo, info, qmode, BIMC_QOS_MODE_LIMITER); |
||
4338 | + |
||
4339 | + bimc_init_mas_reg(binfo, info, qmode, info->node_info->mode); |
||
4340 | + return 0; |
||
4341 | +} |
||
4342 | + |
||
4343 | +static void msm_bus_bimc_node_init(void *hw_data, |
||
4344 | + struct msm_bus_inode_info *info) |
||
4345 | +{ |
||
4346 | + struct msm_bus_bimc_info *binfo = |
||
4347 | + (struct msm_bus_bimc_info *)hw_data; |
||
4348 | + |
||
4349 | + if (!IS_SLAVE(info->node_info->priv_id) && |
||
4350 | + (info->node_info->hw_sel != MSM_BUS_RPM)) |
||
4351 | + msm_bus_bimc_mas_init(binfo, info); |
||
4352 | +} |
||
4353 | + |
||
4354 | +static int msm_bus_bimc_port_halt(uint32_t haltid, uint8_t mport) |
||
4355 | +{ |
||
4356 | + return 0; |
||
4357 | +} |
||
4358 | + |
||
4359 | +static int msm_bus_bimc_port_unhalt(uint32_t haltid, uint8_t mport) |
||
4360 | +{ |
||
4361 | + return 0; |
||
4362 | +} |
||
4363 | + |
||
4364 | +static int msm_bus_bimc_limit_mport(struct msm_bus_node_device_type *info, |
||
4365 | + void __iomem *qos_base, uint32_t qos_off, |
||
4366 | + uint32_t qos_delta, uint32_t qos_freq, |
||
4367 | + bool enable_lim, u64 lim_bw) |
||
4368 | +{ |
||
4369 | + int mode; |
||
4370 | + int i; |
||
4371 | + |
||
4372 | + if (ZERO_OR_NULL_PTR(info->node_info->qport)) { |
||
4373 | + MSM_BUS_DBG("No QoS Ports to limit\n"); |
||
4374 | + return 0; |
||
4375 | + } |
||
4376 | + |
||
4377 | + if (enable_lim && lim_bw) { |
||
4378 | + mode = BIMC_QOS_MODE_LIMITER; |
||
4379 | + |
||
4380 | + if (!info->node_info->lim_bw) { |
||
4381 | + struct msm_bus_bimc_qos_mode qmode; |
||
4382 | + qmode.rl.qhealth[0].limit_commands = 1; |
||
4383 | + qmode.rl.qhealth[1].limit_commands = 0; |
||
4384 | + qmode.rl.qhealth[2].limit_commands = 0; |
||
4385 | + qmode.rl.qhealth[3].limit_commands = 0; |
||
4386 | + |
||
4387 | + for (i = 0; i < info->node_info->num_qports; i++) { |
||
4388 | + /* If not in bypass mode, update priority */ |
||
4389 | + if (mode != BIMC_QOS_MODE_BYPASS) |
||
4390 | + msm_bus_bimc_set_qos_prio(qos_base, |
||
4391 | + info->node_info->qport[i], mode, |
||
4392 | + &qmode); |
||
4393 | + } |
||
4394 | + } |
||
4395 | + |
||
4396 | + for (i = 0; i < info->node_info->num_qports; i++) { |
||
4397 | + struct msm_bus_bimc_qos_bw qbw; |
||
4398 | + /* If not in fixed mode, update bandwidth */ |
||
4399 | + if ((info->node_info->lim_bw != lim_bw)) { |
||
4400 | + qbw.ws = info->node_info->qos_params.ws; |
||
4401 | + qbw.bw = lim_bw; |
||
4402 | + qbw.gp = info->node_info->qos_params.gp; |
||
4403 | + qbw.thmp = info->node_info->qos_params.thmp; |
||
4404 | + bimc_set_static_qos_bw(qos_base, qos_freq, |
||
4405 | + info->node_info->qport[i], &qbw); |
||
4406 | + } |
||
4407 | + bke_switch(qos_base, info->node_info->qport[i], |
||
4408 | + BKE_ON, mode); |
||
4409 | + } |
||
4410 | + info->node_info->lim_bw = lim_bw; |
||
4411 | + } else { |
||
4412 | + mode = info->node_info->qos_params.mode; |
||
4413 | + for (i = 0; i < info->node_info->num_qports; i++) { |
||
4414 | + bke_switch(qos_base, info->node_info->qport[i], |
||
4415 | + BKE_OFF, mode); |
||
4416 | + } |
||
4417 | + } |
||
4418 | + info->node_info->qos_params.cur_mode = mode; |
||
4419 | + return 0; |
||
4420 | +} |
||
4421 | + |
||
4422 | +static bool msm_bus_bimc_update_bw_reg(int mode) |
||
4423 | +{ |
||
4424 | + bool ret = false; |
||
4425 | + |
||
4426 | + if ((mode == BIMC_QOS_MODE_LIMITER) |
||
4427 | + || (mode == BIMC_QOS_MODE_REGULATOR)) |
||
4428 | + ret = true; |
||
4429 | + |
||
4430 | + return ret; |
||
4431 | +} |
||
4432 | + |
||
4433 | +static int msm_bus_bimc_qos_init(struct msm_bus_node_device_type *info, |
||
4434 | + void __iomem *qos_base, |
||
4435 | + uint32_t qos_off, uint32_t qos_delta, |
||
4436 | + uint32_t qos_freq) |
||
4437 | +{ |
||
4438 | + int i; |
||
4439 | + struct msm_bus_bimc_qos_mode qmode; |
||
4440 | + |
||
4441 | + switch (info->node_info->qos_params.mode) { |
||
4442 | + case BIMC_QOS_MODE_FIXED: |
||
4443 | + qmode.fixed.prio_level = info->node_info->qos_params.prio_lvl; |
||
4444 | + qmode.fixed.areq_prio_rd = info->node_info->qos_params.prio_rd; |
||
4445 | + qmode.fixed.areq_prio_wr = info->node_info->qos_params.prio_wr; |
||
4446 | + break; |
||
4447 | + case BIMC_QOS_MODE_LIMITER: |
||
4448 | + qmode.rl.qhealth[0].limit_commands = 1; |
||
4449 | + qmode.rl.qhealth[1].limit_commands = 0; |
||
4450 | + qmode.rl.qhealth[2].limit_commands = 0; |
||
4451 | + qmode.rl.qhealth[3].limit_commands = 0; |
||
4452 | + break; |
||
4453 | + default: |
||
4454 | + break; |
||
4455 | + } |
||
4456 | + |
||
4457 | + if (ZERO_OR_NULL_PTR(info->node_info->qport)) { |
||
4458 | + MSM_BUS_DBG("No QoS Ports to init\n"); |
||
4459 | + return 0; |
||
4460 | + } |
||
4461 | + |
||
4462 | + for (i = 0; i < info->node_info->num_qports; i++) { |
||
4463 | + /* If not in bypass mode, update priority */ |
||
4464 | + if (info->node_info->qos_params.mode != BIMC_QOS_MODE_BYPASS) |
||
4465 | + msm_bus_bimc_set_qos_prio(qos_base, info->node_info-> |
||
4466 | + qport[i], info->node_info->qos_params.mode, |
||
4467 | + &qmode); |
||
4468 | + |
||
4469 | + /* set mode */ |
||
4470 | + if (info->node_info->qos_params.mode == BIMC_QOS_MODE_LIMITER) |
||
4471 | + bke_switch(qos_base, info->node_info->qport[i], |
||
4472 | + BKE_OFF, BIMC_QOS_MODE_FIXED); |
||
4473 | + else |
||
4474 | + msm_bus_bimc_set_qos_mode(qos_base, |
||
4475 | + info->node_info->qport[i], |
||
4476 | + info->node_info->qos_params.mode); |
||
4477 | + } |
||
4478 | + |
||
4479 | + return 0; |
||
4480 | +} |
||
4481 | + |
||
4482 | +static int msm_bus_bimc_set_bw(struct msm_bus_node_device_type *dev, |
||
4483 | + void __iomem *qos_base, uint32_t qos_off, |
||
4484 | + uint32_t qos_delta, uint32_t qos_freq) |
||
4485 | +{ |
||
4486 | + struct msm_bus_bimc_qos_bw qbw; |
||
4487 | + int i; |
||
4488 | + int64_t bw = 0; |
||
4489 | + int ret = 0; |
||
4490 | + struct msm_bus_node_info_type *info = dev->node_info; |
||
4491 | + |
||
4492 | + if (info && info->num_qports && |
||
4493 | + ((info->qos_params.mode == BIMC_QOS_MODE_LIMITER) || |
||
4494 | + (info->qos_params.mode == BIMC_QOS_MODE_REGULATOR))) { |
||
4495 | + bw = msm_bus_div64(info->num_qports, |
||
4496 | + dev->node_ab.ab[DUAL_CTX]); |
||
4497 | + |
||
4498 | + for (i = 0; i < info->num_qports; i++) { |
||
4499 | + MSM_BUS_DBG("BIMC: Update mas_bw for ID: %d -> %llu\n", |
||
4500 | + info->id, bw); |
||
4501 | + |
||
4502 | + if (!info->qport) { |
||
4503 | + MSM_BUS_DBG("No qos ports to update!\n"); |
||
4504 | + break; |
||
4505 | + } |
||
4506 | + |
||
4507 | + qbw.bw = bw + info->qos_params.bw_buffer; |
||
4508 | + trace_bus_bimc_config_limiter(info->id, bw); |
||
4509 | + |
||
4510 | + /* Default to gp of 5us */ |
||
4511 | + qbw.gp = (info->qos_params.gp ? |
||
4512 | + info->qos_params.gp : 5000); |
||
4513 | + /* Default to thmp of 50% */ |
||
4514 | + qbw.thmp = (info->qos_params.thmp ? |
||
4515 | + info->qos_params.thmp : 50); |
||
4516 | + /* |
||
4517 | + * If the BW vote is 0 then set the QoS mode to |
||
4518 | + * Fixed. |
||
4519 | + */ |
||
4520 | + if (bw) { |
||
4521 | + bimc_set_static_qos_bw(qos_base, qos_freq, |
||
4522 | + info->qport[i], &qbw); |
||
4523 | + bke_switch(qos_base, info->qport[i], |
||
4524 | + BKE_ON, info->qos_params.mode); |
||
4525 | + } else { |
||
4526 | + bke_switch(qos_base, info->qport[i], |
||
4527 | + BKE_OFF, BIMC_QOS_MODE_FIXED); |
||
4528 | + } |
||
4529 | + } |
||
4530 | + } |
||
4531 | + return ret; |
||
4532 | +} |
||
4533 | + |
||
4534 | +int msm_bus_bimc_hw_init(struct msm_bus_fabric_registration *pdata, |
||
4535 | + struct msm_bus_hw_algorithm *hw_algo) |
||
4536 | +{ |
||
4537 | + /* Set interleaving to true by default */ |
||
4538 | + MSM_BUS_DBG("\nInitializing BIMC...\n"); |
||
4539 | + pdata->il_flag = true; |
||
4540 | + hw_algo->allocate_commit_data = msm_bus_bimc_allocate_commit_data; |
||
4541 | + hw_algo->allocate_hw_data = msm_bus_bimc_allocate_bimc_data; |
||
4542 | + hw_algo->node_init = msm_bus_bimc_node_init; |
||
4543 | + hw_algo->free_commit_data = free_commit_data; |
||
4544 | + hw_algo->update_bw = msm_bus_bimc_update_bw; |
||
4545 | + hw_algo->commit = msm_bus_bimc_commit; |
||
4546 | + hw_algo->port_halt = msm_bus_bimc_port_halt; |
||
4547 | + hw_algo->port_unhalt = msm_bus_bimc_port_unhalt; |
||
4548 | + hw_algo->config_master = msm_bus_bimc_config_master; |
||
4549 | + hw_algo->config_limiter = msm_bus_bimc_config_limiter; |
||
4550 | + hw_algo->update_bw_reg = msm_bus_bimc_update_bw_reg; |
||
4551 | + /* BIMC slaves are shared. Slave registers are set through RPM */ |
||
4552 | + if (!pdata->ahb) |
||
4553 | + pdata->rpm_enabled = 1; |
||
4554 | + return 0; |
||
4555 | +} |
||
4556 | + |
||
4557 | +int msm_bus_bimc_set_ops(struct msm_bus_node_device_type *bus_dev) |
||
4558 | +{ |
||
4559 | + if (!bus_dev) |
||
4560 | + return -ENODEV; |
||
4561 | + else { |
||
4562 | + bus_dev->fabdev->noc_ops.qos_init = msm_bus_bimc_qos_init; |
||
4563 | + bus_dev->fabdev->noc_ops.set_bw = msm_bus_bimc_set_bw; |
||
4564 | + bus_dev->fabdev->noc_ops.limit_mport = msm_bus_bimc_limit_mport; |
||
4565 | + bus_dev->fabdev->noc_ops.update_bw_reg = |
||
4566 | + msm_bus_bimc_update_bw_reg; |
||
4567 | + } |
||
4568 | + return 0; |
||
4569 | +} |
||
4570 | +EXPORT_SYMBOL(msm_bus_bimc_set_ops); |
||
4571 | --- /dev/null |
||
4572 | +++ b/drivers/bus/msm_bus/msm_bus_bimc.h |
||
4573 | @@ -0,0 +1,127 @@ |
||
4574 | +/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved. |
||
4575 | + * |
||
4576 | + * This program is free software; you can redistribute it and/or modify |
||
4577 | + * it under the terms of the GNU General Public License version 2 and |
||
4578 | + * only version 2 as published by the Free Software Foundation. |
||
4579 | + * |
||
4580 | + * This program is distributed in the hope that it will be useful, |
||
4581 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
4582 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
4583 | + * GNU General Public License for more details. |
||
4584 | + */ |
||
4585 | + |
||
4586 | +#ifndef _ARCH_ARM_MACH_MSM_BUS_BIMC_H |
||
4587 | +#define _ARCH_ARM_MACH_MSM_BUS_BIMC_H |
||
4588 | + |
||
4589 | +struct msm_bus_bimc_params { |
||
4590 | + uint32_t bus_id; |
||
4591 | + uint32_t addr_width; |
||
4592 | + uint32_t data_width; |
||
4593 | + uint32_t nmasters; |
||
4594 | + uint32_t nslaves; |
||
4595 | +}; |
||
4596 | + |
||
4597 | +struct msm_bus_bimc_commit { |
||
4598 | + struct msm_bus_node_hw_info *mas; |
||
4599 | + struct msm_bus_node_hw_info *slv; |
||
4600 | +}; |
||
4601 | + |
||
4602 | +struct msm_bus_bimc_info { |
||
4603 | + void __iomem *base; |
||
4604 | + uint32_t base_addr; |
||
4605 | + uint32_t qos_freq; |
||
4606 | + struct msm_bus_bimc_params params; |
||
4607 | + struct msm_bus_bimc_commit cdata[NUM_CTX]; |
||
4608 | +}; |
||
4609 | + |
||
4610 | +struct msm_bus_bimc_node { |
||
4611 | + uint32_t conn_mask; |
||
4612 | + uint32_t data_width; |
||
4613 | + uint8_t slv_arb_mode; |
||
4614 | +}; |
||
4615 | + |
||
4616 | +enum msm_bus_bimc_arb_mode { |
||
4617 | + BIMC_ARB_MODE_RR = 0, |
||
4618 | + BIMC_ARB_MODE_PRIORITY_RR, |
||
4619 | + BIMC_ARB_MODE_TIERED_RR, |
||
4620 | +}; |
||
4621 | + |
||
4622 | + |
||
4623 | +enum msm_bus_bimc_interleave { |
||
4624 | + BIMC_INTERLEAVE_NONE = 0, |
||
4625 | + BIMC_INTERLEAVE_ODD, |
||
4626 | + BIMC_INTERLEAVE_EVEN, |
||
4627 | +}; |
||
4628 | + |
||
4629 | +struct msm_bus_bimc_slave_seg { |
||
4630 | + bool enable; |
||
4631 | + uint64_t start_addr; |
||
4632 | + uint64_t seg_size; |
||
4633 | + uint8_t interleave; |
||
4634 | +}; |
||
4635 | + |
||
4636 | +enum msm_bus_bimc_qos_mode_type { |
||
4637 | + BIMC_QOS_MODE_FIXED = 0, |
||
4638 | + BIMC_QOS_MODE_LIMITER, |
||
4639 | + BIMC_QOS_MODE_BYPASS, |
||
4640 | + BIMC_QOS_MODE_REGULATOR, |
||
4641 | +}; |
||
4642 | + |
||
4643 | +struct msm_bus_bimc_qos_health { |
||
4644 | + bool limit_commands; |
||
4645 | + uint32_t areq_prio; |
||
4646 | + uint32_t prio_level; |
||
4647 | +}; |
||
4648 | + |
||
4649 | +struct msm_bus_bimc_mode_fixed { |
||
4650 | + uint32_t prio_level; |
||
4651 | + uint32_t areq_prio_rd; |
||
4652 | + uint32_t areq_prio_wr; |
||
4653 | +}; |
||
4654 | + |
||
4655 | +struct msm_bus_bimc_mode_rl { |
||
4656 | + uint8_t qhealthnum; |
||
4657 | + struct msm_bus_bimc_qos_health qhealth[4]; |
||
4658 | +}; |
||
4659 | + |
||
4660 | +struct msm_bus_bimc_qos_mode { |
||
4661 | + uint8_t mode; |
||
4662 | + struct msm_bus_bimc_mode_fixed fixed; |
||
4663 | + struct msm_bus_bimc_mode_rl rl; |
||
4664 | +}; |
||
4665 | + |
||
4666 | +struct msm_bus_bimc_qos_bw { |
||
4667 | + uint64_t bw; /* bw is in Bytes/sec */ |
||
4668 | + uint32_t ws; /* Window size in nano seconds*/ |
||
4669 | + int64_t thh; /* Threshold high, bytes per second */ |
||
4670 | + int64_t thm; /* Threshold medium, bytes per second */ |
||
4671 | + int64_t thl; /* Threshold low, bytes per second */ |
||
4672 | + u32 gp; /* Grant Period in micro seconds */ |
||
4673 | + u32 thmp; /* Threshold medium in percentage */ |
||
4674 | +}; |
||
4675 | + |
||
4676 | +struct msm_bus_bimc_clk_gate { |
||
4677 | + bool core_clk_gate_en; |
||
4678 | + bool arb_clk_gate_en; /* For arbiter */ |
||
4679 | + bool port_clk_gate_en; /* For regs on BIMC core clock */ |
||
4680 | +}; |
||
4681 | + |
||
4682 | +void msm_bus_bimc_set_slave_seg(struct msm_bus_bimc_info *binfo, |
||
4683 | + uint32_t slv_index, uint32_t seg_index, |
||
4684 | + struct msm_bus_bimc_slave_seg *bsseg); |
||
4685 | +void msm_bus_bimc_set_slave_clk_gate(struct msm_bus_bimc_info *binfo, |
||
4686 | + uint32_t slv_index, struct msm_bus_bimc_clk_gate *bgate); |
||
4687 | +void msm_bus_bimc_set_mas_clk_gate(struct msm_bus_bimc_info *binfo, |
||
4688 | + uint32_t mas_index, struct msm_bus_bimc_clk_gate *bgate); |
||
4689 | +void msm_bus_bimc_arb_en(struct msm_bus_bimc_info *binfo, |
||
4690 | + uint32_t slv_index, bool en); |
||
4691 | +void msm_bus_bimc_get_params(struct msm_bus_bimc_info *binfo, |
||
4692 | + struct msm_bus_bimc_params *params); |
||
4693 | +void msm_bus_bimc_get_mas_params(struct msm_bus_bimc_info *binfo, |
||
4694 | + uint32_t mas_index, struct msm_bus_bimc_node *mparams); |
||
4695 | +void msm_bus_bimc_get_slv_params(struct msm_bus_bimc_info *binfo, |
||
4696 | + uint32_t slv_index, struct msm_bus_bimc_node *sparams); |
||
4697 | +bool msm_bus_bimc_get_arb_en(struct msm_bus_bimc_info *binfo, |
||
4698 | + uint32_t slv_index); |
||
4699 | + |
||
4700 | +#endif /*_ARCH_ARM_MACH_MSM_BUS_BIMC_H*/ |
||
4701 | --- /dev/null |
||
4702 | +++ b/drivers/bus/msm_bus/msm_bus_client_api.c |
||
4703 | @@ -0,0 +1,83 @@ |
||
4704 | +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. |
||
4705 | + * |
||
4706 | + * This program is free software; you can redistribute it and/or modify |
||
4707 | + * it under the terms of the GNU General Public License version 2 and |
||
4708 | + * only version 2 as published by the Free Software Foundation. |
||
4709 | + * |
||
4710 | + * This program is distributed in the hope that it will be useful, |
||
4711 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
4712 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
4713 | + * GNU General Public License for more details. |
||
4714 | + */ |
||
4715 | + |
||
4716 | +#define pr_fmt(fmt) "AXI: %s(): " fmt, __func__ |
||
4717 | + |
||
4718 | +#include <linux/kernel.h> |
||
4719 | +#include <linux/init.h> |
||
4720 | +#include <linux/list.h> |
||
4721 | +#include <linux/module.h> |
||
4722 | +#include <linux/slab.h> |
||
4723 | +#include <linux/mutex.h> |
||
4724 | +#include <linux/radix-tree.h> |
||
4725 | +#include <linux/clk.h> |
||
4726 | +#include "msm-bus.h" |
||
4727 | +#include "msm_bus_core.h" |
||
4728 | + |
||
4729 | +struct msm_bus_arb_ops arb_ops; |
||
4730 | + |
||
4731 | +/** |
||
4732 | + * msm_bus_scale_register_client() - Register the clients with the msm bus |
||
4733 | + * driver |
||
4734 | + * @pdata: Platform data of the client, containing src, dest, ab, ib. |
||
4735 | + * Return non-zero value in case of success, 0 in case of failure. |
||
4736 | + * |
||
4737 | + * Client data contains the vectors specifying arbitrated bandwidth (ab) |
||
4738 | + * and instantaneous bandwidth (ib) requested between a particular |
||
4739 | + * src and dest. |
||
4740 | + */ |
||
4741 | +uint32_t msm_bus_scale_register_client(struct msm_bus_scale_pdata *pdata) |
||
4742 | +{ |
||
4743 | + if (arb_ops.register_client) |
||
4744 | + return arb_ops.register_client(pdata); |
||
4745 | + else { |
||
4746 | + pr_err("%s: Bus driver not ready.", |
||
4747 | + __func__); |
||
4748 | + return 0; |
||
4749 | + } |
||
4750 | +} |
||
4751 | +EXPORT_SYMBOL(msm_bus_scale_register_client); |
||
4752 | + |
||
4753 | +/** |
||
4754 | + * msm_bus_scale_client_update_request() - Update the request for bandwidth |
||
4755 | + * from a particular client |
||
4756 | + * |
||
4757 | + * cl: Handle to the client |
||
4758 | + * index: Index into the vector, to which the bw and clock values need to be |
||
4759 | + * updated |
||
4760 | + */ |
||
4761 | +int msm_bus_scale_client_update_request(uint32_t cl, unsigned int index) |
||
4762 | +{ |
||
4763 | + if (arb_ops.update_request) |
||
4764 | + return arb_ops.update_request(cl, index); |
||
4765 | + else { |
||
4766 | + pr_err("%s: Bus driver not ready.", |
||
4767 | + __func__); |
||
4768 | + return -EPROBE_DEFER; |
||
4769 | + } |
||
4770 | +} |
||
4771 | +EXPORT_SYMBOL(msm_bus_scale_client_update_request); |
||
4772 | + |
||
4773 | +/** |
||
4774 | + * msm_bus_scale_unregister_client() - Unregister the client from the bus driver |
||
4775 | + * @cl: Handle to the client |
||
4776 | + */ |
||
4777 | +void msm_bus_scale_unregister_client(uint32_t cl) |
||
4778 | +{ |
||
4779 | + if (arb_ops.unregister_client) |
||
4780 | + arb_ops.unregister_client(cl); |
||
4781 | + else { |
||
4782 | + pr_err("%s: Bus driver not ready.", |
||
4783 | + __func__); |
||
4784 | + } |
||
4785 | +} |
||
4786 | +EXPORT_SYMBOL(msm_bus_scale_unregister_client); |
||
4787 | --- /dev/null |
||
4788 | +++ b/drivers/bus/msm_bus/msm_bus_core.c |
||
4789 | @@ -0,0 +1,125 @@ |
||
4790 | +/* Copyright (c) 2010-2014, The Linux Foundation. All rights reserved. |
||
4791 | + * |
||
4792 | + * This program is free software; you can redistribute it and/or modify |
||
4793 | + * it under the terms of the GNU General Public License version 2 and |
||
4794 | + * only version 2 as published by the Free Software Foundation. |
||
4795 | + * |
||
4796 | + * This program is distributed in the hope that it will be useful, |
||
4797 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
4798 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
4799 | + * GNU General Public License for more details. |
||
4800 | + */ |
||
4801 | + |
||
4802 | +#define pr_fmt(fmt) "AXI: %s(): " fmt, __func__ |
||
4803 | + |
||
4804 | +#include <linux/kernel.h> |
||
4805 | +#include <linux/init.h> |
||
4806 | +#include <linux/module.h> |
||
4807 | +#include <linux/slab.h> |
||
4808 | +#include <linux/mutex.h> |
||
4809 | +#include <linux/radix-tree.h> |
||
4810 | +#include <linux/clk.h> |
||
4811 | +#include "msm-bus-board.h" |
||
4812 | +#include "msm-bus.h" |
||
4813 | +#include "msm_bus_core.h" |
||
4814 | + |
||
4815 | +static atomic_t num_fab = ATOMIC_INIT(0); |
||
4816 | + |
||
4817 | +int msm_bus_get_num_fab(void) |
||
4818 | +{ |
||
4819 | + return atomic_read(&num_fab); |
||
4820 | +} |
||
4821 | + |
||
4822 | +int msm_bus_device_match(struct device *dev, void *id) |
||
4823 | +{ |
||
4824 | + struct msm_bus_fabric_device *fabdev = to_msm_bus_fabric_device(dev); |
||
4825 | + |
||
4826 | + if (!fabdev) { |
||
4827 | + MSM_BUS_WARN("Fabric %p returning 0\n", fabdev); |
||
4828 | + return 0; |
||
4829 | + } |
||
4830 | + return fabdev->id == *(int *)id; |
||
4831 | +} |
||
4832 | + |
||
4833 | +static void msm_bus_release(struct device *device) |
||
4834 | +{ |
||
4835 | +} |
||
4836 | + |
||
4837 | +struct bus_type msm_bus_type = { |
||
4838 | + .name = "msm-bus-type", |
||
4839 | +}; |
||
4840 | +EXPORT_SYMBOL(msm_bus_type); |
||
4841 | + |
||
4842 | +/** |
||
4843 | + * msm_bus_get_fabric_device() - This function is used to search for |
||
4844 | + * the fabric device on the bus |
||
4845 | + * @fabid: Fabric id |
||
4846 | + * Function returns: Pointer to the fabric device |
||
4847 | + */ |
||
4848 | +struct msm_bus_fabric_device *msm_bus_get_fabric_device(int fabid) |
||
4849 | +{ |
||
4850 | + struct device *dev; |
||
4851 | + struct msm_bus_fabric_device *fabric; |
||
4852 | + dev = bus_find_device(&msm_bus_type, NULL, (void *)&fabid, |
||
4853 | + msm_bus_device_match); |
||
4854 | + if (!dev) |
||
4855 | + return NULL; |
||
4856 | + fabric = to_msm_bus_fabric_device(dev); |
||
4857 | + return fabric; |
||
4858 | +} |
||
4859 | + |
||
4860 | +/** |
||
4861 | + * msm_bus_fabric_device_register() - Registers a fabric on msm bus |
||
4862 | + * @fabdev: Fabric device to be registered |
||
4863 | + */ |
||
4864 | +int msm_bus_fabric_device_register(struct msm_bus_fabric_device *fabdev) |
||
4865 | +{ |
||
4866 | + int ret = 0; |
||
4867 | + fabdev->dev.bus = &msm_bus_type; |
||
4868 | + fabdev->dev.release = msm_bus_release; |
||
4869 | + ret = dev_set_name(&fabdev->dev, fabdev->name); |
||
4870 | + if (ret) { |
||
4871 | + MSM_BUS_ERR("error setting dev name\n"); |
||
4872 | + goto err; |
||
4873 | + } |
||
4874 | + |
||
4875 | + ret = device_register(&fabdev->dev); |
||
4876 | + if (ret < 0) { |
||
4877 | + MSM_BUS_ERR("error registering device%d %s\n", |
||
4878 | + ret, fabdev->name); |
||
4879 | + goto err; |
||
4880 | + } |
||
4881 | + atomic_inc(&num_fab); |
||
4882 | +err: |
||
4883 | + return ret; |
||
4884 | +} |
||
4885 | + |
||
4886 | +/** |
||
4887 | + * msm_bus_fabric_device_unregister() - Unregisters the fabric |
||
4888 | + * devices from the msm bus |
||
4889 | + */ |
||
4890 | +void msm_bus_fabric_device_unregister(struct msm_bus_fabric_device *fabdev) |
||
4891 | +{ |
||
4892 | + device_unregister(&fabdev->dev); |
||
4893 | + atomic_dec(&num_fab); |
||
4894 | +} |
||
4895 | + |
||
4896 | +static void __exit msm_bus_exit(void) |
||
4897 | +{ |
||
4898 | + bus_unregister(&msm_bus_type); |
||
4899 | +} |
||
4900 | + |
||
4901 | +static int __init msm_bus_init(void) |
||
4902 | +{ |
||
4903 | + int retval = 0; |
||
4904 | + retval = bus_register(&msm_bus_type); |
||
4905 | + if (retval) |
||
4906 | + MSM_BUS_ERR("bus_register error! %d\n", |
||
4907 | + retval); |
||
4908 | + return retval; |
||
4909 | +} |
||
4910 | +postcore_initcall(msm_bus_init); |
||
4911 | +module_exit(msm_bus_exit); |
||
4912 | +MODULE_LICENSE("GPL v2"); |
||
4913 | +MODULE_VERSION("0.2"); |
||
4914 | +MODULE_ALIAS("platform:msm_bus"); |
||
4915 | --- /dev/null |
||
4916 | +++ b/drivers/bus/msm_bus/msm_bus_core.h |
||
4917 | @@ -0,0 +1,375 @@ |
||
4918 | +/* Copyright (c) 2011-2014, The Linux Foundation. All rights reserved. |
||
4919 | + * |
||
4920 | + * This program is free software; you can redistribute it and/or modify |
||
4921 | + * it under the terms of the GNU General Public License version 2 and |
||
4922 | + * only version 2 as published by the Free Software Foundation. |
||
4923 | + * |
||
4924 | + * This program is distributed in the hope that it will be useful, |
||
4925 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
4926 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
4927 | + * GNU General Public License for more details. |
||
4928 | + */ |
||
4929 | + |
||
4930 | +#ifndef _ARCH_ARM_MACH_MSM_BUS_CORE_H |
||
4931 | +#define _ARCH_ARM_MACH_MSM_BUS_CORE_H |
||
4932 | + |
||
4933 | +#include <linux/types.h> |
||
4934 | +#include <linux/device.h> |
||
4935 | +#include <linux/radix-tree.h> |
||
4936 | +#include <linux/platform_device.h> |
||
4937 | +#include "msm-bus-board.h" |
||
4938 | +#include "msm-bus.h" |
||
4939 | + |
||
4940 | +#define MSM_BUS_DBG(msg, ...) \ |
||
4941 | + pr_debug(msg, ## __VA_ARGS__) |
||
4942 | +#define MSM_BUS_ERR(msg, ...) \ |
||
4943 | + pr_err(msg, ## __VA_ARGS__) |
||
4944 | +#define MSM_BUS_WARN(msg, ...) \ |
||
4945 | + pr_warn(msg, ## __VA_ARGS__) |
||
4946 | +#define MSM_FAB_ERR(msg, ...) \ |
||
4947 | + dev_err(&fabric->fabdev.dev, msg, ## __VA_ARGS__) |
||
4948 | + |
||
4949 | +#define IS_MASTER_VALID(mas) \ |
||
4950 | + (((mas >= MSM_BUS_MASTER_FIRST) && (mas <= MSM_BUS_MASTER_LAST)) \ |
||
4951 | + ? 1 : 0) |
||
4952 | +#define IS_SLAVE_VALID(slv) \ |
||
4953 | + (((slv >= MSM_BUS_SLAVE_FIRST) && (slv <= MSM_BUS_SLAVE_LAST)) ? 1 : 0) |
||
4954 | + |
||
4955 | +#define INTERLEAVED_BW(fab_pdata, bw, ports) \ |
||
4956 | + ((fab_pdata->il_flag) ? ((bw < 0) \ |
||
4957 | + ? -msm_bus_div64((ports), (-bw)) : msm_bus_div64((ports), (bw))) : (bw)) |
||
4958 | +#define INTERLEAVED_VAL(fab_pdata, n) \ |
||
4959 | + ((fab_pdata->il_flag) ? (n) : 1) |
||
4960 | +#define KBTOB(a) (a * 1000ULL) |
||
4961 | + |
||
4962 | +enum msm_bus_dbg_op_type { |
||
4963 | + MSM_BUS_DBG_UNREGISTER = -2, |
||
4964 | + MSM_BUS_DBG_REGISTER, |
||
4965 | + MSM_BUS_DBG_OP = 1, |
||
4966 | +}; |
||
4967 | + |
||
4968 | +enum msm_bus_hw_sel { |
||
4969 | + MSM_BUS_RPM = 0, |
||
4970 | + MSM_BUS_NOC, |
||
4971 | + MSM_BUS_BIMC, |
||
4972 | +}; |
||
4973 | + |
||
4974 | +struct msm_bus_arb_ops { |
||
4975 | + uint32_t (*register_client)(struct msm_bus_scale_pdata *pdata); |
||
4976 | + int (*update_request)(uint32_t cl, unsigned int index); |
||
4977 | + void (*unregister_client)(uint32_t cl); |
||
4978 | +}; |
||
4979 | + |
||
4980 | +enum { |
||
4981 | + SLAVE_NODE, |
||
4982 | + MASTER_NODE, |
||
4983 | + CLK_NODE, |
||
4984 | + NR_LIM_NODE, |
||
4985 | +}; |
||
4986 | + |
||
4987 | + |
||
4988 | +extern struct bus_type msm_bus_type; |
||
4989 | +extern struct msm_bus_arb_ops arb_ops; |
||
4990 | +extern void msm_bus_arb_setops_legacy(struct msm_bus_arb_ops *arb_ops); |
||
4991 | + |
||
4992 | +struct msm_bus_node_info { |
||
4993 | + unsigned int id; |
||
4994 | + unsigned int priv_id; |
||
4995 | + unsigned int mas_hw_id; |
||
4996 | + unsigned int slv_hw_id; |
||
4997 | + int gateway; |
||
4998 | + int *masterp; |
||
4999 | + int *qport; |
||
5000 | + int num_mports; |
||
5001 | + int *slavep; |
||
5002 | + int num_sports; |
||
5003 | + int *tier; |
||
5004 | + int num_tiers; |
||
5005 | + int ahb; |
||
5006 | + int hw_sel; |
||
5007 | + const char *slaveclk[NUM_CTX]; |
||
5008 | + const char *memclk[NUM_CTX]; |
||
5009 | + const char *iface_clk_node; |
||
5010 | + unsigned int buswidth; |
||
5011 | + unsigned int ws; |
||
5012 | + unsigned int mode; |
||
5013 | + unsigned int perm_mode; |
||
5014 | + unsigned int prio_lvl; |
||
5015 | + unsigned int prio_rd; |
||
5016 | + unsigned int prio_wr; |
||
5017 | + unsigned int prio1; |
||
5018 | + unsigned int prio0; |
||
5019 | + unsigned int num_thresh; |
||
5020 | + u64 *th; |
||
5021 | + u64 cur_lim_bw; |
||
5022 | + unsigned int mode_thresh; |
||
5023 | + bool dual_conf; |
||
5024 | + u64 *bimc_bw; |
||
5025 | + bool nr_lim; |
||
5026 | + u32 ff; |
||
5027 | + bool rt_mas; |
||
5028 | + u32 bimc_gp; |
||
5029 | + u32 bimc_thmp; |
||
5030 | + u64 floor_bw; |
||
5031 | + const char *name; |
||
5032 | +}; |
||
5033 | + |
||
5034 | +struct path_node { |
||
5035 | + uint64_t clk[NUM_CTX]; |
||
5036 | + uint64_t bw[NUM_CTX]; |
||
5037 | + uint64_t *sel_clk; |
||
5038 | + uint64_t *sel_bw; |
||
5039 | + int next; |
||
5040 | +}; |
||
5041 | + |
||
5042 | +struct msm_bus_link_info { |
||
5043 | + uint64_t clk[NUM_CTX]; |
||
5044 | + uint64_t *sel_clk; |
||
5045 | + uint64_t memclk; |
||
5046 | + int64_t bw[NUM_CTX]; |
||
5047 | + int64_t *sel_bw; |
||
5048 | + int *tier; |
||
5049 | + int num_tiers; |
||
5050 | +}; |
||
5051 | + |
||
5052 | +struct nodeclk { |
||
5053 | + struct clk *clk; |
||
5054 | + uint64_t rate; |
||
5055 | + bool dirty; |
||
5056 | + bool enable; |
||
5057 | +}; |
||
5058 | + |
||
5059 | +struct msm_bus_inode_info { |
||
5060 | + struct msm_bus_node_info *node_info; |
||
5061 | + uint64_t max_bw; |
||
5062 | + uint64_t max_clk; |
||
5063 | + uint64_t cur_lim_bw; |
||
5064 | + uint64_t cur_prg_bw; |
||
5065 | + struct msm_bus_link_info link_info; |
||
5066 | + int num_pnodes; |
||
5067 | + struct path_node *pnode; |
||
5068 | + int commit_index; |
||
5069 | + struct nodeclk nodeclk[NUM_CTX]; |
||
5070 | + struct nodeclk memclk[NUM_CTX]; |
||
5071 | + struct nodeclk iface_clk; |
||
5072 | + void *hw_data; |
||
5073 | +}; |
||
5074 | + |
||
5075 | +struct msm_bus_node_hw_info { |
||
5076 | + bool dirty; |
||
5077 | + unsigned int hw_id; |
||
5078 | + uint64_t bw; |
||
5079 | +}; |
||
5080 | + |
||
5081 | +struct msm_bus_hw_algorithm { |
||
5082 | + int (*allocate_commit_data)(struct msm_bus_fabric_registration |
||
5083 | + *fab_pdata, void **cdata, int ctx); |
||
5084 | + void *(*allocate_hw_data)(struct platform_device *pdev, |
||
5085 | + struct msm_bus_fabric_registration *fab_pdata); |
||
5086 | + void (*node_init)(void *hw_data, struct msm_bus_inode_info *info); |
||
5087 | + void (*free_commit_data)(void *cdata); |
||
5088 | + void (*update_bw)(struct msm_bus_inode_info *hop, |
||
5089 | + struct msm_bus_inode_info *info, |
||
5090 | + struct msm_bus_fabric_registration *fab_pdata, |
||
5091 | + void *sel_cdata, int *master_tiers, |
||
5092 | + int64_t add_bw); |
||
5093 | + void (*fill_cdata_buffer)(int *curr, char *buf, const int max_size, |
||
5094 | + void *cdata, int nmasters, int nslaves, int ntslaves); |
||
5095 | + int (*commit)(struct msm_bus_fabric_registration |
||
5096 | + *fab_pdata, void *hw_data, void **cdata); |
||
5097 | + int (*port_unhalt)(uint32_t haltid, uint8_t mport); |
||
5098 | + int (*port_halt)(uint32_t haltid, uint8_t mport); |
||
5099 | + void (*config_master)(struct msm_bus_fabric_registration *fab_pdata, |
||
5100 | + struct msm_bus_inode_info *info, |
||
5101 | + uint64_t req_clk, uint64_t req_bw); |
||
5102 | + void (*config_limiter)(struct msm_bus_fabric_registration *fab_pdata, |
||
5103 | + struct msm_bus_inode_info *info); |
||
5104 | + bool (*update_bw_reg)(int mode); |
||
5105 | +}; |
||
5106 | + |
||
5107 | +struct msm_bus_fabric_device { |
||
5108 | + int id; |
||
5109 | + const char *name; |
||
5110 | + struct device dev; |
||
5111 | + const struct msm_bus_fab_algorithm *algo; |
||
5112 | + const struct msm_bus_board_algorithm *board_algo; |
||
5113 | + struct msm_bus_hw_algorithm hw_algo; |
||
5114 | + int visited; |
||
5115 | + int num_nr_lim; |
||
5116 | + u64 nr_lim_thresh; |
||
5117 | + u32 eff_fact; |
||
5118 | +}; |
||
5119 | +#define to_msm_bus_fabric_device(d) container_of(d, \ |
||
5120 | + struct msm_bus_fabric_device, d) |
||
5121 | + |
||
5122 | +struct msm_bus_fabric { |
||
5123 | + struct msm_bus_fabric_device fabdev; |
||
5124 | + int ahb; |
||
5125 | + void *cdata[NUM_CTX]; |
||
5126 | + bool arb_dirty; |
||
5127 | + bool clk_dirty; |
||
5128 | + struct radix_tree_root fab_tree; |
||
5129 | + int num_nodes; |
||
5130 | + struct list_head gateways; |
||
5131 | + struct msm_bus_inode_info info; |
||
5132 | + struct msm_bus_fabric_registration *pdata; |
||
5133 | + void *hw_data; |
||
5134 | +}; |
||
5135 | +#define to_msm_bus_fabric(d) container_of(d, \ |
||
5136 | + struct msm_bus_fabric, d) |
||
5137 | + |
||
5138 | + |
||
5139 | +struct msm_bus_fab_algorithm { |
||
5140 | + int (*update_clks)(struct msm_bus_fabric_device *fabdev, |
||
5141 | + struct msm_bus_inode_info *pme, int index, |
||
5142 | + uint64_t curr_clk, uint64_t req_clk, |
||
5143 | + uint64_t bwsum, int flag, int ctx, |
||
5144 | + unsigned int cl_active_flag); |
||
5145 | + int (*port_halt)(struct msm_bus_fabric_device *fabdev, int portid); |
||
5146 | + int (*port_unhalt)(struct msm_bus_fabric_device *fabdev, int portid); |
||
5147 | + int (*commit)(struct msm_bus_fabric_device *fabdev); |
||
5148 | + struct msm_bus_inode_info *(*find_node)(struct msm_bus_fabric_device |
||
5149 | + *fabdev, int id); |
||
5150 | + struct msm_bus_inode_info *(*find_gw_node)(struct msm_bus_fabric_device |
||
5151 | + *fabdev, int id); |
||
5152 | + struct list_head *(*get_gw_list)(struct msm_bus_fabric_device *fabdev); |
||
5153 | + void (*update_bw)(struct msm_bus_fabric_device *fabdev, struct |
||
5154 | + msm_bus_inode_info * hop, struct msm_bus_inode_info *info, |
||
5155 | + int64_t add_bw, int *master_tiers, int ctx); |
||
5156 | + void (*config_master)(struct msm_bus_fabric_device *fabdev, |
||
5157 | + struct msm_bus_inode_info *info, uint64_t req_clk, |
||
5158 | + uint64_t req_bw); |
||
5159 | + void (*config_limiter)(struct msm_bus_fabric_device *fabdev, |
||
5160 | + struct msm_bus_inode_info *info); |
||
5161 | +}; |
||
5162 | + |
||
5163 | +struct msm_bus_board_algorithm { |
||
5164 | + int board_nfab; |
||
5165 | + void (*assign_iids)(struct msm_bus_fabric_registration *fabreg, |
||
5166 | + int fabid); |
||
5167 | + int (*get_iid)(int id); |
||
5168 | +}; |
||
5169 | + |
||
5170 | +/** |
||
5171 | + * Used to store the list of fabrics and other info to be |
||
5172 | + * maintained outside the fabric structure. |
||
5173 | + * Used while calculating path, and to find fabric ptrs |
||
5174 | + */ |
||
5175 | +struct msm_bus_fabnodeinfo { |
||
5176 | + struct list_head list; |
||
5177 | + struct msm_bus_inode_info *info; |
||
5178 | +}; |
||
5179 | + |
||
5180 | +struct msm_bus_client { |
||
5181 | + int id; |
||
5182 | + struct msm_bus_scale_pdata *pdata; |
||
5183 | + int *src_pnode; |
||
5184 | + int curr; |
||
5185 | +}; |
||
5186 | + |
||
5187 | +uint64_t msm_bus_div64(unsigned int width, uint64_t bw); |
||
5188 | +int msm_bus_fabric_device_register(struct msm_bus_fabric_device *fabric); |
||
5189 | +void msm_bus_fabric_device_unregister(struct msm_bus_fabric_device *fabric); |
||
5190 | +struct msm_bus_fabric_device *msm_bus_get_fabric_device(int fabid); |
||
5191 | +int msm_bus_get_num_fab(void); |
||
5192 | + |
||
5193 | + |
||
5194 | +int msm_bus_hw_fab_init(struct msm_bus_fabric_registration *pdata, |
||
5195 | + struct msm_bus_hw_algorithm *hw_algo); |
||
5196 | +void msm_bus_board_init(struct msm_bus_fabric_registration *pdata); |
||
5197 | +void msm_bus_board_set_nfab(struct msm_bus_fabric_registration *pdata, |
||
5198 | + int nfab); |
||
5199 | +#if defined(CONFIG_MSM_RPM_SMD) |
||
5200 | +int msm_bus_rpm_hw_init(struct msm_bus_fabric_registration *pdata, |
||
5201 | + struct msm_bus_hw_algorithm *hw_algo); |
||
5202 | +int msm_bus_remote_hw_commit(struct msm_bus_fabric_registration |
||
5203 | + *fab_pdata, void *hw_data, void **cdata); |
||
5204 | +void msm_bus_rpm_fill_cdata_buffer(int *curr, char *buf, const int max_size, |
||
5205 | + void *cdata, int nmasters, int nslaves, int ntslaves); |
||
5206 | +#else |
||
5207 | +static inline int msm_bus_rpm_hw_init(struct msm_bus_fabric_registration *pdata, |
||
5208 | + struct msm_bus_hw_algorithm *hw_algo) |
||
5209 | +{ |
||
5210 | + return 0; |
||
5211 | +} |
||
5212 | +static inline int msm_bus_remote_hw_commit(struct msm_bus_fabric_registration |
||
5213 | + *fab_pdata, void *hw_data, void **cdata) |
||
5214 | +{ |
||
5215 | + return 0; |
||
5216 | +} |
||
5217 | +static inline void msm_bus_rpm_fill_cdata_buffer(int *curr, char *buf, |
||
5218 | + const int max_size, void *cdata, int nmasters, int nslaves, |
||
5219 | + int ntslaves) |
||
5220 | +{ |
||
5221 | +} |
||
5222 | +#endif |
||
5223 | + |
||
5224 | +int msm_bus_noc_hw_init(struct msm_bus_fabric_registration *pdata, |
||
5225 | + struct msm_bus_hw_algorithm *hw_algo); |
||
5226 | +int msm_bus_bimc_hw_init(struct msm_bus_fabric_registration *pdata, |
||
5227 | + struct msm_bus_hw_algorithm *hw_algo); |
||
5228 | +#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_MSM_BUS_SCALING) |
||
5229 | +void msm_bus_dbg_client_data(struct msm_bus_scale_pdata *pdata, int index, |
||
5230 | + uint32_t cl); |
||
5231 | +void msm_bus_dbg_commit_data(const char *fabname, void *cdata, |
||
5232 | + int nmasters, int nslaves, int ntslaves, int op); |
||
5233 | +#else |
||
5234 | +static inline void msm_bus_dbg_client_data(struct msm_bus_scale_pdata *pdata, |
||
5235 | + int index, uint32_t cl) |
||
5236 | +{ |
||
5237 | +} |
||
5238 | +static inline void msm_bus_dbg_commit_data(const char *fabname, |
||
5239 | + void *cdata, int nmasters, int nslaves, int ntslaves, |
||
5240 | + int op) |
||
5241 | +{ |
||
5242 | +} |
||
5243 | +#endif |
||
5244 | + |
||
5245 | +#ifdef CONFIG_CORESIGHT |
||
5246 | +int msmbus_coresight_init(struct platform_device *pdev); |
||
5247 | +void msmbus_coresight_remove(struct platform_device *pdev); |
||
5248 | +int msmbus_coresight_init_adhoc(struct platform_device *pdev, |
||
5249 | + struct device_node *of_node); |
||
5250 | +void msmbus_coresight_remove_adhoc(struct platform_device *pdev); |
||
5251 | +#else |
||
5252 | +static inline int msmbus_coresight_init(struct platform_device *pdev) |
||
5253 | +{ |
||
5254 | + return 0; |
||
5255 | +} |
||
5256 | + |
||
5257 | +static inline void msmbus_coresight_remove(struct platform_device *pdev) |
||
5258 | +{ |
||
5259 | +} |
||
5260 | + |
||
5261 | +static inline int msmbus_coresight_init_adhoc(struct platform_device *pdev, |
||
5262 | + struct device_node *of_node) |
||
5263 | +{ |
||
5264 | + return 0; |
||
5265 | +} |
||
5266 | + |
||
5267 | +static inline void msmbus_coresight_remove_adhoc(struct platform_device *pdev) |
||
5268 | +{ |
||
5269 | +} |
||
5270 | +#endif |
||
5271 | + |
||
5272 | + |
||
5273 | +#ifdef CONFIG_OF |
||
5274 | +void msm_bus_of_get_nfab(struct platform_device *pdev, |
||
5275 | + struct msm_bus_fabric_registration *pdata); |
||
5276 | +struct msm_bus_fabric_registration |
||
5277 | + *msm_bus_of_get_fab_data(struct platform_device *pdev); |
||
5278 | +#else |
||
5279 | +static inline void msm_bus_of_get_nfab(struct platform_device *pdev, |
||
5280 | + struct msm_bus_fabric_registration *pdata) |
||
5281 | +{ |
||
5282 | + return; |
||
5283 | +} |
||
5284 | + |
||
5285 | +static inline struct msm_bus_fabric_registration |
||
5286 | + *msm_bus_of_get_fab_data(struct platform_device *pdev) |
||
5287 | +{ |
||
5288 | + return NULL; |
||
5289 | +} |
||
5290 | +#endif |
||
5291 | + |
||
5292 | +#endif /*_ARCH_ARM_MACH_MSM_BUS_CORE_H*/ |
||
5293 | --- /dev/null |
||
5294 | +++ b/drivers/bus/msm_bus/msm_bus_dbg.c |
||
5295 | @@ -0,0 +1,810 @@ |
||
5296 | +/* Copyright (c) 2010-2012, 2014, The Linux Foundation. All rights reserved. |
||
5297 | + * |
||
5298 | + * This program is free software; you can redistribute it and/or modify |
||
5299 | + * it under the terms of the GNU General Public License version 2 and |
||
5300 | + * only version 2 as published by the Free Software Foundation. |
||
5301 | + * |
||
5302 | + * This program is distributed in the hope that it will be useful, |
||
5303 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
5304 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
5305 | + * GNU General Public License for more details. |
||
5306 | + * |
||
5307 | + */ |
||
5308 | + |
||
5309 | +#define pr_fmt(fmt) "AXI: %s(): " fmt, __func__ |
||
5310 | + |
||
5311 | +#include <linux/kernel.h> |
||
5312 | +#include <linux/module.h> |
||
5313 | +#include <linux/seq_file.h> |
||
5314 | +#include <linux/debugfs.h> |
||
5315 | +#include <linux/slab.h> |
||
5316 | +#include <linux/mutex.h> |
||
5317 | +#include <linux/string.h> |
||
5318 | +#include <linux/uaccess.h> |
||
5319 | +#include <linux/hrtimer.h> |
||
5320 | +#include "msm-bus-board.h" |
||
5321 | +#include "msm-bus.h" |
||
5322 | +#include "msm_bus_rules.h" |
||
5323 | +#include "msm_bus_core.h" |
||
5324 | +#include "msm_bus_adhoc.h" |
||
5325 | + |
||
5326 | +#define CREATE_TRACE_POINTS |
||
5327 | +#include <trace/events/trace_msm_bus.h> |
||
5328 | + |
||
5329 | +#define MAX_BUFF_SIZE 4096 |
||
5330 | +#define FILL_LIMIT 128 |
||
5331 | + |
||
5332 | +static struct dentry *clients; |
||
5333 | +static struct dentry *dir; |
||
5334 | +static DEFINE_MUTEX(msm_bus_dbg_fablist_lock); |
||
5335 | +struct msm_bus_dbg_state { |
||
5336 | + uint32_t cl; |
||
5337 | + uint8_t enable; |
||
5338 | + uint8_t current_index; |
||
5339 | +} clstate; |
||
5340 | + |
||
5341 | +struct msm_bus_cldata { |
||
5342 | + const struct msm_bus_scale_pdata *pdata; |
||
5343 | + int index; |
||
5344 | + uint32_t clid; |
||
5345 | + int size; |
||
5346 | + struct dentry *file; |
||
5347 | + struct list_head list; |
||
5348 | + char buffer[MAX_BUFF_SIZE]; |
||
5349 | +}; |
||
5350 | + |
||
5351 | +struct msm_bus_fab_list { |
||
5352 | + const char *name; |
||
5353 | + int size; |
||
5354 | + struct dentry *file; |
||
5355 | + struct list_head list; |
||
5356 | + char buffer[MAX_BUFF_SIZE]; |
||
5357 | +}; |
||
5358 | + |
||
5359 | +static char *rules_buf; |
||
5360 | + |
||
5361 | +LIST_HEAD(fabdata_list); |
||
5362 | +LIST_HEAD(cl_list); |
||
5363 | + |
||
5364 | +/** |
||
5365 | + * The following structures and funtions are used for |
||
5366 | + * the test-client which can be created at run-time. |
||
5367 | + */ |
||
5368 | + |
||
5369 | +static struct msm_bus_vectors init_vectors[1]; |
||
5370 | +static struct msm_bus_vectors current_vectors[1]; |
||
5371 | +static struct msm_bus_vectors requested_vectors[1]; |
||
5372 | + |
||
5373 | +static struct msm_bus_paths shell_client_usecases[] = { |
||
5374 | + { |
||
5375 | + .num_paths = ARRAY_SIZE(init_vectors), |
||
5376 | + .vectors = init_vectors, |
||
5377 | + }, |
||
5378 | + { |
||
5379 | + .num_paths = ARRAY_SIZE(current_vectors), |
||
5380 | + .vectors = current_vectors, |
||
5381 | + }, |
||
5382 | + { |
||
5383 | + .num_paths = ARRAY_SIZE(requested_vectors), |
||
5384 | + .vectors = requested_vectors, |
||
5385 | + }, |
||
5386 | +}; |
||
5387 | + |
||
5388 | +static struct msm_bus_scale_pdata shell_client = { |
||
5389 | + .usecase = shell_client_usecases, |
||
5390 | + .num_usecases = ARRAY_SIZE(shell_client_usecases), |
||
5391 | + .name = "test-client", |
||
5392 | +}; |
||
5393 | + |
||
5394 | +static void msm_bus_dbg_init_vectors(void) |
||
5395 | +{ |
||
5396 | + init_vectors[0].src = -1; |
||
5397 | + init_vectors[0].dst = -1; |
||
5398 | + init_vectors[0].ab = 0; |
||
5399 | + init_vectors[0].ib = 0; |
||
5400 | + current_vectors[0].src = -1; |
||
5401 | + current_vectors[0].dst = -1; |
||
5402 | + current_vectors[0].ab = 0; |
||
5403 | + current_vectors[0].ib = 0; |
||
5404 | + requested_vectors[0].src = -1; |
||
5405 | + requested_vectors[0].dst = -1; |
||
5406 | + requested_vectors[0].ab = 0; |
||
5407 | + requested_vectors[0].ib = 0; |
||
5408 | + clstate.enable = 0; |
||
5409 | + clstate.current_index = 0; |
||
5410 | +} |
||
5411 | + |
||
5412 | +static int msm_bus_dbg_update_cl_request(uint32_t cl) |
||
5413 | +{ |
||
5414 | + int ret = 0; |
||
5415 | + |
||
5416 | + if (clstate.current_index < 2) |
||
5417 | + clstate.current_index = 2; |
||
5418 | + else { |
||
5419 | + clstate.current_index = 1; |
||
5420 | + current_vectors[0].ab = requested_vectors[0].ab; |
||
5421 | + current_vectors[0].ib = requested_vectors[0].ib; |
||
5422 | + } |
||
5423 | + |
||
5424 | + if (clstate.enable) { |
||
5425 | + MSM_BUS_DBG("Updating request for shell client, index: %d\n", |
||
5426 | + clstate.current_index); |
||
5427 | + ret = msm_bus_scale_client_update_request(clstate.cl, |
||
5428 | + clstate.current_index); |
||
5429 | + } else |
||
5430 | + MSM_BUS_DBG("Enable bit not set. Skipping update request\n"); |
||
5431 | + |
||
5432 | + return ret; |
||
5433 | +} |
||
5434 | + |
||
5435 | +static void msm_bus_dbg_unregister_client(uint32_t cl) |
||
5436 | +{ |
||
5437 | + MSM_BUS_DBG("Unregistering shell client\n"); |
||
5438 | + msm_bus_scale_unregister_client(clstate.cl); |
||
5439 | + clstate.cl = 0; |
||
5440 | +} |
||
5441 | + |
||
5442 | +static uint32_t msm_bus_dbg_register_client(void) |
||
5443 | +{ |
||
5444 | + int ret = 0; |
||
5445 | + |
||
5446 | + if (init_vectors[0].src != requested_vectors[0].src) { |
||
5447 | + MSM_BUS_DBG("Shell client master changed. Unregistering\n"); |
||
5448 | + msm_bus_dbg_unregister_client(clstate.cl); |
||
5449 | + } |
||
5450 | + if (init_vectors[0].dst != requested_vectors[0].dst) { |
||
5451 | + MSM_BUS_DBG("Shell client slave changed. Unregistering\n"); |
||
5452 | + msm_bus_dbg_unregister_client(clstate.cl); |
||
5453 | + } |
||
5454 | + |
||
5455 | + current_vectors[0].src = init_vectors[0].src; |
||
5456 | + requested_vectors[0].src = init_vectors[0].src; |
||
5457 | + current_vectors[0].dst = init_vectors[0].dst; |
||
5458 | + requested_vectors[0].dst = init_vectors[0].dst; |
||
5459 | + |
||
5460 | + if (!clstate.enable) { |
||
5461 | + MSM_BUS_DBG("Enable bit not set, skipping registration: cl " |
||
5462 | + "%d\n", clstate.cl); |
||
5463 | + return 0; |
||
5464 | + } |
||
5465 | + |
||
5466 | + if (clstate.cl) { |
||
5467 | + MSM_BUS_DBG("Client registered, skipping registration\n"); |
||
5468 | + return clstate.cl; |
||
5469 | + } |
||
5470 | + |
||
5471 | + MSM_BUS_DBG("Registering shell client\n"); |
||
5472 | + ret = msm_bus_scale_register_client(&shell_client); |
||
5473 | + return ret; |
||
5474 | +} |
||
5475 | + |
||
5476 | +static int msm_bus_dbg_mas_get(void *data, u64 *val) |
||
5477 | +{ |
||
5478 | + *val = init_vectors[0].src; |
||
5479 | + MSM_BUS_DBG("Get master: %llu\n", *val); |
||
5480 | + return 0; |
||
5481 | +} |
||
5482 | + |
||
5483 | +static int msm_bus_dbg_mas_set(void *data, u64 val) |
||
5484 | +{ |
||
5485 | + init_vectors[0].src = val; |
||
5486 | + MSM_BUS_DBG("Set master: %llu\n", val); |
||
5487 | + clstate.cl = msm_bus_dbg_register_client(); |
||
5488 | + return 0; |
||
5489 | +} |
||
5490 | +DEFINE_SIMPLE_ATTRIBUTE(shell_client_mas_fops, msm_bus_dbg_mas_get, |
||
5491 | + msm_bus_dbg_mas_set, "%llu\n"); |
||
5492 | + |
||
5493 | +static int msm_bus_dbg_slv_get(void *data, u64 *val) |
||
5494 | +{ |
||
5495 | + *val = init_vectors[0].dst; |
||
5496 | + MSM_BUS_DBG("Get slave: %llu\n", *val); |
||
5497 | + return 0; |
||
5498 | +} |
||
5499 | + |
||
5500 | +static int msm_bus_dbg_slv_set(void *data, u64 val) |
||
5501 | +{ |
||
5502 | + init_vectors[0].dst = val; |
||
5503 | + MSM_BUS_DBG("Set slave: %llu\n", val); |
||
5504 | + clstate.cl = msm_bus_dbg_register_client(); |
||
5505 | + return 0; |
||
5506 | +} |
||
5507 | +DEFINE_SIMPLE_ATTRIBUTE(shell_client_slv_fops, msm_bus_dbg_slv_get, |
||
5508 | + msm_bus_dbg_slv_set, "%llu\n"); |
||
5509 | + |
||
5510 | +static int msm_bus_dbg_ab_get(void *data, u64 *val) |
||
5511 | +{ |
||
5512 | + *val = requested_vectors[0].ab; |
||
5513 | + MSM_BUS_DBG("Get ab: %llu\n", *val); |
||
5514 | + return 0; |
||
5515 | +} |
||
5516 | + |
||
5517 | +static int msm_bus_dbg_ab_set(void *data, u64 val) |
||
5518 | +{ |
||
5519 | + requested_vectors[0].ab = val; |
||
5520 | + MSM_BUS_DBG("Set ab: %llu\n", val); |
||
5521 | + return 0; |
||
5522 | +} |
||
5523 | +DEFINE_SIMPLE_ATTRIBUTE(shell_client_ab_fops, msm_bus_dbg_ab_get, |
||
5524 | + msm_bus_dbg_ab_set, "%llu\n"); |
||
5525 | + |
||
5526 | +static int msm_bus_dbg_ib_get(void *data, u64 *val) |
||
5527 | +{ |
||
5528 | + *val = requested_vectors[0].ib; |
||
5529 | + MSM_BUS_DBG("Get ib: %llu\n", *val); |
||
5530 | + return 0; |
||
5531 | +} |
||
5532 | + |
||
5533 | +static int msm_bus_dbg_ib_set(void *data, u64 val) |
||
5534 | +{ |
||
5535 | + requested_vectors[0].ib = val; |
||
5536 | + MSM_BUS_DBG("Set ib: %llu\n", val); |
||
5537 | + return 0; |
||
5538 | +} |
||
5539 | +DEFINE_SIMPLE_ATTRIBUTE(shell_client_ib_fops, msm_bus_dbg_ib_get, |
||
5540 | + msm_bus_dbg_ib_set, "%llu\n"); |
||
5541 | + |
||
5542 | +static int msm_bus_dbg_en_get(void *data, u64 *val) |
||
5543 | +{ |
||
5544 | + *val = clstate.enable; |
||
5545 | + MSM_BUS_DBG("Get enable: %llu\n", *val); |
||
5546 | + return 0; |
||
5547 | +} |
||
5548 | + |
||
5549 | +static int msm_bus_dbg_en_set(void *data, u64 val) |
||
5550 | +{ |
||
5551 | + int ret = 0; |
||
5552 | + |
||
5553 | + clstate.enable = val; |
||
5554 | + if (clstate.enable) { |
||
5555 | + if (!clstate.cl) { |
||
5556 | + MSM_BUS_DBG("client: %u\n", clstate.cl); |
||
5557 | + clstate.cl = msm_bus_dbg_register_client(); |
||
5558 | + if (clstate.cl) |
||
5559 | + ret = msm_bus_dbg_update_cl_request(clstate.cl); |
||
5560 | + } else { |
||
5561 | + MSM_BUS_DBG("update request for cl: %u\n", clstate.cl); |
||
5562 | + ret = msm_bus_dbg_update_cl_request(clstate.cl); |
||
5563 | + } |
||
5564 | + } |
||
5565 | + |
||
5566 | + MSM_BUS_DBG("Set enable: %llu\n", val); |
||
5567 | + return ret; |
||
5568 | +} |
||
5569 | +DEFINE_SIMPLE_ATTRIBUTE(shell_client_en_fops, msm_bus_dbg_en_get, |
||
5570 | + msm_bus_dbg_en_set, "%llu\n"); |
||
5571 | + |
||
5572 | +/** |
||
5573 | + * The following funtions are used for viewing the client data |
||
5574 | + * and changing the client request at run-time |
||
5575 | + */ |
||
5576 | + |
||
5577 | +static ssize_t client_data_read(struct file *file, char __user *buf, |
||
5578 | + size_t count, loff_t *ppos) |
||
5579 | +{ |
||
5580 | + int bsize = 0; |
||
5581 | + uint32_t cl = (uint32_t)(uintptr_t)file->private_data; |
||
5582 | + struct msm_bus_cldata *cldata = NULL; |
||
5583 | + int found = 0; |
||
5584 | + |
||
5585 | + list_for_each_entry(cldata, &cl_list, list) { |
||
5586 | + if (cldata->clid == cl) { |
||
5587 | + found = 1; |
||
5588 | + break; |
||
5589 | + } |
||
5590 | + } |
||
5591 | + if (!found) |
||
5592 | + return 0; |
||
5593 | + |
||
5594 | + bsize = cldata->size; |
||
5595 | + return simple_read_from_buffer(buf, count, ppos, |
||
5596 | + cldata->buffer, bsize); |
||
5597 | +} |
||
5598 | + |
||
5599 | +static int client_data_open(struct inode *inode, struct file *file) |
||
5600 | +{ |
||
5601 | + file->private_data = inode->i_private; |
||
5602 | + return 0; |
||
5603 | +} |
||
5604 | + |
||
5605 | +static const struct file_operations client_data_fops = { |
||
5606 | + .open = client_data_open, |
||
5607 | + .read = client_data_read, |
||
5608 | +}; |
||
5609 | + |
||
5610 | +struct dentry *msm_bus_dbg_create(const char *name, mode_t mode, |
||
5611 | + struct dentry *dent, uint32_t clid) |
||
5612 | +{ |
||
5613 | + if (dent == NULL) { |
||
5614 | + MSM_BUS_DBG("debugfs not ready yet\n"); |
||
5615 | + return NULL; |
||
5616 | + } |
||
5617 | + return debugfs_create_file(name, mode, dent, (void *)(uintptr_t)clid, |
||
5618 | + &client_data_fops); |
||
5619 | +} |
||
5620 | + |
||
5621 | +#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_MSM_BUS_SCALING) |
||
5622 | +static int msm_bus_dbg_record_client(const struct msm_bus_scale_pdata *pdata, |
||
5623 | + int index, uint32_t clid, struct dentry *file) |
||
5624 | +{ |
||
5625 | + struct msm_bus_cldata *cldata; |
||
5626 | + |
||
5627 | + cldata = kmalloc(sizeof(struct msm_bus_cldata), GFP_KERNEL); |
||
5628 | + if (!cldata) { |
||
5629 | + MSM_BUS_DBG("Failed to allocate memory for client data\n"); |
||
5630 | + return -ENOMEM; |
||
5631 | + } |
||
5632 | + cldata->pdata = pdata; |
||
5633 | + cldata->index = index; |
||
5634 | + cldata->clid = clid; |
||
5635 | + cldata->file = file; |
||
5636 | + cldata->size = 0; |
||
5637 | + list_add_tail(&cldata->list, &cl_list); |
||
5638 | + return 0; |
||
5639 | +} |
||
5640 | + |
||
5641 | +static void msm_bus_dbg_free_client(uint32_t clid) |
||
5642 | +{ |
||
5643 | + struct msm_bus_cldata *cldata = NULL; |
||
5644 | + |
||
5645 | + list_for_each_entry(cldata, &cl_list, list) { |
||
5646 | + if (cldata->clid == clid) { |
||
5647 | + debugfs_remove(cldata->file); |
||
5648 | + list_del(&cldata->list); |
||
5649 | + kfree(cldata); |
||
5650 | + break; |
||
5651 | + } |
||
5652 | + } |
||
5653 | +} |
||
5654 | + |
||
5655 | +static int msm_bus_dbg_fill_cl_buffer(const struct msm_bus_scale_pdata *pdata, |
||
5656 | + int index, uint32_t clid) |
||
5657 | +{ |
||
5658 | + int i = 0, j; |
||
5659 | + char *buf = NULL; |
||
5660 | + struct msm_bus_cldata *cldata = NULL; |
||
5661 | + struct timespec ts; |
||
5662 | + int found = 0; |
||
5663 | + |
||
5664 | + list_for_each_entry(cldata, &cl_list, list) { |
||
5665 | + if (cldata->clid == clid) { |
||
5666 | + found = 1; |
||
5667 | + break; |
||
5668 | + } |
||
5669 | + } |
||
5670 | + |
||
5671 | + if (!found) |
||
5672 | + return -ENOENT; |
||
5673 | + |
||
5674 | + if (cldata->file == NULL) { |
||
5675 | + if (pdata->name == NULL) { |
||
5676 | + MSM_BUS_DBG("Client doesn't have a name\n"); |
||
5677 | + return -EINVAL; |
||
5678 | + } |
||
5679 | + cldata->file = msm_bus_dbg_create(pdata->name, S_IRUGO, |
||
5680 | + clients, clid); |
||
5681 | + } |
||
5682 | + |
||
5683 | + if (cldata->size < (MAX_BUFF_SIZE - FILL_LIMIT)) |
||
5684 | + i = cldata->size; |
||
5685 | + else { |
||
5686 | + i = 0; |
||
5687 | + cldata->size = 0; |
||
5688 | + } |
||
5689 | + buf = cldata->buffer; |
||
5690 | + ts = ktime_to_timespec(ktime_get()); |
||
5691 | + i += scnprintf(buf + i, MAX_BUFF_SIZE - i, "\n%d.%d\n", |
||
5692 | + (int)ts.tv_sec, (int)ts.tv_nsec); |
||
5693 | + i += scnprintf(buf + i, MAX_BUFF_SIZE - i, "curr : %d\n", index); |
||
5694 | + i += scnprintf(buf + i, MAX_BUFF_SIZE - i, "masters: "); |
||
5695 | + |
||
5696 | + for (j = 0; j < pdata->usecase->num_paths; j++) |
||
5697 | + i += scnprintf(buf + i, MAX_BUFF_SIZE - i, "%d ", |
||
5698 | + pdata->usecase[index].vectors[j].src); |
||
5699 | + i += scnprintf(buf + i, MAX_BUFF_SIZE - i, "\nslaves : "); |
||
5700 | + for (j = 0; j < pdata->usecase->num_paths; j++) |
||
5701 | + i += scnprintf(buf + i, MAX_BUFF_SIZE - i, "%d ", |
||
5702 | + pdata->usecase[index].vectors[j].dst); |
||
5703 | + i += scnprintf(buf + i, MAX_BUFF_SIZE - i, "\nab : "); |
||
5704 | + for (j = 0; j < pdata->usecase->num_paths; j++) |
||
5705 | + i += scnprintf(buf + i, MAX_BUFF_SIZE - i, "%llu ", |
||
5706 | + pdata->usecase[index].vectors[j].ab); |
||
5707 | + i += scnprintf(buf + i, MAX_BUFF_SIZE - i, "\nib : "); |
||
5708 | + for (j = 0; j < pdata->usecase->num_paths; j++) |
||
5709 | + i += scnprintf(buf + i, MAX_BUFF_SIZE - i, "%llu ", |
||
5710 | + pdata->usecase[index].vectors[j].ib); |
||
5711 | + i += scnprintf(buf + i, MAX_BUFF_SIZE - i, "\n"); |
||
5712 | + |
||
5713 | + for (j = 0; j < pdata->usecase->num_paths; j++) |
||
5714 | + trace_bus_update_request((int)ts.tv_sec, (int)ts.tv_nsec, |
||
5715 | + pdata->name, index, |
||
5716 | + pdata->usecase[index].vectors[j].src, |
||
5717 | + pdata->usecase[index].vectors[j].dst, |
||
5718 | + pdata->usecase[index].vectors[j].ab, |
||
5719 | + pdata->usecase[index].vectors[j].ib); |
||
5720 | + |
||
5721 | + cldata->size = i; |
||
5722 | + return i; |
||
5723 | +} |
||
5724 | +#endif |
||
5725 | + |
||
5726 | +static int msm_bus_dbg_update_request(struct msm_bus_cldata *cldata, int index) |
||
5727 | +{ |
||
5728 | + int ret = 0; |
||
5729 | + |
||
5730 | + if ((index < 0) || (index > cldata->pdata->num_usecases)) { |
||
5731 | + MSM_BUS_DBG("Invalid index!\n"); |
||
5732 | + return -EINVAL; |
||
5733 | + } |
||
5734 | + ret = msm_bus_scale_client_update_request(cldata->clid, index); |
||
5735 | + return ret; |
||
5736 | +} |
||
5737 | + |
||
5738 | +static ssize_t msm_bus_dbg_update_request_write(struct file *file, |
||
5739 | + const char __user *ubuf, size_t cnt, loff_t *ppos) |
||
5740 | +{ |
||
5741 | + struct msm_bus_cldata *cldata; |
||
5742 | + unsigned long index = 0; |
||
5743 | + int ret = 0; |
||
5744 | + char *chid; |
||
5745 | + char *buf = kmalloc((sizeof(char) * (cnt + 1)), GFP_KERNEL); |
||
5746 | + int found = 0; |
||
5747 | + |
||
5748 | + if (!buf || IS_ERR(buf)) { |
||
5749 | + MSM_BUS_ERR("Memory allocation for buffer failed\n"); |
||
5750 | + return -ENOMEM; |
||
5751 | + } |
||
5752 | + if (cnt == 0) { |
||
5753 | + kfree(buf); |
||
5754 | + return 0; |
||
5755 | + } |
||
5756 | + if (copy_from_user(buf, ubuf, cnt)) { |
||
5757 | + kfree(buf); |
||
5758 | + return -EFAULT; |
||
5759 | + } |
||
5760 | + buf[cnt] = '\0'; |
||
5761 | + chid = buf; |
||
5762 | + MSM_BUS_DBG("buffer: %s\n size: %zu\n", buf, sizeof(ubuf)); |
||
5763 | + |
||
5764 | + list_for_each_entry(cldata, &cl_list, list) { |
||
5765 | + if (strnstr(chid, cldata->pdata->name, cnt)) { |
||
5766 | + found = 1; |
||
5767 | + cldata = cldata; |
||
5768 | + strsep(&chid, " "); |
||
5769 | + if (chid) { |
||
5770 | + ret = kstrtoul(chid, 10, &index); |
||
5771 | + if (ret) { |
||
5772 | + MSM_BUS_DBG("Index conversion" |
||
5773 | + " failed\n"); |
||
5774 | + return -EFAULT; |
||
5775 | + } |
||
5776 | + } else { |
||
5777 | + MSM_BUS_DBG("Error parsing input. Index not" |
||
5778 | + " found\n"); |
||
5779 | + found = 0; |
||
5780 | + } |
||
5781 | + break; |
||
5782 | + } |
||
5783 | + } |
||
5784 | + |
||
5785 | + if (found) |
||
5786 | + msm_bus_dbg_update_request(cldata, index); |
||
5787 | + kfree(buf); |
||
5788 | + return cnt; |
||
5789 | +} |
||
5790 | + |
||
5791 | +/** |
||
5792 | + * The following funtions are used for viewing the commit data |
||
5793 | + * for each fabric |
||
5794 | + */ |
||
5795 | +static ssize_t fabric_data_read(struct file *file, char __user *buf, |
||
5796 | + size_t count, loff_t *ppos) |
||
5797 | +{ |
||
5798 | + struct msm_bus_fab_list *fablist = NULL; |
||
5799 | + int bsize = 0; |
||
5800 | + ssize_t ret; |
||
5801 | + const char *name = file->private_data; |
||
5802 | + int found = 0; |
||
5803 | + |
||
5804 | + mutex_lock(&msm_bus_dbg_fablist_lock); |
||
5805 | + list_for_each_entry(fablist, &fabdata_list, list) { |
||
5806 | + if (strcmp(fablist->name, name) == 0) { |
||
5807 | + found = 1; |
||
5808 | + break; |
||
5809 | + } |
||
5810 | + } |
||
5811 | + if (!found) |
||
5812 | + return -ENOENT; |
||
5813 | + bsize = fablist->size; |
||
5814 | + ret = simple_read_from_buffer(buf, count, ppos, |
||
5815 | + fablist->buffer, bsize); |
||
5816 | + mutex_unlock(&msm_bus_dbg_fablist_lock); |
||
5817 | + return ret; |
||
5818 | +} |
||
5819 | + |
||
5820 | +static const struct file_operations fabric_data_fops = { |
||
5821 | + .open = client_data_open, |
||
5822 | + .read = fabric_data_read, |
||
5823 | +}; |
||
5824 | + |
||
5825 | +static ssize_t rules_dbg_read(struct file *file, char __user *buf, |
||
5826 | + size_t count, loff_t *ppos) |
||
5827 | +{ |
||
5828 | + ssize_t ret; |
||
5829 | + memset(rules_buf, 0, MAX_BUFF_SIZE); |
||
5830 | + print_rules_buf(rules_buf, MAX_BUFF_SIZE); |
||
5831 | + ret = simple_read_from_buffer(buf, count, ppos, |
||
5832 | + rules_buf, MAX_BUFF_SIZE); |
||
5833 | + return ret; |
||
5834 | +} |
||
5835 | + |
||
5836 | +static int rules_dbg_open(struct inode *inode, struct file *file) |
||
5837 | +{ |
||
5838 | + file->private_data = inode->i_private; |
||
5839 | + return 0; |
||
5840 | +} |
||
5841 | + |
||
5842 | +static const struct file_operations rules_dbg_fops = { |
||
5843 | + .open = rules_dbg_open, |
||
5844 | + .read = rules_dbg_read, |
||
5845 | +}; |
||
5846 | + |
||
5847 | +#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_MSM_BUS_SCALING) |
||
5848 | +static int msm_bus_dbg_record_fabric(const char *fabname, struct dentry *file) |
||
5849 | +{ |
||
5850 | + struct msm_bus_fab_list *fablist; |
||
5851 | + int ret = 0; |
||
5852 | + |
||
5853 | + mutex_lock(&msm_bus_dbg_fablist_lock); |
||
5854 | + fablist = kmalloc(sizeof(struct msm_bus_fab_list), GFP_KERNEL); |
||
5855 | + if (!fablist) { |
||
5856 | + MSM_BUS_DBG("Failed to allocate memory for commit data\n"); |
||
5857 | + ret = -ENOMEM; |
||
5858 | + goto err; |
||
5859 | + } |
||
5860 | + |
||
5861 | + fablist->name = fabname; |
||
5862 | + fablist->size = 0; |
||
5863 | + list_add_tail(&fablist->list, &fabdata_list); |
||
5864 | +err: |
||
5865 | + mutex_unlock(&msm_bus_dbg_fablist_lock); |
||
5866 | + return ret; |
||
5867 | +} |
||
5868 | + |
||
5869 | +static void msm_bus_dbg_free_fabric(const char *fabname) |
||
5870 | +{ |
||
5871 | + struct msm_bus_fab_list *fablist = NULL; |
||
5872 | + |
||
5873 | + mutex_lock(&msm_bus_dbg_fablist_lock); |
||
5874 | + list_for_each_entry(fablist, &fabdata_list, list) { |
||
5875 | + if (strcmp(fablist->name, fabname) == 0) { |
||
5876 | + debugfs_remove(fablist->file); |
||
5877 | + list_del(&fablist->list); |
||
5878 | + kfree(fablist); |
||
5879 | + break; |
||
5880 | + } |
||
5881 | + } |
||
5882 | + mutex_unlock(&msm_bus_dbg_fablist_lock); |
||
5883 | +} |
||
5884 | + |
||
5885 | +static int msm_bus_dbg_fill_fab_buffer(const char *fabname, |
||
5886 | + void *cdata, int nmasters, int nslaves, |
||
5887 | + int ntslaves) |
||
5888 | +{ |
||
5889 | + int i; |
||
5890 | + char *buf = NULL; |
||
5891 | + struct msm_bus_fab_list *fablist = NULL; |
||
5892 | + struct timespec ts; |
||
5893 | + int found = 0; |
||
5894 | + |
||
5895 | + mutex_lock(&msm_bus_dbg_fablist_lock); |
||
5896 | + list_for_each_entry(fablist, &fabdata_list, list) { |
||
5897 | + if (strcmp(fablist->name, fabname) == 0) { |
||
5898 | + found = 1; |
||
5899 | + break; |
||
5900 | + } |
||
5901 | + } |
||
5902 | + if (!found) |
||
5903 | + return -ENOENT; |
||
5904 | + |
||
5905 | + if (fablist->file == NULL) { |
||
5906 | + MSM_BUS_DBG("Fabric dbg entry does not exist\n"); |
||
5907 | + mutex_unlock(&msm_bus_dbg_fablist_lock); |
||
5908 | + return -EFAULT; |
||
5909 | + } |
||
5910 | + |
||
5911 | + if (fablist->size < MAX_BUFF_SIZE - 256) |
||
5912 | + i = fablist->size; |
||
5913 | + else { |
||
5914 | + i = 0; |
||
5915 | + fablist->size = 0; |
||
5916 | + } |
||
5917 | + buf = fablist->buffer; |
||
5918 | + mutex_unlock(&msm_bus_dbg_fablist_lock); |
||
5919 | + ts = ktime_to_timespec(ktime_get()); |
||
5920 | + i += scnprintf(buf + i, MAX_BUFF_SIZE - i, "\n%d.%d\n", |
||
5921 | + (int)ts.tv_sec, (int)ts.tv_nsec); |
||
5922 | + |
||
5923 | + msm_bus_rpm_fill_cdata_buffer(&i, buf, MAX_BUFF_SIZE, cdata, |
||
5924 | + nmasters, nslaves, ntslaves); |
||
5925 | + i += scnprintf(buf + i, MAX_BUFF_SIZE - i, "\n"); |
||
5926 | + mutex_lock(&msm_bus_dbg_fablist_lock); |
||
5927 | + fablist->size = i; |
||
5928 | + mutex_unlock(&msm_bus_dbg_fablist_lock); |
||
5929 | + return 0; |
||
5930 | +} |
||
5931 | +#endif |
||
5932 | + |
||
5933 | +static const struct file_operations msm_bus_dbg_update_request_fops = { |
||
5934 | + .open = client_data_open, |
||
5935 | + .write = msm_bus_dbg_update_request_write, |
||
5936 | +}; |
||
5937 | + |
||
5938 | +#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_MSM_BUS_SCALING) |
||
5939 | +/** |
||
5940 | + * msm_bus_dbg_client_data() - Add debug data for clients |
||
5941 | + * @pdata: Platform data of the client |
||
5942 | + * @index: The current index or operation to be performed |
||
5943 | + * @clid: Client handle obtained during registration |
||
5944 | + */ |
||
5945 | +void msm_bus_dbg_client_data(struct msm_bus_scale_pdata *pdata, int index, |
||
5946 | + uint32_t clid) |
||
5947 | +{ |
||
5948 | + struct dentry *file = NULL; |
||
5949 | + |
||
5950 | + if (index == MSM_BUS_DBG_REGISTER) { |
||
5951 | + msm_bus_dbg_record_client(pdata, index, clid, file); |
||
5952 | + if (!pdata->name) { |
||
5953 | + MSM_BUS_DBG("Cannot create debugfs entry. Null name\n"); |
||
5954 | + return; |
||
5955 | + } |
||
5956 | + } else if (index == MSM_BUS_DBG_UNREGISTER) { |
||
5957 | + msm_bus_dbg_free_client(clid); |
||
5958 | + MSM_BUS_DBG("Client %d unregistered\n", clid); |
||
5959 | + } else |
||
5960 | + msm_bus_dbg_fill_cl_buffer(pdata, index, clid); |
||
5961 | +} |
||
5962 | +EXPORT_SYMBOL(msm_bus_dbg_client_data); |
||
5963 | + |
||
5964 | +/** |
||
5965 | + * msm_bus_dbg_commit_data() - Add commit data from fabrics |
||
5966 | + * @fabname: Fabric name specified in platform data |
||
5967 | + * @cdata: Commit Data |
||
5968 | + * @nmasters: Number of masters attached to fabric |
||
5969 | + * @nslaves: Number of slaves attached to fabric |
||
5970 | + * @ntslaves: Number of tiered slaves attached to fabric |
||
5971 | + * @op: Operation to be performed |
||
5972 | + */ |
||
5973 | +void msm_bus_dbg_commit_data(const char *fabname, void *cdata, |
||
5974 | + int nmasters, int nslaves, int ntslaves, int op) |
||
5975 | +{ |
||
5976 | + struct dentry *file = NULL; |
||
5977 | + |
||
5978 | + if (op == MSM_BUS_DBG_REGISTER) |
||
5979 | + msm_bus_dbg_record_fabric(fabname, file); |
||
5980 | + else if (op == MSM_BUS_DBG_UNREGISTER) |
||
5981 | + msm_bus_dbg_free_fabric(fabname); |
||
5982 | + else |
||
5983 | + msm_bus_dbg_fill_fab_buffer(fabname, cdata, nmasters, |
||
5984 | + nslaves, ntslaves); |
||
5985 | +} |
||
5986 | +EXPORT_SYMBOL(msm_bus_dbg_commit_data); |
||
5987 | +#endif |
||
5988 | + |
||
5989 | +static int __init msm_bus_debugfs_init(void) |
||
5990 | +{ |
||
5991 | + struct dentry *commit, *shell_client, *rules_dbg; |
||
5992 | + struct msm_bus_fab_list *fablist; |
||
5993 | + struct msm_bus_cldata *cldata = NULL; |
||
5994 | + uint64_t val = 0; |
||
5995 | + |
||
5996 | + dir = debugfs_create_dir("msm-bus-dbg", NULL); |
||
5997 | + if ((!dir) || IS_ERR(dir)) { |
||
5998 | + MSM_BUS_ERR("Couldn't create msm-bus-dbg\n"); |
||
5999 | + goto err; |
||
6000 | + } |
||
6001 | + |
||
6002 | + clients = debugfs_create_dir("client-data", dir); |
||
6003 | + if ((!dir) || IS_ERR(dir)) { |
||
6004 | + MSM_BUS_ERR("Couldn't create clients\n"); |
||
6005 | + goto err; |
||
6006 | + } |
||
6007 | + |
||
6008 | + shell_client = debugfs_create_dir("shell-client", dir); |
||
6009 | + if ((!dir) || IS_ERR(dir)) { |
||
6010 | + MSM_BUS_ERR("Couldn't create clients\n"); |
||
6011 | + goto err; |
||
6012 | + } |
||
6013 | + |
||
6014 | + commit = debugfs_create_dir("commit-data", dir); |
||
6015 | + if ((!dir) || IS_ERR(dir)) { |
||
6016 | + MSM_BUS_ERR("Couldn't create commit\n"); |
||
6017 | + goto err; |
||
6018 | + } |
||
6019 | + |
||
6020 | + rules_dbg = debugfs_create_dir("rules-dbg", dir); |
||
6021 | + if ((!rules_dbg) || IS_ERR(rules_dbg)) { |
||
6022 | + MSM_BUS_ERR("Couldn't create rules-dbg\n"); |
||
6023 | + goto err; |
||
6024 | + } |
||
6025 | + |
||
6026 | + if (debugfs_create_file("print_rules", S_IRUGO | S_IWUSR, |
||
6027 | + rules_dbg, &val, &rules_dbg_fops) == NULL) |
||
6028 | + goto err; |
||
6029 | + |
||
6030 | + if (debugfs_create_file("update_request", S_IRUGO | S_IWUSR, |
||
6031 | + shell_client, &val, &shell_client_en_fops) == NULL) |
||
6032 | + goto err; |
||
6033 | + if (debugfs_create_file("ib", S_IRUGO | S_IWUSR, shell_client, &val, |
||
6034 | + &shell_client_ib_fops) == NULL) |
||
6035 | + goto err; |
||
6036 | + if (debugfs_create_file("ab", S_IRUGO | S_IWUSR, shell_client, &val, |
||
6037 | + &shell_client_ab_fops) == NULL) |
||
6038 | + goto err; |
||
6039 | + if (debugfs_create_file("slv", S_IRUGO | S_IWUSR, shell_client, |
||
6040 | + &val, &shell_client_slv_fops) == NULL) |
||
6041 | + goto err; |
||
6042 | + if (debugfs_create_file("mas", S_IRUGO | S_IWUSR, shell_client, |
||
6043 | + &val, &shell_client_mas_fops) == NULL) |
||
6044 | + goto err; |
||
6045 | + if (debugfs_create_file("update-request", S_IRUGO | S_IWUSR, |
||
6046 | + clients, NULL, &msm_bus_dbg_update_request_fops) == NULL) |
||
6047 | + goto err; |
||
6048 | + |
||
6049 | + rules_buf = kzalloc(MAX_BUFF_SIZE, GFP_KERNEL); |
||
6050 | + if (!rules_buf) { |
||
6051 | + MSM_BUS_ERR("Failed to alloc rules_buf"); |
||
6052 | + goto err; |
||
6053 | + } |
||
6054 | + |
||
6055 | + list_for_each_entry(cldata, &cl_list, list) { |
||
6056 | + if (cldata->pdata->name == NULL) { |
||
6057 | + MSM_BUS_DBG("Client name not found\n"); |
||
6058 | + continue; |
||
6059 | + } |
||
6060 | + cldata->file = msm_bus_dbg_create(cldata-> |
||
6061 | + pdata->name, S_IRUGO, clients, cldata->clid); |
||
6062 | + } |
||
6063 | + |
||
6064 | + mutex_lock(&msm_bus_dbg_fablist_lock); |
||
6065 | + list_for_each_entry(fablist, &fabdata_list, list) { |
||
6066 | + fablist->file = debugfs_create_file(fablist->name, S_IRUGO, |
||
6067 | + commit, (void *)fablist->name, &fabric_data_fops); |
||
6068 | + if (fablist->file == NULL) { |
||
6069 | + MSM_BUS_DBG("Cannot create files for commit data\n"); |
||
6070 | + kfree(rules_buf); |
||
6071 | + goto err; |
||
6072 | + } |
||
6073 | + } |
||
6074 | + mutex_unlock(&msm_bus_dbg_fablist_lock); |
||
6075 | + |
||
6076 | + msm_bus_dbg_init_vectors(); |
||
6077 | + return 0; |
||
6078 | +err: |
||
6079 | + debugfs_remove_recursive(dir); |
||
6080 | + return -ENODEV; |
||
6081 | +} |
||
6082 | +late_initcall(msm_bus_debugfs_init); |
||
6083 | + |
||
6084 | +static void __exit msm_bus_dbg_teardown(void) |
||
6085 | +{ |
||
6086 | + struct msm_bus_fab_list *fablist = NULL, *fablist_temp; |
||
6087 | + struct msm_bus_cldata *cldata = NULL, *cldata_temp; |
||
6088 | + |
||
6089 | + debugfs_remove_recursive(dir); |
||
6090 | + list_for_each_entry_safe(cldata, cldata_temp, &cl_list, list) { |
||
6091 | + list_del(&cldata->list); |
||
6092 | + kfree(cldata); |
||
6093 | + } |
||
6094 | + mutex_lock(&msm_bus_dbg_fablist_lock); |
||
6095 | + list_for_each_entry_safe(fablist, fablist_temp, &fabdata_list, list) { |
||
6096 | + list_del(&fablist->list); |
||
6097 | + kfree(fablist); |
||
6098 | + } |
||
6099 | + kfree(rules_buf); |
||
6100 | + mutex_unlock(&msm_bus_dbg_fablist_lock); |
||
6101 | +} |
||
6102 | +module_exit(msm_bus_dbg_teardown); |
||
6103 | +MODULE_DESCRIPTION("Debugfs for msm bus scaling client"); |
||
6104 | +MODULE_LICENSE("GPL v2"); |
||
6105 | +MODULE_AUTHOR("Gagan Mac <gmac@codeaurora.org>"); |
||
6106 | --- /dev/null |
||
6107 | +++ b/drivers/bus/msm_bus/msm_bus_fabric_adhoc.c |
||
6108 | @@ -0,0 +1,1281 @@ |
||
6109 | +/* Copyright (c) 2014, Linux Foundation. All rights reserved. |
||
6110 | + * |
||
6111 | + * This program is free software; you can redistribute it and/or modify |
||
6112 | + * it under the terms of the GNU General Public License version 2 and |
||
6113 | + * only version 2 as published by the Free Software Foundation. |
||
6114 | + * |
||
6115 | + * This program is distributed in the hope that it will be useful, |
||
6116 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
6117 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
6118 | + * GNU General Public License for more details. |
||
6119 | + */ |
||
6120 | + |
||
6121 | +#include <linux/clk.h> |
||
6122 | +#include <linux/device.h> |
||
6123 | +#include <linux/init.h> |
||
6124 | +#include <linux/io.h> |
||
6125 | +#include <linux/kernel.h> |
||
6126 | +#include <linux/module.h> |
||
6127 | +#include <linux/slab.h> |
||
6128 | +#include "rpm-smd.h" |
||
6129 | +#include "msm_bus_core.h" |
||
6130 | +#include "msm_bus_adhoc.h" |
||
6131 | +#include "msm_bus_noc.h" |
||
6132 | +#include "msm_bus_bimc.h" |
||
6133 | + |
||
6134 | +ssize_t vrail_show(struct device *dev, struct device_attribute *attr, |
||
6135 | + char *buf) |
||
6136 | +{ |
||
6137 | + struct msm_bus_node_info_type *node_info = NULL; |
||
6138 | + struct msm_bus_node_device_type *bus_node = NULL; |
||
6139 | + |
||
6140 | + bus_node = dev->platform_data; |
||
6141 | + if (!bus_node) |
||
6142 | + return -EINVAL; |
||
6143 | + node_info = bus_node->node_info; |
||
6144 | + |
||
6145 | + return snprintf(buf, PAGE_SIZE, "%u", node_info->vrail_comp); |
||
6146 | +} |
||
6147 | + |
||
6148 | +ssize_t vrail_store(struct device *dev, struct device_attribute *attr, |
||
6149 | + const char *buf, size_t count) |
||
6150 | +{ |
||
6151 | + struct msm_bus_node_info_type *node_info = NULL; |
||
6152 | + struct msm_bus_node_device_type *bus_node = NULL; |
||
6153 | + int ret = 0; |
||
6154 | + |
||
6155 | + bus_node = dev->platform_data; |
||
6156 | + if (!bus_node) |
||
6157 | + return -EINVAL; |
||
6158 | + node_info = bus_node->node_info; |
||
6159 | + |
||
6160 | + ret = sscanf(buf, "%u", &node_info->vrail_comp); |
||
6161 | + if (ret != 1) |
||
6162 | + return -EINVAL; |
||
6163 | + return count; |
||
6164 | +} |
||
6165 | + |
||
6166 | +DEVICE_ATTR(vrail, 0600, vrail_show, vrail_store); |
||
6167 | + |
||
6168 | +struct static_rules_type { |
||
6169 | + int num_rules; |
||
6170 | + struct bus_rule_type *rules; |
||
6171 | +}; |
||
6172 | + |
||
6173 | +static struct static_rules_type static_rules; |
||
6174 | + |
||
6175 | +static int enable_nodeclk(struct nodeclk *nclk) |
||
6176 | +{ |
||
6177 | + int ret = 0; |
||
6178 | + |
||
6179 | + if (!nclk->enable) { |
||
6180 | + ret = clk_prepare_enable(nclk->clk); |
||
6181 | + |
||
6182 | + if (ret) { |
||
6183 | + MSM_BUS_ERR("%s: failed to enable clk ", __func__); |
||
6184 | + nclk->enable = false; |
||
6185 | + } else |
||
6186 | + nclk->enable = true; |
||
6187 | + } |
||
6188 | + return ret; |
||
6189 | +} |
||
6190 | + |
||
6191 | +static int disable_nodeclk(struct nodeclk *nclk) |
||
6192 | +{ |
||
6193 | + int ret = 0; |
||
6194 | + |
||
6195 | + if (nclk->enable) { |
||
6196 | + clk_disable_unprepare(nclk->clk); |
||
6197 | + nclk->enable = false; |
||
6198 | + } |
||
6199 | + return ret; |
||
6200 | +} |
||
6201 | + |
||
6202 | +static int setrate_nodeclk(struct nodeclk *nclk, long rate) |
||
6203 | +{ |
||
6204 | + int ret = 0; |
||
6205 | + |
||
6206 | + ret = clk_set_rate(nclk->clk, rate); |
||
6207 | + |
||
6208 | + if (ret) |
||
6209 | + MSM_BUS_ERR("%s: failed to setrate clk", __func__); |
||
6210 | + return ret; |
||
6211 | +} |
||
6212 | + |
||
6213 | +static int msm_bus_agg_fab_clks(struct device *bus_dev, void *data) |
||
6214 | +{ |
||
6215 | + struct msm_bus_node_device_type *node = NULL; |
||
6216 | + int ret = 0; |
||
6217 | + int ctx = *(int *)data; |
||
6218 | + |
||
6219 | + if (ctx >= NUM_CTX) { |
||
6220 | + MSM_BUS_ERR("%s: Invalid Context %d", __func__, ctx); |
||
6221 | + goto exit_agg_fab_clks; |
||
6222 | + } |
||
6223 | + |
||
6224 | + node = bus_dev->platform_data; |
||
6225 | + if (!node) { |
||
6226 | + MSM_BUS_ERR("%s: Can't get device info", __func__); |
||
6227 | + goto exit_agg_fab_clks; |
||
6228 | + } |
||
6229 | + |
||
6230 | + if (!node->node_info->is_fab_dev) { |
||
6231 | + struct msm_bus_node_device_type *bus_dev = NULL; |
||
6232 | + |
||
6233 | + bus_dev = node->node_info->bus_device->platform_data; |
||
6234 | + |
||
6235 | + if (node->cur_clk_hz[ctx] >= bus_dev->cur_clk_hz[ctx]) |
||
6236 | + bus_dev->cur_clk_hz[ctx] = node->cur_clk_hz[ctx]; |
||
6237 | + } |
||
6238 | + |
||
6239 | +exit_agg_fab_clks: |
||
6240 | + return ret; |
||
6241 | +} |
||
6242 | + |
||
6243 | +static int msm_bus_reset_fab_clks(struct device *bus_dev, void *data) |
||
6244 | +{ |
||
6245 | + struct msm_bus_node_device_type *node = NULL; |
||
6246 | + int ret = 0; |
||
6247 | + int ctx = *(int *)data; |
||
6248 | + |
||
6249 | + if (ctx >= NUM_CTX) { |
||
6250 | + MSM_BUS_ERR("%s: Invalid Context %d", __func__, ctx); |
||
6251 | + goto exit_reset_fab_clks; |
||
6252 | + } |
||
6253 | + |
||
6254 | + node = bus_dev->platform_data; |
||
6255 | + if (!node) { |
||
6256 | + MSM_BUS_ERR("%s: Can't get device info", __func__); |
||
6257 | + goto exit_reset_fab_clks; |
||
6258 | + } |
||
6259 | + |
||
6260 | + if (node->node_info->is_fab_dev) { |
||
6261 | + node->cur_clk_hz[ctx] = 0; |
||
6262 | + MSM_BUS_DBG("Resetting for node %d", node->node_info->id); |
||
6263 | + } |
||
6264 | +exit_reset_fab_clks: |
||
6265 | + return ret; |
||
6266 | +} |
||
6267 | + |
||
6268 | + |
||
6269 | +static int send_rpm_msg(struct device *device) |
||
6270 | +{ |
||
6271 | + int ret = 0; |
||
6272 | + int ctx; |
||
6273 | + int rsc_type; |
||
6274 | + struct msm_bus_node_device_type *ndev = |
||
6275 | + device->platform_data; |
||
6276 | + struct msm_rpm_kvp rpm_kvp; |
||
6277 | + |
||
6278 | + if (!ndev) { |
||
6279 | + MSM_BUS_ERR("%s: Error getting node info.", __func__); |
||
6280 | + ret = -ENODEV; |
||
6281 | + goto exit_send_rpm_msg; |
||
6282 | + } |
||
6283 | + |
||
6284 | + rpm_kvp.length = sizeof(uint64_t); |
||
6285 | + rpm_kvp.key = RPM_MASTER_FIELD_BW; |
||
6286 | + |
||
6287 | + for (ctx = MSM_RPM_CTX_ACTIVE_SET; ctx <= MSM_RPM_CTX_SLEEP_SET; |
||
6288 | + ctx++) { |
||
6289 | + if (ctx == MSM_RPM_CTX_ACTIVE_SET) |
||
6290 | + rpm_kvp.data = |
||
6291 | + (uint8_t *)&ndev->node_ab.ab[MSM_RPM_CTX_ACTIVE_SET]; |
||
6292 | + else { |
||
6293 | + rpm_kvp.data = |
||
6294 | + (uint8_t *) &ndev->node_ab.ab[MSM_RPM_CTX_SLEEP_SET]; |
||
6295 | + } |
||
6296 | + |
||
6297 | + if (ndev->node_info->mas_rpm_id != -1) { |
||
6298 | + rsc_type = RPM_BUS_MASTER_REQ; |
||
6299 | + ret = msm_rpm_send_message(ctx, rsc_type, |
||
6300 | + ndev->node_info->mas_rpm_id, &rpm_kvp, 1); |
||
6301 | + if (ret) { |
||
6302 | + MSM_BUS_ERR("%s: Failed to send RPM message:", |
||
6303 | + __func__); |
||
6304 | + MSM_BUS_ERR("%s:Node Id %d RPM id %d", |
||
6305 | + __func__, ndev->node_info->id, |
||
6306 | + ndev->node_info->mas_rpm_id); |
||
6307 | + goto exit_send_rpm_msg; |
||
6308 | + } |
||
6309 | + } |
||
6310 | + |
||
6311 | + if (ndev->node_info->slv_rpm_id != -1) { |
||
6312 | + rsc_type = RPM_BUS_SLAVE_REQ; |
||
6313 | + ret = msm_rpm_send_message(ctx, rsc_type, |
||
6314 | + ndev->node_info->slv_rpm_id, &rpm_kvp, 1); |
||
6315 | + if (ret) { |
||
6316 | + MSM_BUS_ERR("%s: Failed to send RPM message:", |
||
6317 | + __func__); |
||
6318 | + MSM_BUS_ERR("%s: Node Id %d RPM id %d", |
||
6319 | + __func__, ndev->node_info->id, |
||
6320 | + ndev->node_info->slv_rpm_id); |
||
6321 | + goto exit_send_rpm_msg; |
||
6322 | + } |
||
6323 | + } |
||
6324 | + } |
||
6325 | +exit_send_rpm_msg: |
||
6326 | + return ret; |
||
6327 | +} |
||
6328 | + |
||
6329 | +static int flush_bw_data(struct device *node_device, int ctx) |
||
6330 | +{ |
||
6331 | + struct msm_bus_node_device_type *node_info; |
||
6332 | + int ret = 0; |
||
6333 | + |
||
6334 | + node_info = node_device->platform_data; |
||
6335 | + if (!node_info) { |
||
6336 | + MSM_BUS_ERR("%s: Unable to find bus device for device", |
||
6337 | + __func__); |
||
6338 | + ret = -ENODEV; |
||
6339 | + goto exit_flush_bw_data; |
||
6340 | + } |
||
6341 | + |
||
6342 | + if (node_info->node_ab.dirty) { |
||
6343 | + if (node_info->ap_owned) { |
||
6344 | + struct msm_bus_node_device_type *bus_device = |
||
6345 | + node_info->node_info->bus_device->platform_data; |
||
6346 | + struct msm_bus_fab_device_type *fabdev = |
||
6347 | + bus_device->fabdev; |
||
6348 | + |
||
6349 | + if (fabdev && fabdev->noc_ops.update_bw_reg && |
||
6350 | + fabdev->noc_ops.update_bw_reg |
||
6351 | + (node_info->node_info->qos_params.mode)) |
||
6352 | + ret = fabdev->noc_ops.set_bw(node_info, |
||
6353 | + fabdev->qos_base, |
||
6354 | + fabdev->base_offset, |
||
6355 | + fabdev->qos_off, |
||
6356 | + fabdev->qos_freq); |
||
6357 | + } else { |
||
6358 | + ret = send_rpm_msg(node_device); |
||
6359 | + |
||
6360 | + if (ret) |
||
6361 | + MSM_BUS_ERR("%s: Failed to send RPM msg for%d", |
||
6362 | + __func__, node_info->node_info->id); |
||
6363 | + } |
||
6364 | + node_info->node_ab.dirty = false; |
||
6365 | + } |
||
6366 | + |
||
6367 | +exit_flush_bw_data: |
||
6368 | + return ret; |
||
6369 | + |
||
6370 | +} |
||
6371 | + |
||
6372 | +static int flush_clk_data(struct device *node_device, int ctx) |
||
6373 | +{ |
||
6374 | + struct msm_bus_node_device_type *node; |
||
6375 | + struct nodeclk *nodeclk = NULL; |
||
6376 | + int ret = 0; |
||
6377 | + |
||
6378 | + node = node_device->platform_data; |
||
6379 | + if (!node) { |
||
6380 | + MSM_BUS_ERR("Unable to find bus device"); |
||
6381 | + ret = -ENODEV; |
||
6382 | + goto exit_flush_clk_data; |
||
6383 | + } |
||
6384 | + |
||
6385 | + nodeclk = &node->clk[ctx]; |
||
6386 | + if (node->node_info->is_fab_dev) { |
||
6387 | + if (nodeclk->rate != node->cur_clk_hz[ctx]) { |
||
6388 | + nodeclk->rate = node->cur_clk_hz[ctx]; |
||
6389 | + nodeclk->dirty = true; |
||
6390 | + } |
||
6391 | + } |
||
6392 | + |
||
6393 | + if (nodeclk && nodeclk->clk && nodeclk->dirty) { |
||
6394 | + long rounded_rate; |
||
6395 | + |
||
6396 | + if (nodeclk->rate) { |
||
6397 | + rounded_rate = clk_round_rate(nodeclk->clk, |
||
6398 | + nodeclk->rate); |
||
6399 | + ret = setrate_nodeclk(nodeclk, rounded_rate); |
||
6400 | + |
||
6401 | + if (ret) { |
||
6402 | + MSM_BUS_ERR("%s: Failed to set_rate %lu for %d", |
||
6403 | + __func__, rounded_rate, |
||
6404 | + node->node_info->id); |
||
6405 | + ret = -ENODEV; |
||
6406 | + goto exit_flush_clk_data; |
||
6407 | + } |
||
6408 | + |
||
6409 | + ret = enable_nodeclk(nodeclk); |
||
6410 | + } else |
||
6411 | + ret = disable_nodeclk(nodeclk); |
||
6412 | + |
||
6413 | + if (ret) { |
||
6414 | + MSM_BUS_ERR("%s: Failed to enable for %d", __func__, |
||
6415 | + node->node_info->id); |
||
6416 | + ret = -ENODEV; |
||
6417 | + goto exit_flush_clk_data; |
||
6418 | + } |
||
6419 | + MSM_BUS_DBG("%s: Updated %d clk to %llu", __func__, |
||
6420 | + node->node_info->id, nodeclk->rate); |
||
6421 | + |
||
6422 | + } |
||
6423 | +exit_flush_clk_data: |
||
6424 | + /* Reset the aggregated clock rate for fab devices*/ |
||
6425 | + if (node && node->node_info->is_fab_dev) |
||
6426 | + node->cur_clk_hz[ctx] = 0; |
||
6427 | + |
||
6428 | + if (nodeclk) |
||
6429 | + nodeclk->dirty = 0; |
||
6430 | + return ret; |
||
6431 | +} |
||
6432 | + |
||
6433 | +int msm_bus_commit_data(int *dirty_nodes, int ctx, int num_dirty) |
||
6434 | +{ |
||
6435 | + int ret = 0; |
||
6436 | + int i = 0; |
||
6437 | + |
||
6438 | + /* Aggregate the bus clocks */ |
||
6439 | + bus_for_each_dev(&msm_bus_type, NULL, (void *)&ctx, |
||
6440 | + msm_bus_agg_fab_clks); |
||
6441 | + |
||
6442 | + for (i = 0; i < num_dirty; i++) { |
||
6443 | + struct device *node_device = |
||
6444 | + bus_find_device(&msm_bus_type, NULL, |
||
6445 | + (void *)&dirty_nodes[i], |
||
6446 | + msm_bus_device_match_adhoc); |
||
6447 | + |
||
6448 | + if (!node_device) { |
||
6449 | + MSM_BUS_ERR("Can't find device for %d", dirty_nodes[i]); |
||
6450 | + continue; |
||
6451 | + } |
||
6452 | + |
||
6453 | + ret = flush_bw_data(node_device, ctx); |
||
6454 | + if (ret) |
||
6455 | + MSM_BUS_ERR("%s: Error flushing bw data for node %d", |
||
6456 | + __func__, dirty_nodes[i]); |
||
6457 | + |
||
6458 | + ret = flush_clk_data(node_device, ctx); |
||
6459 | + if (ret) |
||
6460 | + MSM_BUS_ERR("%s: Error flushing clk data for node %d", |
||
6461 | + __func__, dirty_nodes[i]); |
||
6462 | + } |
||
6463 | + kfree(dirty_nodes); |
||
6464 | + /* Aggregate the bus clocks */ |
||
6465 | + bus_for_each_dev(&msm_bus_type, NULL, (void *)&ctx, |
||
6466 | + msm_bus_reset_fab_clks); |
||
6467 | + return ret; |
||
6468 | +} |
||
6469 | + |
||
6470 | +void *msm_bus_realloc_devmem(struct device *dev, void *p, size_t old_size, |
||
6471 | + size_t new_size, gfp_t flags) |
||
6472 | +{ |
||
6473 | + void *ret; |
||
6474 | + size_t copy_size = old_size; |
||
6475 | + |
||
6476 | + if (!new_size) { |
||
6477 | + devm_kfree(dev, p); |
||
6478 | + return ZERO_SIZE_PTR; |
||
6479 | + } |
||
6480 | + |
||
6481 | + if (new_size < old_size) |
||
6482 | + copy_size = new_size; |
||
6483 | + |
||
6484 | + ret = devm_kzalloc(dev, new_size, flags); |
||
6485 | + if (!ret) { |
||
6486 | + MSM_BUS_ERR("%s: Error Reallocating memory", __func__); |
||
6487 | + goto exit_realloc_devmem; |
||
6488 | + } |
||
6489 | + |
||
6490 | + memcpy(ret, p, copy_size); |
||
6491 | + devm_kfree(dev, p); |
||
6492 | +exit_realloc_devmem: |
||
6493 | + return ret; |
||
6494 | +} |
||
6495 | + |
||
6496 | + |
||
6497 | +static int add_dirty_node(int **dirty_nodes, int id, int *num_dirty) |
||
6498 | +{ |
||
6499 | + int i; |
||
6500 | + int found = 0; |
||
6501 | + int ret = 0; |
||
6502 | + int *dnode = NULL; |
||
6503 | + |
||
6504 | + for (i = 0; i < *num_dirty; i++) { |
||
6505 | + if ((*dirty_nodes)[i] == id) { |
||
6506 | + found = 1; |
||
6507 | + break; |
||
6508 | + } |
||
6509 | + } |
||
6510 | + |
||
6511 | + if (!found) { |
||
6512 | + (*num_dirty)++; |
||
6513 | + dnode = |
||
6514 | + krealloc(*dirty_nodes, sizeof(int) * (*num_dirty), |
||
6515 | + GFP_KERNEL); |
||
6516 | + |
||
6517 | + if (ZERO_OR_NULL_PTR(dnode)) { |
||
6518 | + MSM_BUS_ERR("%s: Failure allocating dirty nodes array", |
||
6519 | + __func__); |
||
6520 | + ret = -ENOMEM; |
||
6521 | + } else { |
||
6522 | + *dirty_nodes = dnode; |
||
6523 | + (*dirty_nodes)[(*num_dirty) - 1] = id; |
||
6524 | + } |
||
6525 | + } |
||
6526 | + |
||
6527 | + return ret; |
||
6528 | +} |
||
6529 | + |
||
6530 | +int msm_bus_update_bw(struct msm_bus_node_device_type *nodedev, int ctx, |
||
6531 | + int64_t add_bw, int **dirty_nodes, int *num_dirty) |
||
6532 | +{ |
||
6533 | + int ret = 0; |
||
6534 | + int i, j; |
||
6535 | + uint64_t cur_ab_slp = 0; |
||
6536 | + uint64_t cur_ab_act = 0; |
||
6537 | + |
||
6538 | + if (nodedev->node_info->virt_dev) |
||
6539 | + goto exit_update_bw; |
||
6540 | + |
||
6541 | + for (i = 0; i < NUM_CTX; i++) { |
||
6542 | + for (j = 0; j < nodedev->num_lnodes; j++) { |
||
6543 | + if (i == DUAL_CTX) { |
||
6544 | + cur_ab_act += |
||
6545 | + nodedev->lnode_list[j].lnode_ab[i]; |
||
6546 | + cur_ab_slp += |
||
6547 | + nodedev->lnode_list[j].lnode_ab[i]; |
||
6548 | + } else |
||
6549 | + cur_ab_act += |
||
6550 | + nodedev->lnode_list[j].lnode_ab[i]; |
||
6551 | + } |
||
6552 | + } |
||
6553 | + |
||
6554 | + if (nodedev->node_ab.ab[MSM_RPM_CTX_ACTIVE_SET] != cur_ab_act) { |
||
6555 | + nodedev->node_ab.ab[MSM_RPM_CTX_ACTIVE_SET] = cur_ab_act; |
||
6556 | + nodedev->node_ab.ab[MSM_RPM_CTX_SLEEP_SET] = cur_ab_slp; |
||
6557 | + nodedev->node_ab.dirty = true; |
||
6558 | + ret = add_dirty_node(dirty_nodes, nodedev->node_info->id, |
||
6559 | + num_dirty); |
||
6560 | + |
||
6561 | + if (ret) { |
||
6562 | + MSM_BUS_ERR("%s: Failed to add dirty node %d", __func__, |
||
6563 | + nodedev->node_info->id); |
||
6564 | + goto exit_update_bw; |
||
6565 | + } |
||
6566 | + } |
||
6567 | + |
||
6568 | +exit_update_bw: |
||
6569 | + return ret; |
||
6570 | +} |
||
6571 | + |
||
6572 | +int msm_bus_update_clks(struct msm_bus_node_device_type *nodedev, |
||
6573 | + int ctx, int **dirty_nodes, int *num_dirty) |
||
6574 | +{ |
||
6575 | + int status = 0; |
||
6576 | + struct nodeclk *nodeclk; |
||
6577 | + struct nodeclk *busclk; |
||
6578 | + struct msm_bus_node_device_type *bus_info = NULL; |
||
6579 | + uint64_t req_clk; |
||
6580 | + |
||
6581 | + bus_info = nodedev->node_info->bus_device->platform_data; |
||
6582 | + |
||
6583 | + if (!bus_info) { |
||
6584 | + MSM_BUS_ERR("%s: Unable to find bus device for device %d", |
||
6585 | + __func__, nodedev->node_info->id); |
||
6586 | + status = -ENODEV; |
||
6587 | + goto exit_set_clks; |
||
6588 | + } |
||
6589 | + |
||
6590 | + req_clk = nodedev->cur_clk_hz[ctx]; |
||
6591 | + busclk = &bus_info->clk[ctx]; |
||
6592 | + |
||
6593 | + if (busclk->rate != req_clk) { |
||
6594 | + busclk->rate = req_clk; |
||
6595 | + busclk->dirty = 1; |
||
6596 | + MSM_BUS_DBG("%s: Modifying bus clk %d Rate %llu", __func__, |
||
6597 | + bus_info->node_info->id, req_clk); |
||
6598 | + status = add_dirty_node(dirty_nodes, bus_info->node_info->id, |
||
6599 | + num_dirty); |
||
6600 | + |
||
6601 | + if (status) { |
||
6602 | + MSM_BUS_ERR("%s: Failed to add dirty node %d", __func__, |
||
6603 | + bus_info->node_info->id); |
||
6604 | + goto exit_set_clks; |
||
6605 | + } |
||
6606 | + } |
||
6607 | + |
||
6608 | + req_clk = nodedev->cur_clk_hz[ctx]; |
||
6609 | + nodeclk = &nodedev->clk[ctx]; |
||
6610 | + |
||
6611 | + if (IS_ERR_OR_NULL(nodeclk)) |
||
6612 | + goto exit_set_clks; |
||
6613 | + |
||
6614 | + if (!nodeclk->dirty || (nodeclk->dirty && (nodeclk->rate < req_clk))) { |
||
6615 | + nodeclk->rate = req_clk; |
||
6616 | + nodeclk->dirty = 1; |
||
6617 | + MSM_BUS_DBG("%s: Modifying node clk %d Rate %llu", __func__, |
||
6618 | + nodedev->node_info->id, req_clk); |
||
6619 | + status = add_dirty_node(dirty_nodes, nodedev->node_info->id, |
||
6620 | + num_dirty); |
||
6621 | + if (status) { |
||
6622 | + MSM_BUS_ERR("%s: Failed to add dirty node %d", __func__, |
||
6623 | + nodedev->node_info->id); |
||
6624 | + goto exit_set_clks; |
||
6625 | + } |
||
6626 | + } |
||
6627 | + |
||
6628 | +exit_set_clks: |
||
6629 | + return status; |
||
6630 | +} |
||
6631 | + |
||
6632 | +static void msm_bus_fab_init_noc_ops(struct msm_bus_node_device_type *bus_dev) |
||
6633 | +{ |
||
6634 | + switch (bus_dev->fabdev->bus_type) { |
||
6635 | + case MSM_BUS_NOC: |
||
6636 | + msm_bus_noc_set_ops(bus_dev); |
||
6637 | + break; |
||
6638 | + case MSM_BUS_BIMC: |
||
6639 | + msm_bus_bimc_set_ops(bus_dev); |
||
6640 | + break; |
||
6641 | + default: |
||
6642 | + MSM_BUS_ERR("%s: Invalid Bus type", __func__); |
||
6643 | + } |
||
6644 | +} |
||
6645 | + |
||
6646 | +static int msm_bus_qos_disable_clk(struct msm_bus_node_device_type *node, |
||
6647 | + int disable_bus_qos_clk) |
||
6648 | +{ |
||
6649 | + struct msm_bus_node_device_type *bus_node = NULL; |
||
6650 | + int ret = 0; |
||
6651 | + |
||
6652 | + if (!node) { |
||
6653 | + ret = -ENXIO; |
||
6654 | + goto exit_disable_qos_clk; |
||
6655 | + } |
||
6656 | + |
||
6657 | + bus_node = node->node_info->bus_device->platform_data; |
||
6658 | + |
||
6659 | + if (!bus_node) { |
||
6660 | + ret = -ENXIO; |
||
6661 | + goto exit_disable_qos_clk; |
||
6662 | + } |
||
6663 | + |
||
6664 | + if (disable_bus_qos_clk) |
||
6665 | + ret = disable_nodeclk(&bus_node->clk[DUAL_CTX]); |
||
6666 | + |
||
6667 | + if (ret) { |
||
6668 | + MSM_BUS_ERR("%s: Failed to disable bus clk, node %d", |
||
6669 | + __func__, node->node_info->id); |
||
6670 | + goto exit_disable_qos_clk; |
||
6671 | + } |
||
6672 | + |
||
6673 | + if (!IS_ERR_OR_NULL(node->qos_clk.clk)) { |
||
6674 | + ret = disable_nodeclk(&node->qos_clk); |
||
6675 | + |
||
6676 | + if (ret) { |
||
6677 | + MSM_BUS_ERR("%s: Failed to disable mas qos clk,node %d", |
||
6678 | + __func__, node->node_info->id); |
||
6679 | + goto exit_disable_qos_clk; |
||
6680 | + } |
||
6681 | + } |
||
6682 | + |
||
6683 | +exit_disable_qos_clk: |
||
6684 | + return ret; |
||
6685 | +} |
||
6686 | + |
||
6687 | +static int msm_bus_qos_enable_clk(struct msm_bus_node_device_type *node) |
||
6688 | +{ |
||
6689 | + struct msm_bus_node_device_type *bus_node = NULL; |
||
6690 | + long rounded_rate; |
||
6691 | + int ret = 0; |
||
6692 | + int bus_qos_enabled = 0; |
||
6693 | + |
||
6694 | + if (!node) { |
||
6695 | + ret = -ENXIO; |
||
6696 | + goto exit_enable_qos_clk; |
||
6697 | + } |
||
6698 | + |
||
6699 | + bus_node = node->node_info->bus_device->platform_data; |
||
6700 | + |
||
6701 | + if (!bus_node) { |
||
6702 | + ret = -ENXIO; |
||
6703 | + goto exit_enable_qos_clk; |
||
6704 | + } |
||
6705 | + |
||
6706 | + /* Check if the bus clk is already set before trying to set it |
||
6707 | + * Do this only during |
||
6708 | + * a. Bootup |
||
6709 | + * b. Only for bus clks |
||
6710 | + **/ |
||
6711 | + if (!clk_get_rate(bus_node->clk[DUAL_CTX].clk)) { |
||
6712 | + rounded_rate = clk_round_rate(bus_node->clk[DUAL_CTX].clk, 1); |
||
6713 | + ret = setrate_nodeclk(&bus_node->clk[DUAL_CTX], rounded_rate); |
||
6714 | + if (ret) { |
||
6715 | + MSM_BUS_ERR("%s: Failed to set bus clk, node %d", |
||
6716 | + __func__, node->node_info->id); |
||
6717 | + goto exit_enable_qos_clk; |
||
6718 | + } |
||
6719 | + |
||
6720 | + ret = enable_nodeclk(&bus_node->clk[DUAL_CTX]); |
||
6721 | + if (ret) { |
||
6722 | + MSM_BUS_ERR("%s: Failed to enable bus clk, node %d", |
||
6723 | + __func__, node->node_info->id); |
||
6724 | + goto exit_enable_qos_clk; |
||
6725 | + } |
||
6726 | + bus_qos_enabled = 1; |
||
6727 | + } |
||
6728 | + |
||
6729 | + if (!IS_ERR_OR_NULL(node->qos_clk.clk)) { |
||
6730 | + rounded_rate = clk_round_rate(node->qos_clk.clk, 1); |
||
6731 | + ret = setrate_nodeclk(&node->qos_clk, rounded_rate); |
||
6732 | + if (ret) { |
||
6733 | + MSM_BUS_ERR("%s: Failed to enable mas qos clk, node %d", |
||
6734 | + __func__, node->node_info->id); |
||
6735 | + goto exit_enable_qos_clk; |
||
6736 | + } |
||
6737 | + |
||
6738 | + ret = enable_nodeclk(&node->qos_clk); |
||
6739 | + if (ret) { |
||
6740 | + MSM_BUS_ERR("Err enable mas qos clk, node %d ret %d", |
||
6741 | + node->node_info->id, ret); |
||
6742 | + goto exit_enable_qos_clk; |
||
6743 | + } |
||
6744 | + } |
||
6745 | + ret = bus_qos_enabled; |
||
6746 | + |
||
6747 | +exit_enable_qos_clk: |
||
6748 | + return ret; |
||
6749 | +} |
||
6750 | + |
||
6751 | +int msm_bus_enable_limiter(struct msm_bus_node_device_type *node_dev, |
||
6752 | + bool enable, uint64_t lim_bw) |
||
6753 | +{ |
||
6754 | + int ret = 0; |
||
6755 | + struct msm_bus_node_device_type *bus_node_dev; |
||
6756 | + |
||
6757 | + if (!node_dev) { |
||
6758 | + MSM_BUS_ERR("No device specified"); |
||
6759 | + ret = -ENXIO; |
||
6760 | + goto exit_enable_limiter; |
||
6761 | + } |
||
6762 | + |
||
6763 | + if (!node_dev->ap_owned) { |
||
6764 | + MSM_BUS_ERR("Device is not AP owned %d.", |
||
6765 | + node_dev->node_info->id); |
||
6766 | + ret = -ENXIO; |
||
6767 | + goto exit_enable_limiter; |
||
6768 | + } |
||
6769 | + |
||
6770 | + bus_node_dev = node_dev->node_info->bus_device->platform_data; |
||
6771 | + if (!bus_node_dev) { |
||
6772 | + MSM_BUS_ERR("Unable to get bus device infofor %d", |
||
6773 | + node_dev->node_info->id); |
||
6774 | + ret = -ENXIO; |
||
6775 | + goto exit_enable_limiter; |
||
6776 | + } |
||
6777 | + if (bus_node_dev->fabdev && |
||
6778 | + bus_node_dev->fabdev->noc_ops.limit_mport) { |
||
6779 | + ret = msm_bus_qos_enable_clk(node_dev); |
||
6780 | + if (ret < 0) { |
||
6781 | + MSM_BUS_ERR("Can't Enable QoS clk %d", |
||
6782 | + node_dev->node_info->id); |
||
6783 | + goto exit_enable_limiter; |
||
6784 | + } |
||
6785 | + bus_node_dev->fabdev->noc_ops.limit_mport( |
||
6786 | + node_dev, |
||
6787 | + bus_node_dev->fabdev->qos_base, |
||
6788 | + bus_node_dev->fabdev->base_offset, |
||
6789 | + bus_node_dev->fabdev->qos_off, |
||
6790 | + bus_node_dev->fabdev->qos_freq, |
||
6791 | + enable, lim_bw); |
||
6792 | + msm_bus_qos_disable_clk(node_dev, ret); |
||
6793 | + } |
||
6794 | + |
||
6795 | +exit_enable_limiter: |
||
6796 | + return ret; |
||
6797 | +} |
||
6798 | + |
||
6799 | +static int msm_bus_dev_init_qos(struct device *dev, void *data) |
||
6800 | +{ |
||
6801 | + int ret = 0; |
||
6802 | + struct msm_bus_node_device_type *node_dev = NULL; |
||
6803 | + |
||
6804 | + node_dev = dev->platform_data; |
||
6805 | + |
||
6806 | + if (!node_dev) { |
||
6807 | + MSM_BUS_ERR("%s: Unable to get node device info" , __func__); |
||
6808 | + ret = -ENXIO; |
||
6809 | + goto exit_init_qos; |
||
6810 | + } |
||
6811 | + |
||
6812 | + MSM_BUS_DBG("Device = %d", node_dev->node_info->id); |
||
6813 | + |
||
6814 | + if (node_dev->ap_owned) { |
||
6815 | + struct msm_bus_node_device_type *bus_node_info; |
||
6816 | + |
||
6817 | + bus_node_info = node_dev->node_info->bus_device->platform_data; |
||
6818 | + |
||
6819 | + if (!bus_node_info) { |
||
6820 | + MSM_BUS_ERR("%s: Unable to get bus device infofor %d", |
||
6821 | + __func__, |
||
6822 | + node_dev->node_info->id); |
||
6823 | + ret = -ENXIO; |
||
6824 | + goto exit_init_qos; |
||
6825 | + } |
||
6826 | + |
||
6827 | + if (bus_node_info->fabdev && |
||
6828 | + bus_node_info->fabdev->noc_ops.qos_init) { |
||
6829 | + int ret = 0; |
||
6830 | + |
||
6831 | + if (node_dev->ap_owned && |
||
6832 | + (node_dev->node_info->qos_params.mode) != -1) { |
||
6833 | + |
||
6834 | + if (bus_node_info->fabdev->bypass_qos_prg) |
||
6835 | + goto exit_init_qos; |
||
6836 | + |
||
6837 | + ret = msm_bus_qos_enable_clk(node_dev); |
||
6838 | + if (ret < 0) { |
||
6839 | + MSM_BUS_ERR("Can't Enable QoS clk %d", |
||
6840 | + node_dev->node_info->id); |
||
6841 | + goto exit_init_qos; |
||
6842 | + } |
||
6843 | + |
||
6844 | + bus_node_info->fabdev->noc_ops.qos_init( |
||
6845 | + node_dev, |
||
6846 | + bus_node_info->fabdev->qos_base, |
||
6847 | + bus_node_info->fabdev->base_offset, |
||
6848 | + bus_node_info->fabdev->qos_off, |
||
6849 | + bus_node_info->fabdev->qos_freq); |
||
6850 | + msm_bus_qos_disable_clk(node_dev, ret); |
||
6851 | + } |
||
6852 | + } else |
||
6853 | + MSM_BUS_ERR("%s: Skipping QOS init for %d", |
||
6854 | + __func__, node_dev->node_info->id); |
||
6855 | + } |
||
6856 | +exit_init_qos: |
||
6857 | + return ret; |
||
6858 | +} |
||
6859 | + |
||
6860 | +static int msm_bus_fabric_init(struct device *dev, |
||
6861 | + struct msm_bus_node_device_type *pdata) |
||
6862 | +{ |
||
6863 | + struct msm_bus_fab_device_type *fabdev; |
||
6864 | + struct msm_bus_node_device_type *node_dev = NULL; |
||
6865 | + int ret = 0; |
||
6866 | + |
||
6867 | + node_dev = dev->platform_data; |
||
6868 | + if (!node_dev) { |
||
6869 | + MSM_BUS_ERR("%s: Unable to get bus device info" , __func__); |
||
6870 | + ret = -ENXIO; |
||
6871 | + goto exit_fabric_init; |
||
6872 | + } |
||
6873 | + |
||
6874 | + if (node_dev->node_info->virt_dev) { |
||
6875 | + MSM_BUS_ERR("%s: Skip Fab init for virtual device %d", __func__, |
||
6876 | + node_dev->node_info->id); |
||
6877 | + goto exit_fabric_init; |
||
6878 | + } |
||
6879 | + |
||
6880 | + fabdev = devm_kzalloc(dev, sizeof(struct msm_bus_fab_device_type), |
||
6881 | + GFP_KERNEL); |
||
6882 | + if (!fabdev) { |
||
6883 | + MSM_BUS_ERR("Fabric alloc failed\n"); |
||
6884 | + ret = -ENOMEM; |
||
6885 | + goto exit_fabric_init; |
||
6886 | + } |
||
6887 | + |
||
6888 | + node_dev->fabdev = fabdev; |
||
6889 | + fabdev->pqos_base = pdata->fabdev->pqos_base; |
||
6890 | + fabdev->qos_range = pdata->fabdev->qos_range; |
||
6891 | + fabdev->base_offset = pdata->fabdev->base_offset; |
||
6892 | + fabdev->qos_off = pdata->fabdev->qos_off; |
||
6893 | + fabdev->qos_freq = pdata->fabdev->qos_freq; |
||
6894 | + fabdev->bus_type = pdata->fabdev->bus_type; |
||
6895 | + fabdev->bypass_qos_prg = pdata->fabdev->bypass_qos_prg; |
||
6896 | + fabdev->util_fact = pdata->fabdev->util_fact; |
||
6897 | + fabdev->vrail_comp = pdata->fabdev->vrail_comp; |
||
6898 | + msm_bus_fab_init_noc_ops(node_dev); |
||
6899 | + |
||
6900 | + fabdev->qos_base = devm_ioremap(dev, |
||
6901 | + fabdev->pqos_base, fabdev->qos_range); |
||
6902 | + if (!fabdev->qos_base) { |
||
6903 | + MSM_BUS_ERR("%s: Error remapping address 0x%zx :bus device %d", |
||
6904 | + __func__, |
||
6905 | + (size_t)fabdev->pqos_base, node_dev->node_info->id); |
||
6906 | + ret = -ENOMEM; |
||
6907 | + goto exit_fabric_init; |
||
6908 | + } |
||
6909 | + |
||
6910 | + /*if (msmbus_coresight_init(pdev)) |
||
6911 | + pr_warn("Coresight support absent for bus: %d\n", pdata->id);*/ |
||
6912 | +exit_fabric_init: |
||
6913 | + return ret; |
||
6914 | +} |
||
6915 | + |
||
6916 | +static int msm_bus_init_clk(struct device *bus_dev, |
||
6917 | + struct msm_bus_node_device_type *pdata) |
||
6918 | +{ |
||
6919 | + unsigned int ctx; |
||
6920 | + int ret = 0; |
||
6921 | + struct msm_bus_node_device_type *node_dev = bus_dev->platform_data; |
||
6922 | + |
||
6923 | + for (ctx = 0; ctx < NUM_CTX; ctx++) { |
||
6924 | + if (!IS_ERR_OR_NULL(pdata->clk[ctx].clk)) { |
||
6925 | + node_dev->clk[ctx].clk = pdata->clk[ctx].clk; |
||
6926 | + node_dev->clk[ctx].enable = false; |
||
6927 | + node_dev->clk[ctx].dirty = false; |
||
6928 | + MSM_BUS_ERR("%s: Valid node clk node %d ctx %d", |
||
6929 | + __func__, node_dev->node_info->id, ctx); |
||
6930 | + } |
||
6931 | + } |
||
6932 | + |
||
6933 | + if (!IS_ERR_OR_NULL(pdata->qos_clk.clk)) { |
||
6934 | + node_dev->qos_clk.clk = pdata->qos_clk.clk; |
||
6935 | + node_dev->qos_clk.enable = false; |
||
6936 | + MSM_BUS_ERR("%s: Valid Iface clk node %d", __func__, |
||
6937 | + node_dev->node_info->id); |
||
6938 | + } |
||
6939 | + |
||
6940 | + return ret; |
||
6941 | +} |
||
6942 | + |
||
6943 | +static int msm_bus_copy_node_info(struct msm_bus_node_device_type *pdata, |
||
6944 | + struct device *bus_dev) |
||
6945 | +{ |
||
6946 | + int ret = 0; |
||
6947 | + struct msm_bus_node_info_type *node_info = NULL; |
||
6948 | + struct msm_bus_node_info_type *pdata_node_info = NULL; |
||
6949 | + struct msm_bus_node_device_type *bus_node = NULL; |
||
6950 | + |
||
6951 | + bus_node = bus_dev->platform_data; |
||
6952 | + |
||
6953 | + if (!bus_node || !pdata) { |
||
6954 | + ret = -ENXIO; |
||
6955 | + MSM_BUS_ERR("%s: Invalid pointers pdata %p, bus_node %p", |
||
6956 | + __func__, pdata, bus_node); |
||
6957 | + goto exit_copy_node_info; |
||
6958 | + } |
||
6959 | + |
||
6960 | + node_info = bus_node->node_info; |
||
6961 | + pdata_node_info = pdata->node_info; |
||
6962 | + |
||
6963 | + node_info->name = pdata_node_info->name; |
||
6964 | + node_info->id = pdata_node_info->id; |
||
6965 | + node_info->bus_device_id = pdata_node_info->bus_device_id; |
||
6966 | + node_info->mas_rpm_id = pdata_node_info->mas_rpm_id; |
||
6967 | + node_info->slv_rpm_id = pdata_node_info->slv_rpm_id; |
||
6968 | + node_info->num_connections = pdata_node_info->num_connections; |
||
6969 | + node_info->num_blist = pdata_node_info->num_blist; |
||
6970 | + node_info->num_qports = pdata_node_info->num_qports; |
||
6971 | + node_info->buswidth = pdata_node_info->buswidth; |
||
6972 | + node_info->virt_dev = pdata_node_info->virt_dev; |
||
6973 | + node_info->is_fab_dev = pdata_node_info->is_fab_dev; |
||
6974 | + node_info->qos_params.mode = pdata_node_info->qos_params.mode; |
||
6975 | + node_info->qos_params.prio1 = pdata_node_info->qos_params.prio1; |
||
6976 | + node_info->qos_params.prio0 = pdata_node_info->qos_params.prio0; |
||
6977 | + node_info->qos_params.prio_lvl = pdata_node_info->qos_params.prio_lvl; |
||
6978 | + node_info->qos_params.prio_rd = pdata_node_info->qos_params.prio_rd; |
||
6979 | + node_info->qos_params.prio_wr = pdata_node_info->qos_params.prio_wr; |
||
6980 | + node_info->qos_params.gp = pdata_node_info->qos_params.gp; |
||
6981 | + node_info->qos_params.thmp = pdata_node_info->qos_params.thmp; |
||
6982 | + node_info->qos_params.ws = pdata_node_info->qos_params.ws; |
||
6983 | + node_info->qos_params.bw_buffer = pdata_node_info->qos_params.bw_buffer; |
||
6984 | + node_info->util_fact = pdata_node_info->util_fact; |
||
6985 | + node_info->vrail_comp = pdata_node_info->vrail_comp; |
||
6986 | + |
||
6987 | + node_info->dev_connections = devm_kzalloc(bus_dev, |
||
6988 | + sizeof(struct device *) * |
||
6989 | + pdata_node_info->num_connections, |
||
6990 | + GFP_KERNEL); |
||
6991 | + if (!node_info->dev_connections) { |
||
6992 | + MSM_BUS_ERR("%s:Bus dev connections alloc failed\n", __func__); |
||
6993 | + ret = -ENOMEM; |
||
6994 | + goto exit_copy_node_info; |
||
6995 | + } |
||
6996 | + |
||
6997 | + node_info->connections = devm_kzalloc(bus_dev, |
||
6998 | + sizeof(int) * pdata_node_info->num_connections, |
||
6999 | + GFP_KERNEL); |
||
7000 | + if (!node_info->connections) { |
||
7001 | + MSM_BUS_ERR("%s:Bus connections alloc failed\n", __func__); |
||
7002 | + devm_kfree(bus_dev, node_info->dev_connections); |
||
7003 | + ret = -ENOMEM; |
||
7004 | + goto exit_copy_node_info; |
||
7005 | + } |
||
7006 | + |
||
7007 | + memcpy(node_info->connections, |
||
7008 | + pdata_node_info->connections, |
||
7009 | + sizeof(int) * pdata_node_info->num_connections); |
||
7010 | + |
||
7011 | + node_info->black_connections = devm_kzalloc(bus_dev, |
||
7012 | + sizeof(struct device *) * |
||
7013 | + pdata_node_info->num_blist, |
||
7014 | + GFP_KERNEL); |
||
7015 | + if (!node_info->black_connections) { |
||
7016 | + MSM_BUS_ERR("%s: Bus black connections alloc failed\n", |
||
7017 | + __func__); |
||
7018 | + devm_kfree(bus_dev, node_info->dev_connections); |
||
7019 | + devm_kfree(bus_dev, node_info->connections); |
||
7020 | + ret = -ENOMEM; |
||
7021 | + goto exit_copy_node_info; |
||
7022 | + } |
||
7023 | + |
||
7024 | + node_info->black_listed_connections = devm_kzalloc(bus_dev, |
||
7025 | + pdata_node_info->num_blist * sizeof(int), |
||
7026 | + GFP_KERNEL); |
||
7027 | + if (!node_info->black_listed_connections) { |
||
7028 | + MSM_BUS_ERR("%s:Bus black list connections alloc failed\n", |
||
7029 | + __func__); |
||
7030 | + devm_kfree(bus_dev, node_info->black_connections); |
||
7031 | + devm_kfree(bus_dev, node_info->dev_connections); |
||
7032 | + devm_kfree(bus_dev, node_info->connections); |
||
7033 | + ret = -ENOMEM; |
||
7034 | + goto exit_copy_node_info; |
||
7035 | + } |
||
7036 | + |
||
7037 | + memcpy(node_info->black_listed_connections, |
||
7038 | + pdata_node_info->black_listed_connections, |
||
7039 | + sizeof(int) * pdata_node_info->num_blist); |
||
7040 | + |
||
7041 | + node_info->qport = devm_kzalloc(bus_dev, |
||
7042 | + sizeof(int) * pdata_node_info->num_qports, |
||
7043 | + GFP_KERNEL); |
||
7044 | + if (!node_info->qport) { |
||
7045 | + MSM_BUS_ERR("%s:Bus qport allocation failed\n", __func__); |
||
7046 | + devm_kfree(bus_dev, node_info->dev_connections); |
||
7047 | + devm_kfree(bus_dev, node_info->connections); |
||
7048 | + devm_kfree(bus_dev, node_info->black_listed_connections); |
||
7049 | + ret = -ENOMEM; |
||
7050 | + goto exit_copy_node_info; |
||
7051 | + } |
||
7052 | + |
||
7053 | + memcpy(node_info->qport, |
||
7054 | + pdata_node_info->qport, |
||
7055 | + sizeof(int) * pdata_node_info->num_qports); |
||
7056 | + |
||
7057 | +exit_copy_node_info: |
||
7058 | + return ret; |
||
7059 | +} |
||
7060 | + |
||
7061 | +static struct device *msm_bus_device_init( |
||
7062 | + struct msm_bus_node_device_type *pdata) |
||
7063 | +{ |
||
7064 | + struct device *bus_dev = NULL; |
||
7065 | + struct msm_bus_node_device_type *bus_node = NULL; |
||
7066 | + struct msm_bus_node_info_type *node_info = NULL; |
||
7067 | + int ret = 0; |
||
7068 | + |
||
7069 | + bus_dev = kzalloc(sizeof(struct device), GFP_KERNEL); |
||
7070 | + if (!bus_dev) { |
||
7071 | + MSM_BUS_ERR("%s:Device alloc failed\n", __func__); |
||
7072 | + bus_dev = NULL; |
||
7073 | + goto exit_device_init; |
||
7074 | + } |
||
7075 | + /** |
||
7076 | + * Init here so we can use devm calls |
||
7077 | + */ |
||
7078 | + device_initialize(bus_dev); |
||
7079 | + |
||
7080 | + bus_node = devm_kzalloc(bus_dev, |
||
7081 | + sizeof(struct msm_bus_node_device_type), GFP_KERNEL); |
||
7082 | + if (!bus_node) { |
||
7083 | + MSM_BUS_ERR("%s:Bus node alloc failed\n", __func__); |
||
7084 | + kfree(bus_dev); |
||
7085 | + bus_dev = NULL; |
||
7086 | + goto exit_device_init; |
||
7087 | + } |
||
7088 | + |
||
7089 | + node_info = devm_kzalloc(bus_dev, |
||
7090 | + sizeof(struct msm_bus_node_info_type), GFP_KERNEL); |
||
7091 | + if (!node_info) { |
||
7092 | + MSM_BUS_ERR("%s:Bus node info alloc failed\n", __func__); |
||
7093 | + devm_kfree(bus_dev, bus_node); |
||
7094 | + kfree(bus_dev); |
||
7095 | + bus_dev = NULL; |
||
7096 | + goto exit_device_init; |
||
7097 | + } |
||
7098 | + |
||
7099 | + bus_node->node_info = node_info; |
||
7100 | + bus_node->ap_owned = pdata->ap_owned; |
||
7101 | + bus_dev->platform_data = bus_node; |
||
7102 | + |
||
7103 | + if (msm_bus_copy_node_info(pdata, bus_dev) < 0) { |
||
7104 | + devm_kfree(bus_dev, bus_node); |
||
7105 | + devm_kfree(bus_dev, node_info); |
||
7106 | + kfree(bus_dev); |
||
7107 | + bus_dev = NULL; |
||
7108 | + goto exit_device_init; |
||
7109 | + } |
||
7110 | + |
||
7111 | + bus_dev->bus = &msm_bus_type; |
||
7112 | + dev_set_name(bus_dev, bus_node->node_info->name); |
||
7113 | + |
||
7114 | + ret = device_add(bus_dev); |
||
7115 | + if (ret < 0) { |
||
7116 | + MSM_BUS_ERR("%s: Error registering device %d", |
||
7117 | + __func__, pdata->node_info->id); |
||
7118 | + devm_kfree(bus_dev, bus_node); |
||
7119 | + devm_kfree(bus_dev, node_info->dev_connections); |
||
7120 | + devm_kfree(bus_dev, node_info->connections); |
||
7121 | + devm_kfree(bus_dev, node_info->black_connections); |
||
7122 | + devm_kfree(bus_dev, node_info->black_listed_connections); |
||
7123 | + devm_kfree(bus_dev, node_info); |
||
7124 | + kfree(bus_dev); |
||
7125 | + bus_dev = NULL; |
||
7126 | + goto exit_device_init; |
||
7127 | + } |
||
7128 | + device_create_file(bus_dev, &dev_attr_vrail); |
||
7129 | + |
||
7130 | +exit_device_init: |
||
7131 | + return bus_dev; |
||
7132 | +} |
||
7133 | + |
||
7134 | +static int msm_bus_setup_dev_conn(struct device *bus_dev, void *data) |
||
7135 | +{ |
||
7136 | + struct msm_bus_node_device_type *bus_node = NULL; |
||
7137 | + int ret = 0; |
||
7138 | + int j; |
||
7139 | + |
||
7140 | + bus_node = bus_dev->platform_data; |
||
7141 | + if (!bus_node) { |
||
7142 | + MSM_BUS_ERR("%s: Can't get device info", __func__); |
||
7143 | + ret = -ENODEV; |
||
7144 | + goto exit_setup_dev_conn; |
||
7145 | + } |
||
7146 | + |
||
7147 | + /* Setup parent bus device for this node */ |
||
7148 | + if (!bus_node->node_info->is_fab_dev) { |
||
7149 | + struct device *bus_parent_device = |
||
7150 | + bus_find_device(&msm_bus_type, NULL, |
||
7151 | + (void *)&bus_node->node_info->bus_device_id, |
||
7152 | + msm_bus_device_match_adhoc); |
||
7153 | + |
||
7154 | + if (!bus_parent_device) { |
||
7155 | + MSM_BUS_ERR("%s: Error finding parentdev %d parent %d", |
||
7156 | + __func__, |
||
7157 | + bus_node->node_info->id, |
||
7158 | + bus_node->node_info->bus_device_id); |
||
7159 | + ret = -ENXIO; |
||
7160 | + goto exit_setup_dev_conn; |
||
7161 | + } |
||
7162 | + bus_node->node_info->bus_device = bus_parent_device; |
||
7163 | + } |
||
7164 | + |
||
7165 | + bus_node->node_info->is_traversed = false; |
||
7166 | + |
||
7167 | + for (j = 0; j < bus_node->node_info->num_connections; j++) { |
||
7168 | + bus_node->node_info->dev_connections[j] = |
||
7169 | + bus_find_device(&msm_bus_type, NULL, |
||
7170 | + (void *)&bus_node->node_info->connections[j], |
||
7171 | + msm_bus_device_match_adhoc); |
||
7172 | + |
||
7173 | + if (!bus_node->node_info->dev_connections[j]) { |
||
7174 | + MSM_BUS_ERR("%s: Error finding conn %d for device %d", |
||
7175 | + __func__, bus_node->node_info->connections[j], |
||
7176 | + bus_node->node_info->id); |
||
7177 | + ret = -ENODEV; |
||
7178 | + goto exit_setup_dev_conn; |
||
7179 | + } |
||
7180 | + } |
||
7181 | + |
||
7182 | + for (j = 0; j < bus_node->node_info->num_blist; j++) { |
||
7183 | + bus_node->node_info->black_connections[j] = |
||
7184 | + bus_find_device(&msm_bus_type, NULL, |
||
7185 | + (void *)&bus_node->node_info-> |
||
7186 | + black_listed_connections[j], |
||
7187 | + msm_bus_device_match_adhoc); |
||
7188 | + |
||
7189 | + if (!bus_node->node_info->black_connections[j]) { |
||
7190 | + MSM_BUS_ERR("%s: Error finding conn %d for device %d\n", |
||
7191 | + __func__, bus_node->node_info-> |
||
7192 | + black_listed_connections[j], |
||
7193 | + bus_node->node_info->id); |
||
7194 | + ret = -ENODEV; |
||
7195 | + goto exit_setup_dev_conn; |
||
7196 | + } |
||
7197 | + } |
||
7198 | + |
||
7199 | +exit_setup_dev_conn: |
||
7200 | + return ret; |
||
7201 | +} |
||
7202 | + |
||
7203 | +static int msm_bus_node_debug(struct device *bus_dev, void *data) |
||
7204 | +{ |
||
7205 | + int j; |
||
7206 | + int ret = 0; |
||
7207 | + struct msm_bus_node_device_type *bus_node = NULL; |
||
7208 | + |
||
7209 | + bus_node = bus_dev->platform_data; |
||
7210 | + if (!bus_node) { |
||
7211 | + MSM_BUS_ERR("%s: Can't get device info", __func__); |
||
7212 | + ret = -ENODEV; |
||
7213 | + goto exit_node_debug; |
||
7214 | + } |
||
7215 | + |
||
7216 | + MSM_BUS_DBG("Device = %d buswidth %u", bus_node->node_info->id, |
||
7217 | + bus_node->node_info->buswidth); |
||
7218 | + for (j = 0; j < bus_node->node_info->num_connections; j++) { |
||
7219 | + struct msm_bus_node_device_type *bdev = |
||
7220 | + (struct msm_bus_node_device_type *) |
||
7221 | + bus_node->node_info->dev_connections[j]->platform_data; |
||
7222 | + MSM_BUS_DBG("\n\t Connection[%d] %d", j, bdev->node_info->id); |
||
7223 | + } |
||
7224 | + |
||
7225 | +exit_node_debug: |
||
7226 | + return ret; |
||
7227 | +} |
||
7228 | + |
||
7229 | +static int msm_bus_device_probe(struct platform_device *pdev) |
||
7230 | +{ |
||
7231 | + unsigned int i, ret; |
||
7232 | + struct msm_bus_device_node_registration *pdata; |
||
7233 | + |
||
7234 | + /* If possible, get pdata from device-tree */ |
||
7235 | + if (pdev->dev.of_node) |
||
7236 | + pdata = msm_bus_of_to_pdata(pdev); |
||
7237 | + else { |
||
7238 | + pdata = (struct msm_bus_device_node_registration *)pdev-> |
||
7239 | + dev.platform_data; |
||
7240 | + } |
||
7241 | + |
||
7242 | + if (IS_ERR_OR_NULL(pdata)) { |
||
7243 | + MSM_BUS_ERR("No platform data found"); |
||
7244 | + ret = -ENODATA; |
||
7245 | + goto exit_device_probe; |
||
7246 | + } |
||
7247 | + |
||
7248 | + for (i = 0; i < pdata->num_devices; i++) { |
||
7249 | + struct device *node_dev = NULL; |
||
7250 | + |
||
7251 | + node_dev = msm_bus_device_init(&pdata->info[i]); |
||
7252 | + |
||
7253 | + if (!node_dev) { |
||
7254 | + MSM_BUS_ERR("%s: Error during dev init for %d", |
||
7255 | + __func__, pdata->info[i].node_info->id); |
||
7256 | + ret = -ENXIO; |
||
7257 | + goto exit_device_probe; |
||
7258 | + } |
||
7259 | + |
||
7260 | + ret = msm_bus_init_clk(node_dev, &pdata->info[i]); |
||
7261 | + /*Is this a fabric device ?*/ |
||
7262 | + if (pdata->info[i].node_info->is_fab_dev) { |
||
7263 | + MSM_BUS_DBG("%s: %d is a fab", __func__, |
||
7264 | + pdata->info[i].node_info->id); |
||
7265 | + ret = msm_bus_fabric_init(node_dev, &pdata->info[i]); |
||
7266 | + if (ret) { |
||
7267 | + MSM_BUS_ERR("%s: Error intializing fab %d", |
||
7268 | + __func__, pdata->info[i].node_info->id); |
||
7269 | + goto exit_device_probe; |
||
7270 | + } |
||
7271 | + } |
||
7272 | + } |
||
7273 | + |
||
7274 | + ret = bus_for_each_dev(&msm_bus_type, NULL, NULL, |
||
7275 | + msm_bus_setup_dev_conn); |
||
7276 | + if (ret) { |
||
7277 | + MSM_BUS_ERR("%s: Error setting up dev connections", __func__); |
||
7278 | + goto exit_device_probe; |
||
7279 | + } |
||
7280 | + |
||
7281 | + ret = bus_for_each_dev(&msm_bus_type, NULL, NULL, msm_bus_dev_init_qos); |
||
7282 | + if (ret) { |
||
7283 | + MSM_BUS_ERR("%s: Error during qos init", __func__); |
||
7284 | + goto exit_device_probe; |
||
7285 | + } |
||
7286 | + |
||
7287 | + bus_for_each_dev(&msm_bus_type, NULL, NULL, msm_bus_node_debug); |
||
7288 | + |
||
7289 | + /* Register the arb layer ops */ |
||
7290 | + msm_bus_arb_setops_adhoc(&arb_ops); |
||
7291 | + devm_kfree(&pdev->dev, pdata->info); |
||
7292 | + devm_kfree(&pdev->dev, pdata); |
||
7293 | +exit_device_probe: |
||
7294 | + return ret; |
||
7295 | +} |
||
7296 | + |
||
7297 | +static int msm_bus_device_rules_probe(struct platform_device *pdev) |
||
7298 | +{ |
||
7299 | + struct bus_rule_type *rule_data = NULL; |
||
7300 | + int num_rules = 0; |
||
7301 | + |
||
7302 | + num_rules = msm_bus_of_get_static_rules(pdev, &rule_data); |
||
7303 | + |
||
7304 | + if (!rule_data) |
||
7305 | + goto exit_rules_probe; |
||
7306 | + |
||
7307 | + msm_rule_register(num_rules, rule_data, NULL); |
||
7308 | + static_rules.num_rules = num_rules; |
||
7309 | + static_rules.rules = rule_data; |
||
7310 | + pdev->dev.platform_data = &static_rules; |
||
7311 | + |
||
7312 | +exit_rules_probe: |
||
7313 | + return 0; |
||
7314 | +} |
||
7315 | + |
||
7316 | +int msm_bus_device_rules_remove(struct platform_device *pdev) |
||
7317 | +{ |
||
7318 | + struct static_rules_type *static_rules = NULL; |
||
7319 | + |
||
7320 | + static_rules = pdev->dev.platform_data; |
||
7321 | + if (static_rules) |
||
7322 | + msm_rule_unregister(static_rules->num_rules, |
||
7323 | + static_rules->rules, NULL); |
||
7324 | + return 0; |
||
7325 | +} |
||
7326 | + |
||
7327 | +static int msm_bus_free_dev(struct device *dev, void *data) |
||
7328 | +{ |
||
7329 | + struct msm_bus_node_device_type *bus_node = NULL; |
||
7330 | + |
||
7331 | + bus_node = dev->platform_data; |
||
7332 | + |
||
7333 | + if (bus_node) |
||
7334 | + MSM_BUS_ERR("\n%s: Removing device %d", __func__, |
||
7335 | + bus_node->node_info->id); |
||
7336 | + device_unregister(dev); |
||
7337 | + return 0; |
||
7338 | +} |
||
7339 | + |
||
7340 | +int msm_bus_device_remove(struct platform_device *pdev) |
||
7341 | +{ |
||
7342 | + bus_for_each_dev(&msm_bus_type, NULL, NULL, msm_bus_free_dev); |
||
7343 | + return 0; |
||
7344 | +} |
||
7345 | + |
||
7346 | +static struct of_device_id rules_match[] = { |
||
7347 | + {.compatible = "qcom,msm-bus-static-bw-rules"}, |
||
7348 | + {} |
||
7349 | +}; |
||
7350 | + |
||
7351 | +static struct platform_driver msm_bus_rules_driver = { |
||
7352 | + .probe = msm_bus_device_rules_probe, |
||
7353 | + .remove = msm_bus_device_rules_remove, |
||
7354 | + .driver = { |
||
7355 | + .name = "msm_bus_rules_device", |
||
7356 | + .owner = THIS_MODULE, |
||
7357 | + .of_match_table = rules_match, |
||
7358 | + }, |
||
7359 | +}; |
||
7360 | + |
||
7361 | +static struct of_device_id fabric_match[] = { |
||
7362 | + {.compatible = "qcom,msm-bus-device"}, |
||
7363 | + {} |
||
7364 | +}; |
||
7365 | + |
||
7366 | +static struct platform_driver msm_bus_device_driver = { |
||
7367 | + .probe = msm_bus_device_probe, |
||
7368 | + .remove = msm_bus_device_remove, |
||
7369 | + .driver = { |
||
7370 | + .name = "msm_bus_device", |
||
7371 | + .owner = THIS_MODULE, |
||
7372 | + .of_match_table = fabric_match, |
||
7373 | + }, |
||
7374 | +}; |
||
7375 | + |
||
7376 | +int __init msm_bus_device_init_driver(void) |
||
7377 | +{ |
||
7378 | + int rc; |
||
7379 | + |
||
7380 | + MSM_BUS_ERR("msm_bus_fabric_init_driver\n"); |
||
7381 | + rc = platform_driver_register(&msm_bus_device_driver); |
||
7382 | + |
||
7383 | + if (rc) { |
||
7384 | + MSM_BUS_ERR("Failed to register bus device driver"); |
||
7385 | + return rc; |
||
7386 | + } |
||
7387 | + return platform_driver_register(&msm_bus_rules_driver); |
||
7388 | +} |
||
7389 | +subsys_initcall(msm_bus_device_init_driver); |
||
7390 | --- /dev/null |
||
7391 | +++ b/drivers/bus/msm_bus/msm_bus_id.c |
||
7392 | @@ -0,0 +1,94 @@ |
||
7393 | +/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. |
||
7394 | + * |
||
7395 | + * This program is free software; you can redistribute it and/or modify |
||
7396 | + * it under the terms of the GNU General Public License version 2 and |
||
7397 | + * only version 2 as published by the Free Software Foundation. |
||
7398 | + * |
||
7399 | + * This program is distributed in the hope that it will be useful, |
||
7400 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
7401 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
7402 | + * GNU General Public License for more details. |
||
7403 | + * |
||
7404 | + */ |
||
7405 | + |
||
7406 | +#include <linux/kernel.h> |
||
7407 | +#include <linux/init.h> |
||
7408 | +#include <linux/device.h> |
||
7409 | +#include <linux/module.h> |
||
7410 | +#include "msm-bus.h" |
||
7411 | +#include "msm-bus-board.h" |
||
7412 | +#include "msm_bus_core.h" |
||
7413 | +#include "msm_bus_noc.h" |
||
7414 | +#include "msm_bus_bimc.h" |
||
7415 | + |
||
7416 | +static uint32_t master_iids[MSM_BUS_MASTER_LAST]; |
||
7417 | +static uint32_t slave_iids[MSM_BUS_SLAVE_LAST - SLAVE_ID_KEY]; |
||
7418 | + |
||
7419 | +static void msm_bus_assign_iids(struct msm_bus_fabric_registration |
||
7420 | + *fabreg, int fabid) |
||
7421 | +{ |
||
7422 | + int i; |
||
7423 | + for (i = 0; i < fabreg->len; i++) { |
||
7424 | + if (!fabreg->info[i].gateway) { |
||
7425 | + fabreg->info[i].priv_id = fabid + fabreg->info[i].id; |
||
7426 | + if (fabreg->info[i].id < SLAVE_ID_KEY) { |
||
7427 | + if (fabreg->info[i].id >= MSM_BUS_MASTER_LAST) { |
||
7428 | + WARN(1, "id %d exceeds array size!\n", |
||
7429 | + fabreg->info[i].id); |
||
7430 | + continue; |
||
7431 | + } |
||
7432 | + |
||
7433 | + master_iids[fabreg->info[i].id] = |
||
7434 | + fabreg->info[i].priv_id; |
||
7435 | + } else { |
||
7436 | + if ((fabreg->info[i].id - SLAVE_ID_KEY) >= |
||
7437 | + (MSM_BUS_SLAVE_LAST - SLAVE_ID_KEY)) { |
||
7438 | + WARN(1, "id %d exceeds array size!\n", |
||
7439 | + fabreg->info[i].id); |
||
7440 | + continue; |
||
7441 | + } |
||
7442 | + |
||
7443 | + slave_iids[fabreg->info[i].id - (SLAVE_ID_KEY)] |
||
7444 | + = fabreg->info[i].priv_id; |
||
7445 | + } |
||
7446 | + } else { |
||
7447 | + fabreg->info[i].priv_id = fabreg->info[i].id; |
||
7448 | + } |
||
7449 | + } |
||
7450 | +} |
||
7451 | + |
||
7452 | +static int msm_bus_get_iid(int id) |
||
7453 | +{ |
||
7454 | + if ((id < SLAVE_ID_KEY && id >= MSM_BUS_MASTER_LAST) || |
||
7455 | + id >= MSM_BUS_SLAVE_LAST) { |
||
7456 | + MSM_BUS_ERR("Cannot get iid. Invalid id %d passed\n", id); |
||
7457 | + return -EINVAL; |
||
7458 | + } |
||
7459 | + |
||
7460 | + return CHECK_ID(((id < SLAVE_ID_KEY) ? master_iids[id] : |
||
7461 | + slave_iids[id - SLAVE_ID_KEY]), id); |
||
7462 | +} |
||
7463 | + |
||
7464 | +static struct msm_bus_board_algorithm msm_bus_id_algo = { |
||
7465 | + .get_iid = msm_bus_get_iid, |
||
7466 | + .assign_iids = msm_bus_assign_iids, |
||
7467 | +}; |
||
7468 | + |
||
7469 | +int msm_bus_board_rpm_get_il_ids(uint16_t *id) |
||
7470 | +{ |
||
7471 | + return -ENXIO; |
||
7472 | +} |
||
7473 | + |
||
7474 | +void msm_bus_board_init(struct msm_bus_fabric_registration *pdata) |
||
7475 | +{ |
||
7476 | + pdata->board_algo = &msm_bus_id_algo; |
||
7477 | +} |
||
7478 | + |
||
7479 | +void msm_bus_board_set_nfab(struct msm_bus_fabric_registration *pdata, |
||
7480 | + int nfab) |
||
7481 | +{ |
||
7482 | + if (nfab <= 0) |
||
7483 | + return; |
||
7484 | + |
||
7485 | + msm_bus_id_algo.board_nfab = nfab; |
||
7486 | +} |
||
7487 | --- /dev/null |
||
7488 | +++ b/drivers/bus/msm_bus/msm_bus_noc.c |
||
7489 | @@ -0,0 +1,770 @@ |
||
7490 | +/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. |
||
7491 | + * |
||
7492 | + * This program is free software; you can redistribute it and/or modify |
||
7493 | + * it under the terms of the GNU General Public License version 2 and |
||
7494 | + * only version 2 as published by the Free Software Foundation. |
||
7495 | + * |
||
7496 | + * This program is distributed in the hope that it will be useful, |
||
7497 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
7498 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
7499 | + * GNU General Public License for more details. |
||
7500 | + */ |
||
7501 | + |
||
7502 | +#define pr_fmt(fmt) "AXI: NOC: %s(): " fmt, __func__ |
||
7503 | + |
||
7504 | +#include <linux/slab.h> |
||
7505 | +#include <linux/io.h> |
||
7506 | +#include "msm-bus-board.h" |
||
7507 | +#include "msm_bus_core.h" |
||
7508 | +#include "msm_bus_noc.h" |
||
7509 | +#include "msm_bus_adhoc.h" |
||
7510 | + |
||
7511 | +/* NOC_QOS generic */ |
||
7512 | +#define __CLZ(x) ((8 * sizeof(uint32_t)) - 1 - __fls(x)) |
||
7513 | +#define SAT_SCALE 16 /* 16 bytes minimum for saturation */ |
||
7514 | +#define BW_SCALE 256 /* 1/256 byte per cycle unit */ |
||
7515 | +#define QOS_DEFAULT_BASEOFFSET 0x00003000 |
||
7516 | +#define QOS_DEFAULT_DELTA 0x80 |
||
7517 | +#define MAX_BW_FIELD (NOC_QOS_BWn_BW_BMSK >> NOC_QOS_BWn_BW_SHFT) |
||
7518 | +#define MAX_SAT_FIELD (NOC_QOS_SATn_SAT_BMSK >> NOC_QOS_SATn_SAT_SHFT) |
||
7519 | + |
||
7520 | +#define NOC_QOS_REG_BASE(b, o) ((b) + (o)) |
||
7521 | + |
||
7522 | +#define NOC_QOS_ID_COREIDn_ADDR(b, o, n, d) \ |
||
7523 | + (NOC_QOS_REG_BASE(b, o) + (d) * (n)) |
||
7524 | +enum noc_qos_id_coreidn { |
||
7525 | + NOC_QOS_ID_COREIDn_RMSK = 0xffffffff, |
||
7526 | + NOC_QOS_ID_COREIDn_MAXn = 32, |
||
7527 | + NOC_QOS_ID_COREIDn_CORECHSUM_BMSK = 0xffffff00, |
||
7528 | + NOC_QOS_ID_COREIDn_CORECHSUM_SHFT = 0x8, |
||
7529 | + NOC_QOS_ID_COREIDn_CORETYPEID_BMSK = 0xff, |
||
7530 | + NOC_QOS_ID_COREIDn_CORETYPEID_SHFT = 0x0, |
||
7531 | +}; |
||
7532 | + |
||
7533 | +#define NOC_QOS_ID_REVISIONIDn_ADDR(b, o, n, d) \ |
||
7534 | + (NOC_QOS_REG_BASE(b, o) + 0x4 + (d) * (n)) |
||
7535 | +enum noc_qos_id_revisionidn { |
||
7536 | + NOC_QOS_ID_REVISIONIDn_RMSK = 0xffffffff, |
||
7537 | + NOC_QOS_ID_REVISIONIDn_MAXn = 32, |
||
7538 | + NOC_QOS_ID_REVISIONIDn_FLEXNOCID_BMSK = 0xffffff00, |
||
7539 | + NOC_QOS_ID_REVISIONIDn_FLEXNOCID_SHFT = 0x8, |
||
7540 | + NOC_QOS_ID_REVISIONIDn_USERID_BMSK = 0xff, |
||
7541 | + NOC_QOS_ID_REVISIONIDn_USERID_SHFT = 0x0, |
||
7542 | +}; |
||
7543 | + |
||
7544 | +#define NOC_QOS_PRIORITYn_ADDR(b, o, n, d) \ |
||
7545 | + (NOC_QOS_REG_BASE(b, o) + 0x8 + (d) * (n)) |
||
7546 | +enum noc_qos_id_priorityn { |
||
7547 | + NOC_QOS_PRIORITYn_RMSK = 0x0000000f, |
||
7548 | + NOC_QOS_PRIORITYn_MAXn = 32, |
||
7549 | + NOC_QOS_PRIORITYn_P1_BMSK = 0xc, |
||
7550 | + NOC_QOS_PRIORITYn_P1_SHFT = 0x2, |
||
7551 | + NOC_QOS_PRIORITYn_P0_BMSK = 0x3, |
||
7552 | + NOC_QOS_PRIORITYn_P0_SHFT = 0x0, |
||
7553 | +}; |
||
7554 | + |
||
7555 | +#define NOC_QOS_MODEn_ADDR(b, o, n, d) \ |
||
7556 | + (NOC_QOS_REG_BASE(b, o) + 0xC + (d) * (n)) |
||
7557 | +enum noc_qos_id_moden_rmsk { |
||
7558 | + NOC_QOS_MODEn_RMSK = 0x00000003, |
||
7559 | + NOC_QOS_MODEn_MAXn = 32, |
||
7560 | + NOC_QOS_MODEn_MODE_BMSK = 0x3, |
||
7561 | + NOC_QOS_MODEn_MODE_SHFT = 0x0, |
||
7562 | +}; |
||
7563 | + |
||
7564 | +#define NOC_QOS_BWn_ADDR(b, o, n, d) \ |
||
7565 | + (NOC_QOS_REG_BASE(b, o) + 0x10 + (d) * (n)) |
||
7566 | +enum noc_qos_id_bwn { |
||
7567 | + NOC_QOS_BWn_RMSK = 0x0000ffff, |
||
7568 | + NOC_QOS_BWn_MAXn = 32, |
||
7569 | + NOC_QOS_BWn_BW_BMSK = 0xffff, |
||
7570 | + NOC_QOS_BWn_BW_SHFT = 0x0, |
||
7571 | +}; |
||
7572 | + |
||
7573 | +/* QOS Saturation registers */ |
||
7574 | +#define NOC_QOS_SATn_ADDR(b, o, n, d) \ |
||
7575 | + (NOC_QOS_REG_BASE(b, o) + 0x14 + (d) * (n)) |
||
7576 | +enum noc_qos_id_saturationn { |
||
7577 | + NOC_QOS_SATn_RMSK = 0x000003ff, |
||
7578 | + NOC_QOS_SATn_MAXn = 32, |
||
7579 | + NOC_QOS_SATn_SAT_BMSK = 0x3ff, |
||
7580 | + NOC_QOS_SATn_SAT_SHFT = 0x0, |
||
7581 | +}; |
||
7582 | + |
||
7583 | +static int noc_div(uint64_t *a, uint32_t b) |
||
7584 | +{ |
||
7585 | + if ((*a > 0) && (*a < b)) |
||
7586 | + return 1; |
||
7587 | + else |
||
7588 | + return do_div(*a, b); |
||
7589 | +} |
||
7590 | + |
||
7591 | +/** |
||
7592 | + * Calculates bw hardware is using from register values |
||
7593 | + * bw returned is in bytes/sec |
||
7594 | + */ |
||
7595 | +static uint64_t noc_bw(uint32_t bw_field, uint32_t qos_freq) |
||
7596 | +{ |
||
7597 | + uint64_t res; |
||
7598 | + uint32_t rem, scale; |
||
7599 | + |
||
7600 | + res = 2 * qos_freq * bw_field; |
||
7601 | + scale = BW_SCALE * 1000; |
||
7602 | + rem = noc_div(&res, scale); |
||
7603 | + MSM_BUS_DBG("NOC: Calculated bw: %llu\n", res * 1000000ULL); |
||
7604 | + return res * 1000000ULL; |
||
7605 | +} |
||
7606 | + |
||
7607 | +static uint32_t noc_bw_ceil(long int bw_field, uint32_t qos_freq) |
||
7608 | +{ |
||
7609 | + uint64_t bw_temp = 2 * qos_freq * bw_field; |
||
7610 | + uint32_t scale = 1000 * BW_SCALE; |
||
7611 | + noc_div(&bw_temp, scale); |
||
7612 | + return bw_temp * 1000000; |
||
7613 | +} |
||
7614 | +#define MAX_BW(timebase) noc_bw_ceil(MAX_BW_FIELD, (timebase)) |
||
7615 | + |
||
7616 | +/** |
||
7617 | + * Calculates ws hardware is using from register values |
||
7618 | + * ws returned is in nanoseconds |
||
7619 | + */ |
||
7620 | +static uint32_t noc_ws(uint64_t bw, uint32_t sat, uint32_t qos_freq) |
||
7621 | +{ |
||
7622 | + if (bw && qos_freq) { |
||
7623 | + uint32_t bwf = bw * qos_freq; |
||
7624 | + uint64_t scale = 1000000000000LL * BW_SCALE * |
||
7625 | + SAT_SCALE * sat; |
||
7626 | + noc_div(&scale, bwf); |
||
7627 | + MSM_BUS_DBG("NOC: Calculated ws: %llu\n", scale); |
||
7628 | + return scale; |
||
7629 | + } |
||
7630 | + |
||
7631 | + return 0; |
||
7632 | +} |
||
7633 | +#define MAX_WS(bw, timebase) noc_ws((bw), MAX_SAT_FIELD, (timebase)) |
||
7634 | + |
||
7635 | +/* Calculate bandwidth field value for requested bandwidth */ |
||
7636 | +static uint32_t noc_bw_field(uint64_t bw, uint32_t qos_freq) |
||
7637 | +{ |
||
7638 | + uint32_t bw_field = 0; |
||
7639 | + |
||
7640 | + if (bw) { |
||
7641 | + uint32_t rem; |
||
7642 | + uint64_t bw_capped = min_t(uint64_t, bw, MAX_BW(qos_freq)); |
||
7643 | + uint64_t bwc = bw_capped * BW_SCALE; |
||
7644 | + uint64_t qf = 2 * qos_freq * 1000; |
||
7645 | + |
||
7646 | + rem = noc_div(&bwc, qf); |
||
7647 | + bw_field = (uint32_t)min_t(uint64_t, bwc, MAX_BW_FIELD); |
||
7648 | + } |
||
7649 | + |
||
7650 | + MSM_BUS_DBG("NOC: bw_field: %u\n", bw_field); |
||
7651 | + return bw_field; |
||
7652 | +} |
||
7653 | + |
||
7654 | +static uint32_t noc_sat_field(uint64_t bw, uint32_t ws, uint32_t qos_freq) |
||
7655 | +{ |
||
7656 | + uint32_t sat_field = 0, win; |
||
7657 | + |
||
7658 | + if (bw) { |
||
7659 | + /* Limit to max bw and scale bw to 100 KB increments */ |
||
7660 | + uint64_t tbw, tscale; |
||
7661 | + uint64_t bw_scaled = min_t(uint64_t, bw, MAX_BW(qos_freq)); |
||
7662 | + uint32_t rem = noc_div(&bw_scaled, 100000); |
||
7663 | + |
||
7664 | + /** |
||
7665 | + * Calculate saturation from windows size. |
||
7666 | + * WS must be at least one arb period. |
||
7667 | + * Saturation must not exceed max field size |
||
7668 | + * |
||
7669 | + * Bandwidth is in 100KB increments |
||
7670 | + * Window size is in ns |
||
7671 | + * qos_freq is in KHz |
||
7672 | + */ |
||
7673 | + win = max(ws, 1000000 / qos_freq); |
||
7674 | + tbw = bw_scaled * win * qos_freq; |
||
7675 | + tscale = 10000000ULL * BW_SCALE * SAT_SCALE; |
||
7676 | + rem = noc_div(&tbw, tscale); |
||
7677 | + sat_field = (uint32_t)min_t(uint64_t, tbw, MAX_SAT_FIELD); |
||
7678 | + } |
||
7679 | + |
||
7680 | + MSM_BUS_DBG("NOC: sat_field: %d\n", sat_field); |
||
7681 | + return sat_field; |
||
7682 | +} |
||
7683 | + |
||
7684 | +static void noc_set_qos_mode(void __iomem *base, uint32_t qos_off, |
||
7685 | + uint32_t mport, uint32_t qos_delta, uint8_t mode, |
||
7686 | + uint8_t perm_mode) |
||
7687 | +{ |
||
7688 | + if (mode < NOC_QOS_MODE_MAX && |
||
7689 | + ((1 << mode) & perm_mode)) { |
||
7690 | + uint32_t reg_val; |
||
7691 | + |
||
7692 | + reg_val = readl_relaxed(NOC_QOS_MODEn_ADDR(base, qos_off, |
||
7693 | + mport, qos_delta)) & NOC_QOS_MODEn_RMSK; |
||
7694 | + writel_relaxed(((reg_val & (~(NOC_QOS_MODEn_MODE_BMSK))) | |
||
7695 | + (mode & NOC_QOS_MODEn_MODE_BMSK)), |
||
7696 | + NOC_QOS_MODEn_ADDR(base, qos_off, mport, qos_delta)); |
||
7697 | + } |
||
7698 | + /* Ensure qos mode is set before exiting */ |
||
7699 | + wmb(); |
||
7700 | +} |
||
7701 | + |
||
7702 | +static void noc_set_qos_priority(void __iomem *base, uint32_t qos_off, |
||
7703 | + uint32_t mport, uint32_t qos_delta, |
||
7704 | + struct msm_bus_noc_qos_priority *priority) |
||
7705 | +{ |
||
7706 | + uint32_t reg_val, val; |
||
7707 | + |
||
7708 | + reg_val = readl_relaxed(NOC_QOS_PRIORITYn_ADDR(base, qos_off, mport, |
||
7709 | + qos_delta)) & NOC_QOS_PRIORITYn_RMSK; |
||
7710 | + val = priority->p1 << NOC_QOS_PRIORITYn_P1_SHFT; |
||
7711 | + writel_relaxed(((reg_val & (~(NOC_QOS_PRIORITYn_P1_BMSK))) | |
||
7712 | + (val & NOC_QOS_PRIORITYn_P1_BMSK)), |
||
7713 | + NOC_QOS_PRIORITYn_ADDR(base, qos_off, mport, qos_delta)); |
||
7714 | + |
||
7715 | + reg_val = readl_relaxed(NOC_QOS_PRIORITYn_ADDR(base, qos_off, mport, |
||
7716 | + qos_delta)) |
||
7717 | + & NOC_QOS_PRIORITYn_RMSK; |
||
7718 | + writel_relaxed(((reg_val & (~(NOC_QOS_PRIORITYn_P0_BMSK))) | |
||
7719 | + (priority->p0 & NOC_QOS_PRIORITYn_P0_BMSK)), |
||
7720 | + NOC_QOS_PRIORITYn_ADDR(base, qos_off, mport, qos_delta)); |
||
7721 | + /* Ensure qos priority is set before exiting */ |
||
7722 | + wmb(); |
||
7723 | +} |
||
7724 | + |
||
7725 | +static void msm_bus_noc_set_qos_bw(void __iomem *base, uint32_t qos_off, |
||
7726 | + uint32_t qos_freq, uint32_t mport, uint32_t qos_delta, |
||
7727 | + uint8_t perm_mode, struct msm_bus_noc_qos_bw *qbw) |
||
7728 | +{ |
||
7729 | + uint32_t reg_val, val, mode; |
||
7730 | + |
||
7731 | + if (!qos_freq) { |
||
7732 | + MSM_BUS_DBG("Zero QoS Freq\n"); |
||
7733 | + return; |
||
7734 | + } |
||
7735 | + |
||
7736 | + |
||
7737 | + /* If Limiter or Regulator modes are not supported, bw not available*/ |
||
7738 | + if (perm_mode & (NOC_QOS_PERM_MODE_LIMITER | |
||
7739 | + NOC_QOS_PERM_MODE_REGULATOR)) { |
||
7740 | + uint32_t bw_val = noc_bw_field(qbw->bw, qos_freq); |
||
7741 | + uint32_t sat_val = noc_sat_field(qbw->bw, qbw->ws, |
||
7742 | + qos_freq); |
||
7743 | + |
||
7744 | + MSM_BUS_DBG("NOC: BW: perm_mode: %d bw_val: %d, sat_val: %d\n", |
||
7745 | + perm_mode, bw_val, sat_val); |
||
7746 | + /* |
||
7747 | + * If in Limiter/Regulator mode, first go to fixed mode. |
||
7748 | + * Clear QoS accumulator |
||
7749 | + **/ |
||
7750 | + mode = readl_relaxed(NOC_QOS_MODEn_ADDR(base, qos_off, |
||
7751 | + mport, qos_delta)) & NOC_QOS_MODEn_MODE_BMSK; |
||
7752 | + if (mode == NOC_QOS_MODE_REGULATOR || mode == |
||
7753 | + NOC_QOS_MODE_LIMITER) { |
||
7754 | + reg_val = readl_relaxed(NOC_QOS_MODEn_ADDR( |
||
7755 | + base, qos_off, mport, qos_delta)); |
||
7756 | + val = NOC_QOS_MODE_FIXED; |
||
7757 | + writel_relaxed((reg_val & (~(NOC_QOS_MODEn_MODE_BMSK))) |
||
7758 | + | (val & NOC_QOS_MODEn_MODE_BMSK), |
||
7759 | + NOC_QOS_MODEn_ADDR(base, qos_off, mport, |
||
7760 | + qos_delta)); |
||
7761 | + } |
||
7762 | + |
||
7763 | + reg_val = readl_relaxed(NOC_QOS_BWn_ADDR(base, qos_off, mport, |
||
7764 | + qos_delta)); |
||
7765 | + val = bw_val << NOC_QOS_BWn_BW_SHFT; |
||
7766 | + writel_relaxed(((reg_val & (~(NOC_QOS_BWn_BW_BMSK))) | |
||
7767 | + (val & NOC_QOS_BWn_BW_BMSK)), |
||
7768 | + NOC_QOS_BWn_ADDR(base, qos_off, mport, qos_delta)); |
||
7769 | + |
||
7770 | + MSM_BUS_DBG("NOC: BW: Wrote value: 0x%x\n", ((reg_val & |
||
7771 | + (~NOC_QOS_BWn_BW_BMSK)) | (val & |
||
7772 | + NOC_QOS_BWn_BW_BMSK))); |
||
7773 | + |
||
7774 | + reg_val = readl_relaxed(NOC_QOS_SATn_ADDR(base, qos_off, |
||
7775 | + mport, qos_delta)); |
||
7776 | + val = sat_val << NOC_QOS_SATn_SAT_SHFT; |
||
7777 | + writel_relaxed(((reg_val & (~(NOC_QOS_SATn_SAT_BMSK))) | |
||
7778 | + (val & NOC_QOS_SATn_SAT_BMSK)), |
||
7779 | + NOC_QOS_SATn_ADDR(base, qos_off, mport, qos_delta)); |
||
7780 | + |
||
7781 | + MSM_BUS_DBG("NOC: SAT: Wrote value: 0x%x\n", ((reg_val & |
||
7782 | + (~NOC_QOS_SATn_SAT_BMSK)) | (val & |
||
7783 | + NOC_QOS_SATn_SAT_BMSK))); |
||
7784 | + |
||
7785 | + /* Set mode back to what it was initially */ |
||
7786 | + reg_val = readl_relaxed(NOC_QOS_MODEn_ADDR(base, qos_off, |
||
7787 | + mport, qos_delta)); |
||
7788 | + writel_relaxed((reg_val & (~(NOC_QOS_MODEn_MODE_BMSK))) |
||
7789 | + | (mode & NOC_QOS_MODEn_MODE_BMSK), |
||
7790 | + NOC_QOS_MODEn_ADDR(base, qos_off, mport, qos_delta)); |
||
7791 | + /* Ensure that all writes for bandwidth registers have |
||
7792 | + * completed before returning |
||
7793 | + */ |
||
7794 | + wmb(); |
||
7795 | + } |
||
7796 | +} |
||
7797 | + |
||
7798 | +uint8_t msm_bus_noc_get_qos_mode(void __iomem *base, uint32_t qos_off, |
||
7799 | + uint32_t mport, uint32_t qos_delta, uint32_t mode, uint32_t perm_mode) |
||
7800 | +{ |
||
7801 | + if (NOC_QOS_MODES_ALL_PERM == perm_mode) |
||
7802 | + return readl_relaxed(NOC_QOS_MODEn_ADDR(base, qos_off, |
||
7803 | + mport, qos_delta)) & NOC_QOS_MODEn_MODE_BMSK; |
||
7804 | + else |
||
7805 | + return 31 - __CLZ(mode & |
||
7806 | + NOC_QOS_MODES_ALL_PERM); |
||
7807 | +} |
||
7808 | + |
||
7809 | +void msm_bus_noc_get_qos_priority(void __iomem *base, uint32_t qos_off, |
||
7810 | + uint32_t mport, uint32_t qos_delta, |
||
7811 | + struct msm_bus_noc_qos_priority *priority) |
||
7812 | +{ |
||
7813 | + priority->p1 = (readl_relaxed(NOC_QOS_PRIORITYn_ADDR(base, qos_off, |
||
7814 | + mport, qos_delta)) & NOC_QOS_PRIORITYn_P1_BMSK) >> |
||
7815 | + NOC_QOS_PRIORITYn_P1_SHFT; |
||
7816 | + |
||
7817 | + priority->p0 = (readl_relaxed(NOC_QOS_PRIORITYn_ADDR(base, qos_off, |
||
7818 | + mport, qos_delta)) & NOC_QOS_PRIORITYn_P0_BMSK) >> |
||
7819 | + NOC_QOS_PRIORITYn_P0_SHFT; |
||
7820 | +} |
||
7821 | + |
||
7822 | +void msm_bus_noc_get_qos_bw(void __iomem *base, uint32_t qos_off, |
||
7823 | + uint32_t qos_freq, |
||
7824 | + uint32_t mport, uint32_t qos_delta, uint8_t perm_mode, |
||
7825 | + struct msm_bus_noc_qos_bw *qbw) |
||
7826 | +{ |
||
7827 | + if (perm_mode & (NOC_QOS_PERM_MODE_LIMITER | |
||
7828 | + NOC_QOS_PERM_MODE_REGULATOR)) { |
||
7829 | + uint32_t bw_val = readl_relaxed(NOC_QOS_BWn_ADDR( |
||
7830 | + base, qos_off, mport, qos_delta)) & NOC_QOS_BWn_BW_BMSK; |
||
7831 | + uint32_t sat = readl_relaxed(NOC_QOS_SATn_ADDR( |
||
7832 | + base, qos_off, mport, qos_delta)) |
||
7833 | + & NOC_QOS_SATn_SAT_BMSK; |
||
7834 | + |
||
7835 | + qbw->bw = noc_bw(bw_val, qos_freq); |
||
7836 | + qbw->ws = noc_ws(qbw->bw, sat, qos_freq); |
||
7837 | + } else { |
||
7838 | + qbw->bw = 0; |
||
7839 | + qbw->ws = 0; |
||
7840 | + } |
||
7841 | +} |
||
7842 | + |
||
7843 | +static int msm_bus_noc_mas_init(struct msm_bus_noc_info *ninfo, |
||
7844 | + struct msm_bus_inode_info *info) |
||
7845 | +{ |
||
7846 | + int i; |
||
7847 | + struct msm_bus_noc_qos_priority *prio; |
||
7848 | + prio = kzalloc(sizeof(struct msm_bus_noc_qos_priority), |
||
7849 | + GFP_KERNEL); |
||
7850 | + if (!prio) { |
||
7851 | + MSM_BUS_WARN("Couldn't alloc prio data for node: %d\n", |
||
7852 | + info->node_info->id); |
||
7853 | + return -ENOMEM; |
||
7854 | + } |
||
7855 | + |
||
7856 | + prio->read_prio = info->node_info->prio_rd; |
||
7857 | + prio->write_prio = info->node_info->prio_wr; |
||
7858 | + prio->p1 = info->node_info->prio1; |
||
7859 | + prio->p0 = info->node_info->prio0; |
||
7860 | + info->hw_data = (void *)prio; |
||
7861 | + |
||
7862 | + if (!info->node_info->qport) { |
||
7863 | + MSM_BUS_DBG("No QoS Ports to init\n"); |
||
7864 | + return 0; |
||
7865 | + } |
||
7866 | + |
||
7867 | + for (i = 0; i < info->node_info->num_mports; i++) { |
||
7868 | + if (info->node_info->mode != NOC_QOS_MODE_BYPASS) { |
||
7869 | + noc_set_qos_priority(ninfo->base, ninfo->qos_baseoffset, |
||
7870 | + info->node_info->qport[i], ninfo->qos_delta, |
||
7871 | + prio); |
||
7872 | + |
||
7873 | + if (info->node_info->mode != NOC_QOS_MODE_FIXED) { |
||
7874 | + struct msm_bus_noc_qos_bw qbw; |
||
7875 | + qbw.ws = info->node_info->ws; |
||
7876 | + qbw.bw = 0; |
||
7877 | + msm_bus_noc_set_qos_bw(ninfo->base, |
||
7878 | + ninfo->qos_baseoffset, |
||
7879 | + ninfo->qos_freq, info->node_info-> |
||
7880 | + qport[i], ninfo->qos_delta, |
||
7881 | + info->node_info->perm_mode, |
||
7882 | + &qbw); |
||
7883 | + } |
||
7884 | + } |
||
7885 | + |
||
7886 | + noc_set_qos_mode(ninfo->base, ninfo->qos_baseoffset, |
||
7887 | + info->node_info->qport[i], ninfo->qos_delta, |
||
7888 | + info->node_info->mode, |
||
7889 | + info->node_info->perm_mode); |
||
7890 | + } |
||
7891 | + |
||
7892 | + return 0; |
||
7893 | +} |
||
7894 | + |
||
7895 | +static void msm_bus_noc_node_init(void *hw_data, |
||
7896 | + struct msm_bus_inode_info *info) |
||
7897 | +{ |
||
7898 | + struct msm_bus_noc_info *ninfo = |
||
7899 | + (struct msm_bus_noc_info *)hw_data; |
||
7900 | + |
||
7901 | + if (!IS_SLAVE(info->node_info->priv_id)) |
||
7902 | + if (info->node_info->hw_sel != MSM_BUS_RPM) |
||
7903 | + msm_bus_noc_mas_init(ninfo, info); |
||
7904 | +} |
||
7905 | + |
||
7906 | +static int msm_bus_noc_allocate_commit_data(struct msm_bus_fabric_registration |
||
7907 | + *fab_pdata, void **cdata, int ctx) |
||
7908 | +{ |
||
7909 | + struct msm_bus_noc_commit **cd = (struct msm_bus_noc_commit **)cdata; |
||
7910 | + struct msm_bus_noc_info *ninfo = |
||
7911 | + (struct msm_bus_noc_info *)fab_pdata->hw_data; |
||
7912 | + |
||
7913 | + *cd = kzalloc(sizeof(struct msm_bus_noc_commit), GFP_KERNEL); |
||
7914 | + if (!*cd) { |
||
7915 | + MSM_BUS_DBG("Couldn't alloc mem for cdata\n"); |
||
7916 | + return -ENOMEM; |
||
7917 | + } |
||
7918 | + |
||
7919 | + (*cd)->mas = ninfo->cdata[ctx].mas; |
||
7920 | + (*cd)->slv = ninfo->cdata[ctx].slv; |
||
7921 | + |
||
7922 | + return 0; |
||
7923 | +} |
||
7924 | + |
||
7925 | +static void *msm_bus_noc_allocate_noc_data(struct platform_device *pdev, |
||
7926 | + struct msm_bus_fabric_registration *fab_pdata) |
||
7927 | +{ |
||
7928 | + struct resource *noc_mem; |
||
7929 | + struct resource *noc_io; |
||
7930 | + struct msm_bus_noc_info *ninfo; |
||
7931 | + int i; |
||
7932 | + |
||
7933 | + ninfo = kzalloc(sizeof(struct msm_bus_noc_info), GFP_KERNEL); |
||
7934 | + if (!ninfo) { |
||
7935 | + MSM_BUS_DBG("Couldn't alloc mem for noc info\n"); |
||
7936 | + return NULL; |
||
7937 | + } |
||
7938 | + |
||
7939 | + ninfo->nmasters = fab_pdata->nmasters; |
||
7940 | + ninfo->nqos_masters = fab_pdata->nmasters; |
||
7941 | + ninfo->nslaves = fab_pdata->nslaves; |
||
7942 | + ninfo->qos_freq = fab_pdata->qos_freq; |
||
7943 | + |
||
7944 | + if (!fab_pdata->qos_baseoffset) |
||
7945 | + ninfo->qos_baseoffset = QOS_DEFAULT_BASEOFFSET; |
||
7946 | + else |
||
7947 | + ninfo->qos_baseoffset = fab_pdata->qos_baseoffset; |
||
7948 | + |
||
7949 | + if (!fab_pdata->qos_delta) |
||
7950 | + ninfo->qos_delta = QOS_DEFAULT_DELTA; |
||
7951 | + else |
||
7952 | + ninfo->qos_delta = fab_pdata->qos_delta; |
||
7953 | + |
||
7954 | + ninfo->mas_modes = kzalloc(sizeof(uint32_t) * fab_pdata->nmasters, |
||
7955 | + GFP_KERNEL); |
||
7956 | + if (!ninfo->mas_modes) { |
||
7957 | + MSM_BUS_DBG("Couldn't alloc mem for noc master-modes\n"); |
||
7958 | + kfree(ninfo); |
||
7959 | + return NULL; |
||
7960 | + } |
||
7961 | + |
||
7962 | + for (i = 0; i < NUM_CTX; i++) { |
||
7963 | + ninfo->cdata[i].mas = kzalloc(sizeof(struct |
||
7964 | + msm_bus_node_hw_info) * fab_pdata->nmasters * 2, |
||
7965 | + GFP_KERNEL); |
||
7966 | + if (!ninfo->cdata[i].mas) { |
||
7967 | + MSM_BUS_DBG("Couldn't alloc mem for noc master-bw\n"); |
||
7968 | + kfree(ninfo->mas_modes); |
||
7969 | + kfree(ninfo); |
||
7970 | + return NULL; |
||
7971 | + } |
||
7972 | + |
||
7973 | + ninfo->cdata[i].slv = kzalloc(sizeof(struct |
||
7974 | + msm_bus_node_hw_info) * fab_pdata->nslaves * 2, |
||
7975 | + GFP_KERNEL); |
||
7976 | + if (!ninfo->cdata[i].slv) { |
||
7977 | + MSM_BUS_DBG("Couldn't alloc mem for noc master-bw\n"); |
||
7978 | + kfree(ninfo->cdata[i].mas); |
||
7979 | + goto err; |
||
7980 | + } |
||
7981 | + } |
||
7982 | + |
||
7983 | + /* If it's a virtual fabric, don't get memory info */ |
||
7984 | + if (fab_pdata->virt) |
||
7985 | + goto skip_mem; |
||
7986 | + |
||
7987 | + noc_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
||
7988 | + if (!noc_mem && !fab_pdata->virt) { |
||
7989 | + MSM_BUS_ERR("Cannot get NoC Base address\n"); |
||
7990 | + goto err; |
||
7991 | + } |
||
7992 | + |
||
7993 | + noc_io = request_mem_region(noc_mem->start, |
||
7994 | + resource_size(noc_mem), pdev->name); |
||
7995 | + if (!noc_io) { |
||
7996 | + MSM_BUS_ERR("NoC memory unavailable\n"); |
||
7997 | + goto err; |
||
7998 | + } |
||
7999 | + |
||
8000 | + ninfo->base = ioremap(noc_mem->start, resource_size(noc_mem)); |
||
8001 | + if (!ninfo->base) { |
||
8002 | + MSM_BUS_ERR("IOremap failed for NoC!\n"); |
||
8003 | + release_mem_region(noc_mem->start, resource_size(noc_mem)); |
||
8004 | + goto err; |
||
8005 | + } |
||
8006 | + |
||
8007 | +skip_mem: |
||
8008 | + fab_pdata->hw_data = (void *)ninfo; |
||
8009 | + return (void *)ninfo; |
||
8010 | + |
||
8011 | +err: |
||
8012 | + kfree(ninfo->mas_modes); |
||
8013 | + kfree(ninfo); |
||
8014 | + return NULL; |
||
8015 | +} |
||
8016 | + |
||
8017 | +static void free_commit_data(void *cdata) |
||
8018 | +{ |
||
8019 | + struct msm_bus_noc_commit *cd = (struct msm_bus_noc_commit *)cdata; |
||
8020 | + |
||
8021 | + kfree(cd->mas); |
||
8022 | + kfree(cd->slv); |
||
8023 | + kfree(cd); |
||
8024 | +} |
||
8025 | + |
||
8026 | +static bool msm_bus_noc_update_bw_reg(int mode) |
||
8027 | +{ |
||
8028 | + bool ret = false; |
||
8029 | + |
||
8030 | + if ((mode == NOC_QOS_MODE_LIMITER) || |
||
8031 | + (mode == NOC_QOS_MODE_REGULATOR)) |
||
8032 | + ret = true; |
||
8033 | + |
||
8034 | + return ret; |
||
8035 | +} |
||
8036 | + |
||
8037 | +static void msm_bus_noc_update_bw(struct msm_bus_inode_info *hop, |
||
8038 | + struct msm_bus_inode_info *info, |
||
8039 | + struct msm_bus_fabric_registration *fab_pdata, |
||
8040 | + void *sel_cdata, int *master_tiers, |
||
8041 | + int64_t add_bw) |
||
8042 | +{ |
||
8043 | + struct msm_bus_noc_info *ninfo; |
||
8044 | + struct msm_bus_noc_qos_bw qos_bw; |
||
8045 | + int i, ports; |
||
8046 | + int64_t bw; |
||
8047 | + struct msm_bus_noc_commit *sel_cd = |
||
8048 | + (struct msm_bus_noc_commit *)sel_cdata; |
||
8049 | + |
||
8050 | + ninfo = (struct msm_bus_noc_info *)fab_pdata->hw_data; |
||
8051 | + if (!ninfo->qos_freq) { |
||
8052 | + MSM_BUS_DBG("NOC: No qos frequency to update bw\n"); |
||
8053 | + return; |
||
8054 | + } |
||
8055 | + |
||
8056 | + if (info->node_info->num_mports == 0) { |
||
8057 | + MSM_BUS_DBG("NOC: Skip Master BW\n"); |
||
8058 | + goto skip_mas_bw; |
||
8059 | + } |
||
8060 | + |
||
8061 | + ports = info->node_info->num_mports; |
||
8062 | + bw = INTERLEAVED_BW(fab_pdata, add_bw, ports); |
||
8063 | + |
||
8064 | + MSM_BUS_DBG("NOC: Update bw for: %d: %lld\n", |
||
8065 | + info->node_info->priv_id, add_bw); |
||
8066 | + for (i = 0; i < ports; i++) { |
||
8067 | + sel_cd->mas[info->node_info->masterp[i]].bw += bw; |
||
8068 | + sel_cd->mas[info->node_info->masterp[i]].hw_id = |
||
8069 | + info->node_info->mas_hw_id; |
||
8070 | + MSM_BUS_DBG("NOC: Update mas_bw: ID: %d, BW: %llu ports:%d\n", |
||
8071 | + info->node_info->priv_id, |
||
8072 | + sel_cd->mas[info->node_info->masterp[i]].bw, |
||
8073 | + ports); |
||
8074 | + /* Check if info is a shared master. |
||
8075 | + * If it is, mark it dirty |
||
8076 | + * If it isn't, then set QOS Bandwidth |
||
8077 | + **/ |
||
8078 | + if (info->node_info->hw_sel == MSM_BUS_RPM) |
||
8079 | + sel_cd->mas[info->node_info->masterp[i]].dirty = 1; |
||
8080 | + else { |
||
8081 | + if (!info->node_info->qport) { |
||
8082 | + MSM_BUS_DBG("No qos ports to update!\n"); |
||
8083 | + break; |
||
8084 | + } |
||
8085 | + |
||
8086 | + if (!(info->node_info->mode == NOC_QOS_MODE_REGULATOR) |
||
8087 | + || (info->node_info->mode == |
||
8088 | + NOC_QOS_MODE_LIMITER)) { |
||
8089 | + MSM_BUS_DBG("Skip QoS reg programming\n"); |
||
8090 | + break; |
||
8091 | + } |
||
8092 | + qos_bw.bw = sel_cd->mas[info->node_info->masterp[i]]. |
||
8093 | + bw; |
||
8094 | + qos_bw.ws = info->node_info->ws; |
||
8095 | + msm_bus_noc_set_qos_bw(ninfo->base, |
||
8096 | + ninfo->qos_baseoffset, |
||
8097 | + ninfo->qos_freq, |
||
8098 | + info->node_info->qport[i], ninfo->qos_delta, |
||
8099 | + info->node_info->perm_mode, &qos_bw); |
||
8100 | + MSM_BUS_DBG("NOC: QoS: Update mas_bw: ws: %u\n", |
||
8101 | + qos_bw.ws); |
||
8102 | + } |
||
8103 | + } |
||
8104 | + |
||
8105 | +skip_mas_bw: |
||
8106 | + ports = hop->node_info->num_sports; |
||
8107 | + for (i = 0; i < ports; i++) { |
||
8108 | + sel_cd->slv[hop->node_info->slavep[i]].bw += add_bw; |
||
8109 | + sel_cd->slv[hop->node_info->slavep[i]].hw_id = |
||
8110 | + hop->node_info->slv_hw_id; |
||
8111 | + MSM_BUS_DBG("NOC: Update slave_bw for ID: %d -> %llu\n", |
||
8112 | + hop->node_info->priv_id, |
||
8113 | + sel_cd->slv[hop->node_info->slavep[i]].bw); |
||
8114 | + MSM_BUS_DBG("NOC: Update slave_bw for hw_id: %d, index: %d\n", |
||
8115 | + hop->node_info->slv_hw_id, hop->node_info->slavep[i]); |
||
8116 | + /* Check if hop is a shared slave. |
||
8117 | + * If it is, mark it dirty |
||
8118 | + * If it isn't, then nothing to be done as the |
||
8119 | + * slaves are in bypass mode. |
||
8120 | + **/ |
||
8121 | + if (hop->node_info->hw_sel == MSM_BUS_RPM) |
||
8122 | + sel_cd->slv[hop->node_info->slavep[i]].dirty = 1; |
||
8123 | + } |
||
8124 | +} |
||
8125 | + |
||
8126 | +static int msm_bus_noc_commit(struct msm_bus_fabric_registration |
||
8127 | + *fab_pdata, void *hw_data, void **cdata) |
||
8128 | +{ |
||
8129 | + MSM_BUS_DBG("\nReached NOC Commit\n"); |
||
8130 | + msm_bus_remote_hw_commit(fab_pdata, hw_data, cdata); |
||
8131 | + return 0; |
||
8132 | +} |
||
8133 | + |
||
8134 | +static int msm_bus_noc_port_halt(uint32_t haltid, uint8_t mport) |
||
8135 | +{ |
||
8136 | + return 0; |
||
8137 | +} |
||
8138 | + |
||
8139 | +static int msm_bus_noc_port_unhalt(uint32_t haltid, uint8_t mport) |
||
8140 | +{ |
||
8141 | + return 0; |
||
8142 | +} |
||
8143 | + |
||
8144 | +static int msm_bus_noc_qos_init(struct msm_bus_node_device_type *info, |
||
8145 | + void __iomem *qos_base, |
||
8146 | + uint32_t qos_off, uint32_t qos_delta, |
||
8147 | + uint32_t qos_freq) |
||
8148 | +{ |
||
8149 | + struct msm_bus_noc_qos_priority prio; |
||
8150 | + int ret = 0; |
||
8151 | + int i; |
||
8152 | + |
||
8153 | + prio.p1 = info->node_info->qos_params.prio1; |
||
8154 | + prio.p0 = info->node_info->qos_params.prio0; |
||
8155 | + |
||
8156 | + if (!info->node_info->qport) { |
||
8157 | + MSM_BUS_DBG("No QoS Ports to init\n"); |
||
8158 | + ret = 0; |
||
8159 | + goto err_qos_init; |
||
8160 | + } |
||
8161 | + |
||
8162 | + for (i = 0; i < info->node_info->num_qports; i++) { |
||
8163 | + if (info->node_info->qos_params.mode != NOC_QOS_MODE_BYPASS) { |
||
8164 | + noc_set_qos_priority(qos_base, qos_off, |
||
8165 | + info->node_info->qport[i], qos_delta, |
||
8166 | + &prio); |
||
8167 | + |
||
8168 | + if (info->node_info->qos_params.mode != |
||
8169 | + NOC_QOS_MODE_FIXED) { |
||
8170 | + struct msm_bus_noc_qos_bw qbw; |
||
8171 | + qbw.ws = info->node_info->qos_params.ws; |
||
8172 | + qbw.bw = 0; |
||
8173 | + msm_bus_noc_set_qos_bw(qos_base, qos_off, |
||
8174 | + qos_freq, |
||
8175 | + info->node_info->qport[i], |
||
8176 | + qos_delta, |
||
8177 | + info->node_info->qos_params.mode, |
||
8178 | + &qbw); |
||
8179 | + } |
||
8180 | + } |
||
8181 | + |
||
8182 | + noc_set_qos_mode(qos_base, qos_off, info->node_info->qport[i], |
||
8183 | + qos_delta, info->node_info->qos_params.mode, |
||
8184 | + (1 << info->node_info->qos_params.mode)); |
||
8185 | + } |
||
8186 | +err_qos_init: |
||
8187 | + return ret; |
||
8188 | +} |
||
8189 | + |
||
8190 | +static int msm_bus_noc_set_bw(struct msm_bus_node_device_type *dev, |
||
8191 | + void __iomem *qos_base, |
||
8192 | + uint32_t qos_off, uint32_t qos_delta, |
||
8193 | + uint32_t qos_freq) |
||
8194 | +{ |
||
8195 | + int ret = 0; |
||
8196 | + uint64_t bw = 0; |
||
8197 | + int i; |
||
8198 | + struct msm_bus_node_info_type *info = dev->node_info; |
||
8199 | + |
||
8200 | + if (info && info->num_qports && |
||
8201 | + ((info->qos_params.mode == NOC_QOS_MODE_REGULATOR) || |
||
8202 | + (info->qos_params.mode == |
||
8203 | + NOC_QOS_MODE_LIMITER))) { |
||
8204 | + struct msm_bus_noc_qos_bw qos_bw; |
||
8205 | + |
||
8206 | + bw = msm_bus_div64(info->num_qports, |
||
8207 | + dev->node_ab.ab[DUAL_CTX]); |
||
8208 | + |
||
8209 | + for (i = 0; i < info->num_qports; i++) { |
||
8210 | + if (!info->qport) { |
||
8211 | + MSM_BUS_DBG("No qos ports to update!\n"); |
||
8212 | + break; |
||
8213 | + } |
||
8214 | + |
||
8215 | + qos_bw.bw = bw; |
||
8216 | + qos_bw.ws = info->qos_params.ws; |
||
8217 | + msm_bus_noc_set_qos_bw(qos_base, qos_off, qos_freq, |
||
8218 | + info->qport[i], qos_delta, |
||
8219 | + info->qos_params.mode, &qos_bw); |
||
8220 | + MSM_BUS_DBG("NOC: QoS: Update mas_bw: ws: %u\n", |
||
8221 | + qos_bw.ws); |
||
8222 | + } |
||
8223 | + } |
||
8224 | + return ret; |
||
8225 | +} |
||
8226 | +int msm_bus_noc_hw_init(struct msm_bus_fabric_registration *pdata, |
||
8227 | + struct msm_bus_hw_algorithm *hw_algo) |
||
8228 | +{ |
||
8229 | + /* Set interleaving to true by default */ |
||
8230 | + pdata->il_flag = true; |
||
8231 | + hw_algo->allocate_commit_data = msm_bus_noc_allocate_commit_data; |
||
8232 | + hw_algo->allocate_hw_data = msm_bus_noc_allocate_noc_data; |
||
8233 | + hw_algo->node_init = msm_bus_noc_node_init; |
||
8234 | + hw_algo->free_commit_data = free_commit_data; |
||
8235 | + hw_algo->update_bw = msm_bus_noc_update_bw; |
||
8236 | + hw_algo->commit = msm_bus_noc_commit; |
||
8237 | + hw_algo->port_halt = msm_bus_noc_port_halt; |
||
8238 | + hw_algo->port_unhalt = msm_bus_noc_port_unhalt; |
||
8239 | + hw_algo->update_bw_reg = msm_bus_noc_update_bw_reg; |
||
8240 | + hw_algo->config_master = NULL; |
||
8241 | + hw_algo->config_limiter = NULL; |
||
8242 | + |
||
8243 | + return 0; |
||
8244 | +} |
||
8245 | + |
||
8246 | +int msm_bus_noc_set_ops(struct msm_bus_node_device_type *bus_dev) |
||
8247 | +{ |
||
8248 | + if (!bus_dev) |
||
8249 | + return -ENODEV; |
||
8250 | + else { |
||
8251 | + bus_dev->fabdev->noc_ops.qos_init = msm_bus_noc_qos_init; |
||
8252 | + bus_dev->fabdev->noc_ops.set_bw = msm_bus_noc_set_bw; |
||
8253 | + bus_dev->fabdev->noc_ops.limit_mport = NULL; |
||
8254 | + bus_dev->fabdev->noc_ops.update_bw_reg = |
||
8255 | + msm_bus_noc_update_bw_reg; |
||
8256 | + } |
||
8257 | + return 0; |
||
8258 | +} |
||
8259 | +EXPORT_SYMBOL(msm_bus_noc_set_ops); |
||
8260 | --- /dev/null |
||
8261 | +++ b/drivers/bus/msm_bus/msm_bus_noc.h |
||
8262 | @@ -0,0 +1,76 @@ |
||
8263 | +/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. |
||
8264 | + * |
||
8265 | + * This program is free software; you can redistribute it and/or modify |
||
8266 | + * it under the terms of the GNU General Public License version 2 and |
||
8267 | + * only version 2 as published by the Free Software Foundation. |
||
8268 | + * |
||
8269 | + * This program is distributed in the hope that it will be useful, |
||
8270 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
8271 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
8272 | + * GNU General Public License for more details. |
||
8273 | + */ |
||
8274 | + |
||
8275 | +#ifndef _ARCH_ARM_MACH_MSM_BUS_BIMC_H |
||
8276 | +#define _ARCH_ARM_MACH_MSM_BUS_BIMC_H |
||
8277 | + |
||
8278 | +enum msm_bus_noc_qos_mode_type { |
||
8279 | + NOC_QOS_MODE_FIXED = 0, |
||
8280 | + NOC_QOS_MODE_LIMITER, |
||
8281 | + NOC_QOS_MODE_BYPASS, |
||
8282 | + NOC_QOS_MODE_REGULATOR, |
||
8283 | + NOC_QOS_MODE_MAX, |
||
8284 | +}; |
||
8285 | + |
||
8286 | +enum msm_bus_noc_qos_mode_perm { |
||
8287 | + NOC_QOS_PERM_MODE_FIXED = (1 << NOC_QOS_MODE_FIXED), |
||
8288 | + NOC_QOS_PERM_MODE_LIMITER = (1 << NOC_QOS_MODE_LIMITER), |
||
8289 | + NOC_QOS_PERM_MODE_BYPASS = (1 << NOC_QOS_MODE_BYPASS), |
||
8290 | + NOC_QOS_PERM_MODE_REGULATOR = (1 << NOC_QOS_MODE_REGULATOR), |
||
8291 | +}; |
||
8292 | + |
||
8293 | +#define NOC_QOS_MODES_ALL_PERM (NOC_QOS_PERM_MODE_FIXED | \ |
||
8294 | + NOC_QOS_PERM_MODE_LIMITER | NOC_QOS_PERM_MODE_BYPASS | \ |
||
8295 | + NOC_QOS_PERM_MODE_REGULATOR) |
||
8296 | + |
||
8297 | +struct msm_bus_noc_commit { |
||
8298 | + struct msm_bus_node_hw_info *mas; |
||
8299 | + struct msm_bus_node_hw_info *slv; |
||
8300 | +}; |
||
8301 | + |
||
8302 | +struct msm_bus_noc_info { |
||
8303 | + void __iomem *base; |
||
8304 | + uint32_t base_addr; |
||
8305 | + uint32_t nmasters; |
||
8306 | + uint32_t nqos_masters; |
||
8307 | + uint32_t nslaves; |
||
8308 | + uint32_t qos_freq; /* QOS Clock in KHz */ |
||
8309 | + uint32_t qos_baseoffset; |
||
8310 | + uint32_t qos_delta; |
||
8311 | + uint32_t *mas_modes; |
||
8312 | + struct msm_bus_noc_commit cdata[NUM_CTX]; |
||
8313 | +}; |
||
8314 | + |
||
8315 | +struct msm_bus_noc_qos_priority { |
||
8316 | + uint32_t high_prio; |
||
8317 | + uint32_t low_prio; |
||
8318 | + uint32_t read_prio; |
||
8319 | + uint32_t write_prio; |
||
8320 | + uint32_t p1; |
||
8321 | + uint32_t p0; |
||
8322 | +}; |
||
8323 | + |
||
8324 | +struct msm_bus_noc_qos_bw { |
||
8325 | + uint64_t bw; /* Bandwidth in bytes per second */ |
||
8326 | + uint32_t ws; /* Window size in nano seconds */ |
||
8327 | +}; |
||
8328 | + |
||
8329 | +void msm_bus_noc_init(struct msm_bus_noc_info *ninfo); |
||
8330 | +uint8_t msm_bus_noc_get_qos_mode(void __iomem *base, uint32_t qos_off, |
||
8331 | + uint32_t mport, uint32_t qos_delta, uint32_t mode, uint32_t perm_mode); |
||
8332 | +void msm_bus_noc_get_qos_priority(void __iomem *base, uint32_t qos_off, |
||
8333 | + uint32_t mport, uint32_t qos_delta, |
||
8334 | + struct msm_bus_noc_qos_priority *qprio); |
||
8335 | +void msm_bus_noc_get_qos_bw(void __iomem *base, uint32_t qos_off, |
||
8336 | + uint32_t qos_freq, uint32_t mport, uint32_t qos_delta, |
||
8337 | + uint8_t perm_mode, struct msm_bus_noc_qos_bw *qbw); |
||
8338 | +#endif /*_ARCH_ARM_MACH_MSM_BUS_NOC_H */ |
||
8339 | --- /dev/null |
||
8340 | +++ b/drivers/bus/msm_bus/msm_bus_of.c |
||
8341 | @@ -0,0 +1,705 @@ |
||
8342 | +/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. |
||
8343 | + * |
||
8344 | + * This program is free software; you can redistribute it and/or modify |
||
8345 | + * it under the terms of the GNU General Public License version 2 and |
||
8346 | + * only version 2 as published by the Free Software Foundation. |
||
8347 | + * |
||
8348 | + * This program is distributed in the hope that it will be useful, |
||
8349 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
8350 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
8351 | + * GNU General Public License for more details. |
||
8352 | + */ |
||
8353 | + |
||
8354 | +#define pr_fmt(fmt) "AXI: %s(): " fmt, __func__ |
||
8355 | + |
||
8356 | +#include <linux/module.h> |
||
8357 | +#include <linux/slab.h> |
||
8358 | +#include <linux/string.h> |
||
8359 | +#include <linux/of.h> |
||
8360 | +#include <linux/of_device.h> |
||
8361 | +#include <linux/platform_device.h> |
||
8362 | +#include "msm-bus.h" |
||
8363 | +#include "msm-bus-board.h" |
||
8364 | +#include "msm_bus_core.h" |
||
8365 | + |
||
8366 | +static const char * const hw_sel_name[] = {"RPM", "NoC", "BIMC", NULL}; |
||
8367 | +static const char * const mode_sel_name[] = {"Fixed", "Limiter", "Bypass", |
||
8368 | + "Regulator", NULL}; |
||
8369 | + |
||
8370 | +static int get_num(const char *const str[], const char *name) |
||
8371 | +{ |
||
8372 | + int i = 0; |
||
8373 | + |
||
8374 | + do { |
||
8375 | + if (!strcmp(name, str[i])) |
||
8376 | + return i; |
||
8377 | + |
||
8378 | + i++; |
||
8379 | + } while (str[i] != NULL); |
||
8380 | + |
||
8381 | + pr_err("Error: string %s not found\n", name); |
||
8382 | + return -EINVAL; |
||
8383 | +} |
||
8384 | + |
||
8385 | +#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_MSM_BUS_SCALING) |
||
8386 | +static struct msm_bus_scale_pdata *get_pdata(struct platform_device *pdev, |
||
8387 | + struct device_node *of_node) |
||
8388 | +{ |
||
8389 | + struct msm_bus_scale_pdata *pdata = NULL; |
||
8390 | + struct msm_bus_paths *usecase = NULL; |
||
8391 | + int i = 0, j, ret, num_usecases = 0, num_paths, len; |
||
8392 | + const uint32_t *vec_arr = NULL; |
||
8393 | + bool mem_err = false; |
||
8394 | + |
||
8395 | + if (!pdev) { |
||
8396 | + pr_err("Error: Null Platform device\n"); |
||
8397 | + return NULL; |
||
8398 | + } |
||
8399 | + |
||
8400 | + pdata = devm_kzalloc(&pdev->dev, sizeof(struct msm_bus_scale_pdata), |
||
8401 | + GFP_KERNEL); |
||
8402 | + if (!pdata) { |
||
8403 | + pr_err("Error: Memory allocation for pdata failed\n"); |
||
8404 | + mem_err = true; |
||
8405 | + goto err; |
||
8406 | + } |
||
8407 | + |
||
8408 | + ret = of_property_read_string(of_node, "qcom,msm-bus,name", |
||
8409 | + &pdata->name); |
||
8410 | + if (ret) { |
||
8411 | + pr_err("Error: Client name not found\n"); |
||
8412 | + goto err; |
||
8413 | + } |
||
8414 | + |
||
8415 | + ret = of_property_read_u32(of_node, "qcom,msm-bus,num-cases", |
||
8416 | + &num_usecases); |
||
8417 | + if (ret) { |
||
8418 | + pr_err("Error: num-usecases not found\n"); |
||
8419 | + goto err; |
||
8420 | + } |
||
8421 | + |
||
8422 | + pdata->num_usecases = num_usecases; |
||
8423 | + |
||
8424 | + if (of_property_read_bool(of_node, "qcom,msm-bus,active-only")) |
||
8425 | + pdata->active_only = 1; |
||
8426 | + else { |
||
8427 | + pr_debug("active_only flag absent.\n"); |
||
8428 | + pr_debug("Using dual context by default\n"); |
||
8429 | + } |
||
8430 | + |
||
8431 | + usecase = devm_kzalloc(&pdev->dev, (sizeof(struct msm_bus_paths) * |
||
8432 | + pdata->num_usecases), GFP_KERNEL); |
||
8433 | + if (!usecase) { |
||
8434 | + pr_err("Error: Memory allocation for paths failed\n"); |
||
8435 | + mem_err = true; |
||
8436 | + goto err; |
||
8437 | + } |
||
8438 | + |
||
8439 | + ret = of_property_read_u32(of_node, "qcom,msm-bus,num-paths", |
||
8440 | + &num_paths); |
||
8441 | + if (ret) { |
||
8442 | + pr_err("Error: num_paths not found\n"); |
||
8443 | + goto err; |
||
8444 | + } |
||
8445 | + |
||
8446 | + vec_arr = of_get_property(of_node, "qcom,msm-bus,vectors-KBps", &len); |
||
8447 | + if (vec_arr == NULL) { |
||
8448 | + pr_err("Error: Vector array not found\n"); |
||
8449 | + goto err; |
||
8450 | + } |
||
8451 | + |
||
8452 | + if (len != num_usecases * num_paths * sizeof(uint32_t) * 4) { |
||
8453 | + pr_err("Error: Length-error on getting vectors\n"); |
||
8454 | + goto err; |
||
8455 | + } |
||
8456 | + |
||
8457 | + for (i = 0; i < num_usecases; i++) { |
||
8458 | + usecase[i].num_paths = num_paths; |
||
8459 | + usecase[i].vectors = devm_kzalloc(&pdev->dev, num_paths * |
||
8460 | + sizeof(struct msm_bus_vectors), GFP_KERNEL); |
||
8461 | + if (!usecase[i].vectors) { |
||
8462 | + mem_err = true; |
||
8463 | + pr_err("Error: Mem alloc failure in vectors\n"); |
||
8464 | + goto err; |
||
8465 | + } |
||
8466 | + |
||
8467 | + for (j = 0; j < num_paths; j++) { |
||
8468 | + int index = ((i * num_paths) + j) * 4; |
||
8469 | + usecase[i].vectors[j].src = be32_to_cpu(vec_arr[index]); |
||
8470 | + usecase[i].vectors[j].dst = |
||
8471 | + be32_to_cpu(vec_arr[index + 1]); |
||
8472 | + usecase[i].vectors[j].ab = (uint64_t) |
||
8473 | + KBTOB(be32_to_cpu(vec_arr[index + 2])); |
||
8474 | + usecase[i].vectors[j].ib = (uint64_t) |
||
8475 | + KBTOB(be32_to_cpu(vec_arr[index + 3])); |
||
8476 | + } |
||
8477 | + } |
||
8478 | + |
||
8479 | + pdata->usecase = usecase; |
||
8480 | + return pdata; |
||
8481 | +err: |
||
8482 | + if (mem_err) { |
||
8483 | + for (; i > 0; i--) |
||
8484 | + kfree(usecase[i-1].vectors); |
||
8485 | + |
||
8486 | + kfree(usecase); |
||
8487 | + kfree(pdata); |
||
8488 | + } |
||
8489 | + |
||
8490 | + return NULL; |
||
8491 | +} |
||
8492 | + |
||
8493 | +/** |
||
8494 | + * msm_bus_cl_get_pdata() - Generate bus client data from device tree |
||
8495 | + * provided by clients. |
||
8496 | + * |
||
8497 | + * of_node: Device tree node to extract information from |
||
8498 | + * |
||
8499 | + * The function returns a valid pointer to the allocated bus-scale-pdata |
||
8500 | + * if the vectors were correctly read from the client's device node. |
||
8501 | + * Any error in reading or parsing the device node will return NULL |
||
8502 | + * to the caller. |
||
8503 | + */ |
||
8504 | +struct msm_bus_scale_pdata *msm_bus_cl_get_pdata(struct platform_device *pdev) |
||
8505 | +{ |
||
8506 | + struct device_node *of_node; |
||
8507 | + struct msm_bus_scale_pdata *pdata = NULL; |
||
8508 | + |
||
8509 | + if (!pdev) { |
||
8510 | + pr_err("Error: Null Platform device\n"); |
||
8511 | + return NULL; |
||
8512 | + } |
||
8513 | + |
||
8514 | + of_node = pdev->dev.of_node; |
||
8515 | + pdata = get_pdata(pdev, of_node); |
||
8516 | + if (!pdata) { |
||
8517 | + pr_err("client has to provide missing entry for successful registration\n"); |
||
8518 | + return NULL; |
||
8519 | + } |
||
8520 | + |
||
8521 | + return pdata; |
||
8522 | +} |
||
8523 | +EXPORT_SYMBOL(msm_bus_cl_get_pdata); |
||
8524 | + |
||
8525 | +/** |
||
8526 | + * msm_bus_cl_pdata_from_node() - Generate bus client data from device tree |
||
8527 | + * node provided by clients. This function should be used when a client |
||
8528 | + * driver needs to register multiple bus-clients from a single device-tree |
||
8529 | + * node associated with the platform-device. |
||
8530 | + * |
||
8531 | + * of_node: The subnode containing information about the bus scaling |
||
8532 | + * data |
||
8533 | + * |
||
8534 | + * pdev: Platform device associated with the device-tree node |
||
8535 | + * |
||
8536 | + * The function returns a valid pointer to the allocated bus-scale-pdata |
||
8537 | + * if the vectors were correctly read from the client's device node. |
||
8538 | + * Any error in reading or parsing the device node will return NULL |
||
8539 | + * to the caller. |
||
8540 | + */ |
||
8541 | +struct msm_bus_scale_pdata *msm_bus_pdata_from_node( |
||
8542 | + struct platform_device *pdev, struct device_node *of_node) |
||
8543 | +{ |
||
8544 | + struct msm_bus_scale_pdata *pdata = NULL; |
||
8545 | + |
||
8546 | + if (!pdev) { |
||
8547 | + pr_err("Error: Null Platform device\n"); |
||
8548 | + return NULL; |
||
8549 | + } |
||
8550 | + |
||
8551 | + if (!of_node) { |
||
8552 | + pr_err("Error: Null of_node passed to bus driver\n"); |
||
8553 | + return NULL; |
||
8554 | + } |
||
8555 | + |
||
8556 | + pdata = get_pdata(pdev, of_node); |
||
8557 | + if (!pdata) { |
||
8558 | + pr_err("client has to provide missing entry for successful registration\n"); |
||
8559 | + return NULL; |
||
8560 | + } |
||
8561 | + |
||
8562 | + return pdata; |
||
8563 | +} |
||
8564 | +EXPORT_SYMBOL(msm_bus_pdata_from_node); |
||
8565 | + |
||
8566 | +/** |
||
8567 | + * msm_bus_cl_clear_pdata() - Clear pdata allocated from device-tree |
||
8568 | + * of_node: Device tree node to extract information from |
||
8569 | + */ |
||
8570 | +void msm_bus_cl_clear_pdata(struct msm_bus_scale_pdata *pdata) |
||
8571 | +{ |
||
8572 | + int i; |
||
8573 | + |
||
8574 | + for (i = 0; i < pdata->num_usecases; i++) |
||
8575 | + kfree(pdata->usecase[i].vectors); |
||
8576 | + |
||
8577 | + kfree(pdata->usecase); |
||
8578 | + kfree(pdata); |
||
8579 | +} |
||
8580 | +EXPORT_SYMBOL(msm_bus_cl_clear_pdata); |
||
8581 | +#endif |
||
8582 | + |
||
8583 | +static int *get_arr(struct platform_device *pdev, |
||
8584 | + const struct device_node *node, const char *prop, |
||
8585 | + int *nports) |
||
8586 | +{ |
||
8587 | + int size = 0, ret; |
||
8588 | + int *arr = NULL; |
||
8589 | + |
||
8590 | + if (of_get_property(node, prop, &size)) { |
||
8591 | + *nports = size / sizeof(int); |
||
8592 | + } else { |
||
8593 | + pr_debug("Property %s not available\n", prop); |
||
8594 | + *nports = 0; |
||
8595 | + return NULL; |
||
8596 | + } |
||
8597 | + |
||
8598 | + if (!size) { |
||
8599 | + *nports = 0; |
||
8600 | + return NULL; |
||
8601 | + } |
||
8602 | + |
||
8603 | + arr = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); |
||
8604 | + if (ZERO_OR_NULL_PTR(arr)) { |
||
8605 | + pr_err("Error: Failed to alloc mem for %s\n", prop); |
||
8606 | + return NULL; |
||
8607 | + } |
||
8608 | + |
||
8609 | + ret = of_property_read_u32_array(node, prop, (u32 *)arr, *nports); |
||
8610 | + if (ret) { |
||
8611 | + pr_err("Error in reading property: %s\n", prop); |
||
8612 | + goto err; |
||
8613 | + } |
||
8614 | + |
||
8615 | + return arr; |
||
8616 | +err: |
||
8617 | + devm_kfree(&pdev->dev, arr); |
||
8618 | + return NULL; |
||
8619 | +} |
||
8620 | + |
||
8621 | +static u64 *get_th_params(struct platform_device *pdev, |
||
8622 | + const struct device_node *node, const char *prop, |
||
8623 | + int *nports) |
||
8624 | +{ |
||
8625 | + int size = 0, ret; |
||
8626 | + u64 *ret_arr = NULL; |
||
8627 | + int *arr = NULL; |
||
8628 | + int i; |
||
8629 | + |
||
8630 | + if (of_get_property(node, prop, &size)) { |
||
8631 | + *nports = size / sizeof(int); |
||
8632 | + } else { |
||
8633 | + pr_debug("Property %s not available\n", prop); |
||
8634 | + *nports = 0; |
||
8635 | + return NULL; |
||
8636 | + } |
||
8637 | + |
||
8638 | + if (!size) { |
||
8639 | + *nports = 0; |
||
8640 | + return NULL; |
||
8641 | + } |
||
8642 | + |
||
8643 | + ret_arr = devm_kzalloc(&pdev->dev, (*nports * sizeof(u64)), |
||
8644 | + GFP_KERNEL); |
||
8645 | + if (ZERO_OR_NULL_PTR(ret_arr)) { |
||
8646 | + pr_err("Error: Failed to alloc mem for ret arr %s\n", prop); |
||
8647 | + return NULL; |
||
8648 | + } |
||
8649 | + |
||
8650 | + arr = kzalloc(size, GFP_KERNEL); |
||
8651 | + if ((ZERO_OR_NULL_PTR(arr))) { |
||
8652 | + pr_err("Error: Failed to alloc temp mem for %s\n", prop); |
||
8653 | + return NULL; |
||
8654 | + } |
||
8655 | + |
||
8656 | + ret = of_property_read_u32_array(node, prop, (u32 *)arr, *nports); |
||
8657 | + if (ret) { |
||
8658 | + pr_err("Error in reading property: %s\n", prop); |
||
8659 | + goto err; |
||
8660 | + } |
||
8661 | + |
||
8662 | + for (i = 0; i < *nports; i++) |
||
8663 | + ret_arr[i] = (uint64_t)KBTOB(arr[i]); |
||
8664 | + |
||
8665 | + MSM_BUS_DBG("%s: num entries %d prop %s", __func__, *nports, prop); |
||
8666 | + |
||
8667 | + for (i = 0; i < *nports; i++) |
||
8668 | + MSM_BUS_DBG("Th %d val %llu", i, ret_arr[i]); |
||
8669 | + |
||
8670 | + kfree(arr); |
||
8671 | + return ret_arr; |
||
8672 | +err: |
||
8673 | + kfree(arr); |
||
8674 | + devm_kfree(&pdev->dev, ret_arr); |
||
8675 | + return NULL; |
||
8676 | +} |
||
8677 | + |
||
8678 | +static struct msm_bus_node_info *get_nodes(struct device_node *of_node, |
||
8679 | + struct platform_device *pdev, |
||
8680 | + struct msm_bus_fabric_registration *pdata) |
||
8681 | +{ |
||
8682 | + struct msm_bus_node_info *info; |
||
8683 | + struct device_node *child_node = NULL; |
||
8684 | + int i = 0, ret; |
||
8685 | + int num_bw = 0; |
||
8686 | + u32 temp; |
||
8687 | + |
||
8688 | + for_each_child_of_node(of_node, child_node) { |
||
8689 | + i++; |
||
8690 | + } |
||
8691 | + |
||
8692 | + pdata->len = i; |
||
8693 | + info = (struct msm_bus_node_info *) |
||
8694 | + devm_kzalloc(&pdev->dev, sizeof(struct msm_bus_node_info) * |
||
8695 | + pdata->len, GFP_KERNEL); |
||
8696 | + if (ZERO_OR_NULL_PTR(info)) { |
||
8697 | + pr_err("Failed to alloc memory for nodes: %d\n", pdata->len); |
||
8698 | + goto err; |
||
8699 | + } |
||
8700 | + |
||
8701 | + i = 0; |
||
8702 | + child_node = NULL; |
||
8703 | + for_each_child_of_node(of_node, child_node) { |
||
8704 | + const char *sel_str; |
||
8705 | + |
||
8706 | + ret = of_property_read_string(child_node, "label", |
||
8707 | + &info[i].name); |
||
8708 | + if (ret) |
||
8709 | + pr_err("Error reading node label\n"); |
||
8710 | + |
||
8711 | + ret = of_property_read_u32(child_node, "cell-id", &info[i].id); |
||
8712 | + if (ret) { |
||
8713 | + pr_err("Error reading node id\n"); |
||
8714 | + goto err; |
||
8715 | + } |
||
8716 | + |
||
8717 | + if (of_property_read_bool(child_node, "qcom,gateway")) |
||
8718 | + info[i].gateway = 1; |
||
8719 | + |
||
8720 | + of_property_read_u32(child_node, "qcom,mas-hw-id", |
||
8721 | + &info[i].mas_hw_id); |
||
8722 | + |
||
8723 | + of_property_read_u32(child_node, "qcom,slv-hw-id", |
||
8724 | + &info[i].slv_hw_id); |
||
8725 | + info[i].masterp = get_arr(pdev, child_node, |
||
8726 | + "qcom,masterp", &info[i].num_mports); |
||
8727 | + /* No need to store number of qports */ |
||
8728 | + info[i].qport = get_arr(pdev, child_node, |
||
8729 | + "qcom,qport", &ret); |
||
8730 | + pdata->nmasters += info[i].num_mports; |
||
8731 | + |
||
8732 | + |
||
8733 | + info[i].slavep = get_arr(pdev, child_node, |
||
8734 | + "qcom,slavep", &info[i].num_sports); |
||
8735 | + pdata->nslaves += info[i].num_sports; |
||
8736 | + |
||
8737 | + |
||
8738 | + info[i].tier = get_arr(pdev, child_node, |
||
8739 | + "qcom,tier", &info[i].num_tiers); |
||
8740 | + |
||
8741 | + if (of_property_read_bool(child_node, "qcom,ahb")) |
||
8742 | + info[i].ahb = 1; |
||
8743 | + |
||
8744 | + ret = of_property_read_string(child_node, "qcom,hw-sel", |
||
8745 | + &sel_str); |
||
8746 | + if (ret) |
||
8747 | + info[i].hw_sel = 0; |
||
8748 | + else { |
||
8749 | + ret = get_num(hw_sel_name, sel_str); |
||
8750 | + if (ret < 0) { |
||
8751 | + pr_err("Invalid hw-sel\n"); |
||
8752 | + goto err; |
||
8753 | + } |
||
8754 | + |
||
8755 | + info[i].hw_sel = ret; |
||
8756 | + } |
||
8757 | + |
||
8758 | + of_property_read_u32(child_node, "qcom,buswidth", |
||
8759 | + &info[i].buswidth); |
||
8760 | + of_property_read_u32(child_node, "qcom,ws", &info[i].ws); |
||
8761 | + |
||
8762 | + info[i].dual_conf = |
||
8763 | + of_property_read_bool(child_node, "qcom,dual-conf"); |
||
8764 | + |
||
8765 | + |
||
8766 | + info[i].th = get_th_params(pdev, child_node, "qcom,thresh", |
||
8767 | + &info[i].num_thresh); |
||
8768 | + |
||
8769 | + info[i].bimc_bw = get_th_params(pdev, child_node, |
||
8770 | + "qcom,bimc,bw", &num_bw); |
||
8771 | + |
||
8772 | + if (num_bw != info[i].num_thresh) { |
||
8773 | + pr_err("%s:num_bw %d must equal num_thresh %d", |
||
8774 | + __func__, num_bw, info[i].num_thresh); |
||
8775 | + pr_err("%s:Err setting up dual conf for %s", |
||
8776 | + __func__, info[i].name); |
||
8777 | + goto err; |
||
8778 | + } |
||
8779 | + |
||
8780 | + of_property_read_u32(child_node, "qcom,bimc,gp", |
||
8781 | + &info[i].bimc_gp); |
||
8782 | + of_property_read_u32(child_node, "qcom,bimc,thmp", |
||
8783 | + &info[i].bimc_thmp); |
||
8784 | + |
||
8785 | + ret = of_property_read_string(child_node, "qcom,mode-thresh", |
||
8786 | + &sel_str); |
||
8787 | + if (ret) |
||
8788 | + info[i].mode_thresh = 0; |
||
8789 | + else { |
||
8790 | + ret = get_num(mode_sel_name, sel_str); |
||
8791 | + if (ret < 0) { |
||
8792 | + pr_err("Unknown mode :%s\n", sel_str); |
||
8793 | + goto err; |
||
8794 | + } |
||
8795 | + |
||
8796 | + info[i].mode_thresh = ret; |
||
8797 | + MSM_BUS_DBG("AXI: THreshold mode set: %d\n", |
||
8798 | + info[i].mode_thresh); |
||
8799 | + } |
||
8800 | + |
||
8801 | + ret = of_property_read_string(child_node, "qcom,mode", |
||
8802 | + &sel_str); |
||
8803 | + |
||
8804 | + if (ret) |
||
8805 | + info[i].mode = 0; |
||
8806 | + else { |
||
8807 | + ret = get_num(mode_sel_name, sel_str); |
||
8808 | + if (ret < 0) { |
||
8809 | + pr_err("Unknown mode :%s\n", sel_str); |
||
8810 | + goto err; |
||
8811 | + } |
||
8812 | + |
||
8813 | + info[i].mode = ret; |
||
8814 | + } |
||
8815 | + |
||
8816 | + info[i].nr_lim = |
||
8817 | + of_property_read_bool(child_node, "qcom,nr-lim"); |
||
8818 | + |
||
8819 | + ret = of_property_read_u32(child_node, "qcom,ff", |
||
8820 | + &info[i].ff); |
||
8821 | + if (ret) { |
||
8822 | + pr_debug("fudge factor not present %d", info[i].id); |
||
8823 | + info[i].ff = 0; |
||
8824 | + } |
||
8825 | + |
||
8826 | + ret = of_property_read_u32(child_node, "qcom,floor-bw", |
||
8827 | + &temp); |
||
8828 | + if (ret) { |
||
8829 | + pr_debug("fabdev floor bw not present %d", info[i].id); |
||
8830 | + info[i].floor_bw = 0; |
||
8831 | + } else { |
||
8832 | + info[i].floor_bw = KBTOB(temp); |
||
8833 | + } |
||
8834 | + |
||
8835 | + info[i].rt_mas = |
||
8836 | + of_property_read_bool(child_node, "qcom,rt-mas"); |
||
8837 | + |
||
8838 | + ret = of_property_read_string(child_node, "qcom,perm-mode", |
||
8839 | + &sel_str); |
||
8840 | + if (ret) |
||
8841 | + info[i].perm_mode = 0; |
||
8842 | + else { |
||
8843 | + ret = get_num(mode_sel_name, sel_str); |
||
8844 | + if (ret < 0) |
||
8845 | + goto err; |
||
8846 | + |
||
8847 | + info[i].perm_mode = 1 << ret; |
||
8848 | + } |
||
8849 | + |
||
8850 | + of_property_read_u32(child_node, "qcom,prio-lvl", |
||
8851 | + &info[i].prio_lvl); |
||
8852 | + of_property_read_u32(child_node, "qcom,prio-rd", |
||
8853 | + &info[i].prio_rd); |
||
8854 | + of_property_read_u32(child_node, "qcom,prio-wr", |
||
8855 | + &info[i].prio_wr); |
||
8856 | + of_property_read_u32(child_node, "qcom,prio0", &info[i].prio0); |
||
8857 | + of_property_read_u32(child_node, "qcom,prio1", &info[i].prio1); |
||
8858 | + ret = of_property_read_string(child_node, "qcom,slaveclk-dual", |
||
8859 | + &info[i].slaveclk[DUAL_CTX]); |
||
8860 | + if (!ret) |
||
8861 | + pr_debug("Got slaveclk_dual: %s\n", |
||
8862 | + info[i].slaveclk[DUAL_CTX]); |
||
8863 | + else |
||
8864 | + info[i].slaveclk[DUAL_CTX] = NULL; |
||
8865 | + |
||
8866 | + ret = of_property_read_string(child_node, |
||
8867 | + "qcom,slaveclk-active", &info[i].slaveclk[ACTIVE_CTX]); |
||
8868 | + if (!ret) |
||
8869 | + pr_debug("Got slaveclk_active\n"); |
||
8870 | + else |
||
8871 | + info[i].slaveclk[ACTIVE_CTX] = NULL; |
||
8872 | + |
||
8873 | + ret = of_property_read_string(child_node, "qcom,memclk-dual", |
||
8874 | + &info[i].memclk[DUAL_CTX]); |
||
8875 | + if (!ret) |
||
8876 | + pr_debug("Got memclk_dual\n"); |
||
8877 | + else |
||
8878 | + info[i].memclk[DUAL_CTX] = NULL; |
||
8879 | + |
||
8880 | + ret = of_property_read_string(child_node, "qcom,memclk-active", |
||
8881 | + &info[i].memclk[ACTIVE_CTX]); |
||
8882 | + if (!ret) |
||
8883 | + pr_debug("Got memclk_active\n"); |
||
8884 | + else |
||
8885 | + info[i].memclk[ACTIVE_CTX] = NULL; |
||
8886 | + |
||
8887 | + ret = of_property_read_string(child_node, "qcom,iface-clk-node", |
||
8888 | + &info[i].iface_clk_node); |
||
8889 | + if (!ret) |
||
8890 | + pr_debug("Got iface_clk_node\n"); |
||
8891 | + else |
||
8892 | + info[i].iface_clk_node = NULL; |
||
8893 | + |
||
8894 | + pr_debug("Node name: %s\n", info[i].name); |
||
8895 | + of_node_put(child_node); |
||
8896 | + i++; |
||
8897 | + } |
||
8898 | + |
||
8899 | + pr_debug("Bus %d added: %d masters\n", pdata->id, pdata->nmasters); |
||
8900 | + pr_debug("Bus %d added: %d slaves\n", pdata->id, pdata->nslaves); |
||
8901 | + return info; |
||
8902 | +err: |
||
8903 | + return NULL; |
||
8904 | +} |
||
8905 | + |
||
8906 | +void msm_bus_of_get_nfab(struct platform_device *pdev, |
||
8907 | + struct msm_bus_fabric_registration *pdata) |
||
8908 | +{ |
||
8909 | + struct device_node *of_node; |
||
8910 | + int ret, nfab = 0; |
||
8911 | + |
||
8912 | + if (!pdev) { |
||
8913 | + pr_err("Error: Null platform device\n"); |
||
8914 | + return; |
||
8915 | + } |
||
8916 | + |
||
8917 | + of_node = pdev->dev.of_node; |
||
8918 | + ret = of_property_read_u32(of_node, "qcom,nfab", |
||
8919 | + &nfab); |
||
8920 | + if (!ret) |
||
8921 | + pr_debug("Fab_of: Read number of buses: %u\n", nfab); |
||
8922 | + |
||
8923 | + msm_bus_board_set_nfab(pdata, nfab); |
||
8924 | +} |
||
8925 | + |
||
8926 | +struct msm_bus_fabric_registration |
||
8927 | + *msm_bus_of_get_fab_data(struct platform_device *pdev) |
||
8928 | +{ |
||
8929 | + struct device_node *of_node; |
||
8930 | + struct msm_bus_fabric_registration *pdata; |
||
8931 | + bool mem_err = false; |
||
8932 | + int ret = 0; |
||
8933 | + const char *sel_str; |
||
8934 | + u32 temp; |
||
8935 | + |
||
8936 | + if (!pdev) { |
||
8937 | + pr_err("Error: Null platform device\n"); |
||
8938 | + return NULL; |
||
8939 | + } |
||
8940 | + |
||
8941 | + of_node = pdev->dev.of_node; |
||
8942 | + pdata = devm_kzalloc(&pdev->dev, |
||
8943 | + sizeof(struct msm_bus_fabric_registration), GFP_KERNEL); |
||
8944 | + if (!pdata) { |
||
8945 | + pr_err("Error: Memory allocation for pdata failed\n"); |
||
8946 | + mem_err = true; |
||
8947 | + goto err; |
||
8948 | + } |
||
8949 | + |
||
8950 | + ret = of_property_read_string(of_node, "label", &pdata->name); |
||
8951 | + if (ret) { |
||
8952 | + pr_err("Error: label not found\n"); |
||
8953 | + goto err; |
||
8954 | + } |
||
8955 | + pr_debug("Fab_of: Read name: %s\n", pdata->name); |
||
8956 | + |
||
8957 | + ret = of_property_read_u32(of_node, "cell-id", |
||
8958 | + &pdata->id); |
||
8959 | + if (ret) { |
||
8960 | + pr_err("Error: num-usecases not found\n"); |
||
8961 | + goto err; |
||
8962 | + } |
||
8963 | + pr_debug("Fab_of: Read id: %u\n", pdata->id); |
||
8964 | + |
||
8965 | + if (of_property_read_bool(of_node, "qcom,ahb")) |
||
8966 | + pdata->ahb = 1; |
||
8967 | + |
||
8968 | + ret = of_property_read_string(of_node, "qcom,fabclk-dual", |
||
8969 | + &pdata->fabclk[DUAL_CTX]); |
||
8970 | + if (ret) { |
||
8971 | + pr_debug("fabclk_dual not available\n"); |
||
8972 | + pdata->fabclk[DUAL_CTX] = NULL; |
||
8973 | + } else |
||
8974 | + pr_debug("Fab_of: Read clk dual ctx: %s\n", |
||
8975 | + pdata->fabclk[DUAL_CTX]); |
||
8976 | + ret = of_property_read_string(of_node, "qcom,fabclk-active", |
||
8977 | + &pdata->fabclk[ACTIVE_CTX]); |
||
8978 | + if (ret) { |
||
8979 | + pr_debug("Error: fabclk_active not available\n"); |
||
8980 | + pdata->fabclk[ACTIVE_CTX] = NULL; |
||
8981 | + } else |
||
8982 | + pr_debug("Fab_of: Read clk act ctx: %s\n", |
||
8983 | + pdata->fabclk[ACTIVE_CTX]); |
||
8984 | + |
||
8985 | + ret = of_property_read_u32(of_node, "qcom,ntieredslaves", |
||
8986 | + &pdata->ntieredslaves); |
||
8987 | + if (ret) { |
||
8988 | + pr_err("Error: ntieredslaves not found\n"); |
||
8989 | + goto err; |
||
8990 | + } |
||
8991 | + |
||
8992 | + ret = of_property_read_u32(of_node, "qcom,qos-freq", &pdata->qos_freq); |
||
8993 | + if (ret) |
||
8994 | + pr_debug("qos_freq not available\n"); |
||
8995 | + |
||
8996 | + ret = of_property_read_string(of_node, "qcom,hw-sel", &sel_str); |
||
8997 | + if (ret) { |
||
8998 | + pr_err("Error: hw_sel not found\n"); |
||
8999 | + goto err; |
||
9000 | + } else { |
||
9001 | + ret = get_num(hw_sel_name, sel_str); |
||
9002 | + if (ret < 0) |
||
9003 | + goto err; |
||
9004 | + |
||
9005 | + pdata->hw_sel = ret; |
||
9006 | + } |
||
9007 | + |
||
9008 | + if (of_property_read_bool(of_node, "qcom,virt")) |
||
9009 | + pdata->virt = true; |
||
9010 | + |
||
9011 | + ret = of_property_read_u32(of_node, "qcom,qos-baseoffset", |
||
9012 | + &pdata->qos_baseoffset); |
||
9013 | + if (ret) |
||
9014 | + pr_debug("%s:qos_baseoffset not available\n", __func__); |
||
9015 | + |
||
9016 | + ret = of_property_read_u32(of_node, "qcom,qos-delta", |
||
9017 | + &pdata->qos_delta); |
||
9018 | + if (ret) |
||
9019 | + pr_debug("%s:qos_delta not available\n", __func__); |
||
9020 | + |
||
9021 | + if (of_property_read_bool(of_node, "qcom,rpm-en")) |
||
9022 | + pdata->rpm_enabled = 1; |
||
9023 | + |
||
9024 | + ret = of_property_read_u32(of_node, "qcom,nr-lim-thresh", |
||
9025 | + &temp); |
||
9026 | + |
||
9027 | + if (ret) { |
||
9028 | + pr_err("nr-lim threshold not specified"); |
||
9029 | + pdata->nr_lim_thresh = 0; |
||
9030 | + } else { |
||
9031 | + pdata->nr_lim_thresh = KBTOB(temp); |
||
9032 | + } |
||
9033 | + |
||
9034 | + ret = of_property_read_u32(of_node, "qcom,eff-fact", |
||
9035 | + &pdata->eff_fact); |
||
9036 | + if (ret) { |
||
9037 | + pr_err("Fab eff-factor not present"); |
||
9038 | + pdata->eff_fact = 0; |
||
9039 | + } |
||
9040 | + |
||
9041 | + pdata->info = get_nodes(of_node, pdev, pdata); |
||
9042 | + return pdata; |
||
9043 | +err: |
||
9044 | + return NULL; |
||
9045 | +} |
||
9046 | +EXPORT_SYMBOL(msm_bus_of_get_fab_data); |
||
9047 | --- /dev/null |
||
9048 | +++ b/drivers/bus/msm_bus/msm_bus_of_adhoc.c |
||
9049 | @@ -0,0 +1,641 @@ |
||
9050 | +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. |
||
9051 | + * |
||
9052 | + * This program is free software; you can redistribute it and/or modify |
||
9053 | + * it under the terms of the GNU General Public License version 2 and |
||
9054 | + * only version 2 as published by the Free Software Foundation. |
||
9055 | + * |
||
9056 | + * This program is distributed in the hope that it will be useful, |
||
9057 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
9058 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
9059 | + * GNU General Public License for more details. |
||
9060 | + */ |
||
9061 | + |
||
9062 | +#define pr_fmt(fmt) "AXI: %s(): " fmt, __func__ |
||
9063 | + |
||
9064 | +#include <linux/clk.h> |
||
9065 | +#include <linux/device.h> |
||
9066 | +#include <linux/module.h> |
||
9067 | +#include <linux/slab.h> |
||
9068 | +#include <linux/string.h> |
||
9069 | +#include <linux/of.h> |
||
9070 | +#include <linux/of_device.h> |
||
9071 | +#include <linux/platform_device.h> |
||
9072 | +#include "msm-bus.h" |
||
9073 | +#include "msm-bus-board.h" |
||
9074 | +#include "msm_bus_rules.h" |
||
9075 | +#include "msm_bus_core.h" |
||
9076 | +#include "msm_bus_adhoc.h" |
||
9077 | + |
||
9078 | +#define DEFAULT_QOS_FREQ 19200 |
||
9079 | +#define DEFAULT_UTIL_FACT 100 |
||
9080 | +#define DEFAULT_VRAIL_COMP 100 |
||
9081 | + |
||
9082 | +static int get_qos_mode(struct platform_device *pdev, |
||
9083 | + struct device_node *node, const char *qos_mode) |
||
9084 | +{ |
||
9085 | + const char *qos_names[] = {"fixed", "limiter", "bypass", "regulator"}; |
||
9086 | + int i = 0; |
||
9087 | + int ret = -1; |
||
9088 | + |
||
9089 | + if (!qos_mode) |
||
9090 | + goto exit_get_qos_mode; |
||
9091 | + |
||
9092 | + for (i = 0; i < ARRAY_SIZE(qos_names); i++) { |
||
9093 | + if (!strcmp(qos_mode, qos_names[i])) |
||
9094 | + break; |
||
9095 | + } |
||
9096 | + if (i == ARRAY_SIZE(qos_names)) |
||
9097 | + dev_err(&pdev->dev, "Cannot match mode qos %s using Bypass", |
||
9098 | + qos_mode); |
||
9099 | + else |
||
9100 | + ret = i; |
||
9101 | + |
||
9102 | +exit_get_qos_mode: |
||
9103 | + return ret; |
||
9104 | +} |
||
9105 | + |
||
9106 | +static int *get_arr(struct platform_device *pdev, |
||
9107 | + struct device_node *node, const char *prop, |
||
9108 | + int *nports) |
||
9109 | +{ |
||
9110 | + int size = 0, ret; |
||
9111 | + int *arr = NULL; |
||
9112 | + |
||
9113 | + if (of_get_property(node, prop, &size)) { |
||
9114 | + *nports = size / sizeof(int); |
||
9115 | + } else { |
||
9116 | + dev_dbg(&pdev->dev, "Property %s not available\n", prop); |
||
9117 | + *nports = 0; |
||
9118 | + return NULL; |
||
9119 | + } |
||
9120 | + |
||
9121 | + arr = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); |
||
9122 | + if ((size > 0) && ZERO_OR_NULL_PTR(arr)) { |
||
9123 | + dev_err(&pdev->dev, "Error: Failed to alloc mem for %s\n", |
||
9124 | + prop); |
||
9125 | + return NULL; |
||
9126 | + } |
||
9127 | + |
||
9128 | + ret = of_property_read_u32_array(node, prop, (u32 *)arr, *nports); |
||
9129 | + if (ret) { |
||
9130 | + dev_err(&pdev->dev, "Error in reading property: %s\n", prop); |
||
9131 | + goto arr_err; |
||
9132 | + } |
||
9133 | + |
||
9134 | + return arr; |
||
9135 | +arr_err: |
||
9136 | + devm_kfree(&pdev->dev, arr); |
||
9137 | + return NULL; |
||
9138 | +} |
||
9139 | + |
||
9140 | +static struct msm_bus_fab_device_type *get_fab_device_info( |
||
9141 | + struct device_node *dev_node, |
||
9142 | + struct platform_device *pdev) |
||
9143 | +{ |
||
9144 | + struct msm_bus_fab_device_type *fab_dev; |
||
9145 | + unsigned int ret; |
||
9146 | + struct resource *res; |
||
9147 | + const char *base_name; |
||
9148 | + |
||
9149 | + fab_dev = devm_kzalloc(&pdev->dev, |
||
9150 | + sizeof(struct msm_bus_fab_device_type), |
||
9151 | + GFP_KERNEL); |
||
9152 | + if (!fab_dev) { |
||
9153 | + dev_err(&pdev->dev, |
||
9154 | + "Error: Unable to allocate memory for fab_dev\n"); |
||
9155 | + return NULL; |
||
9156 | + } |
||
9157 | + |
||
9158 | + ret = of_property_read_string(dev_node, "qcom,base-name", &base_name); |
||
9159 | + if (ret) { |
||
9160 | + dev_err(&pdev->dev, "Error: Unable to get base address name\n"); |
||
9161 | + goto fab_dev_err; |
||
9162 | + } |
||
9163 | + |
||
9164 | + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, base_name); |
||
9165 | + if (!res) { |
||
9166 | + dev_err(&pdev->dev, "Error getting qos base addr %s\n", |
||
9167 | + base_name); |
||
9168 | + goto fab_dev_err; |
||
9169 | + } |
||
9170 | + fab_dev->pqos_base = res->start; |
||
9171 | + fab_dev->qos_range = resource_size(res); |
||
9172 | + fab_dev->bypass_qos_prg = of_property_read_bool(dev_node, |
||
9173 | + "qcom,bypass-qos-prg"); |
||
9174 | + |
||
9175 | + ret = of_property_read_u32(dev_node, "qcom,base-offset", |
||
9176 | + &fab_dev->base_offset); |
||
9177 | + if (ret) |
||
9178 | + dev_dbg(&pdev->dev, "Bus base offset is missing\n"); |
||
9179 | + |
||
9180 | + ret = of_property_read_u32(dev_node, "qcom,qos-off", |
||
9181 | + &fab_dev->qos_off); |
||
9182 | + if (ret) |
||
9183 | + dev_dbg(&pdev->dev, "Bus qos off is missing\n"); |
||
9184 | + |
||
9185 | + |
||
9186 | + ret = of_property_read_u32(dev_node, "qcom,bus-type", |
||
9187 | + &fab_dev->bus_type); |
||
9188 | + if (ret) { |
||
9189 | + dev_warn(&pdev->dev, "Bus type is missing\n"); |
||
9190 | + goto fab_dev_err; |
||
9191 | + } |
||
9192 | + |
||
9193 | + ret = of_property_read_u32(dev_node, "qcom,qos-freq", |
||
9194 | + &fab_dev->qos_freq); |
||
9195 | + if (ret) { |
||
9196 | + dev_dbg(&pdev->dev, "Bus qos freq is missing\n"); |
||
9197 | + fab_dev->qos_freq = DEFAULT_QOS_FREQ; |
||
9198 | + } |
||
9199 | + |
||
9200 | + ret = of_property_read_u32(dev_node, "qcom,util-fact", |
||
9201 | + &fab_dev->util_fact); |
||
9202 | + if (ret) { |
||
9203 | + dev_info(&pdev->dev, "Util-fact is missing, default to %d\n", |
||
9204 | + DEFAULT_UTIL_FACT); |
||
9205 | + fab_dev->util_fact = DEFAULT_UTIL_FACT; |
||
9206 | + } |
||
9207 | + |
||
9208 | + ret = of_property_read_u32(dev_node, "qcom,vrail-comp", |
||
9209 | + &fab_dev->vrail_comp); |
||
9210 | + if (ret) { |
||
9211 | + dev_info(&pdev->dev, "Vrail-comp is missing, default to %d\n", |
||
9212 | + DEFAULT_VRAIL_COMP); |
||
9213 | + fab_dev->vrail_comp = DEFAULT_VRAIL_COMP; |
||
9214 | + } |
||
9215 | + |
||
9216 | + return fab_dev; |
||
9217 | + |
||
9218 | +fab_dev_err: |
||
9219 | + devm_kfree(&pdev->dev, fab_dev); |
||
9220 | + fab_dev = 0; |
||
9221 | + return NULL; |
||
9222 | +} |
||
9223 | + |
||
9224 | +static void get_qos_params( |
||
9225 | + struct device_node * const dev_node, |
||
9226 | + struct platform_device * const pdev, |
||
9227 | + struct msm_bus_node_info_type *node_info) |
||
9228 | +{ |
||
9229 | + const char *qos_mode = NULL; |
||
9230 | + unsigned int ret; |
||
9231 | + unsigned int temp; |
||
9232 | + |
||
9233 | + ret = of_property_read_string(dev_node, "qcom,qos-mode", &qos_mode); |
||
9234 | + |
||
9235 | + if (ret) |
||
9236 | + node_info->qos_params.mode = -1; |
||
9237 | + else |
||
9238 | + node_info->qos_params.mode = get_qos_mode(pdev, dev_node, |
||
9239 | + qos_mode); |
||
9240 | + |
||
9241 | + of_property_read_u32(dev_node, "qcom,prio-lvl", |
||
9242 | + &node_info->qos_params.prio_lvl); |
||
9243 | + |
||
9244 | + of_property_read_u32(dev_node, "qcom,prio1", |
||
9245 | + &node_info->qos_params.prio1); |
||
9246 | + |
||
9247 | + of_property_read_u32(dev_node, "qcom,prio0", |
||
9248 | + &node_info->qos_params.prio0); |
||
9249 | + |
||
9250 | + of_property_read_u32(dev_node, "qcom,prio-rd", |
||
9251 | + &node_info->qos_params.prio_rd); |
||
9252 | + |
||
9253 | + of_property_read_u32(dev_node, "qcom,prio-wr", |
||
9254 | + &node_info->qos_params.prio_wr); |
||
9255 | + |
||
9256 | + of_property_read_u32(dev_node, "qcom,gp", |
||
9257 | + &node_info->qos_params.gp); |
||
9258 | + |
||
9259 | + of_property_read_u32(dev_node, "qcom,thmp", |
||
9260 | + &node_info->qos_params.thmp); |
||
9261 | + |
||
9262 | + of_property_read_u32(dev_node, "qcom,ws", |
||
9263 | + &node_info->qos_params.ws); |
||
9264 | + |
||
9265 | + ret = of_property_read_u32(dev_node, "qcom,bw_buffer", &temp); |
||
9266 | + |
||
9267 | + if (ret) |
||
9268 | + node_info->qos_params.bw_buffer = 0; |
||
9269 | + else |
||
9270 | + node_info->qos_params.bw_buffer = KBTOB(temp); |
||
9271 | + |
||
9272 | +} |
||
9273 | + |
||
9274 | + |
||
9275 | +static struct msm_bus_node_info_type *get_node_info_data( |
||
9276 | + struct device_node * const dev_node, |
||
9277 | + struct platform_device * const pdev) |
||
9278 | +{ |
||
9279 | + struct msm_bus_node_info_type *node_info; |
||
9280 | + unsigned int ret; |
||
9281 | + int size; |
||
9282 | + int i; |
||
9283 | + struct device_node *con_node; |
||
9284 | + struct device_node *bus_dev; |
||
9285 | + |
||
9286 | + node_info = devm_kzalloc(&pdev->dev, |
||
9287 | + sizeof(struct msm_bus_node_info_type), |
||
9288 | + GFP_KERNEL); |
||
9289 | + if (!node_info) { |
||
9290 | + dev_err(&pdev->dev, |
||
9291 | + "Error: Unable to allocate memory for node_info\n"); |
||
9292 | + return NULL; |
||
9293 | + } |
||
9294 | + |
||
9295 | + ret = of_property_read_u32(dev_node, "cell-id", &node_info->id); |
||
9296 | + if (ret) { |
||
9297 | + dev_warn(&pdev->dev, "Bus node is missing cell-id\n"); |
||
9298 | + goto node_info_err; |
||
9299 | + } |
||
9300 | + ret = of_property_read_string(dev_node, "label", &node_info->name); |
||
9301 | + if (ret) { |
||
9302 | + dev_warn(&pdev->dev, "Bus node is missing name\n"); |
||
9303 | + goto node_info_err; |
||
9304 | + } |
||
9305 | + node_info->qport = get_arr(pdev, dev_node, "qcom,qport", |
||
9306 | + &node_info->num_qports); |
||
9307 | + |
||
9308 | + if (of_get_property(dev_node, "qcom,connections", &size)) { |
||
9309 | + node_info->num_connections = size / sizeof(int); |
||
9310 | + node_info->connections = devm_kzalloc(&pdev->dev, size, |
||
9311 | + GFP_KERNEL); |
||
9312 | + } else { |
||
9313 | + node_info->num_connections = 0; |
||
9314 | + node_info->connections = 0; |
||
9315 | + } |
||
9316 | + |
||
9317 | + for (i = 0; i < node_info->num_connections; i++) { |
||
9318 | + con_node = of_parse_phandle(dev_node, "qcom,connections", i); |
||
9319 | + if (IS_ERR_OR_NULL(con_node)) |
||
9320 | + goto node_info_err; |
||
9321 | + |
||
9322 | + if (of_property_read_u32(con_node, "cell-id", |
||
9323 | + &node_info->connections[i])) |
||
9324 | + goto node_info_err; |
||
9325 | + of_node_put(con_node); |
||
9326 | + } |
||
9327 | + |
||
9328 | + if (of_get_property(dev_node, "qcom,blacklist", &size)) { |
||
9329 | + node_info->num_blist = size/sizeof(u32); |
||
9330 | + node_info->black_listed_connections = devm_kzalloc(&pdev->dev, |
||
9331 | + size, GFP_KERNEL); |
||
9332 | + } else { |
||
9333 | + node_info->num_blist = 0; |
||
9334 | + node_info->black_listed_connections = 0; |
||
9335 | + } |
||
9336 | + |
||
9337 | + for (i = 0; i < node_info->num_blist; i++) { |
||
9338 | + con_node = of_parse_phandle(dev_node, "qcom,blacklist", i); |
||
9339 | + if (IS_ERR_OR_NULL(con_node)) |
||
9340 | + goto node_info_err; |
||
9341 | + |
||
9342 | + if (of_property_read_u32(con_node, "cell-id", |
||
9343 | + &node_info->black_listed_connections[i])) |
||
9344 | + goto node_info_err; |
||
9345 | + of_node_put(con_node); |
||
9346 | + } |
||
9347 | + |
||
9348 | + bus_dev = of_parse_phandle(dev_node, "qcom,bus-dev", 0); |
||
9349 | + if (!IS_ERR_OR_NULL(bus_dev)) { |
||
9350 | + if (of_property_read_u32(bus_dev, "cell-id", |
||
9351 | + &node_info->bus_device_id)) { |
||
9352 | + dev_err(&pdev->dev, "Can't find bus device. Node %d", |
||
9353 | + node_info->id); |
||
9354 | + goto node_info_err; |
||
9355 | + } |
||
9356 | + |
||
9357 | + of_node_put(bus_dev); |
||
9358 | + } else |
||
9359 | + dev_dbg(&pdev->dev, "Can't find bdev phandle for %d", |
||
9360 | + node_info->id); |
||
9361 | + |
||
9362 | + node_info->is_fab_dev = of_property_read_bool(dev_node, "qcom,fab-dev"); |
||
9363 | + node_info->virt_dev = of_property_read_bool(dev_node, "qcom,virt-dev"); |
||
9364 | + |
||
9365 | + ret = of_property_read_u32(dev_node, "qcom,buswidth", |
||
9366 | + &node_info->buswidth); |
||
9367 | + if (ret) { |
||
9368 | + dev_dbg(&pdev->dev, "Using default 8 bytes %d", node_info->id); |
||
9369 | + node_info->buswidth = 8; |
||
9370 | + } |
||
9371 | + |
||
9372 | + ret = of_property_read_u32(dev_node, "qcom,mas-rpm-id", |
||
9373 | + &node_info->mas_rpm_id); |
||
9374 | + if (ret) { |
||
9375 | + dev_dbg(&pdev->dev, "mas rpm id is missing\n"); |
||
9376 | + node_info->mas_rpm_id = -1; |
||
9377 | + } |
||
9378 | + |
||
9379 | + ret = of_property_read_u32(dev_node, "qcom,slv-rpm-id", |
||
9380 | + &node_info->slv_rpm_id); |
||
9381 | + if (ret) { |
||
9382 | + dev_dbg(&pdev->dev, "slv rpm id is missing\n"); |
||
9383 | + node_info->slv_rpm_id = -1; |
||
9384 | + } |
||
9385 | + ret = of_property_read_u32(dev_node, "qcom,util-fact", |
||
9386 | + &node_info->util_fact); |
||
9387 | + if (ret) |
||
9388 | + node_info->util_fact = 0; |
||
9389 | + ret = of_property_read_u32(dev_node, "qcom,vrail-comp", |
||
9390 | + &node_info->vrail_comp); |
||
9391 | + if (ret) |
||
9392 | + node_info->vrail_comp = 0; |
||
9393 | + get_qos_params(dev_node, pdev, node_info); |
||
9394 | + |
||
9395 | + return node_info; |
||
9396 | + |
||
9397 | +node_info_err: |
||
9398 | + devm_kfree(&pdev->dev, node_info); |
||
9399 | + node_info = 0; |
||
9400 | + return NULL; |
||
9401 | +} |
||
9402 | + |
||
9403 | +static unsigned int get_bus_node_device_data( |
||
9404 | + struct device_node * const dev_node, |
||
9405 | + struct platform_device * const pdev, |
||
9406 | + struct msm_bus_node_device_type * const node_device) |
||
9407 | +{ |
||
9408 | + node_device->node_info = get_node_info_data(dev_node, pdev); |
||
9409 | + if (IS_ERR_OR_NULL(node_device->node_info)) { |
||
9410 | + dev_err(&pdev->dev, "Error: Node info missing\n"); |
||
9411 | + return -ENODATA; |
||
9412 | + } |
||
9413 | + node_device->ap_owned = of_property_read_bool(dev_node, |
||
9414 | + "qcom,ap-owned"); |
||
9415 | + |
||
9416 | + if (node_device->node_info->is_fab_dev) { |
||
9417 | + dev_dbg(&pdev->dev, "Dev %d\n", node_device->node_info->id); |
||
9418 | + |
||
9419 | + if (!node_device->node_info->virt_dev) { |
||
9420 | + node_device->fabdev = |
||
9421 | + get_fab_device_info(dev_node, pdev); |
||
9422 | + if (IS_ERR_OR_NULL(node_device->fabdev)) { |
||
9423 | + dev_err(&pdev->dev, |
||
9424 | + "Error: Fabric device info missing\n"); |
||
9425 | + devm_kfree(&pdev->dev, node_device->node_info); |
||
9426 | + return -ENODATA; |
||
9427 | + } |
||
9428 | + } |
||
9429 | + node_device->clk[DUAL_CTX].clk = of_clk_get_by_name(dev_node, |
||
9430 | + "bus_clk"); |
||
9431 | + |
||
9432 | + if (IS_ERR_OR_NULL(node_device->clk[DUAL_CTX].clk)) |
||
9433 | + dev_dbg(&pdev->dev, |
||
9434 | + "%s:Failed to get bus clk for bus%d ctx%d", |
||
9435 | + __func__, node_device->node_info->id, |
||
9436 | + DUAL_CTX); |
||
9437 | + |
||
9438 | + node_device->clk[ACTIVE_CTX].clk = of_clk_get_by_name(dev_node, |
||
9439 | + "bus_a_clk"); |
||
9440 | + if (IS_ERR_OR_NULL(node_device->clk[ACTIVE_CTX].clk)) |
||
9441 | + dev_err(&pdev->dev, |
||
9442 | + "Failed to get bus clk for bus%d ctx%d", |
||
9443 | + node_device->node_info->id, ACTIVE_CTX); |
||
9444 | + if (msmbus_coresight_init_adhoc(pdev, dev_node)) |
||
9445 | + dev_warn(&pdev->dev, |
||
9446 | + "Coresight support absent for bus: %d\n", |
||
9447 | + node_device->node_info->id); |
||
9448 | + } else { |
||
9449 | + node_device->qos_clk.clk = of_clk_get_by_name(dev_node, |
||
9450 | + "bus_qos_clk"); |
||
9451 | + |
||
9452 | + if (IS_ERR_OR_NULL(node_device->qos_clk.clk)) |
||
9453 | + dev_dbg(&pdev->dev, |
||
9454 | + "%s:Failed to get bus qos clk for mas%d", |
||
9455 | + __func__, node_device->node_info->id); |
||
9456 | + |
||
9457 | + node_device->clk[DUAL_CTX].clk = of_clk_get_by_name(dev_node, |
||
9458 | + "node_clk"); |
||
9459 | + |
||
9460 | + if (IS_ERR_OR_NULL(node_device->clk[DUAL_CTX].clk)) |
||
9461 | + dev_dbg(&pdev->dev, |
||
9462 | + "%s:Failed to get bus clk for bus%d ctx%d", |
||
9463 | + __func__, node_device->node_info->id, |
||
9464 | + DUAL_CTX); |
||
9465 | + |
||
9466 | + } |
||
9467 | + return 0; |
||
9468 | +} |
||
9469 | + |
||
9470 | +struct msm_bus_device_node_registration |
||
9471 | + *msm_bus_of_to_pdata(struct platform_device *pdev) |
||
9472 | +{ |
||
9473 | + struct device_node *of_node, *child_node; |
||
9474 | + struct msm_bus_device_node_registration *pdata; |
||
9475 | + unsigned int i = 0, j; |
||
9476 | + unsigned int ret; |
||
9477 | + |
||
9478 | + if (!pdev) { |
||
9479 | + pr_err("Error: Null platform device\n"); |
||
9480 | + return NULL; |
||
9481 | + } |
||
9482 | + |
||
9483 | + of_node = pdev->dev.of_node; |
||
9484 | + |
||
9485 | + pdata = devm_kzalloc(&pdev->dev, |
||
9486 | + sizeof(struct msm_bus_device_node_registration), |
||
9487 | + GFP_KERNEL); |
||
9488 | + if (!pdata) { |
||
9489 | + dev_err(&pdev->dev, |
||
9490 | + "Error: Memory allocation for pdata failed\n"); |
||
9491 | + return NULL; |
||
9492 | + } |
||
9493 | + |
||
9494 | + pdata->num_devices = of_get_child_count(of_node); |
||
9495 | + |
||
9496 | + pdata->info = devm_kzalloc(&pdev->dev, |
||
9497 | + sizeof(struct msm_bus_node_device_type) * |
||
9498 | + pdata->num_devices, GFP_KERNEL); |
||
9499 | + |
||
9500 | + if (!pdata->info) { |
||
9501 | + dev_err(&pdev->dev, |
||
9502 | + "Error: Memory allocation for pdata->info failed\n"); |
||
9503 | + goto node_reg_err; |
||
9504 | + } |
||
9505 | + |
||
9506 | + ret = 0; |
||
9507 | + for_each_child_of_node(of_node, child_node) { |
||
9508 | + ret = get_bus_node_device_data(child_node, pdev, |
||
9509 | + &pdata->info[i]); |
||
9510 | + if (ret) { |
||
9511 | + dev_err(&pdev->dev, "Error: unable to initialize bus nodes\n"); |
||
9512 | + goto node_reg_err_1; |
||
9513 | + } |
||
9514 | + i++; |
||
9515 | + } |
||
9516 | + |
||
9517 | + dev_dbg(&pdev->dev, "bus topology:\n"); |
||
9518 | + for (i = 0; i < pdata->num_devices; i++) { |
||
9519 | + dev_dbg(&pdev->dev, "id %d\nnum_qports %d\nnum_connections %d", |
||
9520 | + pdata->info[i].node_info->id, |
||
9521 | + pdata->info[i].node_info->num_qports, |
||
9522 | + pdata->info[i].node_info->num_connections); |
||
9523 | + dev_dbg(&pdev->dev, "\nbus_device_id %d\n buswidth %d\n", |
||
9524 | + pdata->info[i].node_info->bus_device_id, |
||
9525 | + pdata->info[i].node_info->buswidth); |
||
9526 | + for (j = 0; j < pdata->info[i].node_info->num_connections; |
||
9527 | + j++) { |
||
9528 | + dev_dbg(&pdev->dev, "connection[%d]: %d\n", j, |
||
9529 | + pdata->info[i].node_info->connections[j]); |
||
9530 | + } |
||
9531 | + for (j = 0; j < pdata->info[i].node_info->num_blist; |
||
9532 | + j++) { |
||
9533 | + dev_dbg(&pdev->dev, "black_listed_node[%d]: %d\n", j, |
||
9534 | + pdata->info[i].node_info-> |
||
9535 | + black_listed_connections[j]); |
||
9536 | + } |
||
9537 | + if (pdata->info[i].fabdev) |
||
9538 | + dev_dbg(&pdev->dev, "base_addr %zu\nbus_type %d\n", |
||
9539 | + (size_t)pdata->info[i]. |
||
9540 | + fabdev->pqos_base, |
||
9541 | + pdata->info[i].fabdev->bus_type); |
||
9542 | + } |
||
9543 | + return pdata; |
||
9544 | + |
||
9545 | +node_reg_err_1: |
||
9546 | + devm_kfree(&pdev->dev, pdata->info); |
||
9547 | +node_reg_err: |
||
9548 | + devm_kfree(&pdev->dev, pdata); |
||
9549 | + pdata = NULL; |
||
9550 | + return NULL; |
||
9551 | +} |
||
9552 | + |
||
9553 | +static int msm_bus_of_get_ids(struct platform_device *pdev, |
||
9554 | + struct device_node *dev_node, int **dev_ids, |
||
9555 | + int *num_ids, char *prop_name) |
||
9556 | +{ |
||
9557 | + int ret = 0; |
||
9558 | + int size, i; |
||
9559 | + struct device_node *rule_node; |
||
9560 | + int *ids = NULL; |
||
9561 | + |
||
9562 | + if (of_get_property(dev_node, prop_name, &size)) { |
||
9563 | + *num_ids = size / sizeof(int); |
||
9564 | + ids = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); |
||
9565 | + } else { |
||
9566 | + dev_err(&pdev->dev, "No rule nodes, skipping node"); |
||
9567 | + ret = -ENXIO; |
||
9568 | + goto exit_get_ids; |
||
9569 | + } |
||
9570 | + |
||
9571 | + *dev_ids = ids; |
||
9572 | + for (i = 0; i < *num_ids; i++) { |
||
9573 | + rule_node = of_parse_phandle(dev_node, prop_name, i); |
||
9574 | + if (IS_ERR_OR_NULL(rule_node)) { |
||
9575 | + dev_err(&pdev->dev, "Can't get rule node id"); |
||
9576 | + ret = -ENXIO; |
||
9577 | + goto err_get_ids; |
||
9578 | + } |
||
9579 | + |
||
9580 | + if (of_property_read_u32(rule_node, "cell-id", |
||
9581 | + &ids[i])) { |
||
9582 | + dev_err(&pdev->dev, "Can't get rule node id"); |
||
9583 | + ret = -ENXIO; |
||
9584 | + goto err_get_ids; |
||
9585 | + } |
||
9586 | + of_node_put(rule_node); |
||
9587 | + } |
||
9588 | +exit_get_ids: |
||
9589 | + return ret; |
||
9590 | +err_get_ids: |
||
9591 | + devm_kfree(&pdev->dev, ids); |
||
9592 | + of_node_put(rule_node); |
||
9593 | + ids = NULL; |
||
9594 | + return ret; |
||
9595 | +} |
||
9596 | + |
||
9597 | +int msm_bus_of_get_static_rules(struct platform_device *pdev, |
||
9598 | + struct bus_rule_type **static_rules) |
||
9599 | +{ |
||
9600 | + int ret = 0; |
||
9601 | + struct device_node *of_node, *child_node; |
||
9602 | + int num_rules = 0; |
||
9603 | + int rule_idx = 0; |
||
9604 | + int bw_fld = 0; |
||
9605 | + int i; |
||
9606 | + struct bus_rule_type *static_rule = NULL; |
||
9607 | + |
||
9608 | + of_node = pdev->dev.of_node; |
||
9609 | + num_rules = of_get_child_count(of_node); |
||
9610 | + static_rule = devm_kzalloc(&pdev->dev, |
||
9611 | + sizeof(struct bus_rule_type) * num_rules, |
||
9612 | + GFP_KERNEL); |
||
9613 | + |
||
9614 | + if (IS_ERR_OR_NULL(static_rule)) { |
||
9615 | + ret = -ENOMEM; |
||
9616 | + goto exit_static_rules; |
||
9617 | + } |
||
9618 | + |
||
9619 | + *static_rules = static_rule; |
||
9620 | + for_each_child_of_node(of_node, child_node) { |
||
9621 | + ret = msm_bus_of_get_ids(pdev, child_node, |
||
9622 | + &static_rule[rule_idx].src_id, |
||
9623 | + &static_rule[rule_idx].num_src, |
||
9624 | + "qcom,src-nodes"); |
||
9625 | + |
||
9626 | + ret = msm_bus_of_get_ids(pdev, child_node, |
||
9627 | + &static_rule[rule_idx].dst_node, |
||
9628 | + &static_rule[rule_idx].num_dst, |
||
9629 | + "qcom,dest-node"); |
||
9630 | + |
||
9631 | + ret = of_property_read_u32(child_node, "qcom,src-field", |
||
9632 | + &static_rule[rule_idx].src_field); |
||
9633 | + if (ret) { |
||
9634 | + dev_err(&pdev->dev, "src-field missing"); |
||
9635 | + ret = -ENXIO; |
||
9636 | + goto err_static_rules; |
||
9637 | + } |
||
9638 | + |
||
9639 | + ret = of_property_read_u32(child_node, "qcom,src-op", |
||
9640 | + &static_rule[rule_idx].op); |
||
9641 | + if (ret) { |
||
9642 | + dev_err(&pdev->dev, "src-op missing"); |
||
9643 | + ret = -ENXIO; |
||
9644 | + goto err_static_rules; |
||
9645 | + } |
||
9646 | + |
||
9647 | + ret = of_property_read_u32(child_node, "qcom,mode", |
||
9648 | + &static_rule[rule_idx].mode); |
||
9649 | + if (ret) { |
||
9650 | + dev_err(&pdev->dev, "mode missing"); |
||
9651 | + ret = -ENXIO; |
||
9652 | + goto err_static_rules; |
||
9653 | + } |
||
9654 | + |
||
9655 | + ret = of_property_read_u32(child_node, "qcom,thresh", &bw_fld); |
||
9656 | + if (ret) { |
||
9657 | + dev_err(&pdev->dev, "thresh missing"); |
||
9658 | + ret = -ENXIO; |
||
9659 | + goto err_static_rules; |
||
9660 | + } else |
||
9661 | + static_rule[rule_idx].thresh = KBTOB(bw_fld); |
||
9662 | + |
||
9663 | + ret = of_property_read_u32(child_node, "qcom,dest-bw", |
||
9664 | + &bw_fld); |
||
9665 | + if (ret) |
||
9666 | + static_rule[rule_idx].dst_bw = 0; |
||
9667 | + else |
||
9668 | + static_rule[rule_idx].dst_bw = KBTOB(bw_fld); |
||
9669 | + |
||
9670 | + rule_idx++; |
||
9671 | + } |
||
9672 | + ret = rule_idx; |
||
9673 | +exit_static_rules: |
||
9674 | + return ret; |
||
9675 | +err_static_rules: |
||
9676 | + for (i = 0; i < num_rules; i++) { |
||
9677 | + if (!IS_ERR_OR_NULL(static_rule)) { |
||
9678 | + if (!IS_ERR_OR_NULL(static_rule[i].src_id)) |
||
9679 | + devm_kfree(&pdev->dev, |
||
9680 | + static_rule[i].src_id); |
||
9681 | + if (!IS_ERR_OR_NULL(static_rule[i].dst_node)) |
||
9682 | + devm_kfree(&pdev->dev, |
||
9683 | + static_rule[i].dst_node); |
||
9684 | + devm_kfree(&pdev->dev, static_rule); |
||
9685 | + } |
||
9686 | + } |
||
9687 | + devm_kfree(&pdev->dev, *static_rules); |
||
9688 | + static_rules = NULL; |
||
9689 | + return ret; |
||
9690 | +} |
||
9691 | --- /dev/null |
||
9692 | +++ b/drivers/bus/msm_bus/msm_bus_rules.c |
||
9693 | @@ -0,0 +1,624 @@ |
||
9694 | +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. |
||
9695 | + * |
||
9696 | + * This program is free software; you can redistribute it and/or modify |
||
9697 | + * it under the terms of the GNU General Public License version 2 and |
||
9698 | + * only version 2 as published by the Free Software Foundation. |
||
9699 | + * |
||
9700 | + * This program is distributed in the hope that it will be useful, |
||
9701 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
9702 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
9703 | + * GNU General Public License for more details. |
||
9704 | + */ |
||
9705 | + |
||
9706 | +#include <linux/list_sort.h> |
||
9707 | +#include <linux/slab.h> |
||
9708 | +#include <linux/types.h> |
||
9709 | +#include "msm-bus-board.h" |
||
9710 | +#include "msm_bus_rules.h" |
||
9711 | +#include <trace/events/trace_msm_bus.h> |
||
9712 | + |
||
9713 | +struct node_vote_info { |
||
9714 | + int id; |
||
9715 | + u64 ib; |
||
9716 | + u64 ab; |
||
9717 | + u64 clk; |
||
9718 | +}; |
||
9719 | + |
||
9720 | +struct rules_def { |
||
9721 | + int rule_id; |
||
9722 | + int num_src; |
||
9723 | + int state; |
||
9724 | + struct node_vote_info *src_info; |
||
9725 | + struct bus_rule_type rule_ops; |
||
9726 | + bool state_change; |
||
9727 | + struct list_head link; |
||
9728 | +}; |
||
9729 | + |
||
9730 | +struct rule_node_info { |
||
9731 | + int id; |
||
9732 | + void *data; |
||
9733 | + struct raw_notifier_head rule_notify_list; |
||
9734 | + int cur_rule; |
||
9735 | + int num_rules; |
||
9736 | + struct list_head node_rules; |
||
9737 | + struct list_head link; |
||
9738 | + struct rule_apply_rcm_info apply; |
||
9739 | +}; |
||
9740 | + |
||
9741 | +DEFINE_MUTEX(msm_bus_rules_lock); |
||
9742 | +static LIST_HEAD(node_list); |
||
9743 | +static struct rule_node_info *get_node(u32 id, void *data); |
||
9744 | + |
||
9745 | +#define LE(op1, op2) (op1 <= op2) |
||
9746 | +#define LT(op1, op2) (op1 < op2) |
||
9747 | +#define GE(op1, op2) (op1 >= op2) |
||
9748 | +#define GT(op1, op2) (op1 > op2) |
||
9749 | +#define NB_ID (0x201) |
||
9750 | + |
||
9751 | +static struct rule_node_info *get_node(u32 id, void *data) |
||
9752 | +{ |
||
9753 | + struct rule_node_info *node_it = NULL; |
||
9754 | + struct rule_node_info *node_match = NULL; |
||
9755 | + |
||
9756 | + list_for_each_entry(node_it, &node_list, link) { |
||
9757 | + if (node_it->id == id) { |
||
9758 | + if ((id == NB_ID)) { |
||
9759 | + if ((node_it->data == data)) { |
||
9760 | + node_match = node_it; |
||
9761 | + break; |
||
9762 | + } |
||
9763 | + } else { |
||
9764 | + node_match = node_it; |
||
9765 | + break; |
||
9766 | + } |
||
9767 | + } |
||
9768 | + } |
||
9769 | + return node_match; |
||
9770 | +} |
||
9771 | + |
||
9772 | +static struct rule_node_info *gen_node(u32 id, void *data) |
||
9773 | +{ |
||
9774 | + struct rule_node_info *node_it = NULL; |
||
9775 | + struct rule_node_info *node_match = NULL; |
||
9776 | + |
||
9777 | + list_for_each_entry(node_it, &node_list, link) { |
||
9778 | + if (node_it->id == id) { |
||
9779 | + node_match = node_it; |
||
9780 | + break; |
||
9781 | + } |
||
9782 | + } |
||
9783 | + |
||
9784 | + if (!node_match) { |
||
9785 | + node_match = kzalloc(sizeof(struct rule_node_info), GFP_KERNEL); |
||
9786 | + if (!node_match) { |
||
9787 | + pr_err("%s: Cannot allocate memory", __func__); |
||
9788 | + goto exit_node_match; |
||
9789 | + } |
||
9790 | + |
||
9791 | + node_match->id = id; |
||
9792 | + node_match->cur_rule = -1; |
||
9793 | + node_match->num_rules = 0; |
||
9794 | + node_match->data = data; |
||
9795 | + list_add_tail(&node_match->link, &node_list); |
||
9796 | + INIT_LIST_HEAD(&node_match->node_rules); |
||
9797 | + RAW_INIT_NOTIFIER_HEAD(&node_match->rule_notify_list); |
||
9798 | + pr_debug("Added new node %d to list\n", id); |
||
9799 | + } |
||
9800 | +exit_node_match: |
||
9801 | + return node_match; |
||
9802 | +} |
||
9803 | + |
||
9804 | +static bool do_compare_op(u64 op1, u64 op2, int op) |
||
9805 | +{ |
||
9806 | + bool ret = false; |
||
9807 | + |
||
9808 | + switch (op) { |
||
9809 | + case OP_LE: |
||
9810 | + ret = LE(op1, op2); |
||
9811 | + break; |
||
9812 | + case OP_LT: |
||
9813 | + ret = LT(op1, op2); |
||
9814 | + break; |
||
9815 | + case OP_GT: |
||
9816 | + ret = GT(op1, op2); |
||
9817 | + break; |
||
9818 | + case OP_GE: |
||
9819 | + ret = GE(op1, op2); |
||
9820 | + break; |
||
9821 | + case OP_NOOP: |
||
9822 | + ret = true; |
||
9823 | + break; |
||
9824 | + default: |
||
9825 | + pr_info("Invalid OP %d", op); |
||
9826 | + break; |
||
9827 | + } |
||
9828 | + return ret; |
||
9829 | +} |
||
9830 | + |
||
9831 | +static void update_src_id_vote(struct rule_update_path_info *inp_node, |
||
9832 | + struct rule_node_info *rule_node) |
||
9833 | +{ |
||
9834 | + struct rules_def *rule; |
||
9835 | + int i; |
||
9836 | + |
||
9837 | + list_for_each_entry(rule, &rule_node->node_rules, link) { |
||
9838 | + for (i = 0; i < rule->num_src; i++) { |
||
9839 | + if (rule->src_info[i].id == inp_node->id) { |
||
9840 | + rule->src_info[i].ib = inp_node->ib; |
||
9841 | + rule->src_info[i].ab = inp_node->ab; |
||
9842 | + rule->src_info[i].clk = inp_node->clk; |
||
9843 | + } |
||
9844 | + } |
||
9845 | + } |
||
9846 | +} |
||
9847 | + |
||
9848 | +static u64 get_field(struct rules_def *rule, int src_id) |
||
9849 | +{ |
||
9850 | + u64 field = 0; |
||
9851 | + int i; |
||
9852 | + |
||
9853 | + for (i = 0; i < rule->num_src; i++) { |
||
9854 | + switch (rule->rule_ops.src_field) { |
||
9855 | + case FLD_IB: |
||
9856 | + field += rule->src_info[i].ib; |
||
9857 | + break; |
||
9858 | + case FLD_AB: |
||
9859 | + field += rule->src_info[i].ab; |
||
9860 | + break; |
||
9861 | + case FLD_CLK: |
||
9862 | + field += rule->src_info[i].clk; |
||
9863 | + break; |
||
9864 | + } |
||
9865 | + } |
||
9866 | + |
||
9867 | + return field; |
||
9868 | +} |
||
9869 | + |
||
9870 | +static bool check_rule(struct rules_def *rule, |
||
9871 | + struct rule_update_path_info *inp) |
||
9872 | +{ |
||
9873 | + bool ret = false; |
||
9874 | + |
||
9875 | + if (!rule) |
||
9876 | + return ret; |
||
9877 | + |
||
9878 | + switch (rule->rule_ops.op) { |
||
9879 | + case OP_LE: |
||
9880 | + case OP_LT: |
||
9881 | + case OP_GT: |
||
9882 | + case OP_GE: |
||
9883 | + { |
||
9884 | + u64 src_field = get_field(rule, inp->id); |
||
9885 | + if (!src_field) |
||
9886 | + ret = false; |
||
9887 | + else |
||
9888 | + ret = do_compare_op(src_field, rule->rule_ops.thresh, |
||
9889 | + rule->rule_ops.op); |
||
9890 | + break; |
||
9891 | + } |
||
9892 | + default: |
||
9893 | + pr_err("Unsupported op %d", rule->rule_ops.op); |
||
9894 | + break; |
||
9895 | + } |
||
9896 | + return ret; |
||
9897 | +} |
||
9898 | + |
||
9899 | +static void match_rule(struct rule_update_path_info *inp_node, |
||
9900 | + struct rule_node_info *node) |
||
9901 | +{ |
||
9902 | + struct rules_def *rule; |
||
9903 | + int i; |
||
9904 | + |
||
9905 | + list_for_each_entry(rule, &node->node_rules, link) { |
||
9906 | + for (i = 0; i < rule->num_src; i++) { |
||
9907 | + if (rule->src_info[i].id == inp_node->id) { |
||
9908 | + if (check_rule(rule, inp_node)) { |
||
9909 | + trace_bus_rules_matches(node->cur_rule, |
||
9910 | + inp_node->id, inp_node->ab, |
||
9911 | + inp_node->ib, inp_node->clk); |
||
9912 | + if (rule->state == |
||
9913 | + RULE_STATE_NOT_APPLIED) |
||
9914 | + rule->state_change = true; |
||
9915 | + rule->state = RULE_STATE_APPLIED; |
||
9916 | + } else { |
||
9917 | + if (rule->state == |
||
9918 | + RULE_STATE_APPLIED) |
||
9919 | + rule->state_change = true; |
||
9920 | + rule->state = RULE_STATE_NOT_APPLIED; |
||
9921 | + } |
||
9922 | + } |
||
9923 | + } |
||
9924 | + } |
||
9925 | +} |
||
9926 | + |
||
9927 | +static void apply_rule(struct rule_node_info *node, |
||
9928 | + struct list_head *output_list) |
||
9929 | +{ |
||
9930 | + struct rules_def *rule; |
||
9931 | + |
||
9932 | + node->cur_rule = -1; |
||
9933 | + list_for_each_entry(rule, &node->node_rules, link) { |
||
9934 | + if ((rule->state == RULE_STATE_APPLIED) && |
||
9935 | + (node->cur_rule == -1)) |
||
9936 | + node->cur_rule = rule->rule_id; |
||
9937 | + |
||
9938 | + if (node->id == NB_ID) { |
||
9939 | + if (rule->state_change) { |
||
9940 | + rule->state_change = false; |
||
9941 | + raw_notifier_call_chain(&node->rule_notify_list, |
||
9942 | + rule->state, (void *)&rule->rule_ops); |
||
9943 | + } |
||
9944 | + } else { |
||
9945 | + if ((rule->state == RULE_STATE_APPLIED) && |
||
9946 | + (node->cur_rule == rule->rule_id)) { |
||
9947 | + node->apply.id = rule->rule_ops.dst_node[0]; |
||
9948 | + node->apply.throttle = rule->rule_ops.mode; |
||
9949 | + node->apply.lim_bw = rule->rule_ops.dst_bw; |
||
9950 | + list_add_tail(&node->apply.link, output_list); |
||
9951 | + } |
||
9952 | + rule->state_change = false; |
||
9953 | + } |
||
9954 | + } |
||
9955 | + |
||
9956 | +} |
||
9957 | + |
||
9958 | +int msm_rules_update_path(struct list_head *input_list, |
||
9959 | + struct list_head *output_list) |
||
9960 | +{ |
||
9961 | + int ret = 0; |
||
9962 | + struct rule_update_path_info *inp_node; |
||
9963 | + struct rule_node_info *node_it = NULL; |
||
9964 | + |
||
9965 | + mutex_lock(&msm_bus_rules_lock); |
||
9966 | + list_for_each_entry(inp_node, input_list, link) { |
||
9967 | + list_for_each_entry(node_it, &node_list, link) { |
||
9968 | + update_src_id_vote(inp_node, node_it); |
||
9969 | + match_rule(inp_node, node_it); |
||
9970 | + } |
||
9971 | + } |
||
9972 | + |
||
9973 | + list_for_each_entry(node_it, &node_list, link) |
||
9974 | + apply_rule(node_it, output_list); |
||
9975 | + |
||
9976 | + mutex_unlock(&msm_bus_rules_lock); |
||
9977 | + return ret; |
||
9978 | +} |
||
9979 | + |
||
9980 | +static bool ops_equal(int op1, int op2) |
||
9981 | +{ |
||
9982 | + bool ret = false; |
||
9983 | + |
||
9984 | + switch (op1) { |
||
9985 | + case OP_GT: |
||
9986 | + case OP_GE: |
||
9987 | + case OP_LT: |
||
9988 | + case OP_LE: |
||
9989 | + if (abs(op1 - op2) <= 1) |
||
9990 | + ret = true; |
||
9991 | + break; |
||
9992 | + default: |
||
9993 | + ret = (op1 == op2); |
||
9994 | + } |
||
9995 | + |
||
9996 | + return ret; |
||
9997 | +} |
||
9998 | + |
||
9999 | +static int node_rules_compare(void *priv, struct list_head *a, |
||
10000 | + struct list_head *b) |
||
10001 | +{ |
||
10002 | + struct rules_def *ra = container_of(a, struct rules_def, link); |
||
10003 | + struct rules_def *rb = container_of(b, struct rules_def, link); |
||
10004 | + int ret = -1; |
||
10005 | + int64_t th_diff = 0; |
||
10006 | + |
||
10007 | + |
||
10008 | + if (ra->rule_ops.mode == rb->rule_ops.mode) { |
||
10009 | + if (ops_equal(ra->rule_ops.op, rb->rule_ops.op)) { |
||
10010 | + if ((ra->rule_ops.op == OP_LT) || |
||
10011 | + (ra->rule_ops.op == OP_LE)) { |
||
10012 | + th_diff = ra->rule_ops.thresh - |
||
10013 | + rb->rule_ops.thresh; |
||
10014 | + if (th_diff > 0) |
||
10015 | + ret = 1; |
||
10016 | + else |
||
10017 | + ret = -1; |
||
10018 | + } else if ((ra->rule_ops.op == OP_GT) || |
||
10019 | + (ra->rule_ops.op == OP_GE)) { |
||
10020 | + th_diff = rb->rule_ops.thresh - |
||
10021 | + ra->rule_ops.thresh; |
||
10022 | + if (th_diff > 0) |
||
10023 | + ret = 1; |
||
10024 | + else |
||
10025 | + ret = -1; |
||
10026 | + } |
||
10027 | + } else |
||
10028 | + ret = ra->rule_ops.op - rb->rule_ops.op; |
||
10029 | + } else if ((ra->rule_ops.mode == THROTTLE_OFF) && |
||
10030 | + (rb->rule_ops.mode == THROTTLE_ON)) { |
||
10031 | + ret = 1; |
||
10032 | + } else if ((ra->rule_ops.mode == THROTTLE_ON) && |
||
10033 | + (rb->rule_ops.mode == THROTTLE_OFF)) { |
||
10034 | + ret = -1; |
||
10035 | + } |
||
10036 | + |
||
10037 | + return ret; |
||
10038 | +} |
||
10039 | + |
||
10040 | +static void print_rules(struct rule_node_info *node_it) |
||
10041 | +{ |
||
10042 | + struct rules_def *node_rule = NULL; |
||
10043 | + int i; |
||
10044 | + |
||
10045 | + if (!node_it) { |
||
10046 | + pr_err("%s: no node for found", __func__); |
||
10047 | + return; |
||
10048 | + } |
||
10049 | + |
||
10050 | + pr_info("\n Now printing rules for Node %d cur rule %d\n", |
||
10051 | + node_it->id, node_it->cur_rule); |
||
10052 | + list_for_each_entry(node_rule, &node_it->node_rules, link) { |
||
10053 | + pr_info("\n num Rules %d rule Id %d\n", |
||
10054 | + node_it->num_rules, node_rule->rule_id); |
||
10055 | + pr_info("Rule: src_field %d\n", node_rule->rule_ops.src_field); |
||
10056 | + for (i = 0; i < node_rule->rule_ops.num_src; i++) |
||
10057 | + pr_info("Rule: src %d\n", |
||
10058 | + node_rule->rule_ops.src_id[i]); |
||
10059 | + for (i = 0; i < node_rule->rule_ops.num_dst; i++) |
||
10060 | + pr_info("Rule: dst %d dst_bw %llu\n", |
||
10061 | + node_rule->rule_ops.dst_node[i], |
||
10062 | + node_rule->rule_ops.dst_bw); |
||
10063 | + pr_info("Rule: thresh %llu op %d mode %d State %d\n", |
||
10064 | + node_rule->rule_ops.thresh, |
||
10065 | + node_rule->rule_ops.op, |
||
10066 | + node_rule->rule_ops.mode, |
||
10067 | + node_rule->state); |
||
10068 | + } |
||
10069 | +} |
||
10070 | + |
||
10071 | +void print_all_rules(void) |
||
10072 | +{ |
||
10073 | + struct rule_node_info *node_it = NULL; |
||
10074 | + |
||
10075 | + list_for_each_entry(node_it, &node_list, link) |
||
10076 | + print_rules(node_it); |
||
10077 | +} |
||
10078 | + |
||
10079 | +void print_rules_buf(char *buf, int max_buf) |
||
10080 | +{ |
||
10081 | + struct rule_node_info *node_it = NULL; |
||
10082 | + struct rules_def *node_rule = NULL; |
||
10083 | + int i; |
||
10084 | + int cnt = 0; |
||
10085 | + |
||
10086 | + list_for_each_entry(node_it, &node_list, link) { |
||
10087 | + cnt += scnprintf(buf + cnt, max_buf - cnt, |
||
10088 | + "\n Now printing rules for Node %d cur_rule %d\n", |
||
10089 | + node_it->id, node_it->cur_rule); |
||
10090 | + list_for_each_entry(node_rule, &node_it->node_rules, link) { |
||
10091 | + cnt += scnprintf(buf + cnt, max_buf - cnt, |
||
10092 | + "\nNum Rules:%d ruleId %d STATE:%d change:%d\n", |
||
10093 | + node_it->num_rules, node_rule->rule_id, |
||
10094 | + node_rule->state, node_rule->state_change); |
||
10095 | + cnt += scnprintf(buf + cnt, max_buf - cnt, |
||
10096 | + "Src_field %d\n", |
||
10097 | + node_rule->rule_ops.src_field); |
||
10098 | + for (i = 0; i < node_rule->rule_ops.num_src; i++) |
||
10099 | + cnt += scnprintf(buf + cnt, max_buf - cnt, |
||
10100 | + "Src %d Cur Ib %llu Ab %llu\n", |
||
10101 | + node_rule->rule_ops.src_id[i], |
||
10102 | + node_rule->src_info[i].ib, |
||
10103 | + node_rule->src_info[i].ab); |
||
10104 | + for (i = 0; i < node_rule->rule_ops.num_dst; i++) |
||
10105 | + cnt += scnprintf(buf + cnt, max_buf - cnt, |
||
10106 | + "Dst %d dst_bw %llu\n", |
||
10107 | + node_rule->rule_ops.dst_node[0], |
||
10108 | + node_rule->rule_ops.dst_bw); |
||
10109 | + cnt += scnprintf(buf + cnt, max_buf - cnt, |
||
10110 | + "Thresh %llu op %d mode %d\n", |
||
10111 | + node_rule->rule_ops.thresh, |
||
10112 | + node_rule->rule_ops.op, |
||
10113 | + node_rule->rule_ops.mode); |
||
10114 | + } |
||
10115 | + } |
||
10116 | +} |
||
10117 | + |
||
10118 | +static int copy_rule(struct bus_rule_type *src, struct rules_def *node_rule, |
||
10119 | + struct notifier_block *nb) |
||
10120 | +{ |
||
10121 | + int i; |
||
10122 | + int ret = 0; |
||
10123 | + |
||
10124 | + memcpy(&node_rule->rule_ops, src, |
||
10125 | + sizeof(struct bus_rule_type)); |
||
10126 | + node_rule->rule_ops.src_id = kzalloc( |
||
10127 | + (sizeof(int) * node_rule->rule_ops.num_src), |
||
10128 | + GFP_KERNEL); |
||
10129 | + if (!node_rule->rule_ops.src_id) { |
||
10130 | + pr_err("%s:Failed to allocate for src_id", |
||
10131 | + __func__); |
||
10132 | + return -ENOMEM; |
||
10133 | + } |
||
10134 | + memcpy(node_rule->rule_ops.src_id, src->src_id, |
||
10135 | + sizeof(int) * src->num_src); |
||
10136 | + |
||
10137 | + |
||
10138 | + if (!nb) { |
||
10139 | + node_rule->rule_ops.dst_node = kzalloc( |
||
10140 | + (sizeof(int) * node_rule->rule_ops.num_dst), |
||
10141 | + GFP_KERNEL); |
||
10142 | + if (!node_rule->rule_ops.dst_node) { |
||
10143 | + pr_err("%s:Failed to allocate for src_id", |
||
10144 | + __func__); |
||
10145 | + return -ENOMEM; |
||
10146 | + } |
||
10147 | + memcpy(node_rule->rule_ops.dst_node, src->dst_node, |
||
10148 | + sizeof(int) * src->num_dst); |
||
10149 | + } |
||
10150 | + |
||
10151 | + node_rule->num_src = src->num_src; |
||
10152 | + node_rule->src_info = kzalloc( |
||
10153 | + (sizeof(struct node_vote_info) * node_rule->rule_ops.num_src), |
||
10154 | + GFP_KERNEL); |
||
10155 | + if (!node_rule->src_info) { |
||
10156 | + pr_err("%s:Failed to allocate for src_id", |
||
10157 | + __func__); |
||
10158 | + return -ENOMEM; |
||
10159 | + } |
||
10160 | + for (i = 0; i < src->num_src; i++) |
||
10161 | + node_rule->src_info[i].id = src->src_id[i]; |
||
10162 | + |
||
10163 | + return ret; |
||
10164 | +} |
||
10165 | + |
||
10166 | +void msm_rule_register(int num_rules, struct bus_rule_type *rule, |
||
10167 | + struct notifier_block *nb) |
||
10168 | +{ |
||
10169 | + struct rule_node_info *node = NULL; |
||
10170 | + int i, j; |
||
10171 | + struct rules_def *node_rule = NULL; |
||
10172 | + int num_dst = 0; |
||
10173 | + |
||
10174 | + if (!rule) |
||
10175 | + return; |
||
10176 | + |
||
10177 | + mutex_lock(&msm_bus_rules_lock); |
||
10178 | + for (i = 0; i < num_rules; i++) { |
||
10179 | + if (nb) |
||
10180 | + num_dst = 1; |
||
10181 | + else |
||
10182 | + num_dst = rule[i].num_dst; |
||
10183 | + |
||
10184 | + for (j = 0; j < num_dst; j++) { |
||
10185 | + int id = 0; |
||
10186 | + |
||
10187 | + if (nb) |
||
10188 | + id = NB_ID; |
||
10189 | + else |
||
10190 | + id = rule[i].dst_node[j]; |
||
10191 | + |
||
10192 | + node = gen_node(id, nb); |
||
10193 | + if (!node) { |
||
10194 | + pr_info("Error getting rule"); |
||
10195 | + goto exit_rule_register; |
||
10196 | + } |
||
10197 | + node_rule = kzalloc(sizeof(struct rules_def), |
||
10198 | + GFP_KERNEL); |
||
10199 | + if (!node_rule) { |
||
10200 | + pr_err("%s: Failed to allocate for rule", |
||
10201 | + __func__); |
||
10202 | + goto exit_rule_register; |
||
10203 | + } |
||
10204 | + |
||
10205 | + if (copy_rule(&rule[i], node_rule, nb)) { |
||
10206 | + pr_err("Error copying rule"); |
||
10207 | + goto exit_rule_register; |
||
10208 | + } |
||
10209 | + |
||
10210 | + node_rule->rule_id = node->num_rules++; |
||
10211 | + if (nb) |
||
10212 | + node->data = nb; |
||
10213 | + |
||
10214 | + list_add_tail(&node_rule->link, &node->node_rules); |
||
10215 | + } |
||
10216 | + } |
||
10217 | + list_sort(NULL, &node->node_rules, node_rules_compare); |
||
10218 | + |
||
10219 | + if (nb) |
||
10220 | + raw_notifier_chain_register(&node->rule_notify_list, nb); |
||
10221 | +exit_rule_register: |
||
10222 | + mutex_unlock(&msm_bus_rules_lock); |
||
10223 | + return; |
||
10224 | +} |
||
10225 | + |
||
10226 | +static int comp_rules(struct bus_rule_type *rulea, struct bus_rule_type *ruleb) |
||
10227 | +{ |
||
10228 | + int ret = 1; |
||
10229 | + |
||
10230 | + if (rulea->num_src == ruleb->num_src) |
||
10231 | + ret = memcmp(rulea->src_id, ruleb->src_id, |
||
10232 | + (sizeof(int) * rulea->num_src)); |
||
10233 | + if (!ret && (rulea->num_dst == ruleb->num_dst)) |
||
10234 | + ret = memcmp(rulea->dst_node, ruleb->dst_node, |
||
10235 | + (sizeof(int) * rulea->num_dst)); |
||
10236 | + if (!ret && (rulea->dst_bw == ruleb->dst_bw) && |
||
10237 | + (rulea->op == ruleb->op) && (rulea->thresh == ruleb->thresh)) |
||
10238 | + ret = 0; |
||
10239 | + |
||
10240 | + return ret; |
||
10241 | +} |
||
10242 | + |
||
10243 | +void msm_rule_unregister(int num_rules, struct bus_rule_type *rule, |
||
10244 | + struct notifier_block *nb) |
||
10245 | +{ |
||
10246 | + int i; |
||
10247 | + struct rule_node_info *node = NULL; |
||
10248 | + struct rule_node_info *node_tmp = NULL; |
||
10249 | + struct rules_def *node_rule; |
||
10250 | + struct rules_def *node_rule_tmp; |
||
10251 | + bool match_found = false; |
||
10252 | + |
||
10253 | + if (!rule) |
||
10254 | + return; |
||
10255 | + |
||
10256 | + mutex_lock(&msm_bus_rules_lock); |
||
10257 | + if (nb) { |
||
10258 | + node = get_node(NB_ID, nb); |
||
10259 | + if (!node) { |
||
10260 | + pr_err("%s: Can't find node", __func__); |
||
10261 | + goto exit_unregister_rule; |
||
10262 | + } |
||
10263 | + |
||
10264 | + list_for_each_entry_safe(node_rule, node_rule_tmp, |
||
10265 | + &node->node_rules, link) { |
||
10266 | + list_del(&node_rule->link); |
||
10267 | + kfree(node_rule); |
||
10268 | + node->num_rules--; |
||
10269 | + } |
||
10270 | + raw_notifier_chain_unregister(&node->rule_notify_list, nb); |
||
10271 | + } else { |
||
10272 | + for (i = 0; i < num_rules; i++) { |
||
10273 | + match_found = false; |
||
10274 | + |
||
10275 | + list_for_each_entry(node, &node_list, link) { |
||
10276 | + list_for_each_entry_safe(node_rule, |
||
10277 | + node_rule_tmp, &node->node_rules, link) { |
||
10278 | + if (comp_rules(&node_rule->rule_ops, |
||
10279 | + &rule[i]) == 0) { |
||
10280 | + list_del(&node_rule->link); |
||
10281 | + kfree(node_rule); |
||
10282 | + match_found = true; |
||
10283 | + node->num_rules--; |
||
10284 | + list_sort(NULL, |
||
10285 | + &node->node_rules, |
||
10286 | + node_rules_compare); |
||
10287 | + break; |
||
10288 | + } |
||
10289 | + } |
||
10290 | + } |
||
10291 | + } |
||
10292 | + } |
||
10293 | + |
||
10294 | + list_for_each_entry_safe(node, node_tmp, |
||
10295 | + &node_list, link) { |
||
10296 | + if (!node->num_rules) { |
||
10297 | + pr_debug("Deleting Rule node %d", node->id); |
||
10298 | + list_del(&node->link); |
||
10299 | + kfree(node); |
||
10300 | + } |
||
10301 | + } |
||
10302 | +exit_unregister_rule: |
||
10303 | + mutex_unlock(&msm_bus_rules_lock); |
||
10304 | +} |
||
10305 | + |
||
10306 | +bool msm_rule_are_rules_registered(void) |
||
10307 | +{ |
||
10308 | + bool ret = false; |
||
10309 | + |
||
10310 | + if (list_empty(&node_list)) |
||
10311 | + ret = false; |
||
10312 | + else |
||
10313 | + ret = true; |
||
10314 | + |
||
10315 | + return ret; |
||
10316 | +} |
||
10317 | + |
||
10318 | --- /dev/null |
||
10319 | +++ b/drivers/bus/msm_bus/msm_bus_rules.h |
||
10320 | @@ -0,0 +1,77 @@ |
||
10321 | +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. |
||
10322 | + * |
||
10323 | + * This program is free software; you can redistribute it and/or modify |
||
10324 | + * it under the terms of the GNU General Public License version 2 and |
||
10325 | + * only version 2 as published by the Free Software Foundation. |
||
10326 | + * |
||
10327 | + * This program is distributed in the hope that it will be useful, |
||
10328 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
10329 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
10330 | + * GNU General Public License for more details. |
||
10331 | + */ |
||
10332 | + |
||
10333 | +#ifndef _ARCH_ARM_MACH_MSM_BUS_RULES_H |
||
10334 | +#define _ARCH_ARM_MACH_MSM_BUS_RULES_H |
||
10335 | + |
||
10336 | +#include <linux/types.h> |
||
10337 | +#include <linux/list.h> |
||
10338 | +#include <linux/notifier.h> |
||
10339 | +#include <dt-bindings/msm/msm-bus-rule-ops.h> |
||
10340 | + |
||
10341 | +#define MAX_NODES (5) |
||
10342 | + |
||
10343 | +struct rule_update_path_info { |
||
10344 | + u32 id; |
||
10345 | + u64 ab; |
||
10346 | + u64 ib; |
||
10347 | + u64 clk; |
||
10348 | + struct list_head link; |
||
10349 | +}; |
||
10350 | + |
||
10351 | +struct rule_apply_rcm_info { |
||
10352 | + u32 id; |
||
10353 | + u64 lim_bw; |
||
10354 | + int throttle; |
||
10355 | + bool after_clk_commit; |
||
10356 | + struct list_head link; |
||
10357 | +}; |
||
10358 | + |
||
10359 | +struct bus_rule_type { |
||
10360 | + int num_src; |
||
10361 | + int *src_id; |
||
10362 | + int src_field; |
||
10363 | + int op; |
||
10364 | + u64 thresh; |
||
10365 | + int num_dst; |
||
10366 | + int *dst_node; |
||
10367 | + u64 dst_bw; |
||
10368 | + int mode; |
||
10369 | + void *client_data; |
||
10370 | +}; |
||
10371 | + |
||
10372 | +#if (defined(CONFIG_BUS_TOPOLOGY_ADHOC)) |
||
10373 | +void msm_rule_register(int num_rules, struct bus_rule_type *rule, |
||
10374 | + struct notifier_block *nb); |
||
10375 | +void msm_rule_unregister(int num_rules, struct bus_rule_type *rule, |
||
10376 | + struct notifier_block *nb); |
||
10377 | +void print_rules_buf(char *buf, int count); |
||
10378 | +bool msm_rule_are_rules_registered(void); |
||
10379 | +#else |
||
10380 | +static inline void msm_rule_register(int num_rules, struct bus_rule_type *rule, |
||
10381 | + struct notifier_block *nb) |
||
10382 | +{ |
||
10383 | +} |
||
10384 | +static inline void msm_rule_unregister(int num_rules, |
||
10385 | + struct bus_rule_type *rule, |
||
10386 | + struct notifier_block *nb) |
||
10387 | +{ |
||
10388 | +} |
||
10389 | +static inline void print_rules_buf(char *buf, int count) |
||
10390 | +{ |
||
10391 | +} |
||
10392 | +static inline bool msm_rule_are_rules_registered(void) |
||
10393 | +{ |
||
10394 | + return false; |
||
10395 | +} |
||
10396 | +#endif /* defined(CONFIG_BUS_TOPOLOGY_ADHOC) */ |
||
10397 | +#endif /* _ARCH_ARM_MACH_MSM_BUS_RULES_H */ |
||
10398 | --- /dev/null |
||
10399 | +++ b/drivers/bus/msm_bus/msm_buspm_coresight_adhoc.c |
||
10400 | @@ -0,0 +1,189 @@ |
||
10401 | +/* Copyright (c) 2014 The Linux Foundation. All rights reserved. |
||
10402 | + * |
||
10403 | + * This program is free software; you can redistribute it and/or modify |
||
10404 | + * it under the terms of the GNU General Public License version 2 and |
||
10405 | + * only version 2 as published by the Free Software Foundation. |
||
10406 | + * |
||
10407 | + * This program is distributed in the hope that it will be useful, |
||
10408 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
10409 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
10410 | + * GNU General Public License for more details. |
||
10411 | + */ |
||
10412 | + |
||
10413 | +#include <linux/clk.h> |
||
10414 | +#include <linux/module.h> |
||
10415 | +#include <linux/device.h> |
||
10416 | +#include <linux/platform_device.h> |
||
10417 | +#include <linux/err.h> |
||
10418 | +#include <linux/slab.h> |
||
10419 | +#include <linux/errno.h> |
||
10420 | +#include <linux/uaccess.h> |
||
10421 | +#include <linux/miscdevice.h> |
||
10422 | +#include <linux/of_coresight.h> |
||
10423 | +#include <linux/coresight.h> |
||
10424 | +#include <linux/io.h> |
||
10425 | +#include <linux/of.h> |
||
10426 | +#include <linux/list.h> |
||
10427 | + |
||
10428 | +struct msmbus_coresight_adhoc_clock_drvdata { |
||
10429 | + int id; |
||
10430 | + struct clk *clk; |
||
10431 | + struct list_head list; |
||
10432 | +}; |
||
10433 | + |
||
10434 | +struct msmbus_coresight_adhoc_drvdata { |
||
10435 | + struct device *dev; |
||
10436 | + struct coresight_device *csdev; |
||
10437 | + struct coresight_desc *desc; |
||
10438 | + struct list_head clocks; |
||
10439 | +}; |
||
10440 | + |
||
10441 | +static int msmbus_coresight_enable_adhoc(struct coresight_device *csdev) |
||
10442 | +{ |
||
10443 | + struct msmbus_coresight_adhoc_clock_drvdata *clk; |
||
10444 | + struct msmbus_coresight_adhoc_drvdata *drvdata = |
||
10445 | + dev_get_drvdata(csdev->dev.parent); |
||
10446 | + long rate; |
||
10447 | + |
||
10448 | + list_for_each_entry(clk, &drvdata->clocks, list) { |
||
10449 | + if (clk->id == csdev->id) { |
||
10450 | + rate = clk_round_rate(clk->clk, 1L); |
||
10451 | + clk_set_rate(clk->clk, rate); |
||
10452 | + return clk_prepare_enable(clk->clk); |
||
10453 | + } |
||
10454 | + } |
||
10455 | + |
||
10456 | + return -ENOENT; |
||
10457 | +} |
||
10458 | + |
||
10459 | +static void msmbus_coresight_disable_adhoc(struct coresight_device *csdev) |
||
10460 | +{ |
||
10461 | + struct msmbus_coresight_adhoc_clock_drvdata *clk; |
||
10462 | + struct msmbus_coresight_adhoc_drvdata *drvdata = |
||
10463 | + dev_get_drvdata(csdev->dev.parent); |
||
10464 | + |
||
10465 | + list_for_each_entry(clk, &drvdata->clocks, list) { |
||
10466 | + if (clk->id == csdev->id) |
||
10467 | + clk_disable_unprepare(clk->clk); |
||
10468 | + } |
||
10469 | +} |
||
10470 | + |
||
10471 | +static const struct coresight_ops_source msmbus_coresight_adhoc_source_ops = { |
||
10472 | + .enable = msmbus_coresight_enable_adhoc, |
||
10473 | + .disable = msmbus_coresight_disable_adhoc, |
||
10474 | +}; |
||
10475 | + |
||
10476 | +static const struct coresight_ops msmbus_coresight_cs_ops = { |
||
10477 | + .source_ops = &msmbus_coresight_adhoc_source_ops, |
||
10478 | +}; |
||
10479 | + |
||
10480 | +void msmbus_coresight_remove_adhoc(struct platform_device *pdev) |
||
10481 | +{ |
||
10482 | + struct msmbus_coresight_adhoc_clock_drvdata *clk, *next_clk; |
||
10483 | + struct msmbus_coresight_adhoc_drvdata *drvdata = |
||
10484 | + platform_get_drvdata(pdev); |
||
10485 | + |
||
10486 | + msmbus_coresight_disable_adhoc(drvdata->csdev); |
||
10487 | + coresight_unregister(drvdata->csdev); |
||
10488 | + list_for_each_entry_safe(clk, next_clk, &drvdata->clocks, list) { |
||
10489 | + list_del(&clk->list); |
||
10490 | + devm_kfree(&pdev->dev, clk); |
||
10491 | + } |
||
10492 | + devm_kfree(&pdev->dev, drvdata->desc); |
||
10493 | + devm_kfree(&pdev->dev, drvdata); |
||
10494 | + platform_set_drvdata(pdev, NULL); |
||
10495 | +} |
||
10496 | +EXPORT_SYMBOL(msmbus_coresight_remove_adhoc); |
||
10497 | + |
||
10498 | +static int buspm_of_get_clk_adhoc(struct device_node *of_node, |
||
10499 | + struct msmbus_coresight_adhoc_drvdata *drvdata, int id) |
||
10500 | +{ |
||
10501 | + struct msmbus_coresight_adhoc_clock_drvdata *clk; |
||
10502 | + clk = devm_kzalloc(drvdata->dev, sizeof(*clk), GFP_KERNEL); |
||
10503 | + |
||
10504 | + if (!clk) |
||
10505 | + return -ENOMEM; |
||
10506 | + |
||
10507 | + clk->id = id; |
||
10508 | + |
||
10509 | + clk->clk = of_clk_get_by_name(of_node, "bus_clk"); |
||
10510 | + if (IS_ERR(clk->clk)) { |
||
10511 | + pr_err("Error: unable to get clock for coresight node %d\n", |
||
10512 | + id); |
||
10513 | + goto err; |
||
10514 | + } |
||
10515 | + |
||
10516 | + list_add(&clk->list, &drvdata->clocks); |
||
10517 | + return 0; |
||
10518 | + |
||
10519 | +err: |
||
10520 | + devm_kfree(drvdata->dev, clk); |
||
10521 | + return -EINVAL; |
||
10522 | +} |
||
10523 | + |
||
10524 | +int msmbus_coresight_init_adhoc(struct platform_device *pdev, |
||
10525 | + struct device_node *of_node) |
||
10526 | +{ |
||
10527 | + int ret; |
||
10528 | + struct device *dev = &pdev->dev; |
||
10529 | + struct coresight_platform_data *pdata; |
||
10530 | + struct msmbus_coresight_adhoc_drvdata *drvdata; |
||
10531 | + struct coresight_desc *desc; |
||
10532 | + |
||
10533 | + pdata = of_get_coresight_platform_data(dev, of_node); |
||
10534 | + if (IS_ERR(pdata)) |
||
10535 | + return PTR_ERR(pdata); |
||
10536 | + |
||
10537 | + drvdata = platform_get_drvdata(pdev); |
||
10538 | + if (IS_ERR_OR_NULL(drvdata)) { |
||
10539 | + drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); |
||
10540 | + if (!drvdata) { |
||
10541 | + pr_err("coresight: Alloc for drvdata failed\n"); |
||
10542 | + return -ENOMEM; |
||
10543 | + } |
||
10544 | + INIT_LIST_HEAD(&drvdata->clocks); |
||
10545 | + drvdata->dev = &pdev->dev; |
||
10546 | + platform_set_drvdata(pdev, drvdata); |
||
10547 | + } |
||
10548 | + ret = buspm_of_get_clk_adhoc(of_node, drvdata, pdata->id); |
||
10549 | + if (ret) { |
||
10550 | + pr_err("Error getting clocks\n"); |
||
10551 | + ret = -ENXIO; |
||
10552 | + goto err1; |
||
10553 | + } |
||
10554 | + |
||
10555 | + desc = devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL); |
||
10556 | + if (!desc) { |
||
10557 | + pr_err("coresight: Error allocating memory\n"); |
||
10558 | + ret = -ENOMEM; |
||
10559 | + goto err1; |
||
10560 | + } |
||
10561 | + |
||
10562 | + desc->type = CORESIGHT_DEV_TYPE_SOURCE; |
||
10563 | + desc->subtype.source_subtype = CORESIGHT_DEV_SUBTYPE_SOURCE_BUS; |
||
10564 | + desc->ops = &msmbus_coresight_cs_ops; |
||
10565 | + desc->pdata = pdata; |
||
10566 | + desc->dev = &pdev->dev; |
||
10567 | + desc->owner = THIS_MODULE; |
||
10568 | + drvdata->desc = desc; |
||
10569 | + drvdata->csdev = coresight_register(desc); |
||
10570 | + if (IS_ERR(drvdata->csdev)) { |
||
10571 | + pr_err("coresight: Coresight register failed\n"); |
||
10572 | + ret = PTR_ERR(drvdata->csdev); |
||
10573 | + goto err0; |
||
10574 | + } |
||
10575 | + |
||
10576 | + dev_info(dev, "msmbus_coresight initialized\n"); |
||
10577 | + |
||
10578 | + return 0; |
||
10579 | +err0: |
||
10580 | + devm_kfree(dev, desc); |
||
10581 | +err1: |
||
10582 | + devm_kfree(dev, drvdata); |
||
10583 | + platform_set_drvdata(pdev, NULL); |
||
10584 | + return ret; |
||
10585 | +} |
||
10586 | +EXPORT_SYMBOL(msmbus_coresight_init_adhoc); |
||
10587 | + |
||
10588 | +MODULE_LICENSE("GPL v2"); |
||
10589 | +MODULE_DESCRIPTION("MSM BusPM Adhoc CoreSight Driver"); |
||
10590 | --- /dev/null |
||
10591 | +++ b/drivers/bus/msm_bus/rpm-smd.h |
||
10592 | @@ -0,0 +1,268 @@ |
||
10593 | +/* Copyright (c) 2012, 2014, The Linux Foundation. All rights reserved. |
||
10594 | + * |
||
10595 | + * This program is free software; you can redistribute it and/or modify |
||
10596 | + * it under the terms of the GNU General Public License version 2 and |
||
10597 | + * only version 2 as published by the Free Software Foundation. |
||
10598 | + * |
||
10599 | + * This program is distributed in the hope that it will be useful, |
||
10600 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
10601 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
10602 | + * GNU General Public License for more details. |
||
10603 | + * |
||
10604 | + */ |
||
10605 | + |
||
10606 | +#ifndef __ARCH_ARM_MACH_MSM_RPM_SMD_H |
||
10607 | +#define __ARCH_ARM_MACH_MSM_RPM_SMD_H |
||
10608 | + |
||
10609 | +/** |
||
10610 | + * enum msm_rpm_set - RPM enumerations for sleep/active set |
||
10611 | + * %MSM_RPM_CTX_SET_0: Set resource parameters for active mode. |
||
10612 | + * %MSM_RPM_CTX_SET_SLEEP: Set resource parameters for sleep. |
||
10613 | + */ |
||
10614 | +enum msm_rpm_set { |
||
10615 | + MSM_RPM_CTX_ACTIVE_SET, |
||
10616 | + MSM_RPM_CTX_SLEEP_SET, |
||
10617 | +}; |
||
10618 | + |
||
10619 | +struct msm_rpm_request; |
||
10620 | + |
||
10621 | +struct msm_rpm_kvp { |
||
10622 | + uint32_t key; |
||
10623 | + uint32_t length; |
||
10624 | + uint8_t *data; |
||
10625 | +}; |
||
10626 | +#ifdef CONFIG_MSM_RPM_SMD |
||
10627 | +/** |
||
10628 | + * msm_rpm_request() - Creates a parent element to identify the |
||
10629 | + * resource on the RPM, that stores the KVPs for different fields modified |
||
10630 | + * for a hardware resource |
||
10631 | + * |
||
10632 | + * @set: if the device is setting the active/sleep set parameter |
||
10633 | + * for the resource |
||
10634 | + * @rsc_type: unsigned 32 bit integer that identifies the type of the resource |
||
10635 | + * @rsc_id: unsigned 32 bit that uniquely identifies a resource within a type |
||
10636 | + * @num_elements: number of KVPs pairs associated with the resource |
||
10637 | + * |
||
10638 | + * returns pointer to a msm_rpm_request on success, NULL on error |
||
10639 | + */ |
||
10640 | +struct msm_rpm_request *msm_rpm_create_request( |
||
10641 | + enum msm_rpm_set set, uint32_t rsc_type, |
||
10642 | + uint32_t rsc_id, int num_elements); |
||
10643 | + |
||
10644 | +/** |
||
10645 | + * msm_rpm_request_noirq() - Creates a parent element to identify the |
||
10646 | + * resource on the RPM, that stores the KVPs for different fields modified |
||
10647 | + * for a hardware resource. This function is similar to msm_rpm_create_request |
||
10648 | + * except that it has to be called with interrupts masked. |
||
10649 | + * |
||
10650 | + * @set: if the device is setting the active/sleep set parameter |
||
10651 | + * for the resource |
||
10652 | + * @rsc_type: unsigned 32 bit integer that identifies the type of the resource |
||
10653 | + * @rsc_id: unsigned 32 bit that uniquely identifies a resource within a type |
||
10654 | + * @num_elements: number of KVPs pairs associated with the resource |
||
10655 | + * |
||
10656 | + * returns pointer to a msm_rpm_request on success, NULL on error |
||
10657 | + */ |
||
10658 | +struct msm_rpm_request *msm_rpm_create_request_noirq( |
||
10659 | + enum msm_rpm_set set, uint32_t rsc_type, |
||
10660 | + uint32_t rsc_id, int num_elements); |
||
10661 | + |
||
10662 | +/** |
||
10663 | + * msm_rpm_add_kvp_data() - Adds a Key value pair to a existing RPM resource. |
||
10664 | + * |
||
10665 | + * @handle: RPM resource handle to which the data should be appended |
||
10666 | + * @key: unsigned integer identify the parameter modified |
||
10667 | + * @data: byte array that contains the value corresponding to key. |
||
10668 | + * @size: size of data in bytes. |
||
10669 | + * |
||
10670 | + * returns 0 on success or errno |
||
10671 | + */ |
||
10672 | +int msm_rpm_add_kvp_data(struct msm_rpm_request *handle, |
||
10673 | + uint32_t key, const uint8_t *data, int size); |
||
10674 | + |
||
10675 | +/** |
||
10676 | + * msm_rpm_add_kvp_data_noirq() - Adds a Key value pair to a existing RPM |
||
10677 | + * resource. This function is similar to msm_rpm_add_kvp_data except that it |
||
10678 | + * has to be called with interrupts masked. |
||
10679 | + * |
||
10680 | + * @handle: RPM resource handle to which the data should be appended |
||
10681 | + * @key: unsigned integer identify the parameter modified |
||
10682 | + * @data: byte array that contains the value corresponding to key. |
||
10683 | + * @size: size of data in bytes. |
||
10684 | + * |
||
10685 | + * returns 0 on success or errno |
||
10686 | + */ |
||
10687 | +int msm_rpm_add_kvp_data_noirq(struct msm_rpm_request *handle, |
||
10688 | + uint32_t key, const uint8_t *data, int size); |
||
10689 | + |
||
10690 | +/** msm_rpm_free_request() - clean up the RPM request handle created with |
||
10691 | + * msm_rpm_create_request |
||
10692 | + * |
||
10693 | + * @handle: RPM resource handle to be cleared. |
||
10694 | + */ |
||
10695 | + |
||
10696 | +void msm_rpm_free_request(struct msm_rpm_request *handle); |
||
10697 | + |
||
10698 | +/** |
||
10699 | + * msm_rpm_send_request() - Send the RPM messages using SMD. The function |
||
10700 | + * assigns a message id before sending the data out to the RPM. RPM hardware |
||
10701 | + * uses the message id to acknowledge the messages. |
||
10702 | + * |
||
10703 | + * @handle: pointer to the msm_rpm_request for the resource being modified. |
||
10704 | + * |
||
10705 | + * returns non-zero message id on success and zero on a failed transaction. |
||
10706 | + * The drivers use message id to wait for ACK from RPM. |
||
10707 | + */ |
||
10708 | +int msm_rpm_send_request(struct msm_rpm_request *handle); |
||
10709 | + |
||
10710 | +/** |
||
10711 | + * msm_rpm_send_request_noirq() - Send the RPM messages using SMD. The |
||
10712 | + * function assigns a message id before sending the data out to the RPM. |
||
10713 | + * RPM hardware uses the message id to acknowledge the messages. This function |
||
10714 | + * is similar to msm_rpm_send_request except that it has to be called with |
||
10715 | + * interrupts masked. |
||
10716 | + * |
||
10717 | + * @handle: pointer to the msm_rpm_request for the resource being modified. |
||
10718 | + * |
||
10719 | + * returns non-zero message id on success and zero on a failed transaction. |
||
10720 | + * The drivers use message id to wait for ACK from RPM. |
||
10721 | + */ |
||
10722 | +int msm_rpm_send_request_noirq(struct msm_rpm_request *handle); |
||
10723 | + |
||
10724 | +/** |
||
10725 | + * msm_rpm_wait_for_ack() - A blocking call that waits for acknowledgment of |
||
10726 | + * a message from RPM. |
||
10727 | + * |
||
10728 | + * @msg_id: the return from msm_rpm_send_requests |
||
10729 | + * |
||
10730 | + * returns 0 on success or errno |
||
10731 | + */ |
||
10732 | +int msm_rpm_wait_for_ack(uint32_t msg_id); |
||
10733 | + |
||
10734 | +/** |
||
10735 | + * msm_rpm_wait_for_ack_noirq() - A blocking call that waits for acknowledgment |
||
10736 | + * of a message from RPM. This function is similar to msm_rpm_wait_for_ack |
||
10737 | + * except that it has to be called with interrupts masked. |
||
10738 | + * |
||
10739 | + * @msg_id: the return from msm_rpm_send_request |
||
10740 | + * |
||
10741 | + * returns 0 on success or errno |
||
10742 | + */ |
||
10743 | +int msm_rpm_wait_for_ack_noirq(uint32_t msg_id); |
||
10744 | + |
||
10745 | +/** |
||
10746 | + * msm_rpm_send_message() -Wrapper function for clients to send data given an |
||
10747 | + * array of key value pairs. |
||
10748 | + * |
||
10749 | + * @set: if the device is setting the active/sleep set parameter |
||
10750 | + * for the resource |
||
10751 | + * @rsc_type: unsigned 32 bit integer that identifies the type of the resource |
||
10752 | + * @rsc_id: unsigned 32 bit that uniquely identifies a resource within a type |
||
10753 | + * @kvp: array of KVP data. |
||
10754 | + * @nelem: number of KVPs pairs associated with the message. |
||
10755 | + * |
||
10756 | + * returns 0 on success and errno on failure. |
||
10757 | + */ |
||
10758 | +int msm_rpm_send_message(enum msm_rpm_set set, uint32_t rsc_type, |
||
10759 | + uint32_t rsc_id, struct msm_rpm_kvp *kvp, int nelems); |
||
10760 | + |
||
10761 | +/** |
||
10762 | + * msm_rpm_send_message_noirq() -Wrapper function for clients to send data |
||
10763 | + * given an array of key value pairs. This function is similar to the |
||
10764 | + * msm_rpm_send_message() except that it has to be called with interrupts |
||
10765 | + * disabled. Clients should choose the irq version when possible for system |
||
10766 | + * performance. |
||
10767 | + * |
||
10768 | + * @set: if the device is setting the active/sleep set parameter |
||
10769 | + * for the resource |
||
10770 | + * @rsc_type: unsigned 32 bit integer that identifies the type of the resource |
||
10771 | + * @rsc_id: unsigned 32 bit that uniquely identifies a resource within a type |
||
10772 | + * @kvp: array of KVP data. |
||
10773 | + * @nelem: number of KVPs pairs associated with the message. |
||
10774 | + * |
||
10775 | + * returns 0 on success and errno on failure. |
||
10776 | + */ |
||
10777 | +int msm_rpm_send_message_noirq(enum msm_rpm_set set, uint32_t rsc_type, |
||
10778 | + uint32_t rsc_id, struct msm_rpm_kvp *kvp, int nelems); |
||
10779 | + |
||
10780 | +/** |
||
10781 | + * msm_rpm_driver_init() - Initialization function that registers for a |
||
10782 | + * rpm platform driver. |
||
10783 | + * |
||
10784 | + * returns 0 on success. |
||
10785 | + */ |
||
10786 | +int __init msm_rpm_driver_init(void); |
||
10787 | + |
||
10788 | +#else |
||
10789 | + |
||
10790 | +static inline struct msm_rpm_request *msm_rpm_create_request( |
||
10791 | + enum msm_rpm_set set, uint32_t rsc_type, |
||
10792 | + uint32_t rsc_id, int num_elements) |
||
10793 | +{ |
||
10794 | + return NULL; |
||
10795 | +} |
||
10796 | + |
||
10797 | +static inline struct msm_rpm_request *msm_rpm_create_request_noirq( |
||
10798 | + enum msm_rpm_set set, uint32_t rsc_type, |
||
10799 | + uint32_t rsc_id, int num_elements) |
||
10800 | +{ |
||
10801 | + return NULL; |
||
10802 | + |
||
10803 | +} |
||
10804 | +static inline uint32_t msm_rpm_add_kvp_data(struct msm_rpm_request *handle, |
||
10805 | + uint32_t key, const uint8_t *data, int count) |
||
10806 | +{ |
||
10807 | + return 0; |
||
10808 | +} |
||
10809 | +static inline uint32_t msm_rpm_add_kvp_data_noirq( |
||
10810 | + struct msm_rpm_request *handle, uint32_t key, |
||
10811 | + const uint8_t *data, int count) |
||
10812 | +{ |
||
10813 | + return 0; |
||
10814 | +} |
||
10815 | + |
||
10816 | +static inline void msm_rpm_free_request(struct msm_rpm_request *handle) |
||
10817 | +{ |
||
10818 | + return; |
||
10819 | +} |
||
10820 | + |
||
10821 | +static inline int msm_rpm_send_request(struct msm_rpm_request *handle) |
||
10822 | +{ |
||
10823 | + return 0; |
||
10824 | +} |
||
10825 | + |
||
10826 | +static inline int msm_rpm_send_request_noirq(struct msm_rpm_request *handle) |
||
10827 | +{ |
||
10828 | + return 0; |
||
10829 | + |
||
10830 | +} |
||
10831 | + |
||
10832 | +static inline int msm_rpm_send_message(enum msm_rpm_set set, uint32_t rsc_type, |
||
10833 | + uint32_t rsc_id, struct msm_rpm_kvp *kvp, int nelems) |
||
10834 | +{ |
||
10835 | + return 0; |
||
10836 | +} |
||
10837 | + |
||
10838 | +static inline int msm_rpm_send_message_noirq(enum msm_rpm_set set, |
||
10839 | + uint32_t rsc_type, uint32_t rsc_id, struct msm_rpm_kvp *kvp, |
||
10840 | + int nelems) |
||
10841 | +{ |
||
10842 | + return 0; |
||
10843 | +} |
||
10844 | + |
||
10845 | +static inline int msm_rpm_wait_for_ack(uint32_t msg_id) |
||
10846 | +{ |
||
10847 | + return 0; |
||
10848 | + |
||
10849 | +} |
||
10850 | +static inline int msm_rpm_wait_for_ack_noirq(uint32_t msg_id) |
||
10851 | +{ |
||
10852 | + return 0; |
||
10853 | +} |
||
10854 | + |
||
10855 | +static inline int __init msm_rpm_driver_init(void) |
||
10856 | +{ |
||
10857 | + return 0; |
||
10858 | +} |
||
10859 | +#endif |
||
10860 | +#endif /*__ARCH_ARM_MACH_MSM_RPM_SMD_H*/ |
||
10861 | --- /dev/null |
||
10862 | +++ b/include/trace/events/trace_msm_bus.h |
||
10863 | @@ -0,0 +1,163 @@ |
||
10864 | +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. |
||
10865 | + * |
||
10866 | + * This program is free software; you can redistribute it and/or modify |
||
10867 | + * it under the terms of the GNU General Public License version 2 and |
||
10868 | + * only version 2 as published by the Free Software Foundation. |
||
10869 | + * |
||
10870 | + * This program is distributed in the hope that it will be useful, |
||
10871 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
10872 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
10873 | + * GNU General Public License for more details. |
||
10874 | + */ |
||
10875 | + |
||
10876 | +#undef TRACE_SYSTEM |
||
10877 | +#define TRACE_SYSTEM msm_bus |
||
10878 | + |
||
10879 | +#if !defined(_TRACE_MSM_BUS_H) || defined(TRACE_HEADER_MULTI_READ) |
||
10880 | +#define _TRACE_MSM_BUS_H |
||
10881 | + |
||
10882 | +#include <linux/tracepoint.h> |
||
10883 | + |
||
10884 | +TRACE_EVENT(bus_update_request, |
||
10885 | + |
||
10886 | + TP_PROTO(int sec, int nsec, const char *name, unsigned int index, |
||
10887 | + int src, int dest, unsigned long long ab, |
||
10888 | + unsigned long long ib), |
||
10889 | + |
||
10890 | + TP_ARGS(sec, nsec, name, index, src, dest, ab, ib), |
||
10891 | + |
||
10892 | + TP_STRUCT__entry( |
||
10893 | + __field(int, sec) |
||
10894 | + __field(int, nsec) |
||
10895 | + __string(name, name) |
||
10896 | + __field(u32, index) |
||
10897 | + __field(int, src) |
||
10898 | + __field(int, dest) |
||
10899 | + __field(u64, ab) |
||
10900 | + __field(u64, ib) |
||
10901 | + ), |
||
10902 | + |
||
10903 | + TP_fast_assign( |
||
10904 | + __entry->sec = sec; |
||
10905 | + __entry->nsec = nsec; |
||
10906 | + __assign_str(name, name); |
||
10907 | + __entry->index = index; |
||
10908 | + __entry->src = src; |
||
10909 | + __entry->dest = dest; |
||
10910 | + __entry->ab = ab; |
||
10911 | + __entry->ib = ib; |
||
10912 | + ), |
||
10913 | + |
||
10914 | + TP_printk("time= %d.%d name=%s index=%u src=%d dest=%d ab=%llu ib=%llu", |
||
10915 | + __entry->sec, |
||
10916 | + __entry->nsec, |
||
10917 | + __get_str(name), |
||
10918 | + (unsigned int)__entry->index, |
||
10919 | + __entry->src, |
||
10920 | + __entry->dest, |
||
10921 | + (unsigned long long)__entry->ab, |
||
10922 | + (unsigned long long)__entry->ib) |
||
10923 | +); |
||
10924 | + |
||
10925 | +TRACE_EVENT(bus_bimc_config_limiter, |
||
10926 | + |
||
10927 | + TP_PROTO(int mas_id, unsigned long long cur_lim_bw), |
||
10928 | + |
||
10929 | + TP_ARGS(mas_id, cur_lim_bw), |
||
10930 | + |
||
10931 | + TP_STRUCT__entry( |
||
10932 | + __field(int, mas_id) |
||
10933 | + __field(u64, cur_lim_bw) |
||
10934 | + ), |
||
10935 | + |
||
10936 | + TP_fast_assign( |
||
10937 | + __entry->mas_id = mas_id; |
||
10938 | + __entry->cur_lim_bw = cur_lim_bw; |
||
10939 | + ), |
||
10940 | + |
||
10941 | + TP_printk("Master=%d cur_lim_bw=%llu", |
||
10942 | + __entry->mas_id, |
||
10943 | + (unsigned long long)__entry->cur_lim_bw) |
||
10944 | +); |
||
10945 | + |
||
10946 | +TRACE_EVENT(bus_avail_bw, |
||
10947 | + |
||
10948 | + TP_PROTO(unsigned long long cur_bimc_bw, unsigned long long cur_mdp_bw), |
||
10949 | + |
||
10950 | + TP_ARGS(cur_bimc_bw, cur_mdp_bw), |
||
10951 | + |
||
10952 | + TP_STRUCT__entry( |
||
10953 | + __field(u64, cur_bimc_bw) |
||
10954 | + __field(u64, cur_mdp_bw) |
||
10955 | + ), |
||
10956 | + |
||
10957 | + TP_fast_assign( |
||
10958 | + __entry->cur_bimc_bw = cur_bimc_bw; |
||
10959 | + __entry->cur_mdp_bw = cur_mdp_bw; |
||
10960 | + ), |
||
10961 | + |
||
10962 | + TP_printk("cur_bimc_bw = %llu cur_mdp_bw = %llu", |
||
10963 | + (unsigned long long)__entry->cur_bimc_bw, |
||
10964 | + (unsigned long long)__entry->cur_mdp_bw) |
||
10965 | +); |
||
10966 | + |
||
10967 | +TRACE_EVENT(bus_rules_matches, |
||
10968 | + |
||
10969 | + TP_PROTO(int node_id, int rule_id, unsigned long long node_ab, |
||
10970 | + unsigned long long node_ib, unsigned long long node_clk), |
||
10971 | + |
||
10972 | + TP_ARGS(node_id, rule_id, node_ab, node_ib, node_clk), |
||
10973 | + |
||
10974 | + TP_STRUCT__entry( |
||
10975 | + __field(int, node_id) |
||
10976 | + __field(int, rule_id) |
||
10977 | + __field(u64, node_ab) |
||
10978 | + __field(u64, node_ib) |
||
10979 | + __field(u64, node_clk) |
||
10980 | + ), |
||
10981 | + |
||
10982 | + TP_fast_assign( |
||
10983 | + __entry->node_id = node_id; |
||
10984 | + __entry->rule_id = rule_id; |
||
10985 | + __entry->node_ab = node_ab; |
||
10986 | + __entry->node_ib = node_ib; |
||
10987 | + __entry->node_clk = node_clk; |
||
10988 | + ), |
||
10989 | + |
||
10990 | + TP_printk("Rule match node%d rule%d node-ab%llu:ib%llu:clk%llu", |
||
10991 | + __entry->node_id, __entry->rule_id, |
||
10992 | + (unsigned long long)__entry->node_ab, |
||
10993 | + (unsigned long long)__entry->node_ib, |
||
10994 | + (unsigned long long)__entry->node_clk) |
||
10995 | +); |
||
10996 | + |
||
10997 | +TRACE_EVENT(bus_bke_params, |
||
10998 | + |
||
10999 | + TP_PROTO(u32 gc, u32 gp, u32 thl, u32 thm, u32 thh), |
||
11000 | + |
||
11001 | + TP_ARGS(gc, gp, thl, thm, thh), |
||
11002 | + |
||
11003 | + TP_STRUCT__entry( |
||
11004 | + __field(u32, gc) |
||
11005 | + __field(u32, gp) |
||
11006 | + __field(u32, thl) |
||
11007 | + __field(u32, thm) |
||
11008 | + __field(u32, thh) |
||
11009 | + ), |
||
11010 | + |
||
11011 | + TP_fast_assign( |
||
11012 | + __entry->gc = gc; |
||
11013 | + __entry->gp = gp; |
||
11014 | + __entry->thl = thl; |
||
11015 | + __entry->thm = thm; |
||
11016 | + __entry->thh = thh; |
||
11017 | + ), |
||
11018 | + |
||
11019 | + TP_printk("BKE Params GC=0x%x GP=0x%x THL=0x%x THM=0x%x THH=0x%x", |
||
11020 | + __entry->gc, __entry->gp, __entry->thl, __entry->thm, |
||
11021 | + __entry->thh) |
||
11022 | +); |
||
11023 | + |
||
11024 | +#endif |
||
11025 | +#define TRACE_INCLUDE_FILE trace_msm_bus |
||
11026 | +#include <trace/define_trace.h> |