.. | .. |
---|
1 | | -/* SPDX-License-Identifier: GPL-2.0 */ |
---|
2 | 1 | /* |
---|
3 | 2 | * Misc utility routines for accessing chip-specific features |
---|
4 | 3 | * of the SiliconBackplane-based Broadcom chips. |
---|
5 | 4 | * |
---|
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 | + * |
---|
8 | 9 | * Unless you and Broadcom execute a separate written software license |
---|
9 | 10 | * agreement governing use of this software, this software is licensed to you |
---|
10 | 11 | * under the terms of the GNU General Public License version 2 (the "GPL"), |
---|
11 | 12 | * available at http://www.broadcom.com/licenses/GPLv2.php, with the |
---|
12 | 13 | * following added to such license: |
---|
13 | | - * |
---|
| 14 | + * |
---|
14 | 15 | * As a special exception, the copyright holders of this software give you |
---|
15 | 16 | * permission to link this software with independent modules, and to copy and |
---|
16 | 17 | * distribute the resulting executable under terms of your choice, provided that |
---|
.. | .. |
---|
18 | 19 | * the license of that module. An independent module is a module which is not |
---|
19 | 20 | * derived from this software. The special exception does not apply to any |
---|
20 | 21 | * modifications of the software. |
---|
21 | | - * |
---|
| 22 | + * |
---|
22 | 23 | * Notwithstanding the above, under no circumstances may you combine this |
---|
23 | 24 | * software in any way with any other Broadcom software provided under a license |
---|
24 | 25 | * other than the GPL, without Broadcom's express prior written consent. |
---|
.. | .. |
---|
26 | 27 | * |
---|
27 | 28 | * <<Broadcom-WL-IPTag/Open:>> |
---|
28 | 29 | * |
---|
29 | | - * $Id: sbutils.c 514727 2014-11-12 03:02:48Z $ |
---|
| 30 | + * $Id: sbutils.c 700323 2017-05-18 16:12:11Z $ |
---|
30 | 31 | */ |
---|
31 | 32 | |
---|
32 | 33 | #include <bcm_cfg.h> |
---|
.. | .. |
---|
43 | 44 | |
---|
44 | 45 | #include "siutils_priv.h" |
---|
45 | 46 | |
---|
46 | | - |
---|
47 | 47 | /* local prototypes */ |
---|
48 | 48 | static uint _sb_coreidx(si_info_t *sii, uint32 sba); |
---|
49 | | -static uint _sb_scan(si_info_t *sii, uint32 sba, void *regs, uint bus, uint32 sbba, |
---|
50 | | - uint ncores); |
---|
| 49 | +static uint _sb_scan(si_info_t *sii, uint32 sba, volatile void *regs, uint bus, uint32 sbba, |
---|
| 50 | + uint ncores, uint devid); |
---|
51 | 51 | static uint32 _sb_coresba(si_info_t *sii); |
---|
52 | | -static void *_sb_setcoreidx(si_info_t *sii, uint coreidx); |
---|
| 52 | +static volatile void *_sb_setcoreidx(si_info_t *sii, uint coreidx); |
---|
53 | 53 | #define SET_SBREG(sii, r, mask, val) \ |
---|
54 | 54 | W_SBREG((sii), (r), ((R_SBREG((sii), (r)) & ~(mask)) | (val))) |
---|
55 | | -#define REGS2SB(va) (sbconfig_t*) ((int8*)(va) + SBCONFIGOFF) |
---|
| 55 | +#define REGS2SB(va) (sbconfig_t*) ((volatile int8*)(va) + SBCONFIGOFF) |
---|
56 | 56 | |
---|
57 | 57 | /* sonicsrev */ |
---|
58 | 58 | #define SONICS_2_2 (SBIDL_RV_2_2 >> SBIDL_RV_SHIFT) |
---|
.. | .. |
---|
66 | 66 | static uint32 |
---|
67 | 67 | sb_read_sbreg(si_info_t *sii, volatile uint32 *sbr) |
---|
68 | 68 | { |
---|
69 | | - si_cores_info_t *cores_info = (si_cores_info_t *)sii->cores_info; |
---|
70 | 69 | uint8 tmp; |
---|
71 | 70 | uint32 val, intr_val = 0; |
---|
72 | | - |
---|
73 | 71 | |
---|
74 | 72 | /* |
---|
75 | 73 | * compact flash only has 11 bits address, while we needs 12 bits address. |
---|
.. | .. |
---|
98 | 96 | static void |
---|
99 | 97 | sb_write_sbreg(si_info_t *sii, volatile uint32 *sbr, uint32 v) |
---|
100 | 98 | { |
---|
101 | | - si_cores_info_t *cores_info = (si_cores_info_t *)sii->cores_info; |
---|
102 | 99 | uint8 tmp; |
---|
103 | 100 | volatile uint32 dummy; |
---|
104 | 101 | uint32 intr_val = 0; |
---|
105 | | - |
---|
106 | 102 | |
---|
107 | 103 | /* |
---|
108 | 104 | * compact flash only has 11 bits address, while we needs 12 bits address. |
---|
.. | .. |
---|
150 | 146 | sb_intflag(si_t *sih) |
---|
151 | 147 | { |
---|
152 | 148 | si_info_t *sii = SI_INFO(sih); |
---|
153 | | - si_cores_info_t *cores_info = (si_cores_info_t *)sii->cores_info; |
---|
154 | | - void *corereg; |
---|
| 149 | + volatile void *corereg; |
---|
155 | 150 | sbconfig_t *sb; |
---|
156 | 151 | uint origidx, intflag, intr_val = 0; |
---|
157 | 152 | |
---|
.. | .. |
---|
215 | 210 | { |
---|
216 | 211 | uint32 sbaddr; |
---|
217 | 212 | |
---|
218 | | - |
---|
219 | 213 | switch (BUSTYPE(sii->pub.bustype)) { |
---|
220 | 214 | case SI_BUS: { |
---|
221 | 215 | sbconfig_t *sb = REGS2SB(sii->curmap); |
---|
.. | .. |
---|
243 | 237 | case SDIO_BUS: |
---|
244 | 238 | sbaddr = (uint32)(uintptr)sii->curmap; |
---|
245 | 239 | break; |
---|
246 | | -#endif |
---|
247 | | - |
---|
| 240 | +#endif // endif |
---|
248 | 241 | |
---|
249 | 242 | default: |
---|
250 | 243 | sbaddr = BADCOREADDR; |
---|
.. | .. |
---|
377 | 370 | sb_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, uint val) |
---|
378 | 371 | { |
---|
379 | 372 | uint origidx = 0; |
---|
380 | | - uint32 *r = NULL; |
---|
| 373 | + volatile uint32 *r = NULL; |
---|
381 | 374 | uint w; |
---|
382 | 375 | uint intr_val = 0; |
---|
383 | 376 | bool fast = FALSE; |
---|
.. | .. |
---|
400 | 393 | SI_CORE_SIZE); |
---|
401 | 394 | ASSERT(GOODREGS(cores_info->regs[coreidx])); |
---|
402 | 395 | } |
---|
403 | | - r = (uint32 *)((uchar *)cores_info->regs[coreidx] + regoff); |
---|
| 396 | + r = (volatile uint32 *)((volatile uchar *)cores_info->regs[coreidx] + regoff); |
---|
404 | 397 | } else if (BUSTYPE(sii->pub.bustype) == PCI_BUS) { |
---|
405 | 398 | /* If pci/pcie, we can get at pci/pcie regs and on newer cores to chipc */ |
---|
406 | 399 | |
---|
.. | .. |
---|
408 | 401 | /* Chipc registers are mapped at 12KB */ |
---|
409 | 402 | |
---|
410 | 403 | fast = TRUE; |
---|
411 | | - r = (uint32 *)((char *)sii->curmap + PCI_16KB0_CCREGS_OFFSET + regoff); |
---|
| 404 | + r = (volatile uint32 *)((volatile char *)sii->curmap + |
---|
| 405 | + PCI_16KB0_CCREGS_OFFSET + regoff); |
---|
412 | 406 | } else if (sii->pub.buscoreidx == coreidx) { |
---|
413 | 407 | /* pci registers are at either in the last 2KB of an 8KB window |
---|
414 | 408 | * or, in pcie and pci rev 13 at 8KB |
---|
415 | 409 | */ |
---|
416 | 410 | fast = TRUE; |
---|
417 | 411 | if (SI_FAST(sii)) |
---|
418 | | - r = (uint32 *)((char *)sii->curmap + |
---|
| 412 | + r = (volatile uint32 *)((volatile char *)sii->curmap + |
---|
419 | 413 | PCI_16KB0_PCIREGS_OFFSET + regoff); |
---|
420 | 414 | else |
---|
421 | | - r = (uint32 *)((char *)sii->curmap + |
---|
| 415 | + r = (volatile uint32 *)((volatile char *)sii->curmap + |
---|
422 | 416 | ((regoff >= SBCONFIGOFF) ? |
---|
423 | 417 | PCI_BAR0_PCISBR_OFFSET : PCI_BAR0_PCIREGS_OFFSET) + |
---|
424 | 418 | regoff); |
---|
.. | .. |
---|
432 | 426 | origidx = si_coreidx(&sii->pub); |
---|
433 | 427 | |
---|
434 | 428 | /* switch core */ |
---|
435 | | - r = (uint32*) ((uchar*)sb_setcoreidx(&sii->pub, coreidx) + regoff); |
---|
| 429 | + r = (volatile uint32*) ((volatile uchar*)sb_setcoreidx(&sii->pub, coreidx) + |
---|
| 430 | + regoff); |
---|
436 | 431 | } |
---|
437 | 432 | ASSERT(r != NULL); |
---|
438 | 433 | |
---|
.. | .. |
---|
451 | 446 | if (regoff >= SBCONFIGOFF) |
---|
452 | 447 | w = R_SBREG(sii, r); |
---|
453 | 448 | else { |
---|
454 | | - if ((CHIPID(sii->pub.chip) == BCM5354_CHIP_ID) && |
---|
455 | | - (coreidx == SI_CC_IDX) && |
---|
456 | | - (regoff == OFFSETOF(chipcregs_t, watchdog))) { |
---|
457 | | - w = val; |
---|
458 | | - } else |
---|
459 | | - w = R_REG(sii->osh, r); |
---|
| 449 | + w = R_REG(sii->osh, r); |
---|
460 | 450 | } |
---|
461 | 451 | |
---|
462 | 452 | if (!fast) { |
---|
.. | .. |
---|
479 | 469 | * For accessing registers that would need a core switch, this function will return |
---|
480 | 470 | * NULL. |
---|
481 | 471 | */ |
---|
482 | | -uint32 * |
---|
| 472 | +volatile uint32 * |
---|
483 | 473 | sb_corereg_addr(si_t *sih, uint coreidx, uint regoff) |
---|
484 | 474 | { |
---|
485 | | - uint32 *r = NULL; |
---|
| 475 | + volatile uint32 *r = NULL; |
---|
486 | 476 | bool fast = FALSE; |
---|
487 | 477 | si_info_t *sii = SI_INFO(sih); |
---|
488 | 478 | si_cores_info_t *cores_info = (si_cores_info_t *)sii->cores_info; |
---|
.. | .. |
---|
502 | 492 | SI_CORE_SIZE); |
---|
503 | 493 | ASSERT(GOODREGS(cores_info->regs[coreidx])); |
---|
504 | 494 | } |
---|
505 | | - r = (uint32 *)((uchar *)cores_info->regs[coreidx] + regoff); |
---|
| 495 | + r = (volatile uint32 *)((volatile uchar *)cores_info->regs[coreidx] + regoff); |
---|
506 | 496 | } else if (BUSTYPE(sii->pub.bustype) == PCI_BUS) { |
---|
507 | 497 | /* If pci/pcie, we can get at pci/pcie regs and on newer cores to chipc */ |
---|
508 | 498 | |
---|
.. | .. |
---|
510 | 500 | /* Chipc registers are mapped at 12KB */ |
---|
511 | 501 | |
---|
512 | 502 | fast = TRUE; |
---|
513 | | - r = (uint32 *)((char *)sii->curmap + PCI_16KB0_CCREGS_OFFSET + regoff); |
---|
| 503 | + r = (volatile uint32 *)((volatile char *)sii->curmap + |
---|
| 504 | + PCI_16KB0_CCREGS_OFFSET + regoff); |
---|
514 | 505 | } else if (sii->pub.buscoreidx == coreidx) { |
---|
515 | 506 | /* pci registers are at either in the last 2KB of an 8KB window |
---|
516 | 507 | * or, in pcie and pci rev 13 at 8KB |
---|
517 | 508 | */ |
---|
518 | 509 | fast = TRUE; |
---|
519 | 510 | if (SI_FAST(sii)) |
---|
520 | | - r = (uint32 *)((char *)sii->curmap + |
---|
| 511 | + r = (volatile uint32 *)((volatile char *)sii->curmap + |
---|
521 | 512 | PCI_16KB0_PCIREGS_OFFSET + regoff); |
---|
522 | 513 | else |
---|
523 | | - r = (uint32 *)((char *)sii->curmap + |
---|
| 514 | + r = (volatile uint32 *)((volatile char *)sii->curmap + |
---|
524 | 515 | ((regoff >= SBCONFIGOFF) ? |
---|
525 | 516 | PCI_BAR0_PCISBR_OFFSET : PCI_BAR0_PCIREGS_OFFSET) + |
---|
526 | 517 | regoff); |
---|
.. | .. |
---|
542 | 533 | */ |
---|
543 | 534 | #define SB_MAXBUSES 2 |
---|
544 | 535 | static uint |
---|
545 | | -_sb_scan(si_info_t *sii, uint32 sba, void *regs, uint bus, uint32 sbba, uint numcores) |
---|
| 536 | +_sb_scan(si_info_t *sii, uint32 sba, volatile void *regs, uint bus, |
---|
| 537 | + uint32 sbba, uint numcores, uint devid) |
---|
546 | 538 | { |
---|
547 | 539 | uint next; |
---|
548 | 540 | uint ncc = 0; |
---|
.. | .. |
---|
588 | 580 | /* Older chips */ |
---|
589 | 581 | uint chip = CHIPID(sii->pub.chip); |
---|
590 | 582 | |
---|
591 | | - if (chip == BCM4306_CHIP_ID) /* < 4306c0 */ |
---|
592 | | - numcores = 6; |
---|
593 | | - else if (chip == BCM4704_CHIP_ID) |
---|
| 583 | + if (chip == BCM4704_CHIP_ID) |
---|
594 | 584 | numcores = 9; |
---|
595 | 585 | else if (chip == BCM5365_CHIP_ID) |
---|
596 | 586 | numcores = 7; |
---|
.. | .. |
---|
612 | 602 | |
---|
613 | 603 | sii->numcores = next + 1; |
---|
614 | 604 | |
---|
615 | | - if ((nsbba & 0xfff00000) != SI_ENUM_BASE) |
---|
| 605 | + if ((nsbba & 0xfff00000) != si_enum_base(devid)) |
---|
616 | 606 | continue; |
---|
617 | 607 | nsbba &= 0xfffff000; |
---|
618 | 608 | if (_sb_coreidx(sii, nsbba) != BADIDX) |
---|
619 | 609 | continue; |
---|
620 | 610 | |
---|
621 | 611 | nsbcc = (R_SBREG(sii, &sb->sbtmstatehigh) & 0x000f0000) >> 16; |
---|
622 | | - nsbcc = _sb_scan(sii, sba, regs, bus + 1, nsbba, nsbcc); |
---|
623 | | - if (sbba == SI_ENUM_BASE) |
---|
| 612 | + nsbcc = _sb_scan(sii, sba, regs, bus + 1, nsbba, nsbcc, devid); |
---|
| 613 | + if (sbba == si_enum_base(devid)) |
---|
624 | 614 | numcores -= nsbcc; |
---|
625 | 615 | ncc += nsbcc; |
---|
626 | 616 | } |
---|
.. | .. |
---|
634 | 624 | |
---|
635 | 625 | /* scan the sb enumerated space to identify all cores */ |
---|
636 | 626 | void |
---|
637 | | -sb_scan(si_t *sih, void *regs, uint devid) |
---|
| 627 | +sb_scan(si_t *sih, volatile void *regs, uint devid) |
---|
638 | 628 | { |
---|
639 | 629 | uint32 origsba; |
---|
640 | 630 | sbconfig_t *sb; |
---|
641 | 631 | si_info_t *sii = SI_INFO(sih); |
---|
| 632 | + BCM_REFERENCE(devid); |
---|
642 | 633 | |
---|
643 | 634 | sb = REGS2SB(sii->curmap); |
---|
644 | 635 | |
---|
.. | .. |
---|
649 | 640 | */ |
---|
650 | 641 | origsba = _sb_coresba(sii); |
---|
651 | 642 | |
---|
652 | | - /* scan all SB(s) starting from SI_ENUM_BASE */ |
---|
653 | | - sii->numcores = _sb_scan(sii, origsba, regs, 0, SI_ENUM_BASE, 1); |
---|
| 643 | + /* scan all SB(s) starting from SI_ENUM_BASE_DEFAULT */ |
---|
| 644 | + sii->numcores = _sb_scan(sii, origsba, regs, 0, si_enum_base(devid), 1, devid); |
---|
654 | 645 | } |
---|
655 | 646 | |
---|
656 | 647 | /* |
---|
.. | .. |
---|
658 | 649 | * must be called with interrupts off. |
---|
659 | 650 | * Moreover, callers should keep interrupts off during switching out of and back to d11 core |
---|
660 | 651 | */ |
---|
661 | | -void * |
---|
| 652 | +volatile void * |
---|
662 | 653 | sb_setcoreidx(si_t *sih, uint coreidx) |
---|
663 | 654 | { |
---|
664 | 655 | si_info_t *sii = SI_INFO(sih); |
---|
.. | .. |
---|
681 | 672 | /* This function changes the logical "focus" to the indicated core. |
---|
682 | 673 | * Return the current core's virtual address. |
---|
683 | 674 | */ |
---|
684 | | -static void * |
---|
| 675 | +static volatile void * |
---|
685 | 676 | _sb_setcoreidx(si_info_t *sii, uint coreidx) |
---|
686 | 677 | { |
---|
687 | 678 | si_cores_info_t *cores_info = (si_cores_info_t *)sii->cores_info; |
---|
688 | 679 | uint32 sbaddr = cores_info->coresba[coreidx]; |
---|
689 | | - void *regs; |
---|
| 680 | + volatile void *regs; |
---|
690 | 681 | |
---|
691 | 682 | switch (BUSTYPE(sii->pub.bustype)) { |
---|
692 | 683 | case SI_BUS: |
---|
.. | .. |
---|
725 | 716 | regs = cores_info->regs[coreidx]; |
---|
726 | 717 | break; |
---|
727 | 718 | #endif /* BCMSDIO */ |
---|
728 | | - |
---|
729 | 719 | |
---|
730 | 720 | default: |
---|
731 | 721 | ASSERT(0); |
---|
.. | .. |
---|
806 | 796 | return (sb_size(R_SBREG(sii, sb_admatch(sii, asidx)))); |
---|
807 | 797 | } |
---|
808 | 798 | |
---|
809 | | - |
---|
810 | 799 | /* do buffered registers update */ |
---|
811 | 800 | void |
---|
812 | 801 | sb_commit(si_t *sih) |
---|
813 | 802 | { |
---|
814 | 803 | si_info_t *sii = SI_INFO(sih); |
---|
815 | | - si_cores_info_t *cores_info = (si_cores_info_t *)sii->cores_info; |
---|
816 | 804 | uint origidx; |
---|
817 | 805 | uint intr_val = 0; |
---|
818 | 806 | |
---|
.. | .. |
---|
974 | 962 | sb_set_initiator_to(si_t *sih, uint32 to, uint idx) |
---|
975 | 963 | { |
---|
976 | 964 | si_info_t *sii = SI_INFO(sih); |
---|
977 | | - si_cores_info_t *cores_info = (si_cores_info_t *)sii->cores_info; |
---|
978 | 965 | uint origidx; |
---|
979 | 966 | uint intr_val = 0; |
---|
980 | 967 | uint32 tmp, ret = 0xffffffff; |
---|
981 | 968 | sbconfig_t *sb; |
---|
982 | | - |
---|
983 | 969 | |
---|
984 | 970 | if ((to & ~TO_MASK) != 0) |
---|
985 | 971 | return ret; |
---|
.. | .. |
---|
996 | 982 | case PCMCIA_BUS: |
---|
997 | 983 | #ifdef BCMSDIO |
---|
998 | 984 | case SDIO_BUS: |
---|
999 | | -#endif |
---|
| 985 | +#endif // endif |
---|
1000 | 986 | idx = si_findcoreidx(sih, PCMCIA_CORE_ID, 0); |
---|
1001 | 987 | break; |
---|
1002 | 988 | case SI_BUS: |
---|
.. | .. |
---|
1106 | 1092 | sb_setcoreidx(sih, origidx); |
---|
1107 | 1093 | INTR_RESTORE(sii, intr_val); |
---|
1108 | 1094 | } |
---|
1109 | | -#endif |
---|
| 1095 | +#endif // endif |
---|