forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/drivers/net/wireless/rockchip_wlan/cywdhd/bcmdhd/aiutils.c
....@@ -1,16 +1,17 @@
1
-/* SPDX-License-Identifier: GPL-2.0 */
21 /*
32 * Misc utility routines for accessing chip-specific features
43 * of the SiliconBackplane-based Broadcom chips.
54 *
6
- * Copyright (C) 1999-2019, Broadcom Corporation
7
- *
5
+ * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
6
+ *
7
+ * Copyright (C) 1999-2017, Broadcom Corporation
8
+ *
89 * Unless you and Broadcom execute a separate written software license
910 * agreement governing use of this software, this software is licensed to you
1011 * under the terms of the GNU General Public License version 2 (the "GPL"),
1112 * available at http://www.broadcom.com/licenses/GPLv2.php, with the
1213 * following added to such license:
13
- *
14
+ *
1415 * As a special exception, the copyright holders of this software give you
1516 * permission to link this software with independent modules, and to copy and
1617 * distribute the resulting executable under terms of your choice, provided that
....@@ -18,7 +19,7 @@
1819 * the license of that module. An independent module is a module which is not
1920 * derived from this software. The special exception does not apply to any
2021 * modifications of the software.
21
- *
22
+ *
2223 * Notwithstanding the above, under no circumstances may you combine this
2324 * software in any way with any other Broadcom software provided under a license
2425 * other than the GPL, without Broadcom's express prior written consent.
....@@ -26,7 +27,7 @@
2627 *
2728 * <<Broadcom-WL-IPTag/Open:>>
2829 *
29
- * $Id: aiutils.c 708487 2018-10-31 05:33:14Z $
30
+ * $Id: aiutils.c 701122 2017-05-23 19:32:45Z $
3031 */
3132 #include <bcm_cfg.h>
3233 #include <typedefs.h>
....@@ -39,23 +40,28 @@
3940 #include <pcicfg.h>
4041
4142 #include "siutils_priv.h"
42
-
43
-
44
-#ifdef LOAD_DHD_WITH_FW_ALIVE
4543 #include <bcmdevs.h>
46
-#include <dhd_chip_info.h>
47
-#endif
4844
49
-#define BCM47162_DMP() (0)
50
-#define BCM5357_DMP() (0)
5145 #define BCM53573_DMP() (0)
5246 #define BCM4707_DMP() (0)
5347 #define PMU_DMP() (0)
5448 #define GCI_DMP() (0)
55
-#define remap_coreid(sih, coreid) (coreid)
56
-#define remap_corerev(sih, corerev) (corerev)
49
+
50
+#if defined(BCM_BACKPLANE_TIMEOUT)
51
+static bool ai_get_apb_bridge(si_t *sih, uint32 coreidx, uint32 *apb_id, uint32 *apb_coreuinit);
52
+#endif /* BCM_BACKPLANE_TIMEOUT */
53
+
54
+#if defined(AXI_TIMEOUTS) || defined(BCM_BACKPLANE_TIMEOUT)
55
+static void ai_reset_axi_to(si_info_t *sii, aidmp_t *ai);
56
+#endif /* defined (AXI_TIMEOUTS) || defined (BCM_BACKPLANE_TIMEOUT) */
5757
5858 /* EROM parsing */
59
+
60
+#ifdef BCMQT
61
+#define SPINWAIT_TIME_US 3000
62
+#else
63
+#define SPINWAIT_TIME_US 300
64
+#endif /* BCMQT */
5965
6066 static uint32
6167 get_erom_ent(si_t *sih, uint32 **eromptr, uint32 mask, uint32 match)
....@@ -101,9 +107,11 @@
101107
102108 static uint32
103109 get_asd(si_t *sih, uint32 **eromptr, uint sp, uint ad, uint st, uint32 *addrl, uint32 *addrh,
104
- uint32 *sizel, uint32 *sizeh)
110
+ uint32 *sizel, uint32 *sizeh)
105111 {
106112 uint32 asd, sz, szd;
113
+
114
+ BCM_REFERENCE(ad);
107115
108116 asd = get_erom_ent(sih, eromptr, ER_VALID, ER_VALID);
109117 if (((asd & ER_TAG1) != ER_ADD) ||
....@@ -134,58 +142,19 @@
134142 return asd;
135143 }
136144
137
-static void
138
-ai_hwfixup(si_info_t *sii)
139
-{
140
-}
141
-
142
-
143
-/* parse the enumeration rom to identify all cores */
145
+/* Parse the enumeration rom to identify all cores
146
+ * Erom content format can be found in:
147
+ * http://hwnbu-twiki.broadcom.com/twiki/pub/Mwgroup/ArmDocumentation/SystemDiscovery.pdf
148
+ */
144149 void
145
-ai_scan(si_t *sih, void *regs, uint devid)
150
+ai_scan(si_t *sih, void *regs, uint32 erombase, uint devid)
146151 {
147152 si_info_t *sii = SI_INFO(sih);
148153 si_cores_info_t *cores_info = (si_cores_info_t *)sii->cores_info;
149
- chipcregs_t *cc = (chipcregs_t *)regs;
150
- uint32 erombase, *eromptr, *eromlim;
154
+ uint32 *eromptr, *eromlim;
155
+ axi_wrapper_t * axi_wrapper = sii->axi_wrapper;
151156
152
-#ifdef LOAD_DHD_WITH_FW_ALIVE
153
- if(alive == FW_ALIVE_MAGIC) {
154
- switch(card_dev) {
155
- case BCM43430_CHIP_ID:
156
- sii->numcores = ai_core_43430;
157
- sii->oob_router = oob_router_43430;
158
- memcpy(&cores_info->coreid, &bcm43430_coreid, sii->numcores * 4);
159
- memcpy(&cores_info->coresba, &bcm43430_coresba, sii->numcores * 4);
160
- memcpy(&cores_info->coresba_size, &bcm43430_coresba_size, sii->numcores * 4);
161
- memcpy(&cores_info->wrapba, &bcm43430_wrapba, sii->numcores * 4);
162
- memcpy(&cores_info->cia, &bcm43430_cia, sii->numcores * 4);
163
- if(card_rev == 2) {
164
- memcpy(&cores_info->cib, &bcm43436_cib, sii->numcores * 4);
165
- } else {
166
- memcpy(&cores_info->cib, &bcm43430_cib, sii->numcores * 4);
167
- }
168
- break;
169
-
170
- case BCM43012_CHIP_ID:
171
- sii->numcores = ai_core_43012;
172
- sii->oob_router = oob_router_43012;
173
- memcpy(&cores_info->coreid, &bcm43012_coreid, sii->numcores * 4);
174
- memcpy(&cores_info->coresba, &bcm43012_coresba, sii->numcores * 4);
175
- memcpy(&cores_info->coresba_size, &bcm43012_coresba_size, sii->numcores * 4);
176
- memcpy(&cores_info->wrapba, &bcm43012_wrapba, sii->numcores * 4);
177
- memcpy(&cores_info->cia, &bcm43012_cia, sii->numcores * 4);
178
- memcpy(&cores_info->cib, &bcm43012_cib, sii->numcores * 4);
179
-
180
- default:
181
- break;
182
- }
183
-
184
- return;
185
- }
186
-#endif
187
-
188
- erombase = R_REG(sii->osh, &cc->eromptr);
157
+ BCM_REFERENCE(devid);
189158
190159 switch (BUSTYPE(sih->bustype)) {
191160 case SI_BUS:
....@@ -215,9 +184,11 @@
215184 return;
216185 }
217186 eromlim = eromptr + (ER_REMAPCONTROL / sizeof(uint32));
187
+ sii->axi_num_wrappers = 0;
218188
219189 SI_VMSG(("ai_scan: regs = 0x%p, erombase = 0x%08x, eromptr = 0x%p, eromlim = 0x%p\n",
220
- regs, erombase, eromptr, eromlim));
190
+ OSL_OBFUSCATE_BUF(regs), erombase,
191
+ OSL_OBFUSCATE_BUF(eromptr), OSL_OBFUSATE_BUF(eromlim)));
221192 while (eromptr < eromlim) {
222193 uint32 cia, cib, cid, mfg, crev, nmw, nsw, nmp, nsp;
223194 uint32 mpd, asd, addrl, addrh, sizel, sizeh;
....@@ -230,7 +201,6 @@
230201 cia = get_erom_ent(sih, &eromptr, ER_TAG, ER_CI);
231202 if (cia == (ER_END | ER_VALID)) {
232203 SI_VMSG(("Found END of erom after %d cores\n", sii->numcores));
233
- ai_hwfixup(sii);
234204 return;
235205 }
236206
....@@ -252,24 +222,49 @@
252222 #ifdef BCMDBG_SI
253223 SI_VMSG(("Found component 0x%04x/0x%04x rev %d at erom addr 0x%p, with nmw = %d, "
254224 "nsw = %d, nmp = %d & nsp = %d\n",
255
- mfg, cid, crev, eromptr - 1, nmw, nsw, nmp, nsp));
225
+ mfg, cid, crev, OSL_OBFUSCATE_BUF(eromptr - 1), nmw, nsw, nmp, nsp));
256226 #else
257227 BCM_REFERENCE(crev);
258
-#endif
228
+#endif // endif
259229
260
- if (((mfg == MFGID_ARM) && (cid == DEF_AI_COMP)) || (nsp == 0))
261
- continue;
230
+ if (BCM4347_CHIP(sih->chip)) {
231
+ /* 4347 has more entries for ARM core
232
+ * This should apply to all chips but crashes on router
233
+ * This is a temp fix to be further analyze
234
+ */
235
+ if (nsp == 0)
236
+ continue;
237
+ } else
238
+ {
239
+ /* Include Default slave wrapper for timeout monitoring */
240
+ if ((nsp == 0) ||
241
+#if !defined(AXI_TIMEOUTS) && !defined(BCM_BACKPLANE_TIMEOUT)
242
+ ((mfg == MFGID_ARM) && (cid == DEF_AI_COMP)) ||
243
+#else
244
+ ((CHIPTYPE(sii->pub.socitype) == SOCI_NAI) &&
245
+ (mfg == MFGID_ARM) && (cid == DEF_AI_COMP)) ||
246
+#endif /* !defined(AXI_TIMEOUTS) && !defined(BCM_BACKPLANE_TIMEOUT) */
247
+ FALSE) {
248
+ continue;
249
+ }
250
+ }
251
+
262252 if ((nmw + nsw == 0)) {
263253 /* A component which is not a core */
264254 if (cid == OOB_ROUTER_CORE_ID) {
265255 asd = get_asd(sih, &eromptr, 0, 0, AD_ST_SLAVE,
266256 &addrl, &addrh, &sizel, &sizeh);
267257 if (asd != 0) {
268
- sii->oob_router = addrl;
258
+ if ((sii->oob_router != 0) && (sii->oob_router != addrl)) {
259
+ sii->oob_router1 = addrl;
260
+ } else {
261
+ sii->oob_router = addrl;
262
+ }
269263 }
270264 }
271
- if (cid != GMAC_COMMON_4706_CORE_ID && cid != NS_CCB_CORE_ID &&
272
- cid != PMU_CORE_ID && cid != GCI_CORE_ID)
265
+ if (cid != NS_CCB_CORE_ID &&
266
+ cid != PMU_CORE_ID && cid != GCI_CORE_ID && cid != SR_CORE_ID &&
267
+ cid != HUB_CORE_ID && cid != HND_OOBR_CORE_ID)
273268 continue;
274269 }
275270
....@@ -277,7 +272,7 @@
277272
278273 cores_info->cia[idx] = cia;
279274 cores_info->cib[idx] = cib;
280
- cores_info->coreid[idx] = remap_coreid(sih, cid);
275
+ cores_info->coreid[idx] = cid;
281276
282277 for (i = 0; i < nmp; i++) {
283278 mpd = get_erom_ent(sih, &eromptr, ER_VALID, ER_VALID);
....@@ -319,7 +314,7 @@
319314 }
320315 cores_info->coresba[idx] = addrl;
321316 cores_info->coresba_size[idx] = sizel;
322
- /* Get any more ASDs in port 0 */
317
+ /* Get any more ASDs in first port */
323318 j = 1;
324319 do {
325320 asd = get_asd(sih, &eromptr, 0, j, AD_ST_SLAVE, &addrl, &addrh,
....@@ -337,7 +332,11 @@
337332 do {
338333 asd = get_asd(sih, &eromptr, i, j, AD_ST_SLAVE, &addrl, &addrh,
339334 &sizel, &sizeh);
340
-
335
+ /* To get the first base address of second slave port */
336
+ if ((asd != 0) && (i == 1) && (j == 0)) {
337
+ cores_info->csp2ba[idx] = addrl;
338
+ cores_info->csp2ba_size[idx] = sizel;
339
+ }
341340 if (asd == 0)
342341 break;
343342 j++;
....@@ -360,10 +359,26 @@
360359 SI_ERROR(("Master wrapper %d is not 4KB\n", i));
361360 goto error;
362361 }
363
- if (i == 0)
362
+ if (i == 0) {
364363 cores_info->wrapba[idx] = addrl;
365
- else if (i == 1)
364
+ } else if (i == 1) {
366365 cores_info->wrapba2[idx] = addrl;
366
+ } else if (i == 2) {
367
+ cores_info->wrapba3[idx] = addrl;
368
+ }
369
+
370
+ if (axi_wrapper &&
371
+ (sii->axi_num_wrappers < SI_MAX_AXI_WRAPPERS)) {
372
+ axi_wrapper[sii->axi_num_wrappers].mfg = mfg;
373
+ axi_wrapper[sii->axi_num_wrappers].cid = cid;
374
+ axi_wrapper[sii->axi_num_wrappers].rev = crev;
375
+ axi_wrapper[sii->axi_num_wrappers].wrapper_type = AI_MASTER_WRAPPER;
376
+ axi_wrapper[sii->axi_num_wrappers].wrapper_addr = addrl;
377
+ sii->axi_num_wrappers++;
378
+ SI_VMSG(("MASTER WRAPPER: %d, mfg:%x, cid:%x,"
379
+ "rev:%x, addr:%x, size:%x\n",
380
+ sii->axi_num_wrappers, mfg, cid, crev, addrl, sizel));
381
+ }
367382 }
368383
369384 /* And finally slave wrappers */
....@@ -377,6 +392,7 @@
377392 ASSERT(sii->num_br < SI_MAXBR);
378393 sii->br_wrapba[sii->num_br++] = addrl;
379394 }
395
+
380396 if (asd == 0) {
381397 SI_ERROR(("Missing descriptor for SW %d\n", i));
382398 goto error;
....@@ -385,16 +401,54 @@
385401 SI_ERROR(("Slave wrapper %d is not 4KB\n", i));
386402 goto error;
387403 }
388
- if ((nmw == 0) && (i == 0))
404
+ if ((nmw == 0) && (i == 0)) {
389405 cores_info->wrapba[idx] = addrl;
390
- else if ((nmw == 0) && (i == 1))
406
+ } else if ((nmw == 0) && (i == 1)) {
391407 cores_info->wrapba2[idx] = addrl;
408
+ } else if ((nmw == 0) && (i == 2)) {
409
+ cores_info->wrapba3[idx] = addrl;
410
+ }
411
+
412
+ /* Include all slave wrappers to the list to
413
+ * enable and monitor watchdog timeouts
414
+ */
415
+
416
+ if (axi_wrapper &&
417
+ (sii->axi_num_wrappers < SI_MAX_AXI_WRAPPERS)) {
418
+ axi_wrapper[sii->axi_num_wrappers].mfg = mfg;
419
+ axi_wrapper[sii->axi_num_wrappers].cid = cid;
420
+ axi_wrapper[sii->axi_num_wrappers].rev = crev;
421
+ axi_wrapper[sii->axi_num_wrappers].wrapper_type = AI_SLAVE_WRAPPER;
422
+
423
+ /* Software WAR as discussed with hardware team, to ensure proper
424
+ * Slave Wrapper Base address is set for 4364 Chip ID.
425
+ * Current address is 0x1810c000, Corrected the same to 0x1810e000.
426
+ * This ensures AXI default slave wrapper is registered along with
427
+ * other slave wrapper cores and is useful while generating trap info
428
+ * when write operation is tried on Invalid Core / Wrapper register
429
+ */
430
+
431
+ if ((CHIPID(sih->chip) == BCM4364_CHIP_ID) &&
432
+ (cid == DEF_AI_COMP)) {
433
+ axi_wrapper[sii->axi_num_wrappers].wrapper_addr =
434
+ 0x1810e000;
435
+ } else {
436
+ axi_wrapper[sii->axi_num_wrappers].wrapper_addr = addrl;
437
+ }
438
+
439
+ sii->axi_num_wrappers++;
440
+
441
+ SI_VMSG(("SLAVE WRAPPER: %d, mfg:%x, cid:%x,"
442
+ "rev:%x, addr:%x, size:%x\n",
443
+ sii->axi_num_wrappers, mfg, cid, crev, addrl, sizel));
444
+ }
392445 }
393446
394
-
447
+#ifndef BCM_BACKPLANE_TIMEOUT
395448 /* Don't record bridges */
396449 if (br)
397450 continue;
451
+#endif // endif
398452
399453 /* Done with core */
400454 sii->numcores++;
....@@ -413,13 +467,13 @@
413467 /* This function changes the logical "focus" to the indicated core.
414468 * Return the current core's virtual address.
415469 */
416
-static void *
417
-_ai_setcoreidx(si_t *sih, uint coreidx, uint use_wrap2)
470
+static volatile void *
471
+_ai_setcoreidx(si_t *sih, uint coreidx, uint use_wrapn)
418472 {
419473 si_info_t *sii = SI_INFO(sih);
420474 si_cores_info_t *cores_info = (si_cores_info_t *)sii->cores_info;
421
- uint32 addr, wrap, wrap2;
422
- void *regs;
475
+ uint32 addr, wrap, wrap2, wrap3;
476
+ volatile void *regs;
423477
424478 if (coreidx >= MIN(sii->numcores, SI_MAXCORES))
425479 return (NULL);
....@@ -427,12 +481,21 @@
427481 addr = cores_info->coresba[coreidx];
428482 wrap = cores_info->wrapba[coreidx];
429483 wrap2 = cores_info->wrapba2[coreidx];
484
+ wrap3 = cores_info->wrapba3[coreidx];
430485
431
- /*
432
- * If the user has provided an interrupt mask enabled function,
433
- * then assert interrupts are disabled before switching the core.
434
- */
435
- ASSERT((sii->intrsenabled_fn == NULL) || !(*(sii)->intrsenabled_fn)((sii)->intr_arg));
486
+#ifdef BCM_BACKPLANE_TIMEOUT
487
+ /* No need to disable interrupts while entering/exiting APB bridge core */
488
+ if ((cores_info->coreid[coreidx] != APB_BRIDGE_CORE_ID) &&
489
+ (cores_info->coreid[sii->curidx] != APB_BRIDGE_CORE_ID))
490
+#endif /* BCM_BACKPLANE_TIMEOUT */
491
+ {
492
+ /*
493
+ * If the user has provided an interrupt mask enabled function,
494
+ * then assert interrupts are disabled before switching the core.
495
+ */
496
+ ASSERT((sii->intrsenabled_fn == NULL) ||
497
+ !(*(sii)->intrsenabled_fn)((sii)->intr_arg));
498
+ }
436499
437500 switch (BUSTYPE(sih->bustype)) {
438501 case SI_BUS:
....@@ -451,18 +514,35 @@
451514 cores_info->wrappers2[coreidx] = REG_MAP(wrap2, SI_CORE_SIZE);
452515 ASSERT(GOODREGS(cores_info->wrappers2[coreidx]));
453516 }
454
- if (use_wrap2)
517
+ if (!cores_info->wrappers3[coreidx] && (wrap3 != 0)) {
518
+ cores_info->wrappers3[coreidx] = REG_MAP(wrap3, SI_CORE_SIZE);
519
+ ASSERT(GOODREGS(cores_info->wrappers3[coreidx]));
520
+ }
521
+
522
+ if (use_wrapn == 2) {
523
+ sii->curwrap = cores_info->wrappers3[coreidx];
524
+ } else if (use_wrapn == 1) {
455525 sii->curwrap = cores_info->wrappers2[coreidx];
456
- else
526
+ } else {
457527 sii->curwrap = cores_info->wrappers[coreidx];
528
+ }
458529 break;
459530
460531 case PCI_BUS:
461
- /* point bar0 window */
462
- OSL_PCI_WRITE_CONFIG(sii->osh, PCI_BAR0_WIN, 4, addr);
532
+#ifdef BCM_BACKPLANE_TIMEOUT
533
+ /* No need to set the BAR0 if core is APB Bridge.
534
+ * This is to reduce 2 PCI writes while checkng for errlog
535
+ */
536
+ if (cores_info->coreid[coreidx] != APB_BRIDGE_CORE_ID)
537
+#endif /* BCM_BACKPLANE_TIMEOUT */
538
+ {
539
+ /* point bar0 window */
540
+ OSL_PCI_WRITE_CONFIG(sii->osh, PCI_BAR0_WIN, 4, addr);
541
+ }
542
+
463543 regs = sii->curmap;
464544 /* point bar0 2nd 4KB window to the primary wrapper */
465
- if (use_wrap2)
545
+ if (use_wrapn)
466546 wrap = wrap2;
467547 if (PCIE_GEN2(sii))
468548 OSL_PCI_WRITE_CONFIG(sii->osh, PCIE2_BAR0_WIN2, 4, wrap);
....@@ -474,7 +554,7 @@
474554 case SPI_BUS:
475555 case SDIO_BUS:
476556 sii->curmap = regs = (void *)((uintptr)addr);
477
- if (use_wrap2)
557
+ if (use_wrapn)
478558 sii->curwrap = (void *)((uintptr)wrap2);
479559 else
480560 sii->curwrap = (void *)((uintptr)wrap);
....@@ -494,16 +574,22 @@
494574 return regs;
495575 }
496576
497
-void *
577
+volatile void *
498578 ai_setcoreidx(si_t *sih, uint coreidx)
499579 {
500580 return _ai_setcoreidx(sih, coreidx, 0);
501581 }
502582
503
-void *
583
+volatile void *
504584 ai_setcoreidx_2ndwrap(si_t *sih, uint coreidx)
505585 {
506586 return _ai_setcoreidx(sih, coreidx, 1);
587
+}
588
+
589
+volatile void *
590
+ai_setcoreidx_3rdwrap(si_t *sih, uint coreidx)
591
+{
592
+ return _ai_setcoreidx(sih, coreidx, 2);
507593 }
508594
509595 void
....@@ -596,12 +682,20 @@
596682 int
597683 ai_numaddrspaces(si_t *sih)
598684 {
685
+
686
+ BCM_REFERENCE(sih);
687
+
599688 return 2;
600689 }
601690
602
-/* Return the address of the nth address space in the current core */
691
+/* Return the address of the nth address space in the current core
692
+ * Arguments:
693
+ * sih : Pointer to struct si_t
694
+ * spidx : slave port index
695
+ * baidx : base address index
696
+ */
603697 uint32
604
-ai_addrspace(si_t *sih, uint asidx)
698
+ai_addrspace(si_t *sih, uint spidx, uint baidx)
605699 {
606700 si_info_t *sii = SI_INFO(sih);
607701 si_cores_info_t *cores_info = (si_cores_info_t *)sii->cores_info;
....@@ -609,36 +703,53 @@
609703
610704 cidx = sii->curidx;
611705
612
- if (asidx == 0)
613
- return cores_info->coresba[cidx];
614
- else if (asidx == 1)
615
- return cores_info->coresba2[cidx];
616
- else {
617
- SI_ERROR(("%s: Need to parse the erom again to find addr space %d\n",
618
- __FUNCTION__, asidx));
619
- return 0;
706
+ if (spidx == CORE_SLAVE_PORT_0) {
707
+ if (baidx == CORE_BASE_ADDR_0)
708
+ return cores_info->coresba[cidx];
709
+ else if (baidx == CORE_BASE_ADDR_1)
710
+ return cores_info->coresba2[cidx];
620711 }
712
+ else if (spidx == CORE_SLAVE_PORT_1) {
713
+ if (baidx == CORE_BASE_ADDR_0)
714
+ return cores_info->csp2ba[cidx];
715
+ }
716
+
717
+ SI_ERROR(("%s: Need to parse the erom again to find %d base addr in %d slave port\n",
718
+ __FUNCTION__, baidx, spidx));
719
+
720
+ return 0;
721
+
621722 }
622723
623
-/* Return the size of the nth address space in the current core */
724
+/* Return the size of the nth address space in the current core
725
+* Arguments:
726
+* sih : Pointer to struct si_t
727
+* spidx : slave port index
728
+* baidx : base address index
729
+*/
624730 uint32
625
-ai_addrspacesize(si_t *sih, uint asidx)
731
+ai_addrspacesize(si_t *sih, uint spidx, uint baidx)
626732 {
627733 si_info_t *sii = SI_INFO(sih);
628734 si_cores_info_t *cores_info = (si_cores_info_t *)sii->cores_info;
629735 uint cidx;
630736
631737 cidx = sii->curidx;
632
-
633
- if (asidx == 0)
634
- return cores_info->coresba_size[cidx];
635
- else if (asidx == 1)
636
- return cores_info->coresba2_size[cidx];
637
- else {
638
- SI_ERROR(("%s: Need to parse the erom again to find addr space %d\n",
639
- __FUNCTION__, asidx));
640
- return 0;
738
+ if (spidx == CORE_SLAVE_PORT_0) {
739
+ if (baidx == CORE_BASE_ADDR_0)
740
+ return cores_info->coresba_size[cidx];
741
+ else if (baidx == CORE_BASE_ADDR_1)
742
+ return cores_info->coresba2_size[cidx];
641743 }
744
+ else if (spidx == CORE_SLAVE_PORT_1) {
745
+ if (baidx == CORE_BASE_ADDR_0)
746
+ return cores_info->csp2ba_size[cidx];
747
+ }
748
+
749
+ SI_ERROR(("%s: Need to parse the erom again to find %d base addr in %d slave port\n",
750
+ __FUNCTION__, baidx, spidx));
751
+
752
+ return 0;
642753 }
643754
644755 uint
....@@ -647,14 +758,6 @@
647758 si_info_t *sii = SI_INFO(sih);
648759 aidmp_t *ai;
649760
650
- if (BCM47162_DMP()) {
651
- SI_ERROR(("%s: Attempting to read MIPS DMP registers on 47162a0", __FUNCTION__));
652
- return sii->curidx;
653
- }
654
- if (BCM5357_DMP()) {
655
- SI_ERROR(("%s: Attempting to read USB20H DMP registers on 5357b0\n", __FUNCTION__));
656
- return sii->curidx;
657
- }
658761 if (BCM4707_DMP()) {
659762 SI_ERROR(("%s: Attempting to read CHIPCOMMONB DMP registers on 4707\n",
660763 __FUNCTION__));
....@@ -664,13 +767,6 @@
664767 SI_ERROR(("%s: Attempting to read DMP registers on 53573\n", __FUNCTION__));
665768 return sii->curidx;
666769 }
667
-#ifdef REROUTE_OOBINT
668
- if (PMU_DMP()) {
669
- SI_ERROR(("%s: Attempting to read PMU DMP registers\n",
670
- __FUNCTION__));
671
- return PMU_OOB_BIT;
672
- }
673
-#else
674770 if (PMU_DMP()) {
675771 uint idx, flag;
676772 idx = sii->curidx;
....@@ -679,7 +775,6 @@
679775 ai_setcoreidx(sih, idx);
680776 return flag;
681777 }
682
-#endif /* REROUTE_OOBINT */
683778
684779 ai = sii->curwrap;
685780 ASSERT(ai != NULL);
....@@ -693,26 +788,11 @@
693788 si_info_t *sii = SI_INFO(sih);
694789 aidmp_t *ai;
695790
696
- if (BCM47162_DMP()) {
697
- SI_ERROR(("%s: Attempting to read MIPS DMP registers on 47162a0", __FUNCTION__));
698
- return sii->curidx;
699
- }
700
- if (BCM5357_DMP()) {
701
- SI_ERROR(("%s: Attempting to read USB20H DMP registers on 5357b0\n", __FUNCTION__));
702
- return sii->curidx;
703
- }
704791 if (BCM4707_DMP()) {
705792 SI_ERROR(("%s: Attempting to read CHIPCOMMONB DMP registers on 4707\n",
706793 __FUNCTION__));
707794 return sii->curidx;
708795 }
709
-#ifdef REROUTE_OOBINT
710
- if (PMU_DMP()) {
711
- SI_ERROR(("%s: Attempting to read PMU DMP registers\n",
712
- __FUNCTION__));
713
- return PMU_OOB_BIT;
714
- }
715
-#endif /* REROUTE_OOBINT */
716796
717797 ai = sii->curwrap;
718798
....@@ -722,22 +802,24 @@
722802 void
723803 ai_setint(si_t *sih, int siflag)
724804 {
805
+ BCM_REFERENCE(sih);
806
+ BCM_REFERENCE(siflag);
807
+
725808 }
726809
727810 uint
728811 ai_wrap_reg(si_t *sih, uint32 offset, uint32 mask, uint32 val)
729812 {
730813 si_info_t *sii = SI_INFO(sih);
731
- uint32 *map = (uint32 *) sii->curwrap;
814
+ uint32 *addr = (uint32 *) ((uchar *)(sii->curwrap) + offset);
732815
733816 if (mask || val) {
734
- uint32 w = R_REG(sii->osh, map+(offset/4));
817
+ uint32 w = R_REG(sii->osh, addr);
735818 w &= ~mask;
736819 w |= val;
737
- W_REG(sii->osh, map+(offset/4), w);
820
+ W_REG(sii->osh, addr, w);
738821 }
739
-
740
- return (R_REG(sii->osh, map+(offset/4)));
822
+ return (R_REG(sii->osh, addr));
741823 }
742824
743825 uint
....@@ -758,9 +840,15 @@
758840 si_cores_info_t *cores_info = (si_cores_info_t *)sii->cores_info;
759841 uint32 cib;
760842
761
-
762843 cib = cores_info->cib[sii->curidx];
763
- return remap_corerev(sih, (cib & CIB_REV_MASK) >> CIB_REV_SHIFT);
844
+ return ((cib & CIB_REV_MASK) >> CIB_REV_SHIFT);
845
+}
846
+
847
+uint
848
+ai_corerev_minor(si_t *sih)
849
+{
850
+ return (ai_core_sflags(sih, 0, 0) >> SISF_MINORREV_D11_SHIFT) &
851
+ SISF_MINORREV_D11_MASK;
764852 }
765853
766854 bool
....@@ -788,13 +876,12 @@
788876 ai_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, uint val)
789877 {
790878 uint origidx = 0;
791
- uint32 *r = NULL;
879
+ volatile uint32 *r = NULL;
792880 uint w;
793881 uint intr_val = 0;
794882 bool fast = FALSE;
795883 si_info_t *sii = SI_INFO(sih);
796884 si_cores_info_t *cores_info = (si_cores_info_t *)sii->cores_info;
797
-
798885
799886 ASSERT(GOODIDX(coreidx));
800887 ASSERT(regoff < SI_CORE_SIZE);
....@@ -812,7 +899,7 @@
812899 SI_CORE_SIZE);
813900 ASSERT(GOODREGS(cores_info->regs[coreidx]));
814901 }
815
- r = (uint32 *)((uchar *)cores_info->regs[coreidx] + regoff);
902
+ r = (volatile uint32 *)((volatile uchar *)cores_info->regs[coreidx] + regoff);
816903 } else if (BUSTYPE(sih->bustype) == PCI_BUS) {
817904 /* If pci/pcie, we can get at pci/pcie regs and on newer cores to chipc */
818905
....@@ -820,17 +907,18 @@
820907 /* Chipc registers are mapped at 12KB */
821908
822909 fast = TRUE;
823
- r = (uint32 *)((char *)sii->curmap + PCI_16KB0_CCREGS_OFFSET + regoff);
910
+ r = (volatile uint32 *)((volatile char *)sii->curmap +
911
+ PCI_16KB0_CCREGS_OFFSET + regoff);
824912 } else if (sii->pub.buscoreidx == coreidx) {
825913 /* pci registers are at either in the last 2KB of an 8KB window
826914 * or, in pcie and pci rev 13 at 8KB
827915 */
828916 fast = TRUE;
829917 if (SI_FAST(sii))
830
- r = (uint32 *)((char *)sii->curmap +
918
+ r = (volatile uint32 *)((volatile char *)sii->curmap +
831919 PCI_16KB0_PCIREGS_OFFSET + regoff);
832920 else
833
- r = (uint32 *)((char *)sii->curmap +
921
+ r = (volatile uint32 *)((volatile char *)sii->curmap +
834922 ((regoff >= SBCONFIGOFF) ?
835923 PCI_BAR0_PCISBR_OFFSET : PCI_BAR0_PCIREGS_OFFSET) +
836924 regoff);
....@@ -844,7 +932,8 @@
844932 origidx = si_coreidx(&sii->pub);
845933
846934 /* switch core */
847
- r = (uint32*) ((uchar*) ai_setcoreidx(&sii->pub, coreidx) + regoff);
935
+ r = (volatile uint32*) ((volatile uchar*) ai_setcoreidx(&sii->pub, coreidx) +
936
+ regoff);
848937 }
849938 ASSERT(r != NULL);
850939
....@@ -869,6 +958,97 @@
869958 }
870959
871960 /*
961
+ * Switch to 'coreidx', issue a single arbitrary 32bit register mask&set operation,
962
+ * switch back to the original core, and return the new value.
963
+ *
964
+ * When using the silicon backplane, no fiddling with interrupts or core switches is needed.
965
+ *
966
+ * Also, when using pci/pcie, we can optimize away the core switching for pci registers
967
+ * and (on newer pci cores) chipcommon registers.
968
+ */
969
+uint
970
+ai_corereg_writeonly(si_t *sih, uint coreidx, uint regoff, uint mask, uint val)
971
+{
972
+ uint origidx = 0;
973
+ volatile uint32 *r = NULL;
974
+ uint w = 0;
975
+ uint intr_val = 0;
976
+ bool fast = FALSE;
977
+ si_info_t *sii = SI_INFO(sih);
978
+ si_cores_info_t *cores_info = (si_cores_info_t *)sii->cores_info;
979
+
980
+ ASSERT(GOODIDX(coreidx));
981
+ ASSERT(regoff < SI_CORE_SIZE);
982
+ ASSERT((val & ~mask) == 0);
983
+
984
+ if (coreidx >= SI_MAXCORES)
985
+ return 0;
986
+
987
+ if (BUSTYPE(sih->bustype) == SI_BUS) {
988
+ /* If internal bus, we can always get at everything */
989
+ fast = TRUE;
990
+ /* map if does not exist */
991
+ if (!cores_info->regs[coreidx]) {
992
+ cores_info->regs[coreidx] = REG_MAP(cores_info->coresba[coreidx],
993
+ SI_CORE_SIZE);
994
+ ASSERT(GOODREGS(cores_info->regs[coreidx]));
995
+ }
996
+ r = (volatile uint32 *)((volatile uchar *)cores_info->regs[coreidx] + regoff);
997
+ } else if (BUSTYPE(sih->bustype) == PCI_BUS) {
998
+ /* If pci/pcie, we can get at pci/pcie regs and on newer cores to chipc */
999
+
1000
+ if ((cores_info->coreid[coreidx] == CC_CORE_ID) && SI_FAST(sii)) {
1001
+ /* Chipc registers are mapped at 12KB */
1002
+
1003
+ fast = TRUE;
1004
+ r = (volatile uint32 *)((volatile char *)sii->curmap +
1005
+ PCI_16KB0_CCREGS_OFFSET + regoff);
1006
+ } else if (sii->pub.buscoreidx == coreidx) {
1007
+ /* pci registers are at either in the last 2KB of an 8KB window
1008
+ * or, in pcie and pci rev 13 at 8KB
1009
+ */
1010
+ fast = TRUE;
1011
+ if (SI_FAST(sii))
1012
+ r = (volatile uint32 *)((volatile char *)sii->curmap +
1013
+ PCI_16KB0_PCIREGS_OFFSET + regoff);
1014
+ else
1015
+ r = (volatile uint32 *)((volatile char *)sii->curmap +
1016
+ ((regoff >= SBCONFIGOFF) ?
1017
+ PCI_BAR0_PCISBR_OFFSET : PCI_BAR0_PCIREGS_OFFSET) +
1018
+ regoff);
1019
+ }
1020
+ }
1021
+
1022
+ if (!fast) {
1023
+ INTR_OFF(sii, intr_val);
1024
+
1025
+ /* save current core index */
1026
+ origidx = si_coreidx(&sii->pub);
1027
+
1028
+ /* switch core */
1029
+ r = (volatile uint32*) ((volatile uchar*) ai_setcoreidx(&sii->pub, coreidx) +
1030
+ regoff);
1031
+ }
1032
+ ASSERT(r != NULL);
1033
+
1034
+ /* mask and set */
1035
+ if (mask || val) {
1036
+ w = (R_REG(sii->osh, r) & ~mask) | val;
1037
+ W_REG(sii->osh, r, w);
1038
+ }
1039
+
1040
+ if (!fast) {
1041
+ /* restore core index */
1042
+ if (origidx != coreidx)
1043
+ ai_setcoreidx(&sii->pub, origidx);
1044
+
1045
+ INTR_RESTORE(sii, intr_val);
1046
+ }
1047
+
1048
+ return (w);
1049
+}
1050
+
1051
+/*
8721052 * If there is no need for fiddling with interrupts or core switches (typically silicon
8731053 * back plane registers, pci registers and chipcommon registers), this function
8741054 * returns the register offset on this core to a mapped address. This address can
....@@ -877,14 +1057,13 @@
8771057 * For accessing registers that would need a core switch, this function will return
8781058 * NULL.
8791059 */
880
-uint32 *
1060
+volatile uint32 *
8811061 ai_corereg_addr(si_t *sih, uint coreidx, uint regoff)
8821062 {
883
- uint32 *r = NULL;
1063
+ volatile uint32 *r = NULL;
8841064 bool fast = FALSE;
8851065 si_info_t *sii = SI_INFO(sih);
8861066 si_cores_info_t *cores_info = (si_cores_info_t *)sii->cores_info;
887
-
8881067
8891068 ASSERT(GOODIDX(coreidx));
8901069 ASSERT(regoff < SI_CORE_SIZE);
....@@ -901,7 +1080,7 @@
9011080 SI_CORE_SIZE);
9021081 ASSERT(GOODREGS(cores_info->regs[coreidx]));
9031082 }
904
- r = (uint32 *)((uchar *)cores_info->regs[coreidx] + regoff);
1083
+ r = (volatile uint32 *)((volatile uchar *)cores_info->regs[coreidx] + regoff);
9051084 } else if (BUSTYPE(sih->bustype) == PCI_BUS) {
9061085 /* If pci/pcie, we can get at pci/pcie regs and on newer cores to chipc */
9071086
....@@ -909,17 +1088,18 @@
9091088 /* Chipc registers are mapped at 12KB */
9101089
9111090 fast = TRUE;
912
- r = (uint32 *)((char *)sii->curmap + PCI_16KB0_CCREGS_OFFSET + regoff);
1091
+ r = (volatile uint32 *)((volatile char *)sii->curmap +
1092
+ PCI_16KB0_CCREGS_OFFSET + regoff);
9131093 } else if (sii->pub.buscoreidx == coreidx) {
9141094 /* pci registers are at either in the last 2KB of an 8KB window
9151095 * or, in pcie and pci rev 13 at 8KB
9161096 */
9171097 fast = TRUE;
9181098 if (SI_FAST(sii))
919
- r = (uint32 *)((char *)sii->curmap +
1099
+ r = (volatile uint32 *)((volatile char *)sii->curmap +
9201100 PCI_16KB0_PCIREGS_OFFSET + regoff);
9211101 else
922
- r = (uint32 *)((char *)sii->curmap +
1102
+ r = (volatile uint32 *)((volatile char *)sii->curmap +
9231103 ((regoff >= SBCONFIGOFF) ?
9241104 PCI_BAR0_PCISBR_OFFSET : PCI_BAR0_PCIREGS_OFFSET) +
9251105 regoff);
....@@ -928,7 +1108,7 @@
9281108
9291109 if (!fast) {
9301110 ASSERT(sii->curidx == coreidx);
931
- r = (uint32*) ((uchar*)sii->curmap + regoff);
1111
+ r = (volatile uint32*) ((volatile uchar*)sii->curmap + regoff);
9321112 }
9331113
9341114 return (r);
....@@ -942,13 +1122,13 @@
9421122 uint32 status;
9431123 aidmp_t *ai;
9441124
945
-
9461125 ASSERT(GOODREGS(sii->curwrap));
9471126 ai = sii->curwrap;
9481127
9491128 /* if core is already in reset, just return */
950
- if (R_REG(sii->osh, &ai->resetctrl) & AIRC_RESET)
1129
+ if (R_REG(sii->osh, &ai->resetctrl) & AIRC_RESET) {
9511130 return;
1131
+ }
9521132
9531133 /* ensure there are no pending backplane operations */
9541134 SPINWAIT(((status = R_REG(sii->osh, &ai->resetstatus)) != 0), 300);
....@@ -982,6 +1162,9 @@
9821162 _ai_core_reset(si_t *sih, uint32 bits, uint32 resetbits)
9831163 {
9841164 si_info_t *sii = SI_INFO(sih);
1165
+#if defined(UCM_CORRUPTION_WAR)
1166
+ si_cores_info_t *cores_info = (si_cores_info_t *)sii->cores_info;
1167
+#endif // endif
9851168 aidmp_t *ai;
9861169 volatile uint32 dummy;
9871170 uint loop_counter = 10;
....@@ -990,41 +1173,56 @@
9901173 ai = sii->curwrap;
9911174
9921175 /* ensure there are no pending backplane operations */
993
- SPINWAIT(((dummy = R_REG(sii->osh, &ai->resetstatus)) != 0), 300);
994
-
1176
+ SPINWAIT(((dummy = R_REG(sii->osh, &ai->resetstatus)) != 0), SPINWAIT_TIME_US);
9951177
9961178 /* put core into reset state */
9971179 W_REG(sii->osh, &ai->resetctrl, AIRC_RESET);
9981180 OSL_DELAY(10);
9991181
10001182 /* ensure there are no pending backplane operations */
1001
- SPINWAIT((R_REG(sii->osh, &ai->resetstatus) != 0), 300);
1183
+ SPINWAIT((R_REG(sii->osh, &ai->resetstatus) != 0), SPINWAIT_TIME_US);
10021184
10031185 W_REG(sii->osh, &ai->ioctrl, (bits | resetbits | SICF_FGC | SICF_CLOCK_EN));
10041186 dummy = R_REG(sii->osh, &ai->ioctrl);
10051187 BCM_REFERENCE(dummy);
1006
-
1188
+#ifdef UCM_CORRUPTION_WAR
1189
+ if (cores_info->coreid[sii->curidx] == D11_CORE_ID) {
1190
+ /* Reset FGC */
1191
+ OSL_DELAY(1);
1192
+ W_REG(sii->osh, &ai->ioctrl, (dummy & (~SICF_FGC)));
1193
+ }
1194
+#endif /* UCM_CORRUPTION_WAR */
10071195 /* ensure there are no pending backplane operations */
1008
- SPINWAIT(((dummy = R_REG(sii->osh, &ai->resetstatus)) != 0), 300);
1009
-
1196
+ SPINWAIT(((dummy = R_REG(sii->osh, &ai->resetstatus)) != 0), SPINWAIT_TIME_US);
10101197
10111198 while (R_REG(sii->osh, &ai->resetctrl) != 0 && --loop_counter != 0) {
10121199 /* ensure there are no pending backplane operations */
1013
- SPINWAIT(((dummy = R_REG(sii->osh, &ai->resetstatus)) != 0), 300);
1014
-
1200
+ SPINWAIT(((dummy = R_REG(sii->osh, &ai->resetstatus)) != 0), SPINWAIT_TIME_US);
10151201
10161202 /* take core out of reset */
10171203 W_REG(sii->osh, &ai->resetctrl, 0);
10181204
10191205 /* ensure there are no pending backplane operations */
1020
- SPINWAIT((R_REG(sii->osh, &ai->resetstatus) != 0), 300);
1206
+ SPINWAIT((R_REG(sii->osh, &ai->resetstatus) != 0), SPINWAIT_TIME_US);
10211207 }
10221208
1023
-
1209
+#ifdef UCM_CORRUPTION_WAR
1210
+ /* Pulse FGC after lifting Reset */
1211
+ W_REG(sii->osh, &ai->ioctrl, (bits | SICF_FGC | SICF_CLOCK_EN));
1212
+#else
10241213 W_REG(sii->osh, &ai->ioctrl, (bits | SICF_CLOCK_EN));
1214
+#endif /* UCM_CORRUPTION_WAR */
10251215 dummy = R_REG(sii->osh, &ai->ioctrl);
10261216 BCM_REFERENCE(dummy);
1217
+#ifdef UCM_CORRUPTION_WAR
1218
+ if (cores_info->coreid[sii->curidx] == D11_CORE_ID) {
1219
+ /* Reset FGC */
1220
+ OSL_DELAY(1);
1221
+ W_REG(sii->osh, &ai->ioctrl, (dummy & (~SICF_FGC)));
1222
+ }
1223
+#endif /* UCM_CORRUPTION_WAR */
10271224 OSL_DELAY(1);
1225
+
10281226 }
10291227
10301228 void
....@@ -1033,6 +1231,12 @@
10331231 si_info_t *sii = SI_INFO(sih);
10341232 si_cores_info_t *cores_info = (si_cores_info_t *)sii->cores_info;
10351233 uint idx = sii->curidx;
1234
+
1235
+ if (cores_info->wrapba3[idx] != 0) {
1236
+ ai_setcoreidx_3rdwrap(sih, idx);
1237
+ _ai_core_reset(sih, bits, resetbits);
1238
+ ai_setcoreidx(sih, idx);
1239
+ }
10361240
10371241 if (cores_info->wrapba2[idx] != 0) {
10381242 ai_setcoreidx_2ndwrap(sih, idx);
....@@ -1050,17 +1254,6 @@
10501254 aidmp_t *ai;
10511255 uint32 w;
10521256
1053
-
1054
- if (BCM47162_DMP()) {
1055
- SI_ERROR(("%s: Accessing MIPS DMP register (ioctrl) on 47162a0",
1056
- __FUNCTION__));
1057
- return;
1058
- }
1059
- if (BCM5357_DMP()) {
1060
- SI_ERROR(("%s: Accessing USB20H DMP register (ioctrl) on 5357\n",
1061
- __FUNCTION__));
1062
- return;
1063
- }
10641257 if (BCM4707_DMP()) {
10651258 SI_ERROR(("%s: Accessing CHIPCOMMONB DMP register (ioctrl) on 4707\n",
10661259 __FUNCTION__));
....@@ -1090,16 +1283,6 @@
10901283 aidmp_t *ai;
10911284 uint32 w;
10921285
1093
- if (BCM47162_DMP()) {
1094
- SI_ERROR(("%s: Accessing MIPS DMP register (ioctrl) on 47162a0",
1095
- __FUNCTION__));
1096
- return 0;
1097
- }
1098
- if (BCM5357_DMP()) {
1099
- SI_ERROR(("%s: Accessing USB20H DMP register (ioctrl) on 5357\n",
1100
- __FUNCTION__));
1101
- return 0;
1102
- }
11031286 if (BCM4707_DMP()) {
11041287 SI_ERROR(("%s: Accessing CHIPCOMMONB DMP register (ioctrl) on 4707\n",
11051288 __FUNCTION__));
....@@ -1131,16 +1314,6 @@
11311314 aidmp_t *ai;
11321315 uint32 w;
11331316
1134
- if (BCM47162_DMP()) {
1135
- SI_ERROR(("%s: Accessing MIPS DMP register (iostatus) on 47162a0",
1136
- __FUNCTION__));
1137
- return 0;
1138
- }
1139
- if (BCM5357_DMP()) {
1140
- SI_ERROR(("%s: Accessing USB20H DMP register (iostatus) on 5357\n",
1141
- __FUNCTION__));
1142
- return 0;
1143
- }
11441317 if (BCM4707_DMP()) {
11451318 SI_ERROR(("%s: Accessing CHIPCOMMONB DMP register (ioctrl) on 4707\n",
11461319 __FUNCTION__));
....@@ -1172,43 +1345,68 @@
11721345 ai_dumpregs(si_t *sih, struct bcmstrbuf *b)
11731346 {
11741347 si_info_t *sii = SI_INFO(sih);
1175
- si_cores_info_t *cores_info = (si_cores_info_t *)sii->cores_info;
11761348 osl_t *osh;
11771349 aidmp_t *ai;
11781350 uint i;
1351
+ uint32 prev_value = 0;
1352
+ axi_wrapper_t * axi_wrapper = sii->axi_wrapper;
1353
+ uint32 cfg_reg = 0;
1354
+ uint bar0_win_offset = 0;
11791355
11801356 osh = sii->osh;
11811357
1182
- for (i = 0; i < sii->numcores; i++) {
1183
- si_setcoreidx(&sii->pub, i);
1184
- ai = sii->curwrap;
1358
+ /* Save and restore wrapper access window */
1359
+ if (BUSTYPE(sii->pub.bustype) == PCI_BUS) {
1360
+ if (PCIE_GEN2(sii)) {
1361
+ cfg_reg = PCIE2_BAR0_CORE2_WIN2;
1362
+ bar0_win_offset = PCIE2_BAR0_CORE2_WIN2_OFFSET;
1363
+ } else {
1364
+ cfg_reg = PCI_BAR0_WIN2;
1365
+ bar0_win_offset = PCI_BAR0_WIN2_OFFSET;
1366
+ }
11851367
1186
- bcm_bprintf(b, "core 0x%x: \n", cores_info->coreid[i]);
1187
- if (BCM47162_DMP()) {
1188
- bcm_bprintf(b, "Skipping mips74k in 47162a0\n");
1189
- continue;
1368
+ prev_value = OSL_PCI_READ_CONFIG(osh, cfg_reg, 4);
1369
+
1370
+ if (prev_value == ID32_INVALID) {
1371
+ SI_PRINT(("%s, PCI_BAR0_WIN2 - %x\n", __FUNCTION__, prev_value));
1372
+ return;
11901373 }
1191
- if (BCM5357_DMP()) {
1192
- bcm_bprintf(b, "Skipping usb20h in 5357\n");
1193
- continue;
1374
+ }
1375
+
1376
+ bcm_bprintf(b, "ChipNum:%x, ChipRev;%x, BusType:%x, BoardType:%x, BoardVendor:%x\n\n",
1377
+ sih->chip, sih->chiprev, sih->bustype, sih->boardtype, sih->boardvendor);
1378
+
1379
+ for (i = 0; i < sii->axi_num_wrappers; i++) {
1380
+
1381
+ if (BUSTYPE(sii->pub.bustype) == PCI_BUS) {
1382
+ /* Set BAR0 window to bridge wapper base address */
1383
+ OSL_PCI_WRITE_CONFIG(osh,
1384
+ cfg_reg, 4, axi_wrapper[i].wrapper_addr);
1385
+
1386
+ ai = (aidmp_t *) ((volatile uint8*)sii->curmap + bar0_win_offset);
1387
+ } else {
1388
+ ai = (aidmp_t *)(uintptr) axi_wrapper[i].wrapper_addr;
11941389 }
1195
- if (BCM4707_DMP()) {
1390
+
1391
+ bcm_bprintf(b, "core 0x%x: core_rev:%d, %s_WR ADDR:%x \n", axi_wrapper[i].cid,
1392
+ axi_wrapper[i].rev,
1393
+ axi_wrapper[i].wrapper_type == AI_SLAVE_WRAPPER ? "SLAVE" : "MASTER",
1394
+ axi_wrapper[i].wrapper_addr);
1395
+
1396
+ /* BCM4707_DMP() */
1397
+ if (BCM4707_CHIP(CHIPID(sih->chip)) &&
1398
+ (axi_wrapper[i].cid == NS_CCB_CORE_ID)) {
11961399 bcm_bprintf(b, "Skipping chipcommonb in 4707\n");
11971400 continue;
11981401 }
11991402
1200
- if (PMU_DMP()) {
1201
- bcm_bprintf(b, "Skipping pmu core\n");
1202
- continue;
1203
- }
1204
-
1205
- bcm_bprintf(b, "ioctrlset 0x%x ioctrlclear 0x%x ioctrl 0x%x iostatus 0x%x"
1403
+ bcm_bprintf(b, "ioctrlset 0x%x ioctrlclear 0x%x ioctrl 0x%x iostatus 0x%x "
12061404 "ioctrlwidth 0x%x iostatuswidth 0x%x\n"
12071405 "resetctrl 0x%x resetstatus 0x%x resetreadid 0x%x resetwriteid 0x%x\n"
1208
- "errlogctrl 0x%x errlogdone 0x%x errlogstatus 0x%x"
1406
+ "errlogctrl 0x%x errlogdone 0x%x errlogstatus 0x%x "
12091407 "errlogaddrlo 0x%x errlogaddrhi 0x%x\n"
12101408 "errlogid 0x%x errloguser 0x%x errlogflags 0x%x\n"
1211
- "intstatus 0x%x config 0x%x itcr 0x%x\n",
1409
+ "intstatus 0x%x config 0x%x itcr 0x%x\n\n",
12121410 R_REG(osh, &ai->ioctrlset),
12131411 R_REG(osh, &ai->ioctrlclear),
12141412 R_REG(osh, &ai->ioctrl),
....@@ -1231,78 +1429,678 @@
12311429 R_REG(osh, &ai->config),
12321430 R_REG(osh, &ai->itcr));
12331431 }
1234
-}
1235
-#endif
12361432
1237
-
1238
-void
1239
-ai_enable_backplane_timeouts(si_t *sih)
1240
-{
1241
-#ifdef AXI_TIMEOUTS
1242
- si_info_t *sii = SI_INFO(sih);
1243
- aidmp_t *ai;
1244
- int i;
1245
-
1246
- for (i = 0; i < sii->num_br; ++i) {
1247
- ai = (aidmp_t *) sii->br_wrapba[i];
1248
- W_REG(sii->osh, &ai->errlogctrl, (1 << AIELC_TO_ENAB_SHIFT) |
1249
- ((AXI_TO_VAL << AIELC_TO_EXP_SHIFT) & AIELC_TO_EXP_MASK));
1250
- }
1251
-#endif /* AXI_TIMEOUTS */
1252
-}
1253
-
1254
-void
1255
-ai_clear_backplane_to(si_t *sih)
1256
-{
1257
-#ifdef AXI_TIMEOUTS
1258
- si_info_t *sii = SI_INFO(sih);
1259
- aidmp_t *ai;
1260
- int i;
1261
- uint32 errlogstatus;
1262
-
1263
- for (i = 0; i < sii->num_br; ++i) {
1264
- ai = (aidmp_t *) sii->br_wrapba[i];
1265
- /* check for backplane timeout & clear backplane hang */
1266
- errlogstatus = R_REG(sii->osh, &ai->errlogstatus);
1267
-
1268
- if ((errlogstatus & AIELS_TIMEOUT_MASK) != 0) {
1269
- /* set ErrDone to clear the condition */
1270
- W_REG(sii->osh, &ai->errlogdone, AIELD_ERRDONE_MASK);
1271
-
1272
- /* SPINWAIT on errlogstatus timeout status bits */
1273
- while (R_REG(sii->osh, &ai->errlogstatus) & AIELS_TIMEOUT_MASK)
1274
- ;
1275
-
1276
- /* only reset APB Bridge on timeout (not slave error, or dec error) */
1277
- switch (errlogstatus & AIELS_TIMEOUT_MASK) {
1278
- case 0x1:
1279
- printf("AXI slave error");
1280
- break;
1281
- case 0x2:
1282
- /* reset APB Bridge */
1283
- OR_REG(sii->osh, &ai->resetctrl, AIRC_RESET);
1284
- /* sync write */
1285
- (void)R_REG(sii->osh, &ai->resetctrl);
1286
- /* clear Reset bit */
1287
- AND_REG(sii->osh, &ai->resetctrl, ~(AIRC_RESET));
1288
- /* sync write */
1289
- (void)R_REG(sii->osh, &ai->resetctrl);
1290
- printf("AXI timeout");
1291
- break;
1292
- case 0x3:
1293
- printf("AXI decode error");
1294
- break;
1295
- default:
1296
- ; /* should be impossible */
1297
- }
1298
- printf("; APB Bridge %d\n", i);
1299
- printf("\t errlog: lo 0x%08x, hi 0x%08x, id 0x%08x, flags 0x%08x",
1300
- R_REG(sii->osh, &ai->errlogaddrlo),
1301
- R_REG(sii->osh, &ai->errlogaddrhi),
1302
- R_REG(sii->osh, &ai->errlogid),
1303
- R_REG(sii->osh, &ai->errlogflags));
1304
- printf(", status 0x%08x\n", errlogstatus);
1433
+ /* Restore the initial wrapper space */
1434
+ if (BUSTYPE(sii->pub.bustype) == PCI_BUS) {
1435
+ if (prev_value && cfg_reg) {
1436
+ OSL_PCI_WRITE_CONFIG(osh, cfg_reg, 4, prev_value);
13051437 }
13061438 }
1307
-#endif /* AXI_TIMEOUTS */
1439
+}
1440
+#endif // endif
1441
+
1442
+void
1443
+ai_update_backplane_timeouts(si_t *sih, bool enable, uint32 timeout_exp, uint32 cid)
1444
+{
1445
+#if defined(AXI_TIMEOUTS) || defined(BCM_BACKPLANE_TIMEOUT)
1446
+ si_info_t *sii = SI_INFO(sih);
1447
+ aidmp_t *ai;
1448
+ uint32 i;
1449
+ axi_wrapper_t * axi_wrapper = sii->axi_wrapper;
1450
+ uint32 errlogctrl = (enable << AIELC_TO_ENAB_SHIFT) |
1451
+ ((timeout_exp << AIELC_TO_EXP_SHIFT) & AIELC_TO_EXP_MASK);
1452
+
1453
+#ifdef BCM_BACKPLANE_TIMEOUT
1454
+ uint32 prev_value = 0;
1455
+ osl_t *osh = sii->osh;
1456
+ uint32 cfg_reg = 0;
1457
+ uint32 offset = 0;
1458
+#endif /* BCM_BACKPLANE_TIMEOUT */
1459
+
1460
+ if ((sii->axi_num_wrappers == 0) ||
1461
+#ifdef BCM_BACKPLANE_TIMEOUT
1462
+ (!PCIE(sii)) ||
1463
+#endif /* BCM_BACKPLANE_TIMEOUT */
1464
+ FALSE) {
1465
+ SI_VMSG((" %s, axi_num_wrappers:%d, Is_PCIE:%d, BUS_TYPE:%d, ID:%x\n",
1466
+ __FUNCTION__, sii->axi_num_wrappers, PCIE(sii),
1467
+ BUSTYPE(sii->pub.bustype), sii->pub.buscoretype));
1468
+ return;
1469
+ }
1470
+
1471
+#ifdef BCM_BACKPLANE_TIMEOUT
1472
+ /* Save and restore the wrapper access window */
1473
+ if (BUSTYPE(sii->pub.bustype) == PCI_BUS) {
1474
+ if (PCIE_GEN1(sii)) {
1475
+ cfg_reg = PCI_BAR0_WIN2;
1476
+ offset = PCI_BAR0_WIN2_OFFSET;
1477
+ } else if (PCIE_GEN2(sii)) {
1478
+ cfg_reg = PCIE2_BAR0_CORE2_WIN2;
1479
+ offset = PCIE2_BAR0_CORE2_WIN2_OFFSET;
1480
+ }
1481
+ else {
1482
+ ASSERT(!"!PCIE_GEN1 && !PCIE_GEN2");
1483
+ }
1484
+
1485
+ prev_value = OSL_PCI_READ_CONFIG(osh, cfg_reg, 4);
1486
+ if (prev_value == ID32_INVALID) {
1487
+ SI_PRINT(("%s, PCI_BAR0_WIN2 - %x\n", __FUNCTION__, prev_value));
1488
+ return;
1489
+ }
1490
+ }
1491
+#endif /* BCM_BACKPLANE_TIMEOUT */
1492
+
1493
+ for (i = 0; i < sii->axi_num_wrappers; ++i) {
1494
+
1495
+ if (axi_wrapper[i].wrapper_type != AI_SLAVE_WRAPPER) {
1496
+ SI_VMSG(("SKIP ENABLE BPT: MFG:%x, CID:%x, ADDR:%x\n",
1497
+ axi_wrapper[i].mfg,
1498
+ axi_wrapper[i].cid,
1499
+ axi_wrapper[i].wrapper_addr));
1500
+ continue;
1501
+ }
1502
+
1503
+ /* Update only given core if requested */
1504
+ if ((cid != 0) && (axi_wrapper[i].cid != cid)) {
1505
+ continue;
1506
+ }
1507
+
1508
+#ifdef BCM_BACKPLANE_TIMEOUT
1509
+ if (BUSTYPE(sii->pub.bustype) == PCI_BUS) {
1510
+ /* Set BAR0_CORE2_WIN2 to bridge wapper base address */
1511
+ OSL_PCI_WRITE_CONFIG(osh,
1512
+ cfg_reg, 4, axi_wrapper[i].wrapper_addr);
1513
+
1514
+ /* set AI to BAR0 + Offset corresponding to Gen1 or gen2 */
1515
+ ai = (aidmp_t *) (DISCARD_QUAL(sii->curmap, uint8) + offset);
1516
+ }
1517
+ else
1518
+#endif /* BCM_BACKPLANE_TIMEOUT */
1519
+ {
1520
+ ai = (aidmp_t *)(uintptr) axi_wrapper[i].wrapper_addr;
1521
+ }
1522
+
1523
+ W_REG(sii->osh, &ai->errlogctrl, errlogctrl);
1524
+
1525
+ SI_VMSG(("ENABLED BPT: MFG:%x, CID:%x, ADDR:%x, ERR_CTRL:%x\n",
1526
+ axi_wrapper[i].mfg,
1527
+ axi_wrapper[i].cid,
1528
+ axi_wrapper[i].wrapper_addr,
1529
+ R_REG(sii->osh, &ai->errlogctrl)));
1530
+ }
1531
+
1532
+#ifdef BCM_BACKPLANE_TIMEOUT
1533
+ /* Restore the initial wrapper space */
1534
+ if (prev_value) {
1535
+ OSL_PCI_WRITE_CONFIG(osh, cfg_reg, 4, prev_value);
1536
+ }
1537
+#endif /* BCM_BACKPLANE_TIMEOUT */
1538
+
1539
+#endif /* AXI_TIMEOUTS || BCM_BACKPLANE_TIMEOUT */
1540
+}
1541
+
1542
+#if defined(AXI_TIMEOUTS) || defined(BCM_BACKPLANE_TIMEOUT)
1543
+
1544
+/* slave error is ignored, so account for those cases */
1545
+static uint32 si_ignore_errlog_cnt = 0;
1546
+
1547
+static bool
1548
+ai_ignore_errlog(si_info_t *sii, aidmp_t *ai,
1549
+ uint32 lo_addr, uint32 hi_addr, uint32 err_axi_id, uint32 errsts)
1550
+{
1551
+ uint32 axi_id;
1552
+#ifdef BCMPCIE_BTLOG
1553
+ uint32 axi_id2 = BCM4347_UNUSED_AXI_ID;
1554
+#endif /* BCMPCIE_BTLOG */
1555
+ uint32 ignore_errsts = AIELS_SLAVE_ERR;
1556
+ uint32 ignore_hi = BT_CC_SPROM_BADREG_HI;
1557
+ uint32 ignore_lo = BT_CC_SPROM_BADREG_LO;
1558
+ uint32 ignore_size = BT_CC_SPROM_BADREG_SIZE;
1559
+
1560
+ /* ignore the BT slave errors if the errlog is to chipcommon addr 0x190 */
1561
+ switch (CHIPID(sii->pub.chip)) {
1562
+ case BCM4350_CHIP_ID:
1563
+ axi_id = BCM4350_BT_AXI_ID;
1564
+ break;
1565
+ case BCM4345_CHIP_ID:
1566
+ axi_id = BCM4345_BT_AXI_ID;
1567
+ break;
1568
+ case BCM4349_CHIP_GRPID:
1569
+ axi_id = BCM4349_BT_AXI_ID;
1570
+ break;
1571
+ case BCM4364_CHIP_ID:
1572
+ case BCM4373_CHIP_ID:
1573
+ axi_id = BCM4364_BT_AXI_ID;
1574
+ break;
1575
+#ifdef BCMPCIE_BTLOG
1576
+ case BCM4347_CHIP_ID:
1577
+ case BCM4357_CHIP_ID:
1578
+ axi_id = BCM4347_CC_AXI_ID;
1579
+ axi_id2 = BCM4347_PCIE_AXI_ID;
1580
+ ignore_errsts = AIELS_TIMEOUT;
1581
+ ignore_hi = BCM4347_BT_ADDR_HI;
1582
+ ignore_lo = BCM4347_BT_ADDR_LO;
1583
+ ignore_size = BCM4347_BT_SIZE;
1584
+ break;
1585
+#endif /* BCMPCIE_BTLOG */
1586
+
1587
+ default:
1588
+ return FALSE;
1589
+ }
1590
+
1591
+ /* AXI ID check */
1592
+ err_axi_id &= AI_ERRLOGID_AXI_ID_MASK;
1593
+ if (!(err_axi_id == axi_id ||
1594
+#ifdef BCMPCIE_BTLOG
1595
+ (axi_id2 != BCM4347_UNUSED_AXI_ID && err_axi_id == axi_id2)))
1596
+#else
1597
+ FALSE))
1598
+#endif /* BCMPCIE_BTLOG */
1599
+ return FALSE;
1600
+
1601
+ /* slave errors */
1602
+ if ((errsts & AIELS_TIMEOUT_MASK) != ignore_errsts)
1603
+ return FALSE;
1604
+
1605
+ /* address range check */
1606
+ if ((hi_addr != ignore_hi) ||
1607
+ (lo_addr < ignore_lo) || (lo_addr >= (ignore_lo + ignore_size)))
1608
+ return FALSE;
1609
+
1610
+#ifdef BCMPCIE_BTLOG
1611
+ if (ignore_errsts == AIELS_TIMEOUT) {
1612
+ /* reset AXI timeout */
1613
+ ai_reset_axi_to(sii, ai);
1614
+ }
1615
+#endif /* BCMPCIE_BTLOG */
1616
+
1617
+ return TRUE;
1618
+}
1619
+#endif /* defined (AXI_TIMEOUTS) || defined (BCM_BACKPLANE_TIMEOUT) */
1620
+
1621
+#ifdef BCM_BACKPLANE_TIMEOUT
1622
+
1623
+/* Function to return the APB bridge details corresponding to the core */
1624
+static bool
1625
+ai_get_apb_bridge(si_t * sih, uint32 coreidx, uint32 *apb_id, uint32 * apb_coreuinit)
1626
+{
1627
+ uint i;
1628
+ uint32 core_base, core_end;
1629
+ si_info_t *sii = SI_INFO(sih);
1630
+ static uint32 coreidx_cached = 0, apb_id_cached = 0, apb_coreunit_cached = 0;
1631
+ uint32 tmp_coreunit = 0;
1632
+ si_cores_info_t *cores_info = (si_cores_info_t *)sii->cores_info;
1633
+
1634
+ if (coreidx >= MIN(sii->numcores, SI_MAXCORES))
1635
+ return FALSE;
1636
+
1637
+ /* Most of the time apb bridge query will be for d11 core.
1638
+ * Maintain the last cache and return if found rather than iterating the table
1639
+ */
1640
+ if (coreidx_cached == coreidx) {
1641
+ *apb_id = apb_id_cached;
1642
+ *apb_coreuinit = apb_coreunit_cached;
1643
+ return TRUE;
1644
+ }
1645
+
1646
+ core_base = cores_info->coresba[coreidx];
1647
+ core_end = core_base + cores_info->coresba_size[coreidx];
1648
+
1649
+ for (i = 0; i < sii->numcores; i++) {
1650
+ if (cores_info->coreid[i] == APB_BRIDGE_ID) {
1651
+ uint32 apb_base;
1652
+ uint32 apb_end;
1653
+
1654
+ apb_base = cores_info->coresba[i];
1655
+ apb_end = apb_base + cores_info->coresba_size[i];
1656
+
1657
+ if ((core_base >= apb_base) &&
1658
+ (core_end <= apb_end)) {
1659
+ /* Current core is attached to this APB bridge */
1660
+ *apb_id = apb_id_cached = APB_BRIDGE_ID;
1661
+ *apb_coreuinit = apb_coreunit_cached = tmp_coreunit;
1662
+ coreidx_cached = coreidx;
1663
+ return TRUE;
1664
+ }
1665
+ /* Increment the coreunit */
1666
+ tmp_coreunit++;
1667
+ }
1668
+ }
1669
+
1670
+ return FALSE;
1671
+}
1672
+
1673
+uint32
1674
+ai_clear_backplane_to_fast(si_t *sih, void *addr)
1675
+{
1676
+ si_info_t *sii = SI_INFO(sih);
1677
+ volatile void *curmap = sii->curmap;
1678
+ bool core_reg = FALSE;
1679
+
1680
+ /* Use fast path only for core register access */
1681
+ if (((uintptr)addr >= (uintptr)curmap) &&
1682
+ ((uintptr)addr < ((uintptr)curmap + SI_CORE_SIZE))) {
1683
+ /* address being accessed is within current core reg map */
1684
+ core_reg = TRUE;
1685
+ }
1686
+
1687
+ if (core_reg) {
1688
+ uint32 apb_id, apb_coreuinit;
1689
+
1690
+ if (ai_get_apb_bridge(sih, si_coreidx(&sii->pub),
1691
+ &apb_id, &apb_coreuinit) == TRUE) {
1692
+ /* Found the APB bridge corresponding to current core,
1693
+ * Check for bus errors in APB wrapper
1694
+ */
1695
+ return ai_clear_backplane_to_per_core(sih,
1696
+ apb_id, apb_coreuinit, NULL);
1697
+ }
1698
+ }
1699
+
1700
+ /* Default is to poll for errors on all slave wrappers */
1701
+ return si_clear_backplane_to(sih);
1702
+}
1703
+#endif /* BCM_BACKPLANE_TIMEOUT */
1704
+
1705
+#if defined(AXI_TIMEOUTS) || defined(BCM_BACKPLANE_TIMEOUT)
1706
+static bool g_disable_backplane_logs = FALSE;
1707
+
1708
+#if defined(ETD)
1709
+static uint32 last_axi_error = AXI_WRAP_STS_NONE;
1710
+static uint32 last_axi_error_core = 0;
1711
+static uint32 last_axi_error_wrap = 0;
1712
+#endif /* ETD */
1713
+
1714
+/*
1715
+ * API to clear the back plane timeout per core.
1716
+ * Caller may passs optional wrapper address. If present this will be used as
1717
+ * the wrapper base address. If wrapper base address is provided then caller
1718
+ * must provide the coreid also.
1719
+ * If both coreid and wrapper is zero, then err status of current bridge
1720
+ * will be verified.
1721
+ */
1722
+uint32
1723
+ai_clear_backplane_to_per_core(si_t *sih, uint coreid, uint coreunit, void *wrap)
1724
+{
1725
+ int ret = AXI_WRAP_STS_NONE;
1726
+ aidmp_t *ai = NULL;
1727
+ uint32 errlog_status = 0;
1728
+ si_info_t *sii = SI_INFO(sih);
1729
+ uint32 errlog_lo = 0, errlog_hi = 0, errlog_id = 0, errlog_flags = 0;
1730
+ uint32 current_coreidx = si_coreidx(sih);
1731
+ uint32 target_coreidx = si_findcoreidx(sih, coreid, coreunit);
1732
+
1733
+#if defined(BCM_BACKPLANE_TIMEOUT)
1734
+ si_axi_error_t * axi_error = sih->err_info ?
1735
+ &sih->err_info->axi_error[sih->err_info->count] : NULL;
1736
+#endif /* BCM_BACKPLANE_TIMEOUT */
1737
+ bool restore_core = FALSE;
1738
+
1739
+ if ((sii->axi_num_wrappers == 0) ||
1740
+#ifdef BCM_BACKPLANE_TIMEOUT
1741
+ (!PCIE(sii)) ||
1742
+#endif /* BCM_BACKPLANE_TIMEOUT */
1743
+ FALSE) {
1744
+ SI_VMSG((" %s, axi_num_wrappers:%d, Is_PCIE:%d, BUS_TYPE:%d, ID:%x\n",
1745
+ __FUNCTION__, sii->axi_num_wrappers, PCIE(sii),
1746
+ BUSTYPE(sii->pub.bustype), sii->pub.buscoretype));
1747
+ return AXI_WRAP_STS_NONE;
1748
+ }
1749
+
1750
+ if (wrap != NULL) {
1751
+ ai = (aidmp_t *)wrap;
1752
+ } else if (coreid && (target_coreidx != current_coreidx)) {
1753
+
1754
+ if (ai_setcoreidx(sih, target_coreidx) == NULL) {
1755
+ /* Unable to set the core */
1756
+ SI_PRINT(("Set Code Failed: coreid:%x, unit:%d, target_coreidx:%d\n",
1757
+ coreid, coreunit, target_coreidx));
1758
+ errlog_lo = target_coreidx;
1759
+ ret = AXI_WRAP_STS_SET_CORE_FAIL;
1760
+ goto end;
1761
+ }
1762
+
1763
+ restore_core = TRUE;
1764
+ ai = (aidmp_t *)si_wrapperregs(sih);
1765
+ } else {
1766
+ /* Read error status of current wrapper */
1767
+ ai = (aidmp_t *)si_wrapperregs(sih);
1768
+
1769
+ /* Update CoreID to current Code ID */
1770
+ coreid = si_coreid(sih);
1771
+ }
1772
+
1773
+ /* read error log status */
1774
+ errlog_status = R_REG(sii->osh, &ai->errlogstatus);
1775
+
1776
+ if (errlog_status == ID32_INVALID) {
1777
+ /* Do not try to peek further */
1778
+ SI_PRINT(("%s, errlogstatus:%x - Slave Wrapper:%x\n",
1779
+ __FUNCTION__, errlog_status, coreid));
1780
+ ret = AXI_WRAP_STS_WRAP_RD_ERR;
1781
+ errlog_lo = (uint32)(uintptr)&ai->errlogstatus;
1782
+ goto end;
1783
+ }
1784
+
1785
+ if ((errlog_status & AIELS_TIMEOUT_MASK) != 0) {
1786
+ uint32 tmp;
1787
+ uint32 count = 0;
1788
+ /* set ErrDone to clear the condition */
1789
+ W_REG(sii->osh, &ai->errlogdone, AIELD_ERRDONE_MASK);
1790
+
1791
+ /* SPINWAIT on errlogstatus timeout status bits */
1792
+ while ((tmp = R_REG(sii->osh, &ai->errlogstatus)) & AIELS_TIMEOUT_MASK) {
1793
+
1794
+ if (tmp == ID32_INVALID) {
1795
+ SI_PRINT(("%s: prev errlogstatus:%x, errlogstatus:%x\n",
1796
+ __FUNCTION__, errlog_status, tmp));
1797
+ ret = AXI_WRAP_STS_WRAP_RD_ERR;
1798
+ errlog_lo = (uint32)(uintptr)&ai->errlogstatus;
1799
+ goto end;
1800
+ }
1801
+ /*
1802
+ * Clear again, to avoid getting stuck in the loop, if a new error
1803
+ * is logged after we cleared the first timeout
1804
+ */
1805
+ W_REG(sii->osh, &ai->errlogdone, AIELD_ERRDONE_MASK);
1806
+
1807
+ count++;
1808
+ OSL_DELAY(10);
1809
+ if ((10 * count) > AI_REG_READ_TIMEOUT) {
1810
+ errlog_status = tmp;
1811
+ break;
1812
+ }
1813
+ }
1814
+
1815
+ errlog_lo = R_REG(sii->osh, &ai->errlogaddrlo);
1816
+ errlog_hi = R_REG(sii->osh, &ai->errlogaddrhi);
1817
+ errlog_id = R_REG(sii->osh, &ai->errlogid);
1818
+ errlog_flags = R_REG(sii->osh, &ai->errlogflags);
1819
+
1820
+ /* we are already in the error path, so OK to check for the slave error */
1821
+ if (ai_ignore_errlog(sii, ai, errlog_lo, errlog_hi, errlog_id,
1822
+ errlog_status)) {
1823
+ si_ignore_errlog_cnt++;
1824
+ goto end;
1825
+ }
1826
+
1827
+ /* only reset APB Bridge on timeout (not slave error, or dec error) */
1828
+ switch (errlog_status & AIELS_TIMEOUT_MASK) {
1829
+ case AIELS_SLAVE_ERR:
1830
+ SI_PRINT(("AXI slave error\n"));
1831
+ ret = AXI_WRAP_STS_SLAVE_ERR;
1832
+ break;
1833
+
1834
+ case AIELS_TIMEOUT:
1835
+ ai_reset_axi_to(sii, ai);
1836
+ ret = AXI_WRAP_STS_TIMEOUT;
1837
+ break;
1838
+
1839
+ case AIELS_DECODE:
1840
+ SI_PRINT(("AXI decode error\n"));
1841
+ ret = AXI_WRAP_STS_DECODE_ERR;
1842
+ break;
1843
+ default:
1844
+ ASSERT(0); /* should be impossible */
1845
+ }
1846
+
1847
+ SI_PRINT(("\tCoreID: %x\n", coreid));
1848
+ SI_PRINT(("\t errlog: lo 0x%08x, hi 0x%08x, id 0x%08x, flags 0x%08x"
1849
+ ", status 0x%08x\n",
1850
+ errlog_lo, errlog_hi, errlog_id, errlog_flags,
1851
+ errlog_status));
1852
+ }
1853
+
1854
+end:
1855
+#if defined(ETD)
1856
+ if (ret != AXI_WRAP_STS_NONE) {
1857
+ last_axi_error = ret;
1858
+ last_axi_error_core = coreid;
1859
+ last_axi_error_wrap = (uint32)ai;
1860
+ }
1861
+#endif /* ETD */
1862
+
1863
+#if defined(BCM_BACKPLANE_TIMEOUT)
1864
+ if (axi_error && (ret != AXI_WRAP_STS_NONE)) {
1865
+ axi_error->error = ret;
1866
+ axi_error->coreid = coreid;
1867
+ axi_error->errlog_lo = errlog_lo;
1868
+ axi_error->errlog_hi = errlog_hi;
1869
+ axi_error->errlog_id = errlog_id;
1870
+ axi_error->errlog_flags = errlog_flags;
1871
+ axi_error->errlog_status = errlog_status;
1872
+ sih->err_info->count++;
1873
+
1874
+ if (sih->err_info->count == SI_MAX_ERRLOG_SIZE) {
1875
+ sih->err_info->count = SI_MAX_ERRLOG_SIZE - 1;
1876
+ SI_PRINT(("AXI Error log overflow\n"));
1877
+ }
1878
+ }
1879
+#endif /* BCM_BACKPLANE_TIMEOUT */
1880
+
1881
+ if (restore_core) {
1882
+ if (ai_setcoreidx(sih, current_coreidx) == NULL) {
1883
+ /* Unable to set the core */
1884
+ return ID32_INVALID;
1885
+ }
1886
+ }
1887
+
1888
+ return ret;
1889
+}
1890
+
1891
+/* reset AXI timeout */
1892
+static void
1893
+ai_reset_axi_to(si_info_t *sii, aidmp_t *ai)
1894
+{
1895
+ /* reset APB Bridge */
1896
+ OR_REG(sii->osh, &ai->resetctrl, AIRC_RESET);
1897
+ /* sync write */
1898
+ (void)R_REG(sii->osh, &ai->resetctrl);
1899
+ /* clear Reset bit */
1900
+ AND_REG(sii->osh, &ai->resetctrl, ~(AIRC_RESET));
1901
+ /* sync write */
1902
+ (void)R_REG(sii->osh, &ai->resetctrl);
1903
+ SI_PRINT(("AXI timeout\n"));
1904
+ if (R_REG(sii->osh, &ai->resetctrl) & AIRC_RESET) {
1905
+ SI_PRINT(("reset failed on wrapper %p\n", ai));
1906
+ g_disable_backplane_logs = TRUE;
1907
+ }
1908
+}
1909
+#endif /* AXI_TIMEOUTS || BCM_BACKPLANE_TIMEOUT */
1910
+
1911
+/*
1912
+ * This API polls all slave wrappers for errors and returns bit map of
1913
+ * all reported errors.
1914
+ * return - bit map of
1915
+ * AXI_WRAP_STS_NONE
1916
+ * AXI_WRAP_STS_TIMEOUT
1917
+ * AXI_WRAP_STS_SLAVE_ERR
1918
+ * AXI_WRAP_STS_DECODE_ERR
1919
+ * AXI_WRAP_STS_PCI_RD_ERR
1920
+ * AXI_WRAP_STS_WRAP_RD_ERR
1921
+ * AXI_WRAP_STS_SET_CORE_FAIL
1922
+ * On timeout detection, correspondign bridge will be reset to
1923
+ * unblock the bus.
1924
+ * Error reported in each wrapper can be retrieved using the API
1925
+ * si_get_axi_errlog_info()
1926
+ */
1927
+uint32
1928
+ai_clear_backplane_to(si_t *sih)
1929
+{
1930
+ uint32 ret = 0;
1931
+#if defined(AXI_TIMEOUTS) || defined(BCM_BACKPLANE_TIMEOUT)
1932
+
1933
+ si_info_t *sii = SI_INFO(sih);
1934
+ aidmp_t *ai;
1935
+ uint32 i;
1936
+ axi_wrapper_t * axi_wrapper = sii->axi_wrapper;
1937
+
1938
+#ifdef BCM_BACKPLANE_TIMEOUT
1939
+ uint32 prev_value = 0;
1940
+ osl_t *osh = sii->osh;
1941
+ uint32 cfg_reg = 0;
1942
+ uint32 offset = 0;
1943
+
1944
+ if ((sii->axi_num_wrappers == 0) || (!PCIE(sii)))
1945
+#else
1946
+ if (sii->axi_num_wrappers == 0)
1947
+#endif // endif
1948
+ {
1949
+ SI_VMSG((" %s, axi_num_wrappers:%d, Is_PCIE:%d, BUS_TYPE:%d, ID:%x\n",
1950
+ __FUNCTION__, sii->axi_num_wrappers, PCIE(sii),
1951
+ BUSTYPE(sii->pub.bustype), sii->pub.buscoretype));
1952
+ return AXI_WRAP_STS_NONE;
1953
+ }
1954
+
1955
+#ifdef BCM_BACKPLANE_TIMEOUT
1956
+ /* Save and restore wrapper access window */
1957
+ if (BUSTYPE(sii->pub.bustype) == PCI_BUS) {
1958
+ if (PCIE_GEN1(sii)) {
1959
+ cfg_reg = PCI_BAR0_WIN2;
1960
+ offset = PCI_BAR0_WIN2_OFFSET;
1961
+ } else if (PCIE_GEN2(sii)) {
1962
+ cfg_reg = PCIE2_BAR0_CORE2_WIN2;
1963
+ offset = PCIE2_BAR0_CORE2_WIN2_OFFSET;
1964
+ }
1965
+ else {
1966
+ ASSERT(!"!PCIE_GEN1 && !PCIE_GEN2");
1967
+ }
1968
+
1969
+ prev_value = OSL_PCI_READ_CONFIG(osh, cfg_reg, 4);
1970
+
1971
+ if (prev_value == ID32_INVALID) {
1972
+ si_axi_error_t * axi_error =
1973
+ sih->err_info ?
1974
+ &sih->err_info->axi_error[sih->err_info->count] :
1975
+ NULL;
1976
+
1977
+ SI_PRINT(("%s, PCI_BAR0_WIN2 - %x\n", __FUNCTION__, prev_value));
1978
+ if (axi_error) {
1979
+ axi_error->error = ret = AXI_WRAP_STS_PCI_RD_ERR;
1980
+ axi_error->errlog_lo = cfg_reg;
1981
+ sih->err_info->count++;
1982
+
1983
+ if (sih->err_info->count == SI_MAX_ERRLOG_SIZE) {
1984
+ sih->err_info->count = SI_MAX_ERRLOG_SIZE - 1;
1985
+ SI_PRINT(("AXI Error log overflow\n"));
1986
+ }
1987
+ }
1988
+
1989
+ return ret;
1990
+ }
1991
+ }
1992
+#endif /* BCM_BACKPLANE_TIMEOUT */
1993
+
1994
+ for (i = 0; i < sii->axi_num_wrappers; ++i) {
1995
+ uint32 tmp;
1996
+
1997
+ if (axi_wrapper[i].wrapper_type != AI_SLAVE_WRAPPER) {
1998
+ continue;
1999
+ }
2000
+
2001
+#ifdef BCM_BACKPLANE_TIMEOUT
2002
+ if (BUSTYPE(sii->pub.bustype) == PCI_BUS) {
2003
+ /* Set BAR0_CORE2_WIN2 to bridge wapper base address */
2004
+ OSL_PCI_WRITE_CONFIG(osh,
2005
+ cfg_reg, 4, axi_wrapper[i].wrapper_addr);
2006
+
2007
+ /* set AI to BAR0 + Offset corresponding to Gen1 or gen2 */
2008
+ ai = (aidmp_t *) (DISCARD_QUAL(sii->curmap, uint8) + offset);
2009
+ }
2010
+ else
2011
+#endif /* BCM_BACKPLANE_TIMEOUT */
2012
+ {
2013
+ ai = (aidmp_t *)(uintptr) axi_wrapper[i].wrapper_addr;
2014
+ }
2015
+
2016
+ tmp = ai_clear_backplane_to_per_core(sih, axi_wrapper[i].cid, 0,
2017
+ DISCARD_QUAL(ai, void));
2018
+
2019
+ ret |= tmp;
2020
+ }
2021
+
2022
+#ifdef BCM_BACKPLANE_TIMEOUT
2023
+ /* Restore the initial wrapper space */
2024
+ if (prev_value) {
2025
+ OSL_PCI_WRITE_CONFIG(osh, cfg_reg, 4, prev_value);
2026
+ }
2027
+#endif /* BCM_BACKPLANE_TIMEOUT */
2028
+
2029
+#endif /* AXI_TIMEOUTS || BCM_BACKPLANE_TIMEOUT */
2030
+
2031
+ return ret;
2032
+}
2033
+
2034
+uint
2035
+ai_num_slaveports(si_t *sih, uint coreidx)
2036
+{
2037
+ si_info_t *sii = SI_INFO(sih);
2038
+ si_cores_info_t *cores_info = (si_cores_info_t *)sii->cores_info;
2039
+ uint32 cib;
2040
+
2041
+ cib = cores_info->cib[coreidx];
2042
+ return ((cib & CIB_NSP_MASK) >> CIB_NSP_SHIFT);
2043
+}
2044
+
2045
+#ifdef UART_TRAP_DBG
2046
+void
2047
+ai_dump_APB_Bridge_registers(si_t *sih)
2048
+{
2049
+aidmp_t *ai;
2050
+si_info_t *sii = SI_INFO(sih);
2051
+
2052
+ ai = (aidmp_t *) sii->br_wrapba[0];
2053
+ printf("APB Bridge 0\n");
2054
+ printf("lo 0x%08x, hi 0x%08x, id 0x%08x, flags 0x%08x",
2055
+ R_REG(sii->osh, &ai->errlogaddrlo),
2056
+ R_REG(sii->osh, &ai->errlogaddrhi),
2057
+ R_REG(sii->osh, &ai->errlogid),
2058
+ R_REG(sii->osh, &ai->errlogflags));
2059
+ printf("\n status 0x%08x\n", R_REG(sii->osh, &ai->errlogstatus));
2060
+}
2061
+#endif /* UART_TRAP_DBG */
2062
+
2063
+void
2064
+ai_force_clocks(si_t *sih, uint clock_state)
2065
+{
2066
+
2067
+ si_info_t *sii = SI_INFO(sih);
2068
+ aidmp_t *ai, *ai_sec = NULL;
2069
+ volatile uint32 dummy;
2070
+ uint32 ioctrl;
2071
+ si_cores_info_t *cores_info = (si_cores_info_t *)sii->cores_info;
2072
+
2073
+ ASSERT(GOODREGS(sii->curwrap));
2074
+ ai = sii->curwrap;
2075
+ if (cores_info->wrapba2[sii->curidx])
2076
+ ai_sec = REG_MAP(cores_info->wrapba2[sii->curidx], SI_CORE_SIZE);
2077
+
2078
+ /* ensure there are no pending backplane operations */
2079
+ SPINWAIT((R_REG(sii->osh, &ai->resetstatus) != 0), 300);
2080
+
2081
+ if (clock_state == FORCE_CLK_ON) {
2082
+ ioctrl = R_REG(sii->osh, &ai->ioctrl);
2083
+ W_REG(sii->osh, &ai->ioctrl, (ioctrl | SICF_FGC));
2084
+ dummy = R_REG(sii->osh, &ai->ioctrl);
2085
+ BCM_REFERENCE(dummy);
2086
+ if (ai_sec) {
2087
+ ioctrl = R_REG(sii->osh, &ai_sec->ioctrl);
2088
+ W_REG(sii->osh, &ai_sec->ioctrl, (ioctrl | SICF_FGC));
2089
+ dummy = R_REG(sii->osh, &ai_sec->ioctrl);
2090
+ BCM_REFERENCE(dummy);
2091
+ }
2092
+ } else {
2093
+ ioctrl = R_REG(sii->osh, &ai->ioctrl);
2094
+ W_REG(sii->osh, &ai->ioctrl, (ioctrl & (~SICF_FGC)));
2095
+ dummy = R_REG(sii->osh, &ai->ioctrl);
2096
+ BCM_REFERENCE(dummy);
2097
+ if (ai_sec) {
2098
+ ioctrl = R_REG(sii->osh, &ai_sec->ioctrl);
2099
+ W_REG(sii->osh, &ai_sec->ioctrl, (ioctrl & (~SICF_FGC)));
2100
+ dummy = R_REG(sii->osh, &ai_sec->ioctrl);
2101
+ BCM_REFERENCE(dummy);
2102
+ }
2103
+ }
2104
+ /* ensure there are no pending backplane operations */
2105
+ SPINWAIT((R_REG(sii->osh, &ai->resetstatus) != 0), 300);
13082106 }