ipq40xx: add target
[openwrt/staging/wigyori.git] / target / linux / ipq40xx / patches-4.14 / 310-msm-adhoc-bus-support.patch
1 From: Christian Lamparter <chunkeey@googlemail.com>
2 Subject: BUS: add MSM_BUS
3 --- a/drivers/bus/Makefile
4 +++ b/drivers/bus/Makefile
5 @@ -11,6 +11,7 @@ obj-$(CONFIG_BRCMSTB_GISB_ARB) += brcmst
6 obj-$(CONFIG_IMX_WEIM) += imx-weim.o
7 obj-$(CONFIG_MIPS_CDMM) += mips_cdmm.o
8 obj-$(CONFIG_MVEBU_MBUS) += mvebu-mbus.o
9 +obj-$(CONFIG_BUS_TOPOLOGY_ADHOC)+= msm_bus/
10
11 # Interconnect bus driver for OMAP SoCs.
12 obj-$(CONFIG_OMAP_INTERCONNECT) += omap_l3_smx.o omap_l3_noc.o
13 --- a/drivers/bus/Kconfig
14 +++ b/drivers/bus/Kconfig
15 @@ -93,6 +93,8 @@ config MVEBU_MBUS
16 Driver needed for the MBus configuration on Marvell EBU SoCs
17 (Kirkwood, Dove, Orion5x, MV78XX0 and Armada 370/XP).
18
19 +source "drivers/bus/msm_bus/Kconfig"
20 +
21 config OMAP_INTERCONNECT
22 tristate "OMAP INTERCONNECT DRIVER"
23 depends on ARCH_OMAP2PLUS
24 --- /dev/null
25 +++ b/include/dt-bindings/msm/msm-bus-ids.h
26 @@ -0,0 +1,869 @@
27 +/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
28 + *
29 + * This program is free software; you can redistribute it and/or modify
30 + * it under the terms of the GNU General Public License version 2 and
31 + * only version 2 as published by the Free Software Foundation.
32 + *
33 + * This program is distributed in the hope that it will be useful,
34 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
35 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
36 + * GNU General Public License for more details.
37 + */
38 +
39 +#ifndef __MSM_BUS_IDS_H
40 +#define __MSM_BUS_IDS_H
41 +
42 +/* Topology related enums */
43 +#define MSM_BUS_FAB_DEFAULT 0
44 +#define MSM_BUS_FAB_APPSS 0
45 +#define MSM_BUS_FAB_SYSTEM 1024
46 +#define MSM_BUS_FAB_MMSS 2048
47 +#define MSM_BUS_FAB_SYSTEM_FPB 3072
48 +#define MSM_BUS_FAB_CPSS_FPB 4096
49 +
50 +#define MSM_BUS_FAB_BIMC 0
51 +#define MSM_BUS_FAB_SYS_NOC 1024
52 +#define MSM_BUS_FAB_MMSS_NOC 2048
53 +#define MSM_BUS_FAB_OCMEM_NOC 3072
54 +#define MSM_BUS_FAB_PERIPH_NOC 4096
55 +#define MSM_BUS_FAB_CONFIG_NOC 5120
56 +#define MSM_BUS_FAB_OCMEM_VNOC 6144
57 +#define MSM_BUS_FAB_MMSS_AHB 2049
58 +#define MSM_BUS_FAB_A0_NOC 6145
59 +#define MSM_BUS_FAB_A1_NOC 6146
60 +#define MSM_BUS_FAB_A2_NOC 6147
61 +
62 +#define MSM_BUS_MASTER_FIRST 1
63 +#define MSM_BUS_MASTER_AMPSS_M0 1
64 +#define MSM_BUS_MASTER_AMPSS_M1 2
65 +#define MSM_BUS_APPSS_MASTER_FAB_MMSS 3
66 +#define MSM_BUS_APPSS_MASTER_FAB_SYSTEM 4
67 +#define MSM_BUS_SYSTEM_MASTER_FAB_APPSS 5
68 +#define MSM_BUS_MASTER_SPS 6
69 +#define MSM_BUS_MASTER_ADM_PORT0 7
70 +#define MSM_BUS_MASTER_ADM_PORT1 8
71 +#define MSM_BUS_SYSTEM_MASTER_ADM1_PORT0 9
72 +#define MSM_BUS_MASTER_ADM1_PORT1 10
73 +#define MSM_BUS_MASTER_LPASS_PROC 11
74 +#define MSM_BUS_MASTER_MSS_PROCI 12
75 +#define MSM_BUS_MASTER_MSS_PROCD 13
76 +#define MSM_BUS_MASTER_MSS_MDM_PORT0 14
77 +#define MSM_BUS_MASTER_LPASS 15
78 +#define MSM_BUS_SYSTEM_MASTER_CPSS_FPB 16
79 +#define MSM_BUS_SYSTEM_MASTER_SYSTEM_FPB 17
80 +#define MSM_BUS_SYSTEM_MASTER_MMSS_FPB 18
81 +#define MSM_BUS_MASTER_ADM1_CI 19
82 +#define MSM_BUS_MASTER_ADM0_CI 20
83 +#define MSM_BUS_MASTER_MSS_MDM_PORT1 21
84 +#define MSM_BUS_MASTER_MDP_PORT0 22
85 +#define MSM_BUS_MASTER_MDP_PORT1 23
86 +#define MSM_BUS_MMSS_MASTER_ADM1_PORT0 24
87 +#define MSM_BUS_MASTER_ROTATOR 25
88 +#define MSM_BUS_MASTER_GRAPHICS_3D 26
89 +#define MSM_BUS_MASTER_JPEG_DEC 27
90 +#define MSM_BUS_MASTER_GRAPHICS_2D_CORE0 28
91 +#define MSM_BUS_MASTER_VFE 29
92 +#define MSM_BUS_MASTER_VPE 30
93 +#define MSM_BUS_MASTER_JPEG_ENC 31
94 +#define MSM_BUS_MASTER_GRAPHICS_2D_CORE1 32
95 +#define MSM_BUS_MMSS_MASTER_APPS_FAB 33
96 +#define MSM_BUS_MASTER_HD_CODEC_PORT0 34
97 +#define MSM_BUS_MASTER_HD_CODEC_PORT1 35
98 +#define MSM_BUS_MASTER_SPDM 36
99 +#define MSM_BUS_MASTER_RPM 37
100 +#define MSM_BUS_MASTER_MSS 38
101 +#define MSM_BUS_MASTER_RIVA 39
102 +#define MSM_BUS_MASTER_SNOC_VMEM 40
103 +#define MSM_BUS_MASTER_MSS_SW_PROC 41
104 +#define MSM_BUS_MASTER_MSS_FW_PROC 42
105 +#define MSM_BUS_MASTER_HMSS 43
106 +#define MSM_BUS_MASTER_GSS_NAV 44
107 +#define MSM_BUS_MASTER_PCIE 45
108 +#define MSM_BUS_MASTER_SATA 46
109 +#define MSM_BUS_MASTER_CRYPTO 47
110 +#define MSM_BUS_MASTER_VIDEO_CAP 48
111 +#define MSM_BUS_MASTER_GRAPHICS_3D_PORT1 49
112 +#define MSM_BUS_MASTER_VIDEO_ENC 50
113 +#define MSM_BUS_MASTER_VIDEO_DEC 51
114 +#define MSM_BUS_MASTER_LPASS_AHB 52
115 +#define MSM_BUS_MASTER_QDSS_BAM 53
116 +#define MSM_BUS_MASTER_SNOC_CFG 54
117 +#define MSM_BUS_MASTER_CRYPTO_CORE0 55
118 +#define MSM_BUS_MASTER_CRYPTO_CORE1 56
119 +#define MSM_BUS_MASTER_MSS_NAV 57
120 +#define MSM_BUS_MASTER_OCMEM_DMA 58
121 +#define MSM_BUS_MASTER_WCSS 59
122 +#define MSM_BUS_MASTER_QDSS_ETR 60
123 +#define MSM_BUS_MASTER_USB3 61
124 +#define MSM_BUS_MASTER_JPEG 62
125 +#define MSM_BUS_MASTER_VIDEO_P0 63
126 +#define MSM_BUS_MASTER_VIDEO_P1 64
127 +#define MSM_BUS_MASTER_MSS_PROC 65
128 +#define MSM_BUS_MASTER_JPEG_OCMEM 66
129 +#define MSM_BUS_MASTER_MDP_OCMEM 67
130 +#define MSM_BUS_MASTER_VIDEO_P0_OCMEM 68
131 +#define MSM_BUS_MASTER_VIDEO_P1_OCMEM 69
132 +#define MSM_BUS_MASTER_VFE_OCMEM 70
133 +#define MSM_BUS_MASTER_CNOC_ONOC_CFG 71
134 +#define MSM_BUS_MASTER_RPM_INST 72
135 +#define MSM_BUS_MASTER_RPM_DATA 73
136 +#define MSM_BUS_MASTER_RPM_SYS 74
137 +#define MSM_BUS_MASTER_DEHR 75
138 +#define MSM_BUS_MASTER_QDSS_DAP 76
139 +#define MSM_BUS_MASTER_TIC 77
140 +#define MSM_BUS_MASTER_SDCC_1 78
141 +#define MSM_BUS_MASTER_SDCC_3 79
142 +#define MSM_BUS_MASTER_SDCC_4 80
143 +#define MSM_BUS_MASTER_SDCC_2 81
144 +#define MSM_BUS_MASTER_TSIF 82
145 +#define MSM_BUS_MASTER_BAM_DMA 83
146 +#define MSM_BUS_MASTER_BLSP_2 84
147 +#define MSM_BUS_MASTER_USB_HSIC 85
148 +#define MSM_BUS_MASTER_BLSP_1 86
149 +#define MSM_BUS_MASTER_USB_HS 87
150 +#define MSM_BUS_MASTER_PNOC_CFG 88
151 +#define MSM_BUS_MASTER_V_OCMEM_GFX3D 89
152 +#define MSM_BUS_MASTER_IPA 90
153 +#define MSM_BUS_MASTER_QPIC 91
154 +#define MSM_BUS_MASTER_MDPE 92
155 +#define MSM_BUS_MASTER_USB_HS2 93
156 +#define MSM_BUS_MASTER_VPU 94
157 +#define MSM_BUS_MASTER_UFS 95
158 +#define MSM_BUS_MASTER_BCAST 96
159 +#define MSM_BUS_MASTER_CRYPTO_CORE2 97
160 +#define MSM_BUS_MASTER_EMAC 98
161 +#define MSM_BUS_MASTER_VPU_1 99
162 +#define MSM_BUS_MASTER_PCIE_1 100
163 +#define MSM_BUS_MASTER_USB3_1 101
164 +#define MSM_BUS_MASTER_CNOC_MNOC_MMSS_CFG 102
165 +#define MSM_BUS_MASTER_CNOC_MNOC_CFG 103
166 +#define MSM_BUS_MASTER_TCU_0 104
167 +#define MSM_BUS_MASTER_TCU_1 105
168 +#define MSM_BUS_MASTER_CPP 106
169 +#define MSM_BUS_MASTER_AUDIO 107
170 +#define MSM_BUS_MASTER_PCIE_2 108
171 +#define MSM_BUS_MASTER_BLSP_BAM 109
172 +#define MSM_BUS_MASTER_USB2_BAM 110
173 +#define MSM_BUS_MASTER_ADDS_DMA0 111
174 +#define MSM_BUS_MASTER_ADDS_DMA1 112
175 +#define MSM_BUS_MASTER_ADDS_DMA2 113
176 +#define MSM_BUS_MASTER_ADDS_DMA3 114
177 +#define MSM_BUS_MASTER_QPIC_BAM 115
178 +#define MSM_BUS_MASTER_SDCC_BAM 116
179 +#define MSM_BUS_MASTER_DDRC_SNOC 117
180 +#define MSM_BUS_MASTER_WSS_0 118
181 +#define MSM_BUS_MASTER_WSS_1 119
182 +#define MSM_BUS_MASTER_ESS 120
183 +#define MSM_BUS_MASTER_QDSS_BAMNDP 121
184 +#define MSM_BUS_MASTER_QDSS_SNOC_CFG 122
185 +#define MSM_BUS_MASTER_LAST 130
186 +
187 +#define MSM_BUS_SYSTEM_FPB_MASTER_SYSTEM MSM_BUS_SYSTEM_MASTER_SYSTEM_FPB
188 +#define MSM_BUS_CPSS_FPB_MASTER_SYSTEM MSM_BUS_SYSTEM_MASTER_CPSS_FPB
189 +
190 +#define MSM_BUS_SNOC_MM_INT_0 10000
191 +#define MSM_BUS_SNOC_MM_INT_1 10001
192 +#define MSM_BUS_SNOC_MM_INT_2 10002
193 +#define MSM_BUS_SNOC_MM_INT_BIMC 10003
194 +#define MSM_BUS_SNOC_INT_0 10004
195 +#define MSM_BUS_SNOC_INT_1 10005
196 +#define MSM_BUS_SNOC_INT_BIMC 10006
197 +#define MSM_BUS_SNOC_BIMC_0_MAS 10007
198 +#define MSM_BUS_SNOC_BIMC_1_MAS 10008
199 +#define MSM_BUS_SNOC_QDSS_INT 10009
200 +#define MSM_BUS_PNOC_SNOC_MAS 10010
201 +#define MSM_BUS_PNOC_SNOC_SLV 10011
202 +#define MSM_BUS_PNOC_INT_0 10012
203 +#define MSM_BUS_PNOC_INT_1 10013
204 +#define MSM_BUS_PNOC_M_0 10014
205 +#define MSM_BUS_PNOC_M_1 10015
206 +#define MSM_BUS_BIMC_SNOC_MAS 10016
207 +#define MSM_BUS_BIMC_SNOC_SLV 10017
208 +#define MSM_BUS_PNOC_SLV_0 10018
209 +#define MSM_BUS_PNOC_SLV_1 10019
210 +#define MSM_BUS_PNOC_SLV_2 10020
211 +#define MSM_BUS_PNOC_SLV_3 10021
212 +#define MSM_BUS_PNOC_SLV_4 10022
213 +#define MSM_BUS_PNOC_SLV_8 10023
214 +#define MSM_BUS_PNOC_SLV_9 10024
215 +#define MSM_BUS_SNOC_BIMC_0_SLV 10025
216 +#define MSM_BUS_SNOC_BIMC_1_SLV 10026
217 +#define MSM_BUS_MNOC_BIMC_MAS 10027
218 +#define MSM_BUS_MNOC_BIMC_SLV 10028
219 +#define MSM_BUS_BIMC_MNOC_MAS 10029
220 +#define MSM_BUS_BIMC_MNOC_SLV 10030
221 +#define MSM_BUS_SNOC_BIMC_MAS 10031
222 +#define MSM_BUS_SNOC_BIMC_SLV 10032
223 +#define MSM_BUS_CNOC_SNOC_MAS 10033
224 +#define MSM_BUS_CNOC_SNOC_SLV 10034
225 +#define MSM_BUS_SNOC_CNOC_MAS 10035
226 +#define MSM_BUS_SNOC_CNOC_SLV 10036
227 +#define MSM_BUS_OVNOC_SNOC_MAS 10037
228 +#define MSM_BUS_OVNOC_SNOC_SLV 10038
229 +#define MSM_BUS_SNOC_OVNOC_MAS 10039
230 +#define MSM_BUS_SNOC_OVNOC_SLV 10040
231 +#define MSM_BUS_SNOC_PNOC_MAS 10041
232 +#define MSM_BUS_SNOC_PNOC_SLV 10042
233 +#define MSM_BUS_BIMC_INT_APPS_EBI 10043
234 +#define MSM_BUS_BIMC_INT_APPS_SNOC 10044
235 +#define MSM_BUS_SNOC_BIMC_2_MAS 10045
236 +#define MSM_BUS_SNOC_BIMC_2_SLV 10046
237 +#define MSM_BUS_PNOC_SLV_5 10047
238 +#define MSM_BUS_PNOC_SLV_6 10048
239 +#define MSM_BUS_PNOC_INT_2 10049
240 +#define MSM_BUS_PNOC_INT_3 10050
241 +#define MSM_BUS_PNOC_INT_4 10051
242 +#define MSM_BUS_PNOC_INT_5 10052
243 +#define MSM_BUS_PNOC_INT_6 10053
244 +#define MSM_BUS_PNOC_INT_7 10054
245 +#define MSM_BUS_BIMC_SNOC_1_MAS 10055
246 +#define MSM_BUS_BIMC_SNOC_1_SLV 10056
247 +#define MSM_BUS_PNOC_A1NOC_MAS 10057
248 +#define MSM_BUS_PNOC_A1NOC_SLV 10058
249 +#define MSM_BUS_CNOC_A1NOC_MAS 10059
250 +#define MSM_BUS_A0NOC_SNOC_MAS 10060
251 +#define MSM_BUS_A0NOC_SNOC_SLV 10061
252 +#define MSM_BUS_A1NOC_SNOC_SLV 10062
253 +#define MSM_BUS_A1NOC_SNOC_MAS 10063
254 +#define MSM_BUS_A2NOC_SNOC_MAS 10064
255 +#define MSM_BUS_A2NOC_SNOC_SLV 10065
256 +#define MSM_BUS_PNOC_SLV_7 10066
257 +#define MSM_BUS_INT_LAST 10067
258 +
259 +#define MSM_BUS_SLAVE_FIRST 512
260 +#define MSM_BUS_SLAVE_EBI_CH0 512
261 +#define MSM_BUS_SLAVE_EBI_CH1 513
262 +#define MSM_BUS_SLAVE_AMPSS_L2 514
263 +#define MSM_BUS_APPSS_SLAVE_FAB_MMSS 515
264 +#define MSM_BUS_APPSS_SLAVE_FAB_SYSTEM 516
265 +#define MSM_BUS_SYSTEM_SLAVE_FAB_APPS 517
266 +#define MSM_BUS_SLAVE_SPS 518
267 +#define MSM_BUS_SLAVE_SYSTEM_IMEM 519
268 +#define MSM_BUS_SLAVE_AMPSS 520
269 +#define MSM_BUS_SLAVE_MSS 521
270 +#define MSM_BUS_SLAVE_LPASS 522
271 +#define MSM_BUS_SYSTEM_SLAVE_CPSS_FPB 523
272 +#define MSM_BUS_SYSTEM_SLAVE_SYSTEM_FPB 524
273 +#define MSM_BUS_SYSTEM_SLAVE_MMSS_FPB 525
274 +#define MSM_BUS_SLAVE_CORESIGHT 526
275 +#define MSM_BUS_SLAVE_RIVA 527
276 +#define MSM_BUS_SLAVE_SMI 528
277 +#define MSM_BUS_MMSS_SLAVE_FAB_APPS 529
278 +#define MSM_BUS_MMSS_SLAVE_FAB_APPS_1 530
279 +#define MSM_BUS_SLAVE_MM_IMEM 531
280 +#define MSM_BUS_SLAVE_CRYPTO 532
281 +#define MSM_BUS_SLAVE_SPDM 533
282 +#define MSM_BUS_SLAVE_RPM 534
283 +#define MSM_BUS_SLAVE_RPM_MSG_RAM 535
284 +#define MSM_BUS_SLAVE_MPM 536
285 +#define MSM_BUS_SLAVE_PMIC1_SSBI1_A 537
286 +#define MSM_BUS_SLAVE_PMIC1_SSBI1_B 538
287 +#define MSM_BUS_SLAVE_PMIC1_SSBI1_C 539
288 +#define MSM_BUS_SLAVE_PMIC2_SSBI2_A 540
289 +#define MSM_BUS_SLAVE_PMIC2_SSBI2_B 541
290 +#define MSM_BUS_SLAVE_GSBI1_UART 542
291 +#define MSM_BUS_SLAVE_GSBI2_UART 543
292 +#define MSM_BUS_SLAVE_GSBI3_UART 544
293 +#define MSM_BUS_SLAVE_GSBI4_UART 545
294 +#define MSM_BUS_SLAVE_GSBI5_UART 546
295 +#define MSM_BUS_SLAVE_GSBI6_UART 547
296 +#define MSM_BUS_SLAVE_GSBI7_UART 548
297 +#define MSM_BUS_SLAVE_GSBI8_UART 549
298 +#define MSM_BUS_SLAVE_GSBI9_UART 550
299 +#define MSM_BUS_SLAVE_GSBI10_UART 551
300 +#define MSM_BUS_SLAVE_GSBI11_UART 552
301 +#define MSM_BUS_SLAVE_GSBI12_UART 553
302 +#define MSM_BUS_SLAVE_GSBI1_QUP 554
303 +#define MSM_BUS_SLAVE_GSBI2_QUP 555
304 +#define MSM_BUS_SLAVE_GSBI3_QUP 556
305 +#define MSM_BUS_SLAVE_GSBI4_QUP 557
306 +#define MSM_BUS_SLAVE_GSBI5_QUP 558
307 +#define MSM_BUS_SLAVE_GSBI6_QUP 559
308 +#define MSM_BUS_SLAVE_GSBI7_QUP 560
309 +#define MSM_BUS_SLAVE_GSBI8_QUP 561
310 +#define MSM_BUS_SLAVE_GSBI9_QUP 562
311 +#define MSM_BUS_SLAVE_GSBI10_QUP 563
312 +#define MSM_BUS_SLAVE_GSBI11_QUP 564
313 +#define MSM_BUS_SLAVE_GSBI12_QUP 565
314 +#define MSM_BUS_SLAVE_EBI2_NAND 566
315 +#define MSM_BUS_SLAVE_EBI2_CS0 567
316 +#define MSM_BUS_SLAVE_EBI2_CS1 568
317 +#define MSM_BUS_SLAVE_EBI2_CS2 569
318 +#define MSM_BUS_SLAVE_EBI2_CS3 570
319 +#define MSM_BUS_SLAVE_EBI2_CS4 571
320 +#define MSM_BUS_SLAVE_EBI2_CS5 572
321 +#define MSM_BUS_SLAVE_USB_FS1 573
322 +#define MSM_BUS_SLAVE_USB_FS2 574
323 +#define MSM_BUS_SLAVE_TSIF 575
324 +#define MSM_BUS_SLAVE_MSM_TSSC 576
325 +#define MSM_BUS_SLAVE_MSM_PDM 577
326 +#define MSM_BUS_SLAVE_MSM_DIMEM 578
327 +#define MSM_BUS_SLAVE_MSM_TCSR 579
328 +#define MSM_BUS_SLAVE_MSM_PRNG 580
329 +#define MSM_BUS_SLAVE_GSS 581
330 +#define MSM_BUS_SLAVE_SATA 582
331 +#define MSM_BUS_SLAVE_USB3 583
332 +#define MSM_BUS_SLAVE_WCSS 584
333 +#define MSM_BUS_SLAVE_OCIMEM 585
334 +#define MSM_BUS_SLAVE_SNOC_OCMEM 586
335 +#define MSM_BUS_SLAVE_SERVICE_SNOC 587
336 +#define MSM_BUS_SLAVE_QDSS_STM 588
337 +#define MSM_BUS_SLAVE_CAMERA_CFG 589
338 +#define MSM_BUS_SLAVE_DISPLAY_CFG 590
339 +#define MSM_BUS_SLAVE_OCMEM_CFG 591
340 +#define MSM_BUS_SLAVE_CPR_CFG 592
341 +#define MSM_BUS_SLAVE_CPR_XPU_CFG 593
342 +#define MSM_BUS_SLAVE_MISC_CFG 594
343 +#define MSM_BUS_SLAVE_MISC_XPU_CFG 595
344 +#define MSM_BUS_SLAVE_VENUS_CFG 596
345 +#define MSM_BUS_SLAVE_MISC_VENUS_CFG 597
346 +#define MSM_BUS_SLAVE_GRAPHICS_3D_CFG 598
347 +#define MSM_BUS_SLAVE_MMSS_CLK_CFG 599
348 +#define MSM_BUS_SLAVE_MMSS_CLK_XPU_CFG 600
349 +#define MSM_BUS_SLAVE_MNOC_MPU_CFG 601
350 +#define MSM_BUS_SLAVE_ONOC_MPU_CFG 602
351 +#define MSM_BUS_SLAVE_SERVICE_MNOC 603
352 +#define MSM_BUS_SLAVE_OCMEM 604
353 +#define MSM_BUS_SLAVE_SERVICE_ONOC 605
354 +#define MSM_BUS_SLAVE_SDCC_1 606
355 +#define MSM_BUS_SLAVE_SDCC_3 607
356 +#define MSM_BUS_SLAVE_SDCC_2 608
357 +#define MSM_BUS_SLAVE_SDCC_4 609
358 +#define MSM_BUS_SLAVE_BAM_DMA 610
359 +#define MSM_BUS_SLAVE_BLSP_2 611
360 +#define MSM_BUS_SLAVE_USB_HSIC 612
361 +#define MSM_BUS_SLAVE_BLSP_1 613
362 +#define MSM_BUS_SLAVE_USB_HS 614
363 +#define MSM_BUS_SLAVE_PDM 615
364 +#define MSM_BUS_SLAVE_PERIPH_APU_CFG 616
365 +#define MSM_BUS_SLAVE_PNOC_MPU_CFG 617
366 +#define MSM_BUS_SLAVE_PRNG 618
367 +#define MSM_BUS_SLAVE_SERVICE_PNOC 619
368 +#define MSM_BUS_SLAVE_CLK_CTL 620
369 +#define MSM_BUS_SLAVE_CNOC_MSS 621
370 +#define MSM_BUS_SLAVE_SECURITY 622
371 +#define MSM_BUS_SLAVE_TCSR 623
372 +#define MSM_BUS_SLAVE_TLMM 624
373 +#define MSM_BUS_SLAVE_CRYPTO_0_CFG 625
374 +#define MSM_BUS_SLAVE_CRYPTO_1_CFG 626
375 +#define MSM_BUS_SLAVE_IMEM_CFG 627
376 +#define MSM_BUS_SLAVE_MESSAGE_RAM 628
377 +#define MSM_BUS_SLAVE_BIMC_CFG 629
378 +#define MSM_BUS_SLAVE_BOOT_ROM 630
379 +#define MSM_BUS_SLAVE_CNOC_MNOC_MMSS_CFG 631
380 +#define MSM_BUS_SLAVE_PMIC_ARB 632
381 +#define MSM_BUS_SLAVE_SPDM_WRAPPER 633
382 +#define MSM_BUS_SLAVE_DEHR_CFG 634
383 +#define MSM_BUS_SLAVE_QDSS_CFG 635
384 +#define MSM_BUS_SLAVE_RBCPR_CFG 636
385 +#define MSM_BUS_SLAVE_RBCPR_QDSS_APU_CFG 637
386 +#define MSM_BUS_SLAVE_SNOC_MPU_CFG 638
387 +#define MSM_BUS_SLAVE_CNOC_ONOC_CFG 639
388 +#define MSM_BUS_SLAVE_CNOC_MNOC_CFG 640
389 +#define MSM_BUS_SLAVE_PNOC_CFG 641
390 +#define MSM_BUS_SLAVE_SNOC_CFG 642
391 +#define MSM_BUS_SLAVE_EBI1_DLL_CFG 643
392 +#define MSM_BUS_SLAVE_PHY_APU_CFG 644
393 +#define MSM_BUS_SLAVE_EBI1_PHY_CFG 645
394 +#define MSM_BUS_SLAVE_SERVICE_CNOC 646
395 +#define MSM_BUS_SLAVE_IPS_CFG 647
396 +#define MSM_BUS_SLAVE_QPIC 648
397 +#define MSM_BUS_SLAVE_DSI_CFG 649
398 +#define MSM_BUS_SLAVE_UFS_CFG 650
399 +#define MSM_BUS_SLAVE_RBCPR_CX_CFG 651
400 +#define MSM_BUS_SLAVE_RBCPR_MX_CFG 652
401 +#define MSM_BUS_SLAVE_PCIE_CFG 653
402 +#define MSM_BUS_SLAVE_USB_PHYS_CFG 654
403 +#define MSM_BUS_SLAVE_VIDEO_CAP_CFG 655
404 +#define MSM_BUS_SLAVE_AVSYNC_CFG 656
405 +#define MSM_BUS_SLAVE_CRYPTO_2_CFG 657
406 +#define MSM_BUS_SLAVE_VPU_CFG 658
407 +#define MSM_BUS_SLAVE_BCAST_CFG 659
408 +#define MSM_BUS_SLAVE_KLM_CFG 660
409 +#define MSM_BUS_SLAVE_GENI_IR_CFG 661
410 +#define MSM_BUS_SLAVE_OCMEM_GFX 662
411 +#define MSM_BUS_SLAVE_CATS_128 663
412 +#define MSM_BUS_SLAVE_OCMEM_64 664
413 +#define MSM_BUS_SLAVE_PCIE_0 665
414 +#define MSM_BUS_SLAVE_PCIE_1 666
415 +#define MSM_BUS_SLAVE_PCIE_0_CFG 667
416 +#define MSM_BUS_SLAVE_PCIE_1_CFG 668
417 +#define MSM_BUS_SLAVE_SRVC_MNOC 669
418 +#define MSM_BUS_SLAVE_USB_HS2 670
419 +#define MSM_BUS_SLAVE_AUDIO 671
420 +#define MSM_BUS_SLAVE_TCU 672
421 +#define MSM_BUS_SLAVE_APPSS 673
422 +#define MSM_BUS_SLAVE_PCIE_PARF 674
423 +#define MSM_BUS_SLAVE_USB3_PHY_CFG 675
424 +#define MSM_BUS_SLAVE_IPA_CFG 676
425 +#define MSM_BUS_SLAVE_A0NOC_SNOC 677
426 +#define MSM_BUS_SLAVE_A1NOC_SNOC 678
427 +#define MSM_BUS_SLAVE_A2NOC_SNOC 679
428 +#define MSM_BUS_SLAVE_HMSS_L3 680
429 +#define MSM_BUS_SLAVE_PIMEM_CFG 681
430 +#define MSM_BUS_SLAVE_DCC_CFG 682
431 +#define MSM_BUS_SLAVE_QDSS_RBCPR_APU_CFG 683
432 +#define MSM_BUS_SLAVE_PCIE_2_CFG 684
433 +#define MSM_BUS_SLAVE_PCIE20_AHB2PHY 685
434 +#define MSM_BUS_SLAVE_A0NOC_CFG 686
435 +#define MSM_BUS_SLAVE_A1NOC_CFG 687
436 +#define MSM_BUS_SLAVE_A2NOC_CFG 688
437 +#define MSM_BUS_SLAVE_A1NOC_MPU_CFG 689
438 +#define MSM_BUS_SLAVE_A2NOC_MPU_CFG 690
439 +#define MSM_BUS_SLAVE_A0NOC_SMMU_CFG 691
440 +#define MSM_BUS_SLAVE_A1NOC_SMMU_CFG 692
441 +#define MSM_BUS_SLAVE_A2NOC_SMMU_CFG 693
442 +#define MSM_BUS_SLAVE_LPASS_SMMU_CFG 694
443 +#define MSM_BUS_SLAVE_MMAGIC_CFG 695
444 +#define MSM_BUS_SLAVE_VENUS_THROTTLE_CFG 696
445 +#define MSM_BUS_SLAVE_SSC_CFG 697
446 +#define MSM_BUS_SLAVE_DSA_CFG 698
447 +#define MSM_BUS_SLAVE_DSA_MPU_CFG 699
448 +#define MSM_BUS_SLAVE_DISPLAY_THROTTLE_CFG 700
449 +#define MSM_BUS_SLAVE_SMMU_CPP_CFG 701
450 +#define MSM_BUS_SLAVE_SMMU_JPEG_CFG 702
451 +#define MSM_BUS_SLAVE_SMMU_MDP_CFG 703
452 +#define MSM_BUS_SLAVE_SMMU_ROTATOR_CFG 704
453 +#define MSM_BUS_SLAVE_SMMU_VENUS_CFG 705
454 +#define MSM_BUS_SLAVE_SMMU_VFE_CFG 706
455 +#define MSM_BUS_SLAVE_A0NOC_MPU_CFG 707
456 +#define MSM_BUS_SLAVE_VMEM_CFG 708
457 +#define MSM_BUS_SLAVE_CAMERA_THROTTLE_CFG 700
458 +#define MSM_BUS_SLAVE_VMEM 709
459 +#define MSM_BUS_SLAVE_AHB2PHY 710
460 +#define MSM_BUS_SLAVE_PIMEM 711
461 +#define MSM_BUS_SLAVE_SNOC_VMEM 712
462 +#define MSM_BUS_SLAVE_PCIE_2 713
463 +#define MSM_BUS_SLAVE_RBCPR_MX 714
464 +#define MSM_BUS_SLAVE_RBCPR_CX 715
465 +#define MSM_BUS_SLAVE_PRNG_APU_CFG 716
466 +#define MSM_BUS_SLAVE_PERIPH_MPU_CFG 717
467 +#define MSM_BUS_SLAVE_GCNT 718
468 +#define MSM_BUS_SLAVE_ADSS_CFG 719
469 +#define MSM_BUS_SLAVE_ADSS_VMIDMT_CFG 720
470 +#define MSM_BUS_SLAVE_QHSS_APU_CFG 721
471 +#define MSM_BUS_SLAVE_MDIO 722
472 +#define MSM_BUS_SLAVE_FEPHY_CFG 723
473 +#define MSM_BUS_SLAVE_SRIF 724
474 +#define MSM_BUS_SLAVE_LAST 730
475 +#define MSM_BUS_SLAVE_DDRC_CFG 731
476 +#define MSM_BUS_SLAVE_DDRC_APU_CFG 732
477 +#define MSM_BUS_SLAVE_MPU0_CFG 733
478 +#define MSM_BUS_SLAVE_MPU1_CFG 734
479 +#define MSM_BUS_SLAVE_MPU2_CFG 734
480 +#define MSM_BUS_SLAVE_ESS_VMIDMT_CFG 735
481 +#define MSM_BUS_SLAVE_ESS_APU_CFG 736
482 +#define MSM_BUS_SLAVE_USB2_CFG 737
483 +#define MSM_BUS_SLAVE_BLSP_CFG 738
484 +#define MSM_BUS_SLAVE_QPIC_CFG 739
485 +#define MSM_BUS_SLAVE_SDCC_CFG 740
486 +#define MSM_BUS_SLAVE_WSS0_VMIDMT_CFG 741
487 +#define MSM_BUS_SLAVE_WSS0_APU_CFG 742
488 +#define MSM_BUS_SLAVE_WSS1_VMIDMT_CFG 743
489 +#define MSM_BUS_SLAVE_WSS1_APU_CFG 744
490 +#define MSM_BUS_SLAVE_SRVC_PCNOC 745
491 +#define MSM_BUS_SLAVE_SNOC_DDRC 746
492 +#define MSM_BUS_SLAVE_A7SS 747
493 +#define MSM_BUS_SLAVE_WSS0_CFG 748
494 +#define MSM_BUS_SLAVE_WSS1_CFG 749
495 +#define MSM_BUS_SLAVE_PCIE 750
496 +#define MSM_BUS_SLAVE_USB3_CFG 751
497 +#define MSM_BUS_SLAVE_CRYPTO_CFG 752
498 +#define MSM_BUS_SLAVE_ESS_CFG 753
499 +#define MSM_BUS_SLAVE_SRVC_SNOC 754
500 +
501 +#define MSM_BUS_SYSTEM_FPB_SLAVE_SYSTEM MSM_BUS_SYSTEM_SLAVE_SYSTEM_FPB
502 +#define MSM_BUS_CPSS_FPB_SLAVE_SYSTEM MSM_BUS_SYSTEM_SLAVE_CPSS_FPB
503 +
504 +/*
505 + * ID's used in RPM messages
506 + */
507 +#define ICBID_MASTER_APPSS_PROC 0
508 +#define ICBID_MASTER_MSS_PROC 1
509 +#define ICBID_MASTER_MNOC_BIMC 2
510 +#define ICBID_MASTER_SNOC_BIMC 3
511 +#define ICBID_MASTER_SNOC_BIMC_0 ICBID_MASTER_SNOC_BIMC
512 +#define ICBID_MASTER_CNOC_MNOC_MMSS_CFG 4
513 +#define ICBID_MASTER_CNOC_MNOC_CFG 5
514 +#define ICBID_MASTER_GFX3D 6
515 +#define ICBID_MASTER_JPEG 7
516 +#define ICBID_MASTER_MDP 8
517 +#define ICBID_MASTER_MDP0 ICBID_MASTER_MDP
518 +#define ICBID_MASTER_MDPS ICBID_MASTER_MDP
519 +#define ICBID_MASTER_VIDEO 9
520 +#define ICBID_MASTER_VIDEO_P0 ICBID_MASTER_VIDEO
521 +#define ICBID_MASTER_VIDEO_P1 10
522 +#define ICBID_MASTER_VFE 11
523 +#define ICBID_MASTER_CNOC_ONOC_CFG 12
524 +#define ICBID_MASTER_JPEG_OCMEM 13
525 +#define ICBID_MASTER_MDP_OCMEM 14
526 +#define ICBID_MASTER_VIDEO_P0_OCMEM 15
527 +#define ICBID_MASTER_VIDEO_P1_OCMEM 16
528 +#define ICBID_MASTER_VFE_OCMEM 17
529 +#define ICBID_MASTER_LPASS_AHB 18
530 +#define ICBID_MASTER_QDSS_BAM 19
531 +#define ICBID_MASTER_SNOC_CFG 20
532 +#define ICBID_MASTER_BIMC_SNOC 21
533 +#define ICBID_MASTER_CNOC_SNOC 22
534 +#define ICBID_MASTER_CRYPTO 23
535 +#define ICBID_MASTER_CRYPTO_CORE0 ICBID_MASTER_CRYPTO
536 +#define ICBID_MASTER_CRYPTO_CORE1 24
537 +#define ICBID_MASTER_LPASS_PROC 25
538 +#define ICBID_MASTER_MSS 26
539 +#define ICBID_MASTER_MSS_NAV 27
540 +#define ICBID_MASTER_OCMEM_DMA 28
541 +#define ICBID_MASTER_PNOC_SNOC 29
542 +#define ICBID_MASTER_WCSS 30
543 +#define ICBID_MASTER_QDSS_ETR 31
544 +#define ICBID_MASTER_USB3 32
545 +#define ICBID_MASTER_USB3_0 ICBID_MASTER_USB3
546 +#define ICBID_MASTER_SDCC_1 33
547 +#define ICBID_MASTER_SDCC_3 34
548 +#define ICBID_MASTER_SDCC_2 35
549 +#define ICBID_MASTER_SDCC_4 36
550 +#define ICBID_MASTER_TSIF 37
551 +#define ICBID_MASTER_BAM_DMA 38
552 +#define ICBID_MASTER_BLSP_2 39
553 +#define ICBID_MASTER_USB_HSIC 40
554 +#define ICBID_MASTER_BLSP_1 41
555 +#define ICBID_MASTER_USB_HS 42
556 +#define ICBID_MASTER_USB_HS1 ICBID_MASTER_USB_HS
557 +#define ICBID_MASTER_PNOC_CFG 43
558 +#define ICBID_MASTER_SNOC_PNOC 44
559 +#define ICBID_MASTER_RPM_INST 45
560 +#define ICBID_MASTER_RPM_DATA 46
561 +#define ICBID_MASTER_RPM_SYS 47
562 +#define ICBID_MASTER_DEHR 48
563 +#define ICBID_MASTER_QDSS_DAP 49
564 +#define ICBID_MASTER_SPDM 50
565 +#define ICBID_MASTER_TIC 51
566 +#define ICBID_MASTER_SNOC_CNOC 52
567 +#define ICBID_MASTER_GFX3D_OCMEM 53
568 +#define ICBID_MASTER_GFX3D_GMEM ICBID_MASTER_GFX3D_OCMEM
569 +#define ICBID_MASTER_OVIRT_SNOC 54
570 +#define ICBID_MASTER_SNOC_OVIRT 55
571 +#define ICBID_MASTER_SNOC_GVIRT ICBID_MASTER_SNOC_OVIRT
572 +#define ICBID_MASTER_ONOC_OVIRT 56
573 +#define ICBID_MASTER_USB_HS2 57
574 +#define ICBID_MASTER_QPIC 58
575 +#define ICBID_MASTER_IPA 59
576 +#define ICBID_MASTER_DSI 60
577 +#define ICBID_MASTER_MDP1 61
578 +#define ICBID_MASTER_MDPE ICBID_MASTER_MDP1
579 +#define ICBID_MASTER_VPU_PROC 62
580 +#define ICBID_MASTER_VPU 63
581 +#define ICBID_MASTER_VPU0 ICBID_MASTER_VPU
582 +#define ICBID_MASTER_CRYPTO_CORE2 64
583 +#define ICBID_MASTER_PCIE_0 65
584 +#define ICBID_MASTER_PCIE_1 66
585 +#define ICBID_MASTER_SATA 67
586 +#define ICBID_MASTER_UFS 68
587 +#define ICBID_MASTER_USB3_1 69
588 +#define ICBID_MASTER_VIDEO_OCMEM 70
589 +#define ICBID_MASTER_VPU1 71
590 +#define ICBID_MASTER_VCAP 72
591 +#define ICBID_MASTER_EMAC 73
592 +#define ICBID_MASTER_BCAST 74
593 +#define ICBID_MASTER_MMSS_PROC 75
594 +#define ICBID_MASTER_SNOC_BIMC_1 76
595 +#define ICBID_MASTER_SNOC_PCNOC 77
596 +#define ICBID_MASTER_AUDIO 78
597 +#define ICBID_MASTER_MM_INT_0 79
598 +#define ICBID_MASTER_MM_INT_1 80
599 +#define ICBID_MASTER_MM_INT_2 81
600 +#define ICBID_MASTER_MM_INT_BIMC 82
601 +#define ICBID_MASTER_MSS_INT 83
602 +#define ICBID_MASTER_PCNOC_CFG 84
603 +#define ICBID_MASTER_PCNOC_INT_0 85
604 +#define ICBID_MASTER_PCNOC_INT_1 86
605 +#define ICBID_MASTER_PCNOC_M_0 87
606 +#define ICBID_MASTER_PCNOC_M_1 88
607 +#define ICBID_MASTER_PCNOC_S_0 89
608 +#define ICBID_MASTER_PCNOC_S_1 90
609 +#define ICBID_MASTER_PCNOC_S_2 91
610 +#define ICBID_MASTER_PCNOC_S_3 92
611 +#define ICBID_MASTER_PCNOC_S_4 93
612 +#define ICBID_MASTER_PCNOC_S_6 94
613 +#define ICBID_MASTER_PCNOC_S_7 95
614 +#define ICBID_MASTER_PCNOC_S_8 96
615 +#define ICBID_MASTER_PCNOC_S_9 97
616 +#define ICBID_MASTER_QDSS_INT 98
617 +#define ICBID_MASTER_SNOC_INT_0 99
618 +#define ICBID_MASTER_SNOC_INT_1 100
619 +#define ICBID_MASTER_SNOC_INT_BIMC 101
620 +#define ICBID_MASTER_TCU_0 102
621 +#define ICBID_MASTER_TCU_1 103
622 +#define ICBID_MASTER_BIMC_INT_0 104
623 +#define ICBID_MASTER_BIMC_INT_1 105
624 +#define ICBID_MASTER_CAMERA 106
625 +#define ICBID_MASTER_RICA 107
626 +#define ICBID_MASTER_PCNOC_S_5 129
627 +#define ICBID_MASTER_PCNOC_INT_2 124
628 +#define ICBID_MASTER_PCNOC_INT_3 125
629 +#define ICBID_MASTER_PCNOC_INT_4 126
630 +#define ICBID_MASTER_PCNOC_INT_5 127
631 +#define ICBID_MASTER_PCNOC_INT_6 128
632 +#define ICBID_MASTER_PCIE_2 119
633 +#define ICBID_MASTER_MASTER_CNOC_A1NOC 116
634 +#define ICBID_MASTER_A0NOC_SNOC 110
635 +#define ICBID_MASTER_A1NOC_SNOC 111
636 +#define ICBID_MASTER_A2NOC_SNOC 112
637 +#define ICBID_MASTER_PNOC_A1NOC 117
638 +#define ICBID_MASTER_ROTATOR 120
639 +#define ICBID_MASTER_SNOC_VMEM 114
640 +#define ICBID_MASTER_VENUS_VMEM 121
641 +#define ICBID_MASTER_HMSS 118
642 +#define ICBID_MASTER_BIMC_SNOC_1 109
643 +#define ICBID_MASTER_CNOC_A1NOC 116
644 +#define ICBID_MASTER_CPP 115
645 +#define ICBID_MASTER_BLSP_BAM 130
646 +#define ICBID_MASTER_USB2_BAM 131
647 +#define ICBID_MASTER_ADSS_DMA0 132
648 +#define ICBID_MASTER_ADSS_DMA1 133
649 +#define ICBID_MASTER_ADSS_DMA2 134
650 +#define ICBID_MASTER_ADSS_DMA3 135
651 +#define ICBID_MASTER_QPIC_BAM 136
652 +#define ICBID_MASTER_SDCC_BAM 137
653 +#define ICBID_MASTER_DDRC_SNOC 138
654 +#define ICBID_MASTER_WSS_0 139
655 +#define ICBID_MASTER_WSS_1 140
656 +#define ICBID_MASTER_ESS 141
657 +#define ICBID_MASTER_PCIE 142
658 +#define ICBID_MASTER_QDSS_BAMNDP 143
659 +#define ICBID_MASTER_QDSS_SNOC_CFG 144
660 +
661 +#define ICBID_SLAVE_EBI1 0
662 +#define ICBID_SLAVE_APPSS_L2 1
663 +#define ICBID_SLAVE_BIMC_SNOC 2
664 +#define ICBID_SLAVE_CAMERA_CFG 3
665 +#define ICBID_SLAVE_DISPLAY_CFG 4
666 +#define ICBID_SLAVE_OCMEM_CFG 5
667 +#define ICBID_SLAVE_CPR_CFG 6
668 +#define ICBID_SLAVE_CPR_XPU_CFG 7
669 +#define ICBID_SLAVE_MISC_CFG 8
670 +#define ICBID_SLAVE_MISC_XPU_CFG 9
671 +#define ICBID_SLAVE_VENUS_CFG 10
672 +#define ICBID_SLAVE_GFX3D_CFG 11
673 +#define ICBID_SLAVE_MMSS_CLK_CFG 12
674 +#define ICBID_SLAVE_MMSS_CLK_XPU_CFG 13
675 +#define ICBID_SLAVE_MNOC_MPU_CFG 14
676 +#define ICBID_SLAVE_ONOC_MPU_CFG 15
677 +#define ICBID_SLAVE_MNOC_BIMC 16
678 +#define ICBID_SLAVE_SERVICE_MNOC 17
679 +#define ICBID_SLAVE_OCMEM 18
680 +#define ICBID_SLAVE_GMEM ICBID_SLAVE_OCMEM
681 +#define ICBID_SLAVE_SERVICE_ONOC 19
682 +#define ICBID_SLAVE_APPSS 20
683 +#define ICBID_SLAVE_LPASS 21
684 +#define ICBID_SLAVE_USB3 22
685 +#define ICBID_SLAVE_USB3_0 ICBID_SLAVE_USB3
686 +#define ICBID_SLAVE_WCSS 23
687 +#define ICBID_SLAVE_SNOC_BIMC 24
688 +#define ICBID_SLAVE_SNOC_BIMC_0 ICBID_SLAVE_SNOC_BIMC
689 +#define ICBID_SLAVE_SNOC_CNOC 25
690 +#define ICBID_SLAVE_IMEM 26
691 +#define ICBID_SLAVE_OCIMEM ICBID_SLAVE_IMEM
692 +#define ICBID_SLAVE_SNOC_OVIRT 27
693 +#define ICBID_SLAVE_SNOC_GVIRT ICBID_SLAVE_SNOC_OVIRT
694 +#define ICBID_SLAVE_SNOC_PNOC 28
695 +#define ICBID_SLAVE_SNOC_PCNOC ICBID_SLAVE_SNOC_PNOC
696 +#define ICBID_SLAVE_SERVICE_SNOC 29
697 +#define ICBID_SLAVE_QDSS_STM 30
698 +#define ICBID_SLAVE_SDCC_1 31
699 +#define ICBID_SLAVE_SDCC_3 32
700 +#define ICBID_SLAVE_SDCC_2 33
701 +#define ICBID_SLAVE_SDCC_4 34
702 +#define ICBID_SLAVE_TSIF 35
703 +#define ICBID_SLAVE_BAM_DMA 36
704 +#define ICBID_SLAVE_BLSP_2 37
705 +#define ICBID_SLAVE_USB_HSIC 38
706 +#define ICBID_SLAVE_BLSP_1 39
707 +#define ICBID_SLAVE_USB_HS 40
708 +#define ICBID_SLAVE_USB_HS1 ICBID_SLAVE_USB_HS
709 +#define ICBID_SLAVE_PDM 41
710 +#define ICBID_SLAVE_PERIPH_APU_CFG 42
711 +#define ICBID_SLAVE_PNOC_MPU_CFG 43
712 +#define ICBID_SLAVE_PRNG 44
713 +#define ICBID_SLAVE_PNOC_SNOC 45
714 +#define ICBID_SLAVE_PCNOC_SNOC ICBID_SLAVE_PNOC_SNOC
715 +#define ICBID_SLAVE_SERVICE_PNOC 46
716 +#define ICBID_SLAVE_CLK_CTL 47
717 +#define ICBID_SLAVE_CNOC_MSS 48
718 +#define ICBID_SLAVE_PCNOC_MSS ICBID_SLAVE_CNOC_MSS
719 +#define ICBID_SLAVE_SECURITY 49
720 +#define ICBID_SLAVE_TCSR 50
721 +#define ICBID_SLAVE_TLMM 51
722 +#define ICBID_SLAVE_CRYPTO_0_CFG 52
723 +#define ICBID_SLAVE_CRYPTO_1_CFG 53
724 +#define ICBID_SLAVE_IMEM_CFG 54
725 +#define ICBID_SLAVE_MESSAGE_RAM 55
726 +#define ICBID_SLAVE_BIMC_CFG 56
727 +#define ICBID_SLAVE_BOOT_ROM 57
728 +#define ICBID_SLAVE_CNOC_MNOC_MMSS_CFG 58
729 +#define ICBID_SLAVE_PMIC_ARB 59
730 +#define ICBID_SLAVE_SPDM_WRAPPER 60
731 +#define ICBID_SLAVE_DEHR_CFG 61
732 +#define ICBID_SLAVE_MPM 62
733 +#define ICBID_SLAVE_QDSS_CFG 63
734 +#define ICBID_SLAVE_RBCPR_CFG 64
735 +#define ICBID_SLAVE_RBCPR_CX_CFG ICBID_SLAVE_RBCPR_CFG
736 +#define ICBID_SLAVE_RBCPR_QDSS_APU_CFG 65
737 +#define ICBID_SLAVE_CNOC_MNOC_CFG 66
738 +#define ICBID_SLAVE_SNOC_MPU_CFG 67
739 +#define ICBID_SLAVE_CNOC_ONOC_CFG 68
740 +#define ICBID_SLAVE_PNOC_CFG 69
741 +#define ICBID_SLAVE_SNOC_CFG 70
742 +#define ICBID_SLAVE_EBI1_DLL_CFG 71
743 +#define ICBID_SLAVE_PHY_APU_CFG 72
744 +#define ICBID_SLAVE_EBI1_PHY_CFG 73
745 +#define ICBID_SLAVE_RPM 74
746 +#define ICBID_SLAVE_CNOC_SNOC 75
747 +#define ICBID_SLAVE_SERVICE_CNOC 76
748 +#define ICBID_SLAVE_OVIRT_SNOC 77
749 +#define ICBID_SLAVE_OVIRT_OCMEM 78
750 +#define ICBID_SLAVE_USB_HS2 79
751 +#define ICBID_SLAVE_QPIC 80
752 +#define ICBID_SLAVE_IPS_CFG 81
753 +#define ICBID_SLAVE_DSI_CFG 82
754 +#define ICBID_SLAVE_USB3_1 83
755 +#define ICBID_SLAVE_PCIE_0 84
756 +#define ICBID_SLAVE_PCIE_1 85
757 +#define ICBID_SLAVE_PSS_SMMU_CFG 86
758 +#define ICBID_SLAVE_CRYPTO_2_CFG 87
759 +#define ICBID_SLAVE_PCIE_0_CFG 88
760 +#define ICBID_SLAVE_PCIE_1_CFG 89
761 +#define ICBID_SLAVE_SATA_CFG 90
762 +#define ICBID_SLAVE_SPSS_GENI_IR 91
763 +#define ICBID_SLAVE_UFS_CFG 92
764 +#define ICBID_SLAVE_AVSYNC_CFG 93
765 +#define ICBID_SLAVE_VPU_CFG 94
766 +#define ICBID_SLAVE_USB_PHY_CFG 95
767 +#define ICBID_SLAVE_RBCPR_MX_CFG 96
768 +#define ICBID_SLAVE_PCIE_PARF 97
769 +#define ICBID_SLAVE_VCAP_CFG 98
770 +#define ICBID_SLAVE_EMAC_CFG 99
771 +#define ICBID_SLAVE_BCAST_CFG 100
772 +#define ICBID_SLAVE_KLM_CFG 101
773 +#define ICBID_SLAVE_DISPLAY_PWM 102
774 +#define ICBID_SLAVE_GENI 103
775 +#define ICBID_SLAVE_SNOC_BIMC_1 104
776 +#define ICBID_SLAVE_AUDIO 105
777 +#define ICBID_SLAVE_CATS_0 106
778 +#define ICBID_SLAVE_CATS_1 107
779 +#define ICBID_SLAVE_MM_INT_0 108
780 +#define ICBID_SLAVE_MM_INT_1 109
781 +#define ICBID_SLAVE_MM_INT_2 110
782 +#define ICBID_SLAVE_MM_INT_BIMC 111
783 +#define ICBID_SLAVE_MMU_MODEM_XPU_CFG 112
784 +#define ICBID_SLAVE_MSS_INT 113
785 +#define ICBID_SLAVE_PCNOC_INT_0 114
786 +#define ICBID_SLAVE_PCNOC_INT_1 115
787 +#define ICBID_SLAVE_PCNOC_M_0 116
788 +#define ICBID_SLAVE_PCNOC_M_1 117
789 +#define ICBID_SLAVE_PCNOC_S_0 118
790 +#define ICBID_SLAVE_PCNOC_S_1 119
791 +#define ICBID_SLAVE_PCNOC_S_2 120
792 +#define ICBID_SLAVE_PCNOC_S_3 121
793 +#define ICBID_SLAVE_PCNOC_S_4 122
794 +#define ICBID_SLAVE_PCNOC_S_6 123
795 +#define ICBID_SLAVE_PCNOC_S_7 124
796 +#define ICBID_SLAVE_PCNOC_S_8 125
797 +#define ICBID_SLAVE_PCNOC_S_9 126
798 +#define ICBID_SLAVE_PRNG_XPU_CFG 127
799 +#define ICBID_SLAVE_QDSS_INT 128
800 +#define ICBID_SLAVE_RPM_XPU_CFG 129
801 +#define ICBID_SLAVE_SNOC_INT_0 130
802 +#define ICBID_SLAVE_SNOC_INT_1 131
803 +#define ICBID_SLAVE_SNOC_INT_BIMC 132
804 +#define ICBID_SLAVE_TCU 133
805 +#define ICBID_SLAVE_BIMC_INT_0 134
806 +#define ICBID_SLAVE_BIMC_INT_1 135
807 +#define ICBID_SLAVE_RICA_CFG 136
808 +#define ICBID_SLAVE_PCNOC_S_5 189
809 +#define ICBID_SLAVE_PCNOC_S_7 124
810 +#define ICBID_SLAVE_PCNOC_INT_2 184
811 +#define ICBID_SLAVE_PCNOC_INT_3 185
812 +#define ICBID_SLAVE_PCNOC_INT_4 186
813 +#define ICBID_SLAVE_PCNOC_INT_5 187
814 +#define ICBID_SLAVE_PCNOC_INT_6 188
815 +#define ICBID_SLAVE_USB3_PHY_CFG 182
816 +#define ICBID_SLAVE_IPA_CFG 183
817 +
818 +#define ICBID_SLAVE_A0NOC_SNOC 141
819 +#define ICBID_SLAVE_A1NOC_SNOC 142
820 +#define ICBID_SLAVE_A2NOC_SNOC 143
821 +#define ICBID_SLAVE_BIMC_SNOC_1 138
822 +#define ICBID_SLAVE_PIMEM 167
823 +#define ICBID_SLAVE_PIMEM_CFG 168
824 +#define ICBID_SLAVE_DCC_CFG 155
825 +#define ICBID_SLAVE_QDSS_RBCPR_APU_CFG 168
826 +#define ICBID_SLAVE_A0NOC_CFG 144
827 +#define ICBID_SLAVE_PCIE_2_CFG 165
828 +#define ICBID_SLAVE_PCIE20_AHB2PHY 163
829 +#define ICBID_SLAVE_PCIE_2 164
830 +#define ICBID_SLAVE_A1NOC_CFG 147
831 +#define ICBID_SLAVE_A1NOC_MPU_CFG 148
832 +#define ICBID_SLAVE_A1NOC_SMMU_CFG 149
833 +#define ICBID_SLAVE_A2NOC_CFG 150
834 +#define ICBID_SLAVE_A2NOC_MPU_CFG 151
835 +#define ICBID_SLAVE_A2NOC_SMMU_CFG 152
836 +#define ICBID_SLAVE_AHB2PHY 153
837 +#define ICBID_SLAVE_HMSS_L3 161
838 +#define ICBID_SLAVE_LPASS_SMMU_CFG 161
839 +#define ICBID_SLAVE_MMAGIC_CFG 162
840 +#define ICBID_SLAVE_SSC_CFG 177
841 +#define ICBID_SLAVE_VENUS_THROTTLE_CFG 178
842 +#define ICBID_SLAVE_DISPLAY_THROTTLE_CFG 156
843 +#define ICBID_SLAVE_CAMERA_THROTTLE_CFG 154
844 +#define ICBID_SLAVE_DSA_CFG 157
845 +#define ICBID_SLAVE_DSA_MPU_CFG 158
846 +#define ICBID_SLAVE_SMMU_CPP_CFG 171
847 +#define ICBID_SLAVE_SMMU_JPEG_CFG 172
848 +#define ICBID_SLAVE_SMMU_MDP_CFG 173
849 +#define ICBID_SLAVE_SMMU_ROTATOR_CFG 174
850 +#define ICBID_SLAVE_SMMU_VENUS_CFG 175
851 +#define ICBID_SLAVE_SMMU_VFE_CFG 176
852 +#define ICBID_SLAVE_A0NOC_MPU_CFG 145
853 +#define ICBID_SLAVE_A0NOC_SMMU_CFG 146
854 +#define ICBID_SLAVE_VMEM_CFG 180
855 +#define ICBID_SLAVE_VMEM 179
856 +#define ICBID_SLAVE_PNOC_A1NOC 139
857 +#define ICBID_SLAVE_SNOC_VMEM 140
858 +#define ICBID_SLAVE_RBCPR_MX 170
859 +#define ICBID_SLAVE_RBCPR_CX 169
860 +#define ICBID_SLAVE_PRNG_APU_CFG 190
861 +#define ICBID_SLAVE_PERIPH_MPU_CFG 191
862 +#define ICBID_SLAVE_GCNT 192
863 +#define ICBID_SLAVE_ADSS_CFG 193
864 +#define ICBID_SLAVE_ADSS_APU 194
865 +#define ICBID_SLAVE_ADSS_VMIDMT_CFG 195
866 +#define ICBID_SLAVE_QHSS_APU_CFG 196
867 +#define ICBID_SLAVE_MDIO 197
868 +#define ICBID_SLAVE_FEPHY_CFG 198
869 +#define ICBID_SLAVE_SRIF 199
870 +#define ICBID_SLAVE_DDRC_CFG 200
871 +#define ICBID_SLAVE_DDRC_APU_CFG 201
872 +#define ICBID_SLAVE_DDRC_MPU0_CFG 202
873 +#define ICBID_SLAVE_DDRC_MPU1_CFG 203
874 +#define ICBID_SLAVE_DDRC_MPU2_CFG 210
875 +#define ICBID_SLAVE_ESS_VMIDMT_CFG 211
876 +#define ICBID_SLAVE_ESS_APU_CFG 212
877 +#define ICBID_SLAVE_USB2_CFG 213
878 +#define ICBID_SLAVE_BLSP_CFG 214
879 +#define ICBID_SLAVE_QPIC_CFG 215
880 +#define ICBID_SLAVE_SDCC_CFG 216
881 +#define ICBID_SLAVE_WSS0_VMIDMT_CFG 217
882 +#define ICBID_SLAVE_WSS0_APU_CFG 218
883 +#define ICBID_SLAVE_WSS1_VMIDMT_CFG 219
884 +#define ICBID_SLAVE_WSS1_APU_CFG 220
885 +#define ICBID_SLAVE_SRVC_PCNOC 221
886 +#define ICBID_SLAVE_SNOC_DDRC 222
887 +#define ICBID_SLAVE_A7SS 223
888 +#define ICBID_SLAVE_WSS0_CFG 224
889 +#define ICBID_SLAVE_WSS1_CFG 225
890 +#define ICBID_SLAVE_PCIE 226
891 +#define ICBID_SLAVE_USB3_CFG 227
892 +#define ICBID_SLAVE_CRYPTO_CFG 228
893 +#define ICBID_SLAVE_ESS_CFG 229
894 +#define ICBID_SLAVE_SRVC_SNOC 230
895 +#endif
896 --- /dev/null
897 +++ b/include/dt-bindings/msm/msm-bus-rule-ops.h
898 @@ -0,0 +1,32 @@
899 +/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
900 + *
901 + * This program is free software; you can redistribute it and/or modify
902 + * it under the terms of the GNU General Public License version 2 and
903 + * only version 2 as published by the Free Software Foundation.
904 + *
905 + * This program is distributed in the hope that it will be useful,
906 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
907 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
908 + * GNU General Public License for more details.
909 + */
910 +
911 +#ifndef __MSM_BUS_RULE_OPS_H
912 +#define __MSM_BUS_RULE_OPS_H
913 +
914 +#define FLD_IB 0
915 +#define FLD_AB 1
916 +#define FLD_CLK 2
917 +
918 +#define OP_LE 0
919 +#define OP_LT 1
920 +#define OP_GE 2
921 +#define OP_GT 3
922 +#define OP_NOOP 4
923 +
924 +#define RULE_STATE_NOT_APPLIED 0
925 +#define RULE_STATE_APPLIED 1
926 +
927 +#define THROTTLE_ON 0
928 +#define THROTTLE_OFF 1
929 +
930 +#endif
931 --- /dev/null
932 +++ b/drivers/bus/msm_bus/Kconfig
933 @@ -0,0 +1,19 @@
934 +config BUS_TOPOLOGY_ADHOC
935 + bool "ad-hoc bus scaling topology"
936 + depends on ARCH_QCOM
937 + default n
938 + help
939 + This option enables a driver that can handle adhoc bus topologies.
940 + Adhoc bus topology driver allows one to many connections and maintains
941 + directionality of connections by explicitly listing device connections
942 + thus avoiding illegal routes.
943 +
944 +config MSM_BUS_SCALING
945 + bool "Bus scaling driver"
946 + depends on BUS_TOPOLOGY_ADHOC
947 + default n
948 + help
949 + This option enables bus scaling on MSM devices. Bus scaling
950 + allows devices to request the clocks be set to rates sufficient
951 + for the active devices needs without keeping the clocks at max
952 + frequency when a slower speed is sufficient.
953 --- /dev/null
954 +++ b/drivers/bus/msm_bus/Makefile
955 @@ -0,0 +1,12 @@
956 +#
957 +# Makefile for msm-bus driver specific files
958 +#
959 +obj-y += msm_bus_bimc.o msm_bus_noc.o msm_bus_core.o msm_bus_client_api.o \
960 + msm_bus_id.o
961 +obj-$(CONFIG_OF) += msm_bus_of.o
962 +
963 +obj-y += msm_bus_fabric_adhoc.o msm_bus_arb_adhoc.o msm_bus_rules.o
964 +obj-$(CONFIG_OF) += msm_bus_of_adhoc.o
965 +obj-$(CONFIG_CORESIGHT) += msm_buspm_coresight_adhoc.o
966 +
967 +obj-$(CONFIG_DEBUG_FS) += msm_bus_dbg.o
968 --- /dev/null
969 +++ b/drivers/bus/msm_bus/msm-bus-board.h
970 @@ -0,0 +1,198 @@
971 +/* Copyright (c) 2010-2014, The Linux Foundation. All rights reserved.
972 + *
973 + * This program is free software; you can redistribute it and/or modify
974 + * it under the terms of the GNU General Public License version 2 and
975 + * only version 2 as published by the Free Software Foundation.
976 + *
977 + * This program is distributed in the hope that it will be useful,
978 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
979 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
980 + * GNU General Public License for more details.
981 + */
982 +
983 +#ifndef __ASM_ARCH_MSM_BUS_BOARD_H
984 +#define __ASM_ARCH_MSM_BUS_BOARD_H
985 +
986 +#include <linux/types.h>
987 +#include <linux/input.h>
988 +
989 +enum context {
990 + DUAL_CTX,
991 + ACTIVE_CTX,
992 + NUM_CTX
993 +};
994 +
995 +struct msm_bus_fabric_registration {
996 + unsigned int id;
997 + const char *name;
998 + struct msm_bus_node_info *info;
999 + unsigned int len;
1000 + int ahb;
1001 + const char *fabclk[NUM_CTX];
1002 + const char *iface_clk;
1003 + unsigned int offset;
1004 + unsigned int haltid;
1005 + unsigned int rpm_enabled;
1006 + unsigned int nmasters;
1007 + unsigned int nslaves;
1008 + unsigned int ntieredslaves;
1009 + bool il_flag;
1010 + const struct msm_bus_board_algorithm *board_algo;
1011 + int hw_sel;
1012 + void *hw_data;
1013 + uint32_t qos_freq;
1014 + uint32_t qos_baseoffset;
1015 + u64 nr_lim_thresh;
1016 + uint32_t eff_fact;
1017 + uint32_t qos_delta;
1018 + bool virt;
1019 +};
1020 +
1021 +struct msm_bus_device_node_registration {
1022 + struct msm_bus_node_device_type *info;
1023 + unsigned int num_devices;
1024 + bool virt;
1025 +};
1026 +
1027 +enum msm_bus_bw_tier_type {
1028 + MSM_BUS_BW_TIER1 = 1,
1029 + MSM_BUS_BW_TIER2,
1030 + MSM_BUS_BW_COUNT,
1031 + MSM_BUS_BW_SIZE = 0x7FFFFFFF,
1032 +};
1033 +
1034 +struct msm_bus_halt_vector {
1035 + uint32_t haltval;
1036 + uint32_t haltmask;
1037 +};
1038 +
1039 +extern struct msm_bus_fabric_registration msm_bus_apps_fabric_pdata;
1040 +extern struct msm_bus_fabric_registration msm_bus_sys_fabric_pdata;
1041 +extern struct msm_bus_fabric_registration msm_bus_mm_fabric_pdata;
1042 +extern struct msm_bus_fabric_registration msm_bus_sys_fpb_pdata;
1043 +extern struct msm_bus_fabric_registration msm_bus_cpss_fpb_pdata;
1044 +extern struct msm_bus_fabric_registration msm_bus_def_fab_pdata;
1045 +
1046 +extern struct msm_bus_fabric_registration msm_bus_8960_apps_fabric_pdata;
1047 +extern struct msm_bus_fabric_registration msm_bus_8960_sys_fabric_pdata;
1048 +extern struct msm_bus_fabric_registration msm_bus_8960_mm_fabric_pdata;
1049 +extern struct msm_bus_fabric_registration msm_bus_8960_sg_mm_fabric_pdata;
1050 +extern struct msm_bus_fabric_registration msm_bus_8960_sys_fpb_pdata;
1051 +extern struct msm_bus_fabric_registration msm_bus_8960_cpss_fpb_pdata;
1052 +
1053 +extern struct msm_bus_fabric_registration msm_bus_8064_apps_fabric_pdata;
1054 +extern struct msm_bus_fabric_registration msm_bus_8064_sys_fabric_pdata;
1055 +extern struct msm_bus_fabric_registration msm_bus_8064_mm_fabric_pdata;
1056 +extern struct msm_bus_fabric_registration msm_bus_8064_sys_fpb_pdata;
1057 +extern struct msm_bus_fabric_registration msm_bus_8064_cpss_fpb_pdata;
1058 +
1059 +extern struct msm_bus_fabric_registration msm_bus_9615_sys_fabric_pdata;
1060 +extern struct msm_bus_fabric_registration msm_bus_9615_def_fab_pdata;
1061 +
1062 +extern struct msm_bus_fabric_registration msm_bus_8930_apps_fabric_pdata;
1063 +extern struct msm_bus_fabric_registration msm_bus_8930_sys_fabric_pdata;
1064 +extern struct msm_bus_fabric_registration msm_bus_8930_mm_fabric_pdata;
1065 +extern struct msm_bus_fabric_registration msm_bus_8930_sys_fpb_pdata;
1066 +extern struct msm_bus_fabric_registration msm_bus_8930_cpss_fpb_pdata;
1067 +
1068 +extern struct msm_bus_fabric_registration msm_bus_8974_sys_noc_pdata;
1069 +extern struct msm_bus_fabric_registration msm_bus_8974_mmss_noc_pdata;
1070 +extern struct msm_bus_fabric_registration msm_bus_8974_bimc_pdata;
1071 +extern struct msm_bus_fabric_registration msm_bus_8974_ocmem_noc_pdata;
1072 +extern struct msm_bus_fabric_registration msm_bus_8974_periph_noc_pdata;
1073 +extern struct msm_bus_fabric_registration msm_bus_8974_config_noc_pdata;
1074 +extern struct msm_bus_fabric_registration msm_bus_8974_ocmem_vnoc_pdata;
1075 +
1076 +extern struct msm_bus_fabric_registration msm_bus_9625_sys_noc_pdata;
1077 +extern struct msm_bus_fabric_registration msm_bus_9625_bimc_pdata;
1078 +extern struct msm_bus_fabric_registration msm_bus_9625_periph_noc_pdata;
1079 +extern struct msm_bus_fabric_registration msm_bus_9625_config_noc_pdata;
1080 +
1081 +extern int msm_bus_device_match_adhoc(struct device *dev, void *id);
1082 +
1083 +void msm_bus_rpm_set_mt_mask(void);
1084 +int msm_bus_board_rpm_get_il_ids(uint16_t *id);
1085 +int msm_bus_board_get_iid(int id);
1086 +
1087 +#define NFAB_MSM8226 6
1088 +#define NFAB_MSM8610 5
1089 +
1090 +/*
1091 + * These macros specify the convention followed for allocating
1092 + * ids to fabrics, masters and slaves for 8x60.
1093 + *
1094 + * A node can be identified as a master/slave/fabric by using
1095 + * these ids.
1096 + */
1097 +#define FABRIC_ID_KEY 1024
1098 +#define SLAVE_ID_KEY ((FABRIC_ID_KEY) >> 1)
1099 +#define MAX_FAB_KEY 7168 /* OR(All fabric ids) */
1100 +#define INT_NODE_START 10000
1101 +
1102 +#define GET_FABID(id) ((id) & MAX_FAB_KEY)
1103 +
1104 +#define NODE_ID(id) ((id) & (FABRIC_ID_KEY - 1))
1105 +#define IS_SLAVE(id) ((NODE_ID(id)) >= SLAVE_ID_KEY ? 1 : 0)
1106 +#define CHECK_ID(iid, id) (((iid & id) != id) ? -ENXIO : iid)
1107 +
1108 +/*
1109 + * The following macros are used to format the data for port halt
1110 + * and unhalt requests.
1111 + */
1112 +#define MSM_BUS_CLK_HALT 0x1
1113 +#define MSM_BUS_CLK_HALT_MASK 0x1
1114 +#define MSM_BUS_CLK_HALT_FIELDSIZE 0x1
1115 +#define MSM_BUS_CLK_UNHALT 0x0
1116 +
1117 +#define MSM_BUS_MASTER_SHIFT(master, fieldsize) \
1118 + ((master) * (fieldsize))
1119 +
1120 +#define MSM_BUS_SET_BITFIELD(word, fieldmask, fieldvalue) \
1121 + { \
1122 + (word) &= ~(fieldmask); \
1123 + (word) |= (fieldvalue); \
1124 + }
1125 +
1126 +
1127 +#define MSM_BUS_MASTER_HALT(u32haltmask, u32haltval, master) \
1128 + MSM_BUS_SET_BITFIELD(u32haltmask, \
1129 + MSM_BUS_CLK_HALT_MASK<<MSM_BUS_MASTER_SHIFT((master),\
1130 + MSM_BUS_CLK_HALT_FIELDSIZE), \
1131 + MSM_BUS_CLK_HALT_MASK<<MSM_BUS_MASTER_SHIFT((master),\
1132 + MSM_BUS_CLK_HALT_FIELDSIZE))\
1133 + MSM_BUS_SET_BITFIELD(u32haltval, \
1134 + MSM_BUS_CLK_HALT_MASK<<MSM_BUS_MASTER_SHIFT((master),\
1135 + MSM_BUS_CLK_HALT_FIELDSIZE), \
1136 + MSM_BUS_CLK_HALT<<MSM_BUS_MASTER_SHIFT((master),\
1137 + MSM_BUS_CLK_HALT_FIELDSIZE))\
1138 +
1139 +#define MSM_BUS_MASTER_UNHALT(u32haltmask, u32haltval, master) \
1140 + MSM_BUS_SET_BITFIELD(u32haltmask, \
1141 + MSM_BUS_CLK_HALT_MASK<<MSM_BUS_MASTER_SHIFT((master),\
1142 + MSM_BUS_CLK_HALT_FIELDSIZE), \
1143 + MSM_BUS_CLK_HALT_MASK<<MSM_BUS_MASTER_SHIFT((master),\
1144 + MSM_BUS_CLK_HALT_FIELDSIZE))\
1145 + MSM_BUS_SET_BITFIELD(u32haltval, \
1146 + MSM_BUS_CLK_HALT_MASK<<MSM_BUS_MASTER_SHIFT((master),\
1147 + MSM_BUS_CLK_HALT_FIELDSIZE), \
1148 + MSM_BUS_CLK_UNHALT<<MSM_BUS_MASTER_SHIFT((master),\
1149 + MSM_BUS_CLK_HALT_FIELDSIZE))\
1150 +
1151 +#define RPM_BUS_SLAVE_REQ 0x766c7362
1152 +#define RPM_BUS_MASTER_REQ 0x73616d62
1153 +
1154 +enum msm_bus_rpm_slave_field_type {
1155 + RPM_SLAVE_FIELD_BW = 0x00007762,
1156 +};
1157 +
1158 +enum msm_bus_rpm_mas_field_type {
1159 + RPM_MASTER_FIELD_BW = 0x00007762,
1160 + RPM_MASTER_FIELD_BW_T0 = 0x30747762,
1161 + RPM_MASTER_FIELD_BW_T1 = 0x31747762,
1162 + RPM_MASTER_FIELD_BW_T2 = 0x32747762,
1163 +};
1164 +
1165 +#include <dt-bindings/msm/msm-bus-ids.h>
1166 +
1167 +
1168 +#endif /*__ASM_ARCH_MSM_BUS_BOARD_H */
1169 --- /dev/null
1170 +++ b/drivers/bus/msm_bus/msm-bus.h
1171 @@ -0,0 +1,139 @@
1172 +/* Copyright (c) 2010-2014, The Linux Foundation. All rights reserved.
1173 + *
1174 + * This program is free software; you can redistribute it and/or modify
1175 + * it under the terms of the GNU General Public License version 2 and
1176 + * only version 2 as published by the Free Software Foundation.
1177 + *
1178 + * This program is distributed in the hope that it will be useful,
1179 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1180 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1181 + * GNU General Public License for more details.
1182 + */
1183 +
1184 +#ifndef _ARCH_ARM_MACH_MSM_BUS_H
1185 +#define _ARCH_ARM_MACH_MSM_BUS_H
1186 +
1187 +#include <linux/types.h>
1188 +#include <linux/input.h>
1189 +#include <linux/platform_device.h>
1190 +
1191 +/*
1192 + * Macros for clients to convert their data to ib and ab
1193 + * Ws : Time window over which to transfer the data in SECONDS
1194 + * Bs : Size of the data block in bytes
1195 + * Per : Recurrence period
1196 + * Tb : Throughput bandwidth to prevent stalling
1197 + * R : Ratio of actual bandwidth used to Tb
1198 + * Ib : Instantaneous bandwidth
1199 + * Ab : Arbitrated bandwidth
1200 + *
1201 + * IB_RECURRBLOCK and AB_RECURRBLOCK:
1202 + * These are used if the requirement is to transfer a
1203 + * recurring block of data over a known time window.
1204 + *
1205 + * IB_THROUGHPUTBW and AB_THROUGHPUTBW:
1206 + * These are used for CPU style masters. Here the requirement
1207 + * is to have minimum throughput bandwidth available to avoid
1208 + * stalling.
1209 + */
1210 +#define IB_RECURRBLOCK(Ws, Bs) ((Ws) == 0 ? 0 : ((Bs)/(Ws)))
1211 +#define AB_RECURRBLOCK(Ws, Per) ((Ws) == 0 ? 0 : ((Bs)/(Per)))
1212 +#define IB_THROUGHPUTBW(Tb) (Tb)
1213 +#define AB_THROUGHPUTBW(Tb, R) ((Tb) * (R))
1214 +
1215 +struct msm_bus_vectors {
1216 + int src; /* Master */
1217 + int dst; /* Slave */
1218 + uint64_t ab; /* Arbitrated bandwidth */
1219 + uint64_t ib; /* Instantaneous bandwidth */
1220 +};
1221 +
1222 +struct msm_bus_paths {
1223 + int num_paths;
1224 + struct msm_bus_vectors *vectors;
1225 +};
1226 +
1227 +struct msm_bus_scale_pdata {
1228 + struct msm_bus_paths *usecase;
1229 + int num_usecases;
1230 + const char *name;
1231 + /*
1232 + * If the active_only flag is set to 1, the BW request is applied
1233 + * only when at least one CPU is active (powered on). If the flag
1234 + * is set to 0, then the BW request is always applied irrespective
1235 + * of the CPU state.
1236 + */
1237 + unsigned int active_only;
1238 +};
1239 +
1240 +/* Scaling APIs */
1241 +
1242 +/*
1243 + * This function returns a handle to the client. This should be used to
1244 + * call msm_bus_scale_client_update_request.
1245 + * The function returns 0 if bus driver is unable to register a client
1246 + */
1247 +
1248 +#if (defined(CONFIG_MSM_BUS_SCALING) || defined(CONFIG_BUS_TOPOLOGY_ADHOC))
1249 +int __init msm_bus_fabric_init_driver(void);
1250 +uint32_t msm_bus_scale_register_client(struct msm_bus_scale_pdata *pdata);
1251 +int msm_bus_scale_client_update_request(uint32_t cl, unsigned int index);
1252 +void msm_bus_scale_unregister_client(uint32_t cl);
1253 +/* AXI Port configuration APIs */
1254 +int msm_bus_axi_porthalt(int master_port);
1255 +int msm_bus_axi_portunhalt(int master_port);
1256 +
1257 +#else
1258 +static inline int __init msm_bus_fabric_init_driver(void) { return 0; }
1259 +
1260 +static inline uint32_t
1261 +msm_bus_scale_register_client(struct msm_bus_scale_pdata *pdata)
1262 +{
1263 + return 1;
1264 +}
1265 +
1266 +static inline int
1267 +msm_bus_scale_client_update_request(uint32_t cl, unsigned int index)
1268 +{
1269 + return 0;
1270 +}
1271 +
1272 +static inline void
1273 +msm_bus_scale_unregister_client(uint32_t cl)
1274 +{
1275 +}
1276 +
1277 +static inline int msm_bus_axi_porthalt(int master_port)
1278 +{
1279 + return 0;
1280 +}
1281 +
1282 +static inline int msm_bus_axi_portunhalt(int master_port)
1283 +{
1284 + return 0;
1285 +}
1286 +#endif
1287 +
1288 +#if defined(CONFIG_OF) && defined(CONFIG_MSM_BUS_SCALING)
1289 +struct msm_bus_scale_pdata *msm_bus_pdata_from_node(
1290 + struct platform_device *pdev, struct device_node *of_node);
1291 +struct msm_bus_scale_pdata *msm_bus_cl_get_pdata(struct platform_device *pdev);
1292 +void msm_bus_cl_clear_pdata(struct msm_bus_scale_pdata *pdata);
1293 +#else
1294 +static inline struct msm_bus_scale_pdata
1295 +*msm_bus_cl_get_pdata(struct platform_device *pdev)
1296 +{
1297 + return NULL;
1298 +}
1299 +
1300 +static inline struct msm_bus_scale_pdata *msm_bus_pdata_from_node(
1301 + struct platform_device *pdev, struct device_node *of_node)
1302 +{
1303 + return NULL;
1304 +}
1305 +
1306 +static inline void msm_bus_cl_clear_pdata(struct msm_bus_scale_pdata *pdata)
1307 +{
1308 +}
1309 +#endif
1310 +#endif /*_ARCH_ARM_MACH_MSM_BUS_H*/
1311 --- /dev/null
1312 +++ b/drivers/bus/msm_bus/msm_bus_adhoc.h
1313 @@ -0,0 +1,141 @@
1314 +/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
1315 + *
1316 + * This program is free software; you can redistribute it and/or modify
1317 + * it under the terms of the GNU General Public License version 2 and
1318 + * only version 2 as published by the Free Software Foundation.
1319 + *
1320 + * This program is distributed in the hope that it will be useful,
1321 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1322 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1323 + * GNU General Public License for more details.
1324 + */
1325 +
1326 +#ifndef _ARCH_ARM_MACH_MSM_BUS_ADHOC_H
1327 +#define _ARCH_ARM_MACH_MSM_BUS_ADHOC_H
1328 +
1329 +#include <linux/types.h>
1330 +#include <linux/device.h>
1331 +#include "msm-bus-board.h"
1332 +#include "msm-bus.h"
1333 +#include "msm_bus_rules.h"
1334 +#include "msm_bus_core.h"
1335 +
1336 +struct msm_bus_node_device_type;
1337 +struct link_node {
1338 + uint64_t lnode_ib[NUM_CTX];
1339 + uint64_t lnode_ab[NUM_CTX];
1340 + int next;
1341 + struct device *next_dev;
1342 + struct list_head link;
1343 + uint32_t in_use;
1344 +};
1345 +
1346 +/* New types introduced for adhoc topology */
1347 +struct msm_bus_noc_ops {
1348 + int (*qos_init)(struct msm_bus_node_device_type *dev,
1349 + void __iomem *qos_base, uint32_t qos_off,
1350 + uint32_t qos_delta, uint32_t qos_freq);
1351 + int (*set_bw)(struct msm_bus_node_device_type *dev,
1352 + void __iomem *qos_base, uint32_t qos_off,
1353 + uint32_t qos_delta, uint32_t qos_freq);
1354 + int (*limit_mport)(struct msm_bus_node_device_type *dev,
1355 + void __iomem *qos_base, uint32_t qos_off,
1356 + uint32_t qos_delta, uint32_t qos_freq, bool enable_lim,
1357 + uint64_t lim_bw);
1358 + bool (*update_bw_reg)(int mode);
1359 +};
1360 +
1361 +struct nodebw {
1362 + uint64_t ab[NUM_CTX];
1363 + bool dirty;
1364 +};
1365 +
1366 +struct msm_bus_fab_device_type {
1367 + void __iomem *qos_base;
1368 + phys_addr_t pqos_base;
1369 + size_t qos_range;
1370 + uint32_t base_offset;
1371 + uint32_t qos_freq;
1372 + uint32_t qos_off;
1373 + uint32_t util_fact;
1374 + uint32_t vrail_comp;
1375 + struct msm_bus_noc_ops noc_ops;
1376 + enum msm_bus_hw_sel bus_type;
1377 + bool bypass_qos_prg;
1378 +};
1379 +
1380 +struct qos_params_type {
1381 + int mode;
1382 + unsigned int prio_lvl;
1383 + unsigned int prio_rd;
1384 + unsigned int prio_wr;
1385 + unsigned int prio1;
1386 + unsigned int prio0;
1387 + unsigned int gp;
1388 + unsigned int thmp;
1389 + unsigned int ws;
1390 + int cur_mode;
1391 + u64 bw_buffer;
1392 +};
1393 +
1394 +struct msm_bus_node_info_type {
1395 + const char *name;
1396 + unsigned int id;
1397 + int mas_rpm_id;
1398 + int slv_rpm_id;
1399 + int num_ports;
1400 + int num_qports;
1401 + int *qport;
1402 + struct qos_params_type qos_params;
1403 + unsigned int num_connections;
1404 + unsigned int num_blist;
1405 + bool is_fab_dev;
1406 + bool virt_dev;
1407 + bool is_traversed;
1408 + unsigned int *connections;
1409 + unsigned int *black_listed_connections;
1410 + struct device **dev_connections;
1411 + struct device **black_connections;
1412 + unsigned int bus_device_id;
1413 + struct device *bus_device;
1414 + unsigned int buswidth;
1415 + struct rule_update_path_info rule;
1416 + uint64_t lim_bw;
1417 + uint32_t util_fact;
1418 + uint32_t vrail_comp;
1419 +};
1420 +
1421 +struct msm_bus_node_device_type {
1422 + struct msm_bus_node_info_type *node_info;
1423 + struct msm_bus_fab_device_type *fabdev;
1424 + int num_lnodes;
1425 + struct link_node *lnode_list;
1426 + uint64_t cur_clk_hz[NUM_CTX];
1427 + struct nodebw node_ab;
1428 + struct list_head link;
1429 + unsigned int ap_owned;
1430 + struct nodeclk clk[NUM_CTX];
1431 + struct nodeclk qos_clk;
1432 +};
1433 +
1434 +int msm_bus_enable_limiter(struct msm_bus_node_device_type *nodedev,
1435 + bool throttle_en, uint64_t lim_bw);
1436 +int msm_bus_update_clks(struct msm_bus_node_device_type *nodedev,
1437 + int ctx, int **dirty_nodes, int *num_dirty);
1438 +int msm_bus_commit_data(int *dirty_nodes, int ctx, int num_dirty);
1439 +int msm_bus_update_bw(struct msm_bus_node_device_type *nodedev, int ctx,
1440 + int64_t add_bw, int **dirty_nodes, int *num_dirty);
1441 +void *msm_bus_realloc_devmem(struct device *dev, void *p, size_t old_size,
1442 + size_t new_size, gfp_t flags);
1443 +
1444 +extern struct msm_bus_device_node_registration
1445 + *msm_bus_of_to_pdata(struct platform_device *pdev);
1446 +extern void msm_bus_arb_setops_adhoc(struct msm_bus_arb_ops *arb_ops);
1447 +extern int msm_bus_bimc_set_ops(struct msm_bus_node_device_type *bus_dev);
1448 +extern int msm_bus_noc_set_ops(struct msm_bus_node_device_type *bus_dev);
1449 +extern int msm_bus_of_get_static_rules(struct platform_device *pdev,
1450 + struct bus_rule_type **static_rule);
1451 +extern int msm_rules_update_path(struct list_head *input_list,
1452 + struct list_head *output_list);
1453 +extern void print_all_rules(void);
1454 +#endif /* _ARCH_ARM_MACH_MSM_BUS_ADHOC_H */
1455 --- /dev/null
1456 +++ b/drivers/bus/msm_bus/msm_bus_arb_adhoc.c
1457 @@ -0,0 +1,998 @@
1458 +/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
1459 + *
1460 + * This program is Mree software; you can redistribute it and/or modify
1461 + * it under the terms of the GNU General Public License version 2 and
1462 + * only version 2 as published by the Free Software Foundation.
1463 + *
1464 + * This program is distributed in the hope that it will be useful,
1465 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1466 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1467 + * GNU General Public License for more details.
1468 + */
1469 +#include <linux/kernel.h>
1470 +#include <linux/init.h>
1471 +#include <linux/list.h>
1472 +#include <linux/module.h>
1473 +#include <linux/slab.h>
1474 +#include <linux/mutex.h>
1475 +#include <linux/clk.h>
1476 +#include "msm-bus.h"
1477 +#include "msm_bus_core.h"
1478 +#include "msm_bus_adhoc.h"
1479 +
1480 +#define NUM_CL_HANDLES 50
1481 +#define NUM_LNODES 3
1482 +
1483 +struct bus_search_type {
1484 + struct list_head link;
1485 + struct list_head node_list;
1486 +};
1487 +
1488 +struct handle_type {
1489 + int num_entries;
1490 + struct msm_bus_client **cl_list;
1491 +};
1492 +
1493 +static struct handle_type handle_list;
1494 +struct list_head input_list;
1495 +struct list_head apply_list;
1496 +
1497 +DEFINE_MUTEX(msm_bus_adhoc_lock);
1498 +
1499 +static bool chk_bl_list(struct list_head *black_list, unsigned int id)
1500 +{
1501 + struct msm_bus_node_device_type *bus_node = NULL;
1502 +
1503 + list_for_each_entry(bus_node, black_list, link) {
1504 + if (bus_node->node_info->id == id)
1505 + return true;
1506 + }
1507 + return false;
1508 +}
1509 +
1510 +static void copy_remaining_nodes(struct list_head *edge_list, struct list_head
1511 + *traverse_list, struct list_head *route_list)
1512 +{
1513 + struct bus_search_type *search_node;
1514 +
1515 + if (list_empty(edge_list) && list_empty(traverse_list))
1516 + return;
1517 +
1518 + search_node = kzalloc(sizeof(struct bus_search_type), GFP_KERNEL);
1519 + INIT_LIST_HEAD(&search_node->node_list);
1520 + list_splice_init(edge_list, traverse_list);
1521 + list_splice_init(traverse_list, &search_node->node_list);
1522 + list_add_tail(&search_node->link, route_list);
1523 +}
1524 +
1525 +/*
1526 + * Duplicate instantiaion from msm_bus_arb.c. Todo there needs to be a
1527 + * "util" file for these common func/macros.
1528 + *
1529 + * */
1530 +uint64_t msm_bus_div64(unsigned int w, uint64_t bw)
1531 +{
1532 + uint64_t *b = &bw;
1533 +
1534 + if ((bw > 0) && (bw < w))
1535 + return 1;
1536 +
1537 + switch (w) {
1538 + case 0:
1539 + WARN(1, "AXI: Divide by 0 attempted\n");
1540 + case 1: return bw;
1541 + case 2: return (bw >> 1);
1542 + case 4: return (bw >> 2);
1543 + case 8: return (bw >> 3);
1544 + case 16: return (bw >> 4);
1545 + case 32: return (bw >> 5);
1546 + }
1547 +
1548 + do_div(*b, w);
1549 + return *b;
1550 +}
1551 +
1552 +int msm_bus_device_match_adhoc(struct device *dev, void *id)
1553 +{
1554 + int ret = 0;
1555 + struct msm_bus_node_device_type *bnode = dev->platform_data;
1556 +
1557 + if (bnode)
1558 + ret = (bnode->node_info->id == *(unsigned int *)id);
1559 + else
1560 + ret = 0;
1561 +
1562 + return ret;
1563 +}
1564 +
1565 +static int gen_lnode(struct device *dev,
1566 + int next_hop, int prev_idx)
1567 +{
1568 + struct link_node *lnode;
1569 + struct msm_bus_node_device_type *cur_dev = NULL;
1570 + int lnode_idx = -1;
1571 +
1572 + if (!dev)
1573 + goto exit_gen_lnode;
1574 +
1575 + cur_dev = dev->platform_data;
1576 + if (!cur_dev) {
1577 + MSM_BUS_ERR("%s: Null device ptr", __func__);
1578 + goto exit_gen_lnode;
1579 + }
1580 +
1581 + if (!cur_dev->num_lnodes) {
1582 + cur_dev->lnode_list = devm_kzalloc(dev,
1583 + sizeof(struct link_node) * NUM_LNODES,
1584 + GFP_KERNEL);
1585 + if (!cur_dev->lnode_list)
1586 + goto exit_gen_lnode;
1587 +
1588 + lnode = cur_dev->lnode_list;
1589 + cur_dev->num_lnodes = NUM_LNODES;
1590 + lnode_idx = 0;
1591 + } else {
1592 + int i;
1593 + for (i = 0; i < cur_dev->num_lnodes; i++) {
1594 + if (!cur_dev->lnode_list[i].in_use)
1595 + break;
1596 + }
1597 +
1598 + if (i < cur_dev->num_lnodes) {
1599 + lnode = &cur_dev->lnode_list[i];
1600 + lnode_idx = i;
1601 + } else {
1602 + struct link_node *realloc_list;
1603 + size_t cur_size = sizeof(struct link_node) *
1604 + cur_dev->num_lnodes;
1605 +
1606 + cur_dev->num_lnodes += NUM_LNODES;
1607 + realloc_list = msm_bus_realloc_devmem(
1608 + dev,
1609 + cur_dev->lnode_list,
1610 + cur_size,
1611 + sizeof(struct link_node) *
1612 + cur_dev->num_lnodes, GFP_KERNEL);
1613 +
1614 + if (!realloc_list)
1615 + goto exit_gen_lnode;
1616 +
1617 + cur_dev->lnode_list = realloc_list;
1618 + lnode = &cur_dev->lnode_list[i];
1619 + lnode_idx = i;
1620 + }
1621 + }
1622 +
1623 + lnode->in_use = 1;
1624 + if (next_hop == cur_dev->node_info->id) {
1625 + lnode->next = -1;
1626 + lnode->next_dev = NULL;
1627 + } else {
1628 + lnode->next = prev_idx;
1629 + lnode->next_dev = bus_find_device(&msm_bus_type, NULL,
1630 + (void *) &next_hop,
1631 + msm_bus_device_match_adhoc);
1632 + }
1633 +
1634 + memset(lnode->lnode_ib, 0, sizeof(uint64_t) * NUM_CTX);
1635 + memset(lnode->lnode_ab, 0, sizeof(uint64_t) * NUM_CTX);
1636 +
1637 +exit_gen_lnode:
1638 + return lnode_idx;
1639 +}
1640 +
1641 +static int remove_lnode(struct msm_bus_node_device_type *cur_dev,
1642 + int lnode_idx)
1643 +{
1644 + int ret = 0;
1645 +
1646 + if (!cur_dev) {
1647 + MSM_BUS_ERR("%s: Null device ptr", __func__);
1648 + ret = -ENODEV;
1649 + goto exit_remove_lnode;
1650 + }
1651 +
1652 + if (lnode_idx != -1) {
1653 + if (!cur_dev->num_lnodes ||
1654 + (lnode_idx > (cur_dev->num_lnodes - 1))) {
1655 + MSM_BUS_ERR("%s: Invalid Idx %d, num_lnodes %d",
1656 + __func__, lnode_idx, cur_dev->num_lnodes);
1657 + ret = -ENODEV;
1658 + goto exit_remove_lnode;
1659 + }
1660 +
1661 + cur_dev->lnode_list[lnode_idx].next = -1;
1662 + cur_dev->lnode_list[lnode_idx].next_dev = NULL;
1663 + cur_dev->lnode_list[lnode_idx].in_use = 0;
1664 + }
1665 +
1666 +exit_remove_lnode:
1667 + return ret;
1668 +}
1669 +
1670 +static int prune_path(struct list_head *route_list, int dest, int src,
1671 + struct list_head *black_list, int found)
1672 +{
1673 + struct bus_search_type *search_node, *temp_search_node;
1674 + struct msm_bus_node_device_type *bus_node;
1675 + struct list_head *bl_list;
1676 + struct list_head *temp_bl_list;
1677 + int search_dev_id = dest;
1678 + struct device *dest_dev = bus_find_device(&msm_bus_type, NULL,
1679 + (void *) &dest,
1680 + msm_bus_device_match_adhoc);
1681 + int lnode_hop = -1;
1682 +
1683 + if (!found)
1684 + goto reset_links;
1685 +
1686 + if (!dest_dev) {
1687 + MSM_BUS_ERR("%s: Can't find dest dev %d", __func__, dest);
1688 + goto exit_prune_path;
1689 + }
1690 +
1691 + lnode_hop = gen_lnode(dest_dev, search_dev_id, lnode_hop);
1692 +
1693 + list_for_each_entry_reverse(search_node, route_list, link) {
1694 + list_for_each_entry(bus_node, &search_node->node_list, link) {
1695 + unsigned int i;
1696 + for (i = 0; i < bus_node->node_info->num_connections;
1697 + i++) {
1698 + if (bus_node->node_info->connections[i] ==
1699 + search_dev_id) {
1700 + dest_dev = bus_find_device(
1701 + &msm_bus_type,
1702 + NULL,
1703 + (void *)
1704 + &bus_node->node_info->
1705 + id,
1706 + msm_bus_device_match_adhoc);
1707 +
1708 + if (!dest_dev) {
1709 + lnode_hop = -1;
1710 + goto reset_links;
1711 + }
1712 +
1713 + lnode_hop = gen_lnode(dest_dev,
1714 + search_dev_id,
1715 + lnode_hop);
1716 + search_dev_id =
1717 + bus_node->node_info->id;
1718 + break;
1719 + }
1720 + }
1721 + }
1722 + }
1723 +reset_links:
1724 + list_for_each_entry_safe(search_node, temp_search_node, route_list,
1725 + link) {
1726 + list_for_each_entry(bus_node, &search_node->node_list,
1727 + link)
1728 + bus_node->node_info->is_traversed = false;
1729 +
1730 + list_del(&search_node->link);
1731 + kfree(search_node);
1732 + }
1733 +
1734 + list_for_each_safe(bl_list, temp_bl_list, black_list)
1735 + list_del(bl_list);
1736 +
1737 +exit_prune_path:
1738 + return lnode_hop;
1739 +}
1740 +
1741 +static void setup_bl_list(struct msm_bus_node_device_type *node,
1742 + struct list_head *black_list)
1743 +{
1744 + unsigned int i;
1745 +
1746 + for (i = 0; i < node->node_info->num_blist; i++) {
1747 + struct msm_bus_node_device_type *bdev;
1748 + bdev = node->node_info->black_connections[i]->platform_data;
1749 + list_add_tail(&bdev->link, black_list);
1750 + }
1751 +}
1752 +
1753 +static int getpath(int src, int dest)
1754 +{
1755 + struct list_head traverse_list;
1756 + struct list_head edge_list;
1757 + struct list_head route_list;
1758 + struct list_head black_list;
1759 + struct device *src_dev = bus_find_device(&msm_bus_type, NULL,
1760 + (void *) &src,
1761 + msm_bus_device_match_adhoc);
1762 + struct msm_bus_node_device_type *src_node;
1763 + struct bus_search_type *search_node;
1764 + int found = 0;
1765 + int depth_index = 0;
1766 + int first_hop = -1;
1767 +
1768 + INIT_LIST_HEAD(&traverse_list);
1769 + INIT_LIST_HEAD(&edge_list);
1770 + INIT_LIST_HEAD(&route_list);
1771 + INIT_LIST_HEAD(&black_list);
1772 +
1773 + if (!src_dev) {
1774 + MSM_BUS_ERR("%s: Cannot locate src dev %d", __func__, src);
1775 + goto exit_getpath;
1776 + }
1777 +
1778 + src_node = src_dev->platform_data;
1779 + if (!src_node) {
1780 + MSM_BUS_ERR("%s:Fatal, Source dev %d not found", __func__, src);
1781 + goto exit_getpath;
1782 + }
1783 + list_add_tail(&src_node->link, &traverse_list);
1784 +
1785 + while ((!found && !list_empty(&traverse_list))) {
1786 + struct msm_bus_node_device_type *bus_node = NULL;
1787 + /* Locate dest_id in the traverse list */
1788 + list_for_each_entry(bus_node, &traverse_list, link) {
1789 + if (bus_node->node_info->id == dest) {
1790 + found = 1;
1791 + break;
1792 + }
1793 + }
1794 +
1795 + if (!found) {
1796 + unsigned int i;
1797 + /* Setup the new edge list */
1798 + list_for_each_entry(bus_node, &traverse_list, link) {
1799 + /* Setup list of black-listed nodes */
1800 + setup_bl_list(bus_node, &black_list);
1801 +
1802 + for (i = 0; i < bus_node->node_info->
1803 + num_connections; i++) {
1804 + bool skip;
1805 + struct msm_bus_node_device_type
1806 + *node_conn;
1807 + node_conn = bus_node->node_info->
1808 + dev_connections[i]->
1809 + platform_data;
1810 + if (node_conn->node_info->
1811 + is_traversed) {
1812 + MSM_BUS_ERR("Circ Path %d\n",
1813 + node_conn->node_info->id);
1814 + goto reset_traversed;
1815 + }
1816 + skip = chk_bl_list(&black_list,
1817 + bus_node->node_info->
1818 + connections[i]);
1819 + if (!skip) {
1820 + list_add_tail(&node_conn->link,
1821 + &edge_list);
1822 + node_conn->node_info->
1823 + is_traversed = true;
1824 + }
1825 + }
1826 + }
1827 +
1828 + /* Keep tabs of the previous search list */
1829 + search_node = kzalloc(sizeof(struct bus_search_type),
1830 + GFP_KERNEL);
1831 + INIT_LIST_HEAD(&search_node->node_list);
1832 + list_splice_init(&traverse_list,
1833 + &search_node->node_list);
1834 + /* Add the previous search list to a route list */
1835 + list_add_tail(&search_node->link, &route_list);
1836 + /* Advancing the list depth */
1837 + depth_index++;
1838 + list_splice_init(&edge_list, &traverse_list);
1839 + }
1840 + }
1841 +reset_traversed:
1842 + copy_remaining_nodes(&edge_list, &traverse_list, &route_list);
1843 + first_hop = prune_path(&route_list, dest, src, &black_list, found);
1844 +
1845 +exit_getpath:
1846 + return first_hop;
1847 +}
1848 +
1849 +static uint64_t arbitrate_bus_req(struct msm_bus_node_device_type *bus_dev,
1850 + int ctx)
1851 +{
1852 + int i;
1853 + uint64_t max_ib = 0;
1854 + uint64_t sum_ab = 0;
1855 + uint64_t bw_max_hz;
1856 + struct msm_bus_node_device_type *fab_dev = NULL;
1857 + uint32_t util_fact = 0;
1858 + uint32_t vrail_comp = 0;
1859 +
1860 + /* Find max ib */
1861 + for (i = 0; i < bus_dev->num_lnodes; i++) {
1862 + max_ib = max(max_ib, bus_dev->lnode_list[i].lnode_ib[ctx]);
1863 + sum_ab += bus_dev->lnode_list[i].lnode_ab[ctx];
1864 + }
1865 + /*
1866 + * Account for Util factor and vrail comp. The new aggregation
1867 + * formula is:
1868 + * Freq_hz = max((sum(ab) * util_fact)/num_chan, max(ib)/vrail_comp)
1869 + * / bus-width
1870 + * util_fact and vrail comp are obtained from fabric/Node's dts
1871 + * properties.
1872 + * They default to 100 if absent.
1873 + */
1874 + fab_dev = bus_dev->node_info->bus_device->platform_data;
1875 + /* Don't do this for virtual fabrics */
1876 + if (fab_dev && fab_dev->fabdev) {
1877 + util_fact = bus_dev->node_info->util_fact ?
1878 + bus_dev->node_info->util_fact :
1879 + fab_dev->fabdev->util_fact;
1880 + vrail_comp = bus_dev->node_info->vrail_comp ?
1881 + bus_dev->node_info->vrail_comp :
1882 + fab_dev->fabdev->vrail_comp;
1883 + sum_ab *= util_fact;
1884 + sum_ab = msm_bus_div64(100, sum_ab);
1885 + max_ib *= 100;
1886 + max_ib = msm_bus_div64(vrail_comp, max_ib);
1887 + }
1888 +
1889 + /* Account for multiple channels if any */
1890 + if (bus_dev->node_info->num_qports > 1)
1891 + sum_ab = msm_bus_div64(bus_dev->node_info->num_qports,
1892 + sum_ab);
1893 +
1894 + if (!bus_dev->node_info->buswidth) {
1895 + MSM_BUS_WARN("No bus width found for %d. Using default\n",
1896 + bus_dev->node_info->id);
1897 + bus_dev->node_info->buswidth = 8;
1898 + }
1899 +
1900 + bw_max_hz = max(max_ib, sum_ab);
1901 + bw_max_hz = msm_bus_div64(bus_dev->node_info->buswidth,
1902 + bw_max_hz);
1903 +
1904 + return bw_max_hz;
1905 +}
1906 +
1907 +static void del_inp_list(struct list_head *list)
1908 +{
1909 + struct rule_update_path_info *rule_node;
1910 + struct rule_update_path_info *rule_node_tmp;
1911 +
1912 + list_for_each_entry_safe(rule_node, rule_node_tmp, list, link)
1913 + list_del(&rule_node->link);
1914 +}
1915 +
1916 +static void del_op_list(struct list_head *list)
1917 +{
1918 + struct rule_apply_rcm_info *rule;
1919 + struct rule_apply_rcm_info *rule_tmp;
1920 +
1921 + list_for_each_entry_safe(rule, rule_tmp, list, link)
1922 + list_del(&rule->link);
1923 +}
1924 +
1925 +static int msm_bus_apply_rules(struct list_head *list, bool after_clk_commit)
1926 +{
1927 + struct rule_apply_rcm_info *rule;
1928 + struct device *dev = NULL;
1929 + struct msm_bus_node_device_type *dev_info = NULL;
1930 + int ret = 0;
1931 + bool throttle_en = false;
1932 +
1933 + list_for_each_entry(rule, list, link) {
1934 + if (!rule)
1935 + break;
1936 +
1937 + if (rule && (rule->after_clk_commit != after_clk_commit))
1938 + continue;
1939 +
1940 + dev = bus_find_device(&msm_bus_type, NULL,
1941 + (void *) &rule->id,
1942 + msm_bus_device_match_adhoc);
1943 +
1944 + if (!dev) {
1945 + MSM_BUS_ERR("Can't find dev node for %d", rule->id);
1946 + continue;
1947 + }
1948 + dev_info = dev->platform_data;
1949 +
1950 + throttle_en = ((rule->throttle == THROTTLE_ON) ? true : false);
1951 + ret = msm_bus_enable_limiter(dev_info, throttle_en,
1952 + rule->lim_bw);
1953 + if (ret)
1954 + MSM_BUS_ERR("Failed to set limiter for %d", rule->id);
1955 + }
1956 +
1957 + return ret;
1958 +}
1959 +
1960 +static uint64_t get_node_aggab(struct msm_bus_node_device_type *bus_dev)
1961 +{
1962 + int i;
1963 + int ctx;
1964 + uint64_t max_agg_ab = 0;
1965 + uint64_t agg_ab = 0;
1966 +
1967 + for (ctx = 0; ctx < NUM_CTX; ctx++) {
1968 + for (i = 0; i < bus_dev->num_lnodes; i++)
1969 + agg_ab += bus_dev->lnode_list[i].lnode_ab[ctx];
1970 +
1971 + if (bus_dev->node_info->num_qports > 1)
1972 + agg_ab = msm_bus_div64(bus_dev->node_info->num_qports,
1973 + agg_ab);
1974 +
1975 + max_agg_ab = max(max_agg_ab, agg_ab);
1976 + }
1977 +
1978 + return max_agg_ab;
1979 +}
1980 +
1981 +static uint64_t get_node_ib(struct msm_bus_node_device_type *bus_dev)
1982 +{
1983 + int i;
1984 + int ctx;
1985 + uint64_t max_ib = 0;
1986 +
1987 + for (ctx = 0; ctx < NUM_CTX; ctx++) {
1988 + for (i = 0; i < bus_dev->num_lnodes; i++)
1989 + max_ib = max(max_ib,
1990 + bus_dev->lnode_list[i].lnode_ib[ctx]);
1991 + }
1992 + return max_ib;
1993 +}
1994 +
1995 +static int update_path(int src, int dest, uint64_t req_ib, uint64_t req_bw,
1996 + uint64_t cur_ib, uint64_t cur_bw, int src_idx, int ctx)
1997 +{
1998 + struct device *src_dev = NULL;
1999 + struct device *next_dev = NULL;
2000 + struct link_node *lnode = NULL;
2001 + struct msm_bus_node_device_type *dev_info = NULL;
2002 + int curr_idx;
2003 + int ret = 0;
2004 + int *dirty_nodes = NULL;
2005 + int num_dirty = 0;
2006 + struct rule_update_path_info *rule_node;
2007 + bool rules_registered = msm_rule_are_rules_registered();
2008 +
2009 + src_dev = bus_find_device(&msm_bus_type, NULL,
2010 + (void *) &src,
2011 + msm_bus_device_match_adhoc);
2012 +
2013 + if (!src_dev) {
2014 + MSM_BUS_ERR("%s: Can't find source device %d", __func__, src);
2015 + ret = -ENODEV;
2016 + goto exit_update_path;
2017 + }
2018 +
2019 + next_dev = src_dev;
2020 +
2021 + if (src_idx < 0) {
2022 + MSM_BUS_ERR("%s: Invalid lnode idx %d", __func__, src_idx);
2023 + ret = -ENXIO;
2024 + goto exit_update_path;
2025 + }
2026 + curr_idx = src_idx;
2027 +
2028 + INIT_LIST_HEAD(&input_list);
2029 + INIT_LIST_HEAD(&apply_list);
2030 +
2031 + while (next_dev) {
2032 + dev_info = next_dev->platform_data;
2033 +
2034 + if (curr_idx >= dev_info->num_lnodes) {
2035 + MSM_BUS_ERR("%s: Invalid lnode Idx %d num lnodes %d",
2036 + __func__, curr_idx, dev_info->num_lnodes);
2037 + ret = -ENXIO;
2038 + goto exit_update_path;
2039 + }
2040 +
2041 + lnode = &dev_info->lnode_list[curr_idx];
2042 + lnode->lnode_ib[ctx] = req_ib;
2043 + lnode->lnode_ab[ctx] = req_bw;
2044 +
2045 + dev_info->cur_clk_hz[ctx] = arbitrate_bus_req(dev_info, ctx);
2046 +
2047 + /* Start updating the clocks at the first hop.
2048 + * Its ok to figure out the aggregated
2049 + * request at this node.
2050 + */
2051 + if (src_dev != next_dev) {
2052 + ret = msm_bus_update_clks(dev_info, ctx, &dirty_nodes,
2053 + &num_dirty);
2054 + if (ret) {
2055 + MSM_BUS_ERR("%s: Failed to update clks dev %d",
2056 + __func__, dev_info->node_info->id);
2057 + goto exit_update_path;
2058 + }
2059 + }
2060 +
2061 + ret = msm_bus_update_bw(dev_info, ctx, req_bw, &dirty_nodes,
2062 + &num_dirty);
2063 + if (ret) {
2064 + MSM_BUS_ERR("%s: Failed to update bw dev %d",
2065 + __func__, dev_info->node_info->id);
2066 + goto exit_update_path;
2067 + }
2068 +
2069 + if (rules_registered) {
2070 + rule_node = &dev_info->node_info->rule;
2071 + rule_node->id = dev_info->node_info->id;
2072 + rule_node->ib = get_node_ib(dev_info);
2073 + rule_node->ab = get_node_aggab(dev_info);
2074 + rule_node->clk = max(dev_info->cur_clk_hz[ACTIVE_CTX],
2075 + dev_info->cur_clk_hz[DUAL_CTX]);
2076 + list_add_tail(&rule_node->link, &input_list);
2077 + }
2078 +
2079 + next_dev = lnode->next_dev;
2080 + curr_idx = lnode->next;
2081 + }
2082 +
2083 + if (rules_registered) {
2084 + msm_rules_update_path(&input_list, &apply_list);
2085 + msm_bus_apply_rules(&apply_list, false);
2086 + }
2087 +
2088 + msm_bus_commit_data(dirty_nodes, ctx, num_dirty);
2089 +
2090 + if (rules_registered) {
2091 + msm_bus_apply_rules(&apply_list, true);
2092 + del_inp_list(&input_list);
2093 + del_op_list(&apply_list);
2094 + }
2095 +exit_update_path:
2096 + return ret;
2097 +}
2098 +
2099 +static int remove_path(int src, int dst, uint64_t cur_ib, uint64_t cur_ab,
2100 + int src_idx, int active_only)
2101 +{
2102 + struct device *src_dev = NULL;
2103 + struct device *next_dev = NULL;
2104 + struct link_node *lnode = NULL;
2105 + struct msm_bus_node_device_type *dev_info = NULL;
2106 + int ret = 0;
2107 + int cur_idx = src_idx;
2108 + int next_idx;
2109 +
2110 + /* Update the current path to zero out all request from
2111 + * this cient on all paths
2112 + */
2113 +
2114 + ret = update_path(src, dst, 0, 0, cur_ib, cur_ab, src_idx,
2115 + active_only);
2116 + if (ret) {
2117 + MSM_BUS_ERR("%s: Error zeroing out path ctx %d",
2118 + __func__, ACTIVE_CTX);
2119 + goto exit_remove_path;
2120 + }
2121 +
2122 + src_dev = bus_find_device(&msm_bus_type, NULL,
2123 + (void *) &src,
2124 + msm_bus_device_match_adhoc);
2125 + if (!src_dev) {
2126 + MSM_BUS_ERR("%s: Can't find source device %d", __func__, src);
2127 + ret = -ENODEV;
2128 + goto exit_remove_path;
2129 + }
2130 +
2131 + next_dev = src_dev;
2132 +
2133 + while (next_dev) {
2134 + dev_info = next_dev->platform_data;
2135 + lnode = &dev_info->lnode_list[cur_idx];
2136 + next_idx = lnode->next;
2137 + next_dev = lnode->next_dev;
2138 + remove_lnode(dev_info, cur_idx);
2139 + cur_idx = next_idx;
2140 + }
2141 +
2142 +exit_remove_path:
2143 + return ret;
2144 +}
2145 +
2146 +static void getpath_debug(int src, int curr, int active_only)
2147 +{
2148 + struct device *dev_node;
2149 + struct device *dev_it;
2150 + unsigned int hop = 1;
2151 + int idx;
2152 + struct msm_bus_node_device_type *devinfo;
2153 + int i;
2154 +
2155 + dev_node = bus_find_device(&msm_bus_type, NULL,
2156 + (void *) &src,
2157 + msm_bus_device_match_adhoc);
2158 +
2159 + if (!dev_node) {
2160 + MSM_BUS_ERR("SRC NOT FOUND %d", src);
2161 + return;
2162 + }
2163 +
2164 + idx = curr;
2165 + devinfo = dev_node->platform_data;
2166 + dev_it = dev_node;
2167 +
2168 + MSM_BUS_ERR("Route list Src %d", src);
2169 + while (dev_it) {
2170 + struct msm_bus_node_device_type *busdev =
2171 + devinfo->node_info->bus_device->platform_data;
2172 +
2173 + MSM_BUS_ERR("Hop[%d] at Device %d ctx %d", hop,
2174 + devinfo->node_info->id, active_only);
2175 +
2176 + for (i = 0; i < NUM_CTX; i++) {
2177 + MSM_BUS_ERR("dev info sel ib %llu",
2178 + devinfo->cur_clk_hz[i]);
2179 + MSM_BUS_ERR("dev info sel ab %llu",
2180 + devinfo->node_ab.ab[i]);
2181 + }
2182 +
2183 + dev_it = devinfo->lnode_list[idx].next_dev;
2184 + idx = devinfo->lnode_list[idx].next;
2185 + if (dev_it)
2186 + devinfo = dev_it->platform_data;
2187 +
2188 + MSM_BUS_ERR("Bus Device %d", busdev->node_info->id);
2189 + MSM_BUS_ERR("Bus Clock %llu", busdev->clk[active_only].rate);
2190 +
2191 + if (idx < 0)
2192 + break;
2193 + hop++;
2194 + }
2195 +}
2196 +
2197 +static void unregister_client_adhoc(uint32_t cl)
2198 +{
2199 + int i;
2200 + struct msm_bus_scale_pdata *pdata;
2201 + int lnode, src, curr, dest;
2202 + uint64_t cur_clk, cur_bw;
2203 + struct msm_bus_client *client;
2204 +
2205 + mutex_lock(&msm_bus_adhoc_lock);
2206 + if (!cl) {
2207 + MSM_BUS_ERR("%s: Null cl handle passed unregister\n",
2208 + __func__);
2209 + goto exit_unregister_client;
2210 + }
2211 + client = handle_list.cl_list[cl];
2212 + pdata = client->pdata;
2213 + if (!pdata) {
2214 + MSM_BUS_ERR("%s: Null pdata passed to unregister\n",
2215 + __func__);
2216 + goto exit_unregister_client;
2217 + }
2218 +
2219 + curr = client->curr;
2220 + if (curr >= pdata->num_usecases) {
2221 + MSM_BUS_ERR("Invalid index Defaulting curr to 0");
2222 + curr = 0;
2223 + }
2224 +
2225 + MSM_BUS_DBG("%s: Unregistering client %p", __func__, client);
2226 +
2227 + for (i = 0; i < pdata->usecase->num_paths; i++) {
2228 + src = client->pdata->usecase[curr].vectors[i].src;
2229 + dest = client->pdata->usecase[curr].vectors[i].dst;
2230 +
2231 + lnode = client->src_pnode[i];
2232 + cur_clk = client->pdata->usecase[curr].vectors[i].ib;
2233 + cur_bw = client->pdata->usecase[curr].vectors[i].ab;
2234 + remove_path(src, dest, cur_clk, cur_bw, lnode,
2235 + pdata->active_only);
2236 + }
2237 + msm_bus_dbg_client_data(client->pdata, MSM_BUS_DBG_UNREGISTER, cl);
2238 + kfree(client->src_pnode);
2239 + kfree(client);
2240 + handle_list.cl_list[cl] = NULL;
2241 +exit_unregister_client:
2242 + mutex_unlock(&msm_bus_adhoc_lock);
2243 + return;
2244 +}
2245 +
2246 +static int alloc_handle_lst(int size)
2247 +{
2248 + int ret = 0;
2249 + struct msm_bus_client **t_cl_list;
2250 +
2251 + if (!handle_list.num_entries) {
2252 + t_cl_list = kzalloc(sizeof(struct msm_bus_client *)
2253 + * NUM_CL_HANDLES, GFP_KERNEL);
2254 + if (ZERO_OR_NULL_PTR(t_cl_list)) {
2255 + ret = -ENOMEM;
2256 + MSM_BUS_ERR("%s: Failed to allocate handles list",
2257 + __func__);
2258 + goto exit_alloc_handle_lst;
2259 + }
2260 + handle_list.cl_list = t_cl_list;
2261 + handle_list.num_entries += NUM_CL_HANDLES;
2262 + } else {
2263 + t_cl_list = krealloc(handle_list.cl_list,
2264 + sizeof(struct msm_bus_client *) *
2265 + handle_list.num_entries + NUM_CL_HANDLES,
2266 + GFP_KERNEL);
2267 + if (ZERO_OR_NULL_PTR(t_cl_list)) {
2268 + ret = -ENOMEM;
2269 + MSM_BUS_ERR("%s: Failed to allocate handles list",
2270 + __func__);
2271 + goto exit_alloc_handle_lst;
2272 + }
2273 +
2274 + memset(&handle_list.cl_list[handle_list.num_entries], 0,
2275 + NUM_CL_HANDLES * sizeof(struct msm_bus_client *));
2276 + handle_list.num_entries += NUM_CL_HANDLES;
2277 + handle_list.cl_list = t_cl_list;
2278 + }
2279 +exit_alloc_handle_lst:
2280 + return ret;
2281 +}
2282 +
2283 +static uint32_t gen_handle(struct msm_bus_client *client)
2284 +{
2285 + uint32_t handle = 0;
2286 + int i;
2287 + int ret = 0;
2288 +
2289 + for (i = 0; i < handle_list.num_entries; i++) {
2290 + if (i && !handle_list.cl_list[i]) {
2291 + handle = i;
2292 + break;
2293 + }
2294 + }
2295 +
2296 + if (!handle) {
2297 + ret = alloc_handle_lst(NUM_CL_HANDLES);
2298 +
2299 + if (ret) {
2300 + MSM_BUS_ERR("%s: Failed to allocate handle list",
2301 + __func__);
2302 + goto exit_gen_handle;
2303 + }
2304 + handle = i + 1;
2305 + }
2306 + handle_list.cl_list[handle] = client;
2307 +exit_gen_handle:
2308 + return handle;
2309 +}
2310 +
2311 +static uint32_t register_client_adhoc(struct msm_bus_scale_pdata *pdata)
2312 +{
2313 + int src, dest;
2314 + int i;
2315 + struct msm_bus_client *client = NULL;
2316 + int *lnode;
2317 + uint32_t handle = 0;
2318 +
2319 + mutex_lock(&msm_bus_adhoc_lock);
2320 + client = kzalloc(sizeof(struct msm_bus_client), GFP_KERNEL);
2321 + if (!client) {
2322 + MSM_BUS_ERR("%s: Error allocating client data", __func__);
2323 + goto exit_register_client;
2324 + }
2325 + client->pdata = pdata;
2326 +
2327 + lnode = kzalloc(pdata->usecase->num_paths * sizeof(int), GFP_KERNEL);
2328 + if (ZERO_OR_NULL_PTR(lnode)) {
2329 + MSM_BUS_ERR("%s: Error allocating pathnode ptr!", __func__);
2330 + goto exit_register_client;
2331 + }
2332 + client->src_pnode = lnode;
2333 +
2334 + for (i = 0; i < pdata->usecase->num_paths; i++) {
2335 + src = pdata->usecase->vectors[i].src;
2336 + dest = pdata->usecase->vectors[i].dst;
2337 +
2338 + if ((src < 0) || (dest < 0)) {
2339 + MSM_BUS_ERR("%s:Invalid src/dst.src %d dest %d",
2340 + __func__, src, dest);
2341 + goto exit_register_client;
2342 + }
2343 +
2344 + lnode[i] = getpath(src, dest);
2345 + if (lnode[i] < 0) {
2346 + MSM_BUS_ERR("%s:Failed to find path.src %d dest %d",
2347 + __func__, src, dest);
2348 + goto exit_register_client;
2349 + }
2350 + }
2351 +
2352 + handle = gen_handle(client);
2353 + msm_bus_dbg_client_data(client->pdata, MSM_BUS_DBG_REGISTER,
2354 + handle);
2355 + MSM_BUS_DBG("%s:Client handle %d %s", __func__, handle,
2356 + client->pdata->name);
2357 +exit_register_client:
2358 + mutex_unlock(&msm_bus_adhoc_lock);
2359 + return handle;
2360 +}
2361 +
2362 +static int update_request_adhoc(uint32_t cl, unsigned int index)
2363 +{
2364 + int i, ret = 0;
2365 + struct msm_bus_scale_pdata *pdata;
2366 + int lnode, src, curr, dest;
2367 + uint64_t req_clk, req_bw, curr_clk, curr_bw;
2368 + struct msm_bus_client *client;
2369 + const char *test_cl = "Null";
2370 + bool log_transaction = false;
2371 +
2372 + mutex_lock(&msm_bus_adhoc_lock);
2373 +
2374 + if (!cl) {
2375 + MSM_BUS_ERR("%s: Invalid client handle %d", __func__, cl);
2376 + ret = -ENXIO;
2377 + goto exit_update_request;
2378 + }
2379 +
2380 + client = handle_list.cl_list[cl];
2381 + pdata = client->pdata;
2382 + if (!pdata) {
2383 + MSM_BUS_ERR("%s: Client data Null.[client didn't register]",
2384 + __func__);
2385 + ret = -ENXIO;
2386 + goto exit_update_request;
2387 + }
2388 +
2389 + if (index >= pdata->num_usecases) {
2390 + MSM_BUS_ERR("Client %u passed invalid index: %d\n",
2391 + cl, index);
2392 + ret = -ENXIO;
2393 + goto exit_update_request;
2394 + }
2395 +
2396 + if (client->curr == index) {
2397 + MSM_BUS_DBG("%s: Not updating client request idx %d unchanged",
2398 + __func__, index);
2399 + goto exit_update_request;
2400 + }
2401 +
2402 + curr = client->curr;
2403 + client->curr = index;
2404 +
2405 + if (!strcmp(test_cl, pdata->name))
2406 + log_transaction = true;
2407 +
2408 + MSM_BUS_DBG("%s: cl: %u index: %d curr: %d num_paths: %d\n", __func__,
2409 + cl, index, client->curr, client->pdata->usecase->num_paths);
2410 +
2411 + for (i = 0; i < pdata->usecase->num_paths; i++) {
2412 + src = client->pdata->usecase[index].vectors[i].src;
2413 + dest = client->pdata->usecase[index].vectors[i].dst;
2414 +
2415 + lnode = client->src_pnode[i];
2416 + req_clk = client->pdata->usecase[index].vectors[i].ib;
2417 + req_bw = client->pdata->usecase[index].vectors[i].ab;
2418 + if (curr < 0) {
2419 + curr_clk = 0;
2420 + curr_bw = 0;
2421 + } else {
2422 + curr_clk = client->pdata->usecase[curr].vectors[i].ib;
2423 + curr_bw = client->pdata->usecase[curr].vectors[i].ab;
2424 + MSM_BUS_DBG("%s:ab: %llu ib: %llu\n", __func__,
2425 + curr_bw, curr_clk);
2426 + }
2427 +
2428 + ret = update_path(src, dest, req_clk, req_bw,
2429 + curr_clk, curr_bw, lnode, pdata->active_only);
2430 +
2431 + if (ret) {
2432 + MSM_BUS_ERR("%s: Update path failed! %d ctx %d\n",
2433 + __func__, ret, ACTIVE_CTX);
2434 + goto exit_update_request;
2435 + }
2436 +
2437 + if (log_transaction)
2438 + getpath_debug(src, lnode, pdata->active_only);
2439 + }
2440 + msm_bus_dbg_client_data(client->pdata, index , cl);
2441 +exit_update_request:
2442 + mutex_unlock(&msm_bus_adhoc_lock);
2443 + return ret;
2444 +}
2445 +
2446 +/**
2447 + * msm_bus_arb_setops_adhoc() : Setup the bus arbitration ops
2448 + * @ arb_ops: pointer to the arb ops.
2449 + */
2450 +void msm_bus_arb_setops_adhoc(struct msm_bus_arb_ops *arb_ops)
2451 +{
2452 + arb_ops->register_client = register_client_adhoc;
2453 + arb_ops->update_request = update_request_adhoc;
2454 + arb_ops->unregister_client = unregister_client_adhoc;
2455 +}
2456 --- /dev/null
2457 +++ b/drivers/bus/msm_bus/msm_bus_bimc.c
2458 @@ -0,0 +1,2112 @@
2459 +/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
2460 + *
2461 + * This program is free software; you can redistribute it and/or modify
2462 + * it under the terms of the GNU General Public License version 2 and
2463 + * only version 2 as published by the Free Software Foundation.
2464 + *
2465 + * This program is distributed in the hope that it will be useful,
2466 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
2467 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2468 + * GNU General Public License for more details.
2469 + */
2470 +
2471 +#define pr_fmt(fmt) "AXI: BIMC: %s(): " fmt, __func__
2472 +
2473 +#include <linux/slab.h>
2474 +#include <linux/io.h>
2475 +#include "msm-bus-board.h"
2476 +#include "msm_bus_core.h"
2477 +#include "msm_bus_bimc.h"
2478 +#include "msm_bus_adhoc.h"
2479 +#include <trace/events/trace_msm_bus.h>
2480 +
2481 +enum msm_bus_bimc_slave_block {
2482 + SLAVE_BLOCK_RESERVED = 0,
2483 + SLAVE_BLOCK_SLAVE_WAY,
2484 + SLAVE_BLOCK_XPU,
2485 + SLAVE_BLOCK_ARBITER,
2486 + SLAVE_BLOCK_SCMO,
2487 +};
2488 +
2489 +enum bke_sw {
2490 + BKE_OFF = 0,
2491 + BKE_ON = 1,
2492 +};
2493 +
2494 +/* M_Generic */
2495 +
2496 +#define M_REG_BASE(b) ((b) + 0x00008000)
2497 +
2498 +#define M_COMPONENT_INFO_ADDR(b, n) \
2499 + (M_REG_BASE(b) + (0x4000 * (n)) + 0x00000000)
2500 +enum bimc_m_component_info {
2501 + M_COMPONENT_INFO_RMSK = 0xffffff,
2502 + M_COMPONENT_INFO_INSTANCE_BMSK = 0xff0000,
2503 + M_COMPONENT_INFO_INSTANCE_SHFT = 0x10,
2504 + M_COMPONENT_INFO_SUB_TYPE_BMSK = 0xff00,
2505 + M_COMPONENT_INFO_SUB_TYPE_SHFT = 0x8,
2506 + M_COMPONENT_INFO_TYPE_BMSK = 0xff,
2507 + M_COMPONENT_INFO_TYPE_SHFT = 0x0,
2508 +};
2509 +
2510 +#define M_CONFIG_INFO_0_ADDR(b, n) \
2511 + (M_REG_BASE(b) + (0x4000 * (n)) + 0x00000020)
2512 +enum bimc_m_config_info_0 {
2513 + M_CONFIG_INFO_0_RMSK = 0xff00ffff,
2514 + M_CONFIG_INFO_0_SYNC_MODE_BMSK = 0xff000000,
2515 + M_CONFIG_INFO_0_SYNC_MODE_SHFT = 0x18,
2516 + M_CONFIG_INFO_0_CONNECTION_TYPE_BMSK = 0xff00,
2517 + M_CONFIG_INFO_0_CONNECTION_TYPE_SHFT = 0x8,
2518 + M_CONFIG_INFO_0_FUNC_BMSK = 0xff,
2519 + M_CONFIG_INFO_0_FUNC_SHFT = 0x0,
2520 +};
2521 +
2522 +#define M_CONFIG_INFO_1_ADDR(b, n) \
2523 + (M_REG_BASE(b) + (0x4000 * (n)) + 0x00000030)
2524 +enum bimc_m_config_info_1 {
2525 + M_CONFIG_INFO_1_RMSK = 0xffffffff,
2526 + M_CONFIG_INFO_1_SWAY_CONNECTIVITY_BMSK = 0xffffffff,
2527 + M_CONFIG_INFO_1_SWAY_CONNECTIVITY_SHFT = 0x0,
2528 +};
2529 +
2530 +#define M_CONFIG_INFO_2_ADDR(b, n) \
2531 + (M_REG_BASE(b) + (0x4000 * (n)) + 0x00000040)
2532 +enum bimc_m_config_info_2 {
2533 + M_CONFIG_INFO_2_RMSK = 0xffffffff,
2534 + M_CONFIG_INFO_2_M_DATA_WIDTH_BMSK = 0xffff0000,
2535 + M_CONFIG_INFO_2_M_DATA_WIDTH_SHFT = 0x10,
2536 + M_CONFIG_INFO_2_M_TID_WIDTH_BMSK = 0xff00,
2537 + M_CONFIG_INFO_2_M_TID_WIDTH_SHFT = 0x8,
2538 + M_CONFIG_INFO_2_M_MID_WIDTH_BMSK = 0xff,
2539 + M_CONFIG_INFO_2_M_MID_WIDTH_SHFT = 0x0,
2540 +};
2541 +
2542 +#define M_CONFIG_INFO_3_ADDR(b, n) \
2543 + (M_REG_BASE(b) + (0x4000 * (n)) + 0x00000050)
2544 +enum bimc_m_config_info_3 {
2545 + M_CONFIG_INFO_3_RMSK = 0xffffffff,
2546 + M_CONFIG_INFO_3_RCH_DEPTH_BMSK = 0xff000000,
2547 + M_CONFIG_INFO_3_RCH_DEPTH_SHFT = 0x18,
2548 + M_CONFIG_INFO_3_BCH_DEPTH_BMSK = 0xff0000,
2549 + M_CONFIG_INFO_3_BCH_DEPTH_SHFT = 0x10,
2550 + M_CONFIG_INFO_3_WCH_DEPTH_BMSK = 0xff00,
2551 + M_CONFIG_INFO_3_WCH_DEPTH_SHFT = 0x8,
2552 + M_CONFIG_INFO_3_ACH_DEPTH_BMSK = 0xff,
2553 + M_CONFIG_INFO_3_ACH_DEPTH_SHFT = 0x0,
2554 +};
2555 +
2556 +#define M_CONFIG_INFO_4_ADDR(b, n) \
2557 + (M_REG_BASE(b) + (0x4000 * (n)) + 0x00000060)
2558 +enum bimc_m_config_info_4 {
2559 + M_CONFIG_INFO_4_RMSK = 0xffff,
2560 + M_CONFIG_INFO_4_REORDER_BUF_DEPTH_BMSK = 0xff00,
2561 + M_CONFIG_INFO_4_REORDER_BUF_DEPTH_SHFT = 0x8,
2562 + M_CONFIG_INFO_4_REORDER_TABLE_DEPTH_BMSK = 0xff,
2563 + M_CONFIG_INFO_4_REORDER_TABLE_DEPTH_SHFT = 0x0,
2564 +};
2565 +
2566 +#define M_CONFIG_INFO_5_ADDR(b, n) \
2567 + (M_REG_BASE(b) + (0x4000 * (n)) + 0x00000070)
2568 +enum bimc_m_config_info_5 {
2569 + M_CONFIG_INFO_5_RMSK = 0x111,
2570 + M_CONFIG_INFO_5_MP2ARB_PIPELINE_EN_BMSK = 0x100,
2571 + M_CONFIG_INFO_5_MP2ARB_PIPELINE_EN_SHFT = 0x8,
2572 + M_CONFIG_INFO_5_MPBUF_PIPELINE_EN_BMSK = 0x10,
2573 + M_CONFIG_INFO_5_MPBUF_PIPELINE_EN_SHFT = 0x4,
2574 + M_CONFIG_INFO_5_M2MP_PIPELINE_EN_BMSK = 0x1,
2575 + M_CONFIG_INFO_5_M2MP_PIPELINE_EN_SHFT = 0x0,
2576 +};
2577 +
2578 +#define M_INT_STATUS_ADDR(b, n) \
2579 + (M_REG_BASE(b) + (0x4000 * (n)) + 0x00000100)
2580 +enum bimc_m_int_status {
2581 + M_INT_STATUS_RMSK = 0x3,
2582 +};
2583 +
2584 +#define M_INT_CLR_ADDR(b, n) \
2585 + (M_REG_BASE(b) + (0x4000 * (n)) + 0x00000108)
2586 +enum bimc_m_int_clr {
2587 + M_INT_CLR_RMSK = 0x3,
2588 +};
2589 +
2590 +#define M_INT_EN_ADDR(b, n) \
2591 + (M_REG_BASE(b) + (0x4000 * (n)) + 0x0000010c)
2592 +enum bimc_m_int_en {
2593 + M_INT_EN_RMSK = 0x3,
2594 +};
2595 +
2596 +#define M_CLK_CTRL_ADDR(b, n) \
2597 + (M_REG_BASE(b) + (0x4000 * (n)) + 0x00000200)
2598 +enum bimc_m_clk_ctrl {
2599 + M_CLK_CTRL_RMSK = 0x3,
2600 + M_CLK_CTRL_MAS_CLK_GATING_EN_BMSK = 0x2,
2601 + M_CLK_CTRL_MAS_CLK_GATING_EN_SHFT = 0x1,
2602 + M_CLK_CTRL_CORE_CLK_GATING_EN_BMSK = 0x1,
2603 + M_CLK_CTRL_CORE_CLK_GATING_EN_SHFT = 0x0,
2604 +};
2605 +
2606 +#define M_MODE_ADDR(b, n) \
2607 + (M_REG_BASE(b) + (0x4000 * (n)) + 0x00000210)
2608 +enum bimc_m_mode {
2609 + M_MODE_RMSK = 0xf0000011,
2610 + M_MODE_WR_GATHER_BEATS_BMSK = 0xf0000000,
2611 + M_MODE_WR_GATHER_BEATS_SHFT = 0x1c,
2612 + M_MODE_NARROW_WR_BMSK = 0x10,
2613 + M_MODE_NARROW_WR_SHFT = 0x4,
2614 + M_MODE_ORDERING_MODEL_BMSK = 0x1,
2615 + M_MODE_ORDERING_MODEL_SHFT = 0x0,
2616 +};
2617 +
2618 +#define M_PRIOLVL_OVERRIDE_ADDR(b, n) \
2619 + (M_REG_BASE(b) + (0x4000 * (n)) + 0x00000230)
2620 +enum bimc_m_priolvl_override {
2621 + M_PRIOLVL_OVERRIDE_RMSK = 0x301,
2622 + M_PRIOLVL_OVERRIDE_BMSK = 0x300,
2623 + M_PRIOLVL_OVERRIDE_SHFT = 0x8,
2624 + M_PRIOLVL_OVERRIDE_OVERRIDE_PRIOLVL_BMSK = 0x1,
2625 + M_PRIOLVL_OVERRIDE_OVERRIDE_PRIOLVL_SHFT = 0x0,
2626 +};
2627 +
2628 +#define M_RD_CMD_OVERRIDE_ADDR(b, n) \
2629 + (M_REG_BASE(b) + (0x4000 * (n)) + 0x00000240)
2630 +enum bimc_m_read_command_override {
2631 + M_RD_CMD_OVERRIDE_RMSK = 0x3071f7f,
2632 + M_RD_CMD_OVERRIDE_AREQPRIO_BMSK = 0x3000000,
2633 + M_RD_CMD_OVERRIDE_AREQPRIO_SHFT = 0x18,
2634 + M_RD_CMD_OVERRIDE_AMEMTYPE_BMSK = 0x70000,
2635 + M_RD_CMD_OVERRIDE_AMEMTYPE_SHFT = 0x10,
2636 + M_RD_CMD_OVERRIDE_ATRANSIENT_BMSK = 0x1000,
2637 + M_RD_CMD_OVERRIDE_ATRANSIENT_SHFT = 0xc,
2638 + M_RD_CMD_OVERRIDE_ASHARED_BMSK = 0x800,
2639 + M_RD_CMD_OVERRIDE_ASHARED_SHFT = 0xb,
2640 + M_RD_CMD_OVERRIDE_AREDIRECT_BMSK = 0x400,
2641 + M_RD_CMD_OVERRIDE_AREDIRECT_SHFT = 0xa,
2642 + M_RD_CMD_OVERRIDE_AOOO_BMSK = 0x200,
2643 + M_RD_CMD_OVERRIDE_AOOO_SHFT = 0x9,
2644 + M_RD_CMD_OVERRIDE_AINNERSHARED_BMSK = 0x100,
2645 + M_RD_CMD_OVERRIDE_AINNERSHARED_SHFT = 0x8,
2646 + M_RD_CMD_OVERRIDE_OVERRIDE_AREQPRIO_BMSK = 0x40,
2647 + M_RD_CMD_OVERRIDE_OVERRIDE_AREQPRIO_SHFT = 0x6,
2648 + M_RD_CMD_OVERRIDE_OVERRIDE_ATRANSIENT_BMSK = 0x20,
2649 + M_RD_CMD_OVERRIDE_OVERRIDE_ATRANSIENT_SHFT = 0x5,
2650 + M_RD_CMD_OVERRIDE_OVERRIDE_AMEMTYPE_BMSK = 0x10,
2651 + M_RD_CMD_OVERRIDE_OVERRIDE_AMEMTYPE_SHFT = 0x4,
2652 + M_RD_CMD_OVERRIDE_OVERRIDE_ASHARED_BMSK = 0x8,
2653 + M_RD_CMD_OVERRIDE_OVERRIDE_ASHARED_SHFT = 0x3,
2654 + M_RD_CMD_OVERRIDE_OVERRIDE_AREDIRECT_BMSK = 0x4,
2655 + M_RD_CMD_OVERRIDE_OVERRIDE_AREDIRECT_SHFT = 0x2,
2656 + M_RD_CMD_OVERRIDE_OVERRIDE_AOOO_BMSK = 0x2,
2657 + M_RD_CMD_OVERRIDE_OVERRIDE_AOOO_SHFT = 0x1,
2658 + M_RD_CMD_OVERRIDE_OVERRIDE_AINNERSHARED_BMSK = 0x1,
2659 + M_RD_CMD_OVERRIDE_OVERRIDE_AINNERSHARED_SHFT = 0x0,
2660 +};
2661 +
2662 +#define M_WR_CMD_OVERRIDE_ADDR(b, n) \
2663 + (M_REG_BASE(b) + (0x4000 * (n)) + 0x00000250)
2664 +enum bimc_m_write_command_override {
2665 + M_WR_CMD_OVERRIDE_RMSK = 0x3071f7f,
2666 + M_WR_CMD_OVERRIDE_AREQPRIO_BMSK = 0x3000000,
2667 + M_WR_CMD_OVERRIDE_AREQPRIO_SHFT = 0x18,
2668 + M_WR_CMD_OVERRIDE_AMEMTYPE_BMSK = 0x70000,
2669 + M_WR_CMD_OVERRIDE_AMEMTYPE_SHFT = 0x10,
2670 + M_WR_CMD_OVERRIDE_ATRANSIENT_BMSK = 0x1000,
2671 + M_WR_CMD_OVERRIDE_ATRANSIENT_SHFT = 0xc,
2672 + M_WR_CMD_OVERRIDE_ASHARED_BMSK = 0x800,
2673 + M_WR_CMD_OVERRIDE_ASHARED_SHFT = 0xb,
2674 + M_WR_CMD_OVERRIDE_AREDIRECT_BMSK = 0x400,
2675 + M_WR_CMD_OVERRIDE_AREDIRECT_SHFT = 0xa,
2676 + M_WR_CMD_OVERRIDE_AOOO_BMSK = 0x200,
2677 + M_WR_CMD_OVERRIDE_AOOO_SHFT = 0x9,
2678 + M_WR_CMD_OVERRIDE_AINNERSHARED_BMSK = 0x100,
2679 + M_WR_CMD_OVERRIDE_AINNERSHARED_SHFT = 0x8,
2680 + M_WR_CMD_OVERRIDE_OVERRIDE_AREQPRIO_BMSK = 0x40,
2681 + M_WR_CMD_OVERRIDE_OVERRIDE_AREQPRIO_SHFT = 0x6,
2682 + M_WR_CMD_OVERRIDE_OVERRIDE_ATRANSIENT_BMSK = 0x20,
2683 + M_WR_CMD_OVERRIDE_OVERRIDE_ATRANSIENT_SHFT = 0x5,
2684 + M_WR_CMD_OVERRIDE_OVERRIDE_AMEMTYPE_BMSK = 0x10,
2685 + M_WR_CMD_OVERRIDE_OVERRIDE_AMEMTYPE_SHFT = 0x4,
2686 + M_WR_CMD_OVERRIDE_OVERRIDE_ASHARED_BMSK = 0x8,
2687 + M_WR_CMD_OVERRIDE_OVERRIDE_ASHARED_SHFT = 0x3,
2688 + M_WR_CMD_OVERRIDE_OVERRIDE_AREDIRECT_BMSK = 0x4,
2689 + M_WR_CMD_OVERRIDE_OVERRIDE_AREDIRECT_SHFT = 0x2,
2690 + M_WR_CMD_OVERRIDE_OVERRIDE_AOOO_BMSK = 0x2,
2691 + M_WR_CMD_OVERRIDE_OVERRIDE_AOOO_SHFT = 0x1,
2692 + M_WR_CMD_OVERRIDE_OVERRIDE_AINNERSHARED_BMSK = 0x1,
2693 + M_WR_CMD_OVERRIDE_OVERRIDE_AINNERSHARED_SHFT = 0x0,
2694 +};
2695 +
2696 +#define M_BKE_EN_ADDR(b, n) \
2697 + (M_REG_BASE(b) + (0x4000 * (n)) + 0x00000300)
2698 +enum bimc_m_bke_en {
2699 + M_BKE_EN_RMSK = 0x1,
2700 + M_BKE_EN_EN_BMSK = 0x1,
2701 + M_BKE_EN_EN_SHFT = 0x0,
2702 +};
2703 +
2704 +/* Grant Period registers */
2705 +#define M_BKE_GP_ADDR(b, n) \
2706 + (M_REG_BASE(b) + (0x4000 * (n)) + 0x00000304)
2707 +enum bimc_m_bke_grant_period {
2708 + M_BKE_GP_RMSK = 0x3ff,
2709 + M_BKE_GP_GP_BMSK = 0x3ff,
2710 + M_BKE_GP_GP_SHFT = 0x0,
2711 +};
2712 +
2713 +/* Grant count register.
2714 + * The Grant count register represents a signed 16 bit
2715 + * value, range 0-0x7fff
2716 + */
2717 +#define M_BKE_GC_ADDR(b, n) \
2718 + (M_REG_BASE(b) + (0x4000 * (n)) + 0x00000308)
2719 +enum bimc_m_bke_grant_count {
2720 + M_BKE_GC_RMSK = 0xffff,
2721 + M_BKE_GC_GC_BMSK = 0xffff,
2722 + M_BKE_GC_GC_SHFT = 0x0,
2723 +};
2724 +
2725 +/* Threshold High Registers */
2726 +#define M_BKE_THH_ADDR(b, n) \
2727 + (M_REG_BASE(b) + (0x4000 * (n)) + 0x00000320)
2728 +enum bimc_m_bke_thresh_high {
2729 + M_BKE_THH_RMSK = 0xffff,
2730 + M_BKE_THH_THRESH_BMSK = 0xffff,
2731 + M_BKE_THH_THRESH_SHFT = 0x0,
2732 +};
2733 +
2734 +/* Threshold Medium Registers */
2735 +#define M_BKE_THM_ADDR(b, n) \
2736 + (M_REG_BASE(b) + (0x4000 * (n)) + 0x00000324)
2737 +enum bimc_m_bke_thresh_medium {
2738 + M_BKE_THM_RMSK = 0xffff,
2739 + M_BKE_THM_THRESH_BMSK = 0xffff,
2740 + M_BKE_THM_THRESH_SHFT = 0x0,
2741 +};
2742 +
2743 +/* Threshold Low Registers */
2744 +#define M_BKE_THL_ADDR(b, n) \
2745 + (M_REG_BASE(b) + (0x4000 * (n)) + 0x00000328)
2746 +enum bimc_m_bke_thresh_low {
2747 + M_BKE_THL_RMSK = 0xffff,
2748 + M_BKE_THL_THRESH_BMSK = 0xffff,
2749 + M_BKE_THL_THRESH_SHFT = 0x0,
2750 +};
2751 +
2752 +#define M_BKE_HEALTH_0_CONFIG_ADDR(b, n) \
2753 + (M_REG_BASE(b) + (0x4000 * (n)) + 0x00000340)
2754 +enum bimc_m_bke_health_0 {
2755 + M_BKE_HEALTH_0_CONFIG_RMSK = 0x80000303,
2756 + M_BKE_HEALTH_0_CONFIG_LIMIT_CMDS_BMSK = 0x80000000,
2757 + M_BKE_HEALTH_0_CONFIG_LIMIT_CMDS_SHFT = 0x1f,
2758 + M_BKE_HEALTH_0_CONFIG_AREQPRIO_BMSK = 0x300,
2759 + M_BKE_HEALTH_0_CONFIG_AREQPRIO_SHFT = 0x8,
2760 + M_BKE_HEALTH_0_CONFIG_PRIOLVL_BMSK = 0x3,
2761 + M_BKE_HEALTH_0_CONFIG_PRIOLVL_SHFT = 0x0,
2762 +};
2763 +
2764 +#define M_BKE_HEALTH_1_CONFIG_ADDR(b, n) \
2765 + (M_REG_BASE(b) + (0x4000 * (n)) + 0x00000344)
2766 +enum bimc_m_bke_health_1 {
2767 + M_BKE_HEALTH_1_CONFIG_RMSK = 0x80000303,
2768 + M_BKE_HEALTH_1_CONFIG_LIMIT_CMDS_BMSK = 0x80000000,
2769 + M_BKE_HEALTH_1_CONFIG_LIMIT_CMDS_SHFT = 0x1f,
2770 + M_BKE_HEALTH_1_CONFIG_AREQPRIO_BMSK = 0x300,
2771 + M_BKE_HEALTH_1_CONFIG_AREQPRIO_SHFT = 0x8,
2772 + M_BKE_HEALTH_1_CONFIG_PRIOLVL_BMSK = 0x3,
2773 + M_BKE_HEALTH_1_CONFIG_PRIOLVL_SHFT = 0x0,
2774 +};
2775 +
2776 +#define M_BKE_HEALTH_2_CONFIG_ADDR(b, n) \
2777 + (M_REG_BASE(b) + (0x4000 * (n)) + 0x00000348)
2778 +enum bimc_m_bke_health_2 {
2779 + M_BKE_HEALTH_2_CONFIG_RMSK = 0x80000303,
2780 + M_BKE_HEALTH_2_CONFIG_LIMIT_CMDS_BMSK = 0x80000000,
2781 + M_BKE_HEALTH_2_CONFIG_LIMIT_CMDS_SHFT = 0x1f,
2782 + M_BKE_HEALTH_2_CONFIG_AREQPRIO_BMSK = 0x300,
2783 + M_BKE_HEALTH_2_CONFIG_AREQPRIO_SHFT = 0x8,
2784 + M_BKE_HEALTH_2_CONFIG_PRIOLVL_BMSK = 0x3,
2785 + M_BKE_HEALTH_2_CONFIG_PRIOLVL_SHFT = 0x0,
2786 +};
2787 +
2788 +#define M_BKE_HEALTH_3_CONFIG_ADDR(b, n) \
2789 + (M_REG_BASE(b) + (0x4000 * (n)) + 0x0000034c)
2790 +enum bimc_m_bke_health_3 {
2791 + M_BKE_HEALTH_3_CONFIG_RMSK = 0x303,
2792 + M_BKE_HEALTH_3_CONFIG_AREQPRIO_BMSK = 0x300,
2793 + M_BKE_HEALTH_3_CONFIG_AREQPRIO_SHFT = 0x8,
2794 + M_BKE_HEALTH_3_CONFIG_PRIOLVL_BMSK = 0x3,
2795 + M_BKE_HEALTH_3_CONFIG_PRIOLVL_SHFT = 0x0,
2796 +};
2797 +
2798 +#define M_BUF_STATUS_ADDR(b, n) \
2799 + (M_REG_BASE(b) + (0x4000 * (n)) + 0x00000400)
2800 +enum bimc_m_buf_status {
2801 + M_BUF_STATUS_RMSK = 0xf03f030,
2802 + M_BUF_STATUS_RCH_DATA_WR_FULL_BMSK = 0x8000000,
2803 + M_BUF_STATUS_RCH_DATA_WR_FULL_SHFT = 0x1b,
2804 + M_BUF_STATUS_RCH_DATA_WR_EMPTY_BMSK = 0x4000000,
2805 + M_BUF_STATUS_RCH_DATA_WR_EMPTY_SHFT = 0x1a,
2806 + M_BUF_STATUS_RCH_CTRL_WR_FULL_BMSK = 0x2000000,
2807 + M_BUF_STATUS_RCH_CTRL_WR_FULL_SHFT = 0x19,
2808 + M_BUF_STATUS_RCH_CTRL_WR_EMPTY_BMSK = 0x1000000,
2809 + M_BUF_STATUS_RCH_CTRL_WR_EMPTY_SHFT = 0x18,
2810 + M_BUF_STATUS_BCH_WR_FULL_BMSK = 0x20000,
2811 + M_BUF_STATUS_BCH_WR_FULL_SHFT = 0x11,
2812 + M_BUF_STATUS_BCH_WR_EMPTY_BMSK = 0x10000,
2813 + M_BUF_STATUS_BCH_WR_EMPTY_SHFT = 0x10,
2814 + M_BUF_STATUS_WCH_DATA_RD_FULL_BMSK = 0x8000,
2815 + M_BUF_STATUS_WCH_DATA_RD_FULL_SHFT = 0xf,
2816 + M_BUF_STATUS_WCH_DATA_RD_EMPTY_BMSK = 0x4000,
2817 + M_BUF_STATUS_WCH_DATA_RD_EMPTY_SHFT = 0xe,
2818 + M_BUF_STATUS_WCH_CTRL_RD_FULL_BMSK = 0x2000,
2819 + M_BUF_STATUS_WCH_CTRL_RD_FULL_SHFT = 0xd,
2820 + M_BUF_STATUS_WCH_CTRL_RD_EMPTY_BMSK = 0x1000,
2821 + M_BUF_STATUS_WCH_CTRL_RD_EMPTY_SHFT = 0xc,
2822 + M_BUF_STATUS_ACH_RD_FULL_BMSK = 0x20,
2823 + M_BUF_STATUS_ACH_RD_FULL_SHFT = 0x5,
2824 + M_BUF_STATUS_ACH_RD_EMPTY_BMSK = 0x10,
2825 + M_BUF_STATUS_ACH_RD_EMPTY_SHFT = 0x4,
2826 +};
2827 +/*BIMC Generic */
2828 +
2829 +#define S_REG_BASE(b) ((b) + 0x00048000)
2830 +
2831 +#define S_COMPONENT_INFO_ADDR(b, n) \
2832 + (S_REG_BASE(b) + (0x8000 * (n)) + 0x00000000)
2833 +enum bimc_s_component_info {
2834 + S_COMPONENT_INFO_RMSK = 0xffffff,
2835 + S_COMPONENT_INFO_INSTANCE_BMSK = 0xff0000,
2836 + S_COMPONENT_INFO_INSTANCE_SHFT = 0x10,
2837 + S_COMPONENT_INFO_SUB_TYPE_BMSK = 0xff00,
2838 + S_COMPONENT_INFO_SUB_TYPE_SHFT = 0x8,
2839 + S_COMPONENT_INFO_TYPE_BMSK = 0xff,
2840 + S_COMPONENT_INFO_TYPE_SHFT = 0x0,
2841 +};
2842 +
2843 +#define S_HW_INFO_ADDR(b, n) \
2844 + (S_REG_BASE(b) + (0x80000 * (n)) + 0x00000010)
2845 +enum bimc_s_hw_info {
2846 + S_HW_INFO_RMSK = 0xffffffff,
2847 + S_HW_INFO_MAJOR_BMSK = 0xff000000,
2848 + S_HW_INFO_MAJOR_SHFT = 0x18,
2849 + S_HW_INFO_BRANCH_BMSK = 0xff0000,
2850 + S_HW_INFO_BRANCH_SHFT = 0x10,
2851 + S_HW_INFO_MINOR_BMSK = 0xff00,
2852 + S_HW_INFO_MINOR_SHFT = 0x8,
2853 + S_HW_INFO_ECO_BMSK = 0xff,
2854 + S_HW_INFO_ECO_SHFT = 0x0,
2855 +};
2856 +
2857 +
2858 +/* S_SCMO_GENERIC */
2859 +
2860 +#define S_SCMO_REG_BASE(b) ((b) + 0x00048000)
2861 +
2862 +#define S_SCMO_CONFIG_INFO_0_ADDR(b, n) \
2863 + (S_SCMO_REG_BASE(b) + (0x8000 * (n)) + 0x00000020)
2864 +enum bimc_s_scmo_config_info_0 {
2865 + S_SCMO_CONFIG_INFO_0_RMSK = 0xffffffff,
2866 + S_SCMO_CONFIG_INFO_0_DATA_WIDTH_BMSK = 0xffff0000,
2867 + S_SCMO_CONFIG_INFO_0_DATA_WIDTH_SHFT = 0x10,
2868 + S_SCMO_CONFIG_INFO_0_TID_WIDTH_BMSK = 0xff00,
2869 + S_SCMO_CONFIG_INFO_0_TID_WIDTH_SHFT = 0x8,
2870 + S_SCMO_CONFIG_INFO_0_MID_WIDTH_BMSK = 0xff,
2871 + S_SCMO_CONFIG_INFO_0_MID_WIDTH_SHFT = 0x0,
2872 +};
2873 +
2874 +#define S_SCMO_CONFIG_INFO_1_ADDR(b, n) \
2875 + (S_SCMO_REG_BASE(b) + (0x8000 * (n)) + 0x00000030)
2876 +enum bimc_s_scmo_config_info_1 {
2877 + S_SCMO_CONFIG_INFO_1_RMSK = 0xffffffff,
2878 + S_SCMO_CONFIG_INFO_1_MPORT_CONNECTIVITY_BMSK = 0xffffffff,
2879 + S_SCMO_CONFIG_INFO_1_MPORT_CONNECTIVITY_SHFT = 0x0,
2880 +};
2881 +
2882 +#define S_SCMO_CONFIG_INFO_2_ADDR(b, n) \
2883 + (S_SCMO_REG_BASE(b) + (0x8000 * (n)) + 0x00000040)
2884 +enum bimc_s_scmo_config_info_2 {
2885 + S_SCMO_CONFIG_INFO_2_RMSK = 0xff00ff,
2886 + S_SCMO_CONFIG_INFO_2_NUM_GLOBAL_MONS_BMSK = 0xff0000,
2887 + S_SCMO_CONFIG_INFO_2_NUM_GLOBAL_MONS_SHFT = 0x10,
2888 + S_SCMO_CONFIG_INFO_2_VMID_WIDTH_BMSK = 0xff,
2889 + S_SCMO_CONFIG_INFO_2_VMID_WIDTH_SHFT = 0x0,
2890 +};
2891 +
2892 +#define S_SCMO_CONFIG_INFO_3_ADDR(b, n) \
2893 + (S_SCMO_REG_BASE(b) + (0x8000 * (n)) + 0x00000050)
2894 +enum bimc_s_scmo_config_info_3 {
2895 + S_SCMO_CONFIG_INFO_3_RMSK = 0xffffffff,
2896 + S_SCMO_CONFIG_INFO_3_RCH0_CTRL_DEPTH_BMSK = 0xff000000,
2897 + S_SCMO_CONFIG_INFO_3_RCH0_CTRL_DEPTH_SHFT = 0x18,
2898 + S_SCMO_CONFIG_INFO_3_RCH0_DEPTH_BMSK = 0xff0000,
2899 + S_SCMO_CONFIG_INFO_3_RCH0_DEPTH_SHFT = 0x10,
2900 + S_SCMO_CONFIG_INFO_3_BCH_DEPTH_BMSK = 0xff00,
2901 + S_SCMO_CONFIG_INFO_3_BCH_DEPTH_SHFT = 0x8,
2902 + S_SCMO_CONFIG_INFO_3_WCH_DEPTH_BMSK = 0xff,
2903 + S_SCMO_CONFIG_INFO_3_WCH_DEPTH_SHFT = 0x0,
2904 +};
2905 +
2906 +#define S_SCMO_CONFIG_INFO_4_ADDR(b, n) \
2907 + (S_SCMO_REG_BASE(b) + (0x8000 * (n)) + 0x00000060)
2908 +enum bimc_s_scmo_config_info_4 {
2909 + S_SCMO_CONFIG_INFO_4_RMSK = 0xffff,
2910 + S_SCMO_CONFIG_INFO_4_RCH1_CTRL_DEPTH_BMSK = 0xff00,
2911 + S_SCMO_CONFIG_INFO_4_RCH1_CTRL_DEPTH_SHFT = 0x8,
2912 + S_SCMO_CONFIG_INFO_4_RCH1_DEPTH_BMSK = 0xff,
2913 + S_SCMO_CONFIG_INFO_4_RCH1_DEPTH_SHFT = 0x0,
2914 +};
2915 +
2916 +#define S_SCMO_CONFIG_INFO_5_ADDR(b, n) \
2917 + (S_SCMO_REG_BASE(b) + (0x8000 * (n)) + 0x00000070)
2918 +enum bimc_s_scmo_config_info_5 {
2919 + S_SCMO_CONFIG_INFO_5_RMSK = 0xffff,
2920 + S_SCMO_CONFIG_INFO_5_DPE_CQ_DEPTH_BMSK = 0xff00,
2921 + S_SCMO_CONFIG_INFO_5_DPE_CQ_DEPTH_SHFT = 0x8,
2922 + S_SCMO_CONFIG_INFO_5_DDR_BUS_WIDTH_BMSK = 0xff,
2923 + S_SCMO_CONFIG_INFO_5_DDR_BUS_WIDTH_SHFT = 0x0,
2924 +};
2925 +
2926 +#define S_SCMO_CONFIG_INFO_6_ADDR(b, n) \
2927 + (S_SCMO_REG_BASE(b) + (0x8000 * (n)) + 0x00000080)
2928 +enum bimc_s_scmo_config_info_6 {
2929 + S_SCMO_CONFIG_INFO_6_RMSK = 0x1111,
2930 + S_SCMO_CONFIG_INFO_6_WBUFC_PIPE_BMSK = 0x1000,
2931 + S_SCMO_CONFIG_INFO_6_WBUFC_PIPE_SHFT = 0xc,
2932 + S_SCMO_CONFIG_INFO_6_RDOPT_PIPE_BMSK = 0x100,
2933 + S_SCMO_CONFIG_INFO_6_RDOPT_PIPE_SHFT = 0x8,
2934 + S_SCMO_CONFIG_INFO_6_ACHAN_INTF_PIPE_BMSK = 0x10,
2935 + S_SCMO_CONFIG_INFO_6_ACHAN_INTF_PIPE_SHFT = 0x4,
2936 + S_SCMO_CONFIG_INFO_6_ADDR_DECODE_HT_BMSK = 0x1,
2937 + S_SCMO_CONFIG_INFO_6_ADDR_DECODE_HT_SHFT = 0x0,
2938 +};
2939 +
2940 +#define S_SCMO_INT_STATUS_ADDR(b, n) \
2941 + (S_SCMO_REG_BASE(b) + (0x8000 * (n)) + 0x00000100)
2942 +enum bimc_s_scmo_int_status {
2943 + S_SCMO_INT_STATUS_RMSK = 0x1,
2944 + S_SCMO_INT_STATUS_ERR_OCCURED_BMSK = 0x1,
2945 + S_SCMO_INT_STATUS_ERR_OCCURED_SHFT = 0x0,
2946 +};
2947 +
2948 +#define S_SCMO_INT_CLR_ADDR(b, n) \
2949 + (S_SCMO_REG_BASE(b) + (0x8000 * (n)) + 0x00000108)
2950 +enum bimc_s_scmo_int_clr {
2951 + S_SCMO_INT_CLR_RMSK = 0x1,
2952 + S_SCMO_INT_CLR_IRQ_CLR_BMSK = 0x1,
2953 + S_SCMO_INT_CLR_IRQ_CLR_SHFT = 0x0,
2954 +};
2955 +
2956 +#define S_SCMO_INT_EN_ADDR(b, n) \
2957 + (S_SCMO_REG_BASE(b) + (0x8000 * (n)) + 0x0000010c)
2958 +enum bimc_s_scmo_int_en {
2959 + S_SCMO_INT_EN_RMSK = 0x1,
2960 + S_SCMO_INT_EN_IRQ_EN_BMSK = 0x1,
2961 + S_SCMO_INT_EN_IRQ_EN_SHFT = 0x0,
2962 +};
2963 +
2964 +#define S_SCMO_ESYN_ADDR_ADDR(b, n) \
2965 + (S_SCMO_REG_BASE(b) + (0x8000 * (n)) + 0x00000120)
2966 +enum bimc_s_scmo_esyn_addr {
2967 + S_SCMO_ESYN_ADDR_RMSK = 0xffffffff,
2968 + S_SCMO_ESYN_ADDR_ESYN_ADDR_ERR_ADDR_BMSK = 0xffffffff,
2969 + S_SCMO_ESYN_ADDR_ESYN_ADDR_ERR_ADDR_SHFT = 0x0,
2970 +};
2971 +
2972 +#define S_SCMO_ESYN_APACKET_0_ADDR(b, n) \
2973 + (S_SCMO_REG_BASE(b) + (0x8000 * (n)) + 0x00000128)
2974 +enum bimc_s_scmo_esyn_apacket_0 {
2975 + S_SCMO_ESYN_APACKET_0_RMSK = 0xff1fffff,
2976 + S_SCMO_ESYN_APACKET_0_ERR_ATID_BMSK = 0xff000000,
2977 + S_SCMO_ESYN_APACKET_0_ERR_ATID_SHFT = 0x18,
2978 + S_SCMO_ESYN_APACKET_0_ERR_AVMID_BMSK = 0x1f0000,
2979 + S_SCMO_ESYN_APACKET_0_ERR_AVMID_SHFT = 0x10,
2980 + S_SCMO_ESYN_APACKET_0_ERR_AMID_BMSK = 0xffff,
2981 + S_SCMO_ESYN_APACKET_0_ERR_AMID_SHFT = 0x0,
2982 +};
2983 +
2984 +#define S_SCMO_ESYN_APACKET_1_ADDR(b, n) \
2985 + (S_SCMO_REG_BASE(b) + (0x8000 * (n)) + 0x0000012c)
2986 +enum bimc_s_scmo_esyn_apacket_1 {
2987 + S_SCMO_ESYN_APACKET_1_RMSK = 0x10ff117,
2988 + S_SCMO_ESYN_APACKET_1_ERR_CODE_BMSK = 0x1000000,
2989 + S_SCMO_ESYN_APACKET_1_ERR_CODE_SHFT = 0x18,
2990 + S_SCMO_ESYN_APACKET_1_ERR_ALEN_BMSK = 0xf0000,
2991 + S_SCMO_ESYN_APACKET_1_ERR_ALEN_SHFT = 0x10,
2992 + S_SCMO_ESYN_APACKET_1_ERR_ASIZE_BMSK = 0xe000,
2993 + S_SCMO_ESYN_APACKET_1_ERR_ASIZE_SHFT = 0xd,
2994 + S_SCMO_ESYN_APACKET_1_ERR_ABURST_BMSK = 0x1000,
2995 + S_SCMO_ESYN_APACKET_1_ERR_ABURST_SHFT = 0xc,
2996 + S_SCMO_ESYN_APACKET_1_ERR_AEXCLUSIVE_BMSK = 0x100,
2997 + S_SCMO_ESYN_APACKET_1_ERR_AEXCLUSIVE_SHFT = 0x8,
2998 + S_SCMO_ESYN_APACKET_1_ERR_APRONTS_BMSK = 0x10,
2999 + S_SCMO_ESYN_APACKET_1_ERR_APRONTS_SHFT = 0x4,
3000 + S_SCMO_ESYN_APACKET_1_ERR_AOOORD_BMSK = 0x4,
3001 + S_SCMO_ESYN_APACKET_1_ERR_AOOORD_SHFT = 0x2,
3002 + S_SCMO_ESYN_APACKET_1_ERR_AOOOWR_BMSK = 0x2,
3003 + S_SCMO_ESYN_APACKET_1_ERR_AOOOWR_SHFT = 0x1,
3004 + S_SCMO_ESYN_APACKET_1_ERR_AWRITE_BMSK = 0x1,
3005 + S_SCMO_ESYN_APACKET_1_ERR_AWRITE_SHFT = 0x0,
3006 +};
3007 +
3008 +#define S_SCMO_CLK_CTRL_ADDR(b, n) \
3009 + (S_SCMO_REG_BASE(b) + (0x8000 * (n)) + 0x00000200)
3010 +enum bimc_s_scmo_clk_ctrl {
3011 + S_SCMO_CLK_CTRL_RMSK = 0xffff1111,
3012 + S_SCMO_CLK_CTRL_PEN_CMD_CG_EN_BMSK = 0x10000,
3013 + S_SCMO_CLK_CTRL_PEN_CMD_CG_EN_SHFT = 0x10,
3014 + S_SCMO_CLK_CTRL_RCH_CG_EN_BMSK = 0x1000,
3015 + S_SCMO_CLK_CTRL_RCH_CG_EN_SHFT = 0xc,
3016 + S_SCMO_CLK_CTRL_FLUSH_CG_EN_BMSK = 0x100,
3017 + S_SCMO_CLK_CTRL_FLUSH_CG_EN_SHFT = 0x8,
3018 + S_SCMO_CLK_CTRL_WCH_CG_EN_BMSK = 0x10,
3019 + S_SCMO_CLK_CTRL_WCH_CG_EN_SHFT = 0x4,
3020 + S_SCMO_CLK_CTRL_ACH_CG_EN_BMSK = 0x1,
3021 + S_SCMO_CLK_CTRL_ACH_CG_EN_SHFT = 0x0,
3022 +};
3023 +
3024 +#define S_SCMO_SLV_INTERLEAVE_CFG_ADDR(b, n) \
3025 + (S_SCMO_REG_BASE(b) + (0x8000 * (n)) + 0x00000400)
3026 +enum bimc_s_scmo_slv_interleave_cfg {
3027 + S_SCMO_SLV_INTERLEAVE_CFG_RMSK = 0xff,
3028 + S_SCMO_SLV_INTERLEAVE_CFG_INTERLEAVE_CS1_BMSK = 0x10,
3029 + S_SCMO_SLV_INTERLEAVE_CFG_INTERLEAVE_CS1_SHFT = 0x4,
3030 + S_SCMO_SLV_INTERLEAVE_CFG_INTERLEAVE_CS0_BMSK = 0x1,
3031 + S_SCMO_SLV_INTERLEAVE_CFG_INTERLEAVE_CS0_SHFT = 0x0,
3032 +};
3033 +
3034 +#define S_SCMO_ADDR_BASE_CSn_ADDR(b, n, o) \
3035 + (S_SCMO_REG_BASE(b) + (0x8000 * (n)) + 0x00000410 + 0x4 * (o))
3036 +enum bimc_s_scmo_addr_base_csn {
3037 + S_SCMO_ADDR_BASE_CSn_RMSK = 0xffff,
3038 + S_SCMO_ADDR_BASE_CSn_MAXn = 1,
3039 + S_SCMO_ADDR_BASE_CSn_ADDR_BASE_BMSK = 0xfc,
3040 + S_SCMO_ADDR_BASE_CSn_ADDR_BASE_SHFT = 0x2,
3041 +};
3042 +
3043 +#define S_SCMO_ADDR_MAP_CSn_ADDR(b, n, o) \
3044 + (S_SCMO_REG_BASE(b) + (0x8000 * (n)) + 0x00000420 + 0x4 * (o))
3045 +enum bimc_s_scmo_addr_map_csn {
3046 + S_SCMO_ADDR_MAP_CSn_RMSK = 0xffff,
3047 + S_SCMO_ADDR_MAP_CSn_MAXn = 1,
3048 + S_SCMO_ADDR_MAP_CSn_RANK_EN_BMSK = 0x8000,
3049 + S_SCMO_ADDR_MAP_CSn_RANK_EN_SHFT = 0xf,
3050 + S_SCMO_ADDR_MAP_CSn_ADDR_MODE_BMSK = 0x1000,
3051 + S_SCMO_ADDR_MAP_CSn_ADDR_MODE_SHFT = 0xc,
3052 + S_SCMO_ADDR_MAP_CSn_BANK_SIZE_BMSK = 0x100,
3053 + S_SCMO_ADDR_MAP_CSn_BANK_SIZE_SHFT = 0x8,
3054 + S_SCMO_ADDR_MAP_CSn_ROW_SIZE_BMSK = 0x30,
3055 + S_SCMO_ADDR_MAP_CSn_ROW_SIZE_SHFT = 0x4,
3056 + S_SCMO_ADDR_MAP_CSn_COL_SIZE_BMSK = 0x3,
3057 + S_SCMO_ADDR_MAP_CSn_COL_SIZE_SHFT = 0x0,
3058 +};
3059 +
3060 +#define S_SCMO_ADDR_MASK_CSn_ADDR(b, n, o) \
3061 + (S_SCMO_REG_BASE(b) + (0x8000 * (n)) + 0x00000430 + 0x4 * (0))
3062 +enum bimc_s_scmo_addr_mask_csn {
3063 + S_SCMO_ADDR_MASK_CSn_RMSK = 0xffff,
3064 + S_SCMO_ADDR_MASK_CSn_MAXn = 1,
3065 + S_SCMO_ADDR_MASK_CSn_ADDR_MASK_BMSK = 0xfc,
3066 + S_SCMO_ADDR_MASK_CSn_ADDR_MASK_SHFT = 0x2,
3067 +};
3068 +
3069 +#define S_SCMO_SLV_STATUS_ADDR(b, n) \
3070 + (S_SCMO_REG_BASE(b) + (0x8000 * (n)) + 0x00000450)
3071 +enum bimc_s_scmo_slv_status {
3072 + S_SCMO_SLV_STATUS_RMSK = 0xff3,
3073 + S_SCMO_SLV_STATUS_GLOBAL_MONS_IN_USE_BMSK = 0xff0,
3074 + S_SCMO_SLV_STATUS_GLOBAL_MONS_IN_USE_SHFT = 0x4,
3075 + S_SCMO_SLV_STATUS_SLAVE_IDLE_BMSK = 0x3,
3076 + S_SCMO_SLV_STATUS_SLAVE_IDLE_SHFT = 0x0,
3077 +};
3078 +
3079 +#define S_SCMO_CMD_BUF_CFG_ADDR(b, n) \
3080 + (S_SCMO_REG_BASE(b) + (0x8000 * (n)) + 0x00000500)
3081 +enum bimc_s_scmo_cmd_buf_cfg {
3082 + S_SCMO_CMD_BUF_CFG_RMSK = 0xf1f,
3083 + S_SCMO_CMD_BUF_CFG_CMD_ORDERING_BMSK = 0x300,
3084 + S_SCMO_CMD_BUF_CFG_CMD_ORDERING_SHFT = 0x8,
3085 + S_SCMO_CMD_BUF_CFG_HP_CMD_AREQPRIO_MAP_BMSK = 0x10,
3086 + S_SCMO_CMD_BUF_CFG_HP_CMD_AREQPRIO_MAP_SHFT = 0x4,
3087 + S_SCMO_CMD_BUF_CFG_HP_CMD_Q_DEPTH_BMSK = 0x7,
3088 + S_SCMO_CMD_BUF_CFG_HP_CMD_Q_DEPTH_SHFT = 0x0,
3089 +};
3090 +
3091 +#define S_SCM_CMD_BUF_STATUS_ADDR(b, n) \
3092 + (S_SCMO_REG_BASE(b) + (0x8000 * (n)) + 0x00000520)
3093 +enum bimc_s_scm_cmd_buf_status {
3094 + S_SCMO_CMD_BUF_STATUS_RMSK = 0x77,
3095 + S_SCMO_CMD_BUF_STATUS_HP_CMD_BUF_ENTRIES_IN_USE_BMSK = 0x70,
3096 + S_SCMO_CMD_BUF_STATUS_HP_CMD_BUF_ENTRIES_IN_USE_SHFT = 0x4,
3097 + S_SCMO_CMD_BUF_STATUS_LP_CMD_BUF_ENTRIES_IN_USE_BMSK = 0x7,
3098 + S_SCMO_CMD_BUF_STATUS_LP_CMD_BUF_ENTRIES_IN_USE_SHFT = 0x0,
3099 +};
3100 +
3101 +#define S_SCMO_RCH_SEL_ADDR(b, n) \
3102 + (S_SCMO_REG_BASE(b) + (0x8000 * (n)) + 0x00000540)
3103 +enum bimc_s_scmo_rch_sel {
3104 + S_SCMO_RCH_SEL_RMSK = 0xffffffff,
3105 + S_SCMO_CMD_BUF_STATUS_RCH_PORTS_BMSK = 0xffffffff,
3106 + S_SCMO_CMD_BUF_STATUS_RCH_PORTS_SHFT = 0x0,
3107 +};
3108 +
3109 +#define S_SCMO_RCH_BKPR_CFG_ADDR(b, n) \
3110 + (S_SCMO_REG_BASE(b) + (0x8000 * (n)) + 0x00000544)
3111 +enum bimc_s_scmo_rch_bkpr_cfg {
3112 + S_SCMO_RCH_BKPR_CFG_RMSK = 0xffffffff,
3113 + S_SCMO_RCH_BKPR_CFG_RCH1_FIFO_BKPR_HI_TH_BMSK = 0x3f000000,
3114 + S_SCMO_RCH_BKPR_CFG_RCH1_FIFO_BKPR_HI_TH_SHFT = 0x18,
3115 + S_SCMO_RCH_BKPR_CFG_RCH1_FIFO_BKPR_LO_TH_BMSK = 0x3f0000,
3116 + S_SCMO_RCH_BKPR_CFG_RCH1_FIFO_BKPR_LO_TH_SHFT = 0x10,
3117 + S_SCMO_RCH_BKPR_CFG_RCH0_FIFO_BKPR_HI_TH_BMSK = 0x3f00,
3118 + S_SCMO_RCH_BKPR_CFG_RCH0_FIFO_BKPR_HI_TH_SHFT = 0x8,
3119 + S_SCMO_RCH_BKPR_CFG_RCH0_FIFO_BKPR_LO_TH_BMSK = 0x3f,
3120 + S_SCMO_RCH_BKPR_CFG_RCH0_FIFO_BKPR_LO_TH_SHFT = 0x0,
3121 +};
3122 +
3123 +#define S_SCMO_RCH_STATUS_ADDR(b, n) \
3124 + (S_SCMO_REG_BASE(b) + (0x8000 * (n)) + 0x00000560)
3125 +enum bimc_s_scmo_rch_status {
3126 + S_SCMO_RCH_STATUS_RMSK = 0x33333,
3127 + S_SCMO_RCH_STATUS_PRQ_FIFO_FULL_BMSK = 0x20000,
3128 + S_SCMO_RCH_STATUS_PRQ_FIFO_FULL_SHFT = 0x11,
3129 + S_SCMO_RCH_STATUS_PRQ_FIFO_EMPTY_BMSK = 0x10000,
3130 + S_SCMO_RCH_STATUS_PRQ_FIFO_EMPTY_SHFT = 0x10,
3131 + S_SCMO_RCH_STATUS_RCH1_QUAL_FIFO_FULL_BMSK = 0x2000,
3132 + S_SCMO_RCH_STATUS_RCH1_QUAL_FIFO_FULL_SHFT = 0xd,
3133 + S_SCMO_RCH_STATUS_RCH1_QUAL_FIFO_EMPTY_BMSK = 0x1000,
3134 + S_SCMO_RCH_STATUS_RCH1_QUAL_FIFO_EMPTY_SHFT = 0xc,
3135 + S_SCMO_RCH_STATUS_RCH1_DATA_FIFO_FULL_BMSK = 0x200,
3136 + S_SCMO_RCH_STATUS_RCH1_DATA_FIFO_FULL_SHFT = 0x9,
3137 + S_SCMO_RCH_STATUS_RCH1_DATA_FIFO_EMPTY_BMSK = 0x100,
3138 + S_SCMO_RCH_STATUS_RCH1_DATA_FIFO_EMPTY_SHFT = 0x8,
3139 + S_SCMO_RCH_STATUS_RCH0_QUAL_FIFO_FULL_BMSK = 0x20,
3140 + S_SCMO_RCH_STATUS_RCH0_QUAL_FIFO_FULL_SHFT = 0x5,
3141 + S_SCMO_RCH_STATUS_RCH0_QUAL_FIFO_EMPTY_BMSK = 0x10,
3142 + S_SCMO_RCH_STATUS_RCH0_QUAL_FIFO_EMPTY_SHFT = 0x4,
3143 + S_SCMO_RCH_STATUS_RCH0_DATA_FIFO_FULL_BMSK = 0x2,
3144 + S_SCMO_RCH_STATUS_RCH0_DATA_FIFO_FULL_SHFT = 0x1,
3145 + S_SCMO_RCH_STATUS_RCH0_DATA_FIFO_EMPTY_BMSK = 0x1,
3146 + S_SCMO_RCH_STATUS_RCH0_DATA_FIFO_EMPTY_SHFT = 0x0,
3147 +};
3148 +
3149 +#define S_SCMO_WCH_BUF_CFG_ADDR(b, n) \
3150 + (S_SCMO_REG_BASE(b) + (0x8000 * (n)) + 0x00000580)
3151 +enum bimc_s_scmo_wch_buf_cfg {
3152 + S_SCMO_WCH_BUF_CFG_RMSK = 0xff,
3153 + S_SCMO_WCH_BUF_CFG_WRITE_BLOCK_READ_BMSK = 0x10,
3154 + S_SCMO_WCH_BUF_CFG_WRITE_BLOCK_READ_SHFT = 0x4,
3155 + S_SCMO_WCH_BUF_CFG_COALESCE_EN_BMSK = 0x1,
3156 + S_SCMO_WCH_BUF_CFG_COALESCE_EN_SHFT = 0x0,
3157 +};
3158 +
3159 +#define S_SCMO_WCH_STATUS_ADDR(b, n) \
3160 + (S_SCMO_REG_BASE(b) + (0x8000 * (n)) + 0x000005a0)
3161 +enum bimc_s_scmo_wch_status {
3162 + S_SCMO_WCH_STATUS_RMSK = 0x333,
3163 + S_SCMO_WCH_STATUS_BRESP_FIFO_FULL_BMSK = 0x200,
3164 + S_SCMO_WCH_STATUS_BRESP_FIFO_FULL_SHFT = 0x9,
3165 + S_SCMO_WCH_STATUS_BRESP_FIFO_EMPTY_BMSK = 0x100,
3166 + S_SCMO_WCH_STATUS_BRESP_FIFO_EMPTY_SHFT = 0x8,
3167 + S_SCMO_WCH_STATUS_WDATA_FIFO_FULL_BMSK = 0x20,
3168 + S_SCMO_WCH_STATUS_WDATA_FIFO_FULL_SHFT = 0x5,
3169 + S_SCMO_WCH_STATUS_WDATA_FIFO_EMPTY_BMSK = 0x10,
3170 + S_SCMO_WCH_STATUS_WDATA_FIFO_EMPTY_SHFT = 0x4,
3171 + S_SCMO_WCH_STATUS_WBUF_FULL_BMSK = 0x2,
3172 + S_SCMO_WCH_STATUS_WBUF_FULL_SHFT = 0x1,
3173 + S_SCMO_WCH_STATUS_WBUF_EMPTY_BMSK = 0x1,
3174 + S_SCMO_WCH_STATUS_WBUF_EMPTY_SHFT = 0x0,
3175 +};
3176 +
3177 +#define S_SCMO_FLUSH_CFG_ADDR(b, n) \
3178 + (S_SCMO_REG_BASE(b) + (0x8000 * (n)) + 0x000005c0)
3179 +enum bimc_s_scmo_flush_cfg {
3180 + S_SCMO_FLUSH_CFG_RMSK = 0xffffffff,
3181 + S_SCMO_FLUSH_CFG_FLUSH_IN_ORDER_BMSK = 0x10000000,
3182 + S_SCMO_FLUSH_CFG_FLUSH_IN_ORDER_SHFT = 0x1c,
3183 + S_SCMO_FLUSH_CFG_FLUSH_IDLE_DELAY_BMSK = 0x3ff0000,
3184 + S_SCMO_FLUSH_CFG_FLUSH_IDLE_DELAY_SHFT = 0x10,
3185 + S_SCMO_FLUSH_CFG_FLUSH_UPPER_LIMIT_BMSK = 0xf00,
3186 + S_SCMO_FLUSH_CFG_FLUSH_UPPER_LIMIT_SHFT = 0x8,
3187 + S_SCMO_FLUSH_CFG_FLUSH_LOWER_LIMIT_BMSK = 0xf,
3188 + S_SCMO_FLUSH_CFG_FLUSH_LOWER_LIMIT_SHFT = 0x0,
3189 +};
3190 +
3191 +#define S_SCMO_FLUSH_CMD_ADDR(b, n) \
3192 + (S_SCMO_REG_BASE(b) + (0x8000 * (n)) + 0x000005c4)
3193 +enum bimc_s_scmo_flush_cmd {
3194 + S_SCMO_FLUSH_CMD_RMSK = 0xf,
3195 + S_SCMO_FLUSH_CMD_FLUSH_ALL_BUF_BMSK = 0x3,
3196 + S_SCMO_FLUSH_CMD_FLUSH_ALL_BUF_SHFT = 0x0,
3197 +};
3198 +
3199 +#define S_SCMO_CMD_OPT_CFG0_ADDR(b, n) \
3200 + (S_SCM0_REG_BASE(b) + (0x8000 * (n)) + 0x00000700)
3201 +enum bimc_s_scmo_cmd_opt_cfg0 {
3202 + S_SCMO_CMD_OPT_CFG0_RMSK = 0xffffff,
3203 + S_SCMO_CMD_OPT_CFG0_IGNORE_BANK_UNAVL_BMSK = 0x100000,
3204 + S_SCMO_CMD_OPT_CFG0_IGNORE_BANK_UNAVL_SHFT = 0x14,
3205 + S_SCMO_CMD_OPT_CFG0_MASK_CMDOUT_PRI_BMSK = 0x10000,
3206 + S_SCMO_CMD_OPT_CFG0_MASK_CMDOUT_PRI_SHFT = 0x10,
3207 + S_SCMO_CMD_OPT_CFG0_DPE_CMD_REORDERING_BMSK = 0x1000,
3208 + S_SCMO_CMD_OPT_CFG0_DPE_CMD_REORDERING_SHFT = 0xc,
3209 + S_SCMO_CMD_OPT_CFG0_WR_OPT_EN_BMSK = 0x100,
3210 + S_SCMO_CMD_OPT_CFG0_WR_OPT_EN_SHFT = 0x8,
3211 + S_SCMO_CMD_OPT_CFG0_RD_OPT_EN_BMSK = 0x10,
3212 + S_SCMO_CMD_OPT_CFG0_RD_OPT_EN_SHFT = 0x4,
3213 + S_SCMO_CMD_OPT_CFG0_PAGE_MGMT_POLICY_BMSK = 0x1,
3214 + S_SCMO_CMD_OPT_CFG0_PAGE_MGMT_POLICY_SHFT = 0x0,
3215 +};
3216 +
3217 +#define S_SCMO_CMD_OPT_CFG1_ADDR(b, n) \
3218 + (S_SCMO_REG_BASE(b) + (0x8000 * (n)) + 0x00000704)
3219 +enum bimc_s_scmo_cmd_opt_cfg1 {
3220 + S_SCMO_CMD_OPT_CFG1_RMSK = 0xffffffff,
3221 + S_SCMO_CMD_OPT_CFG1_HSTP_CMD_TIMEOUT_BMSK = 0x1f000000,
3222 + S_SCMO_CMD_OPT_CFG1_HSTP_CMD_TIMEOUT_SHFT = 0x18,
3223 + S_SCMO_CMD_OPT_CFG1_HP_CMD_TIMEOUT_BMSK = 0x1f0000,
3224 + S_SCMO_CMD_OPT_CFG1_HP_CMD_TIMEOUT_SHFT = 0x10,
3225 + S_SCMO_CMD_OPT_CFG1_MP_CMD_TIMEOUT_BMSK = 0x1f00,
3226 + S_SCMO_CMD_OPT_CFG1_MP_CMD_TIMEOUT_SHFT = 0x8,
3227 + S_SCMO_CMD_OPT_CFG1_LP_CMD_TIMEOUT_BMSK = 0x1f,
3228 + S_SCMO_CMD_OPT_CFG1_LP_CMD_TIMEOUT_SHFT = 0x0,
3229 +};
3230 +
3231 +#define S_SCMO_CMD_OPT_CFG2_ADDR(b, n) \
3232 + (S_SCMO_REG_BASE(b) + (0x8000 * (n)) + 0x00000708)
3233 +enum bimc_s_scmo_cmd_opt_cfg2 {
3234 + S_SCMO_CMD_OPT_CFG2_RMSK = 0xff,
3235 + S_SCMO_CMD_OPT_CFG2_RWOPT_CMD_TIMEOUT_BMSK = 0xf,
3236 + S_SCMO_CMD_OPT_CFG2_RWOPT_CMD_TIMEOUT_SHFT = 0x0,
3237 +};
3238 +
3239 +#define S_SCMO_CMD_OPT_CFG3_ADDR(b, n) \
3240 + (S_SCMO_REG_BASE(b) + (0x8000 * (n)) + 0x0000070c)
3241 +enum bimc_s_scmo_cmd_opt_cfg3 {
3242 + S_SCMO_CMD_OPT_CFG3_RMSK = 0xff,
3243 + S_SCMO_CMD_OPT_CFG3_FLUSH_CMD_TIMEOUT_BMSK = 0xf,
3244 + S_SCMO_CMD_OPT_CFG3_FLUSH_CMD_TIMEOUT_SHFT = 0x0,
3245 +};
3246 +
3247 +/* S_SWAY_GENERIC */
3248 +#define S_SWAY_REG_BASE(b) ((b) + 0x00048000)
3249 +
3250 +#define S_SWAY_CONFIG_INFO_0_ADDR(b, n) \
3251 + (S_SWAY_REG_BASE(b) + (0x8000 * (n)) + 0x00000020)
3252 +enum bimc_s_sway_config_info_0 {
3253 + S_SWAY_CONFIG_INFO_0_RMSK = 0xff0000ff,
3254 + S_SWAY_CONFIG_INFO_0_SYNC_MODE_BMSK = 0xff000000,
3255 + S_SWAY_CONFIG_INFO_0_SYNC_MODE_SHFT = 0x18,
3256 + S_SWAY_CONFIG_INFO_0_FUNC_BMSK = 0xff,
3257 + S_SWAY_CONFIG_INFO_0_FUNC_SHFT = 0x0,
3258 +};
3259 +
3260 +#define S_SWAY_CONFIG_INFO_1_ADDR(b, n) \
3261 + (S_SWAY_REG_BASE(b) + (0x8000 * (n)) + 0x00000030)
3262 +enum bimc_s_sway_config_info_1 {
3263 + S_SWAY_CONFIG_INFO_1_RMSK = 0xffffffff,
3264 + S_SWAY_CONFIG_INFO_1_MPORT_CONNECTIVITY_BMSK = 0xffffffff,
3265 + S_SWAY_CONFIG_INFO_1_MPORT_CONNECTIVITY_SHFT = 0x0,
3266 +};
3267 +
3268 +#define S_SWAY_CONFIG_INFO_2_ADDR(b, n) \
3269 + (S_SWAY_REG_BASE(b) + (0x8000 * (n)) + 0x00000040)
3270 +enum bimc_s_sway_config_info_2 {
3271 + S_SWAY_CONFIG_INFO_2_RMSK = 0xffff0000,
3272 + S_SWAY_CONFIG_INFO_2_MPORT_CONNECTIVITY_BMSK = 0xffff0000,
3273 + S_SWAY_CONFIG_INFO_2_MPORT_CONNECTIVITY_SHFT = 0x10,
3274 +};
3275 +
3276 +#define S_SWAY_CONFIG_INFO_3_ADDR(b, n) \
3277 + (S_SWAY_REG_BASE(b) + (0x8000 * (n)) + 0x00000050)
3278 +enum bimc_s_sway_config_info_3 {
3279 + S_SWAY_CONFIG_INFO_3_RMSK = 0xffffffff,
3280 + S_SWAY_CONFIG_INFO_3_RCH0_DEPTH_BMSK = 0xff000000,
3281 + S_SWAY_CONFIG_INFO_3_RCH0_DEPTH_SHFT = 0x18,
3282 + S_SWAY_CONFIG_INFO_3_BCH_DEPTH_BMSK = 0xff0000,
3283 + S_SWAY_CONFIG_INFO_3_BCH_DEPTH_SHFT = 0x10,
3284 + S_SWAY_CONFIG_INFO_3_WCH_DEPTH_BMSK = 0xff,
3285 + S_SWAY_CONFIG_INFO_3_WCH_DEPTH_SHFT = 0x0,
3286 +};
3287 +
3288 +#define S_SWAY_CONFIG_INFO_4_ADDR(b, n) \
3289 + (S_SWAY_REG_BASE(b) + (0x8000 * (n)) + 0x00000060)
3290 +enum bimc_s_sway_config_info_4 {
3291 + S_SWAY_CONFIG_INFO_4_RMSK = 0x800000ff,
3292 + S_SWAY_CONFIG_INFO_4_DUAL_RCH_EN_BMSK = 0x80000000,
3293 + S_SWAY_CONFIG_INFO_4_DUAL_RCH_EN_SHFT = 0x1f,
3294 + S_SWAY_CONFIG_INFO_4_RCH1_DEPTH_BMSK = 0xff,
3295 + S_SWAY_CONFIG_INFO_4_RCH1_DEPTH_SHFT = 0x0,
3296 +};
3297 +
3298 +#define S_SWAY_CONFIG_INFO_5_ADDR(b, n) \
3299 + (S_SWAY_REG_BASE(b) + (0x8000 * (n)) + 0x00000070)
3300 +enum bimc_s_sway_config_info_5 {
3301 + S_SWAY_CONFIG_INFO_5_RMSK = 0x800000ff,
3302 + S_SWAY_CONFIG_INFO_5_QCH_EN_BMSK = 0x80000000,
3303 + S_SWAY_CONFIG_INFO_5_QCH_EN_SHFT = 0x1f,
3304 + S_SWAY_CONFIG_INFO_5_QCH_DEPTH_BMSK = 0xff,
3305 + S_SWAY_CONFIG_INFO_5_QCH_DEPTH_SHFT = 0x0,
3306 +};
3307 +
3308 +#define S_SWAY_CONFIG_INFO_6_ADDR(b, n) \
3309 + (S_SWAY_REG_BASE(b) + (0x8000 * (n)) + 0x00000080)
3310 +enum bimc_s_sway_config_info_6 {
3311 + S_SWAY_CONFIG_INFO_6_RMSK = 0x1,
3312 + S_SWAY_CONFIG_INFO_6_S2SW_PIPELINE_EN_BMSK = 0x1,
3313 + S_SWAY_CONFIG_INFO_6_S2SW_PIPELINE_EN_SHFT = 0x0,
3314 +};
3315 +
3316 +#define S_SWAY_INT_STATUS_ADDR(b, n) \
3317 + (S_SWAY_REG_BASE(b) + (0x8000 * (n)) + 0x00000100)
3318 +enum bimc_s_sway_int_status {
3319 + S_SWAY_INT_STATUS_RMSK = 0x3,
3320 + S_SWAY_INT_STATUS_RFU_BMSK = 0x3,
3321 + S_SWAY_INT_STATUS_RFU_SHFT = 0x0,
3322 +};
3323 +
3324 +#define S_SWAY_INT_CLR_ADDR(b, n) \
3325 + (S_SWAY_REG_BASE(b) + (0x8000 * (n)) + 0x00000108)
3326 +enum bimc_s_sway_int_clr {
3327 + S_SWAY_INT_CLR_RMSK = 0x3,
3328 + S_SWAY_INT_CLR_RFU_BMSK = 0x3,
3329 + S_SWAY_INT_CLR_RFU_SHFT = 0x0,
3330 +};
3331 +
3332 +
3333 +#define S_SWAY_INT_EN_ADDR(b, n) \
3334 + (S_SWAY_REG_BASE(b) + (0x8000 * (n)) + 0x0000010c)
3335 +enum bimc_s_sway_int_en {
3336 + S_SWAY_INT_EN_RMSK = 0x3,
3337 + S_SWAY_INT_EN_RFU_BMSK = 0x3,
3338 + S_SWAY_INT_EN_RFU_SHFT = 0x0,
3339 +};
3340 +
3341 +#define S_SWAY_CLK_CTRL_ADDR(b, n) \
3342 + (S_SWAY_REG_BASE(b) + (0x8000 * (n)) + 0x00000200)
3343 +enum bimc_s_sway_clk_ctrl {
3344 + S_SWAY_CLK_CTRL_RMSK = 0x3,
3345 + S_SWAY_CLK_CTRL_SLAVE_CLK_GATING_EN_BMSK = 0x2,
3346 + S_SWAY_CLK_CTRL_SLAVE_CLK_GATING_EN_SHFT = 0x1,
3347 + S_SWAY_CLK_CTRL_CORE_CLK_GATING_EN_BMSK = 0x1,
3348 + S_SWAY_CLK_CTRL_CORE_CLK_GATING_EN_SHFT = 0x0,
3349 +};
3350 +
3351 +#define S_SWAY_RCH_SEL_ADDR(b, n) \
3352 + (S_SWAY_REG_BASE(b) + (0x8000 * (n)) + 0x00000210)
3353 +enum bimc_s_sway_rch_sel {
3354 + S_SWAY_RCH_SEL_RMSK = 0x7f,
3355 + S_SWAY_RCH_SEL_UNUSED_BMSK = 0x7f,
3356 + S_SWAY_RCH_SEL_UNUSED_SHFT = 0x0,
3357 +};
3358 +
3359 +
3360 +#define S_SWAY_MAX_OUTSTANDING_REQS_ADDR(b, n) \
3361 + (S_SWAY_REG_BASE(b) + (0x8000 * (n)) + 0x00000220)
3362 +enum bimc_s_sway_max_outstanding_reqs {
3363 + S_SWAY_MAX_OUTSTANDING_REQS_RMSK = 0xffff,
3364 + S_SWAY_MAX_OUTSTANDING_REQS_WRITE_BMSK = 0xff00,
3365 + S_SWAY_MAX_OUTSTANDING_REQS_WRITE_SHFT = 0x8,
3366 + S_SWAY_MAX_OUTSTANDING_REQS_READ_BMSK = 0xff,
3367 + S_SWAY_MAX_OUTSTANDING_REQS_READ_SHFT = 0x0,
3368 +};
3369 +
3370 +
3371 +#define S_SWAY_BUF_STATUS_0_ADDR(b, n) \
3372 + (S_SWAY_REG_BASE(b) + (0x8000 * (n)) + 0x00000400)
3373 +enum bimc_s_sway_buf_status_0 {
3374 + S_SWAY_BUF_STATUS_0_RMSK = 0xf0300f03,
3375 + S_SWAY_BUF_STATUS_0_RCH0_DATA_RD_FULL_BMSK = 0x80000000,
3376 + S_SWAY_BUF_STATUS_0_RCH0_DATA_RD_FULL_SHFT = 0x1f,
3377 + S_SWAY_BUF_STATUS_0_RCH0_DATA_RD_EMPTY_BMSK = 0x40000000,
3378 + S_SWAY_BUF_STATUS_0_RCH0_DATA_RD_EMPTY_SHFT = 0x1e,
3379 + S_SWAY_BUF_STATUS_0_RCH0_CTRL_RD_FULL_BMSK = 0x20000000,
3380 + S_SWAY_BUF_STATUS_0_RCH0_CTRL_RD_FULL_SHFT = 0x1d,
3381 + S_SWAY_BUF_STATUS_0_RCH0_CTRL_RD_EMPTY_BMSK = 0x10000000,
3382 + S_SWAY_BUF_STATUS_0_RCH0_CTRL_RD_EMPTY_SHFT = 0x1c,
3383 + S_SWAY_BUF_STATUS_0_BCH_RD_FULL_BMSK = 0x200000,
3384 + S_SWAY_BUF_STATUS_0_BCH_RD_FULL_SHFT = 0x15,
3385 + S_SWAY_BUF_STATUS_0_BCH_RD_EMPTY_BMSK = 0x100000,
3386 + S_SWAY_BUF_STATUS_0_BCH_RD_EMPTY_SHFT = 0x14,
3387 + S_SWAY_BUF_STATUS_0_WCH_DATA_WR_FULL_BMSK = 0x800,
3388 + S_SWAY_BUF_STATUS_0_WCH_DATA_WR_FULL_SHFT = 0xb,
3389 + S_SWAY_BUF_STATUS_0_WCH_DATA_WR_EMPTY_BMSK = 0x400,
3390 + S_SWAY_BUF_STATUS_0_WCH_DATA_WR_EMPTY_SHFT = 0xa,
3391 + S_SWAY_BUF_STATUS_0_WCH_CTRL_WR_FULL_BMSK = 0x200,
3392 + S_SWAY_BUF_STATUS_0_WCH_CTRL_WR_FULL_SHFT = 0x9,
3393 + S_SWAY_BUF_STATUS_0_WCH_CTRL_WR_EMPTY_BMSK = 0x100,
3394 + S_SWAY_BUF_STATUS_0_WCH_CTRL_WR_EMPTY_SHFT = 0x8,
3395 + S_SWAY_BUF_STATUS_0_ACH_WR_FULL_BMSK = 0x2,
3396 + S_SWAY_BUF_STATUS_0_ACH_WR_FULL_SHFT = 0x1,
3397 + S_SWAY_BUF_STATUS_0_ACH_WR_EMPTY_BMSK = 0x1,
3398 + S_SWAY_BUF_STATUS_0_ACH_WR_EMPTY_SHFT = 0x0,
3399 +};
3400 +
3401 +#define S_SWAY_BUF_STATUS_1_ADDR(b, n) \
3402 + (S_SWAY_REG_BASE(b) + (0x8000 * (n)) + 0x00000410)
3403 +enum bimc_s_sway_buf_status_1 {
3404 + S_SWAY_BUF_STATUS_1_RMSK = 0xf0,
3405 + S_SWAY_BUF_STATUS_1_RCH1_DATA_RD_FULL_BMSK = 0x80,
3406 + S_SWAY_BUF_STATUS_1_RCH1_DATA_RD_FULL_SHFT = 0x7,
3407 + S_SWAY_BUF_STATUS_1_RCH1_DATA_RD_EMPTY_BMSK = 0x40,
3408 + S_SWAY_BUF_STATUS_1_RCH1_DATA_RD_EMPTY_SHFT = 0x6,
3409 + S_SWAY_BUF_STATUS_1_RCH1_CTRL_RD_FULL_BMSK = 0x20,
3410 + S_SWAY_BUF_STATUS_1_RCH1_CTRL_RD_FULL_SHFT = 0x5,
3411 + S_SWAY_BUF_STATUS_1_RCH1_CTRL_RD_EMPTY_BMSK = 0x10,
3412 + S_SWAY_BUF_STATUS_1_RCH1_CTRL_RD_EMPTY_SHFT = 0x4,
3413 +};
3414 +
3415 +#define S_SWAY_BUF_STATUS_2_ADDR(b, n) \
3416 + (S_SWAY_REG_BASE(b) + (0x8000 * (n)) + 0x00000420)
3417 +enum bimc_s_sway_buf_status_2 {
3418 + S_SWAY_BUF_STATUS_2_RMSK = 0x30,
3419 + S_SWAY_BUF_STATUS_2_QCH_RD_FULL_BMSK = 0x20,
3420 + S_SWAY_BUF_STATUS_2_QCH_RD_FULL_SHFT = 0x5,
3421 + S_SWAY_BUF_STATUS_2_QCH_RD_EMPTY_BMSK = 0x10,
3422 + S_SWAY_BUF_STATUS_2_QCH_RD_EMPTY_SHFT = 0x4,
3423 +};
3424 +
3425 +/* S_ARB_GENERIC */
3426 +
3427 +#define S_ARB_REG_BASE(b) ((b) + 0x00049000)
3428 +
3429 +#define S_ARB_COMPONENT_INFO_ADDR(b, n) \
3430 + (S_SWAY_REG_BASE(b) + (0x8000 * (n)) + 0x00000000)
3431 +enum bimc_s_arb_component_info {
3432 + S_ARB_COMPONENT_INFO_RMSK = 0xffffff,
3433 + S_ARB_COMPONENT_INFO_INSTANCE_BMSK = 0xff0000,
3434 + S_ARB_COMPONENT_INFO_INSTANCE_SHFT = 0x10,
3435 + S_ARB_COMPONENT_INFO_SUB_TYPE_BMSK = 0xff00,
3436 + S_ARB_COMPONENT_INFO_SUB_TYPE_SHFT = 0x8,
3437 + S_ARB_COMPONENT_INFO_TYPE_BMSK = 0xff,
3438 + S_ARB_COMPONENT_INFO_TYPE_SHFT = 0x0,
3439 +};
3440 +
3441 +#define S_ARB_CONFIG_INFO_0_ADDR(b, n) \
3442 + (S_ARB_REG_BASE(b) + (0x8000 * (n)) + 0x00000020)
3443 +enum bimc_s_arb_config_info_0 {
3444 + S_ARB_CONFIG_INFO_0_RMSK = 0x800000ff,
3445 + S_ARB_CONFIG_INFO_0_ARB2SW_PIPELINE_EN_BMSK = 0x80000000,
3446 + S_ARB_CONFIG_INFO_0_ARB2SW_PIPELINE_EN_SHFT = 0x1f,
3447 + S_ARB_CONFIG_INFO_0_FUNC_BMSK = 0xff,
3448 + S_ARB_CONFIG_INFO_0_FUNC_SHFT = 0x0,
3449 +};
3450 +
3451 +#define S_ARB_CONFIG_INFO_1_ADDR(b, n) \
3452 + (S_ARB_REG_BASE(b) + (0x8000 * (n)) + 0x00000030)
3453 +enum bimc_s_arb_config_info_1 {
3454 + S_ARB_CONFIG_INFO_1_RMSK = 0xffffffff,
3455 + S_ARB_CONFIG_INFO_1_MPORT_CONNECTIVITY_BMSK = 0xffffffff,
3456 + S_ARB_CONFIG_INFO_1_MPORT_CONNECTIVITY_SHFT = 0x0,
3457 +};
3458 +
3459 +#define S_ARB_CLK_CTRL_ADDR(b) \
3460 + (S_ARB_REG_BASE(b) + (0x8000 * (n)) + 0x00000200)
3461 +enum bimc_s_arb_clk_ctrl {
3462 + S_ARB_CLK_CTRL_RMSK = 0x1,
3463 + S_ARB_CLK_CTRL_SLAVE_CLK_GATING_EN_BMSK = 0x2,
3464 + S_ARB_CLK_CTRL_SLAVE_CLK_GATING_EN_SHFT = 0x1,
3465 + S_ARB_CLK_CTRL_CORE_CLK_GATING_EN_BMSK = 0x1,
3466 + S_ARB_CLK_CTRL_CORE_CLK_GATING_EN_SHFT = 0x0,
3467 + S_ARB_CLK_CTRL_CLK_GATING_EN_BMSK = 0x1,
3468 + S_ARB_CLK_CTRL_CLK_GATING_EN_SHFT = 0x0,
3469 +};
3470 +
3471 +#define S_ARB_MODE_ADDR(b, n) \
3472 + (S_ARB_REG_BASE(b) + (0x8000 * (n)) + 0x00000210)
3473 +enum bimc_s_arb_mode {
3474 + S_ARB_MODE_RMSK = 0xf0000001,
3475 + S_ARB_MODE_WR_GRANTS_AHEAD_BMSK = 0xf0000000,
3476 + S_ARB_MODE_WR_GRANTS_AHEAD_SHFT = 0x1c,
3477 + S_ARB_MODE_PRIO_RR_EN_BMSK = 0x1,
3478 + S_ARB_MODE_PRIO_RR_EN_SHFT = 0x0,
3479 +};
3480 +
3481 +#define BKE_HEALTH_MASK \
3482 + (M_BKE_HEALTH_0_CONFIG_LIMIT_CMDS_BMSK |\
3483 + M_BKE_HEALTH_0_CONFIG_AREQPRIO_BMSK |\
3484 + M_BKE_HEALTH_0_CONFIG_PRIOLVL_BMSK)
3485 +
3486 +#define BKE_HEALTH_VAL(limit, areq, plvl) \
3487 + ((((limit) << M_BKE_HEALTH_0_CONFIG_LIMIT_CMDS_SHFT) & \
3488 + M_BKE_HEALTH_0_CONFIG_LIMIT_CMDS_BMSK) | \
3489 + (((areq) << M_BKE_HEALTH_0_CONFIG_AREQPRIO_SHFT) & \
3490 + M_BKE_HEALTH_0_CONFIG_AREQPRIO_BMSK) | \
3491 + (((plvl) << M_BKE_HEALTH_0_CONFIG_PRIOLVL_SHFT) & \
3492 + M_BKE_HEALTH_0_CONFIG_PRIOLVL_BMSK))
3493 +
3494 +#define MAX_GRANT_PERIOD \
3495 + (M_BKE_GP_GP_BMSK >> \
3496 + M_BKE_GP_GP_SHFT)
3497 +
3498 +#define MAX_GC \
3499 + (M_BKE_GC_GC_BMSK >> \
3500 + (M_BKE_GC_GC_SHFT + 1))
3501 +
3502 +static int bimc_div(int64_t *a, uint32_t b)
3503 +{
3504 + if ((*a > 0) && (*a < b)) {
3505 + *a = 0;
3506 + return 1;
3507 + } else {
3508 + return do_div(*a, b);
3509 + }
3510 +}
3511 +
3512 +#define ENABLE(val) ((val) == 1 ? 1 : 0)
3513 +void msm_bus_bimc_set_mas_clk_gate(struct msm_bus_bimc_info *binfo,
3514 + uint32_t mas_index, struct msm_bus_bimc_clk_gate *bgate)
3515 +{
3516 + uint32_t val, mask, reg_val;
3517 + void __iomem *addr;
3518 +
3519 + reg_val = readl_relaxed(M_CLK_CTRL_ADDR(binfo->base,
3520 + mas_index)) & M_CLK_CTRL_RMSK;
3521 + addr = M_CLK_CTRL_ADDR(binfo->base, mas_index);
3522 + mask = (M_CLK_CTRL_MAS_CLK_GATING_EN_BMSK |
3523 + M_CLK_CTRL_CORE_CLK_GATING_EN_BMSK);
3524 + val = (bgate->core_clk_gate_en <<
3525 + M_CLK_CTRL_MAS_CLK_GATING_EN_SHFT) |
3526 + bgate->port_clk_gate_en;
3527 + writel_relaxed(((reg_val & (~mask)) | (val & mask)), addr);
3528 + /* Ensure clock gating enable mask is set before exiting */
3529 + wmb();
3530 +}
3531 +
3532 +void msm_bus_bimc_arb_en(struct msm_bus_bimc_info *binfo,
3533 + uint32_t slv_index, bool en)
3534 +{
3535 + uint32_t reg_val, reg_mask_val, enable, val;
3536 +
3537 + reg_mask_val = (readl_relaxed(S_ARB_CONFIG_INFO_0_ADDR(binfo->
3538 + base, slv_index)) & S_ARB_CONFIG_INFO_0_FUNC_BMSK)
3539 + >> S_ARB_CONFIG_INFO_0_FUNC_SHFT;
3540 + enable = ENABLE(en);
3541 + val = enable << S_ARB_MODE_PRIO_RR_EN_SHFT;
3542 + if (reg_mask_val == BIMC_ARB_MODE_PRIORITY_RR) {
3543 + reg_val = readl_relaxed(S_ARB_CONFIG_INFO_0_ADDR(binfo->
3544 + base, slv_index)) & S_ARB_MODE_RMSK;
3545 + writel_relaxed(((reg_val & (~(S_ARB_MODE_PRIO_RR_EN_BMSK))) |
3546 + (val & S_ARB_MODE_PRIO_RR_EN_BMSK)),
3547 + S_ARB_MODE_ADDR(binfo->base, slv_index));
3548 + /* Ensure arbitration mode is set before returning */
3549 + wmb();
3550 + }
3551 +}
3552 +
3553 +static void set_qos_mode(void __iomem *baddr, uint32_t index, uint32_t val0,
3554 + uint32_t val1, uint32_t val2)
3555 +{
3556 + uint32_t reg_val, val;
3557 +
3558 + reg_val = readl_relaxed(M_PRIOLVL_OVERRIDE_ADDR(baddr,
3559 + index)) & M_PRIOLVL_OVERRIDE_RMSK;
3560 + val = val0 << M_PRIOLVL_OVERRIDE_OVERRIDE_PRIOLVL_SHFT;
3561 + writel_relaxed(((reg_val & ~(M_PRIOLVL_OVERRIDE_OVERRIDE_PRIOLVL_BMSK))
3562 + | (val & M_PRIOLVL_OVERRIDE_OVERRIDE_PRIOLVL_BMSK)),
3563 + M_PRIOLVL_OVERRIDE_ADDR(baddr, index));
3564 + reg_val = readl_relaxed(M_RD_CMD_OVERRIDE_ADDR(baddr, index)) &
3565 + M_RD_CMD_OVERRIDE_RMSK;
3566 + val = val1 << M_RD_CMD_OVERRIDE_OVERRIDE_AREQPRIO_SHFT;
3567 + writel_relaxed(((reg_val & ~(M_RD_CMD_OVERRIDE_OVERRIDE_AREQPRIO_BMSK
3568 + )) | (val & M_RD_CMD_OVERRIDE_OVERRIDE_AREQPRIO_BMSK)),
3569 + M_RD_CMD_OVERRIDE_ADDR(baddr, index));
3570 + reg_val = readl_relaxed(M_WR_CMD_OVERRIDE_ADDR(baddr, index)) &
3571 + M_WR_CMD_OVERRIDE_RMSK;
3572 + val = val2 << M_WR_CMD_OVERRIDE_OVERRIDE_AREQPRIO_SHFT;
3573 + writel_relaxed(((reg_val & ~(M_WR_CMD_OVERRIDE_OVERRIDE_AREQPRIO_BMSK
3574 + )) | (val & M_WR_CMD_OVERRIDE_OVERRIDE_AREQPRIO_BMSK)),
3575 + M_WR_CMD_OVERRIDE_ADDR(baddr, index));
3576 + /* Ensure the priority register writes go through */
3577 + wmb();
3578 +}
3579 +
3580 +static void msm_bus_bimc_set_qos_mode(void __iomem *base,
3581 + uint32_t mas_index, uint8_t qmode_sel)
3582 +{
3583 + uint32_t reg_val, val;
3584 +
3585 + switch (qmode_sel) {
3586 + case BIMC_QOS_MODE_FIXED:
3587 + reg_val = readl_relaxed(M_BKE_EN_ADDR(base,
3588 + mas_index));
3589 + writel_relaxed((reg_val & (~M_BKE_EN_EN_BMSK)),
3590 + M_BKE_EN_ADDR(base, mas_index));
3591 + /* Ensure that the book-keeping register writes
3592 + * go through before setting QoS mode.
3593 + * QoS mode registers might write beyond 1K
3594 + * boundary in future
3595 + */
3596 + wmb();
3597 + set_qos_mode(base, mas_index, 1, 1, 1);
3598 + break;
3599 +
3600 + case BIMC_QOS_MODE_BYPASS:
3601 + reg_val = readl_relaxed(M_BKE_EN_ADDR(base,
3602 + mas_index));
3603 + writel_relaxed((reg_val & (~M_BKE_EN_EN_BMSK)),
3604 + M_BKE_EN_ADDR(base, mas_index));
3605 + /* Ensure that the book-keeping register writes
3606 + * go through before setting QoS mode.
3607 + * QoS mode registers might write beyond 1K
3608 + * boundary in future
3609 + */
3610 + wmb();
3611 + set_qos_mode(base, mas_index, 0, 0, 0);
3612 + break;
3613 +
3614 + case BIMC_QOS_MODE_REGULATOR:
3615 + case BIMC_QOS_MODE_LIMITER:
3616 + set_qos_mode(base, mas_index, 0, 0, 0);
3617 + reg_val = readl_relaxed(M_BKE_EN_ADDR(base,
3618 + mas_index));
3619 + val = 1 << M_BKE_EN_EN_SHFT;
3620 + /* Ensure that the book-keeping register writes
3621 + * go through before setting QoS mode.
3622 + * QoS mode registers might write beyond 1K
3623 + * boundary in future
3624 + */
3625 + wmb();
3626 + writel_relaxed(((reg_val & (~M_BKE_EN_EN_BMSK)) | (val &
3627 + M_BKE_EN_EN_BMSK)), M_BKE_EN_ADDR(base,
3628 + mas_index));
3629 + break;
3630 + default:
3631 + break;
3632 + }
3633 +}
3634 +
3635 +static void set_qos_prio_rl(void __iomem *addr, uint32_t rmsk,
3636 + uint8_t index, struct msm_bus_bimc_qos_mode *qmode)
3637 +{
3638 + uint32_t reg_val, val0, val;
3639 +
3640 + /* Note, addr is already passed with right mas_index */
3641 + reg_val = readl_relaxed(addr) & rmsk;
3642 + val0 = BKE_HEALTH_VAL(qmode->rl.qhealth[index].limit_commands,
3643 + qmode->rl.qhealth[index].areq_prio,
3644 + qmode->rl.qhealth[index].prio_level);
3645 + val = ((reg_val & (~(BKE_HEALTH_MASK))) | (val0 & BKE_HEALTH_MASK));
3646 + writel_relaxed(val, addr);
3647 + /* Ensure that priority for regulator/limiter modes are
3648 + * set before returning
3649 + */
3650 + wmb();
3651 +
3652 +}
3653 +
3654 +static void msm_bus_bimc_set_qos_prio(void __iomem *base,
3655 + uint32_t mas_index, uint8_t qmode_sel,
3656 + struct msm_bus_bimc_qos_mode *qmode)
3657 +{
3658 + uint32_t reg_val, val;
3659 +
3660 + switch (qmode_sel) {
3661 + case BIMC_QOS_MODE_FIXED:
3662 + reg_val = readl_relaxed(M_PRIOLVL_OVERRIDE_ADDR(
3663 + base, mas_index)) & M_PRIOLVL_OVERRIDE_RMSK;
3664 + val = qmode->fixed.prio_level <<
3665 + M_PRIOLVL_OVERRIDE_SHFT;
3666 + writel_relaxed(((reg_val &
3667 + ~(M_PRIOLVL_OVERRIDE_BMSK)) | (val
3668 + & M_PRIOLVL_OVERRIDE_BMSK)),
3669 + M_PRIOLVL_OVERRIDE_ADDR(base, mas_index));
3670 +
3671 + reg_val = readl_relaxed(M_RD_CMD_OVERRIDE_ADDR(
3672 + base, mas_index)) & M_RD_CMD_OVERRIDE_RMSK;
3673 + val = qmode->fixed.areq_prio_rd <<
3674 + M_RD_CMD_OVERRIDE_AREQPRIO_SHFT;
3675 + writel_relaxed(((reg_val & ~(M_RD_CMD_OVERRIDE_AREQPRIO_BMSK))
3676 + | (val & M_RD_CMD_OVERRIDE_AREQPRIO_BMSK)),
3677 + M_RD_CMD_OVERRIDE_ADDR(base, mas_index));
3678 +
3679 + reg_val = readl_relaxed(M_WR_CMD_OVERRIDE_ADDR(
3680 + base, mas_index)) & M_WR_CMD_OVERRIDE_RMSK;
3681 + val = qmode->fixed.areq_prio_wr <<
3682 + M_WR_CMD_OVERRIDE_AREQPRIO_SHFT;
3683 + writel_relaxed(((reg_val & ~(M_WR_CMD_OVERRIDE_AREQPRIO_BMSK))
3684 + | (val & M_WR_CMD_OVERRIDE_AREQPRIO_BMSK)),
3685 + M_WR_CMD_OVERRIDE_ADDR(base, mas_index));
3686 + /* Ensure that fixed mode register writes go through
3687 + * before returning
3688 + */
3689 + wmb();
3690 + break;
3691 +
3692 + case BIMC_QOS_MODE_REGULATOR:
3693 + case BIMC_QOS_MODE_LIMITER:
3694 + set_qos_prio_rl(M_BKE_HEALTH_3_CONFIG_ADDR(base,
3695 + mas_index), M_BKE_HEALTH_3_CONFIG_RMSK, 3, qmode);
3696 + set_qos_prio_rl(M_BKE_HEALTH_2_CONFIG_ADDR(base,
3697 + mas_index), M_BKE_HEALTH_2_CONFIG_RMSK, 2, qmode);
3698 + set_qos_prio_rl(M_BKE_HEALTH_1_CONFIG_ADDR(base,
3699 + mas_index), M_BKE_HEALTH_1_CONFIG_RMSK, 1, qmode);
3700 + set_qos_prio_rl(M_BKE_HEALTH_0_CONFIG_ADDR(base,
3701 + mas_index), M_BKE_HEALTH_0_CONFIG_RMSK, 0 , qmode);
3702 + break;
3703 + case BIMC_QOS_MODE_BYPASS:
3704 + default:
3705 + break;
3706 + }
3707 +}
3708 +
3709 +static void set_qos_bw_regs(void __iomem *baddr, uint32_t mas_index,
3710 + int32_t th, int32_t tm, int32_t tl, uint32_t gp,
3711 + uint32_t gc)
3712 +{
3713 + int32_t reg_val, val;
3714 + int32_t bke_reg_val;
3715 + int16_t val2;
3716 +
3717 + /* Disable BKE before writing to registers as per spec */
3718 + bke_reg_val = readl_relaxed(M_BKE_EN_ADDR(baddr, mas_index));
3719 + writel_relaxed((bke_reg_val & ~(M_BKE_EN_EN_BMSK)),
3720 + M_BKE_EN_ADDR(baddr, mas_index));
3721 +
3722 + /* Write values of registers calculated */
3723 + reg_val = readl_relaxed(M_BKE_GP_ADDR(baddr, mas_index))
3724 + & M_BKE_GP_RMSK;
3725 + val = gp << M_BKE_GP_GP_SHFT;
3726 + writel_relaxed(((reg_val & ~(M_BKE_GP_GP_BMSK)) | (val &
3727 + M_BKE_GP_GP_BMSK)), M_BKE_GP_ADDR(baddr, mas_index));
3728 +
3729 + reg_val = readl_relaxed(M_BKE_GC_ADDR(baddr, mas_index)) &
3730 + M_BKE_GC_RMSK;
3731 + val = gc << M_BKE_GC_GC_SHFT;
3732 + writel_relaxed(((reg_val & ~(M_BKE_GC_GC_BMSK)) | (val &
3733 + M_BKE_GC_GC_BMSK)), M_BKE_GC_ADDR(baddr, mas_index));
3734 +
3735 + reg_val = readl_relaxed(M_BKE_THH_ADDR(baddr, mas_index)) &
3736 + M_BKE_THH_RMSK;
3737 + val = th << M_BKE_THH_THRESH_SHFT;
3738 + writel_relaxed(((reg_val & ~(M_BKE_THH_THRESH_BMSK)) | (val &
3739 + M_BKE_THH_THRESH_BMSK)), M_BKE_THH_ADDR(baddr, mas_index));
3740 +
3741 + reg_val = readl_relaxed(M_BKE_THM_ADDR(baddr, mas_index)) &
3742 + M_BKE_THM_RMSK;
3743 + val2 = tm << M_BKE_THM_THRESH_SHFT;
3744 + writel_relaxed(((reg_val & ~(M_BKE_THM_THRESH_BMSK)) | (val2 &
3745 + M_BKE_THM_THRESH_BMSK)), M_BKE_THM_ADDR(baddr, mas_index));
3746 +
3747 + reg_val = readl_relaxed(M_BKE_THL_ADDR(baddr, mas_index)) &
3748 + M_BKE_THL_RMSK;
3749 + val2 = tl << M_BKE_THL_THRESH_SHFT;
3750 + writel_relaxed(((reg_val & ~(M_BKE_THL_THRESH_BMSK)) |
3751 + (val2 & M_BKE_THL_THRESH_BMSK)), M_BKE_THL_ADDR(baddr,
3752 + mas_index));
3753 +
3754 + /* Ensure that all bandwidth register writes have completed
3755 + * before returning
3756 + */
3757 + wmb();
3758 +}
3759 +
3760 +static void msm_bus_bimc_set_qos_bw(void __iomem *base, uint32_t qos_freq,
3761 + uint32_t mas_index, struct msm_bus_bimc_qos_bw *qbw)
3762 +{
3763 + uint32_t bke_en;
3764 +
3765 + /* Validate QOS Frequency */
3766 + if (qos_freq == 0) {
3767 + MSM_BUS_DBG("Zero frequency\n");
3768 + return;
3769 + }
3770 +
3771 + /* Get enable bit for BKE before programming the period */
3772 + bke_en = (readl_relaxed(M_BKE_EN_ADDR(base, mas_index)) &
3773 + M_BKE_EN_EN_BMSK) >> M_BKE_EN_EN_SHFT;
3774 +
3775 + /* Only calculate if there's a requested bandwidth and window */
3776 + if (qbw->bw && qbw->ws) {
3777 + int64_t th, tm, tl;
3778 + uint32_t gp, gc;
3779 + int64_t gp_nominal, gp_required, gp_calc, data, temp;
3780 + int64_t win = qbw->ws * qos_freq;
3781 + temp = win;
3782 + /*
3783 + * Calculate nominal grant period defined by requested
3784 + * window size.
3785 + * Ceil this value to max grant period.
3786 + */
3787 + bimc_div(&temp, 1000000);
3788 + gp_nominal = min_t(uint64_t, MAX_GRANT_PERIOD, temp);
3789 + /*
3790 + * Calculate max window size, defined by bw request.
3791 + * Units: (KHz, MB/s)
3792 + */
3793 + gp_calc = MAX_GC * qos_freq * 1000;
3794 + gp_required = gp_calc;
3795 + bimc_div(&gp_required, qbw->bw);
3796 +
3797 + /* User min of two grant periods */
3798 + gp = min_t(int64_t, gp_nominal, gp_required);
3799 +
3800 + /* Calculate bandwith in grants and ceil. */
3801 + temp = qbw->bw * gp;
3802 + data = qos_freq * 1000;
3803 + bimc_div(&temp, data);
3804 + gc = min_t(int64_t, MAX_GC, temp);
3805 +
3806 + /* Calculate thresholds */
3807 + th = qbw->bw - qbw->thh;
3808 + tm = qbw->bw - qbw->thm;
3809 + tl = qbw->bw - qbw->thl;
3810 +
3811 + th = th * gp;
3812 + bimc_div(&th, data);
3813 + tm = tm * gp;
3814 + bimc_div(&tm, data);
3815 + tl = tl * gp;
3816 + bimc_div(&tl, data);
3817 +
3818 + MSM_BUS_DBG("BIMC: BW: mas_index: %d, th: %llu tm: %llu\n",
3819 + mas_index, th, tm);
3820 + MSM_BUS_DBG("BIMC: tl: %llu gp:%u gc: %u bke_en: %u\n",
3821 + tl, gp, gc, bke_en);
3822 + set_qos_bw_regs(base, mas_index, th, tm, tl, gp, gc);
3823 + } else
3824 + /* Clear bandwidth registers */
3825 + set_qos_bw_regs(base, mas_index, 0, 0, 0, 0, 0);
3826 +}
3827 +
3828 +static int msm_bus_bimc_allocate_commit_data(struct msm_bus_fabric_registration
3829 + *fab_pdata, void **cdata, int ctx)
3830 +{
3831 + struct msm_bus_bimc_commit **cd = (struct msm_bus_bimc_commit **)cdata;
3832 + struct msm_bus_bimc_info *binfo =
3833 + (struct msm_bus_bimc_info *)fab_pdata->hw_data;
3834 +
3835 + MSM_BUS_DBG("Allocating BIMC commit data\n");
3836 + *cd = kzalloc(sizeof(struct msm_bus_bimc_commit), GFP_KERNEL);
3837 + if (!*cd) {
3838 + MSM_BUS_DBG("Couldn't alloc mem for cdata\n");
3839 + return -ENOMEM;
3840 + }
3841 +
3842 + (*cd)->mas = binfo->cdata[ctx].mas;
3843 + (*cd)->slv = binfo->cdata[ctx].slv;
3844 +
3845 + return 0;
3846 +}
3847 +
3848 +static void *msm_bus_bimc_allocate_bimc_data(struct platform_device *pdev,
3849 + struct msm_bus_fabric_registration *fab_pdata)
3850 +{
3851 + struct resource *bimc_mem;
3852 + struct resource *bimc_io;
3853 + struct msm_bus_bimc_info *binfo;
3854 + int i;
3855 +
3856 + MSM_BUS_DBG("Allocating BIMC data\n");
3857 + binfo = kzalloc(sizeof(struct msm_bus_bimc_info), GFP_KERNEL);
3858 + if (!binfo) {
3859 + WARN(!binfo, "Couldn't alloc mem for bimc_info\n");
3860 + return NULL;
3861 + }
3862 +
3863 + binfo->qos_freq = fab_pdata->qos_freq;
3864 +
3865 + binfo->params.nmasters = fab_pdata->nmasters;
3866 + binfo->params.nslaves = fab_pdata->nslaves;
3867 + binfo->params.bus_id = fab_pdata->id;
3868 +
3869 + for (i = 0; i < NUM_CTX; i++) {
3870 + binfo->cdata[i].mas = kzalloc(sizeof(struct
3871 + msm_bus_node_hw_info) * fab_pdata->nmasters * 2,
3872 + GFP_KERNEL);
3873 + if (!binfo->cdata[i].mas) {
3874 + MSM_BUS_ERR("Couldn't alloc mem for bimc master hw\n");
3875 + kfree(binfo);
3876 + return NULL;
3877 + }
3878 +
3879 + binfo->cdata[i].slv = kzalloc(sizeof(struct
3880 + msm_bus_node_hw_info) * fab_pdata->nslaves * 2,
3881 + GFP_KERNEL);
3882 + if (!binfo->cdata[i].slv) {
3883 + MSM_BUS_DBG("Couldn't alloc mem for bimc slave hw\n");
3884 + kfree(binfo->cdata[i].mas);
3885 + kfree(binfo);
3886 + return NULL;
3887 + }
3888 + }
3889 +
3890 + if (fab_pdata->virt) {
3891 + MSM_BUS_DBG("Don't get memory regions for virtual fabric\n");
3892 + goto skip_mem;
3893 + }
3894 +
3895 + bimc_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
3896 + if (!bimc_mem) {
3897 + MSM_BUS_ERR("Cannot get BIMC Base address\n");
3898 + kfree(binfo);
3899 + return NULL;
3900 + }
3901 +
3902 + bimc_io = request_mem_region(bimc_mem->start,
3903 + resource_size(bimc_mem), pdev->name);
3904 + if (!bimc_io) {
3905 + MSM_BUS_ERR("BIMC memory unavailable\n");
3906 + kfree(binfo);
3907 + return NULL;
3908 + }
3909 +
3910 + binfo->base = ioremap(bimc_mem->start, resource_size(bimc_mem));
3911 + if (!binfo->base) {
3912 + MSM_BUS_ERR("IOremap failed for BIMC!\n");
3913 + release_mem_region(bimc_mem->start, resource_size(bimc_mem));
3914 + kfree(binfo);
3915 + return NULL;
3916 + }
3917 +
3918 +skip_mem:
3919 + fab_pdata->hw_data = (void *)binfo;
3920 + return (void *)binfo;
3921 +}
3922 +
3923 +static void free_commit_data(void *cdata)
3924 +{
3925 + struct msm_bus_bimc_commit *cd = (struct msm_bus_bimc_commit *)cdata;
3926 +
3927 + kfree(cd->mas);
3928 + kfree(cd->slv);
3929 + kfree(cd);
3930 +}
3931 +
3932 +static void bke_switch(
3933 + void __iomem *baddr, uint32_t mas_index, bool req, int mode)
3934 +{
3935 + uint32_t reg_val, val, cur_val;
3936 +
3937 + val = req << M_BKE_EN_EN_SHFT;
3938 + reg_val = readl_relaxed(M_BKE_EN_ADDR(baddr, mas_index));
3939 + cur_val = reg_val & M_BKE_EN_RMSK;
3940 + if (val == cur_val)
3941 + return;
3942 +
3943 + if (!req && mode == BIMC_QOS_MODE_FIXED)
3944 + set_qos_mode(baddr, mas_index, 1, 1, 1);
3945 +
3946 + writel_relaxed(((reg_val & ~(M_BKE_EN_EN_BMSK)) | (val &
3947 + M_BKE_EN_EN_BMSK)), M_BKE_EN_ADDR(baddr, mas_index));
3948 + /* Make sure BKE on/off goes through before changing priorities */
3949 + wmb();
3950 +
3951 + if (req)
3952 + set_qos_mode(baddr, mas_index, 0, 0, 0);
3953 +}
3954 +
3955 +static void bimc_set_static_qos_bw(void __iomem *base, unsigned int qos_freq,
3956 + int mport, struct msm_bus_bimc_qos_bw *qbw)
3957 +{
3958 + int32_t bw_mbps, thh = 0, thm, thl, gc;
3959 + int32_t gp;
3960 + u64 temp;
3961 +
3962 + if (qos_freq == 0) {
3963 + MSM_BUS_DBG("No QoS Frequency.\n");
3964 + return;
3965 + }
3966 +
3967 + if (!(qbw->bw && qbw->gp)) {
3968 + MSM_BUS_DBG("No QoS Bandwidth or Window size\n");
3969 + return;
3970 + }
3971 +
3972 + /* Convert bandwidth to MBPS */
3973 + temp = qbw->bw;
3974 + bimc_div(&temp, 1000000);
3975 + bw_mbps = temp;
3976 +
3977 + /* Grant period in clock cycles
3978 + * Grant period from bandwidth structure
3979 + * is in nano seconds, QoS freq is in KHz.
3980 + * Divide by 1000 to get clock cycles.
3981 + */
3982 + gp = (qos_freq * qbw->gp) / (1000 * NSEC_PER_USEC);
3983 +
3984 + /* Grant count = BW in MBps * Grant period
3985 + * in micro seconds
3986 + */
3987 + gc = bw_mbps * (qbw->gp / NSEC_PER_USEC);
3988 + gc = min(gc, MAX_GC);
3989 +
3990 + /* Medium threshold = -((Medium Threshold percentage *
3991 + * Grant count) / 100)
3992 + */
3993 + thm = -((qbw->thmp * gc) / 100);
3994 + qbw->thm = thm;
3995 +
3996 + /* Low threshold = -(Grant count) */
3997 + thl = -gc;
3998 + qbw->thl = thl;
3999 +
4000 + MSM_BUS_DBG("%s: BKE parameters: gp %d, gc %d, thm %d thl %d thh %d",
4001 + __func__, gp, gc, thm, thl, thh);
4002 +
4003 + trace_bus_bke_params(gc, gp, thl, thm, thl);
4004 + set_qos_bw_regs(base, mport, thh, thm, thl, gp, gc);
4005 +}
4006 +
4007 +static void msm_bus_bimc_config_master(
4008 + struct msm_bus_fabric_registration *fab_pdata,
4009 + struct msm_bus_inode_info *info,
4010 + uint64_t req_clk, uint64_t req_bw)
4011 +{
4012 + int mode, i, ports;
4013 + struct msm_bus_bimc_info *binfo;
4014 + uint64_t bw = 0;
4015 +
4016 + binfo = (struct msm_bus_bimc_info *)fab_pdata->hw_data;
4017 + ports = info->node_info->num_mports;
4018 +
4019 + /**
4020 + * Here check the details of dual configuration.
4021 + * Take actions based on different modes.
4022 + * Check for threshold if limiter mode, etc.
4023 + */
4024 +
4025 + if (req_clk <= info->node_info->th[0]) {
4026 + mode = info->node_info->mode;
4027 + bw = info->node_info->bimc_bw[0];
4028 + } else if ((info->node_info->num_thresh > 1) &&
4029 + (req_clk <= info->node_info->th[1])) {
4030 + mode = info->node_info->mode;
4031 + bw = info->node_info->bimc_bw[1];
4032 + } else
4033 + mode = info->node_info->mode_thresh;
4034 +
4035 + switch (mode) {
4036 + case BIMC_QOS_MODE_BYPASS:
4037 + case BIMC_QOS_MODE_FIXED:
4038 + for (i = 0; i < ports; i++)
4039 + bke_switch(binfo->base, info->node_info->qport[i],
4040 + BKE_OFF, mode);
4041 + break;
4042 + case BIMC_QOS_MODE_REGULATOR:
4043 + case BIMC_QOS_MODE_LIMITER:
4044 + for (i = 0; i < ports; i++) {
4045 + /* If not in fixed mode, update bandwidth */
4046 + if ((info->node_info->cur_lim_bw != bw)
4047 + && (mode != BIMC_QOS_MODE_FIXED)) {
4048 + struct msm_bus_bimc_qos_bw qbw;
4049 + qbw.ws = info->node_info->ws;
4050 + qbw.bw = bw;
4051 + qbw.gp = info->node_info->bimc_gp;
4052 + qbw.thmp = info->node_info->bimc_thmp;
4053 + bimc_set_static_qos_bw(binfo->base,
4054 + binfo->qos_freq,
4055 + info->node_info->qport[i], &qbw);
4056 + info->node_info->cur_lim_bw = bw;
4057 + MSM_BUS_DBG("%s: Qos is %d reqclk %llu bw %llu",
4058 + __func__, mode, req_clk, bw);
4059 + }
4060 + bke_switch(binfo->base, info->node_info->qport[i],
4061 + BKE_ON, mode);
4062 + }
4063 + break;
4064 + default:
4065 + break;
4066 + }
4067 +}
4068 +
4069 +static void msm_bus_bimc_update_bw(struct msm_bus_inode_info *hop,
4070 + struct msm_bus_inode_info *info,
4071 + struct msm_bus_fabric_registration *fab_pdata,
4072 + void *sel_cdata, int *master_tiers,
4073 + int64_t add_bw)
4074 +{
4075 + struct msm_bus_bimc_info *binfo;
4076 + struct msm_bus_bimc_qos_bw qbw;
4077 + int i;
4078 + int64_t bw;
4079 + int ports = info->node_info->num_mports;
4080 + struct msm_bus_bimc_commit *sel_cd =
4081 + (struct msm_bus_bimc_commit *)sel_cdata;
4082 +
4083 + MSM_BUS_DBG("BIMC: Update bw for ID %d, with IID: %d: %lld\n",
4084 + info->node_info->id, info->node_info->priv_id, add_bw);
4085 +
4086 + binfo = (struct msm_bus_bimc_info *)fab_pdata->hw_data;
4087 +
4088 + if (info->node_info->num_mports == 0) {
4089 + MSM_BUS_DBG("BIMC: Skip Master BW\n");
4090 + goto skip_mas_bw;
4091 + }
4092 +
4093 + ports = info->node_info->num_mports;
4094 + bw = INTERLEAVED_BW(fab_pdata, add_bw, ports);
4095 +
4096 + for (i = 0; i < ports; i++) {
4097 + sel_cd->mas[info->node_info->masterp[i]].bw += bw;
4098 + sel_cd->mas[info->node_info->masterp[i]].hw_id =
4099 + info->node_info->mas_hw_id;
4100 + MSM_BUS_DBG("BIMC: Update mas_bw for ID: %d -> %llu\n",
4101 + info->node_info->priv_id,
4102 + sel_cd->mas[info->node_info->masterp[i]].bw);
4103 + if (info->node_info->hw_sel == MSM_BUS_RPM)
4104 + sel_cd->mas[info->node_info->masterp[i]].dirty = 1;
4105 + else {
4106 + if (!info->node_info->qport) {
4107 + MSM_BUS_DBG("No qos ports to update!\n");
4108 + break;
4109 + }
4110 + if (!(info->node_info->mode == BIMC_QOS_MODE_REGULATOR)
4111 + || (info->node_info->mode ==
4112 + BIMC_QOS_MODE_LIMITER)) {
4113 + MSM_BUS_DBG("Skip QoS reg programming\n");
4114 + break;
4115 + }
4116 +
4117 + MSM_BUS_DBG("qport: %d\n", info->node_info->qport[i]);
4118 + qbw.bw = sel_cd->mas[info->node_info->masterp[i]].bw;
4119 + qbw.ws = info->node_info->ws;
4120 + /* Threshold low = 90% of bw */
4121 + qbw.thl = div_s64((90 * bw), 100);
4122 + /* Threshold medium = bw */
4123 + qbw.thm = bw;
4124 + /* Threshold high = 10% more than bw */
4125 + qbw.thh = div_s64((110 * bw), 100);
4126 + /* Check if info is a shared master.
4127 + * If it is, mark it dirty
4128 + * If it isn't, then set QOS Bandwidth.
4129 + * Also if dual-conf is set, don't program bw regs.
4130 + **/
4131 + if (!info->node_info->dual_conf &&
4132 + ((info->node_info->mode == BIMC_QOS_MODE_LIMITER) ||
4133 + (info->node_info->mode == BIMC_QOS_MODE_REGULATOR)))
4134 + msm_bus_bimc_set_qos_bw(binfo->base,
4135 + binfo->qos_freq,
4136 + info->node_info->qport[i], &qbw);
4137 + }
4138 + }
4139 +
4140 +skip_mas_bw:
4141 + ports = hop->node_info->num_sports;
4142 + MSM_BUS_DBG("BIMC: ID: %d, Sports: %d\n", hop->node_info->priv_id,
4143 + ports);
4144 +
4145 + for (i = 0; i < ports; i++) {
4146 + sel_cd->slv[hop->node_info->slavep[i]].bw += add_bw;
4147 + sel_cd->slv[hop->node_info->slavep[i]].hw_id =
4148 + hop->node_info->slv_hw_id;
4149 + MSM_BUS_DBG("BIMC: Update slave_bw: ID: %d -> %llu\n",
4150 + hop->node_info->priv_id,
4151 + sel_cd->slv[hop->node_info->slavep[i]].bw);
4152 + MSM_BUS_DBG("BIMC: Update slave_bw: index: %d\n",
4153 + hop->node_info->slavep[i]);
4154 + /* Check if hop is a shared slave.
4155 + * If it is, mark it dirty
4156 + * If it isn't, then nothing to be done as the
4157 + * slaves are in bypass mode.
4158 + **/
4159 + if (hop->node_info->hw_sel == MSM_BUS_RPM) {
4160 + MSM_BUS_DBG("Slave dirty: %d, slavep: %d\n",
4161 + hop->node_info->priv_id,
4162 + hop->node_info->slavep[i]);
4163 + sel_cd->slv[hop->node_info->slavep[i]].dirty = 1;
4164 + }
4165 + }
4166 +}
4167 +
4168 +static int msm_bus_bimc_commit(struct msm_bus_fabric_registration
4169 + *fab_pdata, void *hw_data, void **cdata)
4170 +{
4171 + MSM_BUS_DBG("\nReached BIMC Commit\n");
4172 + msm_bus_remote_hw_commit(fab_pdata, hw_data, cdata);
4173 + return 0;
4174 +}
4175 +
4176 +static void msm_bus_bimc_config_limiter(
4177 + struct msm_bus_fabric_registration *fab_pdata,
4178 + struct msm_bus_inode_info *info)
4179 +{
4180 + struct msm_bus_bimc_info *binfo;
4181 + int mode, i, ports;
4182 +
4183 + binfo = (struct msm_bus_bimc_info *)fab_pdata->hw_data;
4184 + ports = info->node_info->num_mports;
4185 +
4186 + if (!info->node_info->qport) {
4187 + MSM_BUS_DBG("No QoS Ports to init\n");
4188 + return;
4189 + }
4190 +
4191 + if (info->cur_lim_bw)
4192 + mode = BIMC_QOS_MODE_LIMITER;
4193 + else
4194 + mode = info->node_info->mode;
4195 +
4196 + switch (mode) {
4197 + case BIMC_QOS_MODE_BYPASS:
4198 + case BIMC_QOS_MODE_FIXED:
4199 + for (i = 0; i < ports; i++)
4200 + bke_switch(binfo->base, info->node_info->qport[i],
4201 + BKE_OFF, mode);
4202 + break;
4203 + case BIMC_QOS_MODE_REGULATOR:
4204 + case BIMC_QOS_MODE_LIMITER:
4205 + if (info->cur_lim_bw != info->cur_prg_bw) {
4206 + MSM_BUS_DBG("Enabled BKE throttling node %d to %llu\n",
4207 + info->node_info->id, info->cur_lim_bw);
4208 + trace_bus_bimc_config_limiter(info->node_info->id,
4209 + info->cur_lim_bw);
4210 + for (i = 0; i < ports; i++) {
4211 + /* If not in fixed mode, update bandwidth */
4212 + struct msm_bus_bimc_qos_bw qbw;
4213 +
4214 + qbw.ws = info->node_info->ws;
4215 + qbw.bw = info->cur_lim_bw;
4216 + qbw.gp = info->node_info->bimc_gp;
4217 + qbw.thmp = info->node_info->bimc_thmp;
4218 + bimc_set_static_qos_bw(binfo->base,
4219 + binfo->qos_freq,
4220 + info->node_info->qport[i], &qbw);
4221 + bke_switch(binfo->base,
4222 + info->node_info->qport[i],
4223 + BKE_ON, mode);
4224 + info->cur_prg_bw = qbw.bw;
4225 + }
4226 + }
4227 + break;
4228 + default:
4229 + break;
4230 + }
4231 +}
4232 +
4233 +static void bimc_init_mas_reg(struct msm_bus_bimc_info *binfo,
4234 + struct msm_bus_inode_info *info,
4235 + struct msm_bus_bimc_qos_mode *qmode, int mode)
4236 +{
4237 + int i;
4238 +
4239 + switch (mode) {
4240 + case BIMC_QOS_MODE_FIXED:
4241 + qmode->fixed.prio_level = info->node_info->prio_lvl;
4242 + qmode->fixed.areq_prio_rd = info->node_info->prio_rd;
4243 + qmode->fixed.areq_prio_wr = info->node_info->prio_wr;
4244 + break;
4245 + case BIMC_QOS_MODE_LIMITER:
4246 + qmode->rl.qhealth[0].limit_commands = 1;
4247 + qmode->rl.qhealth[1].limit_commands = 0;
4248 + qmode->rl.qhealth[2].limit_commands = 0;
4249 + qmode->rl.qhealth[3].limit_commands = 0;
4250 + break;
4251 + default:
4252 + break;
4253 + }
4254 +
4255 + if (!info->node_info->qport) {
4256 + MSM_BUS_DBG("No QoS Ports to init\n");
4257 + return;
4258 + }
4259 +
4260 + for (i = 0; i < info->node_info->num_mports; i++) {
4261 + /* If not in bypass mode, update priority */
4262 + if (mode != BIMC_QOS_MODE_BYPASS) {
4263 + msm_bus_bimc_set_qos_prio(binfo->base,
4264 + info->node_info->
4265 + qport[i], mode, qmode);
4266 +
4267 + /* If not in fixed mode, update bandwidth */
4268 + if (mode != BIMC_QOS_MODE_FIXED) {
4269 + struct msm_bus_bimc_qos_bw qbw;
4270 + qbw.ws = info->node_info->ws;
4271 + qbw.bw = info->node_info->bimc_bw[0];
4272 + qbw.gp = info->node_info->bimc_gp;
4273 + qbw.thmp = info->node_info->bimc_thmp;
4274 + bimc_set_static_qos_bw(binfo->base,
4275 + binfo->qos_freq,
4276 + info->node_info->qport[i], &qbw);
4277 + }
4278 + }
4279 +
4280 + /* set mode */
4281 + msm_bus_bimc_set_qos_mode(binfo->base,
4282 + info->node_info->qport[i],
4283 + mode);
4284 + }
4285 +}
4286 +
4287 +static void init_health_regs(struct msm_bus_bimc_info *binfo,
4288 + struct msm_bus_inode_info *info,
4289 + struct msm_bus_bimc_qos_mode *qmode,
4290 + int mode)
4291 +{
4292 + int i;
4293 +
4294 + if (mode == BIMC_QOS_MODE_LIMITER) {
4295 + qmode->rl.qhealth[0].limit_commands = 1;
4296 + qmode->rl.qhealth[1].limit_commands = 0;
4297 + qmode->rl.qhealth[2].limit_commands = 0;
4298 + qmode->rl.qhealth[3].limit_commands = 0;
4299 +
4300 + if (!info->node_info->qport) {
4301 + MSM_BUS_DBG("No QoS Ports to init\n");
4302 + return;
4303 + }
4304 +
4305 + for (i = 0; i < info->node_info->num_mports; i++) {
4306 + /* If not in bypass mode, update priority */
4307 + if (mode != BIMC_QOS_MODE_BYPASS)
4308 + msm_bus_bimc_set_qos_prio(binfo->base,
4309 + info->node_info->qport[i], mode, qmode);
4310 + }
4311 + }
4312 +}
4313 +
4314 +
4315 +static int msm_bus_bimc_mas_init(struct msm_bus_bimc_info *binfo,
4316 + struct msm_bus_inode_info *info)
4317 +{
4318 + struct msm_bus_bimc_qos_mode *qmode;
4319 + qmode = kzalloc(sizeof(struct msm_bus_bimc_qos_mode),
4320 + GFP_KERNEL);
4321 + if (!qmode) {
4322 + MSM_BUS_WARN("Couldn't alloc prio data for node: %d\n",
4323 + info->node_info->id);
4324 + return -ENOMEM;
4325 + }
4326 +
4327 + info->hw_data = (void *)qmode;
4328 +
4329 + /**
4330 + * If the master supports dual configuration,
4331 + * configure registers for both modes
4332 + */
4333 + if (info->node_info->dual_conf)
4334 + bimc_init_mas_reg(binfo, info, qmode,
4335 + info->node_info->mode_thresh);
4336 + else if (info->node_info->nr_lim)
4337 + init_health_regs(binfo, info, qmode, BIMC_QOS_MODE_LIMITER);
4338 +
4339 + bimc_init_mas_reg(binfo, info, qmode, info->node_info->mode);
4340 + return 0;
4341 +}
4342 +
4343 +static void msm_bus_bimc_node_init(void *hw_data,
4344 + struct msm_bus_inode_info *info)
4345 +{
4346 + struct msm_bus_bimc_info *binfo =
4347 + (struct msm_bus_bimc_info *)hw_data;
4348 +
4349 + if (!IS_SLAVE(info->node_info->priv_id) &&
4350 + (info->node_info->hw_sel != MSM_BUS_RPM))
4351 + msm_bus_bimc_mas_init(binfo, info);
4352 +}
4353 +
4354 +static int msm_bus_bimc_port_halt(uint32_t haltid, uint8_t mport)
4355 +{
4356 + return 0;
4357 +}
4358 +
4359 +static int msm_bus_bimc_port_unhalt(uint32_t haltid, uint8_t mport)
4360 +{
4361 + return 0;
4362 +}
4363 +
4364 +static int msm_bus_bimc_limit_mport(struct msm_bus_node_device_type *info,
4365 + void __iomem *qos_base, uint32_t qos_off,
4366 + uint32_t qos_delta, uint32_t qos_freq,
4367 + bool enable_lim, u64 lim_bw)
4368 +{
4369 + int mode;
4370 + int i;
4371 +
4372 + if (ZERO_OR_NULL_PTR(info->node_info->qport)) {
4373 + MSM_BUS_DBG("No QoS Ports to limit\n");
4374 + return 0;
4375 + }
4376 +
4377 + if (enable_lim && lim_bw) {
4378 + mode = BIMC_QOS_MODE_LIMITER;
4379 +
4380 + if (!info->node_info->lim_bw) {
4381 + struct msm_bus_bimc_qos_mode qmode;
4382 + qmode.rl.qhealth[0].limit_commands = 1;
4383 + qmode.rl.qhealth[1].limit_commands = 0;
4384 + qmode.rl.qhealth[2].limit_commands = 0;
4385 + qmode.rl.qhealth[3].limit_commands = 0;
4386 +
4387 + for (i = 0; i < info->node_info->num_qports; i++) {
4388 + /* If not in bypass mode, update priority */
4389 + if (mode != BIMC_QOS_MODE_BYPASS)
4390 + msm_bus_bimc_set_qos_prio(qos_base,
4391 + info->node_info->qport[i], mode,
4392 + &qmode);
4393 + }
4394 + }
4395 +
4396 + for (i = 0; i < info->node_info->num_qports; i++) {
4397 + struct msm_bus_bimc_qos_bw qbw;
4398 + /* If not in fixed mode, update bandwidth */
4399 + if ((info->node_info->lim_bw != lim_bw)) {
4400 + qbw.ws = info->node_info->qos_params.ws;
4401 + qbw.bw = lim_bw;
4402 + qbw.gp = info->node_info->qos_params.gp;
4403 + qbw.thmp = info->node_info->qos_params.thmp;
4404 + bimc_set_static_qos_bw(qos_base, qos_freq,
4405 + info->node_info->qport[i], &qbw);
4406 + }
4407 + bke_switch(qos_base, info->node_info->qport[i],
4408 + BKE_ON, mode);
4409 + }
4410 + info->node_info->lim_bw = lim_bw;
4411 + } else {
4412 + mode = info->node_info->qos_params.mode;
4413 + for (i = 0; i < info->node_info->num_qports; i++) {
4414 + bke_switch(qos_base, info->node_info->qport[i],
4415 + BKE_OFF, mode);
4416 + }
4417 + }
4418 + info->node_info->qos_params.cur_mode = mode;
4419 + return 0;
4420 +}
4421 +
4422 +static bool msm_bus_bimc_update_bw_reg(int mode)
4423 +{
4424 + bool ret = false;
4425 +
4426 + if ((mode == BIMC_QOS_MODE_LIMITER)
4427 + || (mode == BIMC_QOS_MODE_REGULATOR))
4428 + ret = true;
4429 +
4430 + return ret;
4431 +}
4432 +
4433 +static int msm_bus_bimc_qos_init(struct msm_bus_node_device_type *info,
4434 + void __iomem *qos_base,
4435 + uint32_t qos_off, uint32_t qos_delta,
4436 + uint32_t qos_freq)
4437 +{
4438 + int i;
4439 + struct msm_bus_bimc_qos_mode qmode;
4440 +
4441 + switch (info->node_info->qos_params.mode) {
4442 + case BIMC_QOS_MODE_FIXED:
4443 + qmode.fixed.prio_level = info->node_info->qos_params.prio_lvl;
4444 + qmode.fixed.areq_prio_rd = info->node_info->qos_params.prio_rd;
4445 + qmode.fixed.areq_prio_wr = info->node_info->qos_params.prio_wr;
4446 + break;
4447 + case BIMC_QOS_MODE_LIMITER:
4448 + qmode.rl.qhealth[0].limit_commands = 1;
4449 + qmode.rl.qhealth[1].limit_commands = 0;
4450 + qmode.rl.qhealth[2].limit_commands = 0;
4451 + qmode.rl.qhealth[3].limit_commands = 0;
4452 + break;
4453 + default:
4454 + break;
4455 + }
4456 +
4457 + if (ZERO_OR_NULL_PTR(info->node_info->qport)) {
4458 + MSM_BUS_DBG("No QoS Ports to init\n");
4459 + return 0;
4460 + }
4461 +
4462 + for (i = 0; i < info->node_info->num_qports; i++) {
4463 + /* If not in bypass mode, update priority */
4464 + if (info->node_info->qos_params.mode != BIMC_QOS_MODE_BYPASS)
4465 + msm_bus_bimc_set_qos_prio(qos_base, info->node_info->
4466 + qport[i], info->node_info->qos_params.mode,
4467 + &qmode);
4468 +
4469 + /* set mode */
4470 + if (info->node_info->qos_params.mode == BIMC_QOS_MODE_LIMITER)
4471 + bke_switch(qos_base, info->node_info->qport[i],
4472 + BKE_OFF, BIMC_QOS_MODE_FIXED);
4473 + else
4474 + msm_bus_bimc_set_qos_mode(qos_base,
4475 + info->node_info->qport[i],
4476 + info->node_info->qos_params.mode);
4477 + }
4478 +
4479 + return 0;
4480 +}
4481 +
4482 +static int msm_bus_bimc_set_bw(struct msm_bus_node_device_type *dev,
4483 + void __iomem *qos_base, uint32_t qos_off,
4484 + uint32_t qos_delta, uint32_t qos_freq)
4485 +{
4486 + struct msm_bus_bimc_qos_bw qbw;
4487 + int i;
4488 + int64_t bw = 0;
4489 + int ret = 0;
4490 + struct msm_bus_node_info_type *info = dev->node_info;
4491 +
4492 + if (info && info->num_qports &&
4493 + ((info->qos_params.mode == BIMC_QOS_MODE_LIMITER) ||
4494 + (info->qos_params.mode == BIMC_QOS_MODE_REGULATOR))) {
4495 + bw = msm_bus_div64(info->num_qports,
4496 + dev->node_ab.ab[DUAL_CTX]);
4497 +
4498 + for (i = 0; i < info->num_qports; i++) {
4499 + MSM_BUS_DBG("BIMC: Update mas_bw for ID: %d -> %llu\n",
4500 + info->id, bw);
4501 +
4502 + if (!info->qport) {
4503 + MSM_BUS_DBG("No qos ports to update!\n");
4504 + break;
4505 + }
4506 +
4507 + qbw.bw = bw + info->qos_params.bw_buffer;
4508 + trace_bus_bimc_config_limiter(info->id, bw);
4509 +
4510 + /* Default to gp of 5us */
4511 + qbw.gp = (info->qos_params.gp ?
4512 + info->qos_params.gp : 5000);
4513 + /* Default to thmp of 50% */
4514 + qbw.thmp = (info->qos_params.thmp ?
4515 + info->qos_params.thmp : 50);
4516 + /*
4517 + * If the BW vote is 0 then set the QoS mode to
4518 + * Fixed.
4519 + */
4520 + if (bw) {
4521 + bimc_set_static_qos_bw(qos_base, qos_freq,
4522 + info->qport[i], &qbw);
4523 + bke_switch(qos_base, info->qport[i],
4524 + BKE_ON, info->qos_params.mode);
4525 + } else {
4526 + bke_switch(qos_base, info->qport[i],
4527 + BKE_OFF, BIMC_QOS_MODE_FIXED);
4528 + }
4529 + }
4530 + }
4531 + return ret;
4532 +}
4533 +
4534 +int msm_bus_bimc_hw_init(struct msm_bus_fabric_registration *pdata,
4535 + struct msm_bus_hw_algorithm *hw_algo)
4536 +{
4537 + /* Set interleaving to true by default */
4538 + MSM_BUS_DBG("\nInitializing BIMC...\n");
4539 + pdata->il_flag = true;
4540 + hw_algo->allocate_commit_data = msm_bus_bimc_allocate_commit_data;
4541 + hw_algo->allocate_hw_data = msm_bus_bimc_allocate_bimc_data;
4542 + hw_algo->node_init = msm_bus_bimc_node_init;
4543 + hw_algo->free_commit_data = free_commit_data;
4544 + hw_algo->update_bw = msm_bus_bimc_update_bw;
4545 + hw_algo->commit = msm_bus_bimc_commit;
4546 + hw_algo->port_halt = msm_bus_bimc_port_halt;
4547 + hw_algo->port_unhalt = msm_bus_bimc_port_unhalt;
4548 + hw_algo->config_master = msm_bus_bimc_config_master;
4549 + hw_algo->config_limiter = msm_bus_bimc_config_limiter;
4550 + hw_algo->update_bw_reg = msm_bus_bimc_update_bw_reg;
4551 + /* BIMC slaves are shared. Slave registers are set through RPM */
4552 + if (!pdata->ahb)
4553 + pdata->rpm_enabled = 1;
4554 + return 0;
4555 +}
4556 +
4557 +int msm_bus_bimc_set_ops(struct msm_bus_node_device_type *bus_dev)
4558 +{
4559 + if (!bus_dev)
4560 + return -ENODEV;
4561 + else {
4562 + bus_dev->fabdev->noc_ops.qos_init = msm_bus_bimc_qos_init;
4563 + bus_dev->fabdev->noc_ops.set_bw = msm_bus_bimc_set_bw;
4564 + bus_dev->fabdev->noc_ops.limit_mport = msm_bus_bimc_limit_mport;
4565 + bus_dev->fabdev->noc_ops.update_bw_reg =
4566 + msm_bus_bimc_update_bw_reg;
4567 + }
4568 + return 0;
4569 +}
4570 +EXPORT_SYMBOL(msm_bus_bimc_set_ops);
4571 --- /dev/null
4572 +++ b/drivers/bus/msm_bus/msm_bus_bimc.h
4573 @@ -0,0 +1,127 @@
4574 +/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
4575 + *
4576 + * This program is free software; you can redistribute it and/or modify
4577 + * it under the terms of the GNU General Public License version 2 and
4578 + * only version 2 as published by the Free Software Foundation.
4579 + *
4580 + * This program is distributed in the hope that it will be useful,
4581 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
4582 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4583 + * GNU General Public License for more details.
4584 + */
4585 +
4586 +#ifndef _ARCH_ARM_MACH_MSM_BUS_BIMC_H
4587 +#define _ARCH_ARM_MACH_MSM_BUS_BIMC_H
4588 +
4589 +struct msm_bus_bimc_params {
4590 + uint32_t bus_id;
4591 + uint32_t addr_width;
4592 + uint32_t data_width;
4593 + uint32_t nmasters;
4594 + uint32_t nslaves;
4595 +};
4596 +
4597 +struct msm_bus_bimc_commit {
4598 + struct msm_bus_node_hw_info *mas;
4599 + struct msm_bus_node_hw_info *slv;
4600 +};
4601 +
4602 +struct msm_bus_bimc_info {
4603 + void __iomem *base;
4604 + uint32_t base_addr;
4605 + uint32_t qos_freq;
4606 + struct msm_bus_bimc_params params;
4607 + struct msm_bus_bimc_commit cdata[NUM_CTX];
4608 +};
4609 +
4610 +struct msm_bus_bimc_node {
4611 + uint32_t conn_mask;
4612 + uint32_t data_width;
4613 + uint8_t slv_arb_mode;
4614 +};
4615 +
4616 +enum msm_bus_bimc_arb_mode {
4617 + BIMC_ARB_MODE_RR = 0,
4618 + BIMC_ARB_MODE_PRIORITY_RR,
4619 + BIMC_ARB_MODE_TIERED_RR,
4620 +};
4621 +
4622 +
4623 +enum msm_bus_bimc_interleave {
4624 + BIMC_INTERLEAVE_NONE = 0,
4625 + BIMC_INTERLEAVE_ODD,
4626 + BIMC_INTERLEAVE_EVEN,
4627 +};
4628 +
4629 +struct msm_bus_bimc_slave_seg {
4630 + bool enable;
4631 + uint64_t start_addr;
4632 + uint64_t seg_size;
4633 + uint8_t interleave;
4634 +};
4635 +
4636 +enum msm_bus_bimc_qos_mode_type {
4637 + BIMC_QOS_MODE_FIXED = 0,
4638 + BIMC_QOS_MODE_LIMITER,
4639 + BIMC_QOS_MODE_BYPASS,
4640 + BIMC_QOS_MODE_REGULATOR,
4641 +};
4642 +
4643 +struct msm_bus_bimc_qos_health {
4644 + bool limit_commands;
4645 + uint32_t areq_prio;
4646 + uint32_t prio_level;
4647 +};
4648 +
4649 +struct msm_bus_bimc_mode_fixed {
4650 + uint32_t prio_level;
4651 + uint32_t areq_prio_rd;
4652 + uint32_t areq_prio_wr;
4653 +};
4654 +
4655 +struct msm_bus_bimc_mode_rl {
4656 + uint8_t qhealthnum;
4657 + struct msm_bus_bimc_qos_health qhealth[4];
4658 +};
4659 +
4660 +struct msm_bus_bimc_qos_mode {
4661 + uint8_t mode;
4662 + struct msm_bus_bimc_mode_fixed fixed;
4663 + struct msm_bus_bimc_mode_rl rl;
4664 +};
4665 +
4666 +struct msm_bus_bimc_qos_bw {
4667 + uint64_t bw; /* bw is in Bytes/sec */
4668 + uint32_t ws; /* Window size in nano seconds*/
4669 + int64_t thh; /* Threshold high, bytes per second */
4670 + int64_t thm; /* Threshold medium, bytes per second */
4671 + int64_t thl; /* Threshold low, bytes per second */
4672 + u32 gp; /* Grant Period in micro seconds */
4673 + u32 thmp; /* Threshold medium in percentage */
4674 +};
4675 +
4676 +struct msm_bus_bimc_clk_gate {
4677 + bool core_clk_gate_en;
4678 + bool arb_clk_gate_en; /* For arbiter */
4679 + bool port_clk_gate_en; /* For regs on BIMC core clock */
4680 +};
4681 +
4682 +void msm_bus_bimc_set_slave_seg(struct msm_bus_bimc_info *binfo,
4683 + uint32_t slv_index, uint32_t seg_index,
4684 + struct msm_bus_bimc_slave_seg *bsseg);
4685 +void msm_bus_bimc_set_slave_clk_gate(struct msm_bus_bimc_info *binfo,
4686 + uint32_t slv_index, struct msm_bus_bimc_clk_gate *bgate);
4687 +void msm_bus_bimc_set_mas_clk_gate(struct msm_bus_bimc_info *binfo,
4688 + uint32_t mas_index, struct msm_bus_bimc_clk_gate *bgate);
4689 +void msm_bus_bimc_arb_en(struct msm_bus_bimc_info *binfo,
4690 + uint32_t slv_index, bool en);
4691 +void msm_bus_bimc_get_params(struct msm_bus_bimc_info *binfo,
4692 + struct msm_bus_bimc_params *params);
4693 +void msm_bus_bimc_get_mas_params(struct msm_bus_bimc_info *binfo,
4694 + uint32_t mas_index, struct msm_bus_bimc_node *mparams);
4695 +void msm_bus_bimc_get_slv_params(struct msm_bus_bimc_info *binfo,
4696 + uint32_t slv_index, struct msm_bus_bimc_node *sparams);
4697 +bool msm_bus_bimc_get_arb_en(struct msm_bus_bimc_info *binfo,
4698 + uint32_t slv_index);
4699 +
4700 +#endif /*_ARCH_ARM_MACH_MSM_BUS_BIMC_H*/
4701 --- /dev/null
4702 +++ b/drivers/bus/msm_bus/msm_bus_client_api.c
4703 @@ -0,0 +1,83 @@
4704 +/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
4705 + *
4706 + * This program is free software; you can redistribute it and/or modify
4707 + * it under the terms of the GNU General Public License version 2 and
4708 + * only version 2 as published by the Free Software Foundation.
4709 + *
4710 + * This program is distributed in the hope that it will be useful,
4711 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
4712 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4713 + * GNU General Public License for more details.
4714 + */
4715 +
4716 +#define pr_fmt(fmt) "AXI: %s(): " fmt, __func__
4717 +
4718 +#include <linux/kernel.h>
4719 +#include <linux/init.h>
4720 +#include <linux/list.h>
4721 +#include <linux/module.h>
4722 +#include <linux/slab.h>
4723 +#include <linux/mutex.h>
4724 +#include <linux/radix-tree.h>
4725 +#include <linux/clk.h>
4726 +#include "msm-bus.h"
4727 +#include "msm_bus_core.h"
4728 +
4729 +struct msm_bus_arb_ops arb_ops;
4730 +
4731 +/**
4732 + * msm_bus_scale_register_client() - Register the clients with the msm bus
4733 + * driver
4734 + * @pdata: Platform data of the client, containing src, dest, ab, ib.
4735 + * Return non-zero value in case of success, 0 in case of failure.
4736 + *
4737 + * Client data contains the vectors specifying arbitrated bandwidth (ab)
4738 + * and instantaneous bandwidth (ib) requested between a particular
4739 + * src and dest.
4740 + */
4741 +uint32_t msm_bus_scale_register_client(struct msm_bus_scale_pdata *pdata)
4742 +{
4743 + if (arb_ops.register_client)
4744 + return arb_ops.register_client(pdata);
4745 + else {
4746 + pr_err("%s: Bus driver not ready.",
4747 + __func__);
4748 + return 0;
4749 + }
4750 +}
4751 +EXPORT_SYMBOL(msm_bus_scale_register_client);
4752 +
4753 +/**
4754 + * msm_bus_scale_client_update_request() - Update the request for bandwidth
4755 + * from a particular client
4756 + *
4757 + * cl: Handle to the client
4758 + * index: Index into the vector, to which the bw and clock values need to be
4759 + * updated
4760 + */
4761 +int msm_bus_scale_client_update_request(uint32_t cl, unsigned int index)
4762 +{
4763 + if (arb_ops.update_request)
4764 + return arb_ops.update_request(cl, index);
4765 + else {
4766 + pr_err("%s: Bus driver not ready.",
4767 + __func__);
4768 + return -EPROBE_DEFER;
4769 + }
4770 +}
4771 +EXPORT_SYMBOL(msm_bus_scale_client_update_request);
4772 +
4773 +/**
4774 + * msm_bus_scale_unregister_client() - Unregister the client from the bus driver
4775 + * @cl: Handle to the client
4776 + */
4777 +void msm_bus_scale_unregister_client(uint32_t cl)
4778 +{
4779 + if (arb_ops.unregister_client)
4780 + arb_ops.unregister_client(cl);
4781 + else {
4782 + pr_err("%s: Bus driver not ready.",
4783 + __func__);
4784 + }
4785 +}
4786 +EXPORT_SYMBOL(msm_bus_scale_unregister_client);
4787 --- /dev/null
4788 +++ b/drivers/bus/msm_bus/msm_bus_core.c
4789 @@ -0,0 +1,125 @@
4790 +/* Copyright (c) 2010-2014, The Linux Foundation. All rights reserved.
4791 + *
4792 + * This program is free software; you can redistribute it and/or modify
4793 + * it under the terms of the GNU General Public License version 2 and
4794 + * only version 2 as published by the Free Software Foundation.
4795 + *
4796 + * This program is distributed in the hope that it will be useful,
4797 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
4798 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4799 + * GNU General Public License for more details.
4800 + */
4801 +
4802 +#define pr_fmt(fmt) "AXI: %s(): " fmt, __func__
4803 +
4804 +#include <linux/kernel.h>
4805 +#include <linux/init.h>
4806 +#include <linux/module.h>
4807 +#include <linux/slab.h>
4808 +#include <linux/mutex.h>
4809 +#include <linux/radix-tree.h>
4810 +#include <linux/clk.h>
4811 +#include "msm-bus-board.h"
4812 +#include "msm-bus.h"
4813 +#include "msm_bus_core.h"
4814 +
4815 +static atomic_t num_fab = ATOMIC_INIT(0);
4816 +
4817 +int msm_bus_get_num_fab(void)
4818 +{
4819 + return atomic_read(&num_fab);
4820 +}
4821 +
4822 +int msm_bus_device_match(struct device *dev, void *id)
4823 +{
4824 + struct msm_bus_fabric_device *fabdev = to_msm_bus_fabric_device(dev);
4825 +
4826 + if (!fabdev) {
4827 + MSM_BUS_WARN("Fabric %p returning 0\n", fabdev);
4828 + return 0;
4829 + }
4830 + return fabdev->id == *(int *)id;
4831 +}
4832 +
4833 +static void msm_bus_release(struct device *device)
4834 +{
4835 +}
4836 +
4837 +struct bus_type msm_bus_type = {
4838 + .name = "msm-bus-type",
4839 +};
4840 +EXPORT_SYMBOL(msm_bus_type);
4841 +
4842 +/**
4843 + * msm_bus_get_fabric_device() - This function is used to search for
4844 + * the fabric device on the bus
4845 + * @fabid: Fabric id
4846 + * Function returns: Pointer to the fabric device
4847 + */
4848 +struct msm_bus_fabric_device *msm_bus_get_fabric_device(int fabid)
4849 +{
4850 + struct device *dev;
4851 + struct msm_bus_fabric_device *fabric;
4852 + dev = bus_find_device(&msm_bus_type, NULL, (void *)&fabid,
4853 + msm_bus_device_match);
4854 + if (!dev)
4855 + return NULL;
4856 + fabric = to_msm_bus_fabric_device(dev);
4857 + return fabric;
4858 +}
4859 +
4860 +/**
4861 + * msm_bus_fabric_device_register() - Registers a fabric on msm bus
4862 + * @fabdev: Fabric device to be registered
4863 + */
4864 +int msm_bus_fabric_device_register(struct msm_bus_fabric_device *fabdev)
4865 +{
4866 + int ret = 0;
4867 + fabdev->dev.bus = &msm_bus_type;
4868 + fabdev->dev.release = msm_bus_release;
4869 + ret = dev_set_name(&fabdev->dev, fabdev->name);
4870 + if (ret) {
4871 + MSM_BUS_ERR("error setting dev name\n");
4872 + goto err;
4873 + }
4874 +
4875 + ret = device_register(&fabdev->dev);
4876 + if (ret < 0) {
4877 + MSM_BUS_ERR("error registering device%d %s\n",
4878 + ret, fabdev->name);
4879 + goto err;
4880 + }
4881 + atomic_inc(&num_fab);
4882 +err:
4883 + return ret;
4884 +}
4885 +
4886 +/**
4887 + * msm_bus_fabric_device_unregister() - Unregisters the fabric
4888 + * devices from the msm bus
4889 + */
4890 +void msm_bus_fabric_device_unregister(struct msm_bus_fabric_device *fabdev)
4891 +{
4892 + device_unregister(&fabdev->dev);
4893 + atomic_dec(&num_fab);
4894 +}
4895 +
4896 +static void __exit msm_bus_exit(void)
4897 +{
4898 + bus_unregister(&msm_bus_type);
4899 +}
4900 +
4901 +static int __init msm_bus_init(void)
4902 +{
4903 + int retval = 0;
4904 + retval = bus_register(&msm_bus_type);
4905 + if (retval)
4906 + MSM_BUS_ERR("bus_register error! %d\n",
4907 + retval);
4908 + return retval;
4909 +}
4910 +postcore_initcall(msm_bus_init);
4911 +module_exit(msm_bus_exit);
4912 +MODULE_LICENSE("GPL v2");
4913 +MODULE_VERSION("0.2");
4914 +MODULE_ALIAS("platform:msm_bus");
4915 --- /dev/null
4916 +++ b/drivers/bus/msm_bus/msm_bus_core.h
4917 @@ -0,0 +1,375 @@
4918 +/* Copyright (c) 2011-2014, The Linux Foundation. All rights reserved.
4919 + *
4920 + * This program is free software; you can redistribute it and/or modify
4921 + * it under the terms of the GNU General Public License version 2 and
4922 + * only version 2 as published by the Free Software Foundation.
4923 + *
4924 + * This program is distributed in the hope that it will be useful,
4925 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
4926 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4927 + * GNU General Public License for more details.
4928 + */
4929 +
4930 +#ifndef _ARCH_ARM_MACH_MSM_BUS_CORE_H
4931 +#define _ARCH_ARM_MACH_MSM_BUS_CORE_H
4932 +
4933 +#include <linux/types.h>
4934 +#include <linux/device.h>
4935 +#include <linux/radix-tree.h>
4936 +#include <linux/platform_device.h>
4937 +#include "msm-bus-board.h"
4938 +#include "msm-bus.h"
4939 +
4940 +#define MSM_BUS_DBG(msg, ...) \
4941 + pr_debug(msg, ## __VA_ARGS__)
4942 +#define MSM_BUS_ERR(msg, ...) \
4943 + pr_err(msg, ## __VA_ARGS__)
4944 +#define MSM_BUS_WARN(msg, ...) \
4945 + pr_warn(msg, ## __VA_ARGS__)
4946 +#define MSM_FAB_ERR(msg, ...) \
4947 + dev_err(&fabric->fabdev.dev, msg, ## __VA_ARGS__)
4948 +
4949 +#define IS_MASTER_VALID(mas) \
4950 + (((mas >= MSM_BUS_MASTER_FIRST) && (mas <= MSM_BUS_MASTER_LAST)) \
4951 + ? 1 : 0)
4952 +#define IS_SLAVE_VALID(slv) \
4953 + (((slv >= MSM_BUS_SLAVE_FIRST) && (slv <= MSM_BUS_SLAVE_LAST)) ? 1 : 0)
4954 +
4955 +#define INTERLEAVED_BW(fab_pdata, bw, ports) \
4956 + ((fab_pdata->il_flag) ? ((bw < 0) \
4957 + ? -msm_bus_div64((ports), (-bw)) : msm_bus_div64((ports), (bw))) : (bw))
4958 +#define INTERLEAVED_VAL(fab_pdata, n) \
4959 + ((fab_pdata->il_flag) ? (n) : 1)
4960 +#define KBTOB(a) (a * 1000ULL)
4961 +
4962 +enum msm_bus_dbg_op_type {
4963 + MSM_BUS_DBG_UNREGISTER = -2,
4964 + MSM_BUS_DBG_REGISTER,
4965 + MSM_BUS_DBG_OP = 1,
4966 +};
4967 +
4968 +enum msm_bus_hw_sel {
4969 + MSM_BUS_RPM = 0,
4970 + MSM_BUS_NOC,
4971 + MSM_BUS_BIMC,
4972 +};
4973 +
4974 +struct msm_bus_arb_ops {
4975 + uint32_t (*register_client)(struct msm_bus_scale_pdata *pdata);
4976 + int (*update_request)(uint32_t cl, unsigned int index);
4977 + void (*unregister_client)(uint32_t cl);
4978 +};
4979 +
4980 +enum {
4981 + SLAVE_NODE,
4982 + MASTER_NODE,
4983 + CLK_NODE,
4984 + NR_LIM_NODE,
4985 +};
4986 +
4987 +
4988 +extern struct bus_type msm_bus_type;
4989 +extern struct msm_bus_arb_ops arb_ops;
4990 +extern void msm_bus_arb_setops_legacy(struct msm_bus_arb_ops *arb_ops);
4991 +
4992 +struct msm_bus_node_info {
4993 + unsigned int id;
4994 + unsigned int priv_id;
4995 + unsigned int mas_hw_id;
4996 + unsigned int slv_hw_id;
4997 + int gateway;
4998 + int *masterp;
4999 + int *qport;
5000 + int num_mports;
5001 + int *slavep;
5002 + int num_sports;
5003 + int *tier;
5004 + int num_tiers;
5005 + int ahb;
5006 + int hw_sel;
5007 + const char *slaveclk[NUM_CTX];
5008 + const char *memclk[NUM_CTX];
5009 + const char *iface_clk_node;
5010 + unsigned int buswidth;
5011 + unsigned int ws;
5012 + unsigned int mode;
5013 + unsigned int perm_mode;
5014 + unsigned int prio_lvl;
5015 + unsigned int prio_rd;
5016 + unsigned int prio_wr;
5017 + unsigned int prio1;
5018 + unsigned int prio0;
5019 + unsigned int num_thresh;
5020 + u64 *th;
5021 + u64 cur_lim_bw;
5022 + unsigned int mode_thresh;
5023 + bool dual_conf;
5024 + u64 *bimc_bw;
5025 + bool nr_lim;
5026 + u32 ff;
5027 + bool rt_mas;
5028 + u32 bimc_gp;
5029 + u32 bimc_thmp;
5030 + u64 floor_bw;
5031 + const char *name;
5032 +};
5033 +
5034 +struct path_node {
5035 + uint64_t clk[NUM_CTX];
5036 + uint64_t bw[NUM_CTX];
5037 + uint64_t *sel_clk;
5038 + uint64_t *sel_bw;
5039 + int next;
5040 +};
5041 +
5042 +struct msm_bus_link_info {
5043 + uint64_t clk[NUM_CTX];
5044 + uint64_t *sel_clk;
5045 + uint64_t memclk;
5046 + int64_t bw[NUM_CTX];
5047 + int64_t *sel_bw;
5048 + int *tier;
5049 + int num_tiers;
5050 +};
5051 +
5052 +struct nodeclk {
5053 + struct clk *clk;
5054 + uint64_t rate;
5055 + bool dirty;
5056 + bool enable;
5057 +};
5058 +
5059 +struct msm_bus_inode_info {
5060 + struct msm_bus_node_info *node_info;
5061 + uint64_t max_bw;
5062 + uint64_t max_clk;
5063 + uint64_t cur_lim_bw;
5064 + uint64_t cur_prg_bw;
5065 + struct msm_bus_link_info link_info;
5066 + int num_pnodes;
5067 + struct path_node *pnode;
5068 + int commit_index;
5069 + struct nodeclk nodeclk[NUM_CTX];
5070 + struct nodeclk memclk[NUM_CTX];
5071 + struct nodeclk iface_clk;
5072 + void *hw_data;
5073 +};
5074 +
5075 +struct msm_bus_node_hw_info {
5076 + bool dirty;
5077 + unsigned int hw_id;
5078 + uint64_t bw;
5079 +};
5080 +
5081 +struct msm_bus_hw_algorithm {
5082 + int (*allocate_commit_data)(struct msm_bus_fabric_registration
5083 + *fab_pdata, void **cdata, int ctx);
5084 + void *(*allocate_hw_data)(struct platform_device *pdev,
5085 + struct msm_bus_fabric_registration *fab_pdata);
5086 + void (*node_init)(void *hw_data, struct msm_bus_inode_info *info);
5087 + void (*free_commit_data)(void *cdata);
5088 + void (*update_bw)(struct msm_bus_inode_info *hop,
5089 + struct msm_bus_inode_info *info,
5090 + struct msm_bus_fabric_registration *fab_pdata,
5091 + void *sel_cdata, int *master_tiers,
5092 + int64_t add_bw);
5093 + void (*fill_cdata_buffer)(int *curr, char *buf, const int max_size,
5094 + void *cdata, int nmasters, int nslaves, int ntslaves);
5095 + int (*commit)(struct msm_bus_fabric_registration
5096 + *fab_pdata, void *hw_data, void **cdata);
5097 + int (*port_unhalt)(uint32_t haltid, uint8_t mport);
5098 + int (*port_halt)(uint32_t haltid, uint8_t mport);
5099 + void (*config_master)(struct msm_bus_fabric_registration *fab_pdata,
5100 + struct msm_bus_inode_info *info,
5101 + uint64_t req_clk, uint64_t req_bw);
5102 + void (*config_limiter)(struct msm_bus_fabric_registration *fab_pdata,
5103 + struct msm_bus_inode_info *info);
5104 + bool (*update_bw_reg)(int mode);
5105 +};
5106 +
5107 +struct msm_bus_fabric_device {
5108 + int id;
5109 + const char *name;
5110 + struct device dev;
5111 + const struct msm_bus_fab_algorithm *algo;
5112 + const struct msm_bus_board_algorithm *board_algo;
5113 + struct msm_bus_hw_algorithm hw_algo;
5114 + int visited;
5115 + int num_nr_lim;
5116 + u64 nr_lim_thresh;
5117 + u32 eff_fact;
5118 +};
5119 +#define to_msm_bus_fabric_device(d) container_of(d, \
5120 + struct msm_bus_fabric_device, d)
5121 +
5122 +struct msm_bus_fabric {
5123 + struct msm_bus_fabric_device fabdev;
5124 + int ahb;
5125 + void *cdata[NUM_CTX];
5126 + bool arb_dirty;
5127 + bool clk_dirty;
5128 + struct radix_tree_root fab_tree;
5129 + int num_nodes;
5130 + struct list_head gateways;
5131 + struct msm_bus_inode_info info;
5132 + struct msm_bus_fabric_registration *pdata;
5133 + void *hw_data;
5134 +};
5135 +#define to_msm_bus_fabric(d) container_of(d, \
5136 + struct msm_bus_fabric, d)
5137 +
5138 +
5139 +struct msm_bus_fab_algorithm {
5140 + int (*update_clks)(struct msm_bus_fabric_device *fabdev,
5141 + struct msm_bus_inode_info *pme, int index,
5142 + uint64_t curr_clk, uint64_t req_clk,
5143 + uint64_t bwsum, int flag, int ctx,
5144 + unsigned int cl_active_flag);
5145 + int (*port_halt)(struct msm_bus_fabric_device *fabdev, int portid);
5146 + int (*port_unhalt)(struct msm_bus_fabric_device *fabdev, int portid);
5147 + int (*commit)(struct msm_bus_fabric_device *fabdev);
5148 + struct msm_bus_inode_info *(*find_node)(struct msm_bus_fabric_device
5149 + *fabdev, int id);
5150 + struct msm_bus_inode_info *(*find_gw_node)(struct msm_bus_fabric_device
5151 + *fabdev, int id);
5152 + struct list_head *(*get_gw_list)(struct msm_bus_fabric_device *fabdev);
5153 + void (*update_bw)(struct msm_bus_fabric_device *fabdev, struct
5154 + msm_bus_inode_info * hop, struct msm_bus_inode_info *info,
5155 + int64_t add_bw, int *master_tiers, int ctx);
5156 + void (*config_master)(struct msm_bus_fabric_device *fabdev,
5157 + struct msm_bus_inode_info *info, uint64_t req_clk,
5158 + uint64_t req_bw);
5159 + void (*config_limiter)(struct msm_bus_fabric_device *fabdev,
5160 + struct msm_bus_inode_info *info);
5161 +};
5162 +
5163 +struct msm_bus_board_algorithm {
5164 + int board_nfab;
5165 + void (*assign_iids)(struct msm_bus_fabric_registration *fabreg,
5166 + int fabid);
5167 + int (*get_iid)(int id);
5168 +};
5169 +
5170 +/**
5171 + * Used to store the list of fabrics and other info to be
5172 + * maintained outside the fabric structure.
5173 + * Used while calculating path, and to find fabric ptrs
5174 + */
5175 +struct msm_bus_fabnodeinfo {
5176 + struct list_head list;
5177 + struct msm_bus_inode_info *info;
5178 +};
5179 +
5180 +struct msm_bus_client {
5181 + int id;
5182 + struct msm_bus_scale_pdata *pdata;
5183 + int *src_pnode;
5184 + int curr;
5185 +};
5186 +
5187 +uint64_t msm_bus_div64(unsigned int width, uint64_t bw);
5188 +int msm_bus_fabric_device_register(struct msm_bus_fabric_device *fabric);
5189 +void msm_bus_fabric_device_unregister(struct msm_bus_fabric_device *fabric);
5190 +struct msm_bus_fabric_device *msm_bus_get_fabric_device(int fabid);
5191 +int msm_bus_get_num_fab(void);
5192 +
5193 +
5194 +int msm_bus_hw_fab_init(struct msm_bus_fabric_registration *pdata,
5195 + struct msm_bus_hw_algorithm *hw_algo);
5196 +void msm_bus_board_init(struct msm_bus_fabric_registration *pdata);
5197 +void msm_bus_board_set_nfab(struct msm_bus_fabric_registration *pdata,
5198 + int nfab);
5199 +#if defined(CONFIG_MSM_RPM_SMD)
5200 +int msm_bus_rpm_hw_init(struct msm_bus_fabric_registration *pdata,
5201 + struct msm_bus_hw_algorithm *hw_algo);
5202 +int msm_bus_remote_hw_commit(struct msm_bus_fabric_registration
5203 + *fab_pdata, void *hw_data, void **cdata);
5204 +void msm_bus_rpm_fill_cdata_buffer(int *curr, char *buf, const int max_size,
5205 + void *cdata, int nmasters, int nslaves, int ntslaves);
5206 +#else
5207 +static inline int msm_bus_rpm_hw_init(struct msm_bus_fabric_registration *pdata,
5208 + struct msm_bus_hw_algorithm *hw_algo)
5209 +{
5210 + return 0;
5211 +}
5212 +static inline int msm_bus_remote_hw_commit(struct msm_bus_fabric_registration
5213 + *fab_pdata, void *hw_data, void **cdata)
5214 +{
5215 + return 0;
5216 +}
5217 +static inline void msm_bus_rpm_fill_cdata_buffer(int *curr, char *buf,
5218 + const int max_size, void *cdata, int nmasters, int nslaves,
5219 + int ntslaves)
5220 +{
5221 +}
5222 +#endif
5223 +
5224 +int msm_bus_noc_hw_init(struct msm_bus_fabric_registration *pdata,
5225 + struct msm_bus_hw_algorithm *hw_algo);
5226 +int msm_bus_bimc_hw_init(struct msm_bus_fabric_registration *pdata,
5227 + struct msm_bus_hw_algorithm *hw_algo);
5228 +#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_MSM_BUS_SCALING)
5229 +void msm_bus_dbg_client_data(struct msm_bus_scale_pdata *pdata, int index,
5230 + uint32_t cl);
5231 +void msm_bus_dbg_commit_data(const char *fabname, void *cdata,
5232 + int nmasters, int nslaves, int ntslaves, int op);
5233 +#else
5234 +static inline void msm_bus_dbg_client_data(struct msm_bus_scale_pdata *pdata,
5235 + int index, uint32_t cl)
5236 +{
5237 +}
5238 +static inline void msm_bus_dbg_commit_data(const char *fabname,
5239 + void *cdata, int nmasters, int nslaves, int ntslaves,
5240 + int op)
5241 +{
5242 +}
5243 +#endif
5244 +
5245 +#ifdef CONFIG_CORESIGHT
5246 +int msmbus_coresight_init(struct platform_device *pdev);
5247 +void msmbus_coresight_remove(struct platform_device *pdev);
5248 +int msmbus_coresight_init_adhoc(struct platform_device *pdev,
5249 + struct device_node *of_node);
5250 +void msmbus_coresight_remove_adhoc(struct platform_device *pdev);
5251 +#else
5252 +static inline int msmbus_coresight_init(struct platform_device *pdev)
5253 +{
5254 + return 0;
5255 +}
5256 +
5257 +static inline void msmbus_coresight_remove(struct platform_device *pdev)
5258 +{
5259 +}
5260 +
5261 +static inline int msmbus_coresight_init_adhoc(struct platform_device *pdev,
5262 + struct device_node *of_node)
5263 +{
5264 + return 0;
5265 +}
5266 +
5267 +static inline void msmbus_coresight_remove_adhoc(struct platform_device *pdev)
5268 +{
5269 +}
5270 +#endif
5271 +
5272 +
5273 +#ifdef CONFIG_OF
5274 +void msm_bus_of_get_nfab(struct platform_device *pdev,
5275 + struct msm_bus_fabric_registration *pdata);
5276 +struct msm_bus_fabric_registration
5277 + *msm_bus_of_get_fab_data(struct platform_device *pdev);
5278 +#else
5279 +static inline void msm_bus_of_get_nfab(struct platform_device *pdev,
5280 + struct msm_bus_fabric_registration *pdata)
5281 +{
5282 + return;
5283 +}
5284 +
5285 +static inline struct msm_bus_fabric_registration
5286 + *msm_bus_of_get_fab_data(struct platform_device *pdev)
5287 +{
5288 + return NULL;
5289 +}
5290 +#endif
5291 +
5292 +#endif /*_ARCH_ARM_MACH_MSM_BUS_CORE_H*/
5293 --- /dev/null
5294 +++ b/drivers/bus/msm_bus/msm_bus_dbg.c
5295 @@ -0,0 +1,810 @@
5296 +/* Copyright (c) 2010-2012, 2014, The Linux Foundation. All rights reserved.
5297 + *
5298 + * This program is free software; you can redistribute it and/or modify
5299 + * it under the terms of the GNU General Public License version 2 and
5300 + * only version 2 as published by the Free Software Foundation.
5301 + *
5302 + * This program is distributed in the hope that it will be useful,
5303 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
5304 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5305 + * GNU General Public License for more details.
5306 + *
5307 + */
5308 +
5309 +#define pr_fmt(fmt) "AXI: %s(): " fmt, __func__
5310 +
5311 +#include <linux/kernel.h>
5312 +#include <linux/module.h>
5313 +#include <linux/seq_file.h>
5314 +#include <linux/debugfs.h>
5315 +#include <linux/slab.h>
5316 +#include <linux/mutex.h>
5317 +#include <linux/string.h>
5318 +#include <linux/uaccess.h>
5319 +#include <linux/hrtimer.h>
5320 +#include "msm-bus-board.h"
5321 +#include "msm-bus.h"
5322 +#include "msm_bus_rules.h"
5323 +#include "msm_bus_core.h"
5324 +#include "msm_bus_adhoc.h"
5325 +
5326 +#define CREATE_TRACE_POINTS
5327 +#include <trace/events/trace_msm_bus.h>
5328 +
5329 +#define MAX_BUFF_SIZE 4096
5330 +#define FILL_LIMIT 128
5331 +
5332 +static struct dentry *clients;
5333 +static struct dentry *dir;
5334 +static DEFINE_MUTEX(msm_bus_dbg_fablist_lock);
5335 +struct msm_bus_dbg_state {
5336 + uint32_t cl;
5337 + uint8_t enable;
5338 + uint8_t current_index;
5339 +} clstate;
5340 +
5341 +struct msm_bus_cldata {
5342 + const struct msm_bus_scale_pdata *pdata;
5343 + int index;
5344 + uint32_t clid;
5345 + int size;
5346 + struct dentry *file;
5347 + struct list_head list;
5348 + char buffer[MAX_BUFF_SIZE];
5349 +};
5350 +
5351 +struct msm_bus_fab_list {
5352 + const char *name;
5353 + int size;
5354 + struct dentry *file;
5355 + struct list_head list;
5356 + char buffer[MAX_BUFF_SIZE];
5357 +};
5358 +
5359 +static char *rules_buf;
5360 +
5361 +LIST_HEAD(fabdata_list);
5362 +LIST_HEAD(cl_list);
5363 +
5364 +/**
5365 + * The following structures and funtions are used for
5366 + * the test-client which can be created at run-time.
5367 + */
5368 +
5369 +static struct msm_bus_vectors init_vectors[1];
5370 +static struct msm_bus_vectors current_vectors[1];
5371 +static struct msm_bus_vectors requested_vectors[1];
5372 +
5373 +static struct msm_bus_paths shell_client_usecases[] = {
5374 + {
5375 + .num_paths = ARRAY_SIZE(init_vectors),
5376 + .vectors = init_vectors,
5377 + },
5378 + {
5379 + .num_paths = ARRAY_SIZE(current_vectors),
5380 + .vectors = current_vectors,
5381 + },
5382 + {
5383 + .num_paths = ARRAY_SIZE(requested_vectors),
5384 + .vectors = requested_vectors,
5385 + },
5386 +};
5387 +
5388 +static struct msm_bus_scale_pdata shell_client = {
5389 + .usecase = shell_client_usecases,
5390 + .num_usecases = ARRAY_SIZE(shell_client_usecases),
5391 + .name = "test-client",
5392 +};
5393 +
5394 +static void msm_bus_dbg_init_vectors(void)
5395 +{
5396 + init_vectors[0].src = -1;
5397 + init_vectors[0].dst = -1;
5398 + init_vectors[0].ab = 0;
5399 + init_vectors[0].ib = 0;
5400 + current_vectors[0].src = -1;
5401 + current_vectors[0].dst = -1;
5402 + current_vectors[0].ab = 0;
5403 + current_vectors[0].ib = 0;
5404 + requested_vectors[0].src = -1;
5405 + requested_vectors[0].dst = -1;
5406 + requested_vectors[0].ab = 0;
5407 + requested_vectors[0].ib = 0;
5408 + clstate.enable = 0;
5409 + clstate.current_index = 0;
5410 +}
5411 +
5412 +static int msm_bus_dbg_update_cl_request(uint32_t cl)
5413 +{
5414 + int ret = 0;
5415 +
5416 + if (clstate.current_index < 2)
5417 + clstate.current_index = 2;
5418 + else {
5419 + clstate.current_index = 1;
5420 + current_vectors[0].ab = requested_vectors[0].ab;
5421 + current_vectors[0].ib = requested_vectors[0].ib;
5422 + }
5423 +
5424 + if (clstate.enable) {
5425 + MSM_BUS_DBG("Updating request for shell client, index: %d\n",
5426 + clstate.current_index);
5427 + ret = msm_bus_scale_client_update_request(clstate.cl,
5428 + clstate.current_index);
5429 + } else
5430 + MSM_BUS_DBG("Enable bit not set. Skipping update request\n");
5431 +
5432 + return ret;
5433 +}
5434 +
5435 +static void msm_bus_dbg_unregister_client(uint32_t cl)
5436 +{
5437 + MSM_BUS_DBG("Unregistering shell client\n");
5438 + msm_bus_scale_unregister_client(clstate.cl);
5439 + clstate.cl = 0;
5440 +}
5441 +
5442 +static uint32_t msm_bus_dbg_register_client(void)
5443 +{
5444 + int ret = 0;
5445 +
5446 + if (init_vectors[0].src != requested_vectors[0].src) {
5447 + MSM_BUS_DBG("Shell client master changed. Unregistering\n");
5448 + msm_bus_dbg_unregister_client(clstate.cl);
5449 + }
5450 + if (init_vectors[0].dst != requested_vectors[0].dst) {
5451 + MSM_BUS_DBG("Shell client slave changed. Unregistering\n");
5452 + msm_bus_dbg_unregister_client(clstate.cl);
5453 + }
5454 +
5455 + current_vectors[0].src = init_vectors[0].src;
5456 + requested_vectors[0].src = init_vectors[0].src;
5457 + current_vectors[0].dst = init_vectors[0].dst;
5458 + requested_vectors[0].dst = init_vectors[0].dst;
5459 +
5460 + if (!clstate.enable) {
5461 + MSM_BUS_DBG("Enable bit not set, skipping registration: cl "
5462 + "%d\n", clstate.cl);
5463 + return 0;
5464 + }
5465 +
5466 + if (clstate.cl) {
5467 + MSM_BUS_DBG("Client registered, skipping registration\n");
5468 + return clstate.cl;
5469 + }
5470 +
5471 + MSM_BUS_DBG("Registering shell client\n");
5472 + ret = msm_bus_scale_register_client(&shell_client);
5473 + return ret;
5474 +}
5475 +
5476 +static int msm_bus_dbg_mas_get(void *data, u64 *val)
5477 +{
5478 + *val = init_vectors[0].src;
5479 + MSM_BUS_DBG("Get master: %llu\n", *val);
5480 + return 0;
5481 +}
5482 +
5483 +static int msm_bus_dbg_mas_set(void *data, u64 val)
5484 +{
5485 + init_vectors[0].src = val;
5486 + MSM_BUS_DBG("Set master: %llu\n", val);
5487 + clstate.cl = msm_bus_dbg_register_client();
5488 + return 0;
5489 +}
5490 +DEFINE_SIMPLE_ATTRIBUTE(shell_client_mas_fops, msm_bus_dbg_mas_get,
5491 + msm_bus_dbg_mas_set, "%llu\n");
5492 +
5493 +static int msm_bus_dbg_slv_get(void *data, u64 *val)
5494 +{
5495 + *val = init_vectors[0].dst;
5496 + MSM_BUS_DBG("Get slave: %llu\n", *val);
5497 + return 0;
5498 +}
5499 +
5500 +static int msm_bus_dbg_slv_set(void *data, u64 val)
5501 +{
5502 + init_vectors[0].dst = val;
5503 + MSM_BUS_DBG("Set slave: %llu\n", val);
5504 + clstate.cl = msm_bus_dbg_register_client();
5505 + return 0;
5506 +}
5507 +DEFINE_SIMPLE_ATTRIBUTE(shell_client_slv_fops, msm_bus_dbg_slv_get,
5508 + msm_bus_dbg_slv_set, "%llu\n");
5509 +
5510 +static int msm_bus_dbg_ab_get(void *data, u64 *val)
5511 +{
5512 + *val = requested_vectors[0].ab;
5513 + MSM_BUS_DBG("Get ab: %llu\n", *val);
5514 + return 0;
5515 +}
5516 +
5517 +static int msm_bus_dbg_ab_set(void *data, u64 val)
5518 +{
5519 + requested_vectors[0].ab = val;
5520 + MSM_BUS_DBG("Set ab: %llu\n", val);
5521 + return 0;
5522 +}
5523 +DEFINE_SIMPLE_ATTRIBUTE(shell_client_ab_fops, msm_bus_dbg_ab_get,
5524 + msm_bus_dbg_ab_set, "%llu\n");
5525 +
5526 +static int msm_bus_dbg_ib_get(void *data, u64 *val)
5527 +{
5528 + *val = requested_vectors[0].ib;
5529 + MSM_BUS_DBG("Get ib: %llu\n", *val);
5530 + return 0;
5531 +}
5532 +
5533 +static int msm_bus_dbg_ib_set(void *data, u64 val)
5534 +{
5535 + requested_vectors[0].ib = val;
5536 + MSM_BUS_DBG("Set ib: %llu\n", val);
5537 + return 0;
5538 +}
5539 +DEFINE_SIMPLE_ATTRIBUTE(shell_client_ib_fops, msm_bus_dbg_ib_get,
5540 + msm_bus_dbg_ib_set, "%llu\n");
5541 +
5542 +static int msm_bus_dbg_en_get(void *data, u64 *val)
5543 +{
5544 + *val = clstate.enable;
5545 + MSM_BUS_DBG("Get enable: %llu\n", *val);
5546 + return 0;
5547 +}
5548 +
5549 +static int msm_bus_dbg_en_set(void *data, u64 val)
5550 +{
5551 + int ret = 0;
5552 +
5553 + clstate.enable = val;
5554 + if (clstate.enable) {
5555 + if (!clstate.cl) {
5556 + MSM_BUS_DBG("client: %u\n", clstate.cl);
5557 + clstate.cl = msm_bus_dbg_register_client();
5558 + if (clstate.cl)
5559 + ret = msm_bus_dbg_update_cl_request(clstate.cl);
5560 + } else {
5561 + MSM_BUS_DBG("update request for cl: %u\n", clstate.cl);
5562 + ret = msm_bus_dbg_update_cl_request(clstate.cl);
5563 + }
5564 + }
5565 +
5566 + MSM_BUS_DBG("Set enable: %llu\n", val);
5567 + return ret;
5568 +}
5569 +DEFINE_SIMPLE_ATTRIBUTE(shell_client_en_fops, msm_bus_dbg_en_get,
5570 + msm_bus_dbg_en_set, "%llu\n");
5571 +
5572 +/**
5573 + * The following funtions are used for viewing the client data
5574 + * and changing the client request at run-time
5575 + */
5576 +
5577 +static ssize_t client_data_read(struct file *file, char __user *buf,
5578 + size_t count, loff_t *ppos)
5579 +{
5580 + int bsize = 0;
5581 + uint32_t cl = (uint32_t)(uintptr_t)file->private_data;
5582 + struct msm_bus_cldata *cldata = NULL;
5583 + int found = 0;
5584 +
5585 + list_for_each_entry(cldata, &cl_list, list) {
5586 + if (cldata->clid == cl) {
5587 + found = 1;
5588 + break;
5589 + }
5590 + }
5591 + if (!found)
5592 + return 0;
5593 +
5594 + bsize = cldata->size;
5595 + return simple_read_from_buffer(buf, count, ppos,
5596 + cldata->buffer, bsize);
5597 +}
5598 +
5599 +static int client_data_open(struct inode *inode, struct file *file)
5600 +{
5601 + file->private_data = inode->i_private;
5602 + return 0;
5603 +}
5604 +
5605 +static const struct file_operations client_data_fops = {
5606 + .open = client_data_open,
5607 + .read = client_data_read,
5608 +};
5609 +
5610 +struct dentry *msm_bus_dbg_create(const char *name, mode_t mode,
5611 + struct dentry *dent, uint32_t clid)
5612 +{
5613 + if (dent == NULL) {
5614 + MSM_BUS_DBG("debugfs not ready yet\n");
5615 + return NULL;
5616 + }
5617 + return debugfs_create_file(name, mode, dent, (void *)(uintptr_t)clid,
5618 + &client_data_fops);
5619 +}
5620 +
5621 +#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_MSM_BUS_SCALING)
5622 +static int msm_bus_dbg_record_client(const struct msm_bus_scale_pdata *pdata,
5623 + int index, uint32_t clid, struct dentry *file)
5624 +{
5625 + struct msm_bus_cldata *cldata;
5626 +
5627 + cldata = kmalloc(sizeof(struct msm_bus_cldata), GFP_KERNEL);
5628 + if (!cldata) {
5629 + MSM_BUS_DBG("Failed to allocate memory for client data\n");
5630 + return -ENOMEM;
5631 + }
5632 + cldata->pdata = pdata;
5633 + cldata->index = index;
5634 + cldata->clid = clid;
5635 + cldata->file = file;
5636 + cldata->size = 0;
5637 + list_add_tail(&cldata->list, &cl_list);
5638 + return 0;
5639 +}
5640 +
5641 +static void msm_bus_dbg_free_client(uint32_t clid)
5642 +{
5643 + struct msm_bus_cldata *cldata = NULL;
5644 +
5645 + list_for_each_entry(cldata, &cl_list, list) {
5646 + if (cldata->clid == clid) {
5647 + debugfs_remove(cldata->file);
5648 + list_del(&cldata->list);
5649 + kfree(cldata);
5650 + break;
5651 + }
5652 + }
5653 +}
5654 +
5655 +static int msm_bus_dbg_fill_cl_buffer(const struct msm_bus_scale_pdata *pdata,
5656 + int index, uint32_t clid)
5657 +{
5658 + int i = 0, j;
5659 + char *buf = NULL;
5660 + struct msm_bus_cldata *cldata = NULL;
5661 + struct timespec ts;
5662 + int found = 0;
5663 +
5664 + list_for_each_entry(cldata, &cl_list, list) {
5665 + if (cldata->clid == clid) {
5666 + found = 1;
5667 + break;
5668 + }
5669 + }
5670 +
5671 + if (!found)
5672 + return -ENOENT;
5673 +
5674 + if (cldata->file == NULL) {
5675 + if (pdata->name == NULL) {
5676 + MSM_BUS_DBG("Client doesn't have a name\n");
5677 + return -EINVAL;
5678 + }
5679 + cldata->file = msm_bus_dbg_create(pdata->name, S_IRUGO,
5680 + clients, clid);
5681 + }
5682 +
5683 + if (cldata->size < (MAX_BUFF_SIZE - FILL_LIMIT))
5684 + i = cldata->size;
5685 + else {
5686 + i = 0;
5687 + cldata->size = 0;
5688 + }
5689 + buf = cldata->buffer;
5690 + ts = ktime_to_timespec(ktime_get());
5691 + i += scnprintf(buf + i, MAX_BUFF_SIZE - i, "\n%d.%d\n",
5692 + (int)ts.tv_sec, (int)ts.tv_nsec);
5693 + i += scnprintf(buf + i, MAX_BUFF_SIZE - i, "curr : %d\n", index);
5694 + i += scnprintf(buf + i, MAX_BUFF_SIZE - i, "masters: ");
5695 +
5696 + for (j = 0; j < pdata->usecase->num_paths; j++)
5697 + i += scnprintf(buf + i, MAX_BUFF_SIZE - i, "%d ",
5698 + pdata->usecase[index].vectors[j].src);
5699 + i += scnprintf(buf + i, MAX_BUFF_SIZE - i, "\nslaves : ");
5700 + for (j = 0; j < pdata->usecase->num_paths; j++)
5701 + i += scnprintf(buf + i, MAX_BUFF_SIZE - i, "%d ",
5702 + pdata->usecase[index].vectors[j].dst);
5703 + i += scnprintf(buf + i, MAX_BUFF_SIZE - i, "\nab : ");
5704 + for (j = 0; j < pdata->usecase->num_paths; j++)
5705 + i += scnprintf(buf + i, MAX_BUFF_SIZE - i, "%llu ",
5706 + pdata->usecase[index].vectors[j].ab);
5707 + i += scnprintf(buf + i, MAX_BUFF_SIZE - i, "\nib : ");
5708 + for (j = 0; j < pdata->usecase->num_paths; j++)
5709 + i += scnprintf(buf + i, MAX_BUFF_SIZE - i, "%llu ",
5710 + pdata->usecase[index].vectors[j].ib);
5711 + i += scnprintf(buf + i, MAX_BUFF_SIZE - i, "\n");
5712 +
5713 + for (j = 0; j < pdata->usecase->num_paths; j++)
5714 + trace_bus_update_request((int)ts.tv_sec, (int)ts.tv_nsec,
5715 + pdata->name, index,
5716 + pdata->usecase[index].vectors[j].src,
5717 + pdata->usecase[index].vectors[j].dst,
5718 + pdata->usecase[index].vectors[j].ab,
5719 + pdata->usecase[index].vectors[j].ib);
5720 +
5721 + cldata->size = i;
5722 + return i;
5723 +}
5724 +#endif
5725 +
5726 +static int msm_bus_dbg_update_request(struct msm_bus_cldata *cldata, int index)
5727 +{
5728 + int ret = 0;
5729 +
5730 + if ((index < 0) || (index > cldata->pdata->num_usecases)) {
5731 + MSM_BUS_DBG("Invalid index!\n");
5732 + return -EINVAL;
5733 + }
5734 + ret = msm_bus_scale_client_update_request(cldata->clid, index);
5735 + return ret;
5736 +}
5737 +
5738 +static ssize_t msm_bus_dbg_update_request_write(struct file *file,
5739 + const char __user *ubuf, size_t cnt, loff_t *ppos)
5740 +{
5741 + struct msm_bus_cldata *cldata;
5742 + unsigned long index = 0;
5743 + int ret = 0;
5744 + char *chid;
5745 + char *buf = kmalloc((sizeof(char) * (cnt + 1)), GFP_KERNEL);
5746 + int found = 0;
5747 +
5748 + if (!buf || IS_ERR(buf)) {
5749 + MSM_BUS_ERR("Memory allocation for buffer failed\n");
5750 + return -ENOMEM;
5751 + }
5752 + if (cnt == 0) {
5753 + kfree(buf);
5754 + return 0;
5755 + }
5756 + if (copy_from_user(buf, ubuf, cnt)) {
5757 + kfree(buf);
5758 + return -EFAULT;
5759 + }
5760 + buf[cnt] = '\0';
5761 + chid = buf;
5762 + MSM_BUS_DBG("buffer: %s\n size: %zu\n", buf, sizeof(ubuf));
5763 +
5764 + list_for_each_entry(cldata, &cl_list, list) {
5765 + if (strnstr(chid, cldata->pdata->name, cnt)) {
5766 + found = 1;
5767 + cldata = cldata;
5768 + strsep(&chid, " ");
5769 + if (chid) {
5770 + ret = kstrtoul(chid, 10, &index);
5771 + if (ret) {
5772 + MSM_BUS_DBG("Index conversion"
5773 + " failed\n");
5774 + return -EFAULT;
5775 + }
5776 + } else {
5777 + MSM_BUS_DBG("Error parsing input. Index not"
5778 + " found\n");
5779 + found = 0;
5780 + }
5781 + break;
5782 + }
5783 + }
5784 +
5785 + if (found)
5786 + msm_bus_dbg_update_request(cldata, index);
5787 + kfree(buf);
5788 + return cnt;
5789 +}
5790 +
5791 +/**
5792 + * The following funtions are used for viewing the commit data
5793 + * for each fabric
5794 + */
5795 +static ssize_t fabric_data_read(struct file *file, char __user *buf,
5796 + size_t count, loff_t *ppos)
5797 +{
5798 + struct msm_bus_fab_list *fablist = NULL;
5799 + int bsize = 0;
5800 + ssize_t ret;
5801 + const char *name = file->private_data;
5802 + int found = 0;
5803 +
5804 + mutex_lock(&msm_bus_dbg_fablist_lock);
5805 + list_for_each_entry(fablist, &fabdata_list, list) {
5806 + if (strcmp(fablist->name, name) == 0) {
5807 + found = 1;
5808 + break;
5809 + }
5810 + }
5811 + if (!found)
5812 + return -ENOENT;
5813 + bsize = fablist->size;
5814 + ret = simple_read_from_buffer(buf, count, ppos,
5815 + fablist->buffer, bsize);
5816 + mutex_unlock(&msm_bus_dbg_fablist_lock);
5817 + return ret;
5818 +}
5819 +
5820 +static const struct file_operations fabric_data_fops = {
5821 + .open = client_data_open,
5822 + .read = fabric_data_read,
5823 +};
5824 +
5825 +static ssize_t rules_dbg_read(struct file *file, char __user *buf,
5826 + size_t count, loff_t *ppos)
5827 +{
5828 + ssize_t ret;
5829 + memset(rules_buf, 0, MAX_BUFF_SIZE);
5830 + print_rules_buf(rules_buf, MAX_BUFF_SIZE);
5831 + ret = simple_read_from_buffer(buf, count, ppos,
5832 + rules_buf, MAX_BUFF_SIZE);
5833 + return ret;
5834 +}
5835 +
5836 +static int rules_dbg_open(struct inode *inode, struct file *file)
5837 +{
5838 + file->private_data = inode->i_private;
5839 + return 0;
5840 +}
5841 +
5842 +static const struct file_operations rules_dbg_fops = {
5843 + .open = rules_dbg_open,
5844 + .read = rules_dbg_read,
5845 +};
5846 +
5847 +#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_MSM_BUS_SCALING)
5848 +static int msm_bus_dbg_record_fabric(const char *fabname, struct dentry *file)
5849 +{
5850 + struct msm_bus_fab_list *fablist;
5851 + int ret = 0;
5852 +
5853 + mutex_lock(&msm_bus_dbg_fablist_lock);
5854 + fablist = kmalloc(sizeof(struct msm_bus_fab_list), GFP_KERNEL);
5855 + if (!fablist) {
5856 + MSM_BUS_DBG("Failed to allocate memory for commit data\n");
5857 + ret = -ENOMEM;
5858 + goto err;
5859 + }
5860 +
5861 + fablist->name = fabname;
5862 + fablist->size = 0;
5863 + list_add_tail(&fablist->list, &fabdata_list);
5864 +err:
5865 + mutex_unlock(&msm_bus_dbg_fablist_lock);
5866 + return ret;
5867 +}
5868 +
5869 +static void msm_bus_dbg_free_fabric(const char *fabname)
5870 +{
5871 + struct msm_bus_fab_list *fablist = NULL;
5872 +
5873 + mutex_lock(&msm_bus_dbg_fablist_lock);
5874 + list_for_each_entry(fablist, &fabdata_list, list) {
5875 + if (strcmp(fablist->name, fabname) == 0) {
5876 + debugfs_remove(fablist->file);
5877 + list_del(&fablist->list);
5878 + kfree(fablist);
5879 + break;
5880 + }
5881 + }
5882 + mutex_unlock(&msm_bus_dbg_fablist_lock);
5883 +}
5884 +
5885 +static int msm_bus_dbg_fill_fab_buffer(const char *fabname,
5886 + void *cdata, int nmasters, int nslaves,
5887 + int ntslaves)
5888 +{
5889 + int i;
5890 + char *buf = NULL;
5891 + struct msm_bus_fab_list *fablist = NULL;
5892 + struct timespec ts;
5893 + int found = 0;
5894 +
5895 + mutex_lock(&msm_bus_dbg_fablist_lock);
5896 + list_for_each_entry(fablist, &fabdata_list, list) {
5897 + if (strcmp(fablist->name, fabname) == 0) {
5898 + found = 1;
5899 + break;
5900 + }
5901 + }
5902 + if (!found)
5903 + return -ENOENT;
5904 +
5905 + if (fablist->file == NULL) {
5906 + MSM_BUS_DBG("Fabric dbg entry does not exist\n");
5907 + mutex_unlock(&msm_bus_dbg_fablist_lock);
5908 + return -EFAULT;
5909 + }
5910 +
5911 + if (fablist->size < MAX_BUFF_SIZE - 256)
5912 + i = fablist->size;
5913 + else {
5914 + i = 0;
5915 + fablist->size = 0;
5916 + }
5917 + buf = fablist->buffer;
5918 + mutex_unlock(&msm_bus_dbg_fablist_lock);
5919 + ts = ktime_to_timespec(ktime_get());
5920 + i += scnprintf(buf + i, MAX_BUFF_SIZE - i, "\n%d.%d\n",
5921 + (int)ts.tv_sec, (int)ts.tv_nsec);
5922 +
5923 + msm_bus_rpm_fill_cdata_buffer(&i, buf, MAX_BUFF_SIZE, cdata,
5924 + nmasters, nslaves, ntslaves);
5925 + i += scnprintf(buf + i, MAX_BUFF_SIZE - i, "\n");
5926 + mutex_lock(&msm_bus_dbg_fablist_lock);
5927 + fablist->size = i;
5928 + mutex_unlock(&msm_bus_dbg_fablist_lock);
5929 + return 0;
5930 +}
5931 +#endif
5932 +
5933 +static const struct file_operations msm_bus_dbg_update_request_fops = {
5934 + .open = client_data_open,
5935 + .write = msm_bus_dbg_update_request_write,
5936 +};
5937 +
5938 +#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_MSM_BUS_SCALING)
5939 +/**
5940 + * msm_bus_dbg_client_data() - Add debug data for clients
5941 + * @pdata: Platform data of the client
5942 + * @index: The current index or operation to be performed
5943 + * @clid: Client handle obtained during registration
5944 + */
5945 +void msm_bus_dbg_client_data(struct msm_bus_scale_pdata *pdata, int index,
5946 + uint32_t clid)
5947 +{
5948 + struct dentry *file = NULL;
5949 +
5950 + if (index == MSM_BUS_DBG_REGISTER) {
5951 + msm_bus_dbg_record_client(pdata, index, clid, file);
5952 + if (!pdata->name) {
5953 + MSM_BUS_DBG("Cannot create debugfs entry. Null name\n");
5954 + return;
5955 + }
5956 + } else if (index == MSM_BUS_DBG_UNREGISTER) {
5957 + msm_bus_dbg_free_client(clid);
5958 + MSM_BUS_DBG("Client %d unregistered\n", clid);
5959 + } else
5960 + msm_bus_dbg_fill_cl_buffer(pdata, index, clid);
5961 +}
5962 +EXPORT_SYMBOL(msm_bus_dbg_client_data);
5963 +
5964 +/**
5965 + * msm_bus_dbg_commit_data() - Add commit data from fabrics
5966 + * @fabname: Fabric name specified in platform data
5967 + * @cdata: Commit Data
5968 + * @nmasters: Number of masters attached to fabric
5969 + * @nslaves: Number of slaves attached to fabric
5970 + * @ntslaves: Number of tiered slaves attached to fabric
5971 + * @op: Operation to be performed
5972 + */
5973 +void msm_bus_dbg_commit_data(const char *fabname, void *cdata,
5974 + int nmasters, int nslaves, int ntslaves, int op)
5975 +{
5976 + struct dentry *file = NULL;
5977 +
5978 + if (op == MSM_BUS_DBG_REGISTER)
5979 + msm_bus_dbg_record_fabric(fabname, file);
5980 + else if (op == MSM_BUS_DBG_UNREGISTER)
5981 + msm_bus_dbg_free_fabric(fabname);
5982 + else
5983 + msm_bus_dbg_fill_fab_buffer(fabname, cdata, nmasters,
5984 + nslaves, ntslaves);
5985 +}
5986 +EXPORT_SYMBOL(msm_bus_dbg_commit_data);
5987 +#endif
5988 +
5989 +static int __init msm_bus_debugfs_init(void)
5990 +{
5991 + struct dentry *commit, *shell_client, *rules_dbg;
5992 + struct msm_bus_fab_list *fablist;
5993 + struct msm_bus_cldata *cldata = NULL;
5994 + uint64_t val = 0;
5995 +
5996 + dir = debugfs_create_dir("msm-bus-dbg", NULL);
5997 + if ((!dir) || IS_ERR(dir)) {
5998 + MSM_BUS_ERR("Couldn't create msm-bus-dbg\n");
5999 + goto err;
6000 + }
6001 +
6002 + clients = debugfs_create_dir("client-data", dir);
6003 + if ((!dir) || IS_ERR(dir)) {
6004 + MSM_BUS_ERR("Couldn't create clients\n");
6005 + goto err;
6006 + }
6007 +
6008 + shell_client = debugfs_create_dir("shell-client", dir);
6009 + if ((!dir) || IS_ERR(dir)) {
6010 + MSM_BUS_ERR("Couldn't create clients\n");
6011 + goto err;
6012 + }
6013 +
6014 + commit = debugfs_create_dir("commit-data", dir);
6015 + if ((!dir) || IS_ERR(dir)) {
6016 + MSM_BUS_ERR("Couldn't create commit\n");
6017 + goto err;
6018 + }
6019 +
6020 + rules_dbg = debugfs_create_dir("rules-dbg", dir);
6021 + if ((!rules_dbg) || IS_ERR(rules_dbg)) {
6022 + MSM_BUS_ERR("Couldn't create rules-dbg\n");
6023 + goto err;
6024 + }
6025 +
6026 + if (debugfs_create_file("print_rules", S_IRUGO | S_IWUSR,
6027 + rules_dbg, &val, &rules_dbg_fops) == NULL)
6028 + goto err;
6029 +
6030 + if (debugfs_create_file("update_request", S_IRUGO | S_IWUSR,
6031 + shell_client, &val, &shell_client_en_fops) == NULL)
6032 + goto err;
6033 + if (debugfs_create_file("ib", S_IRUGO | S_IWUSR, shell_client, &val,
6034 + &shell_client_ib_fops) == NULL)
6035 + goto err;
6036 + if (debugfs_create_file("ab", S_IRUGO | S_IWUSR, shell_client, &val,
6037 + &shell_client_ab_fops) == NULL)
6038 + goto err;
6039 + if (debugfs_create_file("slv", S_IRUGO | S_IWUSR, shell_client,
6040 + &val, &shell_client_slv_fops) == NULL)
6041 + goto err;
6042 + if (debugfs_create_file("mas", S_IRUGO | S_IWUSR, shell_client,
6043 + &val, &shell_client_mas_fops) == NULL)
6044 + goto err;
6045 + if (debugfs_create_file("update-request", S_IRUGO | S_IWUSR,
6046 + clients, NULL, &msm_bus_dbg_update_request_fops) == NULL)
6047 + goto err;
6048 +
6049 + rules_buf = kzalloc(MAX_BUFF_SIZE, GFP_KERNEL);
6050 + if (!rules_buf) {
6051 + MSM_BUS_ERR("Failed to alloc rules_buf");
6052 + goto err;
6053 + }
6054 +
6055 + list_for_each_entry(cldata, &cl_list, list) {
6056 + if (cldata->pdata->name == NULL) {
6057 + MSM_BUS_DBG("Client name not found\n");
6058 + continue;
6059 + }
6060 + cldata->file = msm_bus_dbg_create(cldata->
6061 + pdata->name, S_IRUGO, clients, cldata->clid);
6062 + }
6063 +
6064 + mutex_lock(&msm_bus_dbg_fablist_lock);
6065 + list_for_each_entry(fablist, &fabdata_list, list) {
6066 + fablist->file = debugfs_create_file(fablist->name, S_IRUGO,
6067 + commit, (void *)fablist->name, &fabric_data_fops);
6068 + if (fablist->file == NULL) {
6069 + MSM_BUS_DBG("Cannot create files for commit data\n");
6070 + kfree(rules_buf);
6071 + goto err;
6072 + }
6073 + }
6074 + mutex_unlock(&msm_bus_dbg_fablist_lock);
6075 +
6076 + msm_bus_dbg_init_vectors();
6077 + return 0;
6078 +err:
6079 + debugfs_remove_recursive(dir);
6080 + return -ENODEV;
6081 +}
6082 +late_initcall(msm_bus_debugfs_init);
6083 +
6084 +static void __exit msm_bus_dbg_teardown(void)
6085 +{
6086 + struct msm_bus_fab_list *fablist = NULL, *fablist_temp;
6087 + struct msm_bus_cldata *cldata = NULL, *cldata_temp;
6088 +
6089 + debugfs_remove_recursive(dir);
6090 + list_for_each_entry_safe(cldata, cldata_temp, &cl_list, list) {
6091 + list_del(&cldata->list);
6092 + kfree(cldata);
6093 + }
6094 + mutex_lock(&msm_bus_dbg_fablist_lock);
6095 + list_for_each_entry_safe(fablist, fablist_temp, &fabdata_list, list) {
6096 + list_del(&fablist->list);
6097 + kfree(fablist);
6098 + }
6099 + kfree(rules_buf);
6100 + mutex_unlock(&msm_bus_dbg_fablist_lock);
6101 +}
6102 +module_exit(msm_bus_dbg_teardown);
6103 +MODULE_DESCRIPTION("Debugfs for msm bus scaling client");
6104 +MODULE_LICENSE("GPL v2");
6105 +MODULE_AUTHOR("Gagan Mac <gmac@codeaurora.org>");
6106 --- /dev/null
6107 +++ b/drivers/bus/msm_bus/msm_bus_fabric_adhoc.c
6108 @@ -0,0 +1,1281 @@
6109 +/* Copyright (c) 2014, Linux Foundation. All rights reserved.
6110 + *
6111 + * This program is free software; you can redistribute it and/or modify
6112 + * it under the terms of the GNU General Public License version 2 and
6113 + * only version 2 as published by the Free Software Foundation.
6114 + *
6115 + * This program is distributed in the hope that it will be useful,
6116 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
6117 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6118 + * GNU General Public License for more details.
6119 + */
6120 +
6121 +#include <linux/clk.h>
6122 +#include <linux/device.h>
6123 +#include <linux/init.h>
6124 +#include <linux/io.h>
6125 +#include <linux/kernel.h>
6126 +#include <linux/module.h>
6127 +#include <linux/slab.h>
6128 +#include "rpm-smd.h"
6129 +#include "msm_bus_core.h"
6130 +#include "msm_bus_adhoc.h"
6131 +#include "msm_bus_noc.h"
6132 +#include "msm_bus_bimc.h"
6133 +
6134 +ssize_t vrail_show(struct device *dev, struct device_attribute *attr,
6135 + char *buf)
6136 +{
6137 + struct msm_bus_node_info_type *node_info = NULL;
6138 + struct msm_bus_node_device_type *bus_node = NULL;
6139 +
6140 + bus_node = dev->platform_data;
6141 + if (!bus_node)
6142 + return -EINVAL;
6143 + node_info = bus_node->node_info;
6144 +
6145 + return snprintf(buf, PAGE_SIZE, "%u", node_info->vrail_comp);
6146 +}
6147 +
6148 +ssize_t vrail_store(struct device *dev, struct device_attribute *attr,
6149 + const char *buf, size_t count)
6150 +{
6151 + struct msm_bus_node_info_type *node_info = NULL;
6152 + struct msm_bus_node_device_type *bus_node = NULL;
6153 + int ret = 0;
6154 +
6155 + bus_node = dev->platform_data;
6156 + if (!bus_node)
6157 + return -EINVAL;
6158 + node_info = bus_node->node_info;
6159 +
6160 + ret = sscanf(buf, "%u", &node_info->vrail_comp);
6161 + if (ret != 1)
6162 + return -EINVAL;
6163 + return count;
6164 +}
6165 +
6166 +DEVICE_ATTR(vrail, 0600, vrail_show, vrail_store);
6167 +
6168 +struct static_rules_type {
6169 + int num_rules;
6170 + struct bus_rule_type *rules;
6171 +};
6172 +
6173 +static struct static_rules_type static_rules;
6174 +
6175 +static int enable_nodeclk(struct nodeclk *nclk)
6176 +{
6177 + int ret = 0;
6178 +
6179 + if (!nclk->enable) {
6180 + ret = clk_prepare_enable(nclk->clk);
6181 +
6182 + if (ret) {
6183 + MSM_BUS_ERR("%s: failed to enable clk ", __func__);
6184 + nclk->enable = false;
6185 + } else
6186 + nclk->enable = true;
6187 + }
6188 + return ret;
6189 +}
6190 +
6191 +static int disable_nodeclk(struct nodeclk *nclk)
6192 +{
6193 + int ret = 0;
6194 +
6195 + if (nclk->enable) {
6196 + clk_disable_unprepare(nclk->clk);
6197 + nclk->enable = false;
6198 + }
6199 + return ret;
6200 +}
6201 +
6202 +static int setrate_nodeclk(struct nodeclk *nclk, long rate)
6203 +{
6204 + int ret = 0;
6205 +
6206 + ret = clk_set_rate(nclk->clk, rate);
6207 +
6208 + if (ret)
6209 + MSM_BUS_ERR("%s: failed to setrate clk", __func__);
6210 + return ret;
6211 +}
6212 +
6213 +static int msm_bus_agg_fab_clks(struct device *bus_dev, void *data)
6214 +{
6215 + struct msm_bus_node_device_type *node = NULL;
6216 + int ret = 0;
6217 + int ctx = *(int *)data;
6218 +
6219 + if (ctx >= NUM_CTX) {
6220 + MSM_BUS_ERR("%s: Invalid Context %d", __func__, ctx);
6221 + goto exit_agg_fab_clks;
6222 + }
6223 +
6224 + node = bus_dev->platform_data;
6225 + if (!node) {
6226 + MSM_BUS_ERR("%s: Can't get device info", __func__);
6227 + goto exit_agg_fab_clks;
6228 + }
6229 +
6230 + if (!node->node_info->is_fab_dev) {
6231 + struct msm_bus_node_device_type *bus_dev = NULL;
6232 +
6233 + bus_dev = node->node_info->bus_device->platform_data;
6234 +
6235 + if (node->cur_clk_hz[ctx] >= bus_dev->cur_clk_hz[ctx])
6236 + bus_dev->cur_clk_hz[ctx] = node->cur_clk_hz[ctx];
6237 + }
6238 +
6239 +exit_agg_fab_clks:
6240 + return ret;
6241 +}
6242 +
6243 +static int msm_bus_reset_fab_clks(struct device *bus_dev, void *data)
6244 +{
6245 + struct msm_bus_node_device_type *node = NULL;
6246 + int ret = 0;
6247 + int ctx = *(int *)data;
6248 +
6249 + if (ctx >= NUM_CTX) {
6250 + MSM_BUS_ERR("%s: Invalid Context %d", __func__, ctx);
6251 + goto exit_reset_fab_clks;
6252 + }
6253 +
6254 + node = bus_dev->platform_data;
6255 + if (!node) {
6256 + MSM_BUS_ERR("%s: Can't get device info", __func__);
6257 + goto exit_reset_fab_clks;
6258 + }
6259 +
6260 + if (node->node_info->is_fab_dev) {
6261 + node->cur_clk_hz[ctx] = 0;
6262 + MSM_BUS_DBG("Resetting for node %d", node->node_info->id);
6263 + }
6264 +exit_reset_fab_clks:
6265 + return ret;
6266 +}
6267 +
6268 +
6269 +static int send_rpm_msg(struct device *device)
6270 +{
6271 + int ret = 0;
6272 + int ctx;
6273 + int rsc_type;
6274 + struct msm_bus_node_device_type *ndev =
6275 + device->platform_data;
6276 + struct msm_rpm_kvp rpm_kvp;
6277 +
6278 + if (!ndev) {
6279 + MSM_BUS_ERR("%s: Error getting node info.", __func__);
6280 + ret = -ENODEV;
6281 + goto exit_send_rpm_msg;
6282 + }
6283 +
6284 + rpm_kvp.length = sizeof(uint64_t);
6285 + rpm_kvp.key = RPM_MASTER_FIELD_BW;
6286 +
6287 + for (ctx = MSM_RPM_CTX_ACTIVE_SET; ctx <= MSM_RPM_CTX_SLEEP_SET;
6288 + ctx++) {
6289 + if (ctx == MSM_RPM_CTX_ACTIVE_SET)
6290 + rpm_kvp.data =
6291 + (uint8_t *)&ndev->node_ab.ab[MSM_RPM_CTX_ACTIVE_SET];
6292 + else {
6293 + rpm_kvp.data =
6294 + (uint8_t *) &ndev->node_ab.ab[MSM_RPM_CTX_SLEEP_SET];
6295 + }
6296 +
6297 + if (ndev->node_info->mas_rpm_id != -1) {
6298 + rsc_type = RPM_BUS_MASTER_REQ;
6299 + ret = msm_rpm_send_message(ctx, rsc_type,
6300 + ndev->node_info->mas_rpm_id, &rpm_kvp, 1);
6301 + if (ret) {
6302 + MSM_BUS_ERR("%s: Failed to send RPM message:",
6303 + __func__);
6304 + MSM_BUS_ERR("%s:Node Id %d RPM id %d",
6305 + __func__, ndev->node_info->id,
6306 + ndev->node_info->mas_rpm_id);
6307 + goto exit_send_rpm_msg;
6308 + }
6309 + }
6310 +
6311 + if (ndev->node_info->slv_rpm_id != -1) {
6312 + rsc_type = RPM_BUS_SLAVE_REQ;
6313 + ret = msm_rpm_send_message(ctx, rsc_type,
6314 + ndev->node_info->slv_rpm_id, &rpm_kvp, 1);
6315 + if (ret) {
6316 + MSM_BUS_ERR("%s: Failed to send RPM message:",
6317 + __func__);
6318 + MSM_BUS_ERR("%s: Node Id %d RPM id %d",
6319 + __func__, ndev->node_info->id,
6320 + ndev->node_info->slv_rpm_id);
6321 + goto exit_send_rpm_msg;
6322 + }
6323 + }
6324 + }
6325 +exit_send_rpm_msg:
6326 + return ret;
6327 +}
6328 +
6329 +static int flush_bw_data(struct device *node_device, int ctx)
6330 +{
6331 + struct msm_bus_node_device_type *node_info;
6332 + int ret = 0;
6333 +
6334 + node_info = node_device->platform_data;
6335 + if (!node_info) {
6336 + MSM_BUS_ERR("%s: Unable to find bus device for device",
6337 + __func__);
6338 + ret = -ENODEV;
6339 + goto exit_flush_bw_data;
6340 + }
6341 +
6342 + if (node_info->node_ab.dirty) {
6343 + if (node_info->ap_owned) {
6344 + struct msm_bus_node_device_type *bus_device =
6345 + node_info->node_info->bus_device->platform_data;
6346 + struct msm_bus_fab_device_type *fabdev =
6347 + bus_device->fabdev;
6348 +
6349 + if (fabdev && fabdev->noc_ops.update_bw_reg &&
6350 + fabdev->noc_ops.update_bw_reg
6351 + (node_info->node_info->qos_params.mode))
6352 + ret = fabdev->noc_ops.set_bw(node_info,
6353 + fabdev->qos_base,
6354 + fabdev->base_offset,
6355 + fabdev->qos_off,
6356 + fabdev->qos_freq);
6357 + } else {
6358 + ret = send_rpm_msg(node_device);
6359 +
6360 + if (ret)
6361 + MSM_BUS_ERR("%s: Failed to send RPM msg for%d",
6362 + __func__, node_info->node_info->id);
6363 + }
6364 + node_info->node_ab.dirty = false;
6365 + }
6366 +
6367 +exit_flush_bw_data:
6368 + return ret;
6369 +
6370 +}
6371 +
6372 +static int flush_clk_data(struct device *node_device, int ctx)
6373 +{
6374 + struct msm_bus_node_device_type *node;
6375 + struct nodeclk *nodeclk = NULL;
6376 + int ret = 0;
6377 +
6378 + node = node_device->platform_data;
6379 + if (!node) {
6380 + MSM_BUS_ERR("Unable to find bus device");
6381 + ret = -ENODEV;
6382 + goto exit_flush_clk_data;
6383 + }
6384 +
6385 + nodeclk = &node->clk[ctx];
6386 + if (node->node_info->is_fab_dev) {
6387 + if (nodeclk->rate != node->cur_clk_hz[ctx]) {
6388 + nodeclk->rate = node->cur_clk_hz[ctx];
6389 + nodeclk->dirty = true;
6390 + }
6391 + }
6392 +
6393 + if (nodeclk && nodeclk->clk && nodeclk->dirty) {
6394 + long rounded_rate;
6395 +
6396 + if (nodeclk->rate) {
6397 + rounded_rate = clk_round_rate(nodeclk->clk,
6398 + nodeclk->rate);
6399 + ret = setrate_nodeclk(nodeclk, rounded_rate);
6400 +
6401 + if (ret) {
6402 + MSM_BUS_ERR("%s: Failed to set_rate %lu for %d",
6403 + __func__, rounded_rate,
6404 + node->node_info->id);
6405 + ret = -ENODEV;
6406 + goto exit_flush_clk_data;
6407 + }
6408 +
6409 + ret = enable_nodeclk(nodeclk);
6410 + } else
6411 + ret = disable_nodeclk(nodeclk);
6412 +
6413 + if (ret) {
6414 + MSM_BUS_ERR("%s: Failed to enable for %d", __func__,
6415 + node->node_info->id);
6416 + ret = -ENODEV;
6417 + goto exit_flush_clk_data;
6418 + }
6419 + MSM_BUS_DBG("%s: Updated %d clk to %llu", __func__,
6420 + node->node_info->id, nodeclk->rate);
6421 +
6422 + }
6423 +exit_flush_clk_data:
6424 + /* Reset the aggregated clock rate for fab devices*/
6425 + if (node && node->node_info->is_fab_dev)
6426 + node->cur_clk_hz[ctx] = 0;
6427 +
6428 + if (nodeclk)
6429 + nodeclk->dirty = 0;
6430 + return ret;
6431 +}
6432 +
6433 +int msm_bus_commit_data(int *dirty_nodes, int ctx, int num_dirty)
6434 +{
6435 + int ret = 0;
6436 + int i = 0;
6437 +
6438 + /* Aggregate the bus clocks */
6439 + bus_for_each_dev(&msm_bus_type, NULL, (void *)&ctx,
6440 + msm_bus_agg_fab_clks);
6441 +
6442 + for (i = 0; i < num_dirty; i++) {
6443 + struct device *node_device =
6444 + bus_find_device(&msm_bus_type, NULL,
6445 + (void *)&dirty_nodes[i],
6446 + msm_bus_device_match_adhoc);
6447 +
6448 + if (!node_device) {
6449 + MSM_BUS_ERR("Can't find device for %d", dirty_nodes[i]);
6450 + continue;
6451 + }
6452 +
6453 + ret = flush_bw_data(node_device, ctx);
6454 + if (ret)
6455 + MSM_BUS_ERR("%s: Error flushing bw data for node %d",
6456 + __func__, dirty_nodes[i]);
6457 +
6458 + ret = flush_clk_data(node_device, ctx);
6459 + if (ret)
6460 + MSM_BUS_ERR("%s: Error flushing clk data for node %d",
6461 + __func__, dirty_nodes[i]);
6462 + }
6463 + kfree(dirty_nodes);
6464 + /* Aggregate the bus clocks */
6465 + bus_for_each_dev(&msm_bus_type, NULL, (void *)&ctx,
6466 + msm_bus_reset_fab_clks);
6467 + return ret;
6468 +}
6469 +
6470 +void *msm_bus_realloc_devmem(struct device *dev, void *p, size_t old_size,
6471 + size_t new_size, gfp_t flags)
6472 +{
6473 + void *ret;
6474 + size_t copy_size = old_size;
6475 +
6476 + if (!new_size) {
6477 + devm_kfree(dev, p);
6478 + return ZERO_SIZE_PTR;
6479 + }
6480 +
6481 + if (new_size < old_size)
6482 + copy_size = new_size;
6483 +
6484 + ret = devm_kzalloc(dev, new_size, flags);
6485 + if (!ret) {
6486 + MSM_BUS_ERR("%s: Error Reallocating memory", __func__);
6487 + goto exit_realloc_devmem;
6488 + }
6489 +
6490 + memcpy(ret, p, copy_size);
6491 + devm_kfree(dev, p);
6492 +exit_realloc_devmem:
6493 + return ret;
6494 +}
6495 +
6496 +
6497 +static int add_dirty_node(int **dirty_nodes, int id, int *num_dirty)
6498 +{
6499 + int i;
6500 + int found = 0;
6501 + int ret = 0;
6502 + int *dnode = NULL;
6503 +
6504 + for (i = 0; i < *num_dirty; i++) {
6505 + if ((*dirty_nodes)[i] == id) {
6506 + found = 1;
6507 + break;
6508 + }
6509 + }
6510 +
6511 + if (!found) {
6512 + (*num_dirty)++;
6513 + dnode =
6514 + krealloc(*dirty_nodes, sizeof(int) * (*num_dirty),
6515 + GFP_KERNEL);
6516 +
6517 + if (ZERO_OR_NULL_PTR(dnode)) {
6518 + MSM_BUS_ERR("%s: Failure allocating dirty nodes array",
6519 + __func__);
6520 + ret = -ENOMEM;
6521 + } else {
6522 + *dirty_nodes = dnode;
6523 + (*dirty_nodes)[(*num_dirty) - 1] = id;
6524 + }
6525 + }
6526 +
6527 + return ret;
6528 +}
6529 +
6530 +int msm_bus_update_bw(struct msm_bus_node_device_type *nodedev, int ctx,
6531 + int64_t add_bw, int **dirty_nodes, int *num_dirty)
6532 +{
6533 + int ret = 0;
6534 + int i, j;
6535 + uint64_t cur_ab_slp = 0;
6536 + uint64_t cur_ab_act = 0;
6537 +
6538 + if (nodedev->node_info->virt_dev)
6539 + goto exit_update_bw;
6540 +
6541 + for (i = 0; i < NUM_CTX; i++) {
6542 + for (j = 0; j < nodedev->num_lnodes; j++) {
6543 + if (i == DUAL_CTX) {
6544 + cur_ab_act +=
6545 + nodedev->lnode_list[j].lnode_ab[i];
6546 + cur_ab_slp +=
6547 + nodedev->lnode_list[j].lnode_ab[i];
6548 + } else
6549 + cur_ab_act +=
6550 + nodedev->lnode_list[j].lnode_ab[i];
6551 + }
6552 + }
6553 +
6554 + if (nodedev->node_ab.ab[MSM_RPM_CTX_ACTIVE_SET] != cur_ab_act) {
6555 + nodedev->node_ab.ab[MSM_RPM_CTX_ACTIVE_SET] = cur_ab_act;
6556 + nodedev->node_ab.ab[MSM_RPM_CTX_SLEEP_SET] = cur_ab_slp;
6557 + nodedev->node_ab.dirty = true;
6558 + ret = add_dirty_node(dirty_nodes, nodedev->node_info->id,
6559 + num_dirty);
6560 +
6561 + if (ret) {
6562 + MSM_BUS_ERR("%s: Failed to add dirty node %d", __func__,
6563 + nodedev->node_info->id);
6564 + goto exit_update_bw;
6565 + }
6566 + }
6567 +
6568 +exit_update_bw:
6569 + return ret;
6570 +}
6571 +
6572 +int msm_bus_update_clks(struct msm_bus_node_device_type *nodedev,
6573 + int ctx, int **dirty_nodes, int *num_dirty)
6574 +{
6575 + int status = 0;
6576 + struct nodeclk *nodeclk;
6577 + struct nodeclk *busclk;
6578 + struct msm_bus_node_device_type *bus_info = NULL;
6579 + uint64_t req_clk;
6580 +
6581 + bus_info = nodedev->node_info->bus_device->platform_data;
6582 +
6583 + if (!bus_info) {
6584 + MSM_BUS_ERR("%s: Unable to find bus device for device %d",
6585 + __func__, nodedev->node_info->id);
6586 + status = -ENODEV;
6587 + goto exit_set_clks;
6588 + }
6589 +
6590 + req_clk = nodedev->cur_clk_hz[ctx];
6591 + busclk = &bus_info->clk[ctx];
6592 +
6593 + if (busclk->rate != req_clk) {
6594 + busclk->rate = req_clk;
6595 + busclk->dirty = 1;
6596 + MSM_BUS_DBG("%s: Modifying bus clk %d Rate %llu", __func__,
6597 + bus_info->node_info->id, req_clk);
6598 + status = add_dirty_node(dirty_nodes, bus_info->node_info->id,
6599 + num_dirty);
6600 +
6601 + if (status) {
6602 + MSM_BUS_ERR("%s: Failed to add dirty node %d", __func__,
6603 + bus_info->node_info->id);
6604 + goto exit_set_clks;
6605 + }
6606 + }
6607 +
6608 + req_clk = nodedev->cur_clk_hz[ctx];
6609 + nodeclk = &nodedev->clk[ctx];
6610 +
6611 + if (IS_ERR_OR_NULL(nodeclk))
6612 + goto exit_set_clks;
6613 +
6614 + if (!nodeclk->dirty || (nodeclk->dirty && (nodeclk->rate < req_clk))) {
6615 + nodeclk->rate = req_clk;
6616 + nodeclk->dirty = 1;
6617 + MSM_BUS_DBG("%s: Modifying node clk %d Rate %llu", __func__,
6618 + nodedev->node_info->id, req_clk);
6619 + status = add_dirty_node(dirty_nodes, nodedev->node_info->id,
6620 + num_dirty);
6621 + if (status) {
6622 + MSM_BUS_ERR("%s: Failed to add dirty node %d", __func__,
6623 + nodedev->node_info->id);
6624 + goto exit_set_clks;
6625 + }
6626 + }
6627 +
6628 +exit_set_clks:
6629 + return status;
6630 +}
6631 +
6632 +static void msm_bus_fab_init_noc_ops(struct msm_bus_node_device_type *bus_dev)
6633 +{
6634 + switch (bus_dev->fabdev->bus_type) {
6635 + case MSM_BUS_NOC:
6636 + msm_bus_noc_set_ops(bus_dev);
6637 + break;
6638 + case MSM_BUS_BIMC:
6639 + msm_bus_bimc_set_ops(bus_dev);
6640 + break;
6641 + default:
6642 + MSM_BUS_ERR("%s: Invalid Bus type", __func__);
6643 + }
6644 +}
6645 +
6646 +static int msm_bus_qos_disable_clk(struct msm_bus_node_device_type *node,
6647 + int disable_bus_qos_clk)
6648 +{
6649 + struct msm_bus_node_device_type *bus_node = NULL;
6650 + int ret = 0;
6651 +
6652 + if (!node) {
6653 + ret = -ENXIO;
6654 + goto exit_disable_qos_clk;
6655 + }
6656 +
6657 + bus_node = node->node_info->bus_device->platform_data;
6658 +
6659 + if (!bus_node) {
6660 + ret = -ENXIO;
6661 + goto exit_disable_qos_clk;
6662 + }
6663 +
6664 + if (disable_bus_qos_clk)
6665 + ret = disable_nodeclk(&bus_node->clk[DUAL_CTX]);
6666 +
6667 + if (ret) {
6668 + MSM_BUS_ERR("%s: Failed to disable bus clk, node %d",
6669 + __func__, node->node_info->id);
6670 + goto exit_disable_qos_clk;
6671 + }
6672 +
6673 + if (!IS_ERR_OR_NULL(node->qos_clk.clk)) {
6674 + ret = disable_nodeclk(&node->qos_clk);
6675 +
6676 + if (ret) {
6677 + MSM_BUS_ERR("%s: Failed to disable mas qos clk,node %d",
6678 + __func__, node->node_info->id);
6679 + goto exit_disable_qos_clk;
6680 + }
6681 + }
6682 +
6683 +exit_disable_qos_clk:
6684 + return ret;
6685 +}
6686 +
6687 +static int msm_bus_qos_enable_clk(struct msm_bus_node_device_type *node)
6688 +{
6689 + struct msm_bus_node_device_type *bus_node = NULL;
6690 + long rounded_rate;
6691 + int ret = 0;
6692 + int bus_qos_enabled = 0;
6693 +
6694 + if (!node) {
6695 + ret = -ENXIO;
6696 + goto exit_enable_qos_clk;
6697 + }
6698 +
6699 + bus_node = node->node_info->bus_device->platform_data;
6700 +
6701 + if (!bus_node) {
6702 + ret = -ENXIO;
6703 + goto exit_enable_qos_clk;
6704 + }
6705 +
6706 + /* Check if the bus clk is already set before trying to set it
6707 + * Do this only during
6708 + * a. Bootup
6709 + * b. Only for bus clks
6710 + **/
6711 + if (!clk_get_rate(bus_node->clk[DUAL_CTX].clk)) {
6712 + rounded_rate = clk_round_rate(bus_node->clk[DUAL_CTX].clk, 1);
6713 + ret = setrate_nodeclk(&bus_node->clk[DUAL_CTX], rounded_rate);
6714 + if (ret) {
6715 + MSM_BUS_ERR("%s: Failed to set bus clk, node %d",
6716 + __func__, node->node_info->id);
6717 + goto exit_enable_qos_clk;
6718 + }
6719 +
6720 + ret = enable_nodeclk(&bus_node->clk[DUAL_CTX]);
6721 + if (ret) {
6722 + MSM_BUS_ERR("%s: Failed to enable bus clk, node %d",
6723 + __func__, node->node_info->id);
6724 + goto exit_enable_qos_clk;
6725 + }
6726 + bus_qos_enabled = 1;
6727 + }
6728 +
6729 + if (!IS_ERR_OR_NULL(node->qos_clk.clk)) {
6730 + rounded_rate = clk_round_rate(node->qos_clk.clk, 1);
6731 + ret = setrate_nodeclk(&node->qos_clk, rounded_rate);
6732 + if (ret) {
6733 + MSM_BUS_ERR("%s: Failed to enable mas qos clk, node %d",
6734 + __func__, node->node_info->id);
6735 + goto exit_enable_qos_clk;
6736 + }
6737 +
6738 + ret = enable_nodeclk(&node->qos_clk);
6739 + if (ret) {
6740 + MSM_BUS_ERR("Err enable mas qos clk, node %d ret %d",
6741 + node->node_info->id, ret);
6742 + goto exit_enable_qos_clk;
6743 + }
6744 + }
6745 + ret = bus_qos_enabled;
6746 +
6747 +exit_enable_qos_clk:
6748 + return ret;
6749 +}
6750 +
6751 +int msm_bus_enable_limiter(struct msm_bus_node_device_type *node_dev,
6752 + bool enable, uint64_t lim_bw)
6753 +{
6754 + int ret = 0;
6755 + struct msm_bus_node_device_type *bus_node_dev;
6756 +
6757 + if (!node_dev) {
6758 + MSM_BUS_ERR("No device specified");
6759 + ret = -ENXIO;
6760 + goto exit_enable_limiter;
6761 + }
6762 +
6763 + if (!node_dev->ap_owned) {
6764 + MSM_BUS_ERR("Device is not AP owned %d.",
6765 + node_dev->node_info->id);
6766 + ret = -ENXIO;
6767 + goto exit_enable_limiter;
6768 + }
6769 +
6770 + bus_node_dev = node_dev->node_info->bus_device->platform_data;
6771 + if (!bus_node_dev) {
6772 + MSM_BUS_ERR("Unable to get bus device infofor %d",
6773 + node_dev->node_info->id);
6774 + ret = -ENXIO;
6775 + goto exit_enable_limiter;
6776 + }
6777 + if (bus_node_dev->fabdev &&
6778 + bus_node_dev->fabdev->noc_ops.limit_mport) {
6779 + ret = msm_bus_qos_enable_clk(node_dev);
6780 + if (ret < 0) {
6781 + MSM_BUS_ERR("Can't Enable QoS clk %d",
6782 + node_dev->node_info->id);
6783 + goto exit_enable_limiter;
6784 + }
6785 + bus_node_dev->fabdev->noc_ops.limit_mport(
6786 + node_dev,
6787 + bus_node_dev->fabdev->qos_base,
6788 + bus_node_dev->fabdev->base_offset,
6789 + bus_node_dev->fabdev->qos_off,
6790 + bus_node_dev->fabdev->qos_freq,
6791 + enable, lim_bw);
6792 + msm_bus_qos_disable_clk(node_dev, ret);
6793 + }
6794 +
6795 +exit_enable_limiter:
6796 + return ret;
6797 +}
6798 +
6799 +static int msm_bus_dev_init_qos(struct device *dev, void *data)
6800 +{
6801 + int ret = 0;
6802 + struct msm_bus_node_device_type *node_dev = NULL;
6803 +
6804 + node_dev = dev->platform_data;
6805 +
6806 + if (!node_dev) {
6807 + MSM_BUS_ERR("%s: Unable to get node device info" , __func__);
6808 + ret = -ENXIO;
6809 + goto exit_init_qos;
6810 + }
6811 +
6812 + MSM_BUS_DBG("Device = %d", node_dev->node_info->id);
6813 +
6814 + if (node_dev->ap_owned) {
6815 + struct msm_bus_node_device_type *bus_node_info;
6816 +
6817 + bus_node_info = node_dev->node_info->bus_device->platform_data;
6818 +
6819 + if (!bus_node_info) {
6820 + MSM_BUS_ERR("%s: Unable to get bus device infofor %d",
6821 + __func__,
6822 + node_dev->node_info->id);
6823 + ret = -ENXIO;
6824 + goto exit_init_qos;
6825 + }
6826 +
6827 + if (bus_node_info->fabdev &&
6828 + bus_node_info->fabdev->noc_ops.qos_init) {
6829 + int ret = 0;
6830 +
6831 + if (node_dev->ap_owned &&
6832 + (node_dev->node_info->qos_params.mode) != -1) {
6833 +
6834 + if (bus_node_info->fabdev->bypass_qos_prg)
6835 + goto exit_init_qos;
6836 +
6837 + ret = msm_bus_qos_enable_clk(node_dev);
6838 + if (ret < 0) {
6839 + MSM_BUS_ERR("Can't Enable QoS clk %d",
6840 + node_dev->node_info->id);
6841 + goto exit_init_qos;
6842 + }
6843 +
6844 + bus_node_info->fabdev->noc_ops.qos_init(
6845 + node_dev,
6846 + bus_node_info->fabdev->qos_base,
6847 + bus_node_info->fabdev->base_offset,
6848 + bus_node_info->fabdev->qos_off,
6849 + bus_node_info->fabdev->qos_freq);
6850 + msm_bus_qos_disable_clk(node_dev, ret);
6851 + }
6852 + } else
6853 + MSM_BUS_ERR("%s: Skipping QOS init for %d",
6854 + __func__, node_dev->node_info->id);
6855 + }
6856 +exit_init_qos:
6857 + return ret;
6858 +}
6859 +
6860 +static int msm_bus_fabric_init(struct device *dev,
6861 + struct msm_bus_node_device_type *pdata)
6862 +{
6863 + struct msm_bus_fab_device_type *fabdev;
6864 + struct msm_bus_node_device_type *node_dev = NULL;
6865 + int ret = 0;
6866 +
6867 + node_dev = dev->platform_data;
6868 + if (!node_dev) {
6869 + MSM_BUS_ERR("%s: Unable to get bus device info" , __func__);
6870 + ret = -ENXIO;
6871 + goto exit_fabric_init;
6872 + }
6873 +
6874 + if (node_dev->node_info->virt_dev) {
6875 + MSM_BUS_ERR("%s: Skip Fab init for virtual device %d", __func__,
6876 + node_dev->node_info->id);
6877 + goto exit_fabric_init;
6878 + }
6879 +
6880 + fabdev = devm_kzalloc(dev, sizeof(struct msm_bus_fab_device_type),
6881 + GFP_KERNEL);
6882 + if (!fabdev) {
6883 + MSM_BUS_ERR("Fabric alloc failed\n");
6884 + ret = -ENOMEM;
6885 + goto exit_fabric_init;
6886 + }
6887 +
6888 + node_dev->fabdev = fabdev;
6889 + fabdev->pqos_base = pdata->fabdev->pqos_base;
6890 + fabdev->qos_range = pdata->fabdev->qos_range;
6891 + fabdev->base_offset = pdata->fabdev->base_offset;
6892 + fabdev->qos_off = pdata->fabdev->qos_off;
6893 + fabdev->qos_freq = pdata->fabdev->qos_freq;
6894 + fabdev->bus_type = pdata->fabdev->bus_type;
6895 + fabdev->bypass_qos_prg = pdata->fabdev->bypass_qos_prg;
6896 + fabdev->util_fact = pdata->fabdev->util_fact;
6897 + fabdev->vrail_comp = pdata->fabdev->vrail_comp;
6898 + msm_bus_fab_init_noc_ops(node_dev);
6899 +
6900 + fabdev->qos_base = devm_ioremap(dev,
6901 + fabdev->pqos_base, fabdev->qos_range);
6902 + if (!fabdev->qos_base) {
6903 + MSM_BUS_ERR("%s: Error remapping address 0x%zx :bus device %d",
6904 + __func__,
6905 + (size_t)fabdev->pqos_base, node_dev->node_info->id);
6906 + ret = -ENOMEM;
6907 + goto exit_fabric_init;
6908 + }
6909 +
6910 + /*if (msmbus_coresight_init(pdev))
6911 + pr_warn("Coresight support absent for bus: %d\n", pdata->id);*/
6912 +exit_fabric_init:
6913 + return ret;
6914 +}
6915 +
6916 +static int msm_bus_init_clk(struct device *bus_dev,
6917 + struct msm_bus_node_device_type *pdata)
6918 +{
6919 + unsigned int ctx;
6920 + int ret = 0;
6921 + struct msm_bus_node_device_type *node_dev = bus_dev->platform_data;
6922 +
6923 + for (ctx = 0; ctx < NUM_CTX; ctx++) {
6924 + if (!IS_ERR_OR_NULL(pdata->clk[ctx].clk)) {
6925 + node_dev->clk[ctx].clk = pdata->clk[ctx].clk;
6926 + node_dev->clk[ctx].enable = false;
6927 + node_dev->clk[ctx].dirty = false;
6928 + MSM_BUS_ERR("%s: Valid node clk node %d ctx %d",
6929 + __func__, node_dev->node_info->id, ctx);
6930 + }
6931 + }
6932 +
6933 + if (!IS_ERR_OR_NULL(pdata->qos_clk.clk)) {
6934 + node_dev->qos_clk.clk = pdata->qos_clk.clk;
6935 + node_dev->qos_clk.enable = false;
6936 + MSM_BUS_ERR("%s: Valid Iface clk node %d", __func__,
6937 + node_dev->node_info->id);
6938 + }
6939 +
6940 + return ret;
6941 +}
6942 +
6943 +static int msm_bus_copy_node_info(struct msm_bus_node_device_type *pdata,
6944 + struct device *bus_dev)
6945 +{
6946 + int ret = 0;
6947 + struct msm_bus_node_info_type *node_info = NULL;
6948 + struct msm_bus_node_info_type *pdata_node_info = NULL;
6949 + struct msm_bus_node_device_type *bus_node = NULL;
6950 +
6951 + bus_node = bus_dev->platform_data;
6952 +
6953 + if (!bus_node || !pdata) {
6954 + ret = -ENXIO;
6955 + MSM_BUS_ERR("%s: Invalid pointers pdata %p, bus_node %p",
6956 + __func__, pdata, bus_node);
6957 + goto exit_copy_node_info;
6958 + }
6959 +
6960 + node_info = bus_node->node_info;
6961 + pdata_node_info = pdata->node_info;
6962 +
6963 + node_info->name = pdata_node_info->name;
6964 + node_info->id = pdata_node_info->id;
6965 + node_info->bus_device_id = pdata_node_info->bus_device_id;
6966 + node_info->mas_rpm_id = pdata_node_info->mas_rpm_id;
6967 + node_info->slv_rpm_id = pdata_node_info->slv_rpm_id;
6968 + node_info->num_connections = pdata_node_info->num_connections;
6969 + node_info->num_blist = pdata_node_info->num_blist;
6970 + node_info->num_qports = pdata_node_info->num_qports;
6971 + node_info->buswidth = pdata_node_info->buswidth;
6972 + node_info->virt_dev = pdata_node_info->virt_dev;
6973 + node_info->is_fab_dev = pdata_node_info->is_fab_dev;
6974 + node_info->qos_params.mode = pdata_node_info->qos_params.mode;
6975 + node_info->qos_params.prio1 = pdata_node_info->qos_params.prio1;
6976 + node_info->qos_params.prio0 = pdata_node_info->qos_params.prio0;
6977 + node_info->qos_params.prio_lvl = pdata_node_info->qos_params.prio_lvl;
6978 + node_info->qos_params.prio_rd = pdata_node_info->qos_params.prio_rd;
6979 + node_info->qos_params.prio_wr = pdata_node_info->qos_params.prio_wr;
6980 + node_info->qos_params.gp = pdata_node_info->qos_params.gp;
6981 + node_info->qos_params.thmp = pdata_node_info->qos_params.thmp;
6982 + node_info->qos_params.ws = pdata_node_info->qos_params.ws;
6983 + node_info->qos_params.bw_buffer = pdata_node_info->qos_params.bw_buffer;
6984 + node_info->util_fact = pdata_node_info->util_fact;
6985 + node_info->vrail_comp = pdata_node_info->vrail_comp;
6986 +
6987 + node_info->dev_connections = devm_kzalloc(bus_dev,
6988 + sizeof(struct device *) *
6989 + pdata_node_info->num_connections,
6990 + GFP_KERNEL);
6991 + if (!node_info->dev_connections) {
6992 + MSM_BUS_ERR("%s:Bus dev connections alloc failed\n", __func__);
6993 + ret = -ENOMEM;
6994 + goto exit_copy_node_info;
6995 + }
6996 +
6997 + node_info->connections = devm_kzalloc(bus_dev,
6998 + sizeof(int) * pdata_node_info->num_connections,
6999 + GFP_KERNEL);
7000 + if (!node_info->connections) {
7001 + MSM_BUS_ERR("%s:Bus connections alloc failed\n", __func__);
7002 + devm_kfree(bus_dev, node_info->dev_connections);
7003 + ret = -ENOMEM;
7004 + goto exit_copy_node_info;
7005 + }
7006 +
7007 + memcpy(node_info->connections,
7008 + pdata_node_info->connections,
7009 + sizeof(int) * pdata_node_info->num_connections);
7010 +
7011 + node_info->black_connections = devm_kzalloc(bus_dev,
7012 + sizeof(struct device *) *
7013 + pdata_node_info->num_blist,
7014 + GFP_KERNEL);
7015 + if (!node_info->black_connections) {
7016 + MSM_BUS_ERR("%s: Bus black connections alloc failed\n",
7017 + __func__);
7018 + devm_kfree(bus_dev, node_info->dev_connections);
7019 + devm_kfree(bus_dev, node_info->connections);
7020 + ret = -ENOMEM;
7021 + goto exit_copy_node_info;
7022 + }
7023 +
7024 + node_info->black_listed_connections = devm_kzalloc(bus_dev,
7025 + pdata_node_info->num_blist * sizeof(int),
7026 + GFP_KERNEL);
7027 + if (!node_info->black_listed_connections) {
7028 + MSM_BUS_ERR("%s:Bus black list connections alloc failed\n",
7029 + __func__);
7030 + devm_kfree(bus_dev, node_info->black_connections);
7031 + devm_kfree(bus_dev, node_info->dev_connections);
7032 + devm_kfree(bus_dev, node_info->connections);
7033 + ret = -ENOMEM;
7034 + goto exit_copy_node_info;
7035 + }
7036 +
7037 + memcpy(node_info->black_listed_connections,
7038 + pdata_node_info->black_listed_connections,
7039 + sizeof(int) * pdata_node_info->num_blist);
7040 +
7041 + node_info->qport = devm_kzalloc(bus_dev,
7042 + sizeof(int) * pdata_node_info->num_qports,
7043 + GFP_KERNEL);
7044 + if (!node_info->qport) {
7045 + MSM_BUS_ERR("%s:Bus qport allocation failed\n", __func__);
7046 + devm_kfree(bus_dev, node_info->dev_connections);
7047 + devm_kfree(bus_dev, node_info->connections);
7048 + devm_kfree(bus_dev, node_info->black_listed_connections);
7049 + ret = -ENOMEM;
7050 + goto exit_copy_node_info;
7051 + }
7052 +
7053 + memcpy(node_info->qport,
7054 + pdata_node_info->qport,
7055 + sizeof(int) * pdata_node_info->num_qports);
7056 +
7057 +exit_copy_node_info:
7058 + return ret;
7059 +}
7060 +
7061 +static struct device *msm_bus_device_init(
7062 + struct msm_bus_node_device_type *pdata)
7063 +{
7064 + struct device *bus_dev = NULL;
7065 + struct msm_bus_node_device_type *bus_node = NULL;
7066 + struct msm_bus_node_info_type *node_info = NULL;
7067 + int ret = 0;
7068 +
7069 + bus_dev = kzalloc(sizeof(struct device), GFP_KERNEL);
7070 + if (!bus_dev) {
7071 + MSM_BUS_ERR("%s:Device alloc failed\n", __func__);
7072 + bus_dev = NULL;
7073 + goto exit_device_init;
7074 + }
7075 + /**
7076 + * Init here so we can use devm calls
7077 + */
7078 + device_initialize(bus_dev);
7079 +
7080 + bus_node = devm_kzalloc(bus_dev,
7081 + sizeof(struct msm_bus_node_device_type), GFP_KERNEL);
7082 + if (!bus_node) {
7083 + MSM_BUS_ERR("%s:Bus node alloc failed\n", __func__);
7084 + kfree(bus_dev);
7085 + bus_dev = NULL;
7086 + goto exit_device_init;
7087 + }
7088 +
7089 + node_info = devm_kzalloc(bus_dev,
7090 + sizeof(struct msm_bus_node_info_type), GFP_KERNEL);
7091 + if (!node_info) {
7092 + MSM_BUS_ERR("%s:Bus node info alloc failed\n", __func__);
7093 + devm_kfree(bus_dev, bus_node);
7094 + kfree(bus_dev);
7095 + bus_dev = NULL;
7096 + goto exit_device_init;
7097 + }
7098 +
7099 + bus_node->node_info = node_info;
7100 + bus_node->ap_owned = pdata->ap_owned;
7101 + bus_dev->platform_data = bus_node;
7102 +
7103 + if (msm_bus_copy_node_info(pdata, bus_dev) < 0) {
7104 + devm_kfree(bus_dev, bus_node);
7105 + devm_kfree(bus_dev, node_info);
7106 + kfree(bus_dev);
7107 + bus_dev = NULL;
7108 + goto exit_device_init;
7109 + }
7110 +
7111 + bus_dev->bus = &msm_bus_type;
7112 + dev_set_name(bus_dev, bus_node->node_info->name);
7113 +
7114 + ret = device_add(bus_dev);
7115 + if (ret < 0) {
7116 + MSM_BUS_ERR("%s: Error registering device %d",
7117 + __func__, pdata->node_info->id);
7118 + devm_kfree(bus_dev, bus_node);
7119 + devm_kfree(bus_dev, node_info->dev_connections);
7120 + devm_kfree(bus_dev, node_info->connections);
7121 + devm_kfree(bus_dev, node_info->black_connections);
7122 + devm_kfree(bus_dev, node_info->black_listed_connections);
7123 + devm_kfree(bus_dev, node_info);
7124 + kfree(bus_dev);
7125 + bus_dev = NULL;
7126 + goto exit_device_init;
7127 + }
7128 + device_create_file(bus_dev, &dev_attr_vrail);
7129 +
7130 +exit_device_init:
7131 + return bus_dev;
7132 +}
7133 +
7134 +static int msm_bus_setup_dev_conn(struct device *bus_dev, void *data)
7135 +{
7136 + struct msm_bus_node_device_type *bus_node = NULL;
7137 + int ret = 0;
7138 + int j;
7139 +
7140 + bus_node = bus_dev->platform_data;
7141 + if (!bus_node) {
7142 + MSM_BUS_ERR("%s: Can't get device info", __func__);
7143 + ret = -ENODEV;
7144 + goto exit_setup_dev_conn;
7145 + }
7146 +
7147 + /* Setup parent bus device for this node */
7148 + if (!bus_node->node_info->is_fab_dev) {
7149 + struct device *bus_parent_device =
7150 + bus_find_device(&msm_bus_type, NULL,
7151 + (void *)&bus_node->node_info->bus_device_id,
7152 + msm_bus_device_match_adhoc);
7153 +
7154 + if (!bus_parent_device) {
7155 + MSM_BUS_ERR("%s: Error finding parentdev %d parent %d",
7156 + __func__,
7157 + bus_node->node_info->id,
7158 + bus_node->node_info->bus_device_id);
7159 + ret = -ENXIO;
7160 + goto exit_setup_dev_conn;
7161 + }
7162 + bus_node->node_info->bus_device = bus_parent_device;
7163 + }
7164 +
7165 + bus_node->node_info->is_traversed = false;
7166 +
7167 + for (j = 0; j < bus_node->node_info->num_connections; j++) {
7168 + bus_node->node_info->dev_connections[j] =
7169 + bus_find_device(&msm_bus_type, NULL,
7170 + (void *)&bus_node->node_info->connections[j],
7171 + msm_bus_device_match_adhoc);
7172 +
7173 + if (!bus_node->node_info->dev_connections[j]) {
7174 + MSM_BUS_ERR("%s: Error finding conn %d for device %d",
7175 + __func__, bus_node->node_info->connections[j],
7176 + bus_node->node_info->id);
7177 + ret = -ENODEV;
7178 + goto exit_setup_dev_conn;
7179 + }
7180 + }
7181 +
7182 + for (j = 0; j < bus_node->node_info->num_blist; j++) {
7183 + bus_node->node_info->black_connections[j] =
7184 + bus_find_device(&msm_bus_type, NULL,
7185 + (void *)&bus_node->node_info->
7186 + black_listed_connections[j],
7187 + msm_bus_device_match_adhoc);
7188 +
7189 + if (!bus_node->node_info->black_connections[j]) {
7190 + MSM_BUS_ERR("%s: Error finding conn %d for device %d\n",
7191 + __func__, bus_node->node_info->
7192 + black_listed_connections[j],
7193 + bus_node->node_info->id);
7194 + ret = -ENODEV;
7195 + goto exit_setup_dev_conn;
7196 + }
7197 + }
7198 +
7199 +exit_setup_dev_conn:
7200 + return ret;
7201 +}
7202 +
7203 +static int msm_bus_node_debug(struct device *bus_dev, void *data)
7204 +{
7205 + int j;
7206 + int ret = 0;
7207 + struct msm_bus_node_device_type *bus_node = NULL;
7208 +
7209 + bus_node = bus_dev->platform_data;
7210 + if (!bus_node) {
7211 + MSM_BUS_ERR("%s: Can't get device info", __func__);
7212 + ret = -ENODEV;
7213 + goto exit_node_debug;
7214 + }
7215 +
7216 + MSM_BUS_DBG("Device = %d buswidth %u", bus_node->node_info->id,
7217 + bus_node->node_info->buswidth);
7218 + for (j = 0; j < bus_node->node_info->num_connections; j++) {
7219 + struct msm_bus_node_device_type *bdev =
7220 + (struct msm_bus_node_device_type *)
7221 + bus_node->node_info->dev_connections[j]->platform_data;
7222 + MSM_BUS_DBG("\n\t Connection[%d] %d", j, bdev->node_info->id);
7223 + }
7224 +
7225 +exit_node_debug:
7226 + return ret;
7227 +}
7228 +
7229 +static int msm_bus_device_probe(struct platform_device *pdev)
7230 +{
7231 + unsigned int i, ret;
7232 + struct msm_bus_device_node_registration *pdata;
7233 +
7234 + /* If possible, get pdata from device-tree */
7235 + if (pdev->dev.of_node)
7236 + pdata = msm_bus_of_to_pdata(pdev);
7237 + else {
7238 + pdata = (struct msm_bus_device_node_registration *)pdev->
7239 + dev.platform_data;
7240 + }
7241 +
7242 + if (IS_ERR_OR_NULL(pdata)) {
7243 + MSM_BUS_ERR("No platform data found");
7244 + ret = -ENODATA;
7245 + goto exit_device_probe;
7246 + }
7247 +
7248 + for (i = 0; i < pdata->num_devices; i++) {
7249 + struct device *node_dev = NULL;
7250 +
7251 + node_dev = msm_bus_device_init(&pdata->info[i]);
7252 +
7253 + if (!node_dev) {
7254 + MSM_BUS_ERR("%s: Error during dev init for %d",
7255 + __func__, pdata->info[i].node_info->id);
7256 + ret = -ENXIO;
7257 + goto exit_device_probe;
7258 + }
7259 +
7260 + ret = msm_bus_init_clk(node_dev, &pdata->info[i]);
7261 + /*Is this a fabric device ?*/
7262 + if (pdata->info[i].node_info->is_fab_dev) {
7263 + MSM_BUS_DBG("%s: %d is a fab", __func__,
7264 + pdata->info[i].node_info->id);
7265 + ret = msm_bus_fabric_init(node_dev, &pdata->info[i]);
7266 + if (ret) {
7267 + MSM_BUS_ERR("%s: Error intializing fab %d",
7268 + __func__, pdata->info[i].node_info->id);
7269 + goto exit_device_probe;
7270 + }
7271 + }
7272 + }
7273 +
7274 + ret = bus_for_each_dev(&msm_bus_type, NULL, NULL,
7275 + msm_bus_setup_dev_conn);
7276 + if (ret) {
7277 + MSM_BUS_ERR("%s: Error setting up dev connections", __func__);
7278 + goto exit_device_probe;
7279 + }
7280 +
7281 + ret = bus_for_each_dev(&msm_bus_type, NULL, NULL, msm_bus_dev_init_qos);
7282 + if (ret) {
7283 + MSM_BUS_ERR("%s: Error during qos init", __func__);
7284 + goto exit_device_probe;
7285 + }
7286 +
7287 + bus_for_each_dev(&msm_bus_type, NULL, NULL, msm_bus_node_debug);
7288 +
7289 + /* Register the arb layer ops */
7290 + msm_bus_arb_setops_adhoc(&arb_ops);
7291 + devm_kfree(&pdev->dev, pdata->info);
7292 + devm_kfree(&pdev->dev, pdata);
7293 +exit_device_probe:
7294 + return ret;
7295 +}
7296 +
7297 +static int msm_bus_device_rules_probe(struct platform_device *pdev)
7298 +{
7299 + struct bus_rule_type *rule_data = NULL;
7300 + int num_rules = 0;
7301 +
7302 + num_rules = msm_bus_of_get_static_rules(pdev, &rule_data);
7303 +
7304 + if (!rule_data)
7305 + goto exit_rules_probe;
7306 +
7307 + msm_rule_register(num_rules, rule_data, NULL);
7308 + static_rules.num_rules = num_rules;
7309 + static_rules.rules = rule_data;
7310 + pdev->dev.platform_data = &static_rules;
7311 +
7312 +exit_rules_probe:
7313 + return 0;
7314 +}
7315 +
7316 +int msm_bus_device_rules_remove(struct platform_device *pdev)
7317 +{
7318 + struct static_rules_type *static_rules = NULL;
7319 +
7320 + static_rules = pdev->dev.platform_data;
7321 + if (static_rules)
7322 + msm_rule_unregister(static_rules->num_rules,
7323 + static_rules->rules, NULL);
7324 + return 0;
7325 +}
7326 +
7327 +static int msm_bus_free_dev(struct device *dev, void *data)
7328 +{
7329 + struct msm_bus_node_device_type *bus_node = NULL;
7330 +
7331 + bus_node = dev->platform_data;
7332 +
7333 + if (bus_node)
7334 + MSM_BUS_ERR("\n%s: Removing device %d", __func__,
7335 + bus_node->node_info->id);
7336 + device_unregister(dev);
7337 + return 0;
7338 +}
7339 +
7340 +int msm_bus_device_remove(struct platform_device *pdev)
7341 +{
7342 + bus_for_each_dev(&msm_bus_type, NULL, NULL, msm_bus_free_dev);
7343 + return 0;
7344 +}
7345 +
7346 +static struct of_device_id rules_match[] = {
7347 + {.compatible = "qcom,msm-bus-static-bw-rules"},
7348 + {}
7349 +};
7350 +
7351 +static struct platform_driver msm_bus_rules_driver = {
7352 + .probe = msm_bus_device_rules_probe,
7353 + .remove = msm_bus_device_rules_remove,
7354 + .driver = {
7355 + .name = "msm_bus_rules_device",
7356 + .owner = THIS_MODULE,
7357 + .of_match_table = rules_match,
7358 + },
7359 +};
7360 +
7361 +static struct of_device_id fabric_match[] = {
7362 + {.compatible = "qcom,msm-bus-device"},
7363 + {}
7364 +};
7365 +
7366 +static struct platform_driver msm_bus_device_driver = {
7367 + .probe = msm_bus_device_probe,
7368 + .remove = msm_bus_device_remove,
7369 + .driver = {
7370 + .name = "msm_bus_device",
7371 + .owner = THIS_MODULE,
7372 + .of_match_table = fabric_match,
7373 + },
7374 +};
7375 +
7376 +int __init msm_bus_device_init_driver(void)
7377 +{
7378 + int rc;
7379 +
7380 + MSM_BUS_ERR("msm_bus_fabric_init_driver\n");
7381 + rc = platform_driver_register(&msm_bus_device_driver);
7382 +
7383 + if (rc) {
7384 + MSM_BUS_ERR("Failed to register bus device driver");
7385 + return rc;
7386 + }
7387 + return platform_driver_register(&msm_bus_rules_driver);
7388 +}
7389 +subsys_initcall(msm_bus_device_init_driver);
7390 --- /dev/null
7391 +++ b/drivers/bus/msm_bus/msm_bus_id.c
7392 @@ -0,0 +1,94 @@
7393 +/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
7394 + *
7395 + * This program is free software; you can redistribute it and/or modify
7396 + * it under the terms of the GNU General Public License version 2 and
7397 + * only version 2 as published by the Free Software Foundation.
7398 + *
7399 + * This program is distributed in the hope that it will be useful,
7400 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
7401 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7402 + * GNU General Public License for more details.
7403 + *
7404 + */
7405 +
7406 +#include <linux/kernel.h>
7407 +#include <linux/init.h>
7408 +#include <linux/device.h>
7409 +#include <linux/module.h>
7410 +#include "msm-bus.h"
7411 +#include "msm-bus-board.h"
7412 +#include "msm_bus_core.h"
7413 +#include "msm_bus_noc.h"
7414 +#include "msm_bus_bimc.h"
7415 +
7416 +static uint32_t master_iids[MSM_BUS_MASTER_LAST];
7417 +static uint32_t slave_iids[MSM_BUS_SLAVE_LAST - SLAVE_ID_KEY];
7418 +
7419 +static void msm_bus_assign_iids(struct msm_bus_fabric_registration
7420 + *fabreg, int fabid)
7421 +{
7422 + int i;
7423 + for (i = 0; i < fabreg->len; i++) {
7424 + if (!fabreg->info[i].gateway) {
7425 + fabreg->info[i].priv_id = fabid + fabreg->info[i].id;
7426 + if (fabreg->info[i].id < SLAVE_ID_KEY) {
7427 + if (fabreg->info[i].id >= MSM_BUS_MASTER_LAST) {
7428 + WARN(1, "id %d exceeds array size!\n",
7429 + fabreg->info[i].id);
7430 + continue;
7431 + }
7432 +
7433 + master_iids[fabreg->info[i].id] =
7434 + fabreg->info[i].priv_id;
7435 + } else {
7436 + if ((fabreg->info[i].id - SLAVE_ID_KEY) >=
7437 + (MSM_BUS_SLAVE_LAST - SLAVE_ID_KEY)) {
7438 + WARN(1, "id %d exceeds array size!\n",
7439 + fabreg->info[i].id);
7440 + continue;
7441 + }
7442 +
7443 + slave_iids[fabreg->info[i].id - (SLAVE_ID_KEY)]
7444 + = fabreg->info[i].priv_id;
7445 + }
7446 + } else {
7447 + fabreg->info[i].priv_id = fabreg->info[i].id;
7448 + }
7449 + }
7450 +}
7451 +
7452 +static int msm_bus_get_iid(int id)
7453 +{
7454 + if ((id < SLAVE_ID_KEY && id >= MSM_BUS_MASTER_LAST) ||
7455 + id >= MSM_BUS_SLAVE_LAST) {
7456 + MSM_BUS_ERR("Cannot get iid. Invalid id %d passed\n", id);
7457 + return -EINVAL;
7458 + }
7459 +
7460 + return CHECK_ID(((id < SLAVE_ID_KEY) ? master_iids[id] :
7461 + slave_iids[id - SLAVE_ID_KEY]), id);
7462 +}
7463 +
7464 +static struct msm_bus_board_algorithm msm_bus_id_algo = {
7465 + .get_iid = msm_bus_get_iid,
7466 + .assign_iids = msm_bus_assign_iids,
7467 +};
7468 +
7469 +int msm_bus_board_rpm_get_il_ids(uint16_t *id)
7470 +{
7471 + return -ENXIO;
7472 +}
7473 +
7474 +void msm_bus_board_init(struct msm_bus_fabric_registration *pdata)
7475 +{
7476 + pdata->board_algo = &msm_bus_id_algo;
7477 +}
7478 +
7479 +void msm_bus_board_set_nfab(struct msm_bus_fabric_registration *pdata,
7480 + int nfab)
7481 +{
7482 + if (nfab <= 0)
7483 + return;
7484 +
7485 + msm_bus_id_algo.board_nfab = nfab;
7486 +}
7487 --- /dev/null
7488 +++ b/drivers/bus/msm_bus/msm_bus_noc.c
7489 @@ -0,0 +1,770 @@
7490 +/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
7491 + *
7492 + * This program is free software; you can redistribute it and/or modify
7493 + * it under the terms of the GNU General Public License version 2 and
7494 + * only version 2 as published by the Free Software Foundation.
7495 + *
7496 + * This program is distributed in the hope that it will be useful,
7497 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
7498 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7499 + * GNU General Public License for more details.
7500 + */
7501 +
7502 +#define pr_fmt(fmt) "AXI: NOC: %s(): " fmt, __func__
7503 +
7504 +#include <linux/slab.h>
7505 +#include <linux/io.h>
7506 +#include "msm-bus-board.h"
7507 +#include "msm_bus_core.h"
7508 +#include "msm_bus_noc.h"
7509 +#include "msm_bus_adhoc.h"
7510 +
7511 +/* NOC_QOS generic */
7512 +#define __CLZ(x) ((8 * sizeof(uint32_t)) - 1 - __fls(x))
7513 +#define SAT_SCALE 16 /* 16 bytes minimum for saturation */
7514 +#define BW_SCALE 256 /* 1/256 byte per cycle unit */
7515 +#define QOS_DEFAULT_BASEOFFSET 0x00003000
7516 +#define QOS_DEFAULT_DELTA 0x80
7517 +#define MAX_BW_FIELD (NOC_QOS_BWn_BW_BMSK >> NOC_QOS_BWn_BW_SHFT)
7518 +#define MAX_SAT_FIELD (NOC_QOS_SATn_SAT_BMSK >> NOC_QOS_SATn_SAT_SHFT)
7519 +
7520 +#define NOC_QOS_REG_BASE(b, o) ((b) + (o))
7521 +
7522 +#define NOC_QOS_ID_COREIDn_ADDR(b, o, n, d) \
7523 + (NOC_QOS_REG_BASE(b, o) + (d) * (n))
7524 +enum noc_qos_id_coreidn {
7525 + NOC_QOS_ID_COREIDn_RMSK = 0xffffffff,
7526 + NOC_QOS_ID_COREIDn_MAXn = 32,
7527 + NOC_QOS_ID_COREIDn_CORECHSUM_BMSK = 0xffffff00,
7528 + NOC_QOS_ID_COREIDn_CORECHSUM_SHFT = 0x8,
7529 + NOC_QOS_ID_COREIDn_CORETYPEID_BMSK = 0xff,
7530 + NOC_QOS_ID_COREIDn_CORETYPEID_SHFT = 0x0,
7531 +};
7532 +
7533 +#define NOC_QOS_ID_REVISIONIDn_ADDR(b, o, n, d) \
7534 + (NOC_QOS_REG_BASE(b, o) + 0x4 + (d) * (n))
7535 +enum noc_qos_id_revisionidn {
7536 + NOC_QOS_ID_REVISIONIDn_RMSK = 0xffffffff,
7537 + NOC_QOS_ID_REVISIONIDn_MAXn = 32,
7538 + NOC_QOS_ID_REVISIONIDn_FLEXNOCID_BMSK = 0xffffff00,
7539 + NOC_QOS_ID_REVISIONIDn_FLEXNOCID_SHFT = 0x8,
7540 + NOC_QOS_ID_REVISIONIDn_USERID_BMSK = 0xff,
7541 + NOC_QOS_ID_REVISIONIDn_USERID_SHFT = 0x0,
7542 +};
7543 +
7544 +#define NOC_QOS_PRIORITYn_ADDR(b, o, n, d) \
7545 + (NOC_QOS_REG_BASE(b, o) + 0x8 + (d) * (n))
7546 +enum noc_qos_id_priorityn {
7547 + NOC_QOS_PRIORITYn_RMSK = 0x0000000f,
7548 + NOC_QOS_PRIORITYn_MAXn = 32,
7549 + NOC_QOS_PRIORITYn_P1_BMSK = 0xc,
7550 + NOC_QOS_PRIORITYn_P1_SHFT = 0x2,
7551 + NOC_QOS_PRIORITYn_P0_BMSK = 0x3,
7552 + NOC_QOS_PRIORITYn_P0_SHFT = 0x0,
7553 +};
7554 +
7555 +#define NOC_QOS_MODEn_ADDR(b, o, n, d) \
7556 + (NOC_QOS_REG_BASE(b, o) + 0xC + (d) * (n))
7557 +enum noc_qos_id_moden_rmsk {
7558 + NOC_QOS_MODEn_RMSK = 0x00000003,
7559 + NOC_QOS_MODEn_MAXn = 32,
7560 + NOC_QOS_MODEn_MODE_BMSK = 0x3,
7561 + NOC_QOS_MODEn_MODE_SHFT = 0x0,
7562 +};
7563 +
7564 +#define NOC_QOS_BWn_ADDR(b, o, n, d) \
7565 + (NOC_QOS_REG_BASE(b, o) + 0x10 + (d) * (n))
7566 +enum noc_qos_id_bwn {
7567 + NOC_QOS_BWn_RMSK = 0x0000ffff,
7568 + NOC_QOS_BWn_MAXn = 32,
7569 + NOC_QOS_BWn_BW_BMSK = 0xffff,
7570 + NOC_QOS_BWn_BW_SHFT = 0x0,
7571 +};
7572 +
7573 +/* QOS Saturation registers */
7574 +#define NOC_QOS_SATn_ADDR(b, o, n, d) \
7575 + (NOC_QOS_REG_BASE(b, o) + 0x14 + (d) * (n))
7576 +enum noc_qos_id_saturationn {
7577 + NOC_QOS_SATn_RMSK = 0x000003ff,
7578 + NOC_QOS_SATn_MAXn = 32,
7579 + NOC_QOS_SATn_SAT_BMSK = 0x3ff,
7580 + NOC_QOS_SATn_SAT_SHFT = 0x0,
7581 +};
7582 +
7583 +static int noc_div(uint64_t *a, uint32_t b)
7584 +{
7585 + if ((*a > 0) && (*a < b))
7586 + return 1;
7587 + else
7588 + return do_div(*a, b);
7589 +}
7590 +
7591 +/**
7592 + * Calculates bw hardware is using from register values
7593 + * bw returned is in bytes/sec
7594 + */
7595 +static uint64_t noc_bw(uint32_t bw_field, uint32_t qos_freq)
7596 +{
7597 + uint64_t res;
7598 + uint32_t rem, scale;
7599 +
7600 + res = 2 * qos_freq * bw_field;
7601 + scale = BW_SCALE * 1000;
7602 + rem = noc_div(&res, scale);
7603 + MSM_BUS_DBG("NOC: Calculated bw: %llu\n", res * 1000000ULL);
7604 + return res * 1000000ULL;
7605 +}
7606 +
7607 +static uint32_t noc_bw_ceil(long int bw_field, uint32_t qos_freq)
7608 +{
7609 + uint64_t bw_temp = 2 * qos_freq * bw_field;
7610 + uint32_t scale = 1000 * BW_SCALE;
7611 + noc_div(&bw_temp, scale);
7612 + return bw_temp * 1000000;
7613 +}
7614 +#define MAX_BW(timebase) noc_bw_ceil(MAX_BW_FIELD, (timebase))
7615 +
7616 +/**
7617 + * Calculates ws hardware is using from register values
7618 + * ws returned is in nanoseconds
7619 + */
7620 +static uint32_t noc_ws(uint64_t bw, uint32_t sat, uint32_t qos_freq)
7621 +{
7622 + if (bw && qos_freq) {
7623 + uint32_t bwf = bw * qos_freq;
7624 + uint64_t scale = 1000000000000LL * BW_SCALE *
7625 + SAT_SCALE * sat;
7626 + noc_div(&scale, bwf);
7627 + MSM_BUS_DBG("NOC: Calculated ws: %llu\n", scale);
7628 + return scale;
7629 + }
7630 +
7631 + return 0;
7632 +}
7633 +#define MAX_WS(bw, timebase) noc_ws((bw), MAX_SAT_FIELD, (timebase))
7634 +
7635 +/* Calculate bandwidth field value for requested bandwidth */
7636 +static uint32_t noc_bw_field(uint64_t bw, uint32_t qos_freq)
7637 +{
7638 + uint32_t bw_field = 0;
7639 +
7640 + if (bw) {
7641 + uint32_t rem;
7642 + uint64_t bw_capped = min_t(uint64_t, bw, MAX_BW(qos_freq));
7643 + uint64_t bwc = bw_capped * BW_SCALE;
7644 + uint64_t qf = 2 * qos_freq * 1000;
7645 +
7646 + rem = noc_div(&bwc, qf);
7647 + bw_field = (uint32_t)min_t(uint64_t, bwc, MAX_BW_FIELD);
7648 + }
7649 +
7650 + MSM_BUS_DBG("NOC: bw_field: %u\n", bw_field);
7651 + return bw_field;
7652 +}
7653 +
7654 +static uint32_t noc_sat_field(uint64_t bw, uint32_t ws, uint32_t qos_freq)
7655 +{
7656 + uint32_t sat_field = 0, win;
7657 +
7658 + if (bw) {
7659 + /* Limit to max bw and scale bw to 100 KB increments */
7660 + uint64_t tbw, tscale;
7661 + uint64_t bw_scaled = min_t(uint64_t, bw, MAX_BW(qos_freq));
7662 + uint32_t rem = noc_div(&bw_scaled, 100000);
7663 +
7664 + /**
7665 + * Calculate saturation from windows size.
7666 + * WS must be at least one arb period.
7667 + * Saturation must not exceed max field size
7668 + *
7669 + * Bandwidth is in 100KB increments
7670 + * Window size is in ns
7671 + * qos_freq is in KHz
7672 + */
7673 + win = max(ws, 1000000 / qos_freq);
7674 + tbw = bw_scaled * win * qos_freq;
7675 + tscale = 10000000ULL * BW_SCALE * SAT_SCALE;
7676 + rem = noc_div(&tbw, tscale);
7677 + sat_field = (uint32_t)min_t(uint64_t, tbw, MAX_SAT_FIELD);
7678 + }
7679 +
7680 + MSM_BUS_DBG("NOC: sat_field: %d\n", sat_field);
7681 + return sat_field;
7682 +}
7683 +
7684 +static void noc_set_qos_mode(void __iomem *base, uint32_t qos_off,
7685 + uint32_t mport, uint32_t qos_delta, uint8_t mode,
7686 + uint8_t perm_mode)
7687 +{
7688 + if (mode < NOC_QOS_MODE_MAX &&
7689 + ((1 << mode) & perm_mode)) {
7690 + uint32_t reg_val;
7691 +
7692 + reg_val = readl_relaxed(NOC_QOS_MODEn_ADDR(base, qos_off,
7693 + mport, qos_delta)) & NOC_QOS_MODEn_RMSK;
7694 + writel_relaxed(((reg_val & (~(NOC_QOS_MODEn_MODE_BMSK))) |
7695 + (mode & NOC_QOS_MODEn_MODE_BMSK)),
7696 + NOC_QOS_MODEn_ADDR(base, qos_off, mport, qos_delta));
7697 + }
7698 + /* Ensure qos mode is set before exiting */
7699 + wmb();
7700 +}
7701 +
7702 +static void noc_set_qos_priority(void __iomem *base, uint32_t qos_off,
7703 + uint32_t mport, uint32_t qos_delta,
7704 + struct msm_bus_noc_qos_priority *priority)
7705 +{
7706 + uint32_t reg_val, val;
7707 +
7708 + reg_val = readl_relaxed(NOC_QOS_PRIORITYn_ADDR(base, qos_off, mport,
7709 + qos_delta)) & NOC_QOS_PRIORITYn_RMSK;
7710 + val = priority->p1 << NOC_QOS_PRIORITYn_P1_SHFT;
7711 + writel_relaxed(((reg_val & (~(NOC_QOS_PRIORITYn_P1_BMSK))) |
7712 + (val & NOC_QOS_PRIORITYn_P1_BMSK)),
7713 + NOC_QOS_PRIORITYn_ADDR(base, qos_off, mport, qos_delta));
7714 +
7715 + reg_val = readl_relaxed(NOC_QOS_PRIORITYn_ADDR(base, qos_off, mport,
7716 + qos_delta))
7717 + & NOC_QOS_PRIORITYn_RMSK;
7718 + writel_relaxed(((reg_val & (~(NOC_QOS_PRIORITYn_P0_BMSK))) |
7719 + (priority->p0 & NOC_QOS_PRIORITYn_P0_BMSK)),
7720 + NOC_QOS_PRIORITYn_ADDR(base, qos_off, mport, qos_delta));
7721 + /* Ensure qos priority is set before exiting */
7722 + wmb();
7723 +}
7724 +
7725 +static void msm_bus_noc_set_qos_bw(void __iomem *base, uint32_t qos_off,
7726 + uint32_t qos_freq, uint32_t mport, uint32_t qos_delta,
7727 + uint8_t perm_mode, struct msm_bus_noc_qos_bw *qbw)
7728 +{
7729 + uint32_t reg_val, val, mode;
7730 +
7731 + if (!qos_freq) {
7732 + MSM_BUS_DBG("Zero QoS Freq\n");
7733 + return;
7734 + }
7735 +
7736 +
7737 + /* If Limiter or Regulator modes are not supported, bw not available*/
7738 + if (perm_mode & (NOC_QOS_PERM_MODE_LIMITER |
7739 + NOC_QOS_PERM_MODE_REGULATOR)) {
7740 + uint32_t bw_val = noc_bw_field(qbw->bw, qos_freq);
7741 + uint32_t sat_val = noc_sat_field(qbw->bw, qbw->ws,
7742 + qos_freq);
7743 +
7744 + MSM_BUS_DBG("NOC: BW: perm_mode: %d bw_val: %d, sat_val: %d\n",
7745 + perm_mode, bw_val, sat_val);
7746 + /*
7747 + * If in Limiter/Regulator mode, first go to fixed mode.
7748 + * Clear QoS accumulator
7749 + **/
7750 + mode = readl_relaxed(NOC_QOS_MODEn_ADDR(base, qos_off,
7751 + mport, qos_delta)) & NOC_QOS_MODEn_MODE_BMSK;
7752 + if (mode == NOC_QOS_MODE_REGULATOR || mode ==
7753 + NOC_QOS_MODE_LIMITER) {
7754 + reg_val = readl_relaxed(NOC_QOS_MODEn_ADDR(
7755 + base, qos_off, mport, qos_delta));
7756 + val = NOC_QOS_MODE_FIXED;
7757 + writel_relaxed((reg_val & (~(NOC_QOS_MODEn_MODE_BMSK)))
7758 + | (val & NOC_QOS_MODEn_MODE_BMSK),
7759 + NOC_QOS_MODEn_ADDR(base, qos_off, mport,
7760 + qos_delta));
7761 + }
7762 +
7763 + reg_val = readl_relaxed(NOC_QOS_BWn_ADDR(base, qos_off, mport,
7764 + qos_delta));
7765 + val = bw_val << NOC_QOS_BWn_BW_SHFT;
7766 + writel_relaxed(((reg_val & (~(NOC_QOS_BWn_BW_BMSK))) |
7767 + (val & NOC_QOS_BWn_BW_BMSK)),
7768 + NOC_QOS_BWn_ADDR(base, qos_off, mport, qos_delta));
7769 +
7770 + MSM_BUS_DBG("NOC: BW: Wrote value: 0x%x\n", ((reg_val &
7771 + (~NOC_QOS_BWn_BW_BMSK)) | (val &
7772 + NOC_QOS_BWn_BW_BMSK)));
7773 +
7774 + reg_val = readl_relaxed(NOC_QOS_SATn_ADDR(base, qos_off,
7775 + mport, qos_delta));
7776 + val = sat_val << NOC_QOS_SATn_SAT_SHFT;
7777 + writel_relaxed(((reg_val & (~(NOC_QOS_SATn_SAT_BMSK))) |
7778 + (val & NOC_QOS_SATn_SAT_BMSK)),
7779 + NOC_QOS_SATn_ADDR(base, qos_off, mport, qos_delta));
7780 +
7781 + MSM_BUS_DBG("NOC: SAT: Wrote value: 0x%x\n", ((reg_val &
7782 + (~NOC_QOS_SATn_SAT_BMSK)) | (val &
7783 + NOC_QOS_SATn_SAT_BMSK)));
7784 +
7785 + /* Set mode back to what it was initially */
7786 + reg_val = readl_relaxed(NOC_QOS_MODEn_ADDR(base, qos_off,
7787 + mport, qos_delta));
7788 + writel_relaxed((reg_val & (~(NOC_QOS_MODEn_MODE_BMSK)))
7789 + | (mode & NOC_QOS_MODEn_MODE_BMSK),
7790 + NOC_QOS_MODEn_ADDR(base, qos_off, mport, qos_delta));
7791 + /* Ensure that all writes for bandwidth registers have
7792 + * completed before returning
7793 + */
7794 + wmb();
7795 + }
7796 +}
7797 +
7798 +uint8_t msm_bus_noc_get_qos_mode(void __iomem *base, uint32_t qos_off,
7799 + uint32_t mport, uint32_t qos_delta, uint32_t mode, uint32_t perm_mode)
7800 +{
7801 + if (NOC_QOS_MODES_ALL_PERM == perm_mode)
7802 + return readl_relaxed(NOC_QOS_MODEn_ADDR(base, qos_off,
7803 + mport, qos_delta)) & NOC_QOS_MODEn_MODE_BMSK;
7804 + else
7805 + return 31 - __CLZ(mode &
7806 + NOC_QOS_MODES_ALL_PERM);
7807 +}
7808 +
7809 +void msm_bus_noc_get_qos_priority(void __iomem *base, uint32_t qos_off,
7810 + uint32_t mport, uint32_t qos_delta,
7811 + struct msm_bus_noc_qos_priority *priority)
7812 +{
7813 + priority->p1 = (readl_relaxed(NOC_QOS_PRIORITYn_ADDR(base, qos_off,
7814 + mport, qos_delta)) & NOC_QOS_PRIORITYn_P1_BMSK) >>
7815 + NOC_QOS_PRIORITYn_P1_SHFT;
7816 +
7817 + priority->p0 = (readl_relaxed(NOC_QOS_PRIORITYn_ADDR(base, qos_off,
7818 + mport, qos_delta)) & NOC_QOS_PRIORITYn_P0_BMSK) >>
7819 + NOC_QOS_PRIORITYn_P0_SHFT;
7820 +}
7821 +
7822 +void msm_bus_noc_get_qos_bw(void __iomem *base, uint32_t qos_off,
7823 + uint32_t qos_freq,
7824 + uint32_t mport, uint32_t qos_delta, uint8_t perm_mode,
7825 + struct msm_bus_noc_qos_bw *qbw)
7826 +{
7827 + if (perm_mode & (NOC_QOS_PERM_MODE_LIMITER |
7828 + NOC_QOS_PERM_MODE_REGULATOR)) {
7829 + uint32_t bw_val = readl_relaxed(NOC_QOS_BWn_ADDR(
7830 + base, qos_off, mport, qos_delta)) & NOC_QOS_BWn_BW_BMSK;
7831 + uint32_t sat = readl_relaxed(NOC_QOS_SATn_ADDR(
7832 + base, qos_off, mport, qos_delta))
7833 + & NOC_QOS_SATn_SAT_BMSK;
7834 +
7835 + qbw->bw = noc_bw(bw_val, qos_freq);
7836 + qbw->ws = noc_ws(qbw->bw, sat, qos_freq);
7837 + } else {
7838 + qbw->bw = 0;
7839 + qbw->ws = 0;
7840 + }
7841 +}
7842 +
7843 +static int msm_bus_noc_mas_init(struct msm_bus_noc_info *ninfo,
7844 + struct msm_bus_inode_info *info)
7845 +{
7846 + int i;
7847 + struct msm_bus_noc_qos_priority *prio;
7848 + prio = kzalloc(sizeof(struct msm_bus_noc_qos_priority),
7849 + GFP_KERNEL);
7850 + if (!prio) {
7851 + MSM_BUS_WARN("Couldn't alloc prio data for node: %d\n",
7852 + info->node_info->id);
7853 + return -ENOMEM;
7854 + }
7855 +
7856 + prio->read_prio = info->node_info->prio_rd;
7857 + prio->write_prio = info->node_info->prio_wr;
7858 + prio->p1 = info->node_info->prio1;
7859 + prio->p0 = info->node_info->prio0;
7860 + info->hw_data = (void *)prio;
7861 +
7862 + if (!info->node_info->qport) {
7863 + MSM_BUS_DBG("No QoS Ports to init\n");
7864 + return 0;
7865 + }
7866 +
7867 + for (i = 0; i < info->node_info->num_mports; i++) {
7868 + if (info->node_info->mode != NOC_QOS_MODE_BYPASS) {
7869 + noc_set_qos_priority(ninfo->base, ninfo->qos_baseoffset,
7870 + info->node_info->qport[i], ninfo->qos_delta,
7871 + prio);
7872 +
7873 + if (info->node_info->mode != NOC_QOS_MODE_FIXED) {
7874 + struct msm_bus_noc_qos_bw qbw;
7875 + qbw.ws = info->node_info->ws;
7876 + qbw.bw = 0;
7877 + msm_bus_noc_set_qos_bw(ninfo->base,
7878 + ninfo->qos_baseoffset,
7879 + ninfo->qos_freq, info->node_info->
7880 + qport[i], ninfo->qos_delta,
7881 + info->node_info->perm_mode,
7882 + &qbw);
7883 + }
7884 + }
7885 +
7886 + noc_set_qos_mode(ninfo->base, ninfo->qos_baseoffset,
7887 + info->node_info->qport[i], ninfo->qos_delta,
7888 + info->node_info->mode,
7889 + info->node_info->perm_mode);
7890 + }
7891 +
7892 + return 0;
7893 +}
7894 +
7895 +static void msm_bus_noc_node_init(void *hw_data,
7896 + struct msm_bus_inode_info *info)
7897 +{
7898 + struct msm_bus_noc_info *ninfo =
7899 + (struct msm_bus_noc_info *)hw_data;
7900 +
7901 + if (!IS_SLAVE(info->node_info->priv_id))
7902 + if (info->node_info->hw_sel != MSM_BUS_RPM)
7903 + msm_bus_noc_mas_init(ninfo, info);
7904 +}
7905 +
7906 +static int msm_bus_noc_allocate_commit_data(struct msm_bus_fabric_registration
7907 + *fab_pdata, void **cdata, int ctx)
7908 +{
7909 + struct msm_bus_noc_commit **cd = (struct msm_bus_noc_commit **)cdata;
7910 + struct msm_bus_noc_info *ninfo =
7911 + (struct msm_bus_noc_info *)fab_pdata->hw_data;
7912 +
7913 + *cd = kzalloc(sizeof(struct msm_bus_noc_commit), GFP_KERNEL);
7914 + if (!*cd) {
7915 + MSM_BUS_DBG("Couldn't alloc mem for cdata\n");
7916 + return -ENOMEM;
7917 + }
7918 +
7919 + (*cd)->mas = ninfo->cdata[ctx].mas;
7920 + (*cd)->slv = ninfo->cdata[ctx].slv;
7921 +
7922 + return 0;
7923 +}
7924 +
7925 +static void *msm_bus_noc_allocate_noc_data(struct platform_device *pdev,
7926 + struct msm_bus_fabric_registration *fab_pdata)
7927 +{
7928 + struct resource *noc_mem;
7929 + struct resource *noc_io;
7930 + struct msm_bus_noc_info *ninfo;
7931 + int i;
7932 +
7933 + ninfo = kzalloc(sizeof(struct msm_bus_noc_info), GFP_KERNEL);
7934 + if (!ninfo) {
7935 + MSM_BUS_DBG("Couldn't alloc mem for noc info\n");
7936 + return NULL;
7937 + }
7938 +
7939 + ninfo->nmasters = fab_pdata->nmasters;
7940 + ninfo->nqos_masters = fab_pdata->nmasters;
7941 + ninfo->nslaves = fab_pdata->nslaves;
7942 + ninfo->qos_freq = fab_pdata->qos_freq;
7943 +
7944 + if (!fab_pdata->qos_baseoffset)
7945 + ninfo->qos_baseoffset = QOS_DEFAULT_BASEOFFSET;
7946 + else
7947 + ninfo->qos_baseoffset = fab_pdata->qos_baseoffset;
7948 +
7949 + if (!fab_pdata->qos_delta)
7950 + ninfo->qos_delta = QOS_DEFAULT_DELTA;
7951 + else
7952 + ninfo->qos_delta = fab_pdata->qos_delta;
7953 +
7954 + ninfo->mas_modes = kzalloc(sizeof(uint32_t) * fab_pdata->nmasters,
7955 + GFP_KERNEL);
7956 + if (!ninfo->mas_modes) {
7957 + MSM_BUS_DBG("Couldn't alloc mem for noc master-modes\n");
7958 + kfree(ninfo);
7959 + return NULL;
7960 + }
7961 +
7962 + for (i = 0; i < NUM_CTX; i++) {
7963 + ninfo->cdata[i].mas = kzalloc(sizeof(struct
7964 + msm_bus_node_hw_info) * fab_pdata->nmasters * 2,
7965 + GFP_KERNEL);
7966 + if (!ninfo->cdata[i].mas) {
7967 + MSM_BUS_DBG("Couldn't alloc mem for noc master-bw\n");
7968 + kfree(ninfo->mas_modes);
7969 + kfree(ninfo);
7970 + return NULL;
7971 + }
7972 +
7973 + ninfo->cdata[i].slv = kzalloc(sizeof(struct
7974 + msm_bus_node_hw_info) * fab_pdata->nslaves * 2,
7975 + GFP_KERNEL);
7976 + if (!ninfo->cdata[i].slv) {
7977 + MSM_BUS_DBG("Couldn't alloc mem for noc master-bw\n");
7978 + kfree(ninfo->cdata[i].mas);
7979 + goto err;
7980 + }
7981 + }
7982 +
7983 + /* If it's a virtual fabric, don't get memory info */
7984 + if (fab_pdata->virt)
7985 + goto skip_mem;
7986 +
7987 + noc_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
7988 + if (!noc_mem && !fab_pdata->virt) {
7989 + MSM_BUS_ERR("Cannot get NoC Base address\n");
7990 + goto err;
7991 + }
7992 +
7993 + noc_io = request_mem_region(noc_mem->start,
7994 + resource_size(noc_mem), pdev->name);
7995 + if (!noc_io) {
7996 + MSM_BUS_ERR("NoC memory unavailable\n");
7997 + goto err;
7998 + }
7999 +
8000 + ninfo->base = ioremap(noc_mem->start, resource_size(noc_mem));
8001 + if (!ninfo->base) {
8002 + MSM_BUS_ERR("IOremap failed for NoC!\n");
8003 + release_mem_region(noc_mem->start, resource_size(noc_mem));
8004 + goto err;
8005 + }
8006 +
8007 +skip_mem:
8008 + fab_pdata->hw_data = (void *)ninfo;
8009 + return (void *)ninfo;
8010 +
8011 +err:
8012 + kfree(ninfo->mas_modes);
8013 + kfree(ninfo);
8014 + return NULL;
8015 +}
8016 +
8017 +static void free_commit_data(void *cdata)
8018 +{
8019 + struct msm_bus_noc_commit *cd = (struct msm_bus_noc_commit *)cdata;
8020 +
8021 + kfree(cd->mas);
8022 + kfree(cd->slv);
8023 + kfree(cd);
8024 +}
8025 +
8026 +static bool msm_bus_noc_update_bw_reg(int mode)
8027 +{
8028 + bool ret = false;
8029 +
8030 + if ((mode == NOC_QOS_MODE_LIMITER) ||
8031 + (mode == NOC_QOS_MODE_REGULATOR))
8032 + ret = true;
8033 +
8034 + return ret;
8035 +}
8036 +
8037 +static void msm_bus_noc_update_bw(struct msm_bus_inode_info *hop,
8038 + struct msm_bus_inode_info *info,
8039 + struct msm_bus_fabric_registration *fab_pdata,
8040 + void *sel_cdata, int *master_tiers,
8041 + int64_t add_bw)
8042 +{
8043 + struct msm_bus_noc_info *ninfo;
8044 + struct msm_bus_noc_qos_bw qos_bw;
8045 + int i, ports;
8046 + int64_t bw;
8047 + struct msm_bus_noc_commit *sel_cd =
8048 + (struct msm_bus_noc_commit *)sel_cdata;
8049 +
8050 + ninfo = (struct msm_bus_noc_info *)fab_pdata->hw_data;
8051 + if (!ninfo->qos_freq) {
8052 + MSM_BUS_DBG("NOC: No qos frequency to update bw\n");
8053 + return;
8054 + }
8055 +
8056 + if (info->node_info->num_mports == 0) {
8057 + MSM_BUS_DBG("NOC: Skip Master BW\n");
8058 + goto skip_mas_bw;
8059 + }
8060 +
8061 + ports = info->node_info->num_mports;
8062 + bw = INTERLEAVED_BW(fab_pdata, add_bw, ports);
8063 +
8064 + MSM_BUS_DBG("NOC: Update bw for: %d: %lld\n",
8065 + info->node_info->priv_id, add_bw);
8066 + for (i = 0; i < ports; i++) {
8067 + sel_cd->mas[info->node_info->masterp[i]].bw += bw;
8068 + sel_cd->mas[info->node_info->masterp[i]].hw_id =
8069 + info->node_info->mas_hw_id;
8070 + MSM_BUS_DBG("NOC: Update mas_bw: ID: %d, BW: %llu ports:%d\n",
8071 + info->node_info->priv_id,
8072 + sel_cd->mas[info->node_info->masterp[i]].bw,
8073 + ports);
8074 + /* Check if info is a shared master.
8075 + * If it is, mark it dirty
8076 + * If it isn't, then set QOS Bandwidth
8077 + **/
8078 + if (info->node_info->hw_sel == MSM_BUS_RPM)
8079 + sel_cd->mas[info->node_info->masterp[i]].dirty = 1;
8080 + else {
8081 + if (!info->node_info->qport) {
8082 + MSM_BUS_DBG("No qos ports to update!\n");
8083 + break;
8084 + }
8085 +
8086 + if (!(info->node_info->mode == NOC_QOS_MODE_REGULATOR)
8087 + || (info->node_info->mode ==
8088 + NOC_QOS_MODE_LIMITER)) {
8089 + MSM_BUS_DBG("Skip QoS reg programming\n");
8090 + break;
8091 + }
8092 + qos_bw.bw = sel_cd->mas[info->node_info->masterp[i]].
8093 + bw;
8094 + qos_bw.ws = info->node_info->ws;
8095 + msm_bus_noc_set_qos_bw(ninfo->base,
8096 + ninfo->qos_baseoffset,
8097 + ninfo->qos_freq,
8098 + info->node_info->qport[i], ninfo->qos_delta,
8099 + info->node_info->perm_mode, &qos_bw);
8100 + MSM_BUS_DBG("NOC: QoS: Update mas_bw: ws: %u\n",
8101 + qos_bw.ws);
8102 + }
8103 + }
8104 +
8105 +skip_mas_bw:
8106 + ports = hop->node_info->num_sports;
8107 + for (i = 0; i < ports; i++) {
8108 + sel_cd->slv[hop->node_info->slavep[i]].bw += add_bw;
8109 + sel_cd->slv[hop->node_info->slavep[i]].hw_id =
8110 + hop->node_info->slv_hw_id;
8111 + MSM_BUS_DBG("NOC: Update slave_bw for ID: %d -> %llu\n",
8112 + hop->node_info->priv_id,
8113 + sel_cd->slv[hop->node_info->slavep[i]].bw);
8114 + MSM_BUS_DBG("NOC: Update slave_bw for hw_id: %d, index: %d\n",
8115 + hop->node_info->slv_hw_id, hop->node_info->slavep[i]);
8116 + /* Check if hop is a shared slave.
8117 + * If it is, mark it dirty
8118 + * If it isn't, then nothing to be done as the
8119 + * slaves are in bypass mode.
8120 + **/
8121 + if (hop->node_info->hw_sel == MSM_BUS_RPM)
8122 + sel_cd->slv[hop->node_info->slavep[i]].dirty = 1;
8123 + }
8124 +}
8125 +
8126 +static int msm_bus_noc_commit(struct msm_bus_fabric_registration
8127 + *fab_pdata, void *hw_data, void **cdata)
8128 +{
8129 + MSM_BUS_DBG("\nReached NOC Commit\n");
8130 + msm_bus_remote_hw_commit(fab_pdata, hw_data, cdata);
8131 + return 0;
8132 +}
8133 +
8134 +static int msm_bus_noc_port_halt(uint32_t haltid, uint8_t mport)
8135 +{
8136 + return 0;
8137 +}
8138 +
8139 +static int msm_bus_noc_port_unhalt(uint32_t haltid, uint8_t mport)
8140 +{
8141 + return 0;
8142 +}
8143 +
8144 +static int msm_bus_noc_qos_init(struct msm_bus_node_device_type *info,
8145 + void __iomem *qos_base,
8146 + uint32_t qos_off, uint32_t qos_delta,
8147 + uint32_t qos_freq)
8148 +{
8149 + struct msm_bus_noc_qos_priority prio;
8150 + int ret = 0;
8151 + int i;
8152 +
8153 + prio.p1 = info->node_info->qos_params.prio1;
8154 + prio.p0 = info->node_info->qos_params.prio0;
8155 +
8156 + if (!info->node_info->qport) {
8157 + MSM_BUS_DBG("No QoS Ports to init\n");
8158 + ret = 0;
8159 + goto err_qos_init;
8160 + }
8161 +
8162 + for (i = 0; i < info->node_info->num_qports; i++) {
8163 + if (info->node_info->qos_params.mode != NOC_QOS_MODE_BYPASS) {
8164 + noc_set_qos_priority(qos_base, qos_off,
8165 + info->node_info->qport[i], qos_delta,
8166 + &prio);
8167 +
8168 + if (info->node_info->qos_params.mode !=
8169 + NOC_QOS_MODE_FIXED) {
8170 + struct msm_bus_noc_qos_bw qbw;
8171 + qbw.ws = info->node_info->qos_params.ws;
8172 + qbw.bw = 0;
8173 + msm_bus_noc_set_qos_bw(qos_base, qos_off,
8174 + qos_freq,
8175 + info->node_info->qport[i],
8176 + qos_delta,
8177 + info->node_info->qos_params.mode,
8178 + &qbw);
8179 + }
8180 + }
8181 +
8182 + noc_set_qos_mode(qos_base, qos_off, info->node_info->qport[i],
8183 + qos_delta, info->node_info->qos_params.mode,
8184 + (1 << info->node_info->qos_params.mode));
8185 + }
8186 +err_qos_init:
8187 + return ret;
8188 +}
8189 +
8190 +static int msm_bus_noc_set_bw(struct msm_bus_node_device_type *dev,
8191 + void __iomem *qos_base,
8192 + uint32_t qos_off, uint32_t qos_delta,
8193 + uint32_t qos_freq)
8194 +{
8195 + int ret = 0;
8196 + uint64_t bw = 0;
8197 + int i;
8198 + struct msm_bus_node_info_type *info = dev->node_info;
8199 +
8200 + if (info && info->num_qports &&
8201 + ((info->qos_params.mode == NOC_QOS_MODE_REGULATOR) ||
8202 + (info->qos_params.mode ==
8203 + NOC_QOS_MODE_LIMITER))) {
8204 + struct msm_bus_noc_qos_bw qos_bw;
8205 +
8206 + bw = msm_bus_div64(info->num_qports,
8207 + dev->node_ab.ab[DUAL_CTX]);
8208 +
8209 + for (i = 0; i < info->num_qports; i++) {
8210 + if (!info->qport) {
8211 + MSM_BUS_DBG("No qos ports to update!\n");
8212 + break;
8213 + }
8214 +
8215 + qos_bw.bw = bw;
8216 + qos_bw.ws = info->qos_params.ws;
8217 + msm_bus_noc_set_qos_bw(qos_base, qos_off, qos_freq,
8218 + info->qport[i], qos_delta,
8219 + info->qos_params.mode, &qos_bw);
8220 + MSM_BUS_DBG("NOC: QoS: Update mas_bw: ws: %u\n",
8221 + qos_bw.ws);
8222 + }
8223 + }
8224 + return ret;
8225 +}
8226 +int msm_bus_noc_hw_init(struct msm_bus_fabric_registration *pdata,
8227 + struct msm_bus_hw_algorithm *hw_algo)
8228 +{
8229 + /* Set interleaving to true by default */
8230 + pdata->il_flag = true;
8231 + hw_algo->allocate_commit_data = msm_bus_noc_allocate_commit_data;
8232 + hw_algo->allocate_hw_data = msm_bus_noc_allocate_noc_data;
8233 + hw_algo->node_init = msm_bus_noc_node_init;
8234 + hw_algo->free_commit_data = free_commit_data;
8235 + hw_algo->update_bw = msm_bus_noc_update_bw;
8236 + hw_algo->commit = msm_bus_noc_commit;
8237 + hw_algo->port_halt = msm_bus_noc_port_halt;
8238 + hw_algo->port_unhalt = msm_bus_noc_port_unhalt;
8239 + hw_algo->update_bw_reg = msm_bus_noc_update_bw_reg;
8240 + hw_algo->config_master = NULL;
8241 + hw_algo->config_limiter = NULL;
8242 +
8243 + return 0;
8244 +}
8245 +
8246 +int msm_bus_noc_set_ops(struct msm_bus_node_device_type *bus_dev)
8247 +{
8248 + if (!bus_dev)
8249 + return -ENODEV;
8250 + else {
8251 + bus_dev->fabdev->noc_ops.qos_init = msm_bus_noc_qos_init;
8252 + bus_dev->fabdev->noc_ops.set_bw = msm_bus_noc_set_bw;
8253 + bus_dev->fabdev->noc_ops.limit_mport = NULL;
8254 + bus_dev->fabdev->noc_ops.update_bw_reg =
8255 + msm_bus_noc_update_bw_reg;
8256 + }
8257 + return 0;
8258 +}
8259 +EXPORT_SYMBOL(msm_bus_noc_set_ops);
8260 --- /dev/null
8261 +++ b/drivers/bus/msm_bus/msm_bus_noc.h
8262 @@ -0,0 +1,76 @@
8263 +/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
8264 + *
8265 + * This program is free software; you can redistribute it and/or modify
8266 + * it under the terms of the GNU General Public License version 2 and
8267 + * only version 2 as published by the Free Software Foundation.
8268 + *
8269 + * This program is distributed in the hope that it will be useful,
8270 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
8271 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8272 + * GNU General Public License for more details.
8273 + */
8274 +
8275 +#ifndef _ARCH_ARM_MACH_MSM_BUS_BIMC_H
8276 +#define _ARCH_ARM_MACH_MSM_BUS_BIMC_H
8277 +
8278 +enum msm_bus_noc_qos_mode_type {
8279 + NOC_QOS_MODE_FIXED = 0,
8280 + NOC_QOS_MODE_LIMITER,
8281 + NOC_QOS_MODE_BYPASS,
8282 + NOC_QOS_MODE_REGULATOR,
8283 + NOC_QOS_MODE_MAX,
8284 +};
8285 +
8286 +enum msm_bus_noc_qos_mode_perm {
8287 + NOC_QOS_PERM_MODE_FIXED = (1 << NOC_QOS_MODE_FIXED),
8288 + NOC_QOS_PERM_MODE_LIMITER = (1 << NOC_QOS_MODE_LIMITER),
8289 + NOC_QOS_PERM_MODE_BYPASS = (1 << NOC_QOS_MODE_BYPASS),
8290 + NOC_QOS_PERM_MODE_REGULATOR = (1 << NOC_QOS_MODE_REGULATOR),
8291 +};
8292 +
8293 +#define NOC_QOS_MODES_ALL_PERM (NOC_QOS_PERM_MODE_FIXED | \
8294 + NOC_QOS_PERM_MODE_LIMITER | NOC_QOS_PERM_MODE_BYPASS | \
8295 + NOC_QOS_PERM_MODE_REGULATOR)
8296 +
8297 +struct msm_bus_noc_commit {
8298 + struct msm_bus_node_hw_info *mas;
8299 + struct msm_bus_node_hw_info *slv;
8300 +};
8301 +
8302 +struct msm_bus_noc_info {
8303 + void __iomem *base;
8304 + uint32_t base_addr;
8305 + uint32_t nmasters;
8306 + uint32_t nqos_masters;
8307 + uint32_t nslaves;
8308 + uint32_t qos_freq; /* QOS Clock in KHz */
8309 + uint32_t qos_baseoffset;
8310 + uint32_t qos_delta;
8311 + uint32_t *mas_modes;
8312 + struct msm_bus_noc_commit cdata[NUM_CTX];
8313 +};
8314 +
8315 +struct msm_bus_noc_qos_priority {
8316 + uint32_t high_prio;
8317 + uint32_t low_prio;
8318 + uint32_t read_prio;
8319 + uint32_t write_prio;
8320 + uint32_t p1;
8321 + uint32_t p0;
8322 +};
8323 +
8324 +struct msm_bus_noc_qos_bw {
8325 + uint64_t bw; /* Bandwidth in bytes per second */
8326 + uint32_t ws; /* Window size in nano seconds */
8327 +};
8328 +
8329 +void msm_bus_noc_init(struct msm_bus_noc_info *ninfo);
8330 +uint8_t msm_bus_noc_get_qos_mode(void __iomem *base, uint32_t qos_off,
8331 + uint32_t mport, uint32_t qos_delta, uint32_t mode, uint32_t perm_mode);
8332 +void msm_bus_noc_get_qos_priority(void __iomem *base, uint32_t qos_off,
8333 + uint32_t mport, uint32_t qos_delta,
8334 + struct msm_bus_noc_qos_priority *qprio);
8335 +void msm_bus_noc_get_qos_bw(void __iomem *base, uint32_t qos_off,
8336 + uint32_t qos_freq, uint32_t mport, uint32_t qos_delta,
8337 + uint8_t perm_mode, struct msm_bus_noc_qos_bw *qbw);
8338 +#endif /*_ARCH_ARM_MACH_MSM_BUS_NOC_H */
8339 --- /dev/null
8340 +++ b/drivers/bus/msm_bus/msm_bus_of.c
8341 @@ -0,0 +1,705 @@
8342 +/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
8343 + *
8344 + * This program is free software; you can redistribute it and/or modify
8345 + * it under the terms of the GNU General Public License version 2 and
8346 + * only version 2 as published by the Free Software Foundation.
8347 + *
8348 + * This program is distributed in the hope that it will be useful,
8349 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
8350 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8351 + * GNU General Public License for more details.
8352 + */
8353 +
8354 +#define pr_fmt(fmt) "AXI: %s(): " fmt, __func__
8355 +
8356 +#include <linux/module.h>
8357 +#include <linux/slab.h>
8358 +#include <linux/string.h>
8359 +#include <linux/of.h>
8360 +#include <linux/of_device.h>
8361 +#include <linux/platform_device.h>
8362 +#include "msm-bus.h"
8363 +#include "msm-bus-board.h"
8364 +#include "msm_bus_core.h"
8365 +
8366 +static const char * const hw_sel_name[] = {"RPM", "NoC", "BIMC", NULL};
8367 +static const char * const mode_sel_name[] = {"Fixed", "Limiter", "Bypass",
8368 + "Regulator", NULL};
8369 +
8370 +static int get_num(const char *const str[], const char *name)
8371 +{
8372 + int i = 0;
8373 +
8374 + do {
8375 + if (!strcmp(name, str[i]))
8376 + return i;
8377 +
8378 + i++;
8379 + } while (str[i] != NULL);
8380 +
8381 + pr_err("Error: string %s not found\n", name);
8382 + return -EINVAL;
8383 +}
8384 +
8385 +#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_MSM_BUS_SCALING)
8386 +static struct msm_bus_scale_pdata *get_pdata(struct platform_device *pdev,
8387 + struct device_node *of_node)
8388 +{
8389 + struct msm_bus_scale_pdata *pdata = NULL;
8390 + struct msm_bus_paths *usecase = NULL;
8391 + int i = 0, j, ret, num_usecases = 0, num_paths, len;
8392 + const uint32_t *vec_arr = NULL;
8393 + bool mem_err = false;
8394 +
8395 + if (!pdev) {
8396 + pr_err("Error: Null Platform device\n");
8397 + return NULL;
8398 + }
8399 +
8400 + pdata = devm_kzalloc(&pdev->dev, sizeof(struct msm_bus_scale_pdata),
8401 + GFP_KERNEL);
8402 + if (!pdata) {
8403 + pr_err("Error: Memory allocation for pdata failed\n");
8404 + mem_err = true;
8405 + goto err;
8406 + }
8407 +
8408 + ret = of_property_read_string(of_node, "qcom,msm-bus,name",
8409 + &pdata->name);
8410 + if (ret) {
8411 + pr_err("Error: Client name not found\n");
8412 + goto err;
8413 + }
8414 +
8415 + ret = of_property_read_u32(of_node, "qcom,msm-bus,num-cases",
8416 + &num_usecases);
8417 + if (ret) {
8418 + pr_err("Error: num-usecases not found\n");
8419 + goto err;
8420 + }
8421 +
8422 + pdata->num_usecases = num_usecases;
8423 +
8424 + if (of_property_read_bool(of_node, "qcom,msm-bus,active-only"))
8425 + pdata->active_only = 1;
8426 + else {
8427 + pr_debug("active_only flag absent.\n");
8428 + pr_debug("Using dual context by default\n");
8429 + }
8430 +
8431 + usecase = devm_kzalloc(&pdev->dev, (sizeof(struct msm_bus_paths) *
8432 + pdata->num_usecases), GFP_KERNEL);
8433 + if (!usecase) {
8434 + pr_err("Error: Memory allocation for paths failed\n");
8435 + mem_err = true;
8436 + goto err;
8437 + }
8438 +
8439 + ret = of_property_read_u32(of_node, "qcom,msm-bus,num-paths",
8440 + &num_paths);
8441 + if (ret) {
8442 + pr_err("Error: num_paths not found\n");
8443 + goto err;
8444 + }
8445 +
8446 + vec_arr = of_get_property(of_node, "qcom,msm-bus,vectors-KBps", &len);
8447 + if (vec_arr == NULL) {
8448 + pr_err("Error: Vector array not found\n");
8449 + goto err;
8450 + }
8451 +
8452 + if (len != num_usecases * num_paths * sizeof(uint32_t) * 4) {
8453 + pr_err("Error: Length-error on getting vectors\n");
8454 + goto err;
8455 + }
8456 +
8457 + for (i = 0; i < num_usecases; i++) {
8458 + usecase[i].num_paths = num_paths;
8459 + usecase[i].vectors = devm_kzalloc(&pdev->dev, num_paths *
8460 + sizeof(struct msm_bus_vectors), GFP_KERNEL);
8461 + if (!usecase[i].vectors) {
8462 + mem_err = true;
8463 + pr_err("Error: Mem alloc failure in vectors\n");
8464 + goto err;
8465 + }
8466 +
8467 + for (j = 0; j < num_paths; j++) {
8468 + int index = ((i * num_paths) + j) * 4;
8469 + usecase[i].vectors[j].src = be32_to_cpu(vec_arr[index]);
8470 + usecase[i].vectors[j].dst =
8471 + be32_to_cpu(vec_arr[index + 1]);
8472 + usecase[i].vectors[j].ab = (uint64_t)
8473 + KBTOB(be32_to_cpu(vec_arr[index + 2]));
8474 + usecase[i].vectors[j].ib = (uint64_t)
8475 + KBTOB(be32_to_cpu(vec_arr[index + 3]));
8476 + }
8477 + }
8478 +
8479 + pdata->usecase = usecase;
8480 + return pdata;
8481 +err:
8482 + if (mem_err) {
8483 + for (; i > 0; i--)
8484 + kfree(usecase[i-1].vectors);
8485 +
8486 + kfree(usecase);
8487 + kfree(pdata);
8488 + }
8489 +
8490 + return NULL;
8491 +}
8492 +
8493 +/**
8494 + * msm_bus_cl_get_pdata() - Generate bus client data from device tree
8495 + * provided by clients.
8496 + *
8497 + * of_node: Device tree node to extract information from
8498 + *
8499 + * The function returns a valid pointer to the allocated bus-scale-pdata
8500 + * if the vectors were correctly read from the client's device node.
8501 + * Any error in reading or parsing the device node will return NULL
8502 + * to the caller.
8503 + */
8504 +struct msm_bus_scale_pdata *msm_bus_cl_get_pdata(struct platform_device *pdev)
8505 +{
8506 + struct device_node *of_node;
8507 + struct msm_bus_scale_pdata *pdata = NULL;
8508 +
8509 + if (!pdev) {
8510 + pr_err("Error: Null Platform device\n");
8511 + return NULL;
8512 + }
8513 +
8514 + of_node = pdev->dev.of_node;
8515 + pdata = get_pdata(pdev, of_node);
8516 + if (!pdata) {
8517 + pr_err("client has to provide missing entry for successful registration\n");
8518 + return NULL;
8519 + }
8520 +
8521 + return pdata;
8522 +}
8523 +EXPORT_SYMBOL(msm_bus_cl_get_pdata);
8524 +
8525 +/**
8526 + * msm_bus_cl_pdata_from_node() - Generate bus client data from device tree
8527 + * node provided by clients. This function should be used when a client
8528 + * driver needs to register multiple bus-clients from a single device-tree
8529 + * node associated with the platform-device.
8530 + *
8531 + * of_node: The subnode containing information about the bus scaling
8532 + * data
8533 + *
8534 + * pdev: Platform device associated with the device-tree node
8535 + *
8536 + * The function returns a valid pointer to the allocated bus-scale-pdata
8537 + * if the vectors were correctly read from the client's device node.
8538 + * Any error in reading or parsing the device node will return NULL
8539 + * to the caller.
8540 + */
8541 +struct msm_bus_scale_pdata *msm_bus_pdata_from_node(
8542 + struct platform_device *pdev, struct device_node *of_node)
8543 +{
8544 + struct msm_bus_scale_pdata *pdata = NULL;
8545 +
8546 + if (!pdev) {
8547 + pr_err("Error: Null Platform device\n");
8548 + return NULL;
8549 + }
8550 +
8551 + if (!of_node) {
8552 + pr_err("Error: Null of_node passed to bus driver\n");
8553 + return NULL;
8554 + }
8555 +
8556 + pdata = get_pdata(pdev, of_node);
8557 + if (!pdata) {
8558 + pr_err("client has to provide missing entry for successful registration\n");
8559 + return NULL;
8560 + }
8561 +
8562 + return pdata;
8563 +}
8564 +EXPORT_SYMBOL(msm_bus_pdata_from_node);
8565 +
8566 +/**
8567 + * msm_bus_cl_clear_pdata() - Clear pdata allocated from device-tree
8568 + * of_node: Device tree node to extract information from
8569 + */
8570 +void msm_bus_cl_clear_pdata(struct msm_bus_scale_pdata *pdata)
8571 +{
8572 + int i;
8573 +
8574 + for (i = 0; i < pdata->num_usecases; i++)
8575 + kfree(pdata->usecase[i].vectors);
8576 +
8577 + kfree(pdata->usecase);
8578 + kfree(pdata);
8579 +}
8580 +EXPORT_SYMBOL(msm_bus_cl_clear_pdata);
8581 +#endif
8582 +
8583 +static int *get_arr(struct platform_device *pdev,
8584 + const struct device_node *node, const char *prop,
8585 + int *nports)
8586 +{
8587 + int size = 0, ret;
8588 + int *arr = NULL;
8589 +
8590 + if (of_get_property(node, prop, &size)) {
8591 + *nports = size / sizeof(int);
8592 + } else {
8593 + pr_debug("Property %s not available\n", prop);
8594 + *nports = 0;
8595 + return NULL;
8596 + }
8597 +
8598 + if (!size) {
8599 + *nports = 0;
8600 + return NULL;
8601 + }
8602 +
8603 + arr = devm_kzalloc(&pdev->dev, size, GFP_KERNEL);
8604 + if (ZERO_OR_NULL_PTR(arr)) {
8605 + pr_err("Error: Failed to alloc mem for %s\n", prop);
8606 + return NULL;
8607 + }
8608 +
8609 + ret = of_property_read_u32_array(node, prop, (u32 *)arr, *nports);
8610 + if (ret) {
8611 + pr_err("Error in reading property: %s\n", prop);
8612 + goto err;
8613 + }
8614 +
8615 + return arr;
8616 +err:
8617 + devm_kfree(&pdev->dev, arr);
8618 + return NULL;
8619 +}
8620 +
8621 +static u64 *get_th_params(struct platform_device *pdev,
8622 + const struct device_node *node, const char *prop,
8623 + int *nports)
8624 +{
8625 + int size = 0, ret;
8626 + u64 *ret_arr = NULL;
8627 + int *arr = NULL;
8628 + int i;
8629 +
8630 + if (of_get_property(node, prop, &size)) {
8631 + *nports = size / sizeof(int);
8632 + } else {
8633 + pr_debug("Property %s not available\n", prop);
8634 + *nports = 0;
8635 + return NULL;
8636 + }
8637 +
8638 + if (!size) {
8639 + *nports = 0;
8640 + return NULL;
8641 + }
8642 +
8643 + ret_arr = devm_kzalloc(&pdev->dev, (*nports * sizeof(u64)),
8644 + GFP_KERNEL);
8645 + if (ZERO_OR_NULL_PTR(ret_arr)) {
8646 + pr_err("Error: Failed to alloc mem for ret arr %s\n", prop);
8647 + return NULL;
8648 + }
8649 +
8650 + arr = kzalloc(size, GFP_KERNEL);
8651 + if ((ZERO_OR_NULL_PTR(arr))) {
8652 + pr_err("Error: Failed to alloc temp mem for %s\n", prop);
8653 + return NULL;
8654 + }
8655 +
8656 + ret = of_property_read_u32_array(node, prop, (u32 *)arr, *nports);
8657 + if (ret) {
8658 + pr_err("Error in reading property: %s\n", prop);
8659 + goto err;
8660 + }
8661 +
8662 + for (i = 0; i < *nports; i++)
8663 + ret_arr[i] = (uint64_t)KBTOB(arr[i]);
8664 +
8665 + MSM_BUS_DBG("%s: num entries %d prop %s", __func__, *nports, prop);
8666 +
8667 + for (i = 0; i < *nports; i++)
8668 + MSM_BUS_DBG("Th %d val %llu", i, ret_arr[i]);
8669 +
8670 + kfree(arr);
8671 + return ret_arr;
8672 +err:
8673 + kfree(arr);
8674 + devm_kfree(&pdev->dev, ret_arr);
8675 + return NULL;
8676 +}
8677 +
8678 +static struct msm_bus_node_info *get_nodes(struct device_node *of_node,
8679 + struct platform_device *pdev,
8680 + struct msm_bus_fabric_registration *pdata)
8681 +{
8682 + struct msm_bus_node_info *info;
8683 + struct device_node *child_node = NULL;
8684 + int i = 0, ret;
8685 + int num_bw = 0;
8686 + u32 temp;
8687 +
8688 + for_each_child_of_node(of_node, child_node) {
8689 + i++;
8690 + }
8691 +
8692 + pdata->len = i;
8693 + info = (struct msm_bus_node_info *)
8694 + devm_kzalloc(&pdev->dev, sizeof(struct msm_bus_node_info) *
8695 + pdata->len, GFP_KERNEL);
8696 + if (ZERO_OR_NULL_PTR(info)) {
8697 + pr_err("Failed to alloc memory for nodes: %d\n", pdata->len);
8698 + goto err;
8699 + }
8700 +
8701 + i = 0;
8702 + child_node = NULL;
8703 + for_each_child_of_node(of_node, child_node) {
8704 + const char *sel_str;
8705 +
8706 + ret = of_property_read_string(child_node, "label",
8707 + &info[i].name);
8708 + if (ret)
8709 + pr_err("Error reading node label\n");
8710 +
8711 + ret = of_property_read_u32(child_node, "cell-id", &info[i].id);
8712 + if (ret) {
8713 + pr_err("Error reading node id\n");
8714 + goto err;
8715 + }
8716 +
8717 + if (of_property_read_bool(child_node, "qcom,gateway"))
8718 + info[i].gateway = 1;
8719 +
8720 + of_property_read_u32(child_node, "qcom,mas-hw-id",
8721 + &info[i].mas_hw_id);
8722 +
8723 + of_property_read_u32(child_node, "qcom,slv-hw-id",
8724 + &info[i].slv_hw_id);
8725 + info[i].masterp = get_arr(pdev, child_node,
8726 + "qcom,masterp", &info[i].num_mports);
8727 + /* No need to store number of qports */
8728 + info[i].qport = get_arr(pdev, child_node,
8729 + "qcom,qport", &ret);
8730 + pdata->nmasters += info[i].num_mports;
8731 +
8732 +
8733 + info[i].slavep = get_arr(pdev, child_node,
8734 + "qcom,slavep", &info[i].num_sports);
8735 + pdata->nslaves += info[i].num_sports;
8736 +
8737 +
8738 + info[i].tier = get_arr(pdev, child_node,
8739 + "qcom,tier", &info[i].num_tiers);
8740 +
8741 + if (of_property_read_bool(child_node, "qcom,ahb"))
8742 + info[i].ahb = 1;
8743 +
8744 + ret = of_property_read_string(child_node, "qcom,hw-sel",
8745 + &sel_str);
8746 + if (ret)
8747 + info[i].hw_sel = 0;
8748 + else {
8749 + ret = get_num(hw_sel_name, sel_str);
8750 + if (ret < 0) {
8751 + pr_err("Invalid hw-sel\n");
8752 + goto err;
8753 + }
8754 +
8755 + info[i].hw_sel = ret;
8756 + }
8757 +
8758 + of_property_read_u32(child_node, "qcom,buswidth",
8759 + &info[i].buswidth);
8760 + of_property_read_u32(child_node, "qcom,ws", &info[i].ws);
8761 +
8762 + info[i].dual_conf =
8763 + of_property_read_bool(child_node, "qcom,dual-conf");
8764 +
8765 +
8766 + info[i].th = get_th_params(pdev, child_node, "qcom,thresh",
8767 + &info[i].num_thresh);
8768 +
8769 + info[i].bimc_bw = get_th_params(pdev, child_node,
8770 + "qcom,bimc,bw", &num_bw);
8771 +
8772 + if (num_bw != info[i].num_thresh) {
8773 + pr_err("%s:num_bw %d must equal num_thresh %d",
8774 + __func__, num_bw, info[i].num_thresh);
8775 + pr_err("%s:Err setting up dual conf for %s",
8776 + __func__, info[i].name);
8777 + goto err;
8778 + }
8779 +
8780 + of_property_read_u32(child_node, "qcom,bimc,gp",
8781 + &info[i].bimc_gp);
8782 + of_property_read_u32(child_node, "qcom,bimc,thmp",
8783 + &info[i].bimc_thmp);
8784 +
8785 + ret = of_property_read_string(child_node, "qcom,mode-thresh",
8786 + &sel_str);
8787 + if (ret)
8788 + info[i].mode_thresh = 0;
8789 + else {
8790 + ret = get_num(mode_sel_name, sel_str);
8791 + if (ret < 0) {
8792 + pr_err("Unknown mode :%s\n", sel_str);
8793 + goto err;
8794 + }
8795 +
8796 + info[i].mode_thresh = ret;
8797 + MSM_BUS_DBG("AXI: THreshold mode set: %d\n",
8798 + info[i].mode_thresh);
8799 + }
8800 +
8801 + ret = of_property_read_string(child_node, "qcom,mode",
8802 + &sel_str);
8803 +
8804 + if (ret)
8805 + info[i].mode = 0;
8806 + else {
8807 + ret = get_num(mode_sel_name, sel_str);
8808 + if (ret < 0) {
8809 + pr_err("Unknown mode :%s\n", sel_str);
8810 + goto err;
8811 + }
8812 +
8813 + info[i].mode = ret;
8814 + }
8815 +
8816 + info[i].nr_lim =
8817 + of_property_read_bool(child_node, "qcom,nr-lim");
8818 +
8819 + ret = of_property_read_u32(child_node, "qcom,ff",
8820 + &info[i].ff);
8821 + if (ret) {
8822 + pr_debug("fudge factor not present %d", info[i].id);
8823 + info[i].ff = 0;
8824 + }
8825 +
8826 + ret = of_property_read_u32(child_node, "qcom,floor-bw",
8827 + &temp);
8828 + if (ret) {
8829 + pr_debug("fabdev floor bw not present %d", info[i].id);
8830 + info[i].floor_bw = 0;
8831 + } else {
8832 + info[i].floor_bw = KBTOB(temp);
8833 + }
8834 +
8835 + info[i].rt_mas =
8836 + of_property_read_bool(child_node, "qcom,rt-mas");
8837 +
8838 + ret = of_property_read_string(child_node, "qcom,perm-mode",
8839 + &sel_str);
8840 + if (ret)
8841 + info[i].perm_mode = 0;
8842 + else {
8843 + ret = get_num(mode_sel_name, sel_str);
8844 + if (ret < 0)
8845 + goto err;
8846 +
8847 + info[i].perm_mode = 1 << ret;
8848 + }
8849 +
8850 + of_property_read_u32(child_node, "qcom,prio-lvl",
8851 + &info[i].prio_lvl);
8852 + of_property_read_u32(child_node, "qcom,prio-rd",
8853 + &info[i].prio_rd);
8854 + of_property_read_u32(child_node, "qcom,prio-wr",
8855 + &info[i].prio_wr);
8856 + of_property_read_u32(child_node, "qcom,prio0", &info[i].prio0);
8857 + of_property_read_u32(child_node, "qcom,prio1", &info[i].prio1);
8858 + ret = of_property_read_string(child_node, "qcom,slaveclk-dual",
8859 + &info[i].slaveclk[DUAL_CTX]);
8860 + if (!ret)
8861 + pr_debug("Got slaveclk_dual: %s\n",
8862 + info[i].slaveclk[DUAL_CTX]);
8863 + else
8864 + info[i].slaveclk[DUAL_CTX] = NULL;
8865 +
8866 + ret = of_property_read_string(child_node,
8867 + "qcom,slaveclk-active", &info[i].slaveclk[ACTIVE_CTX]);
8868 + if (!ret)
8869 + pr_debug("Got slaveclk_active\n");
8870 + else
8871 + info[i].slaveclk[ACTIVE_CTX] = NULL;
8872 +
8873 + ret = of_property_read_string(child_node, "qcom,memclk-dual",
8874 + &info[i].memclk[DUAL_CTX]);
8875 + if (!ret)
8876 + pr_debug("Got memclk_dual\n");
8877 + else
8878 + info[i].memclk[DUAL_CTX] = NULL;
8879 +
8880 + ret = of_property_read_string(child_node, "qcom,memclk-active",
8881 + &info[i].memclk[ACTIVE_CTX]);
8882 + if (!ret)
8883 + pr_debug("Got memclk_active\n");
8884 + else
8885 + info[i].memclk[ACTIVE_CTX] = NULL;
8886 +
8887 + ret = of_property_read_string(child_node, "qcom,iface-clk-node",
8888 + &info[i].iface_clk_node);
8889 + if (!ret)
8890 + pr_debug("Got iface_clk_node\n");
8891 + else
8892 + info[i].iface_clk_node = NULL;
8893 +
8894 + pr_debug("Node name: %s\n", info[i].name);
8895 + of_node_put(child_node);
8896 + i++;
8897 + }
8898 +
8899 + pr_debug("Bus %d added: %d masters\n", pdata->id, pdata->nmasters);
8900 + pr_debug("Bus %d added: %d slaves\n", pdata->id, pdata->nslaves);
8901 + return info;
8902 +err:
8903 + return NULL;
8904 +}
8905 +
8906 +void msm_bus_of_get_nfab(struct platform_device *pdev,
8907 + struct msm_bus_fabric_registration *pdata)
8908 +{
8909 + struct device_node *of_node;
8910 + int ret, nfab = 0;
8911 +
8912 + if (!pdev) {
8913 + pr_err("Error: Null platform device\n");
8914 + return;
8915 + }
8916 +
8917 + of_node = pdev->dev.of_node;
8918 + ret = of_property_read_u32(of_node, "qcom,nfab",
8919 + &nfab);
8920 + if (!ret)
8921 + pr_debug("Fab_of: Read number of buses: %u\n", nfab);
8922 +
8923 + msm_bus_board_set_nfab(pdata, nfab);
8924 +}
8925 +
8926 +struct msm_bus_fabric_registration
8927 + *msm_bus_of_get_fab_data(struct platform_device *pdev)
8928 +{
8929 + struct device_node *of_node;
8930 + struct msm_bus_fabric_registration *pdata;
8931 + bool mem_err = false;
8932 + int ret = 0;
8933 + const char *sel_str;
8934 + u32 temp;
8935 +
8936 + if (!pdev) {
8937 + pr_err("Error: Null platform device\n");
8938 + return NULL;
8939 + }
8940 +
8941 + of_node = pdev->dev.of_node;
8942 + pdata = devm_kzalloc(&pdev->dev,
8943 + sizeof(struct msm_bus_fabric_registration), GFP_KERNEL);
8944 + if (!pdata) {
8945 + pr_err("Error: Memory allocation for pdata failed\n");
8946 + mem_err = true;
8947 + goto err;
8948 + }
8949 +
8950 + ret = of_property_read_string(of_node, "label", &pdata->name);
8951 + if (ret) {
8952 + pr_err("Error: label not found\n");
8953 + goto err;
8954 + }
8955 + pr_debug("Fab_of: Read name: %s\n", pdata->name);
8956 +
8957 + ret = of_property_read_u32(of_node, "cell-id",
8958 + &pdata->id);
8959 + if (ret) {
8960 + pr_err("Error: num-usecases not found\n");
8961 + goto err;
8962 + }
8963 + pr_debug("Fab_of: Read id: %u\n", pdata->id);
8964 +
8965 + if (of_property_read_bool(of_node, "qcom,ahb"))
8966 + pdata->ahb = 1;
8967 +
8968 + ret = of_property_read_string(of_node, "qcom,fabclk-dual",
8969 + &pdata->fabclk[DUAL_CTX]);
8970 + if (ret) {
8971 + pr_debug("fabclk_dual not available\n");
8972 + pdata->fabclk[DUAL_CTX] = NULL;
8973 + } else
8974 + pr_debug("Fab_of: Read clk dual ctx: %s\n",
8975 + pdata->fabclk[DUAL_CTX]);
8976 + ret = of_property_read_string(of_node, "qcom,fabclk-active",
8977 + &pdata->fabclk[ACTIVE_CTX]);
8978 + if (ret) {
8979 + pr_debug("Error: fabclk_active not available\n");
8980 + pdata->fabclk[ACTIVE_CTX] = NULL;
8981 + } else
8982 + pr_debug("Fab_of: Read clk act ctx: %s\n",
8983 + pdata->fabclk[ACTIVE_CTX]);
8984 +
8985 + ret = of_property_read_u32(of_node, "qcom,ntieredslaves",
8986 + &pdata->ntieredslaves);
8987 + if (ret) {
8988 + pr_err("Error: ntieredslaves not found\n");
8989 + goto err;
8990 + }
8991 +
8992 + ret = of_property_read_u32(of_node, "qcom,qos-freq", &pdata->qos_freq);
8993 + if (ret)
8994 + pr_debug("qos_freq not available\n");
8995 +
8996 + ret = of_property_read_string(of_node, "qcom,hw-sel", &sel_str);
8997 + if (ret) {
8998 + pr_err("Error: hw_sel not found\n");
8999 + goto err;
9000 + } else {
9001 + ret = get_num(hw_sel_name, sel_str);
9002 + if (ret < 0)
9003 + goto err;
9004 +
9005 + pdata->hw_sel = ret;
9006 + }
9007 +
9008 + if (of_property_read_bool(of_node, "qcom,virt"))
9009 + pdata->virt = true;
9010 +
9011 + ret = of_property_read_u32(of_node, "qcom,qos-baseoffset",
9012 + &pdata->qos_baseoffset);
9013 + if (ret)
9014 + pr_debug("%s:qos_baseoffset not available\n", __func__);
9015 +
9016 + ret = of_property_read_u32(of_node, "qcom,qos-delta",
9017 + &pdata->qos_delta);
9018 + if (ret)
9019 + pr_debug("%s:qos_delta not available\n", __func__);
9020 +
9021 + if (of_property_read_bool(of_node, "qcom,rpm-en"))
9022 + pdata->rpm_enabled = 1;
9023 +
9024 + ret = of_property_read_u32(of_node, "qcom,nr-lim-thresh",
9025 + &temp);
9026 +
9027 + if (ret) {
9028 + pr_err("nr-lim threshold not specified");
9029 + pdata->nr_lim_thresh = 0;
9030 + } else {
9031 + pdata->nr_lim_thresh = KBTOB(temp);
9032 + }
9033 +
9034 + ret = of_property_read_u32(of_node, "qcom,eff-fact",
9035 + &pdata->eff_fact);
9036 + if (ret) {
9037 + pr_err("Fab eff-factor not present");
9038 + pdata->eff_fact = 0;
9039 + }
9040 +
9041 + pdata->info = get_nodes(of_node, pdev, pdata);
9042 + return pdata;
9043 +err:
9044 + return NULL;
9045 +}
9046 +EXPORT_SYMBOL(msm_bus_of_get_fab_data);
9047 --- /dev/null
9048 +++ b/drivers/bus/msm_bus/msm_bus_of_adhoc.c
9049 @@ -0,0 +1,641 @@
9050 +/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
9051 + *
9052 + * This program is free software; you can redistribute it and/or modify
9053 + * it under the terms of the GNU General Public License version 2 and
9054 + * only version 2 as published by the Free Software Foundation.
9055 + *
9056 + * This program is distributed in the hope that it will be useful,
9057 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
9058 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9059 + * GNU General Public License for more details.
9060 + */
9061 +
9062 +#define pr_fmt(fmt) "AXI: %s(): " fmt, __func__
9063 +
9064 +#include <linux/clk.h>
9065 +#include <linux/device.h>
9066 +#include <linux/module.h>
9067 +#include <linux/slab.h>
9068 +#include <linux/string.h>
9069 +#include <linux/of.h>
9070 +#include <linux/of_device.h>
9071 +#include <linux/platform_device.h>
9072 +#include "msm-bus.h"
9073 +#include "msm-bus-board.h"
9074 +#include "msm_bus_rules.h"
9075 +#include "msm_bus_core.h"
9076 +#include "msm_bus_adhoc.h"
9077 +
9078 +#define DEFAULT_QOS_FREQ 19200
9079 +#define DEFAULT_UTIL_FACT 100
9080 +#define DEFAULT_VRAIL_COMP 100
9081 +
9082 +static int get_qos_mode(struct platform_device *pdev,
9083 + struct device_node *node, const char *qos_mode)
9084 +{
9085 + const char *qos_names[] = {"fixed", "limiter", "bypass", "regulator"};
9086 + int i = 0;
9087 + int ret = -1;
9088 +
9089 + if (!qos_mode)
9090 + goto exit_get_qos_mode;
9091 +
9092 + for (i = 0; i < ARRAY_SIZE(qos_names); i++) {
9093 + if (!strcmp(qos_mode, qos_names[i]))
9094 + break;
9095 + }
9096 + if (i == ARRAY_SIZE(qos_names))
9097 + dev_err(&pdev->dev, "Cannot match mode qos %s using Bypass",
9098 + qos_mode);
9099 + else
9100 + ret = i;
9101 +
9102 +exit_get_qos_mode:
9103 + return ret;
9104 +}
9105 +
9106 +static int *get_arr(struct platform_device *pdev,
9107 + struct device_node *node, const char *prop,
9108 + int *nports)
9109 +{
9110 + int size = 0, ret;
9111 + int *arr = NULL;
9112 +
9113 + if (of_get_property(node, prop, &size)) {
9114 + *nports = size / sizeof(int);
9115 + } else {
9116 + dev_dbg(&pdev->dev, "Property %s not available\n", prop);
9117 + *nports = 0;
9118 + return NULL;
9119 + }
9120 +
9121 + arr = devm_kzalloc(&pdev->dev, size, GFP_KERNEL);
9122 + if ((size > 0) && ZERO_OR_NULL_PTR(arr)) {
9123 + dev_err(&pdev->dev, "Error: Failed to alloc mem for %s\n",
9124 + prop);
9125 + return NULL;
9126 + }
9127 +
9128 + ret = of_property_read_u32_array(node, prop, (u32 *)arr, *nports);
9129 + if (ret) {
9130 + dev_err(&pdev->dev, "Error in reading property: %s\n", prop);
9131 + goto arr_err;
9132 + }
9133 +
9134 + return arr;
9135 +arr_err:
9136 + devm_kfree(&pdev->dev, arr);
9137 + return NULL;
9138 +}
9139 +
9140 +static struct msm_bus_fab_device_type *get_fab_device_info(
9141 + struct device_node *dev_node,
9142 + struct platform_device *pdev)
9143 +{
9144 + struct msm_bus_fab_device_type *fab_dev;
9145 + unsigned int ret;
9146 + struct resource *res;
9147 + const char *base_name;
9148 +
9149 + fab_dev = devm_kzalloc(&pdev->dev,
9150 + sizeof(struct msm_bus_fab_device_type),
9151 + GFP_KERNEL);
9152 + if (!fab_dev) {
9153 + dev_err(&pdev->dev,
9154 + "Error: Unable to allocate memory for fab_dev\n");
9155 + return NULL;
9156 + }
9157 +
9158 + ret = of_property_read_string(dev_node, "qcom,base-name", &base_name);
9159 + if (ret) {
9160 + dev_err(&pdev->dev, "Error: Unable to get base address name\n");
9161 + goto fab_dev_err;
9162 + }
9163 +
9164 + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, base_name);
9165 + if (!res) {
9166 + dev_err(&pdev->dev, "Error getting qos base addr %s\n",
9167 + base_name);
9168 + goto fab_dev_err;
9169 + }
9170 + fab_dev->pqos_base = res->start;
9171 + fab_dev->qos_range = resource_size(res);
9172 + fab_dev->bypass_qos_prg = of_property_read_bool(dev_node,
9173 + "qcom,bypass-qos-prg");
9174 +
9175 + ret = of_property_read_u32(dev_node, "qcom,base-offset",
9176 + &fab_dev->base_offset);
9177 + if (ret)
9178 + dev_dbg(&pdev->dev, "Bus base offset is missing\n");
9179 +
9180 + ret = of_property_read_u32(dev_node, "qcom,qos-off",
9181 + &fab_dev->qos_off);
9182 + if (ret)
9183 + dev_dbg(&pdev->dev, "Bus qos off is missing\n");
9184 +
9185 +
9186 + ret = of_property_read_u32(dev_node, "qcom,bus-type",
9187 + &fab_dev->bus_type);
9188 + if (ret) {
9189 + dev_warn(&pdev->dev, "Bus type is missing\n");
9190 + goto fab_dev_err;
9191 + }
9192 +
9193 + ret = of_property_read_u32(dev_node, "qcom,qos-freq",
9194 + &fab_dev->qos_freq);
9195 + if (ret) {
9196 + dev_dbg(&pdev->dev, "Bus qos freq is missing\n");
9197 + fab_dev->qos_freq = DEFAULT_QOS_FREQ;
9198 + }
9199 +
9200 + ret = of_property_read_u32(dev_node, "qcom,util-fact",
9201 + &fab_dev->util_fact);
9202 + if (ret) {
9203 + dev_info(&pdev->dev, "Util-fact is missing, default to %d\n",
9204 + DEFAULT_UTIL_FACT);
9205 + fab_dev->util_fact = DEFAULT_UTIL_FACT;
9206 + }
9207 +
9208 + ret = of_property_read_u32(dev_node, "qcom,vrail-comp",
9209 + &fab_dev->vrail_comp);
9210 + if (ret) {
9211 + dev_info(&pdev->dev, "Vrail-comp is missing, default to %d\n",
9212 + DEFAULT_VRAIL_COMP);
9213 + fab_dev->vrail_comp = DEFAULT_VRAIL_COMP;
9214 + }
9215 +
9216 + return fab_dev;
9217 +
9218 +fab_dev_err:
9219 + devm_kfree(&pdev->dev, fab_dev);
9220 + fab_dev = 0;
9221 + return NULL;
9222 +}
9223 +
9224 +static void get_qos_params(
9225 + struct device_node * const dev_node,
9226 + struct platform_device * const pdev,
9227 + struct msm_bus_node_info_type *node_info)
9228 +{
9229 + const char *qos_mode = NULL;
9230 + unsigned int ret;
9231 + unsigned int temp;
9232 +
9233 + ret = of_property_read_string(dev_node, "qcom,qos-mode", &qos_mode);
9234 +
9235 + if (ret)
9236 + node_info->qos_params.mode = -1;
9237 + else
9238 + node_info->qos_params.mode = get_qos_mode(pdev, dev_node,
9239 + qos_mode);
9240 +
9241 + of_property_read_u32(dev_node, "qcom,prio-lvl",
9242 + &node_info->qos_params.prio_lvl);
9243 +
9244 + of_property_read_u32(dev_node, "qcom,prio1",
9245 + &node_info->qos_params.prio1);
9246 +
9247 + of_property_read_u32(dev_node, "qcom,prio0",
9248 + &node_info->qos_params.prio0);
9249 +
9250 + of_property_read_u32(dev_node, "qcom,prio-rd",
9251 + &node_info->qos_params.prio_rd);
9252 +
9253 + of_property_read_u32(dev_node, "qcom,prio-wr",
9254 + &node_info->qos_params.prio_wr);
9255 +
9256 + of_property_read_u32(dev_node, "qcom,gp",
9257 + &node_info->qos_params.gp);
9258 +
9259 + of_property_read_u32(dev_node, "qcom,thmp",
9260 + &node_info->qos_params.thmp);
9261 +
9262 + of_property_read_u32(dev_node, "qcom,ws",
9263 + &node_info->qos_params.ws);
9264 +
9265 + ret = of_property_read_u32(dev_node, "qcom,bw_buffer", &temp);
9266 +
9267 + if (ret)
9268 + node_info->qos_params.bw_buffer = 0;
9269 + else
9270 + node_info->qos_params.bw_buffer = KBTOB(temp);
9271 +
9272 +}
9273 +
9274 +
9275 +static struct msm_bus_node_info_type *get_node_info_data(
9276 + struct device_node * const dev_node,
9277 + struct platform_device * const pdev)
9278 +{
9279 + struct msm_bus_node_info_type *node_info;
9280 + unsigned int ret;
9281 + int size;
9282 + int i;
9283 + struct device_node *con_node;
9284 + struct device_node *bus_dev;
9285 +
9286 + node_info = devm_kzalloc(&pdev->dev,
9287 + sizeof(struct msm_bus_node_info_type),
9288 + GFP_KERNEL);
9289 + if (!node_info) {
9290 + dev_err(&pdev->dev,
9291 + "Error: Unable to allocate memory for node_info\n");
9292 + return NULL;
9293 + }
9294 +
9295 + ret = of_property_read_u32(dev_node, "cell-id", &node_info->id);
9296 + if (ret) {
9297 + dev_warn(&pdev->dev, "Bus node is missing cell-id\n");
9298 + goto node_info_err;
9299 + }
9300 + ret = of_property_read_string(dev_node, "label", &node_info->name);
9301 + if (ret) {
9302 + dev_warn(&pdev->dev, "Bus node is missing name\n");
9303 + goto node_info_err;
9304 + }
9305 + node_info->qport = get_arr(pdev, dev_node, "qcom,qport",
9306 + &node_info->num_qports);
9307 +
9308 + if (of_get_property(dev_node, "qcom,connections", &size)) {
9309 + node_info->num_connections = size / sizeof(int);
9310 + node_info->connections = devm_kzalloc(&pdev->dev, size,
9311 + GFP_KERNEL);
9312 + } else {
9313 + node_info->num_connections = 0;
9314 + node_info->connections = 0;
9315 + }
9316 +
9317 + for (i = 0; i < node_info->num_connections; i++) {
9318 + con_node = of_parse_phandle(dev_node, "qcom,connections", i);
9319 + if (IS_ERR_OR_NULL(con_node))
9320 + goto node_info_err;
9321 +
9322 + if (of_property_read_u32(con_node, "cell-id",
9323 + &node_info->connections[i]))
9324 + goto node_info_err;
9325 + of_node_put(con_node);
9326 + }
9327 +
9328 + if (of_get_property(dev_node, "qcom,blacklist", &size)) {
9329 + node_info->num_blist = size/sizeof(u32);
9330 + node_info->black_listed_connections = devm_kzalloc(&pdev->dev,
9331 + size, GFP_KERNEL);
9332 + } else {
9333 + node_info->num_blist = 0;
9334 + node_info->black_listed_connections = 0;
9335 + }
9336 +
9337 + for (i = 0; i < node_info->num_blist; i++) {
9338 + con_node = of_parse_phandle(dev_node, "qcom,blacklist", i);
9339 + if (IS_ERR_OR_NULL(con_node))
9340 + goto node_info_err;
9341 +
9342 + if (of_property_read_u32(con_node, "cell-id",
9343 + &node_info->black_listed_connections[i]))
9344 + goto node_info_err;
9345 + of_node_put(con_node);
9346 + }
9347 +
9348 + bus_dev = of_parse_phandle(dev_node, "qcom,bus-dev", 0);
9349 + if (!IS_ERR_OR_NULL(bus_dev)) {
9350 + if (of_property_read_u32(bus_dev, "cell-id",
9351 + &node_info->bus_device_id)) {
9352 + dev_err(&pdev->dev, "Can't find bus device. Node %d",
9353 + node_info->id);
9354 + goto node_info_err;
9355 + }
9356 +
9357 + of_node_put(bus_dev);
9358 + } else
9359 + dev_dbg(&pdev->dev, "Can't find bdev phandle for %d",
9360 + node_info->id);
9361 +
9362 + node_info->is_fab_dev = of_property_read_bool(dev_node, "qcom,fab-dev");
9363 + node_info->virt_dev = of_property_read_bool(dev_node, "qcom,virt-dev");
9364 +
9365 + ret = of_property_read_u32(dev_node, "qcom,buswidth",
9366 + &node_info->buswidth);
9367 + if (ret) {
9368 + dev_dbg(&pdev->dev, "Using default 8 bytes %d", node_info->id);
9369 + node_info->buswidth = 8;
9370 + }
9371 +
9372 + ret = of_property_read_u32(dev_node, "qcom,mas-rpm-id",
9373 + &node_info->mas_rpm_id);
9374 + if (ret) {
9375 + dev_dbg(&pdev->dev, "mas rpm id is missing\n");
9376 + node_info->mas_rpm_id = -1;
9377 + }
9378 +
9379 + ret = of_property_read_u32(dev_node, "qcom,slv-rpm-id",
9380 + &node_info->slv_rpm_id);
9381 + if (ret) {
9382 + dev_dbg(&pdev->dev, "slv rpm id is missing\n");
9383 + node_info->slv_rpm_id = -1;
9384 + }
9385 + ret = of_property_read_u32(dev_node, "qcom,util-fact",
9386 + &node_info->util_fact);
9387 + if (ret)
9388 + node_info->util_fact = 0;
9389 + ret = of_property_read_u32(dev_node, "qcom,vrail-comp",
9390 + &node_info->vrail_comp);
9391 + if (ret)
9392 + node_info->vrail_comp = 0;
9393 + get_qos_params(dev_node, pdev, node_info);
9394 +
9395 + return node_info;
9396 +
9397 +node_info_err:
9398 + devm_kfree(&pdev->dev, node_info);
9399 + node_info = 0;
9400 + return NULL;
9401 +}
9402 +
9403 +static unsigned int get_bus_node_device_data(
9404 + struct device_node * const dev_node,
9405 + struct platform_device * const pdev,
9406 + struct msm_bus_node_device_type * const node_device)
9407 +{
9408 + node_device->node_info = get_node_info_data(dev_node, pdev);
9409 + if (IS_ERR_OR_NULL(node_device->node_info)) {
9410 + dev_err(&pdev->dev, "Error: Node info missing\n");
9411 + return -ENODATA;
9412 + }
9413 + node_device->ap_owned = of_property_read_bool(dev_node,
9414 + "qcom,ap-owned");
9415 +
9416 + if (node_device->node_info->is_fab_dev) {
9417 + dev_dbg(&pdev->dev, "Dev %d\n", node_device->node_info->id);
9418 +
9419 + if (!node_device->node_info->virt_dev) {
9420 + node_device->fabdev =
9421 + get_fab_device_info(dev_node, pdev);
9422 + if (IS_ERR_OR_NULL(node_device->fabdev)) {
9423 + dev_err(&pdev->dev,
9424 + "Error: Fabric device info missing\n");
9425 + devm_kfree(&pdev->dev, node_device->node_info);
9426 + return -ENODATA;
9427 + }
9428 + }
9429 + node_device->clk[DUAL_CTX].clk = of_clk_get_by_name(dev_node,
9430 + "bus_clk");
9431 +
9432 + if (IS_ERR_OR_NULL(node_device->clk[DUAL_CTX].clk))
9433 + dev_dbg(&pdev->dev,
9434 + "%s:Failed to get bus clk for bus%d ctx%d",
9435 + __func__, node_device->node_info->id,
9436 + DUAL_CTX);
9437 +
9438 + node_device->clk[ACTIVE_CTX].clk = of_clk_get_by_name(dev_node,
9439 + "bus_a_clk");
9440 + if (IS_ERR_OR_NULL(node_device->clk[ACTIVE_CTX].clk))
9441 + dev_err(&pdev->dev,
9442 + "Failed to get bus clk for bus%d ctx%d",
9443 + node_device->node_info->id, ACTIVE_CTX);
9444 + if (msmbus_coresight_init_adhoc(pdev, dev_node))
9445 + dev_warn(&pdev->dev,
9446 + "Coresight support absent for bus: %d\n",
9447 + node_device->node_info->id);
9448 + } else {
9449 + node_device->qos_clk.clk = of_clk_get_by_name(dev_node,
9450 + "bus_qos_clk");
9451 +
9452 + if (IS_ERR_OR_NULL(node_device->qos_clk.clk))
9453 + dev_dbg(&pdev->dev,
9454 + "%s:Failed to get bus qos clk for mas%d",
9455 + __func__, node_device->node_info->id);
9456 +
9457 + node_device->clk[DUAL_CTX].clk = of_clk_get_by_name(dev_node,
9458 + "node_clk");
9459 +
9460 + if (IS_ERR_OR_NULL(node_device->clk[DUAL_CTX].clk))
9461 + dev_dbg(&pdev->dev,
9462 + "%s:Failed to get bus clk for bus%d ctx%d",
9463 + __func__, node_device->node_info->id,
9464 + DUAL_CTX);
9465 +
9466 + }
9467 + return 0;
9468 +}
9469 +
9470 +struct msm_bus_device_node_registration
9471 + *msm_bus_of_to_pdata(struct platform_device *pdev)
9472 +{
9473 + struct device_node *of_node, *child_node;
9474 + struct msm_bus_device_node_registration *pdata;
9475 + unsigned int i = 0, j;
9476 + unsigned int ret;
9477 +
9478 + if (!pdev) {
9479 + pr_err("Error: Null platform device\n");
9480 + return NULL;
9481 + }
9482 +
9483 + of_node = pdev->dev.of_node;
9484 +
9485 + pdata = devm_kzalloc(&pdev->dev,
9486 + sizeof(struct msm_bus_device_node_registration),
9487 + GFP_KERNEL);
9488 + if (!pdata) {
9489 + dev_err(&pdev->dev,
9490 + "Error: Memory allocation for pdata failed\n");
9491 + return NULL;
9492 + }
9493 +
9494 + pdata->num_devices = of_get_child_count(of_node);
9495 +
9496 + pdata->info = devm_kzalloc(&pdev->dev,
9497 + sizeof(struct msm_bus_node_device_type) *
9498 + pdata->num_devices, GFP_KERNEL);
9499 +
9500 + if (!pdata->info) {
9501 + dev_err(&pdev->dev,
9502 + "Error: Memory allocation for pdata->info failed\n");
9503 + goto node_reg_err;
9504 + }
9505 +
9506 + ret = 0;
9507 + for_each_child_of_node(of_node, child_node) {
9508 + ret = get_bus_node_device_data(child_node, pdev,
9509 + &pdata->info[i]);
9510 + if (ret) {
9511 + dev_err(&pdev->dev, "Error: unable to initialize bus nodes\n");
9512 + goto node_reg_err_1;
9513 + }
9514 + i++;
9515 + }
9516 +
9517 + dev_dbg(&pdev->dev, "bus topology:\n");
9518 + for (i = 0; i < pdata->num_devices; i++) {
9519 + dev_dbg(&pdev->dev, "id %d\nnum_qports %d\nnum_connections %d",
9520 + pdata->info[i].node_info->id,
9521 + pdata->info[i].node_info->num_qports,
9522 + pdata->info[i].node_info->num_connections);
9523 + dev_dbg(&pdev->dev, "\nbus_device_id %d\n buswidth %d\n",
9524 + pdata->info[i].node_info->bus_device_id,
9525 + pdata->info[i].node_info->buswidth);
9526 + for (j = 0; j < pdata->info[i].node_info->num_connections;
9527 + j++) {
9528 + dev_dbg(&pdev->dev, "connection[%d]: %d\n", j,
9529 + pdata->info[i].node_info->connections[j]);
9530 + }
9531 + for (j = 0; j < pdata->info[i].node_info->num_blist;
9532 + j++) {
9533 + dev_dbg(&pdev->dev, "black_listed_node[%d]: %d\n", j,
9534 + pdata->info[i].node_info->
9535 + black_listed_connections[j]);
9536 + }
9537 + if (pdata->info[i].fabdev)
9538 + dev_dbg(&pdev->dev, "base_addr %zu\nbus_type %d\n",
9539 + (size_t)pdata->info[i].
9540 + fabdev->pqos_base,
9541 + pdata->info[i].fabdev->bus_type);
9542 + }
9543 + return pdata;
9544 +
9545 +node_reg_err_1:
9546 + devm_kfree(&pdev->dev, pdata->info);
9547 +node_reg_err:
9548 + devm_kfree(&pdev->dev, pdata);
9549 + pdata = NULL;
9550 + return NULL;
9551 +}
9552 +
9553 +static int msm_bus_of_get_ids(struct platform_device *pdev,
9554 + struct device_node *dev_node, int **dev_ids,
9555 + int *num_ids, char *prop_name)
9556 +{
9557 + int ret = 0;
9558 + int size, i;
9559 + struct device_node *rule_node;
9560 + int *ids = NULL;
9561 +
9562 + if (of_get_property(dev_node, prop_name, &size)) {
9563 + *num_ids = size / sizeof(int);
9564 + ids = devm_kzalloc(&pdev->dev, size, GFP_KERNEL);
9565 + } else {
9566 + dev_err(&pdev->dev, "No rule nodes, skipping node");
9567 + ret = -ENXIO;
9568 + goto exit_get_ids;
9569 + }
9570 +
9571 + *dev_ids = ids;
9572 + for (i = 0; i < *num_ids; i++) {
9573 + rule_node = of_parse_phandle(dev_node, prop_name, i);
9574 + if (IS_ERR_OR_NULL(rule_node)) {
9575 + dev_err(&pdev->dev, "Can't get rule node id");
9576 + ret = -ENXIO;
9577 + goto err_get_ids;
9578 + }
9579 +
9580 + if (of_property_read_u32(rule_node, "cell-id",
9581 + &ids[i])) {
9582 + dev_err(&pdev->dev, "Can't get rule node id");
9583 + ret = -ENXIO;
9584 + goto err_get_ids;
9585 + }
9586 + of_node_put(rule_node);
9587 + }
9588 +exit_get_ids:
9589 + return ret;
9590 +err_get_ids:
9591 + devm_kfree(&pdev->dev, ids);
9592 + of_node_put(rule_node);
9593 + ids = NULL;
9594 + return ret;
9595 +}
9596 +
9597 +int msm_bus_of_get_static_rules(struct platform_device *pdev,
9598 + struct bus_rule_type **static_rules)
9599 +{
9600 + int ret = 0;
9601 + struct device_node *of_node, *child_node;
9602 + int num_rules = 0;
9603 + int rule_idx = 0;
9604 + int bw_fld = 0;
9605 + int i;
9606 + struct bus_rule_type *static_rule = NULL;
9607 +
9608 + of_node = pdev->dev.of_node;
9609 + num_rules = of_get_child_count(of_node);
9610 + static_rule = devm_kzalloc(&pdev->dev,
9611 + sizeof(struct bus_rule_type) * num_rules,
9612 + GFP_KERNEL);
9613 +
9614 + if (IS_ERR_OR_NULL(static_rule)) {
9615 + ret = -ENOMEM;
9616 + goto exit_static_rules;
9617 + }
9618 +
9619 + *static_rules = static_rule;
9620 + for_each_child_of_node(of_node, child_node) {
9621 + ret = msm_bus_of_get_ids(pdev, child_node,
9622 + &static_rule[rule_idx].src_id,
9623 + &static_rule[rule_idx].num_src,
9624 + "qcom,src-nodes");
9625 +
9626 + ret = msm_bus_of_get_ids(pdev, child_node,
9627 + &static_rule[rule_idx].dst_node,
9628 + &static_rule[rule_idx].num_dst,
9629 + "qcom,dest-node");
9630 +
9631 + ret = of_property_read_u32(child_node, "qcom,src-field",
9632 + &static_rule[rule_idx].src_field);
9633 + if (ret) {
9634 + dev_err(&pdev->dev, "src-field missing");
9635 + ret = -ENXIO;
9636 + goto err_static_rules;
9637 + }
9638 +
9639 + ret = of_property_read_u32(child_node, "qcom,src-op",
9640 + &static_rule[rule_idx].op);
9641 + if (ret) {
9642 + dev_err(&pdev->dev, "src-op missing");
9643 + ret = -ENXIO;
9644 + goto err_static_rules;
9645 + }
9646 +
9647 + ret = of_property_read_u32(child_node, "qcom,mode",
9648 + &static_rule[rule_idx].mode);
9649 + if (ret) {
9650 + dev_err(&pdev->dev, "mode missing");
9651 + ret = -ENXIO;
9652 + goto err_static_rules;
9653 + }
9654 +
9655 + ret = of_property_read_u32(child_node, "qcom,thresh", &bw_fld);
9656 + if (ret) {
9657 + dev_err(&pdev->dev, "thresh missing");
9658 + ret = -ENXIO;
9659 + goto err_static_rules;
9660 + } else
9661 + static_rule[rule_idx].thresh = KBTOB(bw_fld);
9662 +
9663 + ret = of_property_read_u32(child_node, "qcom,dest-bw",
9664 + &bw_fld);
9665 + if (ret)
9666 + static_rule[rule_idx].dst_bw = 0;
9667 + else
9668 + static_rule[rule_idx].dst_bw = KBTOB(bw_fld);
9669 +
9670 + rule_idx++;
9671 + }
9672 + ret = rule_idx;
9673 +exit_static_rules:
9674 + return ret;
9675 +err_static_rules:
9676 + for (i = 0; i < num_rules; i++) {
9677 + if (!IS_ERR_OR_NULL(static_rule)) {
9678 + if (!IS_ERR_OR_NULL(static_rule[i].src_id))
9679 + devm_kfree(&pdev->dev,
9680 + static_rule[i].src_id);
9681 + if (!IS_ERR_OR_NULL(static_rule[i].dst_node))
9682 + devm_kfree(&pdev->dev,
9683 + static_rule[i].dst_node);
9684 + devm_kfree(&pdev->dev, static_rule);
9685 + }
9686 + }
9687 + devm_kfree(&pdev->dev, *static_rules);
9688 + static_rules = NULL;
9689 + return ret;
9690 +}
9691 --- /dev/null
9692 +++ b/drivers/bus/msm_bus/msm_bus_rules.c
9693 @@ -0,0 +1,624 @@
9694 +/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
9695 + *
9696 + * This program is free software; you can redistribute it and/or modify
9697 + * it under the terms of the GNU General Public License version 2 and
9698 + * only version 2 as published by the Free Software Foundation.
9699 + *
9700 + * This program is distributed in the hope that it will be useful,
9701 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
9702 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9703 + * GNU General Public License for more details.
9704 + */
9705 +
9706 +#include <linux/list_sort.h>
9707 +#include <linux/slab.h>
9708 +#include <linux/types.h>
9709 +#include "msm-bus-board.h"
9710 +#include "msm_bus_rules.h"
9711 +#include <trace/events/trace_msm_bus.h>
9712 +
9713 +struct node_vote_info {
9714 + int id;
9715 + u64 ib;
9716 + u64 ab;
9717 + u64 clk;
9718 +};
9719 +
9720 +struct rules_def {
9721 + int rule_id;
9722 + int num_src;
9723 + int state;
9724 + struct node_vote_info *src_info;
9725 + struct bus_rule_type rule_ops;
9726 + bool state_change;
9727 + struct list_head link;
9728 +};
9729 +
9730 +struct rule_node_info {
9731 + int id;
9732 + void *data;
9733 + struct raw_notifier_head rule_notify_list;
9734 + int cur_rule;
9735 + int num_rules;
9736 + struct list_head node_rules;
9737 + struct list_head link;
9738 + struct rule_apply_rcm_info apply;
9739 +};
9740 +
9741 +DEFINE_MUTEX(msm_bus_rules_lock);
9742 +static LIST_HEAD(node_list);
9743 +static struct rule_node_info *get_node(u32 id, void *data);
9744 +
9745 +#define LE(op1, op2) (op1 <= op2)
9746 +#define LT(op1, op2) (op1 < op2)
9747 +#define GE(op1, op2) (op1 >= op2)
9748 +#define GT(op1, op2) (op1 > op2)
9749 +#define NB_ID (0x201)
9750 +
9751 +static struct rule_node_info *get_node(u32 id, void *data)
9752 +{
9753 + struct rule_node_info *node_it = NULL;
9754 + struct rule_node_info *node_match = NULL;
9755 +
9756 + list_for_each_entry(node_it, &node_list, link) {
9757 + if (node_it->id == id) {
9758 + if ((id == NB_ID)) {
9759 + if ((node_it->data == data)) {
9760 + node_match = node_it;
9761 + break;
9762 + }
9763 + } else {
9764 + node_match = node_it;
9765 + break;
9766 + }
9767 + }
9768 + }
9769 + return node_match;
9770 +}
9771 +
9772 +static struct rule_node_info *gen_node(u32 id, void *data)
9773 +{
9774 + struct rule_node_info *node_it = NULL;
9775 + struct rule_node_info *node_match = NULL;
9776 +
9777 + list_for_each_entry(node_it, &node_list, link) {
9778 + if (node_it->id == id) {
9779 + node_match = node_it;
9780 + break;
9781 + }
9782 + }
9783 +
9784 + if (!node_match) {
9785 + node_match = kzalloc(sizeof(struct rule_node_info), GFP_KERNEL);
9786 + if (!node_match) {
9787 + pr_err("%s: Cannot allocate memory", __func__);
9788 + goto exit_node_match;
9789 + }
9790 +
9791 + node_match->id = id;
9792 + node_match->cur_rule = -1;
9793 + node_match->num_rules = 0;
9794 + node_match->data = data;
9795 + list_add_tail(&node_match->link, &node_list);
9796 + INIT_LIST_HEAD(&node_match->node_rules);
9797 + RAW_INIT_NOTIFIER_HEAD(&node_match->rule_notify_list);
9798 + pr_debug("Added new node %d to list\n", id);
9799 + }
9800 +exit_node_match:
9801 + return node_match;
9802 +}
9803 +
9804 +static bool do_compare_op(u64 op1, u64 op2, int op)
9805 +{
9806 + bool ret = false;
9807 +
9808 + switch (op) {
9809 + case OP_LE:
9810 + ret = LE(op1, op2);
9811 + break;
9812 + case OP_LT:
9813 + ret = LT(op1, op2);
9814 + break;
9815 + case OP_GT:
9816 + ret = GT(op1, op2);
9817 + break;
9818 + case OP_GE:
9819 + ret = GE(op1, op2);
9820 + break;
9821 + case OP_NOOP:
9822 + ret = true;
9823 + break;
9824 + default:
9825 + pr_info("Invalid OP %d", op);
9826 + break;
9827 + }
9828 + return ret;
9829 +}
9830 +
9831 +static void update_src_id_vote(struct rule_update_path_info *inp_node,
9832 + struct rule_node_info *rule_node)
9833 +{
9834 + struct rules_def *rule;
9835 + int i;
9836 +
9837 + list_for_each_entry(rule, &rule_node->node_rules, link) {
9838 + for (i = 0; i < rule->num_src; i++) {
9839 + if (rule->src_info[i].id == inp_node->id) {
9840 + rule->src_info[i].ib = inp_node->ib;
9841 + rule->src_info[i].ab = inp_node->ab;
9842 + rule->src_info[i].clk = inp_node->clk;
9843 + }
9844 + }
9845 + }
9846 +}
9847 +
9848 +static u64 get_field(struct rules_def *rule, int src_id)
9849 +{
9850 + u64 field = 0;
9851 + int i;
9852 +
9853 + for (i = 0; i < rule->num_src; i++) {
9854 + switch (rule->rule_ops.src_field) {
9855 + case FLD_IB:
9856 + field += rule->src_info[i].ib;
9857 + break;
9858 + case FLD_AB:
9859 + field += rule->src_info[i].ab;
9860 + break;
9861 + case FLD_CLK:
9862 + field += rule->src_info[i].clk;
9863 + break;
9864 + }
9865 + }
9866 +
9867 + return field;
9868 +}
9869 +
9870 +static bool check_rule(struct rules_def *rule,
9871 + struct rule_update_path_info *inp)
9872 +{
9873 + bool ret = false;
9874 +
9875 + if (!rule)
9876 + return ret;
9877 +
9878 + switch (rule->rule_ops.op) {
9879 + case OP_LE:
9880 + case OP_LT:
9881 + case OP_GT:
9882 + case OP_GE:
9883 + {
9884 + u64 src_field = get_field(rule, inp->id);
9885 + if (!src_field)
9886 + ret = false;
9887 + else
9888 + ret = do_compare_op(src_field, rule->rule_ops.thresh,
9889 + rule->rule_ops.op);
9890 + break;
9891 + }
9892 + default:
9893 + pr_err("Unsupported op %d", rule->rule_ops.op);
9894 + break;
9895 + }
9896 + return ret;
9897 +}
9898 +
9899 +static void match_rule(struct rule_update_path_info *inp_node,
9900 + struct rule_node_info *node)
9901 +{
9902 + struct rules_def *rule;
9903 + int i;
9904 +
9905 + list_for_each_entry(rule, &node->node_rules, link) {
9906 + for (i = 0; i < rule->num_src; i++) {
9907 + if (rule->src_info[i].id == inp_node->id) {
9908 + if (check_rule(rule, inp_node)) {
9909 + trace_bus_rules_matches(node->cur_rule,
9910 + inp_node->id, inp_node->ab,
9911 + inp_node->ib, inp_node->clk);
9912 + if (rule->state ==
9913 + RULE_STATE_NOT_APPLIED)
9914 + rule->state_change = true;
9915 + rule->state = RULE_STATE_APPLIED;
9916 + } else {
9917 + if (rule->state ==
9918 + RULE_STATE_APPLIED)
9919 + rule->state_change = true;
9920 + rule->state = RULE_STATE_NOT_APPLIED;
9921 + }
9922 + }
9923 + }
9924 + }
9925 +}
9926 +
9927 +static void apply_rule(struct rule_node_info *node,
9928 + struct list_head *output_list)
9929 +{
9930 + struct rules_def *rule;
9931 +
9932 + node->cur_rule = -1;
9933 + list_for_each_entry(rule, &node->node_rules, link) {
9934 + if ((rule->state == RULE_STATE_APPLIED) &&
9935 + (node->cur_rule == -1))
9936 + node->cur_rule = rule->rule_id;
9937 +
9938 + if (node->id == NB_ID) {
9939 + if (rule->state_change) {
9940 + rule->state_change = false;
9941 + raw_notifier_call_chain(&node->rule_notify_list,
9942 + rule->state, (void *)&rule->rule_ops);
9943 + }
9944 + } else {
9945 + if ((rule->state == RULE_STATE_APPLIED) &&
9946 + (node->cur_rule == rule->rule_id)) {
9947 + node->apply.id = rule->rule_ops.dst_node[0];
9948 + node->apply.throttle = rule->rule_ops.mode;
9949 + node->apply.lim_bw = rule->rule_ops.dst_bw;
9950 + list_add_tail(&node->apply.link, output_list);
9951 + }
9952 + rule->state_change = false;
9953 + }
9954 + }
9955 +
9956 +}
9957 +
9958 +int msm_rules_update_path(struct list_head *input_list,
9959 + struct list_head *output_list)
9960 +{
9961 + int ret = 0;
9962 + struct rule_update_path_info *inp_node;
9963 + struct rule_node_info *node_it = NULL;
9964 +
9965 + mutex_lock(&msm_bus_rules_lock);
9966 + list_for_each_entry(inp_node, input_list, link) {
9967 + list_for_each_entry(node_it, &node_list, link) {
9968 + update_src_id_vote(inp_node, node_it);
9969 + match_rule(inp_node, node_it);
9970 + }
9971 + }
9972 +
9973 + list_for_each_entry(node_it, &node_list, link)
9974 + apply_rule(node_it, output_list);
9975 +
9976 + mutex_unlock(&msm_bus_rules_lock);
9977 + return ret;
9978 +}
9979 +
9980 +static bool ops_equal(int op1, int op2)
9981 +{
9982 + bool ret = false;
9983 +
9984 + switch (op1) {
9985 + case OP_GT:
9986 + case OP_GE:
9987 + case OP_LT:
9988 + case OP_LE:
9989 + if (abs(op1 - op2) <= 1)
9990 + ret = true;
9991 + break;
9992 + default:
9993 + ret = (op1 == op2);
9994 + }
9995 +
9996 + return ret;
9997 +}
9998 +
9999 +static int node_rules_compare(void *priv, struct list_head *a,
10000 + struct list_head *b)
10001 +{
10002 + struct rules_def *ra = container_of(a, struct rules_def, link);
10003 + struct rules_def *rb = container_of(b, struct rules_def, link);
10004 + int ret = -1;
10005 + int64_t th_diff = 0;
10006 +
10007 +
10008 + if (ra->rule_ops.mode == rb->rule_ops.mode) {
10009 + if (ops_equal(ra->rule_ops.op, rb->rule_ops.op)) {
10010 + if ((ra->rule_ops.op == OP_LT) ||
10011 + (ra->rule_ops.op == OP_LE)) {
10012 + th_diff = ra->rule_ops.thresh -
10013 + rb->rule_ops.thresh;
10014 + if (th_diff > 0)
10015 + ret = 1;
10016 + else
10017 + ret = -1;
10018 + } else if ((ra->rule_ops.op == OP_GT) ||
10019 + (ra->rule_ops.op == OP_GE)) {
10020 + th_diff = rb->rule_ops.thresh -
10021 + ra->rule_ops.thresh;
10022 + if (th_diff > 0)
10023 + ret = 1;
10024 + else
10025 + ret = -1;
10026 + }
10027 + } else
10028 + ret = ra->rule_ops.op - rb->rule_ops.op;
10029 + } else if ((ra->rule_ops.mode == THROTTLE_OFF) &&
10030 + (rb->rule_ops.mode == THROTTLE_ON)) {
10031 + ret = 1;
10032 + } else if ((ra->rule_ops.mode == THROTTLE_ON) &&
10033 + (rb->rule_ops.mode == THROTTLE_OFF)) {
10034 + ret = -1;
10035 + }
10036 +
10037 + return ret;
10038 +}
10039 +
10040 +static void print_rules(struct rule_node_info *node_it)
10041 +{
10042 + struct rules_def *node_rule = NULL;
10043 + int i;
10044 +
10045 + if (!node_it) {
10046 + pr_err("%s: no node for found", __func__);
10047 + return;
10048 + }
10049 +
10050 + pr_info("\n Now printing rules for Node %d cur rule %d\n",
10051 + node_it->id, node_it->cur_rule);
10052 + list_for_each_entry(node_rule, &node_it->node_rules, link) {
10053 + pr_info("\n num Rules %d rule Id %d\n",
10054 + node_it->num_rules, node_rule->rule_id);
10055 + pr_info("Rule: src_field %d\n", node_rule->rule_ops.src_field);
10056 + for (i = 0; i < node_rule->rule_ops.num_src; i++)
10057 + pr_info("Rule: src %d\n",
10058 + node_rule->rule_ops.src_id[i]);
10059 + for (i = 0; i < node_rule->rule_ops.num_dst; i++)
10060 + pr_info("Rule: dst %d dst_bw %llu\n",
10061 + node_rule->rule_ops.dst_node[i],
10062 + node_rule->rule_ops.dst_bw);
10063 + pr_info("Rule: thresh %llu op %d mode %d State %d\n",
10064 + node_rule->rule_ops.thresh,
10065 + node_rule->rule_ops.op,
10066 + node_rule->rule_ops.mode,
10067 + node_rule->state);
10068 + }
10069 +}
10070 +
10071 +void print_all_rules(void)
10072 +{
10073 + struct rule_node_info *node_it = NULL;
10074 +
10075 + list_for_each_entry(node_it, &node_list, link)
10076 + print_rules(node_it);
10077 +}
10078 +
10079 +void print_rules_buf(char *buf, int max_buf)
10080 +{
10081 + struct rule_node_info *node_it = NULL;
10082 + struct rules_def *node_rule = NULL;
10083 + int i;
10084 + int cnt = 0;
10085 +
10086 + list_for_each_entry(node_it, &node_list, link) {
10087 + cnt += scnprintf(buf + cnt, max_buf - cnt,
10088 + "\n Now printing rules for Node %d cur_rule %d\n",
10089 + node_it->id, node_it->cur_rule);
10090 + list_for_each_entry(node_rule, &node_it->node_rules, link) {
10091 + cnt += scnprintf(buf + cnt, max_buf - cnt,
10092 + "\nNum Rules:%d ruleId %d STATE:%d change:%d\n",
10093 + node_it->num_rules, node_rule->rule_id,
10094 + node_rule->state, node_rule->state_change);
10095 + cnt += scnprintf(buf + cnt, max_buf - cnt,
10096 + "Src_field %d\n",
10097 + node_rule->rule_ops.src_field);
10098 + for (i = 0; i < node_rule->rule_ops.num_src; i++)
10099 + cnt += scnprintf(buf + cnt, max_buf - cnt,
10100 + "Src %d Cur Ib %llu Ab %llu\n",
10101 + node_rule->rule_ops.src_id[i],
10102 + node_rule->src_info[i].ib,
10103 + node_rule->src_info[i].ab);
10104 + for (i = 0; i < node_rule->rule_ops.num_dst; i++)
10105 + cnt += scnprintf(buf + cnt, max_buf - cnt,
10106 + "Dst %d dst_bw %llu\n",
10107 + node_rule->rule_ops.dst_node[0],
10108 + node_rule->rule_ops.dst_bw);
10109 + cnt += scnprintf(buf + cnt, max_buf - cnt,
10110 + "Thresh %llu op %d mode %d\n",
10111 + node_rule->rule_ops.thresh,
10112 + node_rule->rule_ops.op,
10113 + node_rule->rule_ops.mode);
10114 + }
10115 + }
10116 +}
10117 +
10118 +static int copy_rule(struct bus_rule_type *src, struct rules_def *node_rule,
10119 + struct notifier_block *nb)
10120 +{
10121 + int i;
10122 + int ret = 0;
10123 +
10124 + memcpy(&node_rule->rule_ops, src,
10125 + sizeof(struct bus_rule_type));
10126 + node_rule->rule_ops.src_id = kzalloc(
10127 + (sizeof(int) * node_rule->rule_ops.num_src),
10128 + GFP_KERNEL);
10129 + if (!node_rule->rule_ops.src_id) {
10130 + pr_err("%s:Failed to allocate for src_id",
10131 + __func__);
10132 + return -ENOMEM;
10133 + }
10134 + memcpy(node_rule->rule_ops.src_id, src->src_id,
10135 + sizeof(int) * src->num_src);
10136 +
10137 +
10138 + if (!nb) {
10139 + node_rule->rule_ops.dst_node = kzalloc(
10140 + (sizeof(int) * node_rule->rule_ops.num_dst),
10141 + GFP_KERNEL);
10142 + if (!node_rule->rule_ops.dst_node) {
10143 + pr_err("%s:Failed to allocate for src_id",
10144 + __func__);
10145 + return -ENOMEM;
10146 + }
10147 + memcpy(node_rule->rule_ops.dst_node, src->dst_node,
10148 + sizeof(int) * src->num_dst);
10149 + }
10150 +
10151 + node_rule->num_src = src->num_src;
10152 + node_rule->src_info = kzalloc(
10153 + (sizeof(struct node_vote_info) * node_rule->rule_ops.num_src),
10154 + GFP_KERNEL);
10155 + if (!node_rule->src_info) {
10156 + pr_err("%s:Failed to allocate for src_id",
10157 + __func__);
10158 + return -ENOMEM;
10159 + }
10160 + for (i = 0; i < src->num_src; i++)
10161 + node_rule->src_info[i].id = src->src_id[i];
10162 +
10163 + return ret;
10164 +}
10165 +
10166 +void msm_rule_register(int num_rules, struct bus_rule_type *rule,
10167 + struct notifier_block *nb)
10168 +{
10169 + struct rule_node_info *node = NULL;
10170 + int i, j;
10171 + struct rules_def *node_rule = NULL;
10172 + int num_dst = 0;
10173 +
10174 + if (!rule)
10175 + return;
10176 +
10177 + mutex_lock(&msm_bus_rules_lock);
10178 + for (i = 0; i < num_rules; i++) {
10179 + if (nb)
10180 + num_dst = 1;
10181 + else
10182 + num_dst = rule[i].num_dst;
10183 +
10184 + for (j = 0; j < num_dst; j++) {
10185 + int id = 0;
10186 +
10187 + if (nb)
10188 + id = NB_ID;
10189 + else
10190 + id = rule[i].dst_node[j];
10191 +
10192 + node = gen_node(id, nb);
10193 + if (!node) {
10194 + pr_info("Error getting rule");
10195 + goto exit_rule_register;
10196 + }
10197 + node_rule = kzalloc(sizeof(struct rules_def),
10198 + GFP_KERNEL);
10199 + if (!node_rule) {
10200 + pr_err("%s: Failed to allocate for rule",
10201 + __func__);
10202 + goto exit_rule_register;
10203 + }
10204 +
10205 + if (copy_rule(&rule[i], node_rule, nb)) {
10206 + pr_err("Error copying rule");
10207 + goto exit_rule_register;
10208 + }
10209 +
10210 + node_rule->rule_id = node->num_rules++;
10211 + if (nb)
10212 + node->data = nb;
10213 +
10214 + list_add_tail(&node_rule->link, &node->node_rules);
10215 + }
10216 + }
10217 + list_sort(NULL, &node->node_rules, node_rules_compare);
10218 +
10219 + if (nb)
10220 + raw_notifier_chain_register(&node->rule_notify_list, nb);
10221 +exit_rule_register:
10222 + mutex_unlock(&msm_bus_rules_lock);
10223 + return;
10224 +}
10225 +
10226 +static int comp_rules(struct bus_rule_type *rulea, struct bus_rule_type *ruleb)
10227 +{
10228 + int ret = 1;
10229 +
10230 + if (rulea->num_src == ruleb->num_src)
10231 + ret = memcmp(rulea->src_id, ruleb->src_id,
10232 + (sizeof(int) * rulea->num_src));
10233 + if (!ret && (rulea->num_dst == ruleb->num_dst))
10234 + ret = memcmp(rulea->dst_node, ruleb->dst_node,
10235 + (sizeof(int) * rulea->num_dst));
10236 + if (!ret && (rulea->dst_bw == ruleb->dst_bw) &&
10237 + (rulea->op == ruleb->op) && (rulea->thresh == ruleb->thresh))
10238 + ret = 0;
10239 +
10240 + return ret;
10241 +}
10242 +
10243 +void msm_rule_unregister(int num_rules, struct bus_rule_type *rule,
10244 + struct notifier_block *nb)
10245 +{
10246 + int i;
10247 + struct rule_node_info *node = NULL;
10248 + struct rule_node_info *node_tmp = NULL;
10249 + struct rules_def *node_rule;
10250 + struct rules_def *node_rule_tmp;
10251 + bool match_found = false;
10252 +
10253 + if (!rule)
10254 + return;
10255 +
10256 + mutex_lock(&msm_bus_rules_lock);
10257 + if (nb) {
10258 + node = get_node(NB_ID, nb);
10259 + if (!node) {
10260 + pr_err("%s: Can't find node", __func__);
10261 + goto exit_unregister_rule;
10262 + }
10263 +
10264 + list_for_each_entry_safe(node_rule, node_rule_tmp,
10265 + &node->node_rules, link) {
10266 + list_del(&node_rule->link);
10267 + kfree(node_rule);
10268 + node->num_rules--;
10269 + }
10270 + raw_notifier_chain_unregister(&node->rule_notify_list, nb);
10271 + } else {
10272 + for (i = 0; i < num_rules; i++) {
10273 + match_found = false;
10274 +
10275 + list_for_each_entry(node, &node_list, link) {
10276 + list_for_each_entry_safe(node_rule,
10277 + node_rule_tmp, &node->node_rules, link) {
10278 + if (comp_rules(&node_rule->rule_ops,
10279 + &rule[i]) == 0) {
10280 + list_del(&node_rule->link);
10281 + kfree(node_rule);
10282 + match_found = true;
10283 + node->num_rules--;
10284 + list_sort(NULL,
10285 + &node->node_rules,
10286 + node_rules_compare);
10287 + break;
10288 + }
10289 + }
10290 + }
10291 + }
10292 + }
10293 +
10294 + list_for_each_entry_safe(node, node_tmp,
10295 + &node_list, link) {
10296 + if (!node->num_rules) {
10297 + pr_debug("Deleting Rule node %d", node->id);
10298 + list_del(&node->link);
10299 + kfree(node);
10300 + }
10301 + }
10302 +exit_unregister_rule:
10303 + mutex_unlock(&msm_bus_rules_lock);
10304 +}
10305 +
10306 +bool msm_rule_are_rules_registered(void)
10307 +{
10308 + bool ret = false;
10309 +
10310 + if (list_empty(&node_list))
10311 + ret = false;
10312 + else
10313 + ret = true;
10314 +
10315 + return ret;
10316 +}
10317 +
10318 --- /dev/null
10319 +++ b/drivers/bus/msm_bus/msm_bus_rules.h
10320 @@ -0,0 +1,77 @@
10321 +/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
10322 + *
10323 + * This program is free software; you can redistribute it and/or modify
10324 + * it under the terms of the GNU General Public License version 2 and
10325 + * only version 2 as published by the Free Software Foundation.
10326 + *
10327 + * This program is distributed in the hope that it will be useful,
10328 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10329 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10330 + * GNU General Public License for more details.
10331 + */
10332 +
10333 +#ifndef _ARCH_ARM_MACH_MSM_BUS_RULES_H
10334 +#define _ARCH_ARM_MACH_MSM_BUS_RULES_H
10335 +
10336 +#include <linux/types.h>
10337 +#include <linux/list.h>
10338 +#include <linux/notifier.h>
10339 +#include <dt-bindings/msm/msm-bus-rule-ops.h>
10340 +
10341 +#define MAX_NODES (5)
10342 +
10343 +struct rule_update_path_info {
10344 + u32 id;
10345 + u64 ab;
10346 + u64 ib;
10347 + u64 clk;
10348 + struct list_head link;
10349 +};
10350 +
10351 +struct rule_apply_rcm_info {
10352 + u32 id;
10353 + u64 lim_bw;
10354 + int throttle;
10355 + bool after_clk_commit;
10356 + struct list_head link;
10357 +};
10358 +
10359 +struct bus_rule_type {
10360 + int num_src;
10361 + int *src_id;
10362 + int src_field;
10363 + int op;
10364 + u64 thresh;
10365 + int num_dst;
10366 + int *dst_node;
10367 + u64 dst_bw;
10368 + int mode;
10369 + void *client_data;
10370 +};
10371 +
10372 +#if (defined(CONFIG_BUS_TOPOLOGY_ADHOC))
10373 +void msm_rule_register(int num_rules, struct bus_rule_type *rule,
10374 + struct notifier_block *nb);
10375 +void msm_rule_unregister(int num_rules, struct bus_rule_type *rule,
10376 + struct notifier_block *nb);
10377 +void print_rules_buf(char *buf, int count);
10378 +bool msm_rule_are_rules_registered(void);
10379 +#else
10380 +static inline void msm_rule_register(int num_rules, struct bus_rule_type *rule,
10381 + struct notifier_block *nb)
10382 +{
10383 +}
10384 +static inline void msm_rule_unregister(int num_rules,
10385 + struct bus_rule_type *rule,
10386 + struct notifier_block *nb)
10387 +{
10388 +}
10389 +static inline void print_rules_buf(char *buf, int count)
10390 +{
10391 +}
10392 +static inline bool msm_rule_are_rules_registered(void)
10393 +{
10394 + return false;
10395 +}
10396 +#endif /* defined(CONFIG_BUS_TOPOLOGY_ADHOC) */
10397 +#endif /* _ARCH_ARM_MACH_MSM_BUS_RULES_H */
10398 --- /dev/null
10399 +++ b/drivers/bus/msm_bus/msm_buspm_coresight_adhoc.c
10400 @@ -0,0 +1,189 @@
10401 +/* Copyright (c) 2014 The Linux Foundation. All rights reserved.
10402 + *
10403 + * This program is free software; you can redistribute it and/or modify
10404 + * it under the terms of the GNU General Public License version 2 and
10405 + * only version 2 as published by the Free Software Foundation.
10406 + *
10407 + * This program is distributed in the hope that it will be useful,
10408 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10409 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10410 + * GNU General Public License for more details.
10411 + */
10412 +
10413 +#include <linux/clk.h>
10414 +#include <linux/module.h>
10415 +#include <linux/device.h>
10416 +#include <linux/platform_device.h>
10417 +#include <linux/err.h>
10418 +#include <linux/slab.h>
10419 +#include <linux/errno.h>
10420 +#include <linux/uaccess.h>
10421 +#include <linux/miscdevice.h>
10422 +#include <linux/of_coresight.h>
10423 +#include <linux/coresight.h>
10424 +#include <linux/io.h>
10425 +#include <linux/of.h>
10426 +#include <linux/list.h>
10427 +
10428 +struct msmbus_coresight_adhoc_clock_drvdata {
10429 + int id;
10430 + struct clk *clk;
10431 + struct list_head list;
10432 +};
10433 +
10434 +struct msmbus_coresight_adhoc_drvdata {
10435 + struct device *dev;
10436 + struct coresight_device *csdev;
10437 + struct coresight_desc *desc;
10438 + struct list_head clocks;
10439 +};
10440 +
10441 +static int msmbus_coresight_enable_adhoc(struct coresight_device *csdev)
10442 +{
10443 + struct msmbus_coresight_adhoc_clock_drvdata *clk;
10444 + struct msmbus_coresight_adhoc_drvdata *drvdata =
10445 + dev_get_drvdata(csdev->dev.parent);
10446 + long rate;
10447 +
10448 + list_for_each_entry(clk, &drvdata->clocks, list) {
10449 + if (clk->id == csdev->id) {
10450 + rate = clk_round_rate(clk->clk, 1L);
10451 + clk_set_rate(clk->clk, rate);
10452 + return clk_prepare_enable(clk->clk);
10453 + }
10454 + }
10455 +
10456 + return -ENOENT;
10457 +}
10458 +
10459 +static void msmbus_coresight_disable_adhoc(struct coresight_device *csdev)
10460 +{
10461 + struct msmbus_coresight_adhoc_clock_drvdata *clk;
10462 + struct msmbus_coresight_adhoc_drvdata *drvdata =
10463 + dev_get_drvdata(csdev->dev.parent);
10464 +
10465 + list_for_each_entry(clk, &drvdata->clocks, list) {
10466 + if (clk->id == csdev->id)
10467 + clk_disable_unprepare(clk->clk);
10468 + }
10469 +}
10470 +
10471 +static const struct coresight_ops_source msmbus_coresight_adhoc_source_ops = {
10472 + .enable = msmbus_coresight_enable_adhoc,
10473 + .disable = msmbus_coresight_disable_adhoc,
10474 +};
10475 +
10476 +static const struct coresight_ops msmbus_coresight_cs_ops = {
10477 + .source_ops = &msmbus_coresight_adhoc_source_ops,
10478 +};
10479 +
10480 +void msmbus_coresight_remove_adhoc(struct platform_device *pdev)
10481 +{
10482 + struct msmbus_coresight_adhoc_clock_drvdata *clk, *next_clk;
10483 + struct msmbus_coresight_adhoc_drvdata *drvdata =
10484 + platform_get_drvdata(pdev);
10485 +
10486 + msmbus_coresight_disable_adhoc(drvdata->csdev);
10487 + coresight_unregister(drvdata->csdev);
10488 + list_for_each_entry_safe(clk, next_clk, &drvdata->clocks, list) {
10489 + list_del(&clk->list);
10490 + devm_kfree(&pdev->dev, clk);
10491 + }
10492 + devm_kfree(&pdev->dev, drvdata->desc);
10493 + devm_kfree(&pdev->dev, drvdata);
10494 + platform_set_drvdata(pdev, NULL);
10495 +}
10496 +EXPORT_SYMBOL(msmbus_coresight_remove_adhoc);
10497 +
10498 +static int buspm_of_get_clk_adhoc(struct device_node *of_node,
10499 + struct msmbus_coresight_adhoc_drvdata *drvdata, int id)
10500 +{
10501 + struct msmbus_coresight_adhoc_clock_drvdata *clk;
10502 + clk = devm_kzalloc(drvdata->dev, sizeof(*clk), GFP_KERNEL);
10503 +
10504 + if (!clk)
10505 + return -ENOMEM;
10506 +
10507 + clk->id = id;
10508 +
10509 + clk->clk = of_clk_get_by_name(of_node, "bus_clk");
10510 + if (IS_ERR(clk->clk)) {
10511 + pr_err("Error: unable to get clock for coresight node %d\n",
10512 + id);
10513 + goto err;
10514 + }
10515 +
10516 + list_add(&clk->list, &drvdata->clocks);
10517 + return 0;
10518 +
10519 +err:
10520 + devm_kfree(drvdata->dev, clk);
10521 + return -EINVAL;
10522 +}
10523 +
10524 +int msmbus_coresight_init_adhoc(struct platform_device *pdev,
10525 + struct device_node *of_node)
10526 +{
10527 + int ret;
10528 + struct device *dev = &pdev->dev;
10529 + struct coresight_platform_data *pdata;
10530 + struct msmbus_coresight_adhoc_drvdata *drvdata;
10531 + struct coresight_desc *desc;
10532 +
10533 + pdata = of_get_coresight_platform_data(dev, of_node);
10534 + if (IS_ERR(pdata))
10535 + return PTR_ERR(pdata);
10536 +
10537 + drvdata = platform_get_drvdata(pdev);
10538 + if (IS_ERR_OR_NULL(drvdata)) {
10539 + drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
10540 + if (!drvdata) {
10541 + pr_err("coresight: Alloc for drvdata failed\n");
10542 + return -ENOMEM;
10543 + }
10544 + INIT_LIST_HEAD(&drvdata->clocks);
10545 + drvdata->dev = &pdev->dev;
10546 + platform_set_drvdata(pdev, drvdata);
10547 + }
10548 + ret = buspm_of_get_clk_adhoc(of_node, drvdata, pdata->id);
10549 + if (ret) {
10550 + pr_err("Error getting clocks\n");
10551 + ret = -ENXIO;
10552 + goto err1;
10553 + }
10554 +
10555 + desc = devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL);
10556 + if (!desc) {
10557 + pr_err("coresight: Error allocating memory\n");
10558 + ret = -ENOMEM;
10559 + goto err1;
10560 + }
10561 +
10562 + desc->type = CORESIGHT_DEV_TYPE_SOURCE;
10563 + desc->subtype.source_subtype = CORESIGHT_DEV_SUBTYPE_SOURCE_BUS;
10564 + desc->ops = &msmbus_coresight_cs_ops;
10565 + desc->pdata = pdata;
10566 + desc->dev = &pdev->dev;
10567 + desc->owner = THIS_MODULE;
10568 + drvdata->desc = desc;
10569 + drvdata->csdev = coresight_register(desc);
10570 + if (IS_ERR(drvdata->csdev)) {
10571 + pr_err("coresight: Coresight register failed\n");
10572 + ret = PTR_ERR(drvdata->csdev);
10573 + goto err0;
10574 + }
10575 +
10576 + dev_info(dev, "msmbus_coresight initialized\n");
10577 +
10578 + return 0;
10579 +err0:
10580 + devm_kfree(dev, desc);
10581 +err1:
10582 + devm_kfree(dev, drvdata);
10583 + platform_set_drvdata(pdev, NULL);
10584 + return ret;
10585 +}
10586 +EXPORT_SYMBOL(msmbus_coresight_init_adhoc);
10587 +
10588 +MODULE_LICENSE("GPL v2");
10589 +MODULE_DESCRIPTION("MSM BusPM Adhoc CoreSight Driver");
10590 --- /dev/null
10591 +++ b/drivers/bus/msm_bus/rpm-smd.h
10592 @@ -0,0 +1,268 @@
10593 +/* Copyright (c) 2012, 2014, The Linux Foundation. All rights reserved.
10594 + *
10595 + * This program is free software; you can redistribute it and/or modify
10596 + * it under the terms of the GNU General Public License version 2 and
10597 + * only version 2 as published by the Free Software Foundation.
10598 + *
10599 + * This program is distributed in the hope that it will be useful,
10600 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10601 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10602 + * GNU General Public License for more details.
10603 + *
10604 + */
10605 +
10606 +#ifndef __ARCH_ARM_MACH_MSM_RPM_SMD_H
10607 +#define __ARCH_ARM_MACH_MSM_RPM_SMD_H
10608 +
10609 +/**
10610 + * enum msm_rpm_set - RPM enumerations for sleep/active set
10611 + * %MSM_RPM_CTX_SET_0: Set resource parameters for active mode.
10612 + * %MSM_RPM_CTX_SET_SLEEP: Set resource parameters for sleep.
10613 + */
10614 +enum msm_rpm_set {
10615 + MSM_RPM_CTX_ACTIVE_SET,
10616 + MSM_RPM_CTX_SLEEP_SET,
10617 +};
10618 +
10619 +struct msm_rpm_request;
10620 +
10621 +struct msm_rpm_kvp {
10622 + uint32_t key;
10623 + uint32_t length;
10624 + uint8_t *data;
10625 +};
10626 +#ifdef CONFIG_MSM_RPM_SMD
10627 +/**
10628 + * msm_rpm_request() - Creates a parent element to identify the
10629 + * resource on the RPM, that stores the KVPs for different fields modified
10630 + * for a hardware resource
10631 + *
10632 + * @set: if the device is setting the active/sleep set parameter
10633 + * for the resource
10634 + * @rsc_type: unsigned 32 bit integer that identifies the type of the resource
10635 + * @rsc_id: unsigned 32 bit that uniquely identifies a resource within a type
10636 + * @num_elements: number of KVPs pairs associated with the resource
10637 + *
10638 + * returns pointer to a msm_rpm_request on success, NULL on error
10639 + */
10640 +struct msm_rpm_request *msm_rpm_create_request(
10641 + enum msm_rpm_set set, uint32_t rsc_type,
10642 + uint32_t rsc_id, int num_elements);
10643 +
10644 +/**
10645 + * msm_rpm_request_noirq() - Creates a parent element to identify the
10646 + * resource on the RPM, that stores the KVPs for different fields modified
10647 + * for a hardware resource. This function is similar to msm_rpm_create_request
10648 + * except that it has to be called with interrupts masked.
10649 + *
10650 + * @set: if the device is setting the active/sleep set parameter
10651 + * for the resource
10652 + * @rsc_type: unsigned 32 bit integer that identifies the type of the resource
10653 + * @rsc_id: unsigned 32 bit that uniquely identifies a resource within a type
10654 + * @num_elements: number of KVPs pairs associated with the resource
10655 + *
10656 + * returns pointer to a msm_rpm_request on success, NULL on error
10657 + */
10658 +struct msm_rpm_request *msm_rpm_create_request_noirq(
10659 + enum msm_rpm_set set, uint32_t rsc_type,
10660 + uint32_t rsc_id, int num_elements);
10661 +
10662 +/**
10663 + * msm_rpm_add_kvp_data() - Adds a Key value pair to a existing RPM resource.
10664 + *
10665 + * @handle: RPM resource handle to which the data should be appended
10666 + * @key: unsigned integer identify the parameter modified
10667 + * @data: byte array that contains the value corresponding to key.
10668 + * @size: size of data in bytes.
10669 + *
10670 + * returns 0 on success or errno
10671 + */
10672 +int msm_rpm_add_kvp_data(struct msm_rpm_request *handle,
10673 + uint32_t key, const uint8_t *data, int size);
10674 +
10675 +/**
10676 + * msm_rpm_add_kvp_data_noirq() - Adds a Key value pair to a existing RPM
10677 + * resource. This function is similar to msm_rpm_add_kvp_data except that it
10678 + * has to be called with interrupts masked.
10679 + *
10680 + * @handle: RPM resource handle to which the data should be appended
10681 + * @key: unsigned integer identify the parameter modified
10682 + * @data: byte array that contains the value corresponding to key.
10683 + * @size: size of data in bytes.
10684 + *
10685 + * returns 0 on success or errno
10686 + */
10687 +int msm_rpm_add_kvp_data_noirq(struct msm_rpm_request *handle,
10688 + uint32_t key, const uint8_t *data, int size);
10689 +
10690 +/** msm_rpm_free_request() - clean up the RPM request handle created with
10691 + * msm_rpm_create_request
10692 + *
10693 + * @handle: RPM resource handle to be cleared.
10694 + */
10695 +
10696 +void msm_rpm_free_request(struct msm_rpm_request *handle);
10697 +
10698 +/**
10699 + * msm_rpm_send_request() - Send the RPM messages using SMD. The function
10700 + * assigns a message id before sending the data out to the RPM. RPM hardware
10701 + * uses the message id to acknowledge the messages.
10702 + *
10703 + * @handle: pointer to the msm_rpm_request for the resource being modified.
10704 + *
10705 + * returns non-zero message id on success and zero on a failed transaction.
10706 + * The drivers use message id to wait for ACK from RPM.
10707 + */
10708 +int msm_rpm_send_request(struct msm_rpm_request *handle);
10709 +
10710 +/**
10711 + * msm_rpm_send_request_noirq() - Send the RPM messages using SMD. The
10712 + * function assigns a message id before sending the data out to the RPM.
10713 + * RPM hardware uses the message id to acknowledge the messages. This function
10714 + * is similar to msm_rpm_send_request except that it has to be called with
10715 + * interrupts masked.
10716 + *
10717 + * @handle: pointer to the msm_rpm_request for the resource being modified.
10718 + *
10719 + * returns non-zero message id on success and zero on a failed transaction.
10720 + * The drivers use message id to wait for ACK from RPM.
10721 + */
10722 +int msm_rpm_send_request_noirq(struct msm_rpm_request *handle);
10723 +
10724 +/**
10725 + * msm_rpm_wait_for_ack() - A blocking call that waits for acknowledgment of
10726 + * a message from RPM.
10727 + *
10728 + * @msg_id: the return from msm_rpm_send_requests
10729 + *
10730 + * returns 0 on success or errno
10731 + */
10732 +int msm_rpm_wait_for_ack(uint32_t msg_id);
10733 +
10734 +/**
10735 + * msm_rpm_wait_for_ack_noirq() - A blocking call that waits for acknowledgment
10736 + * of a message from RPM. This function is similar to msm_rpm_wait_for_ack
10737 + * except that it has to be called with interrupts masked.
10738 + *
10739 + * @msg_id: the return from msm_rpm_send_request
10740 + *
10741 + * returns 0 on success or errno
10742 + */
10743 +int msm_rpm_wait_for_ack_noirq(uint32_t msg_id);
10744 +
10745 +/**
10746 + * msm_rpm_send_message() -Wrapper function for clients to send data given an
10747 + * array of key value pairs.
10748 + *
10749 + * @set: if the device is setting the active/sleep set parameter
10750 + * for the resource
10751 + * @rsc_type: unsigned 32 bit integer that identifies the type of the resource
10752 + * @rsc_id: unsigned 32 bit that uniquely identifies a resource within a type
10753 + * @kvp: array of KVP data.
10754 + * @nelem: number of KVPs pairs associated with the message.
10755 + *
10756 + * returns 0 on success and errno on failure.
10757 + */
10758 +int msm_rpm_send_message(enum msm_rpm_set set, uint32_t rsc_type,
10759 + uint32_t rsc_id, struct msm_rpm_kvp *kvp, int nelems);
10760 +
10761 +/**
10762 + * msm_rpm_send_message_noirq() -Wrapper function for clients to send data
10763 + * given an array of key value pairs. This function is similar to the
10764 + * msm_rpm_send_message() except that it has to be called with interrupts
10765 + * disabled. Clients should choose the irq version when possible for system
10766 + * performance.
10767 + *
10768 + * @set: if the device is setting the active/sleep set parameter
10769 + * for the resource
10770 + * @rsc_type: unsigned 32 bit integer that identifies the type of the resource
10771 + * @rsc_id: unsigned 32 bit that uniquely identifies a resource within a type
10772 + * @kvp: array of KVP data.
10773 + * @nelem: number of KVPs pairs associated with the message.
10774 + *
10775 + * returns 0 on success and errno on failure.
10776 + */
10777 +int msm_rpm_send_message_noirq(enum msm_rpm_set set, uint32_t rsc_type,
10778 + uint32_t rsc_id, struct msm_rpm_kvp *kvp, int nelems);
10779 +
10780 +/**
10781 + * msm_rpm_driver_init() - Initialization function that registers for a
10782 + * rpm platform driver.
10783 + *
10784 + * returns 0 on success.
10785 + */
10786 +int __init msm_rpm_driver_init(void);
10787 +
10788 +#else
10789 +
10790 +static inline struct msm_rpm_request *msm_rpm_create_request(
10791 + enum msm_rpm_set set, uint32_t rsc_type,
10792 + uint32_t rsc_id, int num_elements)
10793 +{
10794 + return NULL;
10795 +}
10796 +
10797 +static inline struct msm_rpm_request *msm_rpm_create_request_noirq(
10798 + enum msm_rpm_set set, uint32_t rsc_type,
10799 + uint32_t rsc_id, int num_elements)
10800 +{
10801 + return NULL;
10802 +
10803 +}
10804 +static inline uint32_t msm_rpm_add_kvp_data(struct msm_rpm_request *handle,
10805 + uint32_t key, const uint8_t *data, int count)
10806 +{
10807 + return 0;
10808 +}
10809 +static inline uint32_t msm_rpm_add_kvp_data_noirq(
10810 + struct msm_rpm_request *handle, uint32_t key,
10811 + const uint8_t *data, int count)
10812 +{
10813 + return 0;
10814 +}
10815 +
10816 +static inline void msm_rpm_free_request(struct msm_rpm_request *handle)
10817 +{
10818 + return;
10819 +}
10820 +
10821 +static inline int msm_rpm_send_request(struct msm_rpm_request *handle)
10822 +{
10823 + return 0;
10824 +}
10825 +
10826 +static inline int msm_rpm_send_request_noirq(struct msm_rpm_request *handle)
10827 +{
10828 + return 0;
10829 +
10830 +}
10831 +
10832 +static inline int msm_rpm_send_message(enum msm_rpm_set set, uint32_t rsc_type,
10833 + uint32_t rsc_id, struct msm_rpm_kvp *kvp, int nelems)
10834 +{
10835 + return 0;
10836 +}
10837 +
10838 +static inline int msm_rpm_send_message_noirq(enum msm_rpm_set set,
10839 + uint32_t rsc_type, uint32_t rsc_id, struct msm_rpm_kvp *kvp,
10840 + int nelems)
10841 +{
10842 + return 0;
10843 +}
10844 +
10845 +static inline int msm_rpm_wait_for_ack(uint32_t msg_id)
10846 +{
10847 + return 0;
10848 +
10849 +}
10850 +static inline int msm_rpm_wait_for_ack_noirq(uint32_t msg_id)
10851 +{
10852 + return 0;
10853 +}
10854 +
10855 +static inline int __init msm_rpm_driver_init(void)
10856 +{
10857 + return 0;
10858 +}
10859 +#endif
10860 +#endif /*__ARCH_ARM_MACH_MSM_RPM_SMD_H*/
10861 --- /dev/null
10862 +++ b/include/trace/events/trace_msm_bus.h
10863 @@ -0,0 +1,163 @@
10864 +/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
10865 + *
10866 + * This program is free software; you can redistribute it and/or modify
10867 + * it under the terms of the GNU General Public License version 2 and
10868 + * only version 2 as published by the Free Software Foundation.
10869 + *
10870 + * This program is distributed in the hope that it will be useful,
10871 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10872 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10873 + * GNU General Public License for more details.
10874 + */
10875 +
10876 +#undef TRACE_SYSTEM
10877 +#define TRACE_SYSTEM msm_bus
10878 +
10879 +#if !defined(_TRACE_MSM_BUS_H) || defined(TRACE_HEADER_MULTI_READ)
10880 +#define _TRACE_MSM_BUS_H
10881 +
10882 +#include <linux/tracepoint.h>
10883 +
10884 +TRACE_EVENT(bus_update_request,
10885 +
10886 + TP_PROTO(int sec, int nsec, const char *name, unsigned int index,
10887 + int src, int dest, unsigned long long ab,
10888 + unsigned long long ib),
10889 +
10890 + TP_ARGS(sec, nsec, name, index, src, dest, ab, ib),
10891 +
10892 + TP_STRUCT__entry(
10893 + __field(int, sec)
10894 + __field(int, nsec)
10895 + __string(name, name)
10896 + __field(u32, index)
10897 + __field(int, src)
10898 + __field(int, dest)
10899 + __field(u64, ab)
10900 + __field(u64, ib)
10901 + ),
10902 +
10903 + TP_fast_assign(
10904 + __entry->sec = sec;
10905 + __entry->nsec = nsec;
10906 + __assign_str(name, name);
10907 + __entry->index = index;
10908 + __entry->src = src;
10909 + __entry->dest = dest;
10910 + __entry->ab = ab;
10911 + __entry->ib = ib;
10912 + ),
10913 +
10914 + TP_printk("time= %d.%d name=%s index=%u src=%d dest=%d ab=%llu ib=%llu",
10915 + __entry->sec,
10916 + __entry->nsec,
10917 + __get_str(name),
10918 + (unsigned int)__entry->index,
10919 + __entry->src,
10920 + __entry->dest,
10921 + (unsigned long long)__entry->ab,
10922 + (unsigned long long)__entry->ib)
10923 +);
10924 +
10925 +TRACE_EVENT(bus_bimc_config_limiter,
10926 +
10927 + TP_PROTO(int mas_id, unsigned long long cur_lim_bw),
10928 +
10929 + TP_ARGS(mas_id, cur_lim_bw),
10930 +
10931 + TP_STRUCT__entry(
10932 + __field(int, mas_id)
10933 + __field(u64, cur_lim_bw)
10934 + ),
10935 +
10936 + TP_fast_assign(
10937 + __entry->mas_id = mas_id;
10938 + __entry->cur_lim_bw = cur_lim_bw;
10939 + ),
10940 +
10941 + TP_printk("Master=%d cur_lim_bw=%llu",
10942 + __entry->mas_id,
10943 + (unsigned long long)__entry->cur_lim_bw)
10944 +);
10945 +
10946 +TRACE_EVENT(bus_avail_bw,
10947 +
10948 + TP_PROTO(unsigned long long cur_bimc_bw, unsigned long long cur_mdp_bw),
10949 +
10950 + TP_ARGS(cur_bimc_bw, cur_mdp_bw),
10951 +
10952 + TP_STRUCT__entry(
10953 + __field(u64, cur_bimc_bw)
10954 + __field(u64, cur_mdp_bw)
10955 + ),
10956 +
10957 + TP_fast_assign(
10958 + __entry->cur_bimc_bw = cur_bimc_bw;
10959 + __entry->cur_mdp_bw = cur_mdp_bw;
10960 + ),
10961 +
10962 + TP_printk("cur_bimc_bw = %llu cur_mdp_bw = %llu",
10963 + (unsigned long long)__entry->cur_bimc_bw,
10964 + (unsigned long long)__entry->cur_mdp_bw)
10965 +);
10966 +
10967 +TRACE_EVENT(bus_rules_matches,
10968 +
10969 + TP_PROTO(int node_id, int rule_id, unsigned long long node_ab,
10970 + unsigned long long node_ib, unsigned long long node_clk),
10971 +
10972 + TP_ARGS(node_id, rule_id, node_ab, node_ib, node_clk),
10973 +
10974 + TP_STRUCT__entry(
10975 + __field(int, node_id)
10976 + __field(int, rule_id)
10977 + __field(u64, node_ab)
10978 + __field(u64, node_ib)
10979 + __field(u64, node_clk)
10980 + ),
10981 +
10982 + TP_fast_assign(
10983 + __entry->node_id = node_id;
10984 + __entry->rule_id = rule_id;
10985 + __entry->node_ab = node_ab;
10986 + __entry->node_ib = node_ib;
10987 + __entry->node_clk = node_clk;
10988 + ),
10989 +
10990 + TP_printk("Rule match node%d rule%d node-ab%llu:ib%llu:clk%llu",
10991 + __entry->node_id, __entry->rule_id,
10992 + (unsigned long long)__entry->node_ab,
10993 + (unsigned long long)__entry->node_ib,
10994 + (unsigned long long)__entry->node_clk)
10995 +);
10996 +
10997 +TRACE_EVENT(bus_bke_params,
10998 +
10999 + TP_PROTO(u32 gc, u32 gp, u32 thl, u32 thm, u32 thh),
11000 +
11001 + TP_ARGS(gc, gp, thl, thm, thh),
11002 +
11003 + TP_STRUCT__entry(
11004 + __field(u32, gc)
11005 + __field(u32, gp)
11006 + __field(u32, thl)
11007 + __field(u32, thm)
11008 + __field(u32, thh)
11009 + ),
11010 +
11011 + TP_fast_assign(
11012 + __entry->gc = gc;
11013 + __entry->gp = gp;
11014 + __entry->thl = thl;
11015 + __entry->thm = thm;
11016 + __entry->thh = thh;
11017 + ),
11018 +
11019 + TP_printk("BKE Params GC=0x%x GP=0x%x THL=0x%x THM=0x%x THH=0x%x",
11020 + __entry->gc, __entry->gp, __entry->thl, __entry->thm,
11021 + __entry->thh)
11022 +);
11023 +
11024 +#endif
11025 +#define TRACE_INCLUDE_FILE trace_msm_bus
11026 +#include <trace/define_trace.h>