2 * Copyright (c) 2014 Broadcom Corporation
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.
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.
16 #include <linux/kernel.h>
17 #include <linux/delay.h>
18 #include <linux/list.h>
19 #include <linux/ssb/ssb_regs.h>
20 #include <linux/bcma/bcma.h>
21 #include <linux/bcma/bcma_regs.h>
25 #include <brcm_hw_ids.h>
26 #include <brcmu_utils.h>
27 #include <chipcommon.h>
31 /* SOC Interconnect types (aka chip types) */
35 /* PL-368 DMP definitions */
36 #define DMP_DESC_TYPE_MSK 0x0000000F
37 #define DMP_DESC_EMPTY 0x00000000
38 #define DMP_DESC_VALID 0x00000001
39 #define DMP_DESC_COMPONENT 0x00000001
40 #define DMP_DESC_MASTER_PORT 0x00000003
41 #define DMP_DESC_ADDRESS 0x00000005
42 #define DMP_DESC_ADDRSIZE_GT32 0x00000008
43 #define DMP_DESC_EOT 0x0000000F
45 #define DMP_COMP_DESIGNER 0xFFF00000
46 #define DMP_COMP_DESIGNER_S 20
47 #define DMP_COMP_PARTNUM 0x000FFF00
48 #define DMP_COMP_PARTNUM_S 8
49 #define DMP_COMP_CLASS 0x000000F0
50 #define DMP_COMP_CLASS_S 4
51 #define DMP_COMP_REVISION 0xFF000000
52 #define DMP_COMP_REVISION_S 24
53 #define DMP_COMP_NUM_SWRAP 0x00F80000
54 #define DMP_COMP_NUM_SWRAP_S 19
55 #define DMP_COMP_NUM_MWRAP 0x0007C000
56 #define DMP_COMP_NUM_MWRAP_S 14
57 #define DMP_COMP_NUM_SPORT 0x00003E00
58 #define DMP_COMP_NUM_SPORT_S 9
59 #define DMP_COMP_NUM_MPORT 0x000001F0
60 #define DMP_COMP_NUM_MPORT_S 4
62 #define DMP_MASTER_PORT_UID 0x0000FF00
63 #define DMP_MASTER_PORT_UID_S 8
64 #define DMP_MASTER_PORT_NUM 0x000000F0
65 #define DMP_MASTER_PORT_NUM_S 4
67 #define DMP_SLAVE_ADDR_BASE 0xFFFFF000
68 #define DMP_SLAVE_ADDR_BASE_S 12
69 #define DMP_SLAVE_PORT_NUM 0x00000F00
70 #define DMP_SLAVE_PORT_NUM_S 8
71 #define DMP_SLAVE_TYPE 0x000000C0
72 #define DMP_SLAVE_TYPE_S 6
73 #define DMP_SLAVE_TYPE_SLAVE 0
74 #define DMP_SLAVE_TYPE_BRIDGE 1
75 #define DMP_SLAVE_TYPE_SWRAP 2
76 #define DMP_SLAVE_TYPE_MWRAP 3
77 #define DMP_SLAVE_SIZE_TYPE 0x00000030
78 #define DMP_SLAVE_SIZE_TYPE_S 4
79 #define DMP_SLAVE_SIZE_4K 0
80 #define DMP_SLAVE_SIZE_8K 1
81 #define DMP_SLAVE_SIZE_16K 2
82 #define DMP_SLAVE_SIZE_DESC 3
85 #define CIB_REV_MASK 0xff000000
86 #define CIB_REV_SHIFT 24
88 /* ARM CR4 core specific control flag bits */
89 #define ARMCR4_BCMA_IOCTL_CPUHALT 0x0020
91 /* D11 core specific control flag bits */
92 #define D11_BCMA_IOCTL_PHYCLOCKEN 0x0004
93 #define D11_BCMA_IOCTL_PHYRESET 0x0008
95 /* chip core base & ramsize */
97 /* SDIO device core, ID 0x829 */
98 #define BCM4329_CORE_BUS_BASE 0x18011000
99 /* internal memory core, ID 0x80e */
100 #define BCM4329_CORE_SOCRAM_BASE 0x18003000
101 /* ARM Cortex M3 core, ID 0x82a */
102 #define BCM4329_CORE_ARM_BASE 0x18002000
103 #define BCM4329_RAMSIZE 0x48000
106 /* SDIO device core */
107 #define BCM43143_CORE_BUS_BASE 0x18002000
108 /* internal memory core */
109 #define BCM43143_CORE_SOCRAM_BASE 0x18004000
110 /* ARM Cortex M3 core, ID 0x82a */
111 #define BCM43143_CORE_ARM_BASE 0x18003000
112 #define BCM43143_RAMSIZE 0x70000
114 #define CORE_SB(base, field) \
115 (base + SBCONFIGOFF + offsetof(struct sbconfig, field))
116 #define SBCOREREV(sbidh) \
117 ((((sbidh) & SSB_IDHIGH_RCHI) >> SSB_IDHIGH_RCHI_SHIFT) | \
118 ((sbidh) & SSB_IDHIGH_RCLO))
122 u32 sbipsflag
; /* initiator port ocp slave flag */
124 u32 sbtpsflag
; /* target port ocp slave flag */
126 u32 sbtmerrloga
; /* (sonics >= 2.3) */
128 u32 sbtmerrlog
; /* (sonics >= 2.3) */
130 u32 sbadmatch3
; /* address match3 */
132 u32 sbadmatch2
; /* address match2 */
134 u32 sbadmatch1
; /* address match1 */
136 u32 sbimstate
; /* initiator agent state */
137 u32 sbintvec
; /* interrupt mask */
138 u32 sbtmstatelow
; /* target state */
139 u32 sbtmstatehigh
; /* target state */
140 u32 sbbwa0
; /* bandwidth allocation table0 */
142 u32 sbimconfiglow
; /* initiator configuration */
143 u32 sbimconfighigh
; /* initiator configuration */
144 u32 sbadmatch0
; /* address match0 */
146 u32 sbtmconfiglow
; /* target configuration */
147 u32 sbtmconfighigh
; /* target configuration */
148 u32 sbbconfig
; /* broadcast configuration */
150 u32 sbbstate
; /* broadcast state */
152 u32 sbactcnfg
; /* activate configuration */
154 u32 sbflagst
; /* current sbflags */
156 u32 sbidlow
; /* identification */
157 u32 sbidhigh
; /* identification */
160 struct brcmf_core_priv
{
161 struct brcmf_core pub
;
163 struct list_head list
;
164 struct brcmf_chip_priv
*chip
;
167 /* ARM CR4 core specific control flag bits */
168 #define ARMCR4_BCMA_IOCTL_CPUHALT 0x0020
170 /* D11 core specific control flag bits */
171 #define D11_BCMA_IOCTL_PHYCLOCKEN 0x0004
172 #define D11_BCMA_IOCTL_PHYRESET 0x0008
174 struct brcmf_chip_priv
{
175 struct brcmf_chip pub
;
176 const struct brcmf_buscore_ops
*ops
;
178 /* assured first core is chipcommon, second core is buscore */
179 struct list_head cores
;
182 bool (*iscoreup
)(struct brcmf_core_priv
*core
);
183 void (*coredisable
)(struct brcmf_core_priv
*core
, u32 prereset
,
185 void (*resetcore
)(struct brcmf_core_priv
*core
, u32 prereset
, u32 reset
,
189 static void brcmf_chip_sb_corerev(struct brcmf_chip_priv
*ci
,
190 struct brcmf_core
*core
)
194 regdata
= ci
->ops
->read32(ci
->ctx
, CORE_SB(core
->base
, sbidhigh
));
195 core
->rev
= SBCOREREV(regdata
);
198 static bool brcmf_chip_sb_iscoreup(struct brcmf_core_priv
*core
)
200 struct brcmf_chip_priv
*ci
;
205 address
= CORE_SB(core
->pub
.base
, sbtmstatelow
);
206 regdata
= ci
->ops
->read32(ci
->ctx
, address
);
207 regdata
&= (SSB_TMSLOW_RESET
| SSB_TMSLOW_REJECT
|
208 SSB_IMSTATE_REJECT
| SSB_TMSLOW_CLOCK
);
209 return SSB_TMSLOW_CLOCK
== regdata
;
212 static bool brcmf_chip_ai_iscoreup(struct brcmf_core_priv
*core
)
214 struct brcmf_chip_priv
*ci
;
219 regdata
= ci
->ops
->read32(ci
->ctx
, core
->wrapbase
+ BCMA_IOCTL
);
220 ret
= (regdata
& (BCMA_IOCTL_FGC
| BCMA_IOCTL_CLK
)) == BCMA_IOCTL_CLK
;
222 regdata
= ci
->ops
->read32(ci
->ctx
, core
->wrapbase
+ BCMA_RESET_CTL
);
223 ret
= ret
&& ((regdata
& BCMA_RESET_CTL_RESET
) == 0);
228 static void brcmf_chip_sb_coredisable(struct brcmf_core_priv
*core
,
229 u32 prereset
, u32 reset
)
231 struct brcmf_chip_priv
*ci
;
235 base
= core
->pub
.base
;
236 val
= ci
->ops
->read32(ci
->ctx
, CORE_SB(base
, sbtmstatelow
));
237 if (val
& SSB_TMSLOW_RESET
)
240 val
= ci
->ops
->read32(ci
->ctx
, CORE_SB(base
, sbtmstatelow
));
241 if ((val
& SSB_TMSLOW_CLOCK
) != 0) {
243 * set target reject and spin until busy is clear
244 * (preserve core-specific bits)
246 val
= ci
->ops
->read32(ci
->ctx
, CORE_SB(base
, sbtmstatelow
));
247 ci
->ops
->write32(ci
->ctx
, CORE_SB(base
, sbtmstatelow
),
248 val
| SSB_TMSLOW_REJECT
);
250 val
= ci
->ops
->read32(ci
->ctx
, CORE_SB(base
, sbtmstatelow
));
252 SPINWAIT((ci
->ops
->read32(ci
->ctx
, CORE_SB(base
, sbtmstatehigh
))
253 & SSB_TMSHIGH_BUSY
), 100000);
255 val
= ci
->ops
->read32(ci
->ctx
, CORE_SB(base
, sbtmstatehigh
));
256 if (val
& SSB_TMSHIGH_BUSY
)
257 brcmf_err("core state still busy\n");
259 val
= ci
->ops
->read32(ci
->ctx
, CORE_SB(base
, sbidlow
));
260 if (val
& SSB_IDLOW_INITIATOR
) {
261 val
= ci
->ops
->read32(ci
->ctx
,
262 CORE_SB(base
, sbimstate
));
263 val
|= SSB_IMSTATE_REJECT
;
264 ci
->ops
->write32(ci
->ctx
,
265 CORE_SB(base
, sbimstate
), val
);
266 val
= ci
->ops
->read32(ci
->ctx
,
267 CORE_SB(base
, sbimstate
));
269 SPINWAIT((ci
->ops
->read32(ci
->ctx
,
270 CORE_SB(base
, sbimstate
)) &
271 SSB_IMSTATE_BUSY
), 100000);
274 /* set reset and reject while enabling the clocks */
275 val
= SSB_TMSLOW_FGC
| SSB_TMSLOW_CLOCK
|
276 SSB_TMSLOW_REJECT
| SSB_TMSLOW_RESET
;
277 ci
->ops
->write32(ci
->ctx
, CORE_SB(base
, sbtmstatelow
), val
);
278 val
= ci
->ops
->read32(ci
->ctx
, CORE_SB(base
, sbtmstatelow
));
281 /* clear the initiator reject bit */
282 val
= ci
->ops
->read32(ci
->ctx
, CORE_SB(base
, sbidlow
));
283 if (val
& SSB_IDLOW_INITIATOR
) {
284 val
= ci
->ops
->read32(ci
->ctx
,
285 CORE_SB(base
, sbimstate
));
286 val
&= ~SSB_IMSTATE_REJECT
;
287 ci
->ops
->write32(ci
->ctx
,
288 CORE_SB(base
, sbimstate
), val
);
292 /* leave reset and reject asserted */
293 ci
->ops
->write32(ci
->ctx
, CORE_SB(base
, sbtmstatelow
),
294 (SSB_TMSLOW_REJECT
| SSB_TMSLOW_RESET
));
298 static void brcmf_chip_ai_coredisable(struct brcmf_core_priv
*core
,
299 u32 prereset
, u32 reset
)
301 struct brcmf_chip_priv
*ci
;
306 /* if core is already in reset, just return */
307 regdata
= ci
->ops
->read32(ci
->ctx
, core
->wrapbase
+ BCMA_RESET_CTL
);
308 if ((regdata
& BCMA_RESET_CTL_RESET
) != 0)
311 /* configure reset */
312 ci
->ops
->write32(ci
->ctx
, core
->wrapbase
+ BCMA_IOCTL
,
313 prereset
| BCMA_IOCTL_FGC
| BCMA_IOCTL_CLK
);
314 ci
->ops
->read32(ci
->ctx
, core
->wrapbase
+ BCMA_IOCTL
);
317 ci
->ops
->write32(ci
->ctx
, core
->wrapbase
+ BCMA_RESET_CTL
,
318 BCMA_RESET_CTL_RESET
);
319 usleep_range(10, 20);
321 /* wait till reset is 1 */
322 SPINWAIT(ci
->ops
->read32(ci
->ctx
, core
->wrapbase
+ BCMA_RESET_CTL
) !=
323 BCMA_RESET_CTL_RESET
, 300);
325 /* in-reset configure */
326 ci
->ops
->write32(ci
->ctx
, core
->wrapbase
+ BCMA_IOCTL
,
327 reset
| BCMA_IOCTL_FGC
| BCMA_IOCTL_CLK
);
328 ci
->ops
->read32(ci
->ctx
, core
->wrapbase
+ BCMA_IOCTL
);
331 static void brcmf_chip_sb_resetcore(struct brcmf_core_priv
*core
, u32 prereset
,
332 u32 reset
, u32 postreset
)
334 struct brcmf_chip_priv
*ci
;
339 base
= core
->pub
.base
;
341 * Must do the disable sequence first to work for
342 * arbitrary current core state.
344 brcmf_chip_sb_coredisable(core
, 0, 0);
347 * Now do the initialization sequence.
348 * set reset while enabling the clock and
349 * forcing them on throughout the core
351 ci
->ops
->write32(ci
->ctx
, CORE_SB(base
, sbtmstatelow
),
352 SSB_TMSLOW_FGC
| SSB_TMSLOW_CLOCK
|
354 regdata
= ci
->ops
->read32(ci
->ctx
, CORE_SB(base
, sbtmstatelow
));
357 /* clear any serror */
358 regdata
= ci
->ops
->read32(ci
->ctx
, CORE_SB(base
, sbtmstatehigh
));
359 if (regdata
& SSB_TMSHIGH_SERR
)
360 ci
->ops
->write32(ci
->ctx
, CORE_SB(base
, sbtmstatehigh
), 0);
362 regdata
= ci
->ops
->read32(ci
->ctx
, CORE_SB(base
, sbimstate
));
363 if (regdata
& (SSB_IMSTATE_IBE
| SSB_IMSTATE_TO
)) {
364 regdata
&= ~(SSB_IMSTATE_IBE
| SSB_IMSTATE_TO
);
365 ci
->ops
->write32(ci
->ctx
, CORE_SB(base
, sbimstate
), regdata
);
368 /* clear reset and allow it to propagate throughout the core */
369 ci
->ops
->write32(ci
->ctx
, CORE_SB(base
, sbtmstatelow
),
370 SSB_TMSLOW_FGC
| SSB_TMSLOW_CLOCK
);
371 regdata
= ci
->ops
->read32(ci
->ctx
, CORE_SB(base
, sbtmstatelow
));
374 /* leave clock enabled */
375 ci
->ops
->write32(ci
->ctx
, CORE_SB(base
, sbtmstatelow
),
377 regdata
= ci
->ops
->read32(ci
->ctx
, CORE_SB(base
, sbtmstatelow
));
381 static void brcmf_chip_ai_resetcore(struct brcmf_core_priv
*core
, u32 prereset
,
382 u32 reset
, u32 postreset
)
384 struct brcmf_chip_priv
*ci
;
389 /* must disable first to work for arbitrary current core state */
390 brcmf_chip_ai_coredisable(core
, prereset
, reset
);
393 while (ci
->ops
->read32(ci
->ctx
, core
->wrapbase
+ BCMA_RESET_CTL
) &
394 BCMA_RESET_CTL_RESET
) {
395 ci
->ops
->write32(ci
->ctx
, core
->wrapbase
+ BCMA_RESET_CTL
, 0);
399 usleep_range(40, 60);
402 ci
->ops
->write32(ci
->ctx
, core
->wrapbase
+ BCMA_IOCTL
,
403 postreset
| BCMA_IOCTL_CLK
);
404 ci
->ops
->read32(ci
->ctx
, core
->wrapbase
+ BCMA_IOCTL
);
407 static char *brcmf_chip_name(uint chipid
, char *buf
, uint len
)
411 fmt
= ((chipid
> 0xa000) || (chipid
< 0x4000)) ? "%d" : "%x";
412 snprintf(buf
, len
, fmt
, chipid
);
416 static struct brcmf_core
*brcmf_chip_add_core(struct brcmf_chip_priv
*ci
,
417 u16 coreid
, u32 base
,
420 struct brcmf_core_priv
*core
;
422 core
= kzalloc(sizeof(*core
), GFP_KERNEL
);
424 return ERR_PTR(-ENOMEM
);
426 core
->pub
.id
= coreid
;
427 core
->pub
.base
= base
;
429 core
->wrapbase
= wrapbase
;
431 list_add_tail(&core
->list
, &ci
->cores
);
436 /* safety check for chipinfo */
437 static int brcmf_chip_cores_check(struct brcmf_chip_priv
*ci
)
439 struct brcmf_core_priv
*core
;
440 bool need_socram
= false;
441 bool has_socram
= false;
444 list_for_each_entry(core
, &ci
->cores
, list
) {
445 brcmf_dbg(INFO
, " [%-2d] core 0x%x:%-2d base 0x%08x wrap 0x%08x\n",
446 idx
++, core
->pub
.id
, core
->pub
.rev
, core
->pub
.base
,
449 switch (core
->pub
.id
) {
450 case BCMA_CORE_ARM_CM3
:
453 case BCMA_CORE_INTERNAL_MEM
:
456 case BCMA_CORE_ARM_CR4
:
457 if (ci
->pub
.rambase
== 0) {
458 brcmf_err("RAM base not provided with ARM CR4 core\n");
467 /* check RAM core presence for ARM CM3 core */
468 if (need_socram
&& !has_socram
) {
469 brcmf_err("RAM core not provided with ARM CM3 core\n");
475 static inline int brcmf_chip_cores_check(struct brcmf_chip_priv
*ci
)
481 static void brcmf_chip_get_raminfo(struct brcmf_chip_priv
*ci
)
483 switch (ci
->pub
.chip
) {
484 case BCM4329_CHIP_ID
:
485 ci
->pub
.ramsize
= BCM4329_RAMSIZE
;
487 case BCM43143_CHIP_ID
:
488 ci
->pub
.ramsize
= BCM43143_RAMSIZE
;
490 case BCM43241_CHIP_ID
:
491 ci
->pub
.ramsize
= 0x90000;
493 case BCM4330_CHIP_ID
:
494 ci
->pub
.ramsize
= 0x48000;
496 case BCM4334_CHIP_ID
:
497 ci
->pub
.ramsize
= 0x80000;
499 case BCM4335_CHIP_ID
:
500 ci
->pub
.ramsize
= 0xc0000;
501 ci
->pub
.rambase
= 0x180000;
503 case BCM43362_CHIP_ID
:
504 ci
->pub
.ramsize
= 0x3c000;
506 case BCM4339_CHIP_ID
:
507 case BCM4354_CHIP_ID
:
508 ci
->pub
.ramsize
= 0xc0000;
509 ci
->pub
.rambase
= 0x180000;
512 brcmf_err("unknown chip: %s\n", ci
->pub
.name
);
517 static u32
brcmf_chip_dmp_get_desc(struct brcmf_chip_priv
*ci
, u32
*eromaddr
,
522 /* read next descriptor */
523 val
= ci
->ops
->read32(ci
->ctx
, *eromaddr
);
529 /* determine descriptor type */
530 *type
= (val
& DMP_DESC_TYPE_MSK
);
531 if ((*type
& ~DMP_DESC_ADDRSIZE_GT32
) == DMP_DESC_ADDRESS
)
532 *type
= DMP_DESC_ADDRESS
;
537 static int brcmf_chip_dmp_get_regaddr(struct brcmf_chip_priv
*ci
, u32
*eromaddr
,
538 u32
*regbase
, u32
*wrapbase
)
543 u8 stype
, sztype
, wraptype
;
548 val
= brcmf_chip_dmp_get_desc(ci
, eromaddr
, &desc
);
549 if (desc
== DMP_DESC_MASTER_PORT
) {
550 mpnum
= (val
& DMP_MASTER_PORT_NUM
) >> DMP_MASTER_PORT_NUM_S
;
551 wraptype
= DMP_SLAVE_TYPE_MWRAP
;
552 } else if (desc
== DMP_DESC_ADDRESS
) {
553 /* revert erom address */
555 wraptype
= DMP_SLAVE_TYPE_SWRAP
;
562 /* locate address descriptor */
564 val
= brcmf_chip_dmp_get_desc(ci
, eromaddr
, &desc
);
565 /* unexpected table end */
566 if (desc
== DMP_DESC_EOT
) {
570 } while (desc
!= DMP_DESC_ADDRESS
);
572 /* skip upper 32-bit address descriptor */
573 if (val
& DMP_DESC_ADDRSIZE_GT32
)
574 brcmf_chip_dmp_get_desc(ci
, eromaddr
, NULL
);
576 sztype
= (val
& DMP_SLAVE_SIZE_TYPE
) >> DMP_SLAVE_SIZE_TYPE_S
;
578 /* next size descriptor can be skipped */
579 if (sztype
== DMP_SLAVE_SIZE_DESC
) {
580 val
= brcmf_chip_dmp_get_desc(ci
, eromaddr
, NULL
);
581 /* skip upper size descriptor if present */
582 if (val
& DMP_DESC_ADDRSIZE_GT32
)
583 brcmf_chip_dmp_get_desc(ci
, eromaddr
, NULL
);
586 /* only look for 4K register regions */
587 if (sztype
!= DMP_SLAVE_SIZE_4K
)
590 stype
= (val
& DMP_SLAVE_TYPE
) >> DMP_SLAVE_TYPE_S
;
592 /* only regular slave and wrapper */
593 if (*regbase
== 0 && stype
== DMP_SLAVE_TYPE_SLAVE
)
594 *regbase
= val
& DMP_SLAVE_ADDR_BASE
;
595 if (*wrapbase
== 0 && stype
== wraptype
)
596 *wrapbase
= val
& DMP_SLAVE_ADDR_BASE
;
597 } while (*regbase
== 0 || *wrapbase
== 0);
603 int brcmf_chip_dmp_erom_scan(struct brcmf_chip_priv
*ci
)
605 struct brcmf_core
*core
;
610 u8 nmp
, nsp
, nmw
, nsw
, rev
;
614 eromaddr
= ci
->ops
->read32(ci
->ctx
, CORE_CC_REG(SI_ENUM_BASE
, eromptr
));
616 while (desc_type
!= DMP_DESC_EOT
) {
617 val
= brcmf_chip_dmp_get_desc(ci
, &eromaddr
, &desc_type
);
618 if (!(val
& DMP_DESC_VALID
))
621 if (desc_type
== DMP_DESC_EMPTY
)
624 /* need a component descriptor */
625 if (desc_type
!= DMP_DESC_COMPONENT
)
628 id
= (val
& DMP_COMP_PARTNUM
) >> DMP_COMP_PARTNUM_S
;
630 /* next descriptor must be component as well */
631 val
= brcmf_chip_dmp_get_desc(ci
, &eromaddr
, &desc_type
);
632 if (WARN_ON((val
& DMP_DESC_TYPE_MSK
) != DMP_DESC_COMPONENT
))
635 /* only look at cores with master port(s) */
636 nmp
= (val
& DMP_COMP_NUM_MPORT
) >> DMP_COMP_NUM_MPORT_S
;
637 nsp
= (val
& DMP_COMP_NUM_SPORT
) >> DMP_COMP_NUM_SPORT_S
;
638 nmw
= (val
& DMP_COMP_NUM_MWRAP
) >> DMP_COMP_NUM_MWRAP_S
;
639 nsw
= (val
& DMP_COMP_NUM_SWRAP
) >> DMP_COMP_NUM_SWRAP_S
;
640 rev
= (val
& DMP_COMP_REVISION
) >> DMP_COMP_REVISION_S
;
642 /* need core with ports */
646 /* try to obtain register address info */
647 err
= brcmf_chip_dmp_get_regaddr(ci
, &eromaddr
, &base
, &wrap
);
651 /* finally a core to be added */
652 core
= brcmf_chip_add_core(ci
, id
, base
, wrap
);
654 return PTR_ERR(core
);
662 static int brcmf_chip_recognition(struct brcmf_chip_priv
*ci
)
664 struct brcmf_core
*core
;
669 * Chipid is assume to be at offset 0 from SI_ENUM_BASE
670 * For different chiptypes or old sdio hosts w/o chipcommon,
671 * other ways of recognition should be added here.
673 regdata
= ci
->ops
->read32(ci
->ctx
, CORE_CC_REG(SI_ENUM_BASE
, chipid
));
674 ci
->pub
.chip
= regdata
& CID_ID_MASK
;
675 ci
->pub
.chiprev
= (regdata
& CID_REV_MASK
) >> CID_REV_SHIFT
;
676 socitype
= (regdata
& CID_TYPE_MASK
) >> CID_TYPE_SHIFT
;
678 brcmf_chip_name(ci
->pub
.chip
, ci
->pub
.name
, sizeof(ci
->pub
.name
));
679 brcmf_dbg(INFO
, "found %s chip: BCM%s, rev=%d\n",
680 socitype
== SOCI_SB
? "SB" : "AXI", ci
->pub
.name
,
683 if (socitype
== SOCI_SB
) {
684 if (ci
->pub
.chip
!= BCM4329_CHIP_ID
) {
685 brcmf_err("SB chip is not supported\n");
688 ci
->iscoreup
= brcmf_chip_sb_iscoreup
;
689 ci
->coredisable
= brcmf_chip_sb_coredisable
;
690 ci
->resetcore
= brcmf_chip_sb_resetcore
;
692 core
= brcmf_chip_add_core(ci
, BCMA_CORE_CHIPCOMMON
,
694 brcmf_chip_sb_corerev(ci
, core
);
695 core
= brcmf_chip_add_core(ci
, BCMA_CORE_SDIO_DEV
,
696 BCM4329_CORE_BUS_BASE
, 0);
697 brcmf_chip_sb_corerev(ci
, core
);
698 core
= brcmf_chip_add_core(ci
, BCMA_CORE_INTERNAL_MEM
,
699 BCM4329_CORE_SOCRAM_BASE
, 0);
700 brcmf_chip_sb_corerev(ci
, core
);
701 core
= brcmf_chip_add_core(ci
, BCMA_CORE_ARM_CM3
,
702 BCM4329_CORE_ARM_BASE
, 0);
703 brcmf_chip_sb_corerev(ci
, core
);
705 core
= brcmf_chip_add_core(ci
, BCMA_CORE_80211
, 0x18001000, 0);
706 brcmf_chip_sb_corerev(ci
, core
);
707 } else if (socitype
== SOCI_AI
) {
708 ci
->iscoreup
= brcmf_chip_ai_iscoreup
;
709 ci
->coredisable
= brcmf_chip_ai_coredisable
;
710 ci
->resetcore
= brcmf_chip_ai_resetcore
;
712 brcmf_chip_dmp_erom_scan(ci
);
714 brcmf_err("chip backplane type %u is not supported\n",
719 brcmf_chip_get_raminfo(ci
);
721 return brcmf_chip_cores_check(ci
);
724 static void brcmf_chip_disable_arm(struct brcmf_chip_priv
*chip
, u16 id
)
726 struct brcmf_core
*core
;
727 struct brcmf_core_priv
*cr4
;
731 core
= brcmf_chip_get_core(&chip
->pub
, id
);
736 case BCMA_CORE_ARM_CM3
:
737 brcmf_chip_coredisable(core
, 0, 0);
739 case BCMA_CORE_ARM_CR4
:
740 cr4
= container_of(core
, struct brcmf_core_priv
, pub
);
742 /* clear all IOCTL bits except HALT bit */
743 val
= chip
->ops
->read32(chip
->ctx
, cr4
->wrapbase
+ BCMA_IOCTL
);
744 val
&= ARMCR4_BCMA_IOCTL_CPUHALT
;
745 brcmf_chip_resetcore(core
, val
, ARMCR4_BCMA_IOCTL_CPUHALT
,
746 ARMCR4_BCMA_IOCTL_CPUHALT
);
749 brcmf_err("unknown id: %u\n", id
);
754 static int brcmf_chip_setup(struct brcmf_chip_priv
*chip
)
756 struct brcmf_chip
*pub
;
757 struct brcmf_core_priv
*cc
;
763 cc
= list_first_entry(&chip
->cores
, struct brcmf_core_priv
, list
);
766 /* get chipcommon capabilites */
767 pub
->cc_caps
= chip
->ops
->read32(chip
->ctx
,
768 CORE_CC_REG(base
, capabilities
));
770 /* get pmu caps & rev */
771 if (pub
->cc_caps
& CC_CAP_PMU
) {
772 val
= chip
->ops
->read32(chip
->ctx
,
773 CORE_CC_REG(base
, pmucapabilities
));
774 pub
->pmurev
= val
& PCAP_REV_MASK
;
778 brcmf_dbg(INFO
, "ccrev=%d, pmurev=%d, pmucaps=0x%x\n",
779 cc
->pub
.rev
, pub
->pmurev
, pub
->pmucaps
);
781 /* execute bus core specific setup */
782 if (chip
->ops
->setup
)
783 ret
= chip
->ops
->setup(chip
->ctx
, pub
);
786 * Make sure any on-chip ARM is off (in case strapping is wrong),
787 * or downloaded code was already running.
789 brcmf_chip_disable_arm(chip
, BCMA_CORE_ARM_CM3
);
790 brcmf_chip_disable_arm(chip
, BCMA_CORE_ARM_CR4
);
794 struct brcmf_chip
*brcmf_chip_attach(void *ctx
,
795 const struct brcmf_buscore_ops
*ops
)
797 struct brcmf_chip_priv
*chip
;
800 if (WARN_ON(!ops
->read32
))
802 if (WARN_ON(!ops
->write32
))
804 if (WARN_ON(!ops
->prepare
))
806 if (WARN_ON(!ops
->exit_dl
))
809 return ERR_PTR(-EINVAL
);
811 chip
= kzalloc(sizeof(*chip
), GFP_KERNEL
);
813 return ERR_PTR(-ENOMEM
);
815 INIT_LIST_HEAD(&chip
->cores
);
820 err
= ops
->prepare(ctx
);
824 err
= brcmf_chip_recognition(chip
);
828 err
= brcmf_chip_setup(chip
);
835 brcmf_chip_detach(&chip
->pub
);
839 void brcmf_chip_detach(struct brcmf_chip
*pub
)
841 struct brcmf_chip_priv
*chip
;
842 struct brcmf_core_priv
*core
;
843 struct brcmf_core_priv
*tmp
;
845 chip
= container_of(pub
, struct brcmf_chip_priv
, pub
);
846 list_for_each_entry_safe(core
, tmp
, &chip
->cores
, list
) {
847 list_del(&core
->list
);
853 struct brcmf_core
*brcmf_chip_get_core(struct brcmf_chip
*pub
, u16 coreid
)
855 struct brcmf_chip_priv
*chip
;
856 struct brcmf_core_priv
*core
;
858 chip
= container_of(pub
, struct brcmf_chip_priv
, pub
);
859 list_for_each_entry(core
, &chip
->cores
, list
)
860 if (core
->pub
.id
== coreid
)
866 struct brcmf_core
*brcmf_chip_get_chipcommon(struct brcmf_chip
*pub
)
868 struct brcmf_chip_priv
*chip
;
869 struct brcmf_core_priv
*cc
;
871 chip
= container_of(pub
, struct brcmf_chip_priv
, pub
);
872 cc
= list_first_entry(&chip
->cores
, struct brcmf_core_priv
, list
);
873 if (WARN_ON(!cc
|| cc
->pub
.id
!= BCMA_CORE_CHIPCOMMON
))
874 return brcmf_chip_get_core(pub
, BCMA_CORE_CHIPCOMMON
);
878 bool brcmf_chip_iscoreup(struct brcmf_core
*pub
)
880 struct brcmf_core_priv
*core
;
882 core
= container_of(pub
, struct brcmf_core_priv
, pub
);
883 return core
->chip
->iscoreup(core
);
886 void brcmf_chip_coredisable(struct brcmf_core
*pub
, u32 prereset
, u32 reset
)
888 struct brcmf_core_priv
*core
;
890 core
= container_of(pub
, struct brcmf_core_priv
, pub
);
891 core
->chip
->coredisable(core
, prereset
, reset
);
894 void brcmf_chip_resetcore(struct brcmf_core
*pub
, u32 prereset
, u32 reset
,
897 struct brcmf_core_priv
*core
;
899 core
= container_of(pub
, struct brcmf_core_priv
, pub
);
900 core
->chip
->resetcore(core
, prereset
, reset
, postreset
);
904 brcmf_chip_cm3_enterdl(struct brcmf_chip_priv
*chip
)
906 struct brcmf_core
*core
;
908 brcmf_chip_disable_arm(chip
, BCMA_CORE_ARM_CM3
);
909 core
= brcmf_chip_get_core(&chip
->pub
, BCMA_CORE_80211
);
910 brcmf_chip_resetcore(core
, D11_BCMA_IOCTL_PHYRESET
|
911 D11_BCMA_IOCTL_PHYCLOCKEN
,
912 D11_BCMA_IOCTL_PHYCLOCKEN
,
913 D11_BCMA_IOCTL_PHYCLOCKEN
);
914 core
= brcmf_chip_get_core(&chip
->pub
, BCMA_CORE_INTERNAL_MEM
);
915 brcmf_chip_resetcore(core
, 0, 0, 0);
918 static bool brcmf_chip_cm3_exitdl(struct brcmf_chip_priv
*chip
)
920 struct brcmf_core
*core
;
922 core
= brcmf_chip_get_core(&chip
->pub
, BCMA_CORE_INTERNAL_MEM
);
923 if (!brcmf_chip_iscoreup(core
)) {
924 brcmf_err("SOCRAM core is down after reset?\n");
928 chip
->ops
->exit_dl(chip
->ctx
, &chip
->pub
, 0);
930 core
= brcmf_chip_get_core(&chip
->pub
, BCMA_CORE_ARM_CM3
);
931 brcmf_chip_resetcore(core
, 0, 0, 0);
937 brcmf_chip_cr4_enterdl(struct brcmf_chip_priv
*chip
)
939 struct brcmf_core
*core
;
941 brcmf_chip_disable_arm(chip
, BCMA_CORE_ARM_CR4
);
943 core
= brcmf_chip_get_core(&chip
->pub
, BCMA_CORE_80211
);
944 brcmf_chip_resetcore(core
, D11_BCMA_IOCTL_PHYRESET
|
945 D11_BCMA_IOCTL_PHYCLOCKEN
,
946 D11_BCMA_IOCTL_PHYCLOCKEN
,
947 D11_BCMA_IOCTL_PHYCLOCKEN
);
950 static bool brcmf_chip_cr4_exitdl(struct brcmf_chip_priv
*chip
, u32 rstvec
)
952 struct brcmf_core
*core
;
954 chip
->ops
->exit_dl(chip
->ctx
, &chip
->pub
, rstvec
);
957 core
= brcmf_chip_get_core(&chip
->pub
, BCMA_CORE_ARM_CR4
);
958 brcmf_chip_resetcore(core
, ARMCR4_BCMA_IOCTL_CPUHALT
, 0, 0);
963 void brcmf_chip_enter_download(struct brcmf_chip
*pub
)
965 struct brcmf_chip_priv
*chip
;
966 struct brcmf_core
*arm
;
968 brcmf_dbg(TRACE
, "Enter\n");
970 chip
= container_of(pub
, struct brcmf_chip_priv
, pub
);
971 arm
= brcmf_chip_get_core(pub
, BCMA_CORE_ARM_CR4
);
973 brcmf_chip_cr4_enterdl(chip
);
977 brcmf_chip_cm3_enterdl(chip
);
980 bool brcmf_chip_exit_download(struct brcmf_chip
*pub
, u32 rstvec
)
982 struct brcmf_chip_priv
*chip
;
983 struct brcmf_core
*arm
;
985 brcmf_dbg(TRACE
, "Enter\n");
987 chip
= container_of(pub
, struct brcmf_chip_priv
, pub
);
988 arm
= brcmf_chip_get_core(pub
, BCMA_CORE_ARM_CR4
);
990 return brcmf_chip_cr4_exitdl(chip
, rstvec
);
992 return brcmf_chip_cm3_exitdl(chip
);
995 bool brcmf_chip_sr_capable(struct brcmf_chip
*pub
)
997 u32 base
, addr
, reg
, pmu_cc3_mask
= ~0;
998 struct brcmf_chip_priv
*chip
;
1000 brcmf_dbg(TRACE
, "Enter\n");
1002 /* old chips with PMU version less than 17 don't support save restore */
1003 if (pub
->pmurev
< 17)
1006 base
= brcmf_chip_get_chipcommon(pub
)->base
;
1007 chip
= container_of(pub
, struct brcmf_chip_priv
, pub
);
1009 switch (pub
->chip
) {
1010 case BCM4354_CHIP_ID
:
1011 /* explicitly check SR engine enable bit */
1012 pmu_cc3_mask
= BIT(2);
1014 case BCM43241_CHIP_ID
:
1015 case BCM4335_CHIP_ID
:
1016 case BCM4339_CHIP_ID
:
1017 /* read PMU chipcontrol register 3 */
1018 addr
= CORE_CC_REG(base
, chipcontrol_addr
);
1019 chip
->ops
->write32(chip
->ctx
, addr
, 3);
1020 addr
= CORE_CC_REG(base
, chipcontrol_data
);
1021 reg
= chip
->ops
->read32(chip
->ctx
, addr
);
1022 return (reg
& pmu_cc3_mask
) != 0;
1024 addr
= CORE_CC_REG(base
, pmucapabilities_ext
);
1025 reg
= chip
->ops
->read32(chip
->ctx
, addr
);
1026 if ((reg
& PCAPEXT_SR_SUPPORTED_MASK
) == 0)
1029 addr
= CORE_CC_REG(base
, retention_ctl
);
1030 reg
= chip
->ops
->read32(chip
->ctx
, addr
);
1031 return (reg
& (PMU_RCTL_MACPHY_DISABLE_MASK
|
1032 PMU_RCTL_LOGIC_DISABLE_MASK
)) == 0;