| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: ISC |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Copyright (c) 2014 Broadcom Corporation |
|---|
| 3 | | - * |
|---|
| 4 | | - * Permission to use, copy, modify, and/or distribute this software for any |
|---|
| 5 | | - * purpose with or without fee is hereby granted, provided that the above |
|---|
| 6 | | - * copyright notice and this permission notice appear in all copies. |
|---|
| 7 | | - * |
|---|
| 8 | | - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
|---|
| 9 | | - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
|---|
| 10 | | - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY |
|---|
| 11 | | - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
|---|
| 12 | | - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION |
|---|
| 13 | | - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN |
|---|
| 14 | | - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
|---|
| 15 | 4 | */ |
|---|
| 16 | 5 | #include <linux/kernel.h> |
|---|
| 17 | 6 | #include <linux/delay.h> |
|---|
| .. | .. |
|---|
| 165 | 154 | #define SRCI_LSS_MASK 0x00f00000 |
|---|
| 166 | 155 | #define SRCI_LSS_SHIFT 20 |
|---|
| 167 | 156 | #define SRCI_SRNB_MASK 0xf0 |
|---|
| 157 | +#define SRCI_SRNB_MASK_EXT 0x100 |
|---|
| 168 | 158 | #define SRCI_SRNB_SHIFT 4 |
|---|
| 169 | 159 | #define SRCI_SRBSZ_MASK 0xf |
|---|
| 170 | 160 | #define SRCI_SRBSZ_SHIFT 0 |
|---|
| .. | .. |
|---|
| 443 | 433 | { |
|---|
| 444 | 434 | struct brcmf_chip_priv *ci; |
|---|
| 445 | 435 | int count; |
|---|
| 436 | + struct brcmf_core *d11core2 = NULL; |
|---|
| 437 | + struct brcmf_core_priv *d11priv2 = NULL; |
|---|
| 446 | 438 | |
|---|
| 447 | 439 | ci = core->chip; |
|---|
| 448 | 440 | |
|---|
| 441 | + /* special handle two D11 cores reset */ |
|---|
| 442 | + if (core->pub.id == BCMA_CORE_80211) { |
|---|
| 443 | + d11core2 = brcmf_chip_get_d11core(&ci->pub, 1); |
|---|
| 444 | + if (d11core2) { |
|---|
| 445 | + brcmf_dbg(INFO, "found two d11 cores, reset both\n"); |
|---|
| 446 | + d11priv2 = container_of(d11core2, |
|---|
| 447 | + struct brcmf_core_priv, pub); |
|---|
| 448 | + } |
|---|
| 449 | + } |
|---|
| 450 | + |
|---|
| 449 | 451 | /* must disable first to work for arbitrary current core state */ |
|---|
| 450 | 452 | brcmf_chip_ai_coredisable(core, prereset, reset); |
|---|
| 453 | + if (d11priv2) |
|---|
| 454 | + brcmf_chip_ai_coredisable(d11priv2, prereset, reset); |
|---|
| 451 | 455 | |
|---|
| 452 | 456 | count = 0; |
|---|
| 453 | 457 | while (ci->ops->read32(ci->ctx, core->wrapbase + BCMA_RESET_CTL) & |
|---|
| .. | .. |
|---|
| 459 | 463 | usleep_range(40, 60); |
|---|
| 460 | 464 | } |
|---|
| 461 | 465 | |
|---|
| 466 | + if (d11priv2) { |
|---|
| 467 | + count = 0; |
|---|
| 468 | + while (ci->ops->read32(ci->ctx, |
|---|
| 469 | + d11priv2->wrapbase + BCMA_RESET_CTL) & |
|---|
| 470 | + BCMA_RESET_CTL_RESET) { |
|---|
| 471 | + ci->ops->write32(ci->ctx, |
|---|
| 472 | + d11priv2->wrapbase + BCMA_RESET_CTL, |
|---|
| 473 | + 0); |
|---|
| 474 | + count++; |
|---|
| 475 | + if (count > 50) |
|---|
| 476 | + break; |
|---|
| 477 | + usleep_range(40, 60); |
|---|
| 478 | + } |
|---|
| 479 | + } |
|---|
| 480 | + |
|---|
| 462 | 481 | ci->ops->write32(ci->ctx, core->wrapbase + BCMA_IOCTL, |
|---|
| 463 | 482 | postreset | BCMA_IOCTL_CLK); |
|---|
| 464 | 483 | ci->ops->read32(ci->ctx, core->wrapbase + BCMA_IOCTL); |
|---|
| 484 | + |
|---|
| 485 | + if (d11priv2) { |
|---|
| 486 | + ci->ops->write32(ci->ctx, d11priv2->wrapbase + BCMA_IOCTL, |
|---|
| 487 | + postreset | BCMA_IOCTL_CLK); |
|---|
| 488 | + ci->ops->read32(ci->ctx, d11priv2->wrapbase + BCMA_IOCTL); |
|---|
| 489 | + } |
|---|
| 465 | 490 | } |
|---|
| 466 | 491 | |
|---|
| 467 | 492 | char *brcmf_chip_name(u32 id, u32 rev, char *buf, uint len) |
|---|
| .. | .. |
|---|
| 592 | 617 | if (lss != 0) |
|---|
| 593 | 618 | *ramsize += (1 << ((lss - 1) + SR_BSZ_BASE)); |
|---|
| 594 | 619 | } else { |
|---|
| 595 | | - nb = (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT; |
|---|
| 620 | + /* length of SRAM Banks increased for corerev greater than 23 */ |
|---|
| 621 | + if (sr->pub.rev >= 23) { |
|---|
| 622 | + nb = (coreinfo & (SRCI_SRNB_MASK | SRCI_SRNB_MASK_EXT)) |
|---|
| 623 | + >> SRCI_SRNB_SHIFT; |
|---|
| 624 | + } else { |
|---|
| 625 | + nb = (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT; |
|---|
| 626 | + } |
|---|
| 596 | 627 | for (i = 0; i < nb; i++) { |
|---|
| 597 | 628 | retent = brcmf_chip_socram_banksize(sr, i, &banksize); |
|---|
| 598 | 629 | *ramsize += banksize; |
|---|
| .. | .. |
|---|
| 681 | 712 | case BRCM_CC_43569_CHIP_ID: |
|---|
| 682 | 713 | case BRCM_CC_43570_CHIP_ID: |
|---|
| 683 | 714 | case BRCM_CC_4358_CHIP_ID: |
|---|
| 684 | | - case BRCM_CC_4359_CHIP_ID: |
|---|
| 685 | 715 | case BRCM_CC_43602_CHIP_ID: |
|---|
| 686 | 716 | case BRCM_CC_4371_CHIP_ID: |
|---|
| 687 | 717 | return 0x180000; |
|---|
| .. | .. |
|---|
| 691 | 721 | case BRCM_CC_4366_CHIP_ID: |
|---|
| 692 | 722 | case BRCM_CC_43664_CHIP_ID: |
|---|
| 693 | 723 | return 0x200000; |
|---|
| 724 | + case BRCM_CC_4359_CHIP_ID: |
|---|
| 725 | + return (ci->pub.chiprev < 9) ? 0x180000 : 0x160000; |
|---|
| 726 | + case BRCM_CC_4364_CHIP_ID: |
|---|
| 694 | 727 | case CY_CC_4373_CHIP_ID: |
|---|
| 695 | 728 | return 0x160000; |
|---|
| 696 | 729 | default: |
|---|
| .. | .. |
|---|
| 700 | 733 | return 0; |
|---|
| 701 | 734 | } |
|---|
| 702 | 735 | |
|---|
| 703 | | -static int brcmf_chip_get_raminfo(struct brcmf_chip_priv *ci) |
|---|
| 736 | +int brcmf_chip_get_raminfo(struct brcmf_chip *pub) |
|---|
| 704 | 737 | { |
|---|
| 738 | + struct brcmf_chip_priv *ci = container_of(pub, struct brcmf_chip_priv, |
|---|
| 739 | + pub); |
|---|
| 705 | 740 | struct brcmf_core_priv *mem_core; |
|---|
| 706 | 741 | struct brcmf_core *mem; |
|---|
| 707 | 742 | |
|---|
| .. | .. |
|---|
| 779 | 814 | u32 *regbase, u32 *wrapbase) |
|---|
| 780 | 815 | { |
|---|
| 781 | 816 | u8 desc; |
|---|
| 782 | | - u32 val; |
|---|
| 783 | | - u8 mpnum = 0; |
|---|
| 817 | + u32 val, szdesc; |
|---|
| 784 | 818 | u8 stype, sztype, wraptype; |
|---|
| 785 | 819 | |
|---|
| 786 | 820 | *regbase = 0; |
|---|
| .. | .. |
|---|
| 788 | 822 | |
|---|
| 789 | 823 | val = brcmf_chip_dmp_get_desc(ci, eromaddr, &desc); |
|---|
| 790 | 824 | if (desc == DMP_DESC_MASTER_PORT) { |
|---|
| 791 | | - mpnum = (val & DMP_MASTER_PORT_NUM) >> DMP_MASTER_PORT_NUM_S; |
|---|
| 792 | 825 | wraptype = DMP_SLAVE_TYPE_MWRAP; |
|---|
| 793 | 826 | } else if (desc == DMP_DESC_ADDRESS) { |
|---|
| 794 | 827 | /* revert erom address */ |
|---|
| .. | .. |
|---|
| 825 | 858 | |
|---|
| 826 | 859 | /* next size descriptor can be skipped */ |
|---|
| 827 | 860 | if (sztype == DMP_SLAVE_SIZE_DESC) { |
|---|
| 828 | | - val = brcmf_chip_dmp_get_desc(ci, eromaddr, NULL); |
|---|
| 861 | + szdesc = brcmf_chip_dmp_get_desc(ci, eromaddr, NULL); |
|---|
| 829 | 862 | /* skip upper size descriptor if present */ |
|---|
| 830 | | - if (val & DMP_DESC_ADDRSIZE_GT32) |
|---|
| 863 | + if (szdesc & DMP_DESC_ADDRSIZE_GT32) |
|---|
| 831 | 864 | brcmf_chip_dmp_get_desc(ci, eromaddr, NULL); |
|---|
| 832 | 865 | } |
|---|
| 833 | 866 | |
|---|
| 834 | | - /* only look for 4K register regions */ |
|---|
| 835 | | - if (sztype != DMP_SLAVE_SIZE_4K) |
|---|
| 867 | + /* look for 4K or 8K register regions */ |
|---|
| 868 | + if (sztype != DMP_SLAVE_SIZE_4K && |
|---|
| 869 | + sztype != DMP_SLAVE_SIZE_8K) |
|---|
| 836 | 870 | continue; |
|---|
| 837 | 871 | |
|---|
| 838 | 872 | stype = (val & DMP_SLAVE_TYPE) >> DMP_SLAVE_TYPE_S; |
|---|
| .. | .. |
|---|
| 855 | 889 | u8 desc_type = 0; |
|---|
| 856 | 890 | u32 val; |
|---|
| 857 | 891 | u16 id; |
|---|
| 858 | | - u8 nmp, nsp, nmw, nsw, rev; |
|---|
| 892 | + u8 nmw, nsw, rev; |
|---|
| 859 | 893 | u32 base, wrap; |
|---|
| 860 | 894 | int err; |
|---|
| 861 | 895 | |
|---|
| .. | .. |
|---|
| 881 | 915 | return -EFAULT; |
|---|
| 882 | 916 | |
|---|
| 883 | 917 | /* only look at cores with master port(s) */ |
|---|
| 884 | | - nmp = (val & DMP_COMP_NUM_MPORT) >> DMP_COMP_NUM_MPORT_S; |
|---|
| 885 | | - nsp = (val & DMP_COMP_NUM_SPORT) >> DMP_COMP_NUM_SPORT_S; |
|---|
| 886 | 918 | nmw = (val & DMP_COMP_NUM_MWRAP) >> DMP_COMP_NUM_MWRAP_S; |
|---|
| 887 | 919 | nsw = (val & DMP_COMP_NUM_SWRAP) >> DMP_COMP_NUM_SWRAP_S; |
|---|
| 888 | 920 | rev = (val & DMP_COMP_REVISION) >> DMP_COMP_REVISION_S; |
|---|
| 889 | 921 | |
|---|
| 890 | 922 | /* need core with ports */ |
|---|
| 891 | 923 | if (nmw + nsw == 0 && |
|---|
| 892 | | - id != BCMA_CORE_PMU) |
|---|
| 924 | + id != BCMA_CORE_PMU && |
|---|
| 925 | + id != BCMA_CORE_GCI) |
|---|
| 893 | 926 | continue; |
|---|
| 894 | 927 | |
|---|
| 895 | 928 | /* try to obtain register address info */ |
|---|
| .. | .. |
|---|
| 981 | 1014 | brcmf_chip_set_passive(&ci->pub); |
|---|
| 982 | 1015 | } |
|---|
| 983 | 1016 | |
|---|
| 984 | | - return brcmf_chip_get_raminfo(ci); |
|---|
| 1017 | + return brcmf_chip_get_raminfo(&ci->pub); |
|---|
| 985 | 1018 | } |
|---|
| 986 | 1019 | |
|---|
| 987 | 1020 | static void brcmf_chip_disable_arm(struct brcmf_chip_priv *chip, u16 id) |
|---|
| .. | .. |
|---|
| 1111 | 1144 | kfree(core); |
|---|
| 1112 | 1145 | } |
|---|
| 1113 | 1146 | kfree(chip); |
|---|
| 1147 | +} |
|---|
| 1148 | + |
|---|
| 1149 | +struct brcmf_core *brcmf_chip_get_d11core(struct brcmf_chip *pub, u8 unit) |
|---|
| 1150 | +{ |
|---|
| 1151 | + struct brcmf_chip_priv *chip; |
|---|
| 1152 | + struct brcmf_core_priv *core; |
|---|
| 1153 | + |
|---|
| 1154 | + chip = container_of(pub, struct brcmf_chip_priv, pub); |
|---|
| 1155 | + list_for_each_entry(core, &chip->cores, list) { |
|---|
| 1156 | + if (core->pub.id == BCMA_CORE_80211) { |
|---|
| 1157 | + if (unit-- == 0) |
|---|
| 1158 | + return &core->pub; |
|---|
| 1159 | + } |
|---|
| 1160 | + } |
|---|
| 1161 | + return NULL; |
|---|
| 1114 | 1162 | } |
|---|
| 1115 | 1163 | |
|---|
| 1116 | 1164 | struct brcmf_core *brcmf_chip_get_core(struct brcmf_chip *pub, u16 coreid) |
|---|
| .. | .. |
|---|
| 1342 | 1390 | case BRCM_CC_4345_CHIP_ID: |
|---|
| 1343 | 1391 | /* explicitly check SR engine enable bit */ |
|---|
| 1344 | 1392 | pmu_cc3_mask = BIT(2); |
|---|
| 1345 | | - /* fall-through */ |
|---|
| 1393 | + fallthrough; |
|---|
| 1346 | 1394 | case BRCM_CC_43241_CHIP_ID: |
|---|
| 1347 | 1395 | case BRCM_CC_4335_CHIP_ID: |
|---|
| 1348 | 1396 | case BRCM_CC_4339_CHIP_ID: |
|---|
| .. | .. |
|---|
| 1356 | 1404 | addr = CORE_CC_REG(base, sr_control1); |
|---|
| 1357 | 1405 | reg = chip->ops->read32(chip->ctx, addr); |
|---|
| 1358 | 1406 | return reg != 0; |
|---|
| 1407 | + case CY_CC_4373_CHIP_ID: |
|---|
| 1408 | + /* explicitly check SR engine enable bit */ |
|---|
| 1409 | + addr = CORE_CC_REG(base, sr_control0); |
|---|
| 1410 | + reg = chip->ops->read32(chip->ctx, addr); |
|---|
| 1411 | + return (reg & CC_SR_CTL0_ENABLE_MASK) != 0; |
|---|
| 1412 | + case BRCM_CC_4359_CHIP_ID: |
|---|
| 1413 | + case CY_CC_43012_CHIP_ID: |
|---|
| 1414 | + addr = CORE_CC_REG(pmu->base, retention_ctl); |
|---|
| 1415 | + reg = chip->ops->read32(chip->ctx, addr); |
|---|
| 1416 | + return (reg & (PMU_RCTL_MACPHY_DISABLE_MASK | |
|---|
| 1417 | + PMU_RCTL_LOGIC_DISABLE_MASK)) == 0; |
|---|
| 1359 | 1418 | default: |
|---|
| 1360 | 1419 | addr = CORE_CC_REG(pmu->base, pmucapabilities_ext); |
|---|
| 1361 | 1420 | reg = chip->ops->read32(chip->ctx, addr); |
|---|