19bf41ad9b5b348b06b85a0b878c04bbdd5d6b62
[oweals/openwrt.git] /
1 From 1b8d2e0a9e4221b99eea375c079507ce8ef655f5 Mon Sep 17 00:00:00 2001
2 From: Wright Feng <wright.feng@cypress.com>
3 Date: Thu, 12 Dec 2019 00:52:45 +0100
4 Subject: [PATCH 1/7] brcmfmac: reset two D11 cores if chip has two D11 cores
5
6 There are two D11 cores in RSDB chips like 4359. We have to reset two
7 D11 cores simutaneously before firmware download, or the firmware may
8 not be initialized correctly and cause "fw initialized failed" error.
9
10 Signed-off-by: Wright Feng <wright.feng@cypress.com>
11 Signed-off-by: Soeren Moch <smoch@web.de>
12 Reviewed-by: Chi-Hsien Lin <chi-hsien.lin@cypress.com>
13 Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
14 ---
15  .../broadcom/brcm80211/brcmfmac/chip.c        | 50 +++++++++++++++++++
16  .../broadcom/brcm80211/brcmfmac/chip.h        |  1 +
17  .../broadcom/brcm80211/brcmfmac/pcie.c        |  2 +-
18  3 files changed, 52 insertions(+), 1 deletion(-)
19
20 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
21 +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
22 @@ -433,11 +433,25 @@ static void brcmf_chip_ai_resetcore(stru
23  {
24         struct brcmf_chip_priv *ci;
25         int count;
26 +       struct brcmf_core *d11core2 = NULL;
27 +       struct brcmf_core_priv *d11priv2 = NULL;
28  
29         ci = core->chip;
30  
31 +       /* special handle two D11 cores reset */
32 +       if (core->pub.id == BCMA_CORE_80211) {
33 +               d11core2 = brcmf_chip_get_d11core(&ci->pub, 1);
34 +               if (d11core2) {
35 +                       brcmf_dbg(INFO, "found two d11 cores, reset both\n");
36 +                       d11priv2 = container_of(d11core2,
37 +                                               struct brcmf_core_priv, pub);
38 +               }
39 +       }
40 +
41         /* must disable first to work for arbitrary current core state */
42         brcmf_chip_ai_coredisable(core, prereset, reset);
43 +       if (d11priv2)
44 +               brcmf_chip_ai_coredisable(d11priv2, prereset, reset);
45  
46         count = 0;
47         while (ci->ops->read32(ci->ctx, core->wrapbase + BCMA_RESET_CTL) &
48 @@ -449,9 +463,30 @@ static void brcmf_chip_ai_resetcore(stru
49                 usleep_range(40, 60);
50         }
51  
52 +       if (d11priv2) {
53 +               count = 0;
54 +               while (ci->ops->read32(ci->ctx,
55 +                                      d11priv2->wrapbase + BCMA_RESET_CTL) &
56 +                                      BCMA_RESET_CTL_RESET) {
57 +                       ci->ops->write32(ci->ctx,
58 +                                        d11priv2->wrapbase + BCMA_RESET_CTL,
59 +                                        0);
60 +                       count++;
61 +                       if (count > 50)
62 +                               break;
63 +                       usleep_range(40, 60);
64 +               }
65 +       }
66 +
67         ci->ops->write32(ci->ctx, core->wrapbase + BCMA_IOCTL,
68                          postreset | BCMA_IOCTL_CLK);
69         ci->ops->read32(ci->ctx, core->wrapbase + BCMA_IOCTL);
70 +
71 +       if (d11priv2) {
72 +               ci->ops->write32(ci->ctx, d11priv2->wrapbase + BCMA_IOCTL,
73 +                                postreset | BCMA_IOCTL_CLK);
74 +               ci->ops->read32(ci->ctx, d11priv2->wrapbase + BCMA_IOCTL);
75 +       }
76  }
77  
78  char *brcmf_chip_name(u32 id, u32 rev, char *buf, uint len)
79 @@ -1109,6 +1144,21 @@ void brcmf_chip_detach(struct brcmf_chip
80         kfree(chip);
81  }
82  
83 +struct brcmf_core *brcmf_chip_get_d11core(struct brcmf_chip *pub, u8 unit)
84 +{
85 +       struct brcmf_chip_priv *chip;
86 +       struct brcmf_core_priv *core;
87 +
88 +       chip = container_of(pub, struct brcmf_chip_priv, pub);
89 +       list_for_each_entry(core, &chip->cores, list) {
90 +               if (core->pub.id == BCMA_CORE_80211) {
91 +                       if (unit-- == 0)
92 +                               return &core->pub;
93 +               }
94 +       }
95 +       return NULL;
96 +}
97 +
98  struct brcmf_core *brcmf_chip_get_core(struct brcmf_chip *pub, u16 coreid)
99  {
100         struct brcmf_chip_priv *chip;
101 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.h
102 +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.h
103 @@ -74,6 +74,7 @@ struct brcmf_chip *brcmf_chip_attach(voi
104                                      const struct brcmf_buscore_ops *ops);
105  void brcmf_chip_detach(struct brcmf_chip *chip);
106  struct brcmf_core *brcmf_chip_get_core(struct brcmf_chip *chip, u16 coreid);
107 +struct brcmf_core *brcmf_chip_get_d11core(struct brcmf_chip *pub, u8 unit);
108  struct brcmf_core *brcmf_chip_get_chipcommon(struct brcmf_chip *chip);
109  struct brcmf_core *brcmf_chip_get_pmu(struct brcmf_chip *pub);
110  bool brcmf_chip_iscoreup(struct brcmf_core *core);
111 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
112 +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
113 @@ -78,7 +78,7 @@ static const struct brcmf_firmware_mappi
114         BRCMF_FW_ENTRY(BRCM_CC_4371_CHIP_ID, 0xFFFFFFFF, 4371),
115  };
116  
117 -#define BRCMF_PCIE_FW_UP_TIMEOUT               2000 /* msec */
118 +#define BRCMF_PCIE_FW_UP_TIMEOUT               5000 /* msec */
119  
120  #define BRCMF_PCIE_REG_MAP_SIZE                        (32 * 1024)
121