1 From: Christian Lamparter <chunkeey@googlemail.com>
2 Subject: BUS: add MSM_BUS
3 --- a/drivers/bus/Makefile
4 +++ b/drivers/bus/Makefile
5 @@ -10,6 +10,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/
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 @@ -92,6 +92,8 @@ config MVEBU_MBUS
16 Driver needed for the MBus configuration on Marvell EBU SoCs
17 (Kirkwood, Dove, Orion5x, MV78XX0 and Armada 370/XP).
19 +source "drivers/bus/msm_bus/Kconfig"
21 config OMAP_INTERCONNECT
22 tristate "OMAP INTERCONNECT DRIVER"
23 depends on ARCH_OMAP2PLUS
25 +++ b/include/dt-bindings/msm/msm-bus-ids.h
27 +/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
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.
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.
39 +#ifndef __MSM_BUS_IDS_H
40 +#define __MSM_BUS_IDS_H
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
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
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
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
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
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
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
505 + * ID's used in RPM messages
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
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
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
897 +++ b/include/dt-bindings/msm/msm-bus-rule-ops.h
899 +/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
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.
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.
911 +#ifndef __MSM_BUS_RULE_OPS_H
912 +#define __MSM_BUS_RULE_OPS_H
924 +#define RULE_STATE_NOT_APPLIED 0
925 +#define RULE_STATE_APPLIED 1
927 +#define THROTTLE_ON 0
928 +#define THROTTLE_OFF 1
932 +++ b/drivers/bus/msm_bus/Kconfig
934 +config BUS_TOPOLOGY_ADHOC
935 + bool "ad-hoc bus scaling topology"
936 + depends on ARCH_QCOM
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.
944 +config MSM_BUS_SCALING
945 + bool "Bus scaling driver"
946 + depends on BUS_TOPOLOGY_ADHOC
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.
954 +++ b/drivers/bus/msm_bus/Makefile
957 +# Makefile for msm-bus driver specific files
959 +obj-y += msm_bus_bimc.o msm_bus_noc.o msm_bus_core.o msm_bus_client_api.o \
961 +obj-$(CONFIG_OF) += msm_bus_of.o
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
967 +obj-$(CONFIG_DEBUG_FS) += msm_bus_dbg.o
969 +++ b/drivers/bus/msm_bus/msm-bus-board.h
971 +/* Copyright (c) 2010-2014, The Linux Foundation. All rights reserved.
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.
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.
983 +#ifndef __ASM_ARCH_MSM_BUS_BOARD_H
984 +#define __ASM_ARCH_MSM_BUS_BOARD_H
986 +#include <linux/types.h>
987 +#include <linux/input.h>
995 +struct msm_bus_fabric_registration {
998 + struct msm_bus_node_info *info;
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;
1010 + const struct msm_bus_board_algorithm *board_algo;
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;
1021 +struct msm_bus_device_node_registration {
1022 + struct msm_bus_node_device_type *info;
1023 + unsigned int num_devices;
1027 +enum msm_bus_bw_tier_type {
1028 + MSM_BUS_BW_TIER1 = 1,
1031 + MSM_BUS_BW_SIZE = 0x7FFFFFFF,
1034 +struct msm_bus_halt_vector {
1036 + uint32_t haltmask;
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;
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;
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;
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;
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;
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;
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;
1081 +extern int msm_bus_device_match_adhoc(struct device *dev, void *id);
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);
1087 +#define NFAB_MSM8226 6
1088 +#define NFAB_MSM8610 5
1091 + * These macros specify the convention followed for allocating
1092 + * ids to fabrics, masters and slaves for 8x60.
1094 + * A node can be identified as a master/slave/fabric by using
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
1102 +#define GET_FABID(id) ((id) & MAX_FAB_KEY)
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)
1109 + * The following macros are used to format the data for port halt
1110 + * and unhalt requests.
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
1117 +#define MSM_BUS_MASTER_SHIFT(master, fieldsize) \
1118 + ((master) * (fieldsize))
1120 +#define MSM_BUS_SET_BITFIELD(word, fieldmask, fieldvalue) \
1122 + (word) &= ~(fieldmask); \
1123 + (word) |= (fieldvalue); \
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))\
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))\
1151 +#define RPM_BUS_SLAVE_REQ 0x766c7362
1152 +#define RPM_BUS_MASTER_REQ 0x73616d62
1154 +enum msm_bus_rpm_slave_field_type {
1155 + RPM_SLAVE_FIELD_BW = 0x00007762,
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,
1165 +#include <dt-bindings/msm/msm-bus-ids.h>
1168 +#endif /*__ASM_ARCH_MSM_BUS_BOARD_H */
1170 +++ b/drivers/bus/msm_bus/msm-bus.h
1172 +/* Copyright (c) 2010-2014, The Linux Foundation. All rights reserved.
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.
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.
1184 +#ifndef _ARCH_ARM_MACH_MSM_BUS_H
1185 +#define _ARCH_ARM_MACH_MSM_BUS_H
1187 +#include <linux/types.h>
1188 +#include <linux/input.h>
1189 +#include <linux/platform_device.h>
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
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.
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
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))
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 */
1222 +struct msm_bus_paths {
1224 + struct msm_bus_vectors *vectors;
1227 +struct msm_bus_scale_pdata {
1228 + struct msm_bus_paths *usecase;
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.
1237 + unsigned int active_only;
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
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);
1258 +static inline int __init msm_bus_fabric_init_driver(void) { return 0; }
1260 +static inline uint32_t
1261 +msm_bus_scale_register_client(struct msm_bus_scale_pdata *pdata)
1267 +msm_bus_scale_client_update_request(uint32_t cl, unsigned int index)
1273 +msm_bus_scale_unregister_client(uint32_t cl)
1277 +static inline int msm_bus_axi_porthalt(int master_port)
1282 +static inline int msm_bus_axi_portunhalt(int master_port)
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);
1294 +static inline struct msm_bus_scale_pdata
1295 +*msm_bus_cl_get_pdata(struct platform_device *pdev)
1300 +static inline struct msm_bus_scale_pdata *msm_bus_pdata_from_node(
1301 + struct platform_device *pdev, struct device_node *of_node)
1306 +static inline void msm_bus_cl_clear_pdata(struct msm_bus_scale_pdata *pdata)
1310 +#endif /*_ARCH_ARM_MACH_MSM_BUS_H*/
1312 +++ b/drivers/bus/msm_bus/msm_bus_adhoc.h
1314 +/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
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.
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.
1326 +#ifndef _ARCH_ARM_MACH_MSM_BUS_ADHOC_H
1327 +#define _ARCH_ARM_MACH_MSM_BUS_ADHOC_H
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"
1336 +struct msm_bus_node_device_type;
1338 + uint64_t lnode_ib[NUM_CTX];
1339 + uint64_t lnode_ab[NUM_CTX];
1341 + struct device *next_dev;
1342 + struct list_head link;
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,
1358 + bool (*update_bw_reg)(int mode);
1362 + uint64_t ab[NUM_CTX];
1366 +struct msm_bus_fab_device_type {
1367 + void __iomem *qos_base;
1368 + phys_addr_t pqos_base;
1370 + uint32_t base_offset;
1371 + uint32_t qos_freq;
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;
1380 +struct qos_params_type {
1382 + unsigned int prio_lvl;
1383 + unsigned int prio_rd;
1384 + unsigned int prio_wr;
1385 + unsigned int prio1;
1386 + unsigned int prio0;
1388 + unsigned int thmp;
1394 +struct msm_bus_node_info_type {
1402 + struct qos_params_type qos_params;
1403 + unsigned int num_connections;
1404 + unsigned int num_blist;
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;
1417 + uint32_t util_fact;
1418 + uint32_t vrail_comp;
1421 +struct msm_bus_node_device_type {
1422 + struct msm_bus_node_info_type *node_info;
1423 + struct msm_bus_fab_device_type *fabdev;
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;
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);
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 */
1456 +++ b/drivers/bus/msm_bus/msm_bus_arb_adhoc.c
1458 +/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
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.
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.
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"
1480 +#define NUM_CL_HANDLES 50
1481 +#define NUM_LNODES 3
1483 +struct bus_search_type {
1484 + struct list_head link;
1485 + struct list_head node_list;
1488 +struct handle_type {
1490 + struct msm_bus_client **cl_list;
1493 +static struct handle_type handle_list;
1494 +struct list_head input_list;
1495 +struct list_head apply_list;
1497 +DEFINE_MUTEX(msm_bus_adhoc_lock);
1499 +static bool chk_bl_list(struct list_head *black_list, unsigned int id)
1501 + struct msm_bus_node_device_type *bus_node = NULL;
1503 + list_for_each_entry(bus_node, black_list, link) {
1504 + if (bus_node->node_info->id == id)
1510 +static void copy_remaining_nodes(struct list_head *edge_list, struct list_head
1511 + *traverse_list, struct list_head *route_list)
1513 + struct bus_search_type *search_node;
1515 + if (list_empty(edge_list) && list_empty(traverse_list))
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);
1526 + * Duplicate instantiaion from msm_bus_arb.c. Todo there needs to be a
1527 + * "util" file for these common func/macros.
1530 +uint64_t msm_bus_div64(unsigned int w, uint64_t bw)
1532 + uint64_t *b = &bw;
1534 + if ((bw > 0) && (bw < w))
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);
1552 +int msm_bus_device_match_adhoc(struct device *dev, void *id)
1555 + struct msm_bus_node_device_type *bnode = dev->platform_data;
1558 + ret = (bnode->node_info->id == *(unsigned int *)id);
1565 +static int gen_lnode(struct device *dev,
1566 + int next_hop, int prev_idx)
1568 + struct link_node *lnode;
1569 + struct msm_bus_node_device_type *cur_dev = NULL;
1570 + int lnode_idx = -1;
1573 + goto exit_gen_lnode;
1575 + cur_dev = dev->platform_data;
1577 + MSM_BUS_ERR("%s: Null device ptr", __func__);
1578 + goto exit_gen_lnode;
1581 + if (!cur_dev->num_lnodes) {
1582 + cur_dev->lnode_list = devm_kzalloc(dev,
1583 + sizeof(struct link_node) * NUM_LNODES,
1585 + if (!cur_dev->lnode_list)
1586 + goto exit_gen_lnode;
1588 + lnode = cur_dev->lnode_list;
1589 + cur_dev->num_lnodes = NUM_LNODES;
1593 + for (i = 0; i < cur_dev->num_lnodes; i++) {
1594 + if (!cur_dev->lnode_list[i].in_use)
1598 + if (i < cur_dev->num_lnodes) {
1599 + lnode = &cur_dev->lnode_list[i];
1602 + struct link_node *realloc_list;
1603 + size_t cur_size = sizeof(struct link_node) *
1604 + cur_dev->num_lnodes;
1606 + cur_dev->num_lnodes += NUM_LNODES;
1607 + realloc_list = msm_bus_realloc_devmem(
1609 + cur_dev->lnode_list,
1611 + sizeof(struct link_node) *
1612 + cur_dev->num_lnodes, GFP_KERNEL);
1614 + if (!realloc_list)
1615 + goto exit_gen_lnode;
1617 + cur_dev->lnode_list = realloc_list;
1618 + lnode = &cur_dev->lnode_list[i];
1623 + lnode->in_use = 1;
1624 + if (next_hop == cur_dev->node_info->id) {
1626 + lnode->next_dev = NULL;
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);
1634 + memset(lnode->lnode_ib, 0, sizeof(uint64_t) * NUM_CTX);
1635 + memset(lnode->lnode_ab, 0, sizeof(uint64_t) * NUM_CTX);
1641 +static int remove_lnode(struct msm_bus_node_device_type *cur_dev,
1647 + MSM_BUS_ERR("%s: Null device ptr", __func__);
1649 + goto exit_remove_lnode;
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);
1658 + goto exit_remove_lnode;
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;
1670 +static int prune_path(struct list_head *route_list, int dest, int src,
1671 + struct list_head *black_list, int found)
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,
1680 + msm_bus_device_match_adhoc);
1681 + int lnode_hop = -1;
1687 + MSM_BUS_ERR("%s: Can't find dest dev %d", __func__, dest);
1688 + goto exit_prune_path;
1691 + lnode_hop = gen_lnode(dest_dev, search_dev_id, lnode_hop);
1693 + list_for_each_entry_reverse(search_node, route_list, link) {
1694 + list_for_each_entry(bus_node, &search_node->node_list, link) {
1696 + for (i = 0; i < bus_node->node_info->num_connections;
1698 + if (bus_node->node_info->connections[i] ==
1700 + dest_dev = bus_find_device(
1704 + &bus_node->node_info->
1706 + msm_bus_device_match_adhoc);
1713 + lnode_hop = gen_lnode(dest_dev,
1717 + bus_node->node_info->id;
1724 + list_for_each_entry_safe(search_node, temp_search_node, route_list,
1726 + list_for_each_entry(bus_node, &search_node->node_list,
1728 + bus_node->node_info->is_traversed = false;
1730 + list_del(&search_node->link);
1731 + kfree(search_node);
1734 + list_for_each_safe(bl_list, temp_bl_list, black_list)
1735 + list_del(bl_list);
1741 +static void setup_bl_list(struct msm_bus_node_device_type *node,
1742 + struct list_head *black_list)
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);
1753 +static int getpath(int src, int dest)
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,
1761 + msm_bus_device_match_adhoc);
1762 + struct msm_bus_node_device_type *src_node;
1763 + struct bus_search_type *search_node;
1765 + int depth_index = 0;
1766 + int first_hop = -1;
1768 + INIT_LIST_HEAD(&traverse_list);
1769 + INIT_LIST_HEAD(&edge_list);
1770 + INIT_LIST_HEAD(&route_list);
1771 + INIT_LIST_HEAD(&black_list);
1774 + MSM_BUS_ERR("%s: Cannot locate src dev %d", __func__, src);
1775 + goto exit_getpath;
1778 + src_node = src_dev->platform_data;
1780 + MSM_BUS_ERR("%s:Fatal, Source dev %d not found", __func__, src);
1781 + goto exit_getpath;
1783 + list_add_tail(&src_node->link, &traverse_list);
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) {
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);
1802 + for (i = 0; i < bus_node->node_info->
1803 + num_connections; i++) {
1805 + struct msm_bus_node_device_type
1807 + node_conn = bus_node->node_info->
1808 + dev_connections[i]->
1810 + if (node_conn->node_info->
1812 + MSM_BUS_ERR("Circ Path %d\n",
1813 + node_conn->node_info->id);
1814 + goto reset_traversed;
1816 + skip = chk_bl_list(&black_list,
1817 + bus_node->node_info->
1820 + list_add_tail(&node_conn->link,
1822 + node_conn->node_info->
1823 + is_traversed = true;
1828 + /* Keep tabs of the previous search list */
1829 + search_node = kzalloc(sizeof(struct bus_search_type),
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 */
1838 + list_splice_init(&edge_list, &traverse_list);
1842 + copy_remaining_nodes(&edge_list, &traverse_list, &route_list);
1843 + first_hop = prune_path(&route_list, dest, src, &black_list, found);
1849 +static uint64_t arbitrate_bus_req(struct msm_bus_node_device_type *bus_dev,
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;
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];
1866 + * Account for Util factor and vrail comp. The new aggregation
1868 + * Freq_hz = max((sum(ab) * util_fact)/num_chan, max(ib)/vrail_comp)
1870 + * util_fact and vrail comp are obtained from fabric/Node's dts
1872 + * They default to 100 if absent.
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);
1886 + max_ib = msm_bus_div64(vrail_comp, max_ib);
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,
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;
1900 + bw_max_hz = max(max_ib, sum_ab);
1901 + bw_max_hz = msm_bus_div64(bus_dev->node_info->buswidth,
1907 +static void del_inp_list(struct list_head *list)
1909 + struct rule_update_path_info *rule_node;
1910 + struct rule_update_path_info *rule_node_tmp;
1912 + list_for_each_entry_safe(rule_node, rule_node_tmp, list, link)
1913 + list_del(&rule_node->link);
1916 +static void del_op_list(struct list_head *list)
1918 + struct rule_apply_rcm_info *rule;
1919 + struct rule_apply_rcm_info *rule_tmp;
1921 + list_for_each_entry_safe(rule, rule_tmp, list, link)
1922 + list_del(&rule->link);
1925 +static int msm_bus_apply_rules(struct list_head *list, bool after_clk_commit)
1927 + struct rule_apply_rcm_info *rule;
1928 + struct device *dev = NULL;
1929 + struct msm_bus_node_device_type *dev_info = NULL;
1931 + bool throttle_en = false;
1933 + list_for_each_entry(rule, list, link) {
1937 + if (rule && (rule->after_clk_commit != after_clk_commit))
1940 + dev = bus_find_device(&msm_bus_type, NULL,
1941 + (void *) &rule->id,
1942 + msm_bus_device_match_adhoc);
1945 + MSM_BUS_ERR("Can't find dev node for %d", rule->id);
1948 + dev_info = dev->platform_data;
1950 + throttle_en = ((rule->throttle == THROTTLE_ON) ? true : false);
1951 + ret = msm_bus_enable_limiter(dev_info, throttle_en,
1954 + MSM_BUS_ERR("Failed to set limiter for %d", rule->id);
1960 +static uint64_t get_node_aggab(struct msm_bus_node_device_type *bus_dev)
1964 + uint64_t max_agg_ab = 0;
1965 + uint64_t agg_ab = 0;
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];
1971 + if (bus_dev->node_info->num_qports > 1)
1972 + agg_ab = msm_bus_div64(bus_dev->node_info->num_qports,
1975 + max_agg_ab = max(max_agg_ab, agg_ab);
1978 + return max_agg_ab;
1981 +static uint64_t get_node_ib(struct msm_bus_node_device_type *bus_dev)
1985 + uint64_t max_ib = 0;
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]);
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)
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;
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();
2009 + src_dev = bus_find_device(&msm_bus_type, NULL,
2011 + msm_bus_device_match_adhoc);
2014 + MSM_BUS_ERR("%s: Can't find source device %d", __func__, src);
2016 + goto exit_update_path;
2019 + next_dev = src_dev;
2021 + if (src_idx < 0) {
2022 + MSM_BUS_ERR("%s: Invalid lnode idx %d", __func__, src_idx);
2024 + goto exit_update_path;
2026 + curr_idx = src_idx;
2028 + INIT_LIST_HEAD(&input_list);
2029 + INIT_LIST_HEAD(&apply_list);
2031 + while (next_dev) {
2032 + dev_info = next_dev->platform_data;
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);
2038 + goto exit_update_path;
2041 + lnode = &dev_info->lnode_list[curr_idx];
2042 + lnode->lnode_ib[ctx] = req_ib;
2043 + lnode->lnode_ab[ctx] = req_bw;
2045 + dev_info->cur_clk_hz[ctx] = arbitrate_bus_req(dev_info, ctx);
2047 + /* Start updating the clocks at the first hop.
2048 + * Its ok to figure out the aggregated
2049 + * request at this node.
2051 + if (src_dev != next_dev) {
2052 + ret = msm_bus_update_clks(dev_info, ctx, &dirty_nodes,
2055 + MSM_BUS_ERR("%s: Failed to update clks dev %d",
2056 + __func__, dev_info->node_info->id);
2057 + goto exit_update_path;
2061 + ret = msm_bus_update_bw(dev_info, ctx, req_bw, &dirty_nodes,
2064 + MSM_BUS_ERR("%s: Failed to update bw dev %d",
2065 + __func__, dev_info->node_info->id);
2066 + goto exit_update_path;
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);
2079 + next_dev = lnode->next_dev;
2080 + curr_idx = lnode->next;
2083 + if (rules_registered) {
2084 + msm_rules_update_path(&input_list, &apply_list);
2085 + msm_bus_apply_rules(&apply_list, false);
2088 + msm_bus_commit_data(dirty_nodes, ctx, num_dirty);
2090 + if (rules_registered) {
2091 + msm_bus_apply_rules(&apply_list, true);
2092 + del_inp_list(&input_list);
2093 + del_op_list(&apply_list);
2099 +static int remove_path(int src, int dst, uint64_t cur_ib, uint64_t cur_ab,
2100 + int src_idx, int active_only)
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;
2107 + int cur_idx = src_idx;
2110 + /* Update the current path to zero out all request from
2111 + * this cient on all paths
2114 + ret = update_path(src, dst, 0, 0, cur_ib, cur_ab, src_idx,
2117 + MSM_BUS_ERR("%s: Error zeroing out path ctx %d",
2118 + __func__, ACTIVE_CTX);
2119 + goto exit_remove_path;
2122 + src_dev = bus_find_device(&msm_bus_type, NULL,
2124 + msm_bus_device_match_adhoc);
2126 + MSM_BUS_ERR("%s: Can't find source device %d", __func__, src);
2128 + goto exit_remove_path;
2131 + next_dev = src_dev;
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;
2146 +static void getpath_debug(int src, int curr, int active_only)
2148 + struct device *dev_node;
2149 + struct device *dev_it;
2150 + unsigned int hop = 1;
2152 + struct msm_bus_node_device_type *devinfo;
2155 + dev_node = bus_find_device(&msm_bus_type, NULL,
2157 + msm_bus_device_match_adhoc);
2160 + MSM_BUS_ERR("SRC NOT FOUND %d", src);
2165 + devinfo = dev_node->platform_data;
2166 + dev_it = dev_node;
2168 + MSM_BUS_ERR("Route list Src %d", src);
2170 + struct msm_bus_node_device_type *busdev =
2171 + devinfo->node_info->bus_device->platform_data;
2173 + MSM_BUS_ERR("Hop[%d] at Device %d ctx %d", hop,
2174 + devinfo->node_info->id, active_only);
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]);
2183 + dev_it = devinfo->lnode_list[idx].next_dev;
2184 + idx = devinfo->lnode_list[idx].next;
2186 + devinfo = dev_it->platform_data;
2188 + MSM_BUS_ERR("Bus Device %d", busdev->node_info->id);
2189 + MSM_BUS_ERR("Bus Clock %llu", busdev->clk[active_only].rate);
2197 +static void unregister_client_adhoc(uint32_t cl)
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;
2205 + mutex_lock(&msm_bus_adhoc_lock);
2207 + MSM_BUS_ERR("%s: Null cl handle passed unregister\n",
2209 + goto exit_unregister_client;
2211 + client = handle_list.cl_list[cl];
2212 + pdata = client->pdata;
2214 + MSM_BUS_ERR("%s: Null pdata passed to unregister\n",
2216 + goto exit_unregister_client;
2219 + curr = client->curr;
2220 + if (curr >= pdata->num_usecases) {
2221 + MSM_BUS_ERR("Invalid index Defaulting curr to 0");
2225 + MSM_BUS_DBG("%s: Unregistering client %p", __func__, client);
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;
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);
2237 + msm_bus_dbg_client_data(client->pdata, MSM_BUS_DBG_UNREGISTER, cl);
2238 + kfree(client->src_pnode);
2240 + handle_list.cl_list[cl] = NULL;
2241 +exit_unregister_client:
2242 + mutex_unlock(&msm_bus_adhoc_lock);
2246 +static int alloc_handle_lst(int size)
2249 + struct msm_bus_client **t_cl_list;
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)) {
2256 + MSM_BUS_ERR("%s: Failed to allocate handles list",
2258 + goto exit_alloc_handle_lst;
2260 + handle_list.cl_list = t_cl_list;
2261 + handle_list.num_entries += NUM_CL_HANDLES;
2263 + t_cl_list = krealloc(handle_list.cl_list,
2264 + sizeof(struct msm_bus_client *) *
2265 + handle_list.num_entries + NUM_CL_HANDLES,
2267 + if (ZERO_OR_NULL_PTR(t_cl_list)) {
2269 + MSM_BUS_ERR("%s: Failed to allocate handles list",
2271 + goto exit_alloc_handle_lst;
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;
2279 +exit_alloc_handle_lst:
2283 +static uint32_t gen_handle(struct msm_bus_client *client)
2285 + uint32_t handle = 0;
2289 + for (i = 0; i < handle_list.num_entries; i++) {
2290 + if (i && !handle_list.cl_list[i]) {
2297 + ret = alloc_handle_lst(NUM_CL_HANDLES);
2300 + MSM_BUS_ERR("%s: Failed to allocate handle list",
2302 + goto exit_gen_handle;
2306 + handle_list.cl_list[handle] = client;
2311 +static uint32_t register_client_adhoc(struct msm_bus_scale_pdata *pdata)
2315 + struct msm_bus_client *client = NULL;
2317 + uint32_t handle = 0;
2319 + mutex_lock(&msm_bus_adhoc_lock);
2320 + client = kzalloc(sizeof(struct msm_bus_client), GFP_KERNEL);
2322 + MSM_BUS_ERR("%s: Error allocating client data", __func__);
2323 + goto exit_register_client;
2325 + client->pdata = pdata;
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;
2332 + client->src_pnode = lnode;
2334 + for (i = 0; i < pdata->usecase->num_paths; i++) {
2335 + src = pdata->usecase->vectors[i].src;
2336 + dest = pdata->usecase->vectors[i].dst;
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;
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;
2352 + handle = gen_handle(client);
2353 + msm_bus_dbg_client_data(client->pdata, MSM_BUS_DBG_REGISTER,
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);
2362 +static int update_request_adhoc(uint32_t cl, unsigned int index)
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;
2372 + mutex_lock(&msm_bus_adhoc_lock);
2375 + MSM_BUS_ERR("%s: Invalid client handle %d", __func__, cl);
2377 + goto exit_update_request;
2380 + client = handle_list.cl_list[cl];
2381 + pdata = client->pdata;
2383 + MSM_BUS_ERR("%s: Client data Null.[client didn't register]",
2386 + goto exit_update_request;
2389 + if (index >= pdata->num_usecases) {
2390 + MSM_BUS_ERR("Client %u passed invalid index: %d\n",
2393 + goto exit_update_request;
2396 + if (client->curr == index) {
2397 + MSM_BUS_DBG("%s: Not updating client request idx %d unchanged",
2399 + goto exit_update_request;
2402 + curr = client->curr;
2403 + client->curr = index;
2405 + if (!strcmp(test_cl, pdata->name))
2406 + log_transaction = true;
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);
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;
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;
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);
2428 + ret = update_path(src, dest, req_clk, req_bw,
2429 + curr_clk, curr_bw, lnode, pdata->active_only);
2432 + MSM_BUS_ERR("%s: Update path failed! %d ctx %d\n",
2433 + __func__, ret, ACTIVE_CTX);
2434 + goto exit_update_request;
2437 + if (log_transaction)
2438 + getpath_debug(src, lnode, pdata->active_only);
2440 + msm_bus_dbg_client_data(client->pdata, index , cl);
2441 +exit_update_request:
2442 + mutex_unlock(&msm_bus_adhoc_lock);
2447 + * msm_bus_arb_setops_adhoc() : Setup the bus arbitration ops
2448 + * @ arb_ops: pointer to the arb ops.
2450 +void msm_bus_arb_setops_adhoc(struct msm_bus_arb_ops *arb_ops)
2452 + arb_ops->register_client = register_client_adhoc;
2453 + arb_ops->update_request = update_request_adhoc;
2454 + arb_ops->unregister_client = unregister_client_adhoc;
2457 +++ b/drivers/bus/msm_bus/msm_bus_bimc.c
2459 +/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
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.
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.
2471 +#define pr_fmt(fmt) "AXI: BIMC: %s(): " fmt, __func__
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>
2481 +enum msm_bus_bimc_slave_block {
2482 + SLAVE_BLOCK_RESERVED = 0,
2483 + SLAVE_BLOCK_SLAVE_WAY,
2485 + SLAVE_BLOCK_ARBITER,
2496 +#define M_REG_BASE(b) ((b) + 0x00008000)
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
2606 +#define M_MODE_ADDR(b, n) \
2607 + (M_REG_BASE(b) + (0x4000 * (n)) + 0x00000210)
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,
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,
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,
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,
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,
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,
2713 +/* Grant count register.
2714 + * The Grant count register represents a signed 16 bit
2715 + * value, range 0-0x7fff
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,
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,
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,
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,
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,
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,
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,
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,
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,
2829 +#define S_REG_BASE(b) ((b) + 0x00048000)
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,
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,
2858 +/* S_SCMO_GENERIC */
2860 +#define S_SCMO_REG_BASE(b) ((b) + 0x00048000)
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
3247 +/* S_SWAY_GENERIC */
3248 +#define S_SWAY_REG_BASE(b) ((b) + 0x00048000)
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
3425 +/* S_ARB_GENERIC */
3427 +#define S_ARB_REG_BASE(b) ((b) + 0x00049000)
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,
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,
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,
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,
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,
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)
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))
3494 +#define MAX_GRANT_PERIOD \
3495 + (M_BKE_GP_GP_BMSK >> \
3499 + (M_BKE_GC_GC_BMSK >> \
3500 + (M_BKE_GC_GC_SHFT + 1))
3502 +static int bimc_div(int64_t *a, uint32_t b)
3504 + if ((*a > 0) && (*a < b)) {
3508 + return do_div(*a, b);
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)
3516 + uint32_t val, mask, reg_val;
3517 + void __iomem *addr;
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 */
3532 +void msm_bus_bimc_arb_en(struct msm_bus_bimc_info *binfo,
3533 + uint32_t slv_index, bool en)
3535 + uint32_t reg_val, reg_mask_val, enable, val;
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 */
3553 +static void set_qos_mode(void __iomem *baddr, uint32_t index, uint32_t val0,
3554 + uint32_t val1, uint32_t val2)
3556 + uint32_t reg_val, val;
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 */
3580 +static void msm_bus_bimc_set_qos_mode(void __iomem *base,
3581 + uint32_t mas_index, uint8_t qmode_sel)
3583 + uint32_t reg_val, val;
3585 + switch (qmode_sel) {
3586 + case BIMC_QOS_MODE_FIXED:
3587 + reg_val = readl_relaxed(M_BKE_EN_ADDR(base,
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
3597 + set_qos_mode(base, mas_index, 1, 1, 1);
3600 + case BIMC_QOS_MODE_BYPASS:
3601 + reg_val = readl_relaxed(M_BKE_EN_ADDR(base,
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
3611 + set_qos_mode(base, mas_index, 0, 0, 0);
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,
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
3626 + writel_relaxed(((reg_val & (~M_BKE_EN_EN_BMSK)) | (val &
3627 + M_BKE_EN_EN_BMSK)), M_BKE_EN_ADDR(base,
3635 +static void set_qos_prio_rl(void __iomem *addr, uint32_t rmsk,
3636 + uint8_t index, struct msm_bus_bimc_qos_mode *qmode)
3638 + uint32_t reg_val, val0, val;
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
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)
3658 + uint32_t reg_val, val;
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));
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));
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
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);
3703 + case BIMC_QOS_MODE_BYPASS:
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,
3713 + int32_t reg_val, val;
3714 + int32_t bke_reg_val;
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));
3722 + /* Write values of registers calculated */
3723 + reg_val = readl_relaxed(M_BKE_GP_ADDR(baddr, mas_index))
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));
3729 + reg_val = readl_relaxed(M_BKE_GC_ADDR(baddr, mas_index)) &
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));
3735 + reg_val = readl_relaxed(M_BKE_THH_ADDR(baddr, mas_index)) &
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));
3741 + reg_val = readl_relaxed(M_BKE_THM_ADDR(baddr, mas_index)) &
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));
3747 + reg_val = readl_relaxed(M_BKE_THL_ADDR(baddr, mas_index)) &
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,
3754 + /* Ensure that all bandwidth register writes have completed
3755 + * before returning
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)
3765 + /* Validate QOS Frequency */
3766 + if (qos_freq == 0) {
3767 + MSM_BUS_DBG("Zero frequency\n");
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;
3775 + /* Only calculate if there's a requested bandwidth and window */
3776 + if (qbw->bw && qbw->ws) {
3777 + int64_t th, tm, tl;
3779 + int64_t gp_nominal, gp_required, gp_calc, data, temp;
3780 + int64_t win = qbw->ws * qos_freq;
3783 + * Calculate nominal grant period defined by requested
3785 + * Ceil this value to max grant period.
3787 + bimc_div(&temp, 1000000);
3788 + gp_nominal = min_t(uint64_t, MAX_GRANT_PERIOD, temp);
3790 + * Calculate max window size, defined by bw request.
3791 + * Units: (KHz, MB/s)
3793 + gp_calc = MAX_GC * qos_freq * 1000;
3794 + gp_required = gp_calc;
3795 + bimc_div(&gp_required, qbw->bw);
3797 + /* User min of two grant periods */
3798 + gp = min_t(int64_t, gp_nominal, gp_required);
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);
3806 + /* Calculate thresholds */
3807 + th = qbw->bw - qbw->thh;
3808 + tm = qbw->bw - qbw->thm;
3809 + tl = qbw->bw - qbw->thl;
3812 + bimc_div(&th, data);
3814 + bimc_div(&tm, data);
3816 + bimc_div(&tl, data);
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);
3824 + /* Clear bandwidth registers */
3825 + set_qos_bw_regs(base, mas_index, 0, 0, 0, 0, 0);
3828 +static int msm_bus_bimc_allocate_commit_data(struct msm_bus_fabric_registration
3829 + *fab_pdata, void **cdata, int ctx)
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;
3835 + MSM_BUS_DBG("Allocating BIMC commit data\n");
3836 + *cd = kzalloc(sizeof(struct msm_bus_bimc_commit), GFP_KERNEL);
3838 + MSM_BUS_DBG("Couldn't alloc mem for cdata\n");
3842 + (*cd)->mas = binfo->cdata[ctx].mas;
3843 + (*cd)->slv = binfo->cdata[ctx].slv;
3848 +static void *msm_bus_bimc_allocate_bimc_data(struct platform_device *pdev,
3849 + struct msm_bus_fabric_registration *fab_pdata)
3851 + struct resource *bimc_mem;
3852 + struct resource *bimc_io;
3853 + struct msm_bus_bimc_info *binfo;
3856 + MSM_BUS_DBG("Allocating BIMC data\n");
3857 + binfo = kzalloc(sizeof(struct msm_bus_bimc_info), GFP_KERNEL);
3859 + WARN(!binfo, "Couldn't alloc mem for bimc_info\n");
3863 + binfo->qos_freq = fab_pdata->qos_freq;
3865 + binfo->params.nmasters = fab_pdata->nmasters;
3866 + binfo->params.nslaves = fab_pdata->nslaves;
3867 + binfo->params.bus_id = fab_pdata->id;
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,
3873 + if (!binfo->cdata[i].mas) {
3874 + MSM_BUS_ERR("Couldn't alloc mem for bimc master hw\n");
3879 + binfo->cdata[i].slv = kzalloc(sizeof(struct
3880 + msm_bus_node_hw_info) * fab_pdata->nslaves * 2,
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);
3890 + if (fab_pdata->virt) {
3891 + MSM_BUS_DBG("Don't get memory regions for virtual fabric\n");
3895 + bimc_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
3897 + MSM_BUS_ERR("Cannot get BIMC Base address\n");
3902 + bimc_io = request_mem_region(bimc_mem->start,
3903 + resource_size(bimc_mem), pdev->name);
3905 + MSM_BUS_ERR("BIMC memory unavailable\n");
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));
3919 + fab_pdata->hw_data = (void *)binfo;
3920 + return (void *)binfo;
3923 +static void free_commit_data(void *cdata)
3925 + struct msm_bus_bimc_commit *cd = (struct msm_bus_bimc_commit *)cdata;
3932 +static void bke_switch(
3933 + void __iomem *baddr, uint32_t mas_index, bool req, int mode)
3935 + uint32_t reg_val, val, cur_val;
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)
3943 + if (!req && mode == BIMC_QOS_MODE_FIXED)
3944 + set_qos_mode(baddr, mas_index, 1, 1, 1);
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 */
3952 + set_qos_mode(baddr, mas_index, 0, 0, 0);
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)
3958 + int32_t bw_mbps, thh = 0, thm, thl, gc;
3962 + if (qos_freq == 0) {
3963 + MSM_BUS_DBG("No QoS Frequency.\n");
3967 + if (!(qbw->bw && qbw->gp)) {
3968 + MSM_BUS_DBG("No QoS Bandwidth or Window size\n");
3972 + /* Convert bandwidth to MBPS */
3974 + bimc_div(&temp, 1000000);
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.
3982 + gp = (qos_freq * qbw->gp) / (1000 * NSEC_PER_USEC);
3984 + /* Grant count = BW in MBps * Grant period
3985 + * in micro seconds
3987 + gc = bw_mbps * (qbw->gp / NSEC_PER_USEC);
3988 + gc = min(gc, MAX_GC);
3990 + /* Medium threshold = -((Medium Threshold percentage *
3991 + * Grant count) / 100)
3993 + thm = -((qbw->thmp * gc) / 100);
3996 + /* Low threshold = -(Grant count) */
4000 + MSM_BUS_DBG("%s: BKE parameters: gp %d, gc %d, thm %d thl %d thh %d",
4001 + __func__, gp, gc, thm, thl, thh);
4003 + trace_bus_bke_params(gc, gp, thl, thm, thl);
4004 + set_qos_bw_regs(base, mport, thh, thm, thl, gp, gc);
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)
4012 + int mode, i, ports;
4013 + struct msm_bus_bimc_info *binfo;
4016 + binfo = (struct msm_bus_bimc_info *)fab_pdata->hw_data;
4017 + ports = info->node_info->num_mports;
4020 + * Here check the details of dual configuration.
4021 + * Take actions based on different modes.
4022 + * Check for threshold if limiter mode, etc.
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];
4033 + mode = info->node_info->mode_thresh;
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],
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;
4051 + qbw.gp = info->node_info->bimc_gp;
4052 + qbw.thmp = info->node_info->bimc_thmp;
4053 + bimc_set_static_qos_bw(binfo->base,
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);
4060 + bke_switch(binfo->base, info->node_info->qport[i],
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,
4075 + struct msm_bus_bimc_info *binfo;
4076 + struct msm_bus_bimc_qos_bw qbw;
4079 + int ports = info->node_info->num_mports;
4080 + struct msm_bus_bimc_commit *sel_cd =
4081 + (struct msm_bus_bimc_commit *)sel_cdata;
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);
4086 + binfo = (struct msm_bus_bimc_info *)fab_pdata->hw_data;
4088 + if (info->node_info->num_mports == 0) {
4089 + MSM_BUS_DBG("BIMC: Skip Master BW\n");
4093 + ports = info->node_info->num_mports;
4094 + bw = INTERLEAVED_BW(fab_pdata, add_bw, ports);
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;
4106 + if (!info->node_info->qport) {
4107 + MSM_BUS_DBG("No qos ports to update!\n");
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");
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 */
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.
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,
4136 + info->node_info->qport[i], &qbw);
4141 + ports = hop->node_info->num_sports;
4142 + MSM_BUS_DBG("BIMC: ID: %d, Sports: %d\n", hop->node_info->priv_id,
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.
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;
4168 +static int msm_bus_bimc_commit(struct msm_bus_fabric_registration
4169 + *fab_pdata, void *hw_data, void **cdata)
4171 + MSM_BUS_DBG("\nReached BIMC Commit\n");
4172 + msm_bus_remote_hw_commit(fab_pdata, hw_data, cdata);
4176 +static void msm_bus_bimc_config_limiter(
4177 + struct msm_bus_fabric_registration *fab_pdata,
4178 + struct msm_bus_inode_info *info)
4180 + struct msm_bus_bimc_info *binfo;
4181 + int mode, i, ports;
4183 + binfo = (struct msm_bus_bimc_info *)fab_pdata->hw_data;
4184 + ports = info->node_info->num_mports;
4186 + if (!info->node_info->qport) {
4187 + MSM_BUS_DBG("No QoS Ports to init\n");
4191 + if (info->cur_lim_bw)
4192 + mode = BIMC_QOS_MODE_LIMITER;
4194 + mode = info->node_info->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],
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;
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,
4220 + info->node_info->qport[i], &qbw);
4221 + bke_switch(binfo->base,
4222 + info->node_info->qport[i],
4224 + info->cur_prg_bw = qbw.bw;
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)
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;
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;
4255 + if (!info->node_info->qport) {
4256 + MSM_BUS_DBG("No QoS Ports to init\n");
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,
4265 + qport[i], mode, qmode);
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,
4276 + info->node_info->qport[i], &qbw);
4281 + msm_bus_bimc_set_qos_mode(binfo->base,
4282 + info->node_info->qport[i],
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,
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;
4300 + if (!info->node_info->qport) {
4301 + MSM_BUS_DBG("No QoS Ports to init\n");
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);
4315 +static int msm_bus_bimc_mas_init(struct msm_bus_bimc_info *binfo,
4316 + struct msm_bus_inode_info *info)
4318 + struct msm_bus_bimc_qos_mode *qmode;
4319 + qmode = kzalloc(sizeof(struct msm_bus_bimc_qos_mode),
4322 + MSM_BUS_WARN("Couldn't alloc prio data for node: %d\n",
4323 + info->node_info->id);
4327 + info->hw_data = (void *)qmode;
4330 + * If the master supports dual configuration,
4331 + * configure registers for both modes
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);
4339 + bimc_init_mas_reg(binfo, info, qmode, info->node_info->mode);
4343 +static void msm_bus_bimc_node_init(void *hw_data,
4344 + struct msm_bus_inode_info *info)
4346 + struct msm_bus_bimc_info *binfo =
4347 + (struct msm_bus_bimc_info *)hw_data;
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);
4354 +static int msm_bus_bimc_port_halt(uint32_t haltid, uint8_t mport)
4359 +static int msm_bus_bimc_port_unhalt(uint32_t haltid, uint8_t mport)
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)
4372 + if (ZERO_OR_NULL_PTR(info->node_info->qport)) {
4373 + MSM_BUS_DBG("No QoS Ports to limit\n");
4377 + if (enable_lim && lim_bw) {
4378 + mode = BIMC_QOS_MODE_LIMITER;
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;
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,
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;
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);
4407 + bke_switch(qos_base, info->node_info->qport[i],
4410 + info->node_info->lim_bw = lim_bw;
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],
4418 + info->node_info->qos_params.cur_mode = mode;
4422 +static bool msm_bus_bimc_update_bw_reg(int mode)
4426 + if ((mode == BIMC_QOS_MODE_LIMITER)
4427 + || (mode == BIMC_QOS_MODE_REGULATOR))
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)
4439 + struct msm_bus_bimc_qos_mode qmode;
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;
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;
4457 + if (ZERO_OR_NULL_PTR(info->node_info->qport)) {
4458 + MSM_BUS_DBG("No QoS Ports to init\n");
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,
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);
4474 + msm_bus_bimc_set_qos_mode(qos_base,
4475 + info->node_info->qport[i],
4476 + info->node_info->qos_params.mode);
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)
4486 + struct msm_bus_bimc_qos_bw qbw;
4490 + struct msm_bus_node_info_type *info = dev->node_info;
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]);
4498 + for (i = 0; i < info->num_qports; i++) {
4499 + MSM_BUS_DBG("BIMC: Update mas_bw for ID: %d -> %llu\n",
4502 + if (!info->qport) {
4503 + MSM_BUS_DBG("No qos ports to update!\n");
4507 + qbw.bw = bw + info->qos_params.bw_buffer;
4508 + trace_bus_bimc_config_limiter(info->id, bw);
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);
4517 + * If the BW vote is 0 then set the QoS mode to
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);
4526 + bke_switch(qos_base, info->qport[i],
4527 + BKE_OFF, BIMC_QOS_MODE_FIXED);
4534 +int msm_bus_bimc_hw_init(struct msm_bus_fabric_registration *pdata,
4535 + struct msm_bus_hw_algorithm *hw_algo)
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 */
4553 + pdata->rpm_enabled = 1;
4557 +int msm_bus_bimc_set_ops(struct msm_bus_node_device_type *bus_dev)
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;
4570 +EXPORT_SYMBOL(msm_bus_bimc_set_ops);
4572 +++ b/drivers/bus/msm_bus/msm_bus_bimc.h
4574 +/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
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.
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.
4586 +#ifndef _ARCH_ARM_MACH_MSM_BUS_BIMC_H
4587 +#define _ARCH_ARM_MACH_MSM_BUS_BIMC_H
4589 +struct msm_bus_bimc_params {
4591 + uint32_t addr_width;
4592 + uint32_t data_width;
4593 + uint32_t nmasters;
4597 +struct msm_bus_bimc_commit {
4598 + struct msm_bus_node_hw_info *mas;
4599 + struct msm_bus_node_hw_info *slv;
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];
4610 +struct msm_bus_bimc_node {
4611 + uint32_t conn_mask;
4612 + uint32_t data_width;
4613 + uint8_t slv_arb_mode;
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,
4623 +enum msm_bus_bimc_interleave {
4624 + BIMC_INTERLEAVE_NONE = 0,
4625 + BIMC_INTERLEAVE_ODD,
4626 + BIMC_INTERLEAVE_EVEN,
4629 +struct msm_bus_bimc_slave_seg {
4631 + uint64_t start_addr;
4632 + uint64_t seg_size;
4633 + uint8_t interleave;
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,
4643 +struct msm_bus_bimc_qos_health {
4644 + bool limit_commands;
4645 + uint32_t areq_prio;
4646 + uint32_t prio_level;
4649 +struct msm_bus_bimc_mode_fixed {
4650 + uint32_t prio_level;
4651 + uint32_t areq_prio_rd;
4652 + uint32_t areq_prio_wr;
4655 +struct msm_bus_bimc_mode_rl {
4656 + uint8_t qhealthnum;
4657 + struct msm_bus_bimc_qos_health qhealth[4];
4660 +struct msm_bus_bimc_qos_mode {
4662 + struct msm_bus_bimc_mode_fixed fixed;
4663 + struct msm_bus_bimc_mode_rl rl;
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 */
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 */
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);
4700 +#endif /*_ARCH_ARM_MACH_MSM_BUS_BIMC_H*/
4702 +++ b/drivers/bus/msm_bus/msm_bus_client_api.c
4704 +/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
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.
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.
4716 +#define pr_fmt(fmt) "AXI: %s(): " fmt, __func__
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"
4729 +struct msm_bus_arb_ops arb_ops;
4732 + * msm_bus_scale_register_client() - Register the clients with the msm bus
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.
4737 + * Client data contains the vectors specifying arbitrated bandwidth (ab)
4738 + * and instantaneous bandwidth (ib) requested between a particular
4741 +uint32_t msm_bus_scale_register_client(struct msm_bus_scale_pdata *pdata)
4743 + if (arb_ops.register_client)
4744 + return arb_ops.register_client(pdata);
4746 + pr_err("%s: Bus driver not ready.",
4751 +EXPORT_SYMBOL(msm_bus_scale_register_client);
4754 + * msm_bus_scale_client_update_request() - Update the request for bandwidth
4755 + * from a particular client
4757 + * cl: Handle to the client
4758 + * index: Index into the vector, to which the bw and clock values need to be
4761 +int msm_bus_scale_client_update_request(uint32_t cl, unsigned int index)
4763 + if (arb_ops.update_request)
4764 + return arb_ops.update_request(cl, index);
4766 + pr_err("%s: Bus driver not ready.",
4768 + return -EPROBE_DEFER;
4771 +EXPORT_SYMBOL(msm_bus_scale_client_update_request);
4774 + * msm_bus_scale_unregister_client() - Unregister the client from the bus driver
4775 + * @cl: Handle to the client
4777 +void msm_bus_scale_unregister_client(uint32_t cl)
4779 + if (arb_ops.unregister_client)
4780 + arb_ops.unregister_client(cl);
4782 + pr_err("%s: Bus driver not ready.",
4786 +EXPORT_SYMBOL(msm_bus_scale_unregister_client);
4788 +++ b/drivers/bus/msm_bus/msm_bus_core.c
4790 +/* Copyright (c) 2010-2014, The Linux Foundation. All rights reserved.
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.
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.
4802 +#define pr_fmt(fmt) "AXI: %s(): " fmt, __func__
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"
4815 +static atomic_t num_fab = ATOMIC_INIT(0);
4817 +int msm_bus_get_num_fab(void)
4819 + return atomic_read(&num_fab);
4822 +int msm_bus_device_match(struct device *dev, void *id)
4824 + struct msm_bus_fabric_device *fabdev = to_msm_bus_fabric_device(dev);
4827 + MSM_BUS_WARN("Fabric %p returning 0\n", fabdev);
4830 + return fabdev->id == *(int *)id;
4833 +static void msm_bus_release(struct device *device)
4837 +struct bus_type msm_bus_type = {
4838 + .name = "msm-bus-type",
4840 +EXPORT_SYMBOL(msm_bus_type);
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
4848 +struct msm_bus_fabric_device *msm_bus_get_fabric_device(int fabid)
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);
4856 + fabric = to_msm_bus_fabric_device(dev);
4861 + * msm_bus_fabric_device_register() - Registers a fabric on msm bus
4862 + * @fabdev: Fabric device to be registered
4864 +int msm_bus_fabric_device_register(struct msm_bus_fabric_device *fabdev)
4867 + fabdev->dev.bus = &msm_bus_type;
4868 + fabdev->dev.release = msm_bus_release;
4869 + ret = dev_set_name(&fabdev->dev, fabdev->name);
4871 + MSM_BUS_ERR("error setting dev name\n");
4875 + ret = device_register(&fabdev->dev);
4877 + MSM_BUS_ERR("error registering device%d %s\n",
4878 + ret, fabdev->name);
4881 + atomic_inc(&num_fab);
4887 + * msm_bus_fabric_device_unregister() - Unregisters the fabric
4888 + * devices from the msm bus
4890 +void msm_bus_fabric_device_unregister(struct msm_bus_fabric_device *fabdev)
4892 + device_unregister(&fabdev->dev);
4893 + atomic_dec(&num_fab);
4896 +static void __exit msm_bus_exit(void)
4898 + bus_unregister(&msm_bus_type);
4901 +static int __init msm_bus_init(void)
4904 + retval = bus_register(&msm_bus_type);
4906 + MSM_BUS_ERR("bus_register error! %d\n",
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");
4916 +++ b/drivers/bus/msm_bus/msm_bus_core.h
4918 +/* Copyright (c) 2011-2014, The Linux Foundation. All rights reserved.
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.
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.
4930 +#ifndef _ARCH_ARM_MACH_MSM_BUS_CORE_H
4931 +#define _ARCH_ARM_MACH_MSM_BUS_CORE_H
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"
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__)
4949 +#define IS_MASTER_VALID(mas) \
4950 + (((mas >= MSM_BUS_MASTER_FIRST) && (mas <= MSM_BUS_MASTER_LAST)) \
4952 +#define IS_SLAVE_VALID(slv) \
4953 + (((slv >= MSM_BUS_SLAVE_FIRST) && (slv <= MSM_BUS_SLAVE_LAST)) ? 1 : 0)
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)
4962 +enum msm_bus_dbg_op_type {
4963 + MSM_BUS_DBG_UNREGISTER = -2,
4964 + MSM_BUS_DBG_REGISTER,
4965 + MSM_BUS_DBG_OP = 1,
4968 +enum msm_bus_hw_sel {
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);
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);
4992 +struct msm_bus_node_info {
4994 + unsigned int priv_id;
4995 + unsigned int mas_hw_id;
4996 + unsigned int slv_hw_id;
5007 + const char *slaveclk[NUM_CTX];
5008 + const char *memclk[NUM_CTX];
5009 + const char *iface_clk_node;
5010 + unsigned int buswidth;
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;
5022 + unsigned int mode_thresh;
5035 + uint64_t clk[NUM_CTX];
5036 + uint64_t bw[NUM_CTX];
5037 + uint64_t *sel_clk;
5042 +struct msm_bus_link_info {
5043 + uint64_t clk[NUM_CTX];
5044 + uint64_t *sel_clk;
5046 + int64_t bw[NUM_CTX];
5059 +struct msm_bus_inode_info {
5060 + struct msm_bus_node_info *node_info;
5063 + uint64_t cur_lim_bw;
5064 + uint64_t cur_prg_bw;
5065 + struct msm_bus_link_info link_info;
5067 + struct path_node *pnode;
5069 + struct nodeclk nodeclk[NUM_CTX];
5070 + struct nodeclk memclk[NUM_CTX];
5071 + struct nodeclk iface_clk;
5075 +struct msm_bus_node_hw_info {
5077 + unsigned int hw_id;
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,
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);
5107 +struct msm_bus_fabric_device {
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;
5116 + u64 nr_lim_thresh;
5119 +#define to_msm_bus_fabric_device(d) container_of(d, \
5120 + struct msm_bus_fabric_device, d)
5122 +struct msm_bus_fabric {
5123 + struct msm_bus_fabric_device fabdev;
5125 + void *cdata[NUM_CTX];
5128 + struct radix_tree_root fab_tree;
5130 + struct list_head gateways;
5131 + struct msm_bus_inode_info info;
5132 + struct msm_bus_fabric_registration *pdata;
5135 +#define to_msm_bus_fabric(d) container_of(d, \
5136 + struct msm_bus_fabric, d)
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
5150 + struct msm_bus_inode_info *(*find_gw_node)(struct msm_bus_fabric_device
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,
5159 + void (*config_limiter)(struct msm_bus_fabric_device *fabdev,
5160 + struct msm_bus_inode_info *info);
5163 +struct msm_bus_board_algorithm {
5165 + void (*assign_iids)(struct msm_bus_fabric_registration *fabreg,
5167 + int (*get_iid)(int id);
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
5175 +struct msm_bus_fabnodeinfo {
5176 + struct list_head list;
5177 + struct msm_bus_inode_info *info;
5180 +struct msm_bus_client {
5182 + struct msm_bus_scale_pdata *pdata;
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);
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,
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);
5207 +static inline int msm_bus_rpm_hw_init(struct msm_bus_fabric_registration *pdata,
5208 + struct msm_bus_hw_algorithm *hw_algo)
5212 +static inline int msm_bus_remote_hw_commit(struct msm_bus_fabric_registration
5213 + *fab_pdata, void *hw_data, void **cdata)
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,
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,
5231 +void msm_bus_dbg_commit_data(const char *fabname, void *cdata,
5232 + int nmasters, int nslaves, int ntslaves, int op);
5234 +static inline void msm_bus_dbg_client_data(struct msm_bus_scale_pdata *pdata,
5235 + int index, uint32_t cl)
5238 +static inline void msm_bus_dbg_commit_data(const char *fabname,
5239 + void *cdata, int nmasters, int nslaves, int ntslaves,
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);
5252 +static inline int msmbus_coresight_init(struct platform_device *pdev)
5257 +static inline void msmbus_coresight_remove(struct platform_device *pdev)
5261 +static inline int msmbus_coresight_init_adhoc(struct platform_device *pdev,
5262 + struct device_node *of_node)
5267 +static inline void msmbus_coresight_remove_adhoc(struct platform_device *pdev)
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);
5279 +static inline void msm_bus_of_get_nfab(struct platform_device *pdev,
5280 + struct msm_bus_fabric_registration *pdata)
5285 +static inline struct msm_bus_fabric_registration
5286 + *msm_bus_of_get_fab_data(struct platform_device *pdev)
5292 +#endif /*_ARCH_ARM_MACH_MSM_BUS_CORE_H*/
5294 +++ b/drivers/bus/msm_bus/msm_bus_dbg.c
5296 +/* Copyright (c) 2010-2012, 2014, The Linux Foundation. All rights reserved.
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.
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.
5309 +#define pr_fmt(fmt) "AXI: %s(): " fmt, __func__
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"
5326 +#define CREATE_TRACE_POINTS
5327 +#include <trace/events/trace_msm_bus.h>
5329 +#define MAX_BUFF_SIZE 4096
5330 +#define FILL_LIMIT 128
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 {
5338 + uint8_t current_index;
5341 +struct msm_bus_cldata {
5342 + const struct msm_bus_scale_pdata *pdata;
5346 + struct dentry *file;
5347 + struct list_head list;
5348 + char buffer[MAX_BUFF_SIZE];
5351 +struct msm_bus_fab_list {
5354 + struct dentry *file;
5355 + struct list_head list;
5356 + char buffer[MAX_BUFF_SIZE];
5359 +static char *rules_buf;
5361 +LIST_HEAD(fabdata_list);
5362 +LIST_HEAD(cl_list);
5365 + * The following structures and funtions are used for
5366 + * the test-client which can be created at run-time.
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];
5373 +static struct msm_bus_paths shell_client_usecases[] = {
5375 + .num_paths = ARRAY_SIZE(init_vectors),
5376 + .vectors = init_vectors,
5379 + .num_paths = ARRAY_SIZE(current_vectors),
5380 + .vectors = current_vectors,
5383 + .num_paths = ARRAY_SIZE(requested_vectors),
5384 + .vectors = requested_vectors,
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",
5394 +static void msm_bus_dbg_init_vectors(void)
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;
5412 +static int msm_bus_dbg_update_cl_request(uint32_t cl)
5416 + if (clstate.current_index < 2)
5417 + clstate.current_index = 2;
5419 + clstate.current_index = 1;
5420 + current_vectors[0].ab = requested_vectors[0].ab;
5421 + current_vectors[0].ib = requested_vectors[0].ib;
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);
5430 + MSM_BUS_DBG("Enable bit not set. Skipping update request\n");
5435 +static void msm_bus_dbg_unregister_client(uint32_t cl)
5437 + MSM_BUS_DBG("Unregistering shell client\n");
5438 + msm_bus_scale_unregister_client(clstate.cl);
5442 +static uint32_t msm_bus_dbg_register_client(void)
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);
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);
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;
5460 + if (!clstate.enable) {
5461 + MSM_BUS_DBG("Enable bit not set, skipping registration: cl "
5462 + "%d\n", clstate.cl);
5467 + MSM_BUS_DBG("Client registered, skipping registration\n");
5468 + return clstate.cl;
5471 + MSM_BUS_DBG("Registering shell client\n");
5472 + ret = msm_bus_scale_register_client(&shell_client);
5476 +static int msm_bus_dbg_mas_get(void *data, u64 *val)
5478 + *val = init_vectors[0].src;
5479 + MSM_BUS_DBG("Get master: %llu\n", *val);
5483 +static int msm_bus_dbg_mas_set(void *data, u64 val)
5485 + init_vectors[0].src = val;
5486 + MSM_BUS_DBG("Set master: %llu\n", val);
5487 + clstate.cl = msm_bus_dbg_register_client();
5490 +DEFINE_SIMPLE_ATTRIBUTE(shell_client_mas_fops, msm_bus_dbg_mas_get,
5491 + msm_bus_dbg_mas_set, "%llu\n");
5493 +static int msm_bus_dbg_slv_get(void *data, u64 *val)
5495 + *val = init_vectors[0].dst;
5496 + MSM_BUS_DBG("Get slave: %llu\n", *val);
5500 +static int msm_bus_dbg_slv_set(void *data, u64 val)
5502 + init_vectors[0].dst = val;
5503 + MSM_BUS_DBG("Set slave: %llu\n", val);
5504 + clstate.cl = msm_bus_dbg_register_client();
5507 +DEFINE_SIMPLE_ATTRIBUTE(shell_client_slv_fops, msm_bus_dbg_slv_get,
5508 + msm_bus_dbg_slv_set, "%llu\n");
5510 +static int msm_bus_dbg_ab_get(void *data, u64 *val)
5512 + *val = requested_vectors[0].ab;
5513 + MSM_BUS_DBG("Get ab: %llu\n", *val);
5517 +static int msm_bus_dbg_ab_set(void *data, u64 val)
5519 + requested_vectors[0].ab = val;
5520 + MSM_BUS_DBG("Set ab: %llu\n", val);
5523 +DEFINE_SIMPLE_ATTRIBUTE(shell_client_ab_fops, msm_bus_dbg_ab_get,
5524 + msm_bus_dbg_ab_set, "%llu\n");
5526 +static int msm_bus_dbg_ib_get(void *data, u64 *val)
5528 + *val = requested_vectors[0].ib;
5529 + MSM_BUS_DBG("Get ib: %llu\n", *val);
5533 +static int msm_bus_dbg_ib_set(void *data, u64 val)
5535 + requested_vectors[0].ib = val;
5536 + MSM_BUS_DBG("Set ib: %llu\n", val);
5539 +DEFINE_SIMPLE_ATTRIBUTE(shell_client_ib_fops, msm_bus_dbg_ib_get,
5540 + msm_bus_dbg_ib_set, "%llu\n");
5542 +static int msm_bus_dbg_en_get(void *data, u64 *val)
5544 + *val = clstate.enable;
5545 + MSM_BUS_DBG("Get enable: %llu\n", *val);
5549 +static int msm_bus_dbg_en_set(void *data, u64 val)
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();
5559 + ret = msm_bus_dbg_update_cl_request(clstate.cl);
5561 + MSM_BUS_DBG("update request for cl: %u\n", clstate.cl);
5562 + ret = msm_bus_dbg_update_cl_request(clstate.cl);
5566 + MSM_BUS_DBG("Set enable: %llu\n", val);
5569 +DEFINE_SIMPLE_ATTRIBUTE(shell_client_en_fops, msm_bus_dbg_en_get,
5570 + msm_bus_dbg_en_set, "%llu\n");
5573 + * The following funtions are used for viewing the client data
5574 + * and changing the client request at run-time
5577 +static ssize_t client_data_read(struct file *file, char __user *buf,
5578 + size_t count, loff_t *ppos)
5581 + uint32_t cl = (uint32_t)(uintptr_t)file->private_data;
5582 + struct msm_bus_cldata *cldata = NULL;
5585 + list_for_each_entry(cldata, &cl_list, list) {
5586 + if (cldata->clid == cl) {
5594 + bsize = cldata->size;
5595 + return simple_read_from_buffer(buf, count, ppos,
5596 + cldata->buffer, bsize);
5599 +static int client_data_open(struct inode *inode, struct file *file)
5601 + file->private_data = inode->i_private;
5605 +static const struct file_operations client_data_fops = {
5606 + .open = client_data_open,
5607 + .read = client_data_read,
5610 +struct dentry *msm_bus_dbg_create(const char *name, mode_t mode,
5611 + struct dentry *dent, uint32_t clid)
5613 + if (dent == NULL) {
5614 + MSM_BUS_DBG("debugfs not ready yet\n");
5617 + return debugfs_create_file(name, mode, dent, (void *)(uintptr_t)clid,
5618 + &client_data_fops);
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)
5625 + struct msm_bus_cldata *cldata;
5627 + cldata = kmalloc(sizeof(struct msm_bus_cldata), GFP_KERNEL);
5629 + MSM_BUS_DBG("Failed to allocate memory for client data\n");
5632 + cldata->pdata = pdata;
5633 + cldata->index = index;
5634 + cldata->clid = clid;
5635 + cldata->file = file;
5637 + list_add_tail(&cldata->list, &cl_list);
5641 +static void msm_bus_dbg_free_client(uint32_t clid)
5643 + struct msm_bus_cldata *cldata = NULL;
5645 + list_for_each_entry(cldata, &cl_list, list) {
5646 + if (cldata->clid == clid) {
5647 + debugfs_remove(cldata->file);
5648 + list_del(&cldata->list);
5655 +static int msm_bus_dbg_fill_cl_buffer(const struct msm_bus_scale_pdata *pdata,
5656 + int index, uint32_t clid)
5660 + struct msm_bus_cldata *cldata = NULL;
5661 + struct timespec ts;
5664 + list_for_each_entry(cldata, &cl_list, list) {
5665 + if (cldata->clid == clid) {
5674 + if (cldata->file == NULL) {
5675 + if (pdata->name == NULL) {
5676 + MSM_BUS_DBG("Client doesn't have a name\n");
5679 + cldata->file = msm_bus_dbg_create(pdata->name, S_IRUGO,
5683 + if (cldata->size < (MAX_BUFF_SIZE - FILL_LIMIT))
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: ");
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");
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);
5726 +static int msm_bus_dbg_update_request(struct msm_bus_cldata *cldata, int index)
5730 + if ((index < 0) || (index > cldata->pdata->num_usecases)) {
5731 + MSM_BUS_DBG("Invalid index!\n");
5734 + ret = msm_bus_scale_client_update_request(cldata->clid, index);
5738 +static ssize_t msm_bus_dbg_update_request_write(struct file *file,
5739 + const char __user *ubuf, size_t cnt, loff_t *ppos)
5741 + struct msm_bus_cldata *cldata;
5742 + unsigned long index = 0;
5745 + char *buf = kmalloc((sizeof(char) * (cnt + 1)), GFP_KERNEL);
5748 + if (!buf || IS_ERR(buf)) {
5749 + MSM_BUS_ERR("Memory allocation for buffer failed\n");
5756 + if (copy_from_user(buf, ubuf, cnt)) {
5762 + MSM_BUS_DBG("buffer: %s\n size: %zu\n", buf, sizeof(ubuf));
5764 + list_for_each_entry(cldata, &cl_list, list) {
5765 + if (strnstr(chid, cldata->pdata->name, cnt)) {
5768 + strsep(&chid, " ");
5770 + ret = kstrtoul(chid, 10, &index);
5772 + MSM_BUS_DBG("Index conversion"
5777 + MSM_BUS_DBG("Error parsing input. Index not"
5786 + msm_bus_dbg_update_request(cldata, index);
5792 + * The following funtions are used for viewing the commit data
5795 +static ssize_t fabric_data_read(struct file *file, char __user *buf,
5796 + size_t count, loff_t *ppos)
5798 + struct msm_bus_fab_list *fablist = NULL;
5801 + const char *name = file->private_data;
5804 + mutex_lock(&msm_bus_dbg_fablist_lock);
5805 + list_for_each_entry(fablist, &fabdata_list, list) {
5806 + if (strcmp(fablist->name, name) == 0) {
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);
5820 +static const struct file_operations fabric_data_fops = {
5821 + .open = client_data_open,
5822 + .read = fabric_data_read,
5825 +static ssize_t rules_dbg_read(struct file *file, char __user *buf,
5826 + size_t count, loff_t *ppos)
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);
5836 +static int rules_dbg_open(struct inode *inode, struct file *file)
5838 + file->private_data = inode->i_private;
5842 +static const struct file_operations rules_dbg_fops = {
5843 + .open = rules_dbg_open,
5844 + .read = rules_dbg_read,
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)
5850 + struct msm_bus_fab_list *fablist;
5853 + mutex_lock(&msm_bus_dbg_fablist_lock);
5854 + fablist = kmalloc(sizeof(struct msm_bus_fab_list), GFP_KERNEL);
5856 + MSM_BUS_DBG("Failed to allocate memory for commit data\n");
5861 + fablist->name = fabname;
5862 + fablist->size = 0;
5863 + list_add_tail(&fablist->list, &fabdata_list);
5865 + mutex_unlock(&msm_bus_dbg_fablist_lock);
5869 +static void msm_bus_dbg_free_fabric(const char *fabname)
5871 + struct msm_bus_fab_list *fablist = NULL;
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);
5882 + mutex_unlock(&msm_bus_dbg_fablist_lock);
5885 +static int msm_bus_dbg_fill_fab_buffer(const char *fabname,
5886 + void *cdata, int nmasters, int nslaves,
5891 + struct msm_bus_fab_list *fablist = NULL;
5892 + struct timespec ts;
5895 + mutex_lock(&msm_bus_dbg_fablist_lock);
5896 + list_for_each_entry(fablist, &fabdata_list, list) {
5897 + if (strcmp(fablist->name, fabname) == 0) {
5905 + if (fablist->file == NULL) {
5906 + MSM_BUS_DBG("Fabric dbg entry does not exist\n");
5907 + mutex_unlock(&msm_bus_dbg_fablist_lock);
5911 + if (fablist->size < MAX_BUFF_SIZE - 256)
5912 + i = fablist->size;
5915 + fablist->size = 0;
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);
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);
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,
5938 +#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_MSM_BUS_SCALING)
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
5945 +void msm_bus_dbg_client_data(struct msm_bus_scale_pdata *pdata, int index,
5948 + struct dentry *file = NULL;
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");
5956 + } else if (index == MSM_BUS_DBG_UNREGISTER) {
5957 + msm_bus_dbg_free_client(clid);
5958 + MSM_BUS_DBG("Client %d unregistered\n", clid);
5960 + msm_bus_dbg_fill_cl_buffer(pdata, index, clid);
5962 +EXPORT_SYMBOL(msm_bus_dbg_client_data);
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
5973 +void msm_bus_dbg_commit_data(const char *fabname, void *cdata,
5974 + int nmasters, int nslaves, int ntslaves, int op)
5976 + struct dentry *file = NULL;
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);
5983 + msm_bus_dbg_fill_fab_buffer(fabname, cdata, nmasters,
5984 + nslaves, ntslaves);
5986 +EXPORT_SYMBOL(msm_bus_dbg_commit_data);
5989 +static int __init msm_bus_debugfs_init(void)
5991 + struct dentry *commit, *shell_client, *rules_dbg;
5992 + struct msm_bus_fab_list *fablist;
5993 + struct msm_bus_cldata *cldata = NULL;
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");
6002 + clients = debugfs_create_dir("client-data", dir);
6003 + if ((!dir) || IS_ERR(dir)) {
6004 + MSM_BUS_ERR("Couldn't create clients\n");
6008 + shell_client = debugfs_create_dir("shell-client", dir);
6009 + if ((!dir) || IS_ERR(dir)) {
6010 + MSM_BUS_ERR("Couldn't create clients\n");
6014 + commit = debugfs_create_dir("commit-data", dir);
6015 + if ((!dir) || IS_ERR(dir)) {
6016 + MSM_BUS_ERR("Couldn't create commit\n");
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");
6026 + if (debugfs_create_file("print_rules", S_IRUGO | S_IWUSR,
6027 + rules_dbg, &val, &rules_dbg_fops) == NULL)
6030 + if (debugfs_create_file("update_request", S_IRUGO | S_IWUSR,
6031 + shell_client, &val, &shell_client_en_fops) == NULL)
6033 + if (debugfs_create_file("ib", S_IRUGO | S_IWUSR, shell_client, &val,
6034 + &shell_client_ib_fops) == NULL)
6036 + if (debugfs_create_file("ab", S_IRUGO | S_IWUSR, shell_client, &val,
6037 + &shell_client_ab_fops) == NULL)
6039 + if (debugfs_create_file("slv", S_IRUGO | S_IWUSR, shell_client,
6040 + &val, &shell_client_slv_fops) == NULL)
6042 + if (debugfs_create_file("mas", S_IRUGO | S_IWUSR, shell_client,
6043 + &val, &shell_client_mas_fops) == NULL)
6045 + if (debugfs_create_file("update-request", S_IRUGO | S_IWUSR,
6046 + clients, NULL, &msm_bus_dbg_update_request_fops) == NULL)
6049 + rules_buf = kzalloc(MAX_BUFF_SIZE, GFP_KERNEL);
6051 + MSM_BUS_ERR("Failed to alloc rules_buf");
6055 + list_for_each_entry(cldata, &cl_list, list) {
6056 + if (cldata->pdata->name == NULL) {
6057 + MSM_BUS_DBG("Client name not found\n");
6060 + cldata->file = msm_bus_dbg_create(cldata->
6061 + pdata->name, S_IRUGO, clients, cldata->clid);
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");
6074 + mutex_unlock(&msm_bus_dbg_fablist_lock);
6076 + msm_bus_dbg_init_vectors();
6079 + debugfs_remove_recursive(dir);
6082 +late_initcall(msm_bus_debugfs_init);
6084 +static void __exit msm_bus_dbg_teardown(void)
6086 + struct msm_bus_fab_list *fablist = NULL, *fablist_temp;
6087 + struct msm_bus_cldata *cldata = NULL, *cldata_temp;
6089 + debugfs_remove_recursive(dir);
6090 + list_for_each_entry_safe(cldata, cldata_temp, &cl_list, list) {
6091 + list_del(&cldata->list);
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);
6100 + mutex_unlock(&msm_bus_dbg_fablist_lock);
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>");
6107 +++ b/drivers/bus/msm_bus/msm_bus_fabric_adhoc.c
6109 +/* Copyright (c) 2014, Linux Foundation. All rights reserved.
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.
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.
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"
6134 +ssize_t vrail_show(struct device *dev, struct device_attribute *attr,
6137 + struct msm_bus_node_info_type *node_info = NULL;
6138 + struct msm_bus_node_device_type *bus_node = NULL;
6140 + bus_node = dev->platform_data;
6143 + node_info = bus_node->node_info;
6145 + return snprintf(buf, PAGE_SIZE, "%u", node_info->vrail_comp);
6148 +ssize_t vrail_store(struct device *dev, struct device_attribute *attr,
6149 + const char *buf, size_t count)
6151 + struct msm_bus_node_info_type *node_info = NULL;
6152 + struct msm_bus_node_device_type *bus_node = NULL;
6155 + bus_node = dev->platform_data;
6158 + node_info = bus_node->node_info;
6160 + ret = sscanf(buf, "%u", &node_info->vrail_comp);
6166 +DEVICE_ATTR(vrail, 0600, vrail_show, vrail_store);
6168 +struct static_rules_type {
6170 + struct bus_rule_type *rules;
6173 +static struct static_rules_type static_rules;
6175 +static int enable_nodeclk(struct nodeclk *nclk)
6179 + if (!nclk->enable) {
6180 + ret = clk_prepare_enable(nclk->clk);
6183 + MSM_BUS_ERR("%s: failed to enable clk ", __func__);
6184 + nclk->enable = false;
6186 + nclk->enable = true;
6191 +static int disable_nodeclk(struct nodeclk *nclk)
6195 + if (nclk->enable) {
6196 + clk_disable_unprepare(nclk->clk);
6197 + nclk->enable = false;
6202 +static int setrate_nodeclk(struct nodeclk *nclk, long rate)
6206 + ret = clk_set_rate(nclk->clk, rate);
6209 + MSM_BUS_ERR("%s: failed to setrate clk", __func__);
6213 +static int msm_bus_agg_fab_clks(struct device *bus_dev, void *data)
6215 + struct msm_bus_node_device_type *node = NULL;
6217 + int ctx = *(int *)data;
6219 + if (ctx >= NUM_CTX) {
6220 + MSM_BUS_ERR("%s: Invalid Context %d", __func__, ctx);
6221 + goto exit_agg_fab_clks;
6224 + node = bus_dev->platform_data;
6226 + MSM_BUS_ERR("%s: Can't get device info", __func__);
6227 + goto exit_agg_fab_clks;
6230 + if (!node->node_info->is_fab_dev) {
6231 + struct msm_bus_node_device_type *bus_dev = NULL;
6233 + bus_dev = node->node_info->bus_device->platform_data;
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];
6243 +static int msm_bus_reset_fab_clks(struct device *bus_dev, void *data)
6245 + struct msm_bus_node_device_type *node = NULL;
6247 + int ctx = *(int *)data;
6249 + if (ctx >= NUM_CTX) {
6250 + MSM_BUS_ERR("%s: Invalid Context %d", __func__, ctx);
6251 + goto exit_reset_fab_clks;
6254 + node = bus_dev->platform_data;
6256 + MSM_BUS_ERR("%s: Can't get device info", __func__);
6257 + goto exit_reset_fab_clks;
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);
6264 +exit_reset_fab_clks:
6269 +static int send_rpm_msg(struct device *device)
6274 + struct msm_bus_node_device_type *ndev =
6275 + device->platform_data;
6276 + struct msm_rpm_kvp rpm_kvp;
6279 + MSM_BUS_ERR("%s: Error getting node info.", __func__);
6281 + goto exit_send_rpm_msg;
6284 + rpm_kvp.length = sizeof(uint64_t);
6285 + rpm_kvp.key = RPM_MASTER_FIELD_BW;
6287 + for (ctx = MSM_RPM_CTX_ACTIVE_SET; ctx <= MSM_RPM_CTX_SLEEP_SET;
6289 + if (ctx == MSM_RPM_CTX_ACTIVE_SET)
6291 + (uint8_t *)&ndev->node_ab.ab[MSM_RPM_CTX_ACTIVE_SET];
6294 + (uint8_t *) &ndev->node_ab.ab[MSM_RPM_CTX_SLEEP_SET];
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);
6302 + MSM_BUS_ERR("%s: Failed to send RPM message:",
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;
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);
6316 + MSM_BUS_ERR("%s: Failed to send RPM message:",
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;
6329 +static int flush_bw_data(struct device *node_device, int ctx)
6331 + struct msm_bus_node_device_type *node_info;
6334 + node_info = node_device->platform_data;
6336 + MSM_BUS_ERR("%s: Unable to find bus device for device",
6339 + goto exit_flush_bw_data;
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;
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,
6354 + fabdev->base_offset,
6356 + fabdev->qos_freq);
6358 + ret = send_rpm_msg(node_device);
6361 + MSM_BUS_ERR("%s: Failed to send RPM msg for%d",
6362 + __func__, node_info->node_info->id);
6364 + node_info->node_ab.dirty = false;
6367 +exit_flush_bw_data:
6372 +static int flush_clk_data(struct device *node_device, int ctx)
6374 + struct msm_bus_node_device_type *node;
6375 + struct nodeclk *nodeclk = NULL;
6378 + node = node_device->platform_data;
6380 + MSM_BUS_ERR("Unable to find bus device");
6382 + goto exit_flush_clk_data;
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;
6393 + if (nodeclk && nodeclk->clk && nodeclk->dirty) {
6394 + long rounded_rate;
6396 + if (nodeclk->rate) {
6397 + rounded_rate = clk_round_rate(nodeclk->clk,
6399 + ret = setrate_nodeclk(nodeclk, rounded_rate);
6402 + MSM_BUS_ERR("%s: Failed to set_rate %lu for %d",
6403 + __func__, rounded_rate,
6404 + node->node_info->id);
6406 + goto exit_flush_clk_data;
6409 + ret = enable_nodeclk(nodeclk);
6411 + ret = disable_nodeclk(nodeclk);
6414 + MSM_BUS_ERR("%s: Failed to enable for %d", __func__,
6415 + node->node_info->id);
6417 + goto exit_flush_clk_data;
6419 + MSM_BUS_DBG("%s: Updated %d clk to %llu", __func__,
6420 + node->node_info->id, nodeclk->rate);
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;
6429 + nodeclk->dirty = 0;
6433 +int msm_bus_commit_data(int *dirty_nodes, int ctx, int num_dirty)
6438 + /* Aggregate the bus clocks */
6439 + bus_for_each_dev(&msm_bus_type, NULL, (void *)&ctx,
6440 + msm_bus_agg_fab_clks);
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);
6448 + if (!node_device) {
6449 + MSM_BUS_ERR("Can't find device for %d", dirty_nodes[i]);
6453 + ret = flush_bw_data(node_device, ctx);
6455 + MSM_BUS_ERR("%s: Error flushing bw data for node %d",
6456 + __func__, dirty_nodes[i]);
6458 + ret = flush_clk_data(node_device, ctx);
6460 + MSM_BUS_ERR("%s: Error flushing clk data for node %d",
6461 + __func__, dirty_nodes[i]);
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);
6470 +void *msm_bus_realloc_devmem(struct device *dev, void *p, size_t old_size,
6471 + size_t new_size, gfp_t flags)
6474 + size_t copy_size = old_size;
6477 + devm_kfree(dev, p);
6478 + return ZERO_SIZE_PTR;
6481 + if (new_size < old_size)
6482 + copy_size = new_size;
6484 + ret = devm_kzalloc(dev, new_size, flags);
6486 + MSM_BUS_ERR("%s: Error Reallocating memory", __func__);
6487 + goto exit_realloc_devmem;
6490 + memcpy(ret, p, copy_size);
6491 + devm_kfree(dev, p);
6492 +exit_realloc_devmem:
6497 +static int add_dirty_node(int **dirty_nodes, int id, int *num_dirty)
6502 + int *dnode = NULL;
6504 + for (i = 0; i < *num_dirty; i++) {
6505 + if ((*dirty_nodes)[i] == id) {
6514 + krealloc(*dirty_nodes, sizeof(int) * (*num_dirty),
6517 + if (ZERO_OR_NULL_PTR(dnode)) {
6518 + MSM_BUS_ERR("%s: Failure allocating dirty nodes array",
6522 + *dirty_nodes = dnode;
6523 + (*dirty_nodes)[(*num_dirty) - 1] = id;
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)
6535 + uint64_t cur_ab_slp = 0;
6536 + uint64_t cur_ab_act = 0;
6538 + if (nodedev->node_info->virt_dev)
6539 + goto exit_update_bw;
6541 + for (i = 0; i < NUM_CTX; i++) {
6542 + for (j = 0; j < nodedev->num_lnodes; j++) {
6543 + if (i == DUAL_CTX) {
6545 + nodedev->lnode_list[j].lnode_ab[i];
6547 + nodedev->lnode_list[j].lnode_ab[i];
6550 + nodedev->lnode_list[j].lnode_ab[i];
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,
6562 + MSM_BUS_ERR("%s: Failed to add dirty node %d", __func__,
6563 + nodedev->node_info->id);
6564 + goto exit_update_bw;
6572 +int msm_bus_update_clks(struct msm_bus_node_device_type *nodedev,
6573 + int ctx, int **dirty_nodes, int *num_dirty)
6576 + struct nodeclk *nodeclk;
6577 + struct nodeclk *busclk;
6578 + struct msm_bus_node_device_type *bus_info = NULL;
6581 + bus_info = nodedev->node_info->bus_device->platform_data;
6584 + MSM_BUS_ERR("%s: Unable to find bus device for device %d",
6585 + __func__, nodedev->node_info->id);
6587 + goto exit_set_clks;
6590 + req_clk = nodedev->cur_clk_hz[ctx];
6591 + busclk = &bus_info->clk[ctx];
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,
6602 + MSM_BUS_ERR("%s: Failed to add dirty node %d", __func__,
6603 + bus_info->node_info->id);
6604 + goto exit_set_clks;
6608 + req_clk = nodedev->cur_clk_hz[ctx];
6609 + nodeclk = &nodedev->clk[ctx];
6611 + if (IS_ERR_OR_NULL(nodeclk))
6612 + goto exit_set_clks;
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,
6622 + MSM_BUS_ERR("%s: Failed to add dirty node %d", __func__,
6623 + nodedev->node_info->id);
6624 + goto exit_set_clks;
6632 +static void msm_bus_fab_init_noc_ops(struct msm_bus_node_device_type *bus_dev)
6634 + switch (bus_dev->fabdev->bus_type) {
6636 + msm_bus_noc_set_ops(bus_dev);
6638 + case MSM_BUS_BIMC:
6639 + msm_bus_bimc_set_ops(bus_dev);
6642 + MSM_BUS_ERR("%s: Invalid Bus type", __func__);
6646 +static int msm_bus_qos_disable_clk(struct msm_bus_node_device_type *node,
6647 + int disable_bus_qos_clk)
6649 + struct msm_bus_node_device_type *bus_node = NULL;
6654 + goto exit_disable_qos_clk;
6657 + bus_node = node->node_info->bus_device->platform_data;
6661 + goto exit_disable_qos_clk;
6664 + if (disable_bus_qos_clk)
6665 + ret = disable_nodeclk(&bus_node->clk[DUAL_CTX]);
6668 + MSM_BUS_ERR("%s: Failed to disable bus clk, node %d",
6669 + __func__, node->node_info->id);
6670 + goto exit_disable_qos_clk;
6673 + if (!IS_ERR_OR_NULL(node->qos_clk.clk)) {
6674 + ret = disable_nodeclk(&node->qos_clk);
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;
6683 +exit_disable_qos_clk:
6687 +static int msm_bus_qos_enable_clk(struct msm_bus_node_device_type *node)
6689 + struct msm_bus_node_device_type *bus_node = NULL;
6690 + long rounded_rate;
6692 + int bus_qos_enabled = 0;
6696 + goto exit_enable_qos_clk;
6699 + bus_node = node->node_info->bus_device->platform_data;
6703 + goto exit_enable_qos_clk;
6706 + /* Check if the bus clk is already set before trying to set it
6707 + * Do this only during
6709 + * b. Only for bus clks
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);
6715 + MSM_BUS_ERR("%s: Failed to set bus clk, node %d",
6716 + __func__, node->node_info->id);
6717 + goto exit_enable_qos_clk;
6720 + ret = enable_nodeclk(&bus_node->clk[DUAL_CTX]);
6722 + MSM_BUS_ERR("%s: Failed to enable bus clk, node %d",
6723 + __func__, node->node_info->id);
6724 + goto exit_enable_qos_clk;
6726 + bus_qos_enabled = 1;
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);
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;
6738 + ret = enable_nodeclk(&node->qos_clk);
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;
6745 + ret = bus_qos_enabled;
6747 +exit_enable_qos_clk:
6751 +int msm_bus_enable_limiter(struct msm_bus_node_device_type *node_dev,
6752 + bool enable, uint64_t lim_bw)
6755 + struct msm_bus_node_device_type *bus_node_dev;
6758 + MSM_BUS_ERR("No device specified");
6760 + goto exit_enable_limiter;
6763 + if (!node_dev->ap_owned) {
6764 + MSM_BUS_ERR("Device is not AP owned %d.",
6765 + node_dev->node_info->id);
6767 + goto exit_enable_limiter;
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);
6775 + goto exit_enable_limiter;
6777 + if (bus_node_dev->fabdev &&
6778 + bus_node_dev->fabdev->noc_ops.limit_mport) {
6779 + ret = msm_bus_qos_enable_clk(node_dev);
6781 + MSM_BUS_ERR("Can't Enable QoS clk %d",
6782 + node_dev->node_info->id);
6783 + goto exit_enable_limiter;
6785 + bus_node_dev->fabdev->noc_ops.limit_mport(
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,
6792 + msm_bus_qos_disable_clk(node_dev, ret);
6795 +exit_enable_limiter:
6799 +static int msm_bus_dev_init_qos(struct device *dev, void *data)
6802 + struct msm_bus_node_device_type *node_dev = NULL;
6804 + node_dev = dev->platform_data;
6807 + MSM_BUS_ERR("%s: Unable to get node device info" , __func__);
6809 + goto exit_init_qos;
6812 + MSM_BUS_DBG("Device = %d", node_dev->node_info->id);
6814 + if (node_dev->ap_owned) {
6815 + struct msm_bus_node_device_type *bus_node_info;
6817 + bus_node_info = node_dev->node_info->bus_device->platform_data;
6819 + if (!bus_node_info) {
6820 + MSM_BUS_ERR("%s: Unable to get bus device infofor %d",
6822 + node_dev->node_info->id);
6824 + goto exit_init_qos;
6827 + if (bus_node_info->fabdev &&
6828 + bus_node_info->fabdev->noc_ops.qos_init) {
6831 + if (node_dev->ap_owned &&
6832 + (node_dev->node_info->qos_params.mode) != -1) {
6834 + if (bus_node_info->fabdev->bypass_qos_prg)
6835 + goto exit_init_qos;
6837 + ret = msm_bus_qos_enable_clk(node_dev);
6839 + MSM_BUS_ERR("Can't Enable QoS clk %d",
6840 + node_dev->node_info->id);
6841 + goto exit_init_qos;
6844 + bus_node_info->fabdev->noc_ops.qos_init(
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);
6853 + MSM_BUS_ERR("%s: Skipping QOS init for %d",
6854 + __func__, node_dev->node_info->id);
6860 +static int msm_bus_fabric_init(struct device *dev,
6861 + struct msm_bus_node_device_type *pdata)
6863 + struct msm_bus_fab_device_type *fabdev;
6864 + struct msm_bus_node_device_type *node_dev = NULL;
6867 + node_dev = dev->platform_data;
6869 + MSM_BUS_ERR("%s: Unable to get bus device info" , __func__);
6871 + goto exit_fabric_init;
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;
6880 + fabdev = devm_kzalloc(dev, sizeof(struct msm_bus_fab_device_type),
6883 + MSM_BUS_ERR("Fabric alloc failed\n");
6885 + goto exit_fabric_init;
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);
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",
6905 + (size_t)fabdev->pqos_base, node_dev->node_info->id);
6907 + goto exit_fabric_init;
6910 + /*if (msmbus_coresight_init(pdev))
6911 + pr_warn("Coresight support absent for bus: %d\n", pdata->id);*/
6916 +static int msm_bus_init_clk(struct device *bus_dev,
6917 + struct msm_bus_node_device_type *pdata)
6921 + struct msm_bus_node_device_type *node_dev = bus_dev->platform_data;
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);
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);
6943 +static int msm_bus_copy_node_info(struct msm_bus_node_device_type *pdata,
6944 + struct device *bus_dev)
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;
6951 + bus_node = bus_dev->platform_data;
6953 + if (!bus_node || !pdata) {
6955 + MSM_BUS_ERR("%s: Invalid pointers pdata %p, bus_node %p",
6956 + __func__, pdata, bus_node);
6957 + goto exit_copy_node_info;
6960 + node_info = bus_node->node_info;
6961 + pdata_node_info = pdata->node_info;
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;
6987 + node_info->dev_connections = devm_kzalloc(bus_dev,
6988 + sizeof(struct device *) *
6989 + pdata_node_info->num_connections,
6991 + if (!node_info->dev_connections) {
6992 + MSM_BUS_ERR("%s:Bus dev connections alloc failed\n", __func__);
6994 + goto exit_copy_node_info;
6997 + node_info->connections = devm_kzalloc(bus_dev,
6998 + sizeof(int) * pdata_node_info->num_connections,
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);
7004 + goto exit_copy_node_info;
7007 + memcpy(node_info->connections,
7008 + pdata_node_info->connections,
7009 + sizeof(int) * pdata_node_info->num_connections);
7011 + node_info->black_connections = devm_kzalloc(bus_dev,
7012 + sizeof(struct device *) *
7013 + pdata_node_info->num_blist,
7015 + if (!node_info->black_connections) {
7016 + MSM_BUS_ERR("%s: Bus black connections alloc failed\n",
7018 + devm_kfree(bus_dev, node_info->dev_connections);
7019 + devm_kfree(bus_dev, node_info->connections);
7021 + goto exit_copy_node_info;
7024 + node_info->black_listed_connections = devm_kzalloc(bus_dev,
7025 + pdata_node_info->num_blist * sizeof(int),
7027 + if (!node_info->black_listed_connections) {
7028 + MSM_BUS_ERR("%s:Bus black list connections alloc failed\n",
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);
7034 + goto exit_copy_node_info;
7037 + memcpy(node_info->black_listed_connections,
7038 + pdata_node_info->black_listed_connections,
7039 + sizeof(int) * pdata_node_info->num_blist);
7041 + node_info->qport = devm_kzalloc(bus_dev,
7042 + sizeof(int) * pdata_node_info->num_qports,
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);
7050 + goto exit_copy_node_info;
7053 + memcpy(node_info->qport,
7054 + pdata_node_info->qport,
7055 + sizeof(int) * pdata_node_info->num_qports);
7057 +exit_copy_node_info:
7061 +static struct device *msm_bus_device_init(
7062 + struct msm_bus_node_device_type *pdata)
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;
7069 + bus_dev = kzalloc(sizeof(struct device), GFP_KERNEL);
7071 + MSM_BUS_ERR("%s:Device alloc failed\n", __func__);
7073 + goto exit_device_init;
7076 + * Init here so we can use devm calls
7078 + device_initialize(bus_dev);
7080 + bus_node = devm_kzalloc(bus_dev,
7081 + sizeof(struct msm_bus_node_device_type), GFP_KERNEL);
7083 + MSM_BUS_ERR("%s:Bus node alloc failed\n", __func__);
7086 + goto exit_device_init;
7089 + node_info = devm_kzalloc(bus_dev,
7090 + sizeof(struct msm_bus_node_info_type), GFP_KERNEL);
7092 + MSM_BUS_ERR("%s:Bus node info alloc failed\n", __func__);
7093 + devm_kfree(bus_dev, bus_node);
7096 + goto exit_device_init;
7099 + bus_node->node_info = node_info;
7100 + bus_node->ap_owned = pdata->ap_owned;
7101 + bus_dev->platform_data = bus_node;
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);
7108 + goto exit_device_init;
7111 + bus_dev->bus = &msm_bus_type;
7112 + dev_set_name(bus_dev, bus_node->node_info->name);
7114 + ret = device_add(bus_dev);
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);
7126 + goto exit_device_init;
7128 + device_create_file(bus_dev, &dev_attr_vrail);
7134 +static int msm_bus_setup_dev_conn(struct device *bus_dev, void *data)
7136 + struct msm_bus_node_device_type *bus_node = NULL;
7140 + bus_node = bus_dev->platform_data;
7142 + MSM_BUS_ERR("%s: Can't get device info", __func__);
7144 + goto exit_setup_dev_conn;
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);
7154 + if (!bus_parent_device) {
7155 + MSM_BUS_ERR("%s: Error finding parentdev %d parent %d",
7157 + bus_node->node_info->id,
7158 + bus_node->node_info->bus_device_id);
7160 + goto exit_setup_dev_conn;
7162 + bus_node->node_info->bus_device = bus_parent_device;
7165 + bus_node->node_info->is_traversed = false;
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);
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);
7178 + goto exit_setup_dev_conn;
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);
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);
7195 + goto exit_setup_dev_conn;
7199 +exit_setup_dev_conn:
7203 +static int msm_bus_node_debug(struct device *bus_dev, void *data)
7207 + struct msm_bus_node_device_type *bus_node = NULL;
7209 + bus_node = bus_dev->platform_data;
7211 + MSM_BUS_ERR("%s: Can't get device info", __func__);
7213 + goto exit_node_debug;
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);
7229 +static int msm_bus_device_probe(struct platform_device *pdev)
7231 + unsigned int i, ret;
7232 + struct msm_bus_device_node_registration *pdata;
7234 + /* If possible, get pdata from device-tree */
7235 + if (pdev->dev.of_node)
7236 + pdata = msm_bus_of_to_pdata(pdev);
7238 + pdata = (struct msm_bus_device_node_registration *)pdev->
7239 + dev.platform_data;
7242 + if (IS_ERR_OR_NULL(pdata)) {
7243 + MSM_BUS_ERR("No platform data found");
7245 + goto exit_device_probe;
7248 + for (i = 0; i < pdata->num_devices; i++) {
7249 + struct device *node_dev = NULL;
7251 + node_dev = msm_bus_device_init(&pdata->info[i]);
7254 + MSM_BUS_ERR("%s: Error during dev init for %d",
7255 + __func__, pdata->info[i].node_info->id);
7257 + goto exit_device_probe;
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]);
7267 + MSM_BUS_ERR("%s: Error intializing fab %d",
7268 + __func__, pdata->info[i].node_info->id);
7269 + goto exit_device_probe;
7274 + ret = bus_for_each_dev(&msm_bus_type, NULL, NULL,
7275 + msm_bus_setup_dev_conn);
7277 + MSM_BUS_ERR("%s: Error setting up dev connections", __func__);
7278 + goto exit_device_probe;
7281 + ret = bus_for_each_dev(&msm_bus_type, NULL, NULL, msm_bus_dev_init_qos);
7283 + MSM_BUS_ERR("%s: Error during qos init", __func__);
7284 + goto exit_device_probe;
7287 + bus_for_each_dev(&msm_bus_type, NULL, NULL, msm_bus_node_debug);
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);
7297 +static int msm_bus_device_rules_probe(struct platform_device *pdev)
7299 + struct bus_rule_type *rule_data = NULL;
7300 + int num_rules = 0;
7302 + num_rules = msm_bus_of_get_static_rules(pdev, &rule_data);
7305 + goto exit_rules_probe;
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;
7316 +int msm_bus_device_rules_remove(struct platform_device *pdev)
7318 + struct static_rules_type *static_rules = NULL;
7320 + static_rules = pdev->dev.platform_data;
7322 + msm_rule_unregister(static_rules->num_rules,
7323 + static_rules->rules, NULL);
7327 +static int msm_bus_free_dev(struct device *dev, void *data)
7329 + struct msm_bus_node_device_type *bus_node = NULL;
7331 + bus_node = dev->platform_data;
7334 + MSM_BUS_ERR("\n%s: Removing device %d", __func__,
7335 + bus_node->node_info->id);
7336 + device_unregister(dev);
7340 +int msm_bus_device_remove(struct platform_device *pdev)
7342 + bus_for_each_dev(&msm_bus_type, NULL, NULL, msm_bus_free_dev);
7346 +static struct of_device_id rules_match[] = {
7347 + {.compatible = "qcom,msm-bus-static-bw-rules"},
7351 +static struct platform_driver msm_bus_rules_driver = {
7352 + .probe = msm_bus_device_rules_probe,
7353 + .remove = msm_bus_device_rules_remove,
7355 + .name = "msm_bus_rules_device",
7356 + .owner = THIS_MODULE,
7357 + .of_match_table = rules_match,
7361 +static struct of_device_id fabric_match[] = {
7362 + {.compatible = "qcom,msm-bus-device"},
7366 +static struct platform_driver msm_bus_device_driver = {
7367 + .probe = msm_bus_device_probe,
7368 + .remove = msm_bus_device_remove,
7370 + .name = "msm_bus_device",
7371 + .owner = THIS_MODULE,
7372 + .of_match_table = fabric_match,
7376 +int __init msm_bus_device_init_driver(void)
7380 + MSM_BUS_ERR("msm_bus_fabric_init_driver\n");
7381 + rc = platform_driver_register(&msm_bus_device_driver);
7384 + MSM_BUS_ERR("Failed to register bus device driver");
7387 + return platform_driver_register(&msm_bus_rules_driver);
7389 +subsys_initcall(msm_bus_device_init_driver);
7391 +++ b/drivers/bus/msm_bus/msm_bus_id.c
7393 +/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
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.
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.
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"
7416 +static uint32_t master_iids[MSM_BUS_MASTER_LAST];
7417 +static uint32_t slave_iids[MSM_BUS_SLAVE_LAST - SLAVE_ID_KEY];
7419 +static void msm_bus_assign_iids(struct msm_bus_fabric_registration
7420 + *fabreg, int fabid)
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);
7433 + master_iids[fabreg->info[i].id] =
7434 + fabreg->info[i].priv_id;
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);
7443 + slave_iids[fabreg->info[i].id - (SLAVE_ID_KEY)]
7444 + = fabreg->info[i].priv_id;
7447 + fabreg->info[i].priv_id = fabreg->info[i].id;
7452 +static int msm_bus_get_iid(int id)
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);
7460 + return CHECK_ID(((id < SLAVE_ID_KEY) ? master_iids[id] :
7461 + slave_iids[id - SLAVE_ID_KEY]), id);
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,
7469 +int msm_bus_board_rpm_get_il_ids(uint16_t *id)
7474 +void msm_bus_board_init(struct msm_bus_fabric_registration *pdata)
7476 + pdata->board_algo = &msm_bus_id_algo;
7479 +void msm_bus_board_set_nfab(struct msm_bus_fabric_registration *pdata,
7485 + msm_bus_id_algo.board_nfab = nfab;
7488 +++ b/drivers/bus/msm_bus/msm_bus_noc.c
7490 +/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
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.
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.
7502 +#define pr_fmt(fmt) "AXI: NOC: %s(): " fmt, __func__
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"
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)
7520 +#define NOC_QOS_REG_BASE(b, o) ((b) + (o))
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,
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,
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,
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,
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,
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,
7583 +static int noc_div(uint64_t *a, uint32_t b)
7585 + if ((*a > 0) && (*a < b))
7588 + return do_div(*a, b);
7592 + * Calculates bw hardware is using from register values
7593 + * bw returned is in bytes/sec
7595 +static uint64_t noc_bw(uint32_t bw_field, uint32_t qos_freq)
7598 + uint32_t rem, scale;
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;
7607 +static uint32_t noc_bw_ceil(long int bw_field, uint32_t qos_freq)
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;
7614 +#define MAX_BW(timebase) noc_bw_ceil(MAX_BW_FIELD, (timebase))
7617 + * Calculates ws hardware is using from register values
7618 + * ws returned is in nanoseconds
7620 +static uint32_t noc_ws(uint64_t bw, uint32_t sat, uint32_t qos_freq)
7622 + if (bw && qos_freq) {
7623 + uint32_t bwf = bw * qos_freq;
7624 + uint64_t scale = 1000000000000LL * BW_SCALE *
7626 + noc_div(&scale, bwf);
7627 + MSM_BUS_DBG("NOC: Calculated ws: %llu\n", scale);
7633 +#define MAX_WS(bw, timebase) noc_ws((bw), MAX_SAT_FIELD, (timebase))
7635 +/* Calculate bandwidth field value for requested bandwidth */
7636 +static uint32_t noc_bw_field(uint64_t bw, uint32_t qos_freq)
7638 + uint32_t bw_field = 0;
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;
7646 + rem = noc_div(&bwc, qf);
7647 + bw_field = (uint32_t)min_t(uint64_t, bwc, MAX_BW_FIELD);
7650 + MSM_BUS_DBG("NOC: bw_field: %u\n", bw_field);
7654 +static uint32_t noc_sat_field(uint64_t bw, uint32_t ws, uint32_t qos_freq)
7656 + uint32_t sat_field = 0, win;
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);
7665 + * Calculate saturation from windows size.
7666 + * WS must be at least one arb period.
7667 + * Saturation must not exceed max field size
7669 + * Bandwidth is in 100KB increments
7670 + * Window size is in ns
7671 + * qos_freq is in KHz
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);
7680 + MSM_BUS_DBG("NOC: sat_field: %d\n", sat_field);
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)
7688 + if (mode < NOC_QOS_MODE_MAX &&
7689 + ((1 << mode) & perm_mode)) {
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));
7698 + /* Ensure qos mode is set before exiting */
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)
7706 + uint32_t reg_val, val;
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));
7715 + reg_val = readl_relaxed(NOC_QOS_PRIORITYn_ADDR(base, qos_off, mport,
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 */
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)
7729 + uint32_t reg_val, val, mode;
7732 + MSM_BUS_DBG("Zero QoS Freq\n");
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,
7744 + MSM_BUS_DBG("NOC: BW: perm_mode: %d bw_val: %d, sat_val: %d\n",
7745 + perm_mode, bw_val, sat_val);
7747 + * If in Limiter/Regulator mode, first go to fixed mode.
7748 + * Clear QoS accumulator
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,
7763 + reg_val = readl_relaxed(NOC_QOS_BWn_ADDR(base, qos_off, mport,
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));
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)));
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));
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)));
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
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)
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;
7805 + return 31 - __CLZ(mode &
7806 + NOC_QOS_MODES_ALL_PERM);
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)
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;
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;
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)
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;
7835 + qbw->bw = noc_bw(bw_val, qos_freq);
7836 + qbw->ws = noc_ws(qbw->bw, sat, qos_freq);
7843 +static int msm_bus_noc_mas_init(struct msm_bus_noc_info *ninfo,
7844 + struct msm_bus_inode_info *info)
7847 + struct msm_bus_noc_qos_priority *prio;
7848 + prio = kzalloc(sizeof(struct msm_bus_noc_qos_priority),
7851 + MSM_BUS_WARN("Couldn't alloc prio data for node: %d\n",
7852 + info->node_info->id);
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;
7862 + if (!info->node_info->qport) {
7863 + MSM_BUS_DBG("No QoS Ports to init\n");
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,
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;
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,
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);
7895 +static void msm_bus_noc_node_init(void *hw_data,
7896 + struct msm_bus_inode_info *info)
7898 + struct msm_bus_noc_info *ninfo =
7899 + (struct msm_bus_noc_info *)hw_data;
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);
7906 +static int msm_bus_noc_allocate_commit_data(struct msm_bus_fabric_registration
7907 + *fab_pdata, void **cdata, int ctx)
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;
7913 + *cd = kzalloc(sizeof(struct msm_bus_noc_commit), GFP_KERNEL);
7915 + MSM_BUS_DBG("Couldn't alloc mem for cdata\n");
7919 + (*cd)->mas = ninfo->cdata[ctx].mas;
7920 + (*cd)->slv = ninfo->cdata[ctx].slv;
7925 +static void *msm_bus_noc_allocate_noc_data(struct platform_device *pdev,
7926 + struct msm_bus_fabric_registration *fab_pdata)
7928 + struct resource *noc_mem;
7929 + struct resource *noc_io;
7930 + struct msm_bus_noc_info *ninfo;
7933 + ninfo = kzalloc(sizeof(struct msm_bus_noc_info), GFP_KERNEL);
7935 + MSM_BUS_DBG("Couldn't alloc mem for noc info\n");
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;
7944 + if (!fab_pdata->qos_baseoffset)
7945 + ninfo->qos_baseoffset = QOS_DEFAULT_BASEOFFSET;
7947 + ninfo->qos_baseoffset = fab_pdata->qos_baseoffset;
7949 + if (!fab_pdata->qos_delta)
7950 + ninfo->qos_delta = QOS_DEFAULT_DELTA;
7952 + ninfo->qos_delta = fab_pdata->qos_delta;
7954 + ninfo->mas_modes = kzalloc(sizeof(uint32_t) * fab_pdata->nmasters,
7956 + if (!ninfo->mas_modes) {
7957 + MSM_BUS_DBG("Couldn't alloc mem for noc master-modes\n");
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,
7966 + if (!ninfo->cdata[i].mas) {
7967 + MSM_BUS_DBG("Couldn't alloc mem for noc master-bw\n");
7968 + kfree(ninfo->mas_modes);
7973 + ninfo->cdata[i].slv = kzalloc(sizeof(struct
7974 + msm_bus_node_hw_info) * fab_pdata->nslaves * 2,
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);
7983 + /* If it's a virtual fabric, don't get memory info */
7984 + if (fab_pdata->virt)
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");
7993 + noc_io = request_mem_region(noc_mem->start,
7994 + resource_size(noc_mem), pdev->name);
7996 + MSM_BUS_ERR("NoC memory unavailable\n");
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));
8008 + fab_pdata->hw_data = (void *)ninfo;
8009 + return (void *)ninfo;
8012 + kfree(ninfo->mas_modes);
8017 +static void free_commit_data(void *cdata)
8019 + struct msm_bus_noc_commit *cd = (struct msm_bus_noc_commit *)cdata;
8026 +static bool msm_bus_noc_update_bw_reg(int mode)
8030 + if ((mode == NOC_QOS_MODE_LIMITER) ||
8031 + (mode == NOC_QOS_MODE_REGULATOR))
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,
8043 + struct msm_bus_noc_info *ninfo;
8044 + struct msm_bus_noc_qos_bw qos_bw;
8047 + struct msm_bus_noc_commit *sel_cd =
8048 + (struct msm_bus_noc_commit *)sel_cdata;
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");
8056 + if (info->node_info->num_mports == 0) {
8057 + MSM_BUS_DBG("NOC: Skip Master BW\n");
8061 + ports = info->node_info->num_mports;
8062 + bw = INTERLEAVED_BW(fab_pdata, add_bw, ports);
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,
8074 + /* Check if info is a shared master.
8075 + * If it is, mark it dirty
8076 + * If it isn't, then set QOS Bandwidth
8078 + if (info->node_info->hw_sel == MSM_BUS_RPM)
8079 + sel_cd->mas[info->node_info->masterp[i]].dirty = 1;
8081 + if (!info->node_info->qport) {
8082 + MSM_BUS_DBG("No qos ports to update!\n");
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");
8092 + qos_bw.bw = sel_cd->mas[info->node_info->masterp[i]].
8094 + qos_bw.ws = info->node_info->ws;
8095 + msm_bus_noc_set_qos_bw(ninfo->base,
8096 + ninfo->qos_baseoffset,
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",
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.
8121 + if (hop->node_info->hw_sel == MSM_BUS_RPM)
8122 + sel_cd->slv[hop->node_info->slavep[i]].dirty = 1;
8126 +static int msm_bus_noc_commit(struct msm_bus_fabric_registration
8127 + *fab_pdata, void *hw_data, void **cdata)
8129 + MSM_BUS_DBG("\nReached NOC Commit\n");
8130 + msm_bus_remote_hw_commit(fab_pdata, hw_data, cdata);
8134 +static int msm_bus_noc_port_halt(uint32_t haltid, uint8_t mport)
8139 +static int msm_bus_noc_port_unhalt(uint32_t haltid, uint8_t mport)
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)
8149 + struct msm_bus_noc_qos_priority prio;
8153 + prio.p1 = info->node_info->qos_params.prio1;
8154 + prio.p0 = info->node_info->qos_params.prio0;
8156 + if (!info->node_info->qport) {
8157 + MSM_BUS_DBG("No QoS Ports to init\n");
8159 + goto err_qos_init;
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,
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;
8173 + msm_bus_noc_set_qos_bw(qos_base, qos_off,
8175 + info->node_info->qport[i],
8177 + info->node_info->qos_params.mode,
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));
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)
8198 + struct msm_bus_node_info_type *info = dev->node_info;
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;
8206 + bw = msm_bus_div64(info->num_qports,
8207 + dev->node_ab.ab[DUAL_CTX]);
8209 + for (i = 0; i < info->num_qports; i++) {
8210 + if (!info->qport) {
8211 + MSM_BUS_DBG("No qos ports to update!\n");
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",
8226 +int msm_bus_noc_hw_init(struct msm_bus_fabric_registration *pdata,
8227 + struct msm_bus_hw_algorithm *hw_algo)
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;
8246 +int msm_bus_noc_set_ops(struct msm_bus_node_device_type *bus_dev)
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;
8259 +EXPORT_SYMBOL(msm_bus_noc_set_ops);
8261 +++ b/drivers/bus/msm_bus/msm_bus_noc.h
8263 +/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
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.
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.
8275 +#ifndef _ARCH_ARM_MACH_MSM_BUS_BIMC_H
8276 +#define _ARCH_ARM_MACH_MSM_BUS_BIMC_H
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,
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),
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)
8297 +struct msm_bus_noc_commit {
8298 + struct msm_bus_node_hw_info *mas;
8299 + struct msm_bus_node_hw_info *slv;
8302 +struct msm_bus_noc_info {
8303 + void __iomem *base;
8304 + uint32_t base_addr;
8305 + uint32_t nmasters;
8306 + uint32_t nqos_masters;
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];
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;
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 */
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 */
8340 +++ b/drivers/bus/msm_bus/msm_bus_of.c
8342 +/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
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.
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.
8354 +#define pr_fmt(fmt) "AXI: %s(): " fmt, __func__
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"
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};
8370 +static int get_num(const char *const str[], const char *name)
8375 + if (!strcmp(name, str[i]))
8379 + } while (str[i] != NULL);
8381 + pr_err("Error: string %s not found\n", name);
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)
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;
8396 + pr_err("Error: Null Platform device\n");
8400 + pdata = devm_kzalloc(&pdev->dev, sizeof(struct msm_bus_scale_pdata),
8403 + pr_err("Error: Memory allocation for pdata failed\n");
8408 + ret = of_property_read_string(of_node, "qcom,msm-bus,name",
8411 + pr_err("Error: Client name not found\n");
8415 + ret = of_property_read_u32(of_node, "qcom,msm-bus,num-cases",
8418 + pr_err("Error: num-usecases not found\n");
8422 + pdata->num_usecases = num_usecases;
8424 + if (of_property_read_bool(of_node, "qcom,msm-bus,active-only"))
8425 + pdata->active_only = 1;
8427 + pr_debug("active_only flag absent.\n");
8428 + pr_debug("Using dual context by default\n");
8431 + usecase = devm_kzalloc(&pdev->dev, (sizeof(struct msm_bus_paths) *
8432 + pdata->num_usecases), GFP_KERNEL);
8434 + pr_err("Error: Memory allocation for paths failed\n");
8439 + ret = of_property_read_u32(of_node, "qcom,msm-bus,num-paths",
8442 + pr_err("Error: num_paths not found\n");
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");
8452 + if (len != num_usecases * num_paths * sizeof(uint32_t) * 4) {
8453 + pr_err("Error: Length-error on getting vectors\n");
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) {
8463 + pr_err("Error: Mem alloc failure in vectors\n");
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]));
8479 + pdata->usecase = usecase;
8483 + for (; i > 0; i--)
8484 + kfree(usecase[i-1].vectors);
8494 + * msm_bus_cl_get_pdata() - Generate bus client data from device tree
8495 + * provided by clients.
8497 + * of_node: Device tree node to extract information from
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
8504 +struct msm_bus_scale_pdata *msm_bus_cl_get_pdata(struct platform_device *pdev)
8506 + struct device_node *of_node;
8507 + struct msm_bus_scale_pdata *pdata = NULL;
8510 + pr_err("Error: Null Platform device\n");
8514 + of_node = pdev->dev.of_node;
8515 + pdata = get_pdata(pdev, of_node);
8517 + pr_err("client has to provide missing entry for successful registration\n");
8523 +EXPORT_SYMBOL(msm_bus_cl_get_pdata);
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.
8531 + * of_node: The subnode containing information about the bus scaling
8534 + * pdev: Platform device associated with the device-tree node
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
8541 +struct msm_bus_scale_pdata *msm_bus_pdata_from_node(
8542 + struct platform_device *pdev, struct device_node *of_node)
8544 + struct msm_bus_scale_pdata *pdata = NULL;
8547 + pr_err("Error: Null Platform device\n");
8552 + pr_err("Error: Null of_node passed to bus driver\n");
8556 + pdata = get_pdata(pdev, of_node);
8558 + pr_err("client has to provide missing entry for successful registration\n");
8564 +EXPORT_SYMBOL(msm_bus_pdata_from_node);
8567 + * msm_bus_cl_clear_pdata() - Clear pdata allocated from device-tree
8568 + * of_node: Device tree node to extract information from
8570 +void msm_bus_cl_clear_pdata(struct msm_bus_scale_pdata *pdata)
8574 + for (i = 0; i < pdata->num_usecases; i++)
8575 + kfree(pdata->usecase[i].vectors);
8577 + kfree(pdata->usecase);
8580 +EXPORT_SYMBOL(msm_bus_cl_clear_pdata);
8583 +static int *get_arr(struct platform_device *pdev,
8584 + const struct device_node *node, const char *prop,
8587 + int size = 0, ret;
8590 + if (of_get_property(node, prop, &size)) {
8591 + *nports = size / sizeof(int);
8593 + pr_debug("Property %s not available\n", prop);
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);
8609 + ret = of_property_read_u32_array(node, prop, (u32 *)arr, *nports);
8611 + pr_err("Error in reading property: %s\n", prop);
8617 + devm_kfree(&pdev->dev, arr);
8621 +static u64 *get_th_params(struct platform_device *pdev,
8622 + const struct device_node *node, const char *prop,
8625 + int size = 0, ret;
8626 + u64 *ret_arr = NULL;
8630 + if (of_get_property(node, prop, &size)) {
8631 + *nports = size / sizeof(int);
8633 + pr_debug("Property %s not available\n", prop);
8643 + ret_arr = devm_kzalloc(&pdev->dev, (*nports * sizeof(u64)),
8645 + if (ZERO_OR_NULL_PTR(ret_arr)) {
8646 + pr_err("Error: Failed to alloc mem for ret arr %s\n", prop);
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);
8656 + ret = of_property_read_u32_array(node, prop, (u32 *)arr, *nports);
8658 + pr_err("Error in reading property: %s\n", prop);
8662 + for (i = 0; i < *nports; i++)
8663 + ret_arr[i] = (uint64_t)KBTOB(arr[i]);
8665 + MSM_BUS_DBG("%s: num entries %d prop %s", __func__, *nports, prop);
8667 + for (i = 0; i < *nports; i++)
8668 + MSM_BUS_DBG("Th %d val %llu", i, ret_arr[i]);
8674 + devm_kfree(&pdev->dev, ret_arr);
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)
8682 + struct msm_bus_node_info *info;
8683 + struct device_node *child_node = NULL;
8688 + for_each_child_of_node(of_node, child_node) {
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);
8702 + child_node = NULL;
8703 + for_each_child_of_node(of_node, child_node) {
8704 + const char *sel_str;
8706 + ret = of_property_read_string(child_node, "label",
8709 + pr_err("Error reading node label\n");
8711 + ret = of_property_read_u32(child_node, "cell-id", &info[i].id);
8713 + pr_err("Error reading node id\n");
8717 + if (of_property_read_bool(child_node, "qcom,gateway"))
8718 + info[i].gateway = 1;
8720 + of_property_read_u32(child_node, "qcom,mas-hw-id",
8721 + &info[i].mas_hw_id);
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;
8733 + info[i].slavep = get_arr(pdev, child_node,
8734 + "qcom,slavep", &info[i].num_sports);
8735 + pdata->nslaves += info[i].num_sports;
8738 + info[i].tier = get_arr(pdev, child_node,
8739 + "qcom,tier", &info[i].num_tiers);
8741 + if (of_property_read_bool(child_node, "qcom,ahb"))
8744 + ret = of_property_read_string(child_node, "qcom,hw-sel",
8747 + info[i].hw_sel = 0;
8749 + ret = get_num(hw_sel_name, sel_str);
8751 + pr_err("Invalid hw-sel\n");
8755 + info[i].hw_sel = ret;
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);
8762 + info[i].dual_conf =
8763 + of_property_read_bool(child_node, "qcom,dual-conf");
8766 + info[i].th = get_th_params(pdev, child_node, "qcom,thresh",
8767 + &info[i].num_thresh);
8769 + info[i].bimc_bw = get_th_params(pdev, child_node,
8770 + "qcom,bimc,bw", &num_bw);
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);
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);
8785 + ret = of_property_read_string(child_node, "qcom,mode-thresh",
8788 + info[i].mode_thresh = 0;
8790 + ret = get_num(mode_sel_name, sel_str);
8792 + pr_err("Unknown mode :%s\n", sel_str);
8796 + info[i].mode_thresh = ret;
8797 + MSM_BUS_DBG("AXI: THreshold mode set: %d\n",
8798 + info[i].mode_thresh);
8801 + ret = of_property_read_string(child_node, "qcom,mode",
8807 + ret = get_num(mode_sel_name, sel_str);
8809 + pr_err("Unknown mode :%s\n", sel_str);
8813 + info[i].mode = ret;
8817 + of_property_read_bool(child_node, "qcom,nr-lim");
8819 + ret = of_property_read_u32(child_node, "qcom,ff",
8822 + pr_debug("fudge factor not present %d", info[i].id);
8826 + ret = of_property_read_u32(child_node, "qcom,floor-bw",
8829 + pr_debug("fabdev floor bw not present %d", info[i].id);
8830 + info[i].floor_bw = 0;
8832 + info[i].floor_bw = KBTOB(temp);
8836 + of_property_read_bool(child_node, "qcom,rt-mas");
8838 + ret = of_property_read_string(child_node, "qcom,perm-mode",
8841 + info[i].perm_mode = 0;
8843 + ret = get_num(mode_sel_name, sel_str);
8847 + info[i].perm_mode = 1 << ret;
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]);
8861 + pr_debug("Got slaveclk_dual: %s\n",
8862 + info[i].slaveclk[DUAL_CTX]);
8864 + info[i].slaveclk[DUAL_CTX] = NULL;
8866 + ret = of_property_read_string(child_node,
8867 + "qcom,slaveclk-active", &info[i].slaveclk[ACTIVE_CTX]);
8869 + pr_debug("Got slaveclk_active\n");
8871 + info[i].slaveclk[ACTIVE_CTX] = NULL;
8873 + ret = of_property_read_string(child_node, "qcom,memclk-dual",
8874 + &info[i].memclk[DUAL_CTX]);
8876 + pr_debug("Got memclk_dual\n");
8878 + info[i].memclk[DUAL_CTX] = NULL;
8880 + ret = of_property_read_string(child_node, "qcom,memclk-active",
8881 + &info[i].memclk[ACTIVE_CTX]);
8883 + pr_debug("Got memclk_active\n");
8885 + info[i].memclk[ACTIVE_CTX] = NULL;
8887 + ret = of_property_read_string(child_node, "qcom,iface-clk-node",
8888 + &info[i].iface_clk_node);
8890 + pr_debug("Got iface_clk_node\n");
8892 + info[i].iface_clk_node = NULL;
8894 + pr_debug("Node name: %s\n", info[i].name);
8895 + of_node_put(child_node);
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);
8906 +void msm_bus_of_get_nfab(struct platform_device *pdev,
8907 + struct msm_bus_fabric_registration *pdata)
8909 + struct device_node *of_node;
8910 + int ret, nfab = 0;
8913 + pr_err("Error: Null platform device\n");
8917 + of_node = pdev->dev.of_node;
8918 + ret = of_property_read_u32(of_node, "qcom,nfab",
8921 + pr_debug("Fab_of: Read number of buses: %u\n", nfab);
8923 + msm_bus_board_set_nfab(pdata, nfab);
8926 +struct msm_bus_fabric_registration
8927 + *msm_bus_of_get_fab_data(struct platform_device *pdev)
8929 + struct device_node *of_node;
8930 + struct msm_bus_fabric_registration *pdata;
8931 + bool mem_err = false;
8933 + const char *sel_str;
8937 + pr_err("Error: Null platform device\n");
8941 + of_node = pdev->dev.of_node;
8942 + pdata = devm_kzalloc(&pdev->dev,
8943 + sizeof(struct msm_bus_fabric_registration), GFP_KERNEL);
8945 + pr_err("Error: Memory allocation for pdata failed\n");
8950 + ret = of_property_read_string(of_node, "label", &pdata->name);
8952 + pr_err("Error: label not found\n");
8955 + pr_debug("Fab_of: Read name: %s\n", pdata->name);
8957 + ret = of_property_read_u32(of_node, "cell-id",
8960 + pr_err("Error: num-usecases not found\n");
8963 + pr_debug("Fab_of: Read id: %u\n", pdata->id);
8965 + if (of_property_read_bool(of_node, "qcom,ahb"))
8968 + ret = of_property_read_string(of_node, "qcom,fabclk-dual",
8969 + &pdata->fabclk[DUAL_CTX]);
8971 + pr_debug("fabclk_dual not available\n");
8972 + pdata->fabclk[DUAL_CTX] = NULL;
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]);
8979 + pr_debug("Error: fabclk_active not available\n");
8980 + pdata->fabclk[ACTIVE_CTX] = NULL;
8982 + pr_debug("Fab_of: Read clk act ctx: %s\n",
8983 + pdata->fabclk[ACTIVE_CTX]);
8985 + ret = of_property_read_u32(of_node, "qcom,ntieredslaves",
8986 + &pdata->ntieredslaves);
8988 + pr_err("Error: ntieredslaves not found\n");
8992 + ret = of_property_read_u32(of_node, "qcom,qos-freq", &pdata->qos_freq);
8994 + pr_debug("qos_freq not available\n");
8996 + ret = of_property_read_string(of_node, "qcom,hw-sel", &sel_str);
8998 + pr_err("Error: hw_sel not found\n");
9001 + ret = get_num(hw_sel_name, sel_str);
9005 + pdata->hw_sel = ret;
9008 + if (of_property_read_bool(of_node, "qcom,virt"))
9009 + pdata->virt = true;
9011 + ret = of_property_read_u32(of_node, "qcom,qos-baseoffset",
9012 + &pdata->qos_baseoffset);
9014 + pr_debug("%s:qos_baseoffset not available\n", __func__);
9016 + ret = of_property_read_u32(of_node, "qcom,qos-delta",
9017 + &pdata->qos_delta);
9019 + pr_debug("%s:qos_delta not available\n", __func__);
9021 + if (of_property_read_bool(of_node, "qcom,rpm-en"))
9022 + pdata->rpm_enabled = 1;
9024 + ret = of_property_read_u32(of_node, "qcom,nr-lim-thresh",
9028 + pr_err("nr-lim threshold not specified");
9029 + pdata->nr_lim_thresh = 0;
9031 + pdata->nr_lim_thresh = KBTOB(temp);
9034 + ret = of_property_read_u32(of_node, "qcom,eff-fact",
9035 + &pdata->eff_fact);
9037 + pr_err("Fab eff-factor not present");
9038 + pdata->eff_fact = 0;
9041 + pdata->info = get_nodes(of_node, pdev, pdata);
9046 +EXPORT_SYMBOL(msm_bus_of_get_fab_data);
9048 +++ b/drivers/bus/msm_bus/msm_bus_of_adhoc.c
9050 +/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
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.
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.
9062 +#define pr_fmt(fmt) "AXI: %s(): " fmt, __func__
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"
9078 +#define DEFAULT_QOS_FREQ 19200
9079 +#define DEFAULT_UTIL_FACT 100
9080 +#define DEFAULT_VRAIL_COMP 100
9082 +static int get_qos_mode(struct platform_device *pdev,
9083 + struct device_node *node, const char *qos_mode)
9085 + const char *qos_names[] = {"fixed", "limiter", "bypass", "regulator"};
9090 + goto exit_get_qos_mode;
9092 + for (i = 0; i < ARRAY_SIZE(qos_names); i++) {
9093 + if (!strcmp(qos_mode, qos_names[i]))
9096 + if (i == ARRAY_SIZE(qos_names))
9097 + dev_err(&pdev->dev, "Cannot match mode qos %s using Bypass",
9106 +static int *get_arr(struct platform_device *pdev,
9107 + struct device_node *node, const char *prop,
9110 + int size = 0, ret;
9113 + if (of_get_property(node, prop, &size)) {
9114 + *nports = size / sizeof(int);
9116 + dev_dbg(&pdev->dev, "Property %s not available\n", prop);
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",
9128 + ret = of_property_read_u32_array(node, prop, (u32 *)arr, *nports);
9130 + dev_err(&pdev->dev, "Error in reading property: %s\n", prop);
9136 + devm_kfree(&pdev->dev, arr);
9140 +static struct msm_bus_fab_device_type *get_fab_device_info(
9141 + struct device_node *dev_node,
9142 + struct platform_device *pdev)
9144 + struct msm_bus_fab_device_type *fab_dev;
9146 + struct resource *res;
9147 + const char *base_name;
9149 + fab_dev = devm_kzalloc(&pdev->dev,
9150 + sizeof(struct msm_bus_fab_device_type),
9153 + dev_err(&pdev->dev,
9154 + "Error: Unable to allocate memory for fab_dev\n");
9158 + ret = of_property_read_string(dev_node, "qcom,base-name", &base_name);
9160 + dev_err(&pdev->dev, "Error: Unable to get base address name\n");
9164 + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, base_name);
9166 + dev_err(&pdev->dev, "Error getting qos base addr %s\n",
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");
9175 + ret = of_property_read_u32(dev_node, "qcom,base-offset",
9176 + &fab_dev->base_offset);
9178 + dev_dbg(&pdev->dev, "Bus base offset is missing\n");
9180 + ret = of_property_read_u32(dev_node, "qcom,qos-off",
9181 + &fab_dev->qos_off);
9183 + dev_dbg(&pdev->dev, "Bus qos off is missing\n");
9186 + ret = of_property_read_u32(dev_node, "qcom,bus-type",
9187 + &fab_dev->bus_type);
9189 + dev_warn(&pdev->dev, "Bus type is missing\n");
9193 + ret = of_property_read_u32(dev_node, "qcom,qos-freq",
9194 + &fab_dev->qos_freq);
9196 + dev_dbg(&pdev->dev, "Bus qos freq is missing\n");
9197 + fab_dev->qos_freq = DEFAULT_QOS_FREQ;
9200 + ret = of_property_read_u32(dev_node, "qcom,util-fact",
9201 + &fab_dev->util_fact);
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;
9208 + ret = of_property_read_u32(dev_node, "qcom,vrail-comp",
9209 + &fab_dev->vrail_comp);
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;
9219 + devm_kfree(&pdev->dev, fab_dev);
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)
9229 + const char *qos_mode = NULL;
9231 + unsigned int temp;
9233 + ret = of_property_read_string(dev_node, "qcom,qos-mode", &qos_mode);
9236 + node_info->qos_params.mode = -1;
9238 + node_info->qos_params.mode = get_qos_mode(pdev, dev_node,
9241 + of_property_read_u32(dev_node, "qcom,prio-lvl",
9242 + &node_info->qos_params.prio_lvl);
9244 + of_property_read_u32(dev_node, "qcom,prio1",
9245 + &node_info->qos_params.prio1);
9247 + of_property_read_u32(dev_node, "qcom,prio0",
9248 + &node_info->qos_params.prio0);
9250 + of_property_read_u32(dev_node, "qcom,prio-rd",
9251 + &node_info->qos_params.prio_rd);
9253 + of_property_read_u32(dev_node, "qcom,prio-wr",
9254 + &node_info->qos_params.prio_wr);
9256 + of_property_read_u32(dev_node, "qcom,gp",
9257 + &node_info->qos_params.gp);
9259 + of_property_read_u32(dev_node, "qcom,thmp",
9260 + &node_info->qos_params.thmp);
9262 + of_property_read_u32(dev_node, "qcom,ws",
9263 + &node_info->qos_params.ws);
9265 + ret = of_property_read_u32(dev_node, "qcom,bw_buffer", &temp);
9268 + node_info->qos_params.bw_buffer = 0;
9270 + node_info->qos_params.bw_buffer = KBTOB(temp);
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)
9279 + struct msm_bus_node_info_type *node_info;
9283 + struct device_node *con_node;
9284 + struct device_node *bus_dev;
9286 + node_info = devm_kzalloc(&pdev->dev,
9287 + sizeof(struct msm_bus_node_info_type),
9290 + dev_err(&pdev->dev,
9291 + "Error: Unable to allocate memory for node_info\n");
9295 + ret = of_property_read_u32(dev_node, "cell-id", &node_info->id);
9297 + dev_warn(&pdev->dev, "Bus node is missing cell-id\n");
9298 + goto node_info_err;
9300 + ret = of_property_read_string(dev_node, "label", &node_info->name);
9302 + dev_warn(&pdev->dev, "Bus node is missing name\n");
9303 + goto node_info_err;
9305 + node_info->qport = get_arr(pdev, dev_node, "qcom,qport",
9306 + &node_info->num_qports);
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,
9313 + node_info->num_connections = 0;
9314 + node_info->connections = 0;
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;
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);
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);
9333 + node_info->num_blist = 0;
9334 + node_info->black_listed_connections = 0;
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;
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);
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",
9354 + goto node_info_err;
9357 + of_node_put(bus_dev);
9359 + dev_dbg(&pdev->dev, "Can't find bdev phandle for %d",
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");
9365 + ret = of_property_read_u32(dev_node, "qcom,buswidth",
9366 + &node_info->buswidth);
9368 + dev_dbg(&pdev->dev, "Using default 8 bytes %d", node_info->id);
9369 + node_info->buswidth = 8;
9372 + ret = of_property_read_u32(dev_node, "qcom,mas-rpm-id",
9373 + &node_info->mas_rpm_id);
9375 + dev_dbg(&pdev->dev, "mas rpm id is missing\n");
9376 + node_info->mas_rpm_id = -1;
9379 + ret = of_property_read_u32(dev_node, "qcom,slv-rpm-id",
9380 + &node_info->slv_rpm_id);
9382 + dev_dbg(&pdev->dev, "slv rpm id is missing\n");
9383 + node_info->slv_rpm_id = -1;
9385 + ret = of_property_read_u32(dev_node, "qcom,util-fact",
9386 + &node_info->util_fact);
9388 + node_info->util_fact = 0;
9389 + ret = of_property_read_u32(dev_node, "qcom,vrail-comp",
9390 + &node_info->vrail_comp);
9392 + node_info->vrail_comp = 0;
9393 + get_qos_params(dev_node, pdev, node_info);
9398 + devm_kfree(&pdev->dev, node_info);
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)
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");
9413 + node_device->ap_owned = of_property_read_bool(dev_node,
9416 + if (node_device->node_info->is_fab_dev) {
9417 + dev_dbg(&pdev->dev, "Dev %d\n", node_device->node_info->id);
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);
9429 + node_device->clk[DUAL_CTX].clk = of_clk_get_by_name(dev_node,
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,
9438 + node_device->clk[ACTIVE_CTX].clk = of_clk_get_by_name(dev_node,
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);
9449 + node_device->qos_clk.clk = of_clk_get_by_name(dev_node,
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);
9457 + node_device->clk[DUAL_CTX].clk = of_clk_get_by_name(dev_node,
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,
9470 +struct msm_bus_device_node_registration
9471 + *msm_bus_of_to_pdata(struct platform_device *pdev)
9473 + struct device_node *of_node, *child_node;
9474 + struct msm_bus_device_node_registration *pdata;
9475 + unsigned int i = 0, j;
9479 + pr_err("Error: Null platform device\n");
9483 + of_node = pdev->dev.of_node;
9485 + pdata = devm_kzalloc(&pdev->dev,
9486 + sizeof(struct msm_bus_device_node_registration),
9489 + dev_err(&pdev->dev,
9490 + "Error: Memory allocation for pdata failed\n");
9494 + pdata->num_devices = of_get_child_count(of_node);
9496 + pdata->info = devm_kzalloc(&pdev->dev,
9497 + sizeof(struct msm_bus_node_device_type) *
9498 + pdata->num_devices, GFP_KERNEL);
9500 + if (!pdata->info) {
9501 + dev_err(&pdev->dev,
9502 + "Error: Memory allocation for pdata->info failed\n");
9503 + goto node_reg_err;
9507 + for_each_child_of_node(of_node, child_node) {
9508 + ret = get_bus_node_device_data(child_node, pdev,
9511 + dev_err(&pdev->dev, "Error: unable to initialize bus nodes\n");
9512 + goto node_reg_err_1;
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;
9528 + dev_dbg(&pdev->dev, "connection[%d]: %d\n", j,
9529 + pdata->info[i].node_info->connections[j]);
9531 + for (j = 0; j < pdata->info[i].node_info->num_blist;
9533 + dev_dbg(&pdev->dev, "black_listed_node[%d]: %d\n", j,
9534 + pdata->info[i].node_info->
9535 + black_listed_connections[j]);
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);
9546 + devm_kfree(&pdev->dev, pdata->info);
9548 + devm_kfree(&pdev->dev, pdata);
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)
9559 + struct device_node *rule_node;
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);
9566 + dev_err(&pdev->dev, "No rule nodes, skipping node");
9568 + goto exit_get_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");
9580 + if (of_property_read_u32(rule_node, "cell-id",
9582 + dev_err(&pdev->dev, "Can't get rule node id");
9586 + of_node_put(rule_node);
9591 + devm_kfree(&pdev->dev, ids);
9592 + of_node_put(rule_node);
9597 +int msm_bus_of_get_static_rules(struct platform_device *pdev,
9598 + struct bus_rule_type **static_rules)
9601 + struct device_node *of_node, *child_node;
9602 + int num_rules = 0;
9606 + struct bus_rule_type *static_rule = NULL;
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,
9614 + if (IS_ERR_OR_NULL(static_rule)) {
9616 + goto exit_static_rules;
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");
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");
9631 + ret = of_property_read_u32(child_node, "qcom,src-field",
9632 + &static_rule[rule_idx].src_field);
9634 + dev_err(&pdev->dev, "src-field missing");
9636 + goto err_static_rules;
9639 + ret = of_property_read_u32(child_node, "qcom,src-op",
9640 + &static_rule[rule_idx].op);
9642 + dev_err(&pdev->dev, "src-op missing");
9644 + goto err_static_rules;
9647 + ret = of_property_read_u32(child_node, "qcom,mode",
9648 + &static_rule[rule_idx].mode);
9650 + dev_err(&pdev->dev, "mode missing");
9652 + goto err_static_rules;
9655 + ret = of_property_read_u32(child_node, "qcom,thresh", &bw_fld);
9657 + dev_err(&pdev->dev, "thresh missing");
9659 + goto err_static_rules;
9661 + static_rule[rule_idx].thresh = KBTOB(bw_fld);
9663 + ret = of_property_read_u32(child_node, "qcom,dest-bw",
9666 + static_rule[rule_idx].dst_bw = 0;
9668 + static_rule[rule_idx].dst_bw = KBTOB(bw_fld);
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);
9687 + devm_kfree(&pdev->dev, *static_rules);
9688 + static_rules = NULL;
9692 +++ b/drivers/bus/msm_bus/msm_bus_rules.c
9694 +/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
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.
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.
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>
9713 +struct node_vote_info {
9724 + struct node_vote_info *src_info;
9725 + struct bus_rule_type rule_ops;
9726 + bool state_change;
9727 + struct list_head link;
9730 +struct rule_node_info {
9733 + struct raw_notifier_head rule_notify_list;
9736 + struct list_head node_rules;
9737 + struct list_head link;
9738 + struct rule_apply_rcm_info apply;
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);
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)
9751 +static struct rule_node_info *get_node(u32 id, void *data)
9753 + struct rule_node_info *node_it = NULL;
9754 + struct rule_node_info *node_match = NULL;
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;
9764 + node_match = node_it;
9769 + return node_match;
9772 +static struct rule_node_info *gen_node(u32 id, void *data)
9774 + struct rule_node_info *node_it = NULL;
9775 + struct rule_node_info *node_match = NULL;
9777 + list_for_each_entry(node_it, &node_list, link) {
9778 + if (node_it->id == id) {
9779 + node_match = node_it;
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;
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);
9801 + return node_match;
9804 +static bool do_compare_op(u64 op1, u64 op2, int op)
9810 + ret = LE(op1, op2);
9813 + ret = LT(op1, op2);
9816 + ret = GT(op1, op2);
9819 + ret = GE(op1, op2);
9825 + pr_info("Invalid OP %d", op);
9831 +static void update_src_id_vote(struct rule_update_path_info *inp_node,
9832 + struct rule_node_info *rule_node)
9834 + struct rules_def *rule;
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;
9848 +static u64 get_field(struct rules_def *rule, int src_id)
9853 + for (i = 0; i < rule->num_src; i++) {
9854 + switch (rule->rule_ops.src_field) {
9856 + field += rule->src_info[i].ib;
9859 + field += rule->src_info[i].ab;
9862 + field += rule->src_info[i].clk;
9870 +static bool check_rule(struct rules_def *rule,
9871 + struct rule_update_path_info *inp)
9878 + switch (rule->rule_ops.op) {
9884 + u64 src_field = get_field(rule, inp->id);
9888 + ret = do_compare_op(src_field, rule->rule_ops.thresh,
9889 + rule->rule_ops.op);
9893 + pr_err("Unsupported op %d", rule->rule_ops.op);
9899 +static void match_rule(struct rule_update_path_info *inp_node,
9900 + struct rule_node_info *node)
9902 + struct rules_def *rule;
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;
9917 + if (rule->state ==
9918 + RULE_STATE_APPLIED)
9919 + rule->state_change = true;
9920 + rule->state = RULE_STATE_NOT_APPLIED;
9927 +static void apply_rule(struct rule_node_info *node,
9928 + struct list_head *output_list)
9930 + struct rules_def *rule;
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;
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);
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);
9952 + rule->state_change = false;
9958 +int msm_rules_update_path(struct list_head *input_list,
9959 + struct list_head *output_list)
9962 + struct rule_update_path_info *inp_node;
9963 + struct rule_node_info *node_it = NULL;
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);
9973 + list_for_each_entry(node_it, &node_list, link)
9974 + apply_rule(node_it, output_list);
9976 + mutex_unlock(&msm_bus_rules_lock);
9980 +static bool ops_equal(int op1, int op2)
9989 + if (abs(op1 - op2) <= 1)
9993 + ret = (op1 == op2);
9999 +static int node_rules_compare(void *priv, struct list_head *a,
10000 + struct list_head *b)
10002 + struct rules_def *ra = container_of(a, struct rules_def, link);
10003 + struct rules_def *rb = container_of(b, struct rules_def, link);
10005 + int64_t th_diff = 0;
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;
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;
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)) {
10032 + } else if ((ra->rule_ops.mode == THROTTLE_ON) &&
10033 + (rb->rule_ops.mode == THROTTLE_OFF)) {
10040 +static void print_rules(struct rule_node_info *node_it)
10042 + struct rules_def *node_rule = NULL;
10046 + pr_err("%s: no node for found", __func__);
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);
10071 +void print_all_rules(void)
10073 + struct rule_node_info *node_it = NULL;
10075 + list_for_each_entry(node_it, &node_list, link)
10076 + print_rules(node_it);
10079 +void print_rules_buf(char *buf, int max_buf)
10081 + struct rule_node_info *node_it = NULL;
10082 + struct rules_def *node_rule = NULL;
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);
10118 +static int copy_rule(struct bus_rule_type *src, struct rules_def *node_rule,
10119 + struct notifier_block *nb)
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),
10129 + if (!node_rule->rule_ops.src_id) {
10130 + pr_err("%s:Failed to allocate for src_id",
10134 + memcpy(node_rule->rule_ops.src_id, src->src_id,
10135 + sizeof(int) * src->num_src);
10139 + node_rule->rule_ops.dst_node = kzalloc(
10140 + (sizeof(int) * node_rule->rule_ops.num_dst),
10142 + if (!node_rule->rule_ops.dst_node) {
10143 + pr_err("%s:Failed to allocate for src_id",
10147 + memcpy(node_rule->rule_ops.dst_node, src->dst_node,
10148 + sizeof(int) * src->num_dst);
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),
10155 + if (!node_rule->src_info) {
10156 + pr_err("%s:Failed to allocate for src_id",
10160 + for (i = 0; i < src->num_src; i++)
10161 + node_rule->src_info[i].id = src->src_id[i];
10166 +void msm_rule_register(int num_rules, struct bus_rule_type *rule,
10167 + struct notifier_block *nb)
10169 + struct rule_node_info *node = NULL;
10171 + struct rules_def *node_rule = NULL;
10177 + mutex_lock(&msm_bus_rules_lock);
10178 + for (i = 0; i < num_rules; i++) {
10182 + num_dst = rule[i].num_dst;
10184 + for (j = 0; j < num_dst; j++) {
10190 + id = rule[i].dst_node[j];
10192 + node = gen_node(id, nb);
10194 + pr_info("Error getting rule");
10195 + goto exit_rule_register;
10197 + node_rule = kzalloc(sizeof(struct rules_def),
10199 + if (!node_rule) {
10200 + pr_err("%s: Failed to allocate for rule",
10202 + goto exit_rule_register;
10205 + if (copy_rule(&rule[i], node_rule, nb)) {
10206 + pr_err("Error copying rule");
10207 + goto exit_rule_register;
10210 + node_rule->rule_id = node->num_rules++;
10214 + list_add_tail(&node_rule->link, &node->node_rules);
10217 + list_sort(NULL, &node->node_rules, node_rules_compare);
10220 + raw_notifier_chain_register(&node->rule_notify_list, nb);
10221 +exit_rule_register:
10222 + mutex_unlock(&msm_bus_rules_lock);
10226 +static int comp_rules(struct bus_rule_type *rulea, struct bus_rule_type *ruleb)
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))
10243 +void msm_rule_unregister(int num_rules, struct bus_rule_type *rule,
10244 + struct notifier_block *nb)
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;
10256 + mutex_lock(&msm_bus_rules_lock);
10258 + node = get_node(NB_ID, nb);
10260 + pr_err("%s: Can't find node", __func__);
10261 + goto exit_unregister_rule;
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--;
10270 + raw_notifier_chain_unregister(&node->rule_notify_list, nb);
10272 + for (i = 0; i < num_rules; i++) {
10273 + match_found = false;
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--;
10285 + &node->node_rules,
10286 + node_rules_compare);
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);
10302 +exit_unregister_rule:
10303 + mutex_unlock(&msm_bus_rules_lock);
10306 +bool msm_rule_are_rules_registered(void)
10308 + bool ret = false;
10310 + if (list_empty(&node_list))
10319 +++ b/drivers/bus/msm_bus/msm_bus_rules.h
10321 +/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
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.
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.
10333 +#ifndef _ARCH_ARM_MACH_MSM_BUS_RULES_H
10334 +#define _ARCH_ARM_MACH_MSM_BUS_RULES_H
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>
10341 +#define MAX_NODES (5)
10343 +struct rule_update_path_info {
10348 + struct list_head link;
10351 +struct rule_apply_rcm_info {
10355 + bool after_clk_commit;
10356 + struct list_head link;
10359 +struct bus_rule_type {
10369 + void *client_data;
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);
10380 +static inline void msm_rule_register(int num_rules, struct bus_rule_type *rule,
10381 + struct notifier_block *nb)
10384 +static inline void msm_rule_unregister(int num_rules,
10385 + struct bus_rule_type *rule,
10386 + struct notifier_block *nb)
10389 +static inline void print_rules_buf(char *buf, int count)
10392 +static inline bool msm_rule_are_rules_registered(void)
10396 +#endif /* defined(CONFIG_BUS_TOPOLOGY_ADHOC) */
10397 +#endif /* _ARCH_ARM_MACH_MSM_BUS_RULES_H */
10399 +++ b/drivers/bus/msm_bus/msm_buspm_coresight_adhoc.c
10401 +/* Copyright (c) 2014 The Linux Foundation. All rights reserved.
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.
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.
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>
10428 +struct msmbus_coresight_adhoc_clock_drvdata {
10431 + struct list_head list;
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;
10441 +static int msmbus_coresight_enable_adhoc(struct coresight_device *csdev)
10443 + struct msmbus_coresight_adhoc_clock_drvdata *clk;
10444 + struct msmbus_coresight_adhoc_drvdata *drvdata =
10445 + dev_get_drvdata(csdev->dev.parent);
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);
10459 +static void msmbus_coresight_disable_adhoc(struct coresight_device *csdev)
10461 + struct msmbus_coresight_adhoc_clock_drvdata *clk;
10462 + struct msmbus_coresight_adhoc_drvdata *drvdata =
10463 + dev_get_drvdata(csdev->dev.parent);
10465 + list_for_each_entry(clk, &drvdata->clocks, list) {
10466 + if (clk->id == csdev->id)
10467 + clk_disable_unprepare(clk->clk);
10471 +static const struct coresight_ops_source msmbus_coresight_adhoc_source_ops = {
10472 + .enable = msmbus_coresight_enable_adhoc,
10473 + .disable = msmbus_coresight_disable_adhoc,
10476 +static const struct coresight_ops msmbus_coresight_cs_ops = {
10477 + .source_ops = &msmbus_coresight_adhoc_source_ops,
10480 +void msmbus_coresight_remove_adhoc(struct platform_device *pdev)
10482 + struct msmbus_coresight_adhoc_clock_drvdata *clk, *next_clk;
10483 + struct msmbus_coresight_adhoc_drvdata *drvdata =
10484 + platform_get_drvdata(pdev);
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);
10492 + devm_kfree(&pdev->dev, drvdata->desc);
10493 + devm_kfree(&pdev->dev, drvdata);
10494 + platform_set_drvdata(pdev, NULL);
10496 +EXPORT_SYMBOL(msmbus_coresight_remove_adhoc);
10498 +static int buspm_of_get_clk_adhoc(struct device_node *of_node,
10499 + struct msmbus_coresight_adhoc_drvdata *drvdata, int id)
10501 + struct msmbus_coresight_adhoc_clock_drvdata *clk;
10502 + clk = devm_kzalloc(drvdata->dev, sizeof(*clk), GFP_KERNEL);
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",
10516 + list_add(&clk->list, &drvdata->clocks);
10520 + devm_kfree(drvdata->dev, clk);
10524 +int msmbus_coresight_init_adhoc(struct platform_device *pdev,
10525 + struct device_node *of_node)
10528 + struct device *dev = &pdev->dev;
10529 + struct coresight_platform_data *pdata;
10530 + struct msmbus_coresight_adhoc_drvdata *drvdata;
10531 + struct coresight_desc *desc;
10533 + pdata = of_get_coresight_platform_data(dev, of_node);
10534 + if (IS_ERR(pdata))
10535 + return PTR_ERR(pdata);
10537 + drvdata = platform_get_drvdata(pdev);
10538 + if (IS_ERR_OR_NULL(drvdata)) {
10539 + drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
10541 + pr_err("coresight: Alloc for drvdata failed\n");
10544 + INIT_LIST_HEAD(&drvdata->clocks);
10545 + drvdata->dev = &pdev->dev;
10546 + platform_set_drvdata(pdev, drvdata);
10548 + ret = buspm_of_get_clk_adhoc(of_node, drvdata, pdata->id);
10550 + pr_err("Error getting clocks\n");
10555 + desc = devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL);
10557 + pr_err("coresight: Error allocating memory\n");
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);
10576 + dev_info(dev, "msmbus_coresight initialized\n");
10580 + devm_kfree(dev, desc);
10582 + devm_kfree(dev, drvdata);
10583 + platform_set_drvdata(pdev, NULL);
10586 +EXPORT_SYMBOL(msmbus_coresight_init_adhoc);
10588 +MODULE_LICENSE("GPL v2");
10589 +MODULE_DESCRIPTION("MSM BusPM Adhoc CoreSight Driver");
10591 +++ b/drivers/bus/msm_bus/rpm-smd.h
10593 +/* Copyright (c) 2012, 2014, The Linux Foundation. All rights reserved.
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.
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.
10606 +#ifndef __ARCH_ARM_MACH_MSM_RPM_SMD_H
10607 +#define __ARCH_ARM_MACH_MSM_RPM_SMD_H
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.
10614 +enum msm_rpm_set {
10615 + MSM_RPM_CTX_ACTIVE_SET,
10616 + MSM_RPM_CTX_SLEEP_SET,
10619 +struct msm_rpm_request;
10621 +struct msm_rpm_kvp {
10626 +#ifdef CONFIG_MSM_RPM_SMD
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
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
10638 + * returns pointer to a msm_rpm_request on success, NULL on error
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);
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.
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
10656 + * returns pointer to a msm_rpm_request on success, NULL on error
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);
10663 + * msm_rpm_add_kvp_data() - Adds a Key value pair to a existing RPM resource.
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.
10670 + * returns 0 on success or errno
10672 +int msm_rpm_add_kvp_data(struct msm_rpm_request *handle,
10673 + uint32_t key, const uint8_t *data, int size);
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.
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.
10685 + * returns 0 on success or errno
10687 +int msm_rpm_add_kvp_data_noirq(struct msm_rpm_request *handle,
10688 + uint32_t key, const uint8_t *data, int size);
10690 +/** msm_rpm_free_request() - clean up the RPM request handle created with
10691 + * msm_rpm_create_request
10693 + * @handle: RPM resource handle to be cleared.
10696 +void msm_rpm_free_request(struct msm_rpm_request *handle);
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.
10703 + * @handle: pointer to the msm_rpm_request for the resource being modified.
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.
10708 +int msm_rpm_send_request(struct msm_rpm_request *handle);
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.
10717 + * @handle: pointer to the msm_rpm_request for the resource being modified.
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.
10722 +int msm_rpm_send_request_noirq(struct msm_rpm_request *handle);
10725 + * msm_rpm_wait_for_ack() - A blocking call that waits for acknowledgment of
10726 + * a message from RPM.
10728 + * @msg_id: the return from msm_rpm_send_requests
10730 + * returns 0 on success or errno
10732 +int msm_rpm_wait_for_ack(uint32_t msg_id);
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.
10739 + * @msg_id: the return from msm_rpm_send_request
10741 + * returns 0 on success or errno
10743 +int msm_rpm_wait_for_ack_noirq(uint32_t msg_id);
10746 + * msm_rpm_send_message() -Wrapper function for clients to send data given an
10747 + * array of key value pairs.
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.
10756 + * returns 0 on success and errno on failure.
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);
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
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.
10775 + * returns 0 on success and errno on failure.
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);
10781 + * msm_rpm_driver_init() - Initialization function that registers for a
10782 + * rpm platform driver.
10784 + * returns 0 on success.
10786 +int __init msm_rpm_driver_init(void);
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)
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)
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)
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)
10816 +static inline void msm_rpm_free_request(struct msm_rpm_request *handle)
10821 +static inline int msm_rpm_send_request(struct msm_rpm_request *handle)
10826 +static inline int msm_rpm_send_request_noirq(struct msm_rpm_request *handle)
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)
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,
10845 +static inline int msm_rpm_wait_for_ack(uint32_t msg_id)
10850 +static inline int msm_rpm_wait_for_ack_noirq(uint32_t msg_id)
10855 +static inline int __init msm_rpm_driver_init(void)
10860 +#endif /*__ARCH_ARM_MACH_MSM_RPM_SMD_H*/
10862 +++ b/include/trace/events/trace_msm_bus.h
10864 +/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
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.
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.
10876 +#undef TRACE_SYSTEM
10877 +#define TRACE_SYSTEM msm_bus
10879 +#if !defined(_TRACE_MSM_BUS_H) || defined(TRACE_HEADER_MULTI_READ)
10880 +#define _TRACE_MSM_BUS_H
10882 +#include <linux/tracepoint.h>
10884 +TRACE_EVENT(bus_update_request,
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),
10890 + TP_ARGS(sec, nsec, name, index, src, dest, ab, ib),
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)
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;
10914 + TP_printk("time= %d.%d name=%s index=%u src=%d dest=%d ab=%llu ib=%llu",
10918 + (unsigned int)__entry->index,
10921 + (unsigned long long)__entry->ab,
10922 + (unsigned long long)__entry->ib)
10925 +TRACE_EVENT(bus_bimc_config_limiter,
10927 + TP_PROTO(int mas_id, unsigned long long cur_lim_bw),
10929 + TP_ARGS(mas_id, cur_lim_bw),
10931 + TP_STRUCT__entry(
10932 + __field(int, mas_id)
10933 + __field(u64, cur_lim_bw)
10937 + __entry->mas_id = mas_id;
10938 + __entry->cur_lim_bw = cur_lim_bw;
10941 + TP_printk("Master=%d cur_lim_bw=%llu",
10943 + (unsigned long long)__entry->cur_lim_bw)
10946 +TRACE_EVENT(bus_avail_bw,
10948 + TP_PROTO(unsigned long long cur_bimc_bw, unsigned long long cur_mdp_bw),
10950 + TP_ARGS(cur_bimc_bw, cur_mdp_bw),
10952 + TP_STRUCT__entry(
10953 + __field(u64, cur_bimc_bw)
10954 + __field(u64, cur_mdp_bw)
10958 + __entry->cur_bimc_bw = cur_bimc_bw;
10959 + __entry->cur_mdp_bw = cur_mdp_bw;
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)
10967 +TRACE_EVENT(bus_rules_matches,
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),
10972 + TP_ARGS(node_id, rule_id, node_ab, node_ib, node_clk),
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)
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;
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)
10997 +TRACE_EVENT(bus_bke_params,
10999 + TP_PROTO(u32 gc, u32 gp, u32 thl, u32 thm, u32 thh),
11001 + TP_ARGS(gc, gp, thl, thm, thh),
11003 + TP_STRUCT__entry(
11006 + __field(u32, thl)
11007 + __field(u32, thm)
11008 + __field(u32, thh)
11012 + __entry->gc = gc;
11013 + __entry->gp = gp;
11014 + __entry->thl = thl;
11015 + __entry->thm = thm;
11016 + __entry->thh = thh;
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,
11025 +#define TRACE_INCLUDE_FILE trace_msm_bus
11026 +#include <trace/define_trace.h>