1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3 * Misc utility routines for accessing chip-specific features
4 * of the SiliconBackplane-based Broadcom chips.
5 *
6 * Copyright (C) 1999-2017, Broadcom Corporation
7 *
8 * Unless you and Broadcom execute a separate written software license
9 * agreement governing use of this software, this software is licensed to you
10 * under the terms of the GNU General Public License version 2 (the "GPL"),
11 * available at http://www.broadcom.com/licenses/GPLv2.php, with the
12 * following added to such license:
13 *
14 * As a special exception, the copyright holders of this software give you
15 * permission to link this software with independent modules, and to copy and
16 * distribute the resulting executable under terms of your choice, provided that
17 * you also meet, for each linked independent module, the terms and conditions of
18 * the license of that module. An independent module is a module which is not
19 * derived from this software. The special exception does not apply to any
20 * modifications of the software.
21 *
22 * Notwithstanding the above, under no circumstances may you combine this
23 * software in any way with any other Broadcom software provided under a license
24 * other than the GPL, without Broadcom's express prior written consent.
25 *
26 *
27 * <<Broadcom-WL-IPTag/Open:>>
28 *
29 * $Id: siutils.c 668442 2016-11-03 08:42:43Z $
30 */
31
32 #include <bcm_cfg.h>
33 #include <typedefs.h>
34 #include <bcmdefs.h>
35 #include <osl.h>
36 #include <bcmutils.h>
37 #include <siutils.h>
38 #include <bcmdevs.h>
39 #include <hndsoc.h>
40 #include <sbchipc.h>
41 #include <sbgci.h>
42 #ifdef BCMPCIEDEV
43 #include <pciedev.h>
44 #endif /* BCMPCIEDEV */
45 #include <pcicfg.h>
46 #include <sbpcmcia.h>
47 #include <sbsysmem.h>
48 #include <sbsocram.h>
49 #ifdef BCMSDIO
50 #include <bcmsdh.h>
51 #include <sdio.h>
52 #include <sbsdio.h>
53 #include <sbhnddma.h>
54 #include <sbsdpcmdev.h>
55 #include <bcmsdpcm.h>
56 #endif /* BCMSDIO */
57 #include <hndpmu.h>
58 #include <dhd_config.h>
59
60 #ifdef BCM_SDRBL
61 #include <hndcpu.h>
62 #endif /* BCM_SDRBL */
63 #ifdef HNDGCI
64 #include <hndgci.h>
65 #endif /* HNDGCI */
66 #ifdef BCMULP
67 #include <ulp.h>
68 #endif /* BCMULP */
69
70
71 #include "siutils_priv.h"
72 #ifdef SECI_UART
73 /* Defines the set of GPIOs to be used for SECI UART if not specified in NVRAM */
74 #define DEFAULT_SECI_UART_PINMUX_43430 0x0102
75 static bool force_seci_clk = 0;
76 #endif /* SECI_UART */
77
78 /**
79 * A set of PMU registers is clocked in the ILP domain, which has an implication on register write
80 * behavior: if such a register is written, it takes multiple ILP clocks for the PMU block to absorb
81 * the write. During that time the 'SlowWritePending' bit in the PMUStatus register is set.
82 */
83 #define PMUREGS_ILP_SENSITIVE(regoff) \
84 ((regoff) == OFFSETOF(pmuregs_t, pmutimer) || \
85 (regoff) == OFFSETOF(pmuregs_t, pmuwatchdog) || \
86 (regoff) == OFFSETOF(pmuregs_t, res_req_timer))
87
88 #define CHIPCREGS_ILP_SENSITIVE(regoff) \
89 ((regoff) == OFFSETOF(chipcregs_t, pmutimer) || \
90 (regoff) == OFFSETOF(chipcregs_t, pmuwatchdog) || \
91 (regoff) == OFFSETOF(chipcregs_t, res_req_timer))
92
93 #define GCI_FEM_CTRL_WAR 0x11111111
94
95 /* local prototypes */
96 static si_info_t *si_doattach(si_info_t *sii, uint devid, osl_t *osh, volatile void *regs,
97 uint bustype, void *sdh, char **vars, uint *varsz);
98 static bool si_buscore_prep(si_info_t *sii, uint bustype, uint devid, void *sdh);
99 static bool si_buscore_setup(si_info_t *sii, chipcregs_t *cc, uint bustype, uint32 savewin,
100 uint *origidx, volatile void *regs);
101
102
103 static bool si_pmu_is_ilp_sensitive(uint32 idx, uint regoff);
104
105
106
107 /* global variable to indicate reservation/release of gpio's */
108 static uint32 si_gpioreservation = 0;
109
110 /* global flag to prevent shared resources from being initialized multiple times in si_attach() */
111 static bool si_onetimeinit = FALSE;
112
113 #ifdef SR_DEBUG
114 static const uint32 si_power_island_test_array[] = {
115 0x0000, 0x0001, 0x0010, 0x0011,
116 0x0100, 0x0101, 0x0110, 0x0111,
117 0x1000, 0x1001, 0x1010, 0x1011,
118 0x1100, 0x1101, 0x1110, 0x1111
119 };
120 #endif /* SR_DEBUG */
121
122 int do_4360_pcie2_war = 0;
123
124 #ifdef BCMULP
125 /* Variable to store boot_type: warm_boot/cold_boot/etc. */
126 static int boot_type = 0;
127 #endif
128
129 /* global kernel resource */
130 static si_info_t ksii;
131 static si_cores_info_t ksii_cores_info;
132
133 static const char rstr_rmin[] = "rmin";
134 static const char rstr_rmax[] = "rmax";
135
136 /**
137 * Allocate an si handle. This function may be called multiple times.
138 *
139 * devid - pci device id (used to determine chip#)
140 * osh - opaque OS handle
141 * regs - virtual address of initial core registers
142 * bustype - pci/pcmcia/sb/sdio/etc
143 * vars - pointer to a to-be created pointer area for "environment" variables. Some callers of this
144 * function set 'vars' to NULL, making dereferencing of this parameter undesired.
145 * varsz - pointer to int to return the size of the vars
146 */
147 si_t *
si_attach(uint devid,osl_t * osh,volatile void * regs,uint bustype,void * sdh,char ** vars,uint * varsz)148 si_attach(uint devid, osl_t *osh, volatile void *regs,
149 uint bustype, void *sdh, char **vars, uint *varsz)
150 {
151 si_info_t *sii;
152 si_cores_info_t *cores_info;
153 /* alloc si_info_t */
154 if ((sii = MALLOCZ(osh, sizeof (si_info_t))) == NULL) {
155 SI_ERROR(("si_attach: malloc failed! malloced %d bytes\n", MALLOCED(osh)));
156 return (NULL);
157 }
158
159 /* alloc si_cores_info_t */
160 if ((cores_info = (si_cores_info_t *)MALLOCZ(osh, sizeof (si_cores_info_t))) == NULL) {
161 SI_ERROR(("si_attach: malloc failed! malloced %d bytes\n", MALLOCED(osh)));
162 MFREE(osh, sii, sizeof(si_info_t));
163 return (NULL);
164 }
165 sii->cores_info = cores_info;
166
167 if (si_doattach(sii, devid, osh, regs, bustype, sdh, vars, varsz) == NULL) {
168 MFREE(osh, sii, sizeof(si_info_t));
169 MFREE(osh, cores_info, sizeof(si_cores_info_t));
170 return (NULL);
171 }
172 sii->vars = vars ? *vars : NULL;
173 sii->varsz = varsz ? *varsz : 0;
174
175 return (si_t *)sii;
176 }
177
178
179 static uint32 wd_msticks; /**< watchdog timer ticks normalized to ms */
180
181 /** generic kernel variant of si_attach() */
182 si_t *
si_kattach(osl_t * osh)183 si_kattach(osl_t *osh)
184 {
185 static bool ksii_attached = FALSE;
186 si_cores_info_t *cores_info;
187
188 if (!ksii_attached) {
189 void *regs = NULL;
190 regs = REG_MAP(SI_ENUM_BASE, SI_CORE_SIZE);
191 cores_info = (si_cores_info_t *)&ksii_cores_info;
192 ksii.cores_info = cores_info;
193
194 ASSERT(osh);
195 if (si_doattach(&ksii, BCM4710_DEVICE_ID, osh, regs,
196 SI_BUS, NULL,
197 osh != SI_OSH ? &(ksii.vars) : NULL,
198 osh != SI_OSH ? &(ksii.varsz) : NULL) == NULL) {
199 SI_ERROR(("si_kattach: si_doattach failed\n"));
200 REG_UNMAP(regs);
201 return NULL;
202 }
203 REG_UNMAP(regs);
204
205 /* save ticks normalized to ms for si_watchdog_ms() */
206 if (PMUCTL_ENAB(&ksii.pub)) {
207 {
208 /* based on 32KHz ILP clock */
209 wd_msticks = 32;
210 }
211 } else {
212 wd_msticks = ALP_CLOCK / 1000;
213 }
214
215 ksii_attached = TRUE;
216 SI_MSG(("si_kattach done. ccrev = %d, wd_msticks = %d\n",
217 CCREV(ksii.pub.ccrev), wd_msticks));
218 }
219
220 return &ksii.pub;
221 }
222
223 static bool
si_buscore_prep(si_info_t * sii,uint bustype,uint devid,void * sdh)224 si_buscore_prep(si_info_t *sii, uint bustype, uint devid, void *sdh)
225 {
226 BCM_REFERENCE(sdh);
227 BCM_REFERENCE(devid);
228 /* need to set memseg flag for CF card first before any sb registers access */
229 if (BUSTYPE(bustype) == PCMCIA_BUS)
230 sii->memseg = TRUE;
231
232
233 #if defined(BCMSDIO)
234 if (BUSTYPE(bustype) == SDIO_BUS) {
235 int err;
236 uint8 clkset;
237
238 #ifdef DHD_LOAD_CHIPALIVE
239 if (dhd_chip_alive) {
240 goto skip;
241 }
242 #endif
243 /* Try forcing SDIO core to do ALPAvail request only */
244 clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_ALP_AVAIL_REQ;
245 bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err);
246 if (!err) {
247 uint8 clkval;
248
249 /* If register supported, wait for ALPAvail and then force ALP */
250 clkval = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, NULL);
251 if ((clkval & ~SBSDIO_AVBITS) == clkset) {
252 SPINWAIT(((clkval = bcmsdh_cfg_read(sdh, SDIO_FUNC_1,
253 SBSDIO_FUNC1_CHIPCLKCSR, NULL)), !SBSDIO_ALPAV(clkval)),
254 PMU_MAX_TRANSITION_DLY);
255 if (!SBSDIO_ALPAV(clkval)) {
256 SI_ERROR(("timeout on ALPAV wait, clkval 0x%02x\n",
257 clkval));
258 return FALSE;
259 }
260 clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_FORCE_ALP;
261 bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR,
262 clkset, &err);
263 OSL_DELAY(65);
264 }
265 }
266
267 #ifdef DHD_LOAD_CHIPALIVE
268 skip:
269 #endif
270 /* Also, disable the extra SDIO pull-ups */
271 bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_SDIOPULLUP, 0, NULL);
272 }
273
274 #endif /* BCMSDIO && BCMDONGLEHOST */
275
276 return TRUE;
277 }
278
279 uint32
si_get_pmu_reg_addr(si_t * sih,uint32 offset)280 si_get_pmu_reg_addr(si_t *sih, uint32 offset)
281 {
282 si_info_t *sii = SI_INFO(sih);
283 uint32 pmuaddr = INVALID_ADDR;
284 uint origidx = 0;
285
286 SI_MSG(("%s: pmu access, offset: %x\n", __FUNCTION__, offset));
287 if (!(sii->pub.cccaps & CC_CAP_PMU)) {
288 goto done;
289 }
290 if (AOB_ENAB(&sii->pub)) {
291 uint pmucoreidx;
292 pmuregs_t *pmu;
293 SI_MSG(("%s: AOBENAB: %x\n", __FUNCTION__, offset));
294 origidx = sii->curidx;
295 pmucoreidx = si_findcoreidx(&sii->pub, PMU_CORE_ID, 0);
296 pmu = si_setcoreidx(&sii->pub, pmucoreidx);
297 pmuaddr = (uint32)(uintptr)((volatile uint8*)pmu + offset);
298 si_setcoreidx(sih, origidx);
299 } else
300 pmuaddr = SI_ENUM_BASE + offset;
301
302 done:
303 SI_MSG(("%s: addrRET: %x\n", __FUNCTION__, pmuaddr));
304 return pmuaddr;
305 }
306
307 static bool
si_buscore_setup(si_info_t * sii,chipcregs_t * cc,uint bustype,uint32 savewin,uint * origidx,volatile void * regs)308 si_buscore_setup(si_info_t *sii, chipcregs_t *cc, uint bustype, uint32 savewin,
309 uint *origidx, volatile void *regs)
310 {
311 si_cores_info_t *cores_info = (si_cores_info_t *)sii->cores_info;
312 bool pci, pcie, pcie_gen2 = FALSE;
313 uint i;
314 uint pciidx, pcieidx, pcirev, pcierev;
315
316 #if defined(BCM_BACKPLANE_TIMEOUT) || defined(AXI_TIMEOUTS)
317 /* first, enable backplane timeouts */
318 si_slave_wrapper_add(&sii->pub);
319 #endif
320 sii->curidx = 0;
321
322 cc = si_setcoreidx(&sii->pub, SI_CC_IDX);
323 ASSERT((uintptr)cc);
324
325 /* get chipcommon rev */
326 sii->pub.ccrev = (int)si_corerev(&sii->pub);
327
328 /* get chipcommon chipstatus */
329 if (CCREV(sii->pub.ccrev) >= 11)
330 sii->pub.chipst = R_REG(sii->osh, &cc->chipstatus);
331
332 /* get chipcommon capabilites */
333 sii->pub.cccaps = R_REG(sii->osh, &cc->capabilities);
334 /* get chipcommon extended capabilities */
335
336 if (CCREV(sii->pub.ccrev) >= 35)
337 sii->pub.cccaps_ext = R_REG(sii->osh, &cc->capabilities_ext);
338
339 /* get pmu rev and caps */
340 if (sii->pub.cccaps & CC_CAP_PMU) {
341 if (AOB_ENAB(&sii->pub)) {
342 uint pmucoreidx;
343 pmuregs_t *pmu;
344 struct si_pub *sih = &sii->pub;
345
346 pmucoreidx = si_findcoreidx(&sii->pub, PMU_CORE_ID, 0);
347 if (!GOODIDX(pmucoreidx)) {
348 SI_ERROR(("si_buscore_setup: si_findcoreidx failed\n"));
349 return FALSE;
350 }
351
352 pmu = si_setcoreidx(&sii->pub, pmucoreidx);
353 sii->pub.pmucaps = R_REG(sii->osh, &pmu->pmucapabilities);
354 si_setcoreidx(&sii->pub, SI_CC_IDX);
355
356 sii->pub.gcirev = si_corereg(sih,
357 GCI_CORE_IDX(sih),
358 GCI_OFFSETOF(sih, gci_corecaps0), 0, 0) & GCI_CAP0_REV_MASK;
359 } else
360 sii->pub.pmucaps = R_REG(sii->osh, &cc->pmucapabilities);
361
362 sii->pub.pmurev = sii->pub.pmucaps & PCAP_REV_MASK;
363 }
364
365 SI_MSG(("Chipc: rev %d, caps 0x%x, chipst 0x%x pmurev %d, pmucaps 0x%x\n",
366 CCREV(sii->pub.ccrev), sii->pub.cccaps, sii->pub.chipst, sii->pub.pmurev,
367 sii->pub.pmucaps));
368
369 /* figure out bus/orignal core idx */
370 sii->pub.buscoretype = NODEV_CORE_ID;
371 sii->pub.buscorerev = (uint)NOREV;
372 sii->pub.buscoreidx = BADIDX;
373
374 pci = pcie = FALSE;
375 pcirev = pcierev = (uint)NOREV;
376 pciidx = pcieidx = BADIDX;
377
378 for (i = 0; i < sii->numcores; i++) {
379 uint cid, crev;
380
381 si_setcoreidx(&sii->pub, i);
382 cid = si_coreid(&sii->pub);
383 crev = si_corerev(&sii->pub);
384
385 /* Display cores found */
386 SI_VMSG(("CORE[%d]: id 0x%x rev %d base 0x%x regs 0x%p\n",
387 i, cid, crev, cores_info->coresba[i], cores_info->regs[i]));
388
389 if (BUSTYPE(bustype) == SI_BUS) {
390 /* now look at the chipstatus register to figure the pacakge */
391 /* for SDIO but downloaded on PCIE dev */
392 if (cid == PCIE2_CORE_ID) {
393 if (BCM43602_CHIP(sii->pub.chip) ||
394 (CHIPID(sii->pub.chip) == BCM4365_CHIP_ID) ||
395 (CHIPID(sii->pub.chip) == BCM4347_CHIP_ID) ||
396 (CHIPID(sii->pub.chip) == BCM4366_CHIP_ID) ||
397 ((BCM4345_CHIP(sii->pub.chip) ||
398 BCM4349_CHIP(sii->pub.chip)) &&
399 CST4345_CHIPMODE_PCIE(sii->pub.chipst))) {
400 pcieidx = i;
401 pcierev = crev;
402 pcie = TRUE;
403 pcie_gen2 = TRUE;
404 }
405 }
406
407 } else if (BUSTYPE(bustype) == PCI_BUS) {
408 if (cid == PCI_CORE_ID) {
409 pciidx = i;
410 pcirev = crev;
411 pci = TRUE;
412 } else if ((cid == PCIE_CORE_ID) || (cid == PCIE2_CORE_ID)) {
413 pcieidx = i;
414 pcierev = crev;
415 pcie = TRUE;
416 if (cid == PCIE2_CORE_ID)
417 pcie_gen2 = TRUE;
418 }
419 } else if ((BUSTYPE(bustype) == PCMCIA_BUS) &&
420 (cid == PCMCIA_CORE_ID)) {
421 sii->pub.buscorerev = crev;
422 sii->pub.buscoretype = cid;
423 sii->pub.buscoreidx = i;
424 }
425 #ifdef BCMSDIO
426 else if (((BUSTYPE(bustype) == SDIO_BUS) ||
427 (BUSTYPE(bustype) == SPI_BUS)) &&
428 ((cid == PCMCIA_CORE_ID) ||
429 (cid == SDIOD_CORE_ID))) {
430 sii->pub.buscorerev = crev;
431 sii->pub.buscoretype = cid;
432 sii->pub.buscoreidx = i;
433 }
434 #endif /* BCMSDIO */
435
436 /* find the core idx before entering this func. */
437 if ((savewin && (savewin == cores_info->coresba[i])) ||
438 (regs == cores_info->regs[i]))
439 *origidx = i;
440 }
441
442
443 #if defined(PCIE_FULL_DONGLE)
444 if (pcie) {
445 if (pcie_gen2)
446 sii->pub.buscoretype = PCIE2_CORE_ID;
447 else
448 sii->pub.buscoretype = PCIE_CORE_ID;
449 sii->pub.buscorerev = pcierev;
450 sii->pub.buscoreidx = pcieidx;
451 }
452 BCM_REFERENCE(pci);
453 BCM_REFERENCE(pcirev);
454 BCM_REFERENCE(pciidx);
455 #else
456 if (pci) {
457 sii->pub.buscoretype = PCI_CORE_ID;
458 sii->pub.buscorerev = pcirev;
459 sii->pub.buscoreidx = pciidx;
460 } else if (pcie) {
461 if (pcie_gen2)
462 sii->pub.buscoretype = PCIE2_CORE_ID;
463 else
464 sii->pub.buscoretype = PCIE_CORE_ID;
465 sii->pub.buscorerev = pcierev;
466 sii->pub.buscoreidx = pcieidx;
467 }
468 #endif /* defined(PCIE_FULL_DONGLE) */
469
470 SI_VMSG(("Buscore id/type/rev %d/0x%x/%d\n", sii->pub.buscoreidx, sii->pub.buscoretype,
471 sii->pub.buscorerev));
472
473
474 #if defined(BCMSDIO)
475 /* Make sure any on-chip ARM is off (in case strapping is wrong), or downloaded code was
476 * already running.
477 */
478 #ifdef DHD_LOAD_CHIPALIVE
479 if (!dhd_chip_alive) {
480 #endif
481 if ((BUSTYPE(bustype) == SDIO_BUS) || (BUSTYPE(bustype) == SPI_BUS)) {
482 if (si_setcore(&sii->pub, ARM7S_CORE_ID, 0) ||
483 si_setcore(&sii->pub, ARMCM3_CORE_ID, 0))
484 si_core_disable(&sii->pub, 0);
485 }
486 #ifdef DHD_LOAD_CHIPALIVE
487 }
488 #endif
489 #endif /* BCMSDIO && BCMDONGLEHOST */
490
491 /* return to the original core */
492 si_setcoreidx(&sii->pub, *origidx);
493
494 return TRUE;
495 }
496
497
498
499
500
501 uint16
si_chipid(si_t * sih)502 si_chipid(si_t *sih)
503 {
504 si_info_t *sii = SI_INFO(sih);
505
506 return (sii->chipnew) ? sii->chipnew : sih->chip;
507 }
508
509 /* CHIP_ID's being mapped here should not be used anywhere else in the code */
510 static void
si_chipid_fixup(si_t * sih)511 si_chipid_fixup(si_t *sih)
512 {
513 si_info_t *sii = SI_INFO(sih);
514
515 ASSERT(sii->chipnew == 0);
516 switch (sih->chip) {
517 case BCM43567_CHIP_ID:
518 sii->chipnew = sih->chip; /* save it */
519 sii->pub.chip = BCM43570_CHIP_ID; /* chip class */
520 break;
521 case BCM43562_CHIP_ID:
522 case BCM4358_CHIP_ID:
523 case BCM43566_CHIP_ID:
524 sii->chipnew = sih->chip; /* save it */
525 sii->pub.chip = BCM43569_CHIP_ID; /* chip class */
526 break;
527 case BCM4356_CHIP_ID:
528 case BCM4371_CHIP_ID:
529 sii->chipnew = sih->chip; /* save it */
530 sii->pub.chip = BCM4354_CHIP_ID; /* chip class */
531 break;
532 case BCM4357_CHIP_ID:
533 case BCM4361_CHIP_ID:
534 sii->chipnew = sih->chip; /* save it */
535 sii->pub.chip = BCM4347_CHIP_ID; /* chip class */
536 break;
537 default:
538 break;
539 }
540 }
541
542 #ifdef BCMULP
543 static void
si_check_boot_type(si_t * sih,osl_t * osh)544 si_check_boot_type(si_t *sih, osl_t *osh)
545 {
546 if (sih->pmurev >= 30) {
547 boot_type = PMU_REG_NEW(sih, swscratch, 0, 0);
548 } else {
549 boot_type = CHIPC_REG(sih, flashdata, 0, 0);
550 }
551
552 SI_ERROR(("%s: boot_type: 0x%08x\n", __func__, boot_type));
553 }
554 #endif /* BCMULP */
555
556 /**
557 * Allocate an si handle. This function may be called multiple times.
558 *
559 * vars - pointer to a to-be created pointer area for "environment" variables. Some callers of this
560 * function set 'vars' to NULL.
561 */
562 static si_info_t *
si_doattach(si_info_t * sii,uint devid,osl_t * osh,volatile void * regs,uint bustype,void * sdh,char ** vars,uint * varsz)563 si_doattach(si_info_t *sii, uint devid, osl_t *osh, volatile void *regs,
564 uint bustype, void *sdh, char **vars, uint *varsz)
565 {
566 struct si_pub *sih = &sii->pub;
567 uint32 w, savewin;
568 chipcregs_t *cc;
569 char *pvars = NULL;
570 uint origidx;
571 #if !defined(_CFEZ_) || defined(CFG_WL)
572 #endif
573
574 ASSERT(GOODREGS(regs));
575
576 savewin = 0;
577
578 sih->buscoreidx = BADIDX;
579 sii->device_removed = FALSE;
580
581 sii->curmap = regs;
582 sii->sdh = sdh;
583 sii->osh = osh;
584 sii->second_bar0win = ~0x0;
585
586 #if defined(BCM_BACKPLANE_TIMEOUT)
587 sih->err_info = MALLOCZ(osh, sizeof(si_axi_error_info_t));
588 if (sih->err_info == NULL) {
589 SI_ERROR(("%s: %d bytes MALLOC FAILED",
590 __FUNCTION__, sizeof(si_axi_error_info_t)));
591 return NULL;
592 }
593 #endif /* BCM_BACKPLANE_TIMEOUT */
594
595
596 /* check to see if we are a si core mimic'ing a pci core */
597 if ((bustype == PCI_BUS) &&
598 (OSL_PCI_READ_CONFIG(sii->osh, PCI_SPROM_CONTROL, sizeof(uint32)) == 0xffffffff)) {
599 SI_ERROR(("%s: incoming bus is PCI but it's a lie, switching to SI "
600 "devid:0x%x\n", __FUNCTION__, devid));
601 bustype = SI_BUS;
602 }
603
604 /* find Chipcommon address */
605 if (bustype == PCI_BUS) {
606 savewin = OSL_PCI_READ_CONFIG(sii->osh, PCI_BAR0_WIN, sizeof(uint32));
607 if (!GOODCOREADDR(savewin, SI_ENUM_BASE))
608 savewin = SI_ENUM_BASE;
609 OSL_PCI_WRITE_CONFIG(sii->osh, PCI_BAR0_WIN, 4, SI_ENUM_BASE);
610 if (!regs)
611 return NULL;
612 cc = (chipcregs_t *)regs;
613 #ifdef BCMSDIO
614 } else if ((bustype == SDIO_BUS) || (bustype == SPI_BUS)) {
615 cc = (chipcregs_t *)sii->curmap;
616 #endif
617 } else {
618 cc = (chipcregs_t *)REG_MAP(SI_ENUM_BASE, SI_CORE_SIZE);
619 }
620
621 sih->bustype = bustype;
622 #ifdef BCMBUSTYPE
623 if (bustype != BUSTYPE(bustype)) {
624 SI_ERROR(("si_doattach: bus type %d does not match configured bus type %d\n",
625 bustype, BUSTYPE(bustype)));
626 return NULL;
627 }
628 #endif
629
630 /* bus/core/clk setup for register access */
631 if (!si_buscore_prep(sii, bustype, devid, sdh)) {
632 SI_ERROR(("si_doattach: si_core_clk_prep failed %d\n", bustype));
633 return NULL;
634 }
635
636 /* ChipID recognition.
637 * We assume we can read chipid at offset 0 from the regs arg.
638 * If we add other chiptypes (or if we need to support old sdio hosts w/o chipcommon),
639 * some way of recognizing them needs to be added here.
640 */
641 if (!cc) {
642 SI_ERROR(("%s: chipcommon register space is null \n", __FUNCTION__));
643 return NULL;
644 }
645 w = R_REG(osh, &cc->chipid);
646 if ((w & 0xfffff) == 148277) w -= 65532;
647 sih->socitype = (w & CID_TYPE_MASK) >> CID_TYPE_SHIFT;
648 /* Might as wll fill in chip id rev & pkg */
649 sih->chip = w & CID_ID_MASK;
650 sih->chiprev = (w & CID_REV_MASK) >> CID_REV_SHIFT;
651 sih->chippkg = (w & CID_PKG_MASK) >> CID_PKG_SHIFT;
652
653 #if defined(BCMSDIO) && (defined(HW_OOB) || defined(FORCE_WOWLAN))
654 dhd_conf_set_hw_oob_intr(sdh, sih->chip);
655 #endif
656
657 si_chipid_fixup(sih);
658
659 sih->issim = IS_SIM(sih->chippkg);
660
661 /* scan for cores */
662 if (CHIPTYPE(sii->pub.socitype) == SOCI_SB) {
663 SI_MSG(("Found chip type SB (0x%08x)\n", w));
664 sb_scan(&sii->pub, regs, devid);
665 } else if ((CHIPTYPE(sii->pub.socitype) == SOCI_AI) ||
666 (CHIPTYPE(sii->pub.socitype) == SOCI_NAI)) {
667 if (CHIPTYPE(sii->pub.socitype) == SOCI_AI)
668 SI_MSG(("Found chip type AI (0x%08x)\n", w));
669 else
670 SI_MSG(("Found chip type NAI (0x%08x)\n", w));
671 /* pass chipc address instead of original core base */
672
673 sii->axi_wrapper = (axi_wrapper_t *)MALLOCZ(sii->osh,
674 (sizeof(axi_wrapper_t) * SI_MAX_AXI_WRAPPERS));
675
676 if (sii->axi_wrapper == NULL) {
677 SI_ERROR(("%s: %zu bytes MALLOC Failed", __FUNCTION__,
678 (sizeof(axi_wrapper_t) * SI_MAX_AXI_WRAPPERS)));
679 return NULL;
680 }
681
682 ai_scan(&sii->pub, (void *)(uintptr)cc, devid);
683 } else if (CHIPTYPE(sii->pub.socitype) == SOCI_UBUS) {
684 SI_MSG(("Found chip type UBUS (0x%08x), chip id = 0x%4x\n", w, sih->chip));
685 /* pass chipc address instead of original core base */
686 ub_scan(&sii->pub, (void *)(uintptr)cc, devid);
687 } else {
688 SI_ERROR(("Found chip of unknown type (0x%08x)\n", w));
689 return NULL;
690 }
691 /* no cores found, bail out */
692 if (sii->numcores == 0) {
693 SI_ERROR(("si_doattach: could not find any cores\n"));
694 return NULL;
695 }
696 /* bus/core/clk setup */
697 origidx = SI_CC_IDX;
698 if (!si_buscore_setup(sii, cc, bustype, savewin, &origidx, regs)) {
699 SI_ERROR(("si_doattach: si_buscore_setup failed\n"));
700 goto exit;
701 }
702 #ifdef BCMULP
703 si_check_boot_type(sih, osh);
704
705 if (ulp_module_init(osh, sih) != BCME_OK) {
706 ULP_ERR(("%s: err in ulp_module_init\n", __FUNCTION__));
707 goto exit;
708 }
709 #endif /* BCMULP */
710
711 #if !defined(_CFEZ_) || defined(CFG_WL)
712 /* assume current core is CC */
713 if ((CCREV(sii->pub.ccrev) == 0x25) && ((CHIPID(sih->chip) == BCM43236_CHIP_ID ||
714 CHIPID(sih->chip) == BCM43235_CHIP_ID ||
715 CHIPID(sih->chip) == BCM43234_CHIP_ID ||
716 CHIPID(sih->chip) == BCM43238_CHIP_ID) &&
717 (CHIPREV(sii->pub.chiprev) <= 2))) {
718
719 if ((cc->chipstatus & CST43236_BP_CLK) != 0) {
720 uint clkdiv;
721 clkdiv = R_REG(osh, &cc->clkdiv);
722 /* otp_clk_div is even number, 120/14 < 9mhz */
723 clkdiv = (clkdiv & ~CLKD_OTP) | (14 << CLKD_OTP_SHIFT);
724 W_REG(osh, &cc->clkdiv, clkdiv);
725 SI_ERROR(("%s: set clkdiv to %x\n", __FUNCTION__, clkdiv));
726 }
727 OSL_DELAY(10);
728 }
729
730 if (bustype == PCI_BUS) {
731
732 }
733 #endif
734 #ifdef BCM_SDRBL
735 /* 4360 rom bootloader in PCIE case, if the SDR is enabled, But preotection is
736 * not turned on, then we want to hold arm in reset.
737 * Bottomline: In sdrenable case, we allow arm to boot only when protection is
738 * turned on.
739 */
740 if (CHIP_HOSTIF_PCIE(&(sii->pub))) {
741 uint32 sflags = si_arm_sflags(&(sii->pub));
742
743 /* If SDR is enabled but protection is not turned on
744 * then we want to force arm to WFI.
745 */
746 if ((sflags & (SISF_SDRENABLE | SISF_TCMPROT)) == SISF_SDRENABLE) {
747 disable_arm_irq();
748 while (1) {
749 hnd_cpu_wait(sih);
750 }
751 }
752 }
753 #endif /* BCM_SDRBL */
754
755 pvars = NULL;
756 BCM_REFERENCE(pvars);
757
758 if (!si_onetimeinit) {
759
760
761 if (CCREV(sii->pub.ccrev) >= 20) {
762 uint32 gpiopullup = 0, gpiopulldown = 0;
763 cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0);
764 ASSERT(cc != NULL);
765
766 /* 4314/43142 has pin muxing, don't clear gpio bits */
767 if ((CHIPID(sih->chip) == BCM4314_CHIP_ID) ||
768 (CHIPID(sih->chip) == BCM43142_CHIP_ID)) {
769 gpiopullup |= 0x402e0;
770 gpiopulldown |= 0x20500;
771 }
772
773
774 W_REG(osh, &cc->gpiopullup, gpiopullup);
775 W_REG(osh, &cc->gpiopulldown, gpiopulldown);
776 si_setcoreidx(sih, origidx);
777 }
778
779 }
780
781 /* clear any previous epidiag-induced target abort */
782 ASSERT(!si_taclear(sih, FALSE));
783
784
785 #ifdef BOOTLOADER_CONSOLE_OUTPUT
786 /* Enable console prints */
787 si_muxenab(sii, 3);
788 #endif
789
790 return (sii);
791
792 exit:
793
794 return NULL;
795 }
796
797 /** may be called with core in reset */
798 void
si_detach(si_t * sih)799 si_detach(si_t *sih)
800 {
801 si_info_t *sii = SI_INFO(sih);
802 si_cores_info_t *cores_info = (si_cores_info_t *)sii->cores_info;
803 uint idx;
804
805
806 if (BUSTYPE(sih->bustype) == SI_BUS)
807 for (idx = 0; idx < SI_MAXCORES; idx++)
808 if (cores_info->regs[idx]) {
809 REG_UNMAP(cores_info->regs[idx]);
810 cores_info->regs[idx] = NULL;
811 }
812
813
814 #if !defined(BCMBUSTYPE) || (BCMBUSTYPE == SI_BUS)
815 if (cores_info != &ksii_cores_info)
816 #endif /* !BCMBUSTYPE || (BCMBUSTYPE == SI_BUS) */
817 MFREE(sii->osh, cores_info, sizeof(si_cores_info_t));
818
819 #if defined(BCM_BACKPLANE_TIMEOUT)
820 if (sih->err_info) {
821 MFREE(sii->osh, sih->err_info, sizeof(si_axi_error_info_t));
822 sii->pub.err_info = NULL;
823 }
824 #endif /* BCM_BACKPLANE_TIMEOUT */
825
826 if (sii->axi_wrapper) {
827 MFREE(sii->osh, sii->axi_wrapper,
828 (sizeof(axi_wrapper_t) * SI_MAX_AXI_WRAPPERS));
829 sii->axi_wrapper = NULL;
830 }
831
832 #if !defined(BCMBUSTYPE) || (BCMBUSTYPE == SI_BUS)
833 if (sii != &ksii)
834 #endif /* !BCMBUSTYPE || (BCMBUSTYPE == SI_BUS) */
835 MFREE(sii->osh, sii, sizeof(si_info_t));
836 }
837
838 void *
si_osh(si_t * sih)839 si_osh(si_t *sih)
840 {
841 si_info_t *sii;
842
843 sii = SI_INFO(sih);
844 return sii->osh;
845 }
846
847 void
si_setosh(si_t * sih,osl_t * osh)848 si_setosh(si_t *sih, osl_t *osh)
849 {
850 si_info_t *sii;
851
852 sii = SI_INFO(sih);
853 if (sii->osh != NULL) {
854 SI_ERROR(("osh is already set....\n"));
855 ASSERT(!sii->osh);
856 }
857 sii->osh = osh;
858 }
859
860 /** register driver interrupt disabling and restoring callback functions */
861 void
si_register_intr_callback(si_t * sih,void * intrsoff_fn,void * intrsrestore_fn,void * intrsenabled_fn,void * intr_arg)862 si_register_intr_callback(si_t *sih, void *intrsoff_fn, void *intrsrestore_fn,
863 void *intrsenabled_fn, void *intr_arg)
864 {
865 si_info_t *sii = SI_INFO(sih);
866 si_cores_info_t *cores_info = (si_cores_info_t *)sii->cores_info;
867 sii->intr_arg = intr_arg;
868 sii->intrsoff_fn = (si_intrsoff_t)intrsoff_fn;
869 sii->intrsrestore_fn = (si_intrsrestore_t)intrsrestore_fn;
870 sii->intrsenabled_fn = (si_intrsenabled_t)intrsenabled_fn;
871 /* save current core id. when this function called, the current core
872 * must be the core which provides driver functions(il, et, wl, etc.)
873 */
874 sii->dev_coreid = cores_info->coreid[sii->curidx];
875 }
876
877 void
si_deregister_intr_callback(si_t * sih)878 si_deregister_intr_callback(si_t *sih)
879 {
880 si_info_t *sii;
881
882 sii = SI_INFO(sih);
883 sii->intrsoff_fn = NULL;
884 sii->intrsrestore_fn = NULL;
885 sii->intrsenabled_fn = NULL;
886 }
887
888 uint
si_intflag(si_t * sih)889 si_intflag(si_t *sih)
890 {
891 si_info_t *sii = SI_INFO(sih);
892
893 if (CHIPTYPE(sih->socitype) == SOCI_SB)
894 return sb_intflag(sih);
895 else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI))
896 return R_REG(sii->osh, ((uint32 *)(uintptr)
897 (sii->oob_router + OOB_STATUSA)));
898 else {
899 ASSERT(0);
900 return 0;
901 }
902 }
903
904 uint
si_flag(si_t * sih)905 si_flag(si_t *sih)
906 {
907 if (CHIPTYPE(sih->socitype) == SOCI_SB)
908 return sb_flag(sih);
909 else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI))
910 return ai_flag(sih);
911 else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
912 return ub_flag(sih);
913 else {
914 ASSERT(0);
915 return 0;
916 }
917 }
918
919 uint
si_flag_alt(si_t * sih)920 si_flag_alt(si_t *sih)
921 {
922 if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI))
923 return ai_flag_alt(sih);
924 else {
925 ASSERT(0);
926 return 0;
927 }
928 }
929
930 void
si_setint(si_t * sih,int siflag)931 si_setint(si_t *sih, int siflag)
932 {
933 if (CHIPTYPE(sih->socitype) == SOCI_SB)
934 sb_setint(sih, siflag);
935 else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI))
936 ai_setint(sih, siflag);
937 else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
938 ub_setint(sih, siflag);
939 else
940 ASSERT(0);
941 }
942
943 uint
si_coreid(si_t * sih)944 si_coreid(si_t *sih)
945 {
946 si_info_t *sii = SI_INFO(sih);
947 si_cores_info_t *cores_info = (si_cores_info_t *)sii->cores_info;
948
949 return cores_info->coreid[sii->curidx];
950 }
951
952 uint
si_coreidx(si_t * sih)953 si_coreidx(si_t *sih)
954 {
955 si_info_t *sii;
956
957 sii = SI_INFO(sih);
958 return sii->curidx;
959 }
960
961 volatile void *
si_d11_switch_addrbase(si_t * sih,uint coreunit)962 si_d11_switch_addrbase(si_t *sih, uint coreunit)
963 {
964 return si_setcore(sih, D11_CORE_ID, coreunit);
965 }
966
967 /** return the core-type instantiation # of the current core */
968 uint
si_coreunit(si_t * sih)969 si_coreunit(si_t *sih)
970 {
971 si_info_t *sii = SI_INFO(sih);
972 si_cores_info_t *cores_info = (si_cores_info_t *)sii->cores_info;
973 uint idx;
974 uint coreid;
975 uint coreunit;
976 uint i;
977
978 coreunit = 0;
979
980 idx = sii->curidx;
981
982 ASSERT(GOODREGS(sii->curmap));
983 coreid = si_coreid(sih);
984
985 /* count the cores of our type */
986 for (i = 0; i < idx; i++)
987 if (cores_info->coreid[i] == coreid)
988 coreunit++;
989
990 return (coreunit);
991 }
992
993 uint
si_corevendor(si_t * sih)994 si_corevendor(si_t *sih)
995 {
996 if (CHIPTYPE(sih->socitype) == SOCI_SB)
997 return sb_corevendor(sih);
998 else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI))
999 return ai_corevendor(sih);
1000 else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
1001 return ub_corevendor(sih);
1002 else {
1003 ASSERT(0);
1004 return 0;
1005 }
1006 }
1007
1008 bool
si_backplane64(si_t * sih)1009 si_backplane64(si_t *sih)
1010 {
1011 return ((sih->cccaps & CC_CAP_BKPLN64) != 0);
1012 }
1013
1014 uint
si_corerev(si_t * sih)1015 si_corerev(si_t *sih)
1016 {
1017 if (CHIPTYPE(sih->socitype) == SOCI_SB)
1018 return sb_corerev(sih);
1019 else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI))
1020 return ai_corerev(sih);
1021 else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
1022 return ub_corerev(sih);
1023 else {
1024 ASSERT(0);
1025 return 0;
1026 }
1027 }
1028
1029 /* return index of coreid or BADIDX if not found */
1030 uint
si_findcoreidx(si_t * sih,uint coreid,uint coreunit)1031 si_findcoreidx(si_t *sih, uint coreid, uint coreunit)
1032 {
1033 si_info_t *sii = SI_INFO(sih);
1034 si_cores_info_t *cores_info = (si_cores_info_t *)sii->cores_info;
1035 uint found;
1036 uint i;
1037
1038
1039 found = 0;
1040
1041 for (i = 0; i < sii->numcores; i++)
1042 if (cores_info->coreid[i] == coreid) {
1043 if (found == coreunit)
1044 return (i);
1045 found++;
1046 }
1047
1048 return (BADIDX);
1049 }
1050
1051 /** return total coreunit of coreid or zero if not found */
1052 uint
si_numcoreunits(si_t * sih,uint coreid)1053 si_numcoreunits(si_t *sih, uint coreid)
1054 {
1055 if ((CHIPID(sih->chip) == BCM4347_CHIP_ID) &&
1056 (CHIPREV(sih->chiprev) == 0)) {
1057 /*
1058 * 4347TC2 does not have Aux core.
1059 * fixed to 1 here because EROM (using 4349 EROM) has two entries
1060 */
1061 return 1;
1062 } else {
1063 si_info_t *sii = SI_INFO(sih);
1064 si_cores_info_t *cores_info = (si_cores_info_t *)sii->cores_info;
1065 uint found = 0;
1066 uint i;
1067
1068 for (i = 0; i < sii->numcores; i++) {
1069 if (cores_info->coreid[i] == coreid) {
1070 found++;
1071 }
1072 }
1073
1074 return found;
1075 }
1076 }
1077
1078 /** return total D11 coreunits */
1079 uint
BCMRAMFN(si_numd11coreunits)1080 BCMRAMFN(si_numd11coreunits)(si_t *sih)
1081 {
1082 uint found = 0;
1083
1084 found = si_numcoreunits(sih, D11_CORE_ID);
1085
1086 #if defined(WLRSDB) && defined(WLRSDB_DISABLED)
1087 /* If RSDB functionality is compiled out,
1088 * then ignore any D11 cores beyond the first
1089 * Used in norsdb dongle build variants for rsdb chip.
1090 */
1091 found = 1;
1092 #endif /* defined(WLRSDB) && !defined(WLRSDB_DISABLED) */
1093
1094 return found;
1095 }
1096
1097 /** return list of found cores */
1098 uint
si_corelist(si_t * sih,uint coreid[])1099 si_corelist(si_t *sih, uint coreid[])
1100 {
1101 si_info_t *sii = SI_INFO(sih);
1102 si_cores_info_t *cores_info = (si_cores_info_t *)sii->cores_info;
1103
1104 bcopy((uchar*)cores_info->coreid, (uchar*)coreid, (sii->numcores * sizeof(uint)));
1105 return (sii->numcores);
1106 }
1107
1108 /** return current wrapper mapping */
1109 void *
si_wrapperregs(si_t * sih)1110 si_wrapperregs(si_t *sih)
1111 {
1112 si_info_t *sii;
1113
1114 sii = SI_INFO(sih);
1115 ASSERT(GOODREGS(sii->curwrap));
1116
1117 return (sii->curwrap);
1118 }
1119
1120 /** return current register mapping */
1121 volatile void *
si_coreregs(si_t * sih)1122 si_coreregs(si_t *sih)
1123 {
1124 si_info_t *sii;
1125
1126 sii = SI_INFO(sih);
1127 ASSERT(GOODREGS(sii->curmap));
1128
1129 return (sii->curmap);
1130 }
1131
1132
1133 /**
1134 * This function changes logical "focus" to the indicated core;
1135 * must be called with interrupts off.
1136 * Moreover, callers should keep interrupts off during switching out of and back to d11 core
1137 */
1138 volatile void *
si_setcore(si_t * sih,uint coreid,uint coreunit)1139 si_setcore(si_t *sih, uint coreid, uint coreunit)
1140 {
1141 uint idx;
1142
1143 idx = si_findcoreidx(sih, coreid, coreunit);
1144 if (!GOODIDX(idx))
1145 return (NULL);
1146
1147 if (CHIPTYPE(sih->socitype) == SOCI_SB)
1148 return sb_setcoreidx(sih, idx);
1149 else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI))
1150 return ai_setcoreidx(sih, idx);
1151 else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
1152 return ub_setcoreidx(sih, idx);
1153 else {
1154 ASSERT(0);
1155 return NULL;
1156 }
1157 }
1158
1159 volatile void *
si_setcoreidx(si_t * sih,uint coreidx)1160 si_setcoreidx(si_t *sih, uint coreidx)
1161 {
1162 if (CHIPTYPE(sih->socitype) == SOCI_SB)
1163 return sb_setcoreidx(sih, coreidx);
1164 else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI))
1165 return ai_setcoreidx(sih, coreidx);
1166 else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
1167 return ub_setcoreidx(sih, coreidx);
1168 else {
1169 ASSERT(0);
1170 return NULL;
1171 }
1172 }
1173
1174 /** Turn off interrupt as required by sb_setcore, before switch core */
1175 volatile void *
si_switch_core(si_t * sih,uint coreid,uint * origidx,uint * intr_val)1176 si_switch_core(si_t *sih, uint coreid, uint *origidx, uint *intr_val)
1177 {
1178 volatile void *cc;
1179 si_info_t *sii = SI_INFO(sih);
1180
1181 if (SI_FAST(sii)) {
1182 /* Overloading the origidx variable to remember the coreid,
1183 * this works because the core ids cannot be confused with
1184 * core indices.
1185 */
1186 *origidx = coreid;
1187 if (coreid == CC_CORE_ID)
1188 return (volatile void *)CCREGS_FAST(sii);
1189 else if (coreid == BUSCORETYPE(sih->buscoretype))
1190 return (volatile void *)PCIEREGS(sii);
1191 }
1192 INTR_OFF(sii, *intr_val);
1193 *origidx = sii->curidx;
1194 cc = si_setcore(sih, coreid, 0);
1195 ASSERT(cc != NULL);
1196
1197 return cc;
1198 }
1199
1200 /* restore coreidx and restore interrupt */
1201 void
si_restore_core(si_t * sih,uint coreid,uint intr_val)1202 si_restore_core(si_t *sih, uint coreid, uint intr_val)
1203 {
1204 si_info_t *sii = SI_INFO(sih);
1205
1206 if (SI_FAST(sii) && ((coreid == CC_CORE_ID) || (coreid == BUSCORETYPE(sih->buscoretype))))
1207 return;
1208
1209 si_setcoreidx(sih, coreid);
1210 INTR_RESTORE(sii, intr_val);
1211 }
1212
1213 int
si_numaddrspaces(si_t * sih)1214 si_numaddrspaces(si_t *sih)
1215 {
1216 if (CHIPTYPE(sih->socitype) == SOCI_SB)
1217 return sb_numaddrspaces(sih);
1218 else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI))
1219 return ai_numaddrspaces(sih);
1220 else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
1221 return ub_numaddrspaces(sih);
1222 else {
1223 ASSERT(0);
1224 return 0;
1225 }
1226 }
1227
1228 uint32
si_addrspace(si_t * sih,uint asidx)1229 si_addrspace(si_t *sih, uint asidx)
1230 {
1231 if (CHIPTYPE(sih->socitype) == SOCI_SB)
1232 return sb_addrspace(sih, asidx);
1233 else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI))
1234 return ai_addrspace(sih, asidx);
1235 else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
1236 return ub_addrspace(sih, asidx);
1237 else {
1238 ASSERT(0);
1239 return 0;
1240 }
1241 }
1242
1243 uint32
si_addrspacesize(si_t * sih,uint asidx)1244 si_addrspacesize(si_t *sih, uint asidx)
1245 {
1246 if (CHIPTYPE(sih->socitype) == SOCI_SB)
1247 return sb_addrspacesize(sih, asidx);
1248 else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI))
1249 return ai_addrspacesize(sih, asidx);
1250 else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
1251 return ub_addrspacesize(sih, asidx);
1252 else {
1253 ASSERT(0);
1254 return 0;
1255 }
1256 }
1257
1258 void
si_coreaddrspaceX(si_t * sih,uint asidx,uint32 * addr,uint32 * size)1259 si_coreaddrspaceX(si_t *sih, uint asidx, uint32 *addr, uint32 *size)
1260 {
1261 /* Only supported for SOCI_AI */
1262 if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI))
1263 ai_coreaddrspaceX(sih, asidx, addr, size);
1264 else
1265 *size = 0;
1266 }
1267
1268 uint32
si_core_cflags(si_t * sih,uint32 mask,uint32 val)1269 si_core_cflags(si_t *sih, uint32 mask, uint32 val)
1270 {
1271 if (CHIPTYPE(sih->socitype) == SOCI_SB)
1272 return sb_core_cflags(sih, mask, val);
1273 else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI))
1274 return ai_core_cflags(sih, mask, val);
1275 else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
1276 return ub_core_cflags(sih, mask, val);
1277 else {
1278 ASSERT(0);
1279 return 0;
1280 }
1281 }
1282
1283 void
si_core_cflags_wo(si_t * sih,uint32 mask,uint32 val)1284 si_core_cflags_wo(si_t *sih, uint32 mask, uint32 val)
1285 {
1286 if (CHIPTYPE(sih->socitype) == SOCI_SB)
1287 sb_core_cflags_wo(sih, mask, val);
1288 else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI))
1289 ai_core_cflags_wo(sih, mask, val);
1290 else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
1291 ub_core_cflags_wo(sih, mask, val);
1292 else
1293 ASSERT(0);
1294 }
1295
1296 uint32
si_core_sflags(si_t * sih,uint32 mask,uint32 val)1297 si_core_sflags(si_t *sih, uint32 mask, uint32 val)
1298 {
1299 if (CHIPTYPE(sih->socitype) == SOCI_SB)
1300 return sb_core_sflags(sih, mask, val);
1301 else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI))
1302 return ai_core_sflags(sih, mask, val);
1303 else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
1304 return ub_core_sflags(sih, mask, val);
1305 else {
1306 ASSERT(0);
1307 return 0;
1308 }
1309 }
1310
1311 void
si_commit(si_t * sih)1312 si_commit(si_t *sih)
1313 {
1314 if (CHIPTYPE(sih->socitype) == SOCI_SB)
1315 sb_commit(sih);
1316 else if (CHIPTYPE(sih->socitype) == SOCI_AI || CHIPTYPE(sih->socitype) == SOCI_NAI)
1317 ;
1318 else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
1319 ;
1320 else {
1321 ASSERT(0);
1322 }
1323 }
1324
1325 bool
si_iscoreup(si_t * sih)1326 si_iscoreup(si_t *sih)
1327 {
1328 if (CHIPTYPE(sih->socitype) == SOCI_SB)
1329 return sb_iscoreup(sih);
1330 else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI))
1331 return ai_iscoreup(sih);
1332 else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
1333 return ub_iscoreup(sih);
1334 else {
1335 ASSERT(0);
1336 return FALSE;
1337 }
1338 }
1339
1340 uint
si_wrapperreg(si_t * sih,uint32 offset,uint32 mask,uint32 val)1341 si_wrapperreg(si_t *sih, uint32 offset, uint32 mask, uint32 val)
1342 {
1343 /* only for AI back plane chips */
1344 if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI))
1345 return (ai_wrap_reg(sih, offset, mask, val));
1346 return 0;
1347 }
1348 /* si_backplane_access is used to read full backplane address from host for PCIE FD
1349 * it uses secondary bar-0 window which lies at an offset of 16K from primary bar-0
1350 * Provides support for read/write of 1/2/4 bytes of backplane address
1351 * Can be used to read/write
1352 * 1. core regs
1353 * 2. Wrapper regs
1354 * 3. memory
1355 * 4. BT area
1356 * For accessing any 32 bit backplane address, [31 : 12] of backplane should be given in "region"
1357 * [11 : 0] should be the "regoff"
1358 * for reading 4 bytes from reg 0x200 of d11 core use it like below
1359 * : si_backplane_access(sih, 0x18001000, 0x200, 4, 0, TRUE)
1360 */
si_backplane_addr_sane(uint addr,uint size)1361 static int si_backplane_addr_sane(uint addr, uint size)
1362 {
1363 int bcmerror = BCME_OK;
1364
1365 /* For 2 byte access, address has to be 2 byte aligned */
1366 if (size == 2) {
1367 if (addr & 0x1) {
1368 bcmerror = BCME_ERROR;
1369 }
1370 }
1371 /* For 4 byte access, address has to be 4 byte aligned */
1372 if (size == 4) {
1373 if (addr & 0x3) {
1374 bcmerror = BCME_ERROR;
1375 }
1376 }
1377 return bcmerror;
1378 }
1379
1380 void
si_invalidate_second_bar0win(si_t * sih)1381 si_invalidate_second_bar0win(si_t *sih)
1382 {
1383 si_info_t *sii = SI_INFO(sih);
1384 sii->second_bar0win = ~0x0;
1385 }
1386
1387 uint
si_backplane_access(si_t * sih,uint addr,uint size,uint * val,bool read)1388 si_backplane_access(si_t *sih, uint addr, uint size, uint *val, bool read)
1389 {
1390 volatile uint32 *r = NULL;
1391 uint32 region = 0;
1392 si_info_t *sii = SI_INFO(sih);
1393
1394 /* Valid only for pcie bus */
1395 if (BUSTYPE(sih->bustype) != PCI_BUS) {
1396 SI_ERROR(("Valid only for pcie bus \n"));
1397 return BCME_ERROR;
1398 }
1399
1400 /* Split adrr into region and address offset */
1401 region = (addr & (0xFFFFF << 12));
1402 addr = addr & 0xFFF;
1403
1404 /* check for address and size sanity */
1405 if (si_backplane_addr_sane(addr, size) != BCME_OK)
1406 return BCME_ERROR;
1407
1408 /* Update window if required */
1409 if (sii->second_bar0win != region) {
1410 OSL_PCI_WRITE_CONFIG(sii->osh, PCIE2_BAR0_CORE2_WIN, 4, region);
1411 sii->second_bar0win = region;
1412 }
1413
1414 /* Estimate effective address
1415 * sii->curmap : bar-0 virtual address
1416 * PCI_SECOND_BAR0_OFFSET : secondar bar-0 offset
1417 * regoff : actual reg offset
1418 */
1419 r = (volatile uint32 *)((volatile char *)sii->curmap + PCI_SECOND_BAR0_OFFSET + addr);
1420
1421 SI_VMSG(("si curmap %p region %x regaddr %x effective addr %p READ %d\n",
1422 (volatile char*)sii->curmap, region, addr, r, read));
1423
1424 switch (size) {
1425 case sizeof(uint8) :
1426 if (read)
1427 *val = R_REG(sii->osh, (volatile uint8*)r);
1428 else
1429 W_REG(sii->osh, (volatile uint8*)r, *val);
1430 break;
1431 case sizeof(uint16) :
1432 if (read)
1433 *val = R_REG(sii->osh, (volatile uint16*)r);
1434 else
1435 W_REG(sii->osh, (volatile uint16*)r, *val);
1436 break;
1437 case sizeof(uint32) :
1438 if (read)
1439 *val = R_REG(sii->osh, (volatile uint32*)r);
1440 else
1441 W_REG(sii->osh, (volatile uint32*)r, *val);
1442 break;
1443 default :
1444 SI_ERROR(("Invalid size %d \n", size));
1445 return (BCME_ERROR);
1446 break;
1447 }
1448
1449 return (BCME_OK);
1450 }
1451 uint
si_corereg(si_t * sih,uint coreidx,uint regoff,uint mask,uint val)1452 si_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, uint val)
1453 {
1454 if (CHIPTYPE(sih->socitype) == SOCI_SB)
1455 return sb_corereg(sih, coreidx, regoff, mask, val);
1456 else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI))
1457 return ai_corereg(sih, coreidx, regoff, mask, val);
1458 else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
1459 return ub_corereg(sih, coreidx, regoff, mask, val);
1460 else {
1461 ASSERT(0);
1462 return 0;
1463 }
1464 }
1465
1466 /** ILP sensitive register access needs special treatment to avoid backplane stalls */
si_pmu_is_ilp_sensitive(uint32 idx,uint regoff)1467 bool si_pmu_is_ilp_sensitive(uint32 idx, uint regoff)
1468 {
1469 if (idx == SI_CC_IDX) {
1470 if (CHIPCREGS_ILP_SENSITIVE(regoff))
1471 return TRUE;
1472 } else if (PMUREGS_ILP_SENSITIVE(regoff)) {
1473 return TRUE;
1474 }
1475
1476 return FALSE;
1477 }
1478
1479 /** 'idx' should refer either to the chipcommon core or the PMU core */
1480 uint
si_pmu_corereg(si_t * sih,uint32 idx,uint regoff,uint mask,uint val)1481 si_pmu_corereg(si_t *sih, uint32 idx, uint regoff, uint mask, uint val)
1482 {
1483 int pmustatus_offset;
1484
1485 /* prevent backplane stall on double write to 'ILP domain' registers in the PMU */
1486 if (mask != 0 && PMUREV(sih->pmurev) >= 22 &&
1487 si_pmu_is_ilp_sensitive(idx, regoff)) {
1488 pmustatus_offset = AOB_ENAB(sih) ? OFFSETOF(pmuregs_t, pmustatus) :
1489 OFFSETOF(chipcregs_t, pmustatus);
1490
1491 while (si_corereg(sih, idx, pmustatus_offset, 0, 0) & PST_SLOW_WR_PENDING)
1492 {};
1493 }
1494
1495 return si_corereg(sih, idx, regoff, mask, val);
1496 }
1497
1498 /*
1499 * If there is no need for fiddling with interrupts or core switches (typically silicon
1500 * back plane registers, pci registers and chipcommon registers), this function
1501 * returns the register offset on this core to a mapped address. This address can
1502 * be used for W_REG/R_REG directly.
1503 *
1504 * For accessing registers that would need a core switch, this function will return
1505 * NULL.
1506 */
1507 volatile uint32 *
si_corereg_addr(si_t * sih,uint coreidx,uint regoff)1508 si_corereg_addr(si_t *sih, uint coreidx, uint regoff)
1509 {
1510 if (CHIPTYPE(sih->socitype) == SOCI_SB)
1511 return sb_corereg_addr(sih, coreidx, regoff);
1512 else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI))
1513 return ai_corereg_addr(sih, coreidx, regoff);
1514 else {
1515 return 0;
1516 }
1517 }
1518
1519 void
si_core_disable(si_t * sih,uint32 bits)1520 si_core_disable(si_t *sih, uint32 bits)
1521 {
1522 if (CHIPTYPE(sih->socitype) == SOCI_SB)
1523 sb_core_disable(sih, bits);
1524 else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI))
1525 ai_core_disable(sih, bits);
1526 else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
1527 ub_core_disable(sih, bits);
1528 }
1529
1530 void
si_core_reset(si_t * sih,uint32 bits,uint32 resetbits)1531 si_core_reset(si_t *sih, uint32 bits, uint32 resetbits)
1532 {
1533 if (CHIPTYPE(sih->socitype) == SOCI_SB)
1534 sb_core_reset(sih, bits, resetbits);
1535 else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI))
1536 ai_core_reset(sih, bits, resetbits);
1537 else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
1538 ub_core_reset(sih, bits, resetbits);
1539 }
1540
1541 /** Run bist on current core. Caller needs to take care of core-specific bist hazards */
1542 int
si_corebist(si_t * sih)1543 si_corebist(si_t *sih)
1544 {
1545 uint32 cflags;
1546 int result = 0;
1547
1548 /* Read core control flags */
1549 cflags = si_core_cflags(sih, 0, 0);
1550
1551 /* Set bist & fgc */
1552 si_core_cflags(sih, ~0, (SICF_BIST_EN | SICF_FGC));
1553
1554 /* Wait for bist done */
1555 SPINWAIT(((si_core_sflags(sih, 0, 0) & SISF_BIST_DONE) == 0), 100000);
1556
1557 if (si_core_sflags(sih, 0, 0) & SISF_BIST_ERROR)
1558 result = BCME_ERROR;
1559
1560 /* Reset core control flags */
1561 si_core_cflags(sih, 0xffff, cflags);
1562
1563 return result;
1564 }
1565
1566 uint
si_num_slaveports(si_t * sih,uint coreid)1567 si_num_slaveports(si_t *sih, uint coreid)
1568 {
1569 uint idx = si_findcoreidx(sih, coreid, 0);
1570 uint num = 0;
1571
1572 if ((CHIPTYPE(sih->socitype) == SOCI_AI))
1573 num = ai_num_slaveports(sih, idx);
1574
1575 return num;
1576 }
1577
1578 uint32
si_get_slaveport_addr(si_t * sih,uint asidx,uint core_id,uint coreunit)1579 si_get_slaveport_addr(si_t *sih, uint asidx, uint core_id, uint coreunit)
1580 {
1581 si_info_t *sii = SI_INFO(sih);
1582 uint origidx = sii->curidx;
1583 uint32 addr = 0x0;
1584
1585 if (!((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI)))
1586 goto done;
1587
1588 si_setcore(sih, core_id, coreunit);
1589
1590 addr = ai_addrspace(sih, asidx);
1591
1592 si_setcoreidx(sih, origidx);
1593
1594 done:
1595 return addr;
1596 }
1597
1598 uint32
si_get_d11_slaveport_addr(si_t * sih,uint asidx,uint coreunit)1599 si_get_d11_slaveport_addr(si_t *sih, uint asidx, uint coreunit)
1600 {
1601 si_info_t *sii = SI_INFO(sih);
1602 uint origidx = sii->curidx;
1603 uint32 addr = 0x0;
1604
1605 if (!((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI)))
1606 goto done;
1607
1608 si_setcore(sih, D11_CORE_ID, coreunit);
1609
1610 addr = ai_addrspace(sih, asidx);
1611
1612 si_setcoreidx(sih, origidx);
1613
1614 done:
1615 return addr;
1616 }
1617
1618 static uint32
factor6(uint32 x)1619 factor6(uint32 x)
1620 {
1621 switch (x) {
1622 case CC_F6_2: return 2;
1623 case CC_F6_3: return 3;
1624 case CC_F6_4: return 4;
1625 case CC_F6_5: return 5;
1626 case CC_F6_6: return 6;
1627 case CC_F6_7: return 7;
1628 default: return 0;
1629 }
1630 }
1631
1632 /*
1633 * Divide the clock by the divisor with protection for
1634 * a zero divisor.
1635 */
1636 static uint32
divide_clock(uint32 clock,uint32 div)1637 divide_clock(uint32 clock, uint32 div)
1638 {
1639 return div ? clock / div : 0;
1640 }
1641
1642
1643 /** calculate the speed the SI would run at given a set of clockcontrol values */
1644 uint32
si_clock_rate(uint32 pll_type,uint32 n,uint32 m)1645 si_clock_rate(uint32 pll_type, uint32 n, uint32 m)
1646 {
1647 uint32 n1, n2, clock, m1, m2, m3, mc;
1648
1649 n1 = n & CN_N1_MASK;
1650 n2 = (n & CN_N2_MASK) >> CN_N2_SHIFT;
1651
1652 if (pll_type == PLL_TYPE6) {
1653 if (m & CC_T6_MMASK)
1654 return CC_T6_M1;
1655 else
1656 return CC_T6_M0;
1657 } else if ((pll_type == PLL_TYPE1) ||
1658 (pll_type == PLL_TYPE3) ||
1659 (pll_type == PLL_TYPE4) ||
1660 (pll_type == PLL_TYPE7)) {
1661 n1 = factor6(n1);
1662 n2 += CC_F5_BIAS;
1663 } else if (pll_type == PLL_TYPE2) {
1664 n1 += CC_T2_BIAS;
1665 n2 += CC_T2_BIAS;
1666 ASSERT((n1 >= 2) && (n1 <= 7));
1667 ASSERT((n2 >= 5) && (n2 <= 23));
1668 } else if (pll_type == PLL_TYPE5) {
1669 return (100000000);
1670 } else
1671 ASSERT(0);
1672 /* PLL types 3 and 7 use BASE2 (25Mhz) */
1673 if ((pll_type == PLL_TYPE3) ||
1674 (pll_type == PLL_TYPE7)) {
1675 clock = CC_CLOCK_BASE2 * n1 * n2;
1676 } else
1677 clock = CC_CLOCK_BASE1 * n1 * n2;
1678
1679 if (clock == 0)
1680 return 0;
1681
1682 m1 = m & CC_M1_MASK;
1683 m2 = (m & CC_M2_MASK) >> CC_M2_SHIFT;
1684 m3 = (m & CC_M3_MASK) >> CC_M3_SHIFT;
1685 mc = (m & CC_MC_MASK) >> CC_MC_SHIFT;
1686
1687 if ((pll_type == PLL_TYPE1) ||
1688 (pll_type == PLL_TYPE3) ||
1689 (pll_type == PLL_TYPE4) ||
1690 (pll_type == PLL_TYPE7)) {
1691 m1 = factor6(m1);
1692 if ((pll_type == PLL_TYPE1) || (pll_type == PLL_TYPE3))
1693 m2 += CC_F5_BIAS;
1694 else
1695 m2 = factor6(m2);
1696 m3 = factor6(m3);
1697
1698 switch (mc) {
1699 case CC_MC_BYPASS: return (clock);
1700 case CC_MC_M1: return divide_clock(clock, m1);
1701 case CC_MC_M1M2: return divide_clock(clock, m1 * m2);
1702 case CC_MC_M1M2M3: return divide_clock(clock, m1 * m2 * m3);
1703 case CC_MC_M1M3: return divide_clock(clock, m1 * m3);
1704 default: return (0);
1705 }
1706 } else {
1707 ASSERT(pll_type == PLL_TYPE2);
1708
1709 m1 += CC_T2_BIAS;
1710 m2 += CC_T2M2_BIAS;
1711 m3 += CC_T2_BIAS;
1712 ASSERT((m1 >= 2) && (m1 <= 7));
1713 ASSERT((m2 >= 3) && (m2 <= 10));
1714 ASSERT((m3 >= 2) && (m3 <= 7));
1715
1716 if ((mc & CC_T2MC_M1BYP) == 0)
1717 clock /= m1;
1718 if ((mc & CC_T2MC_M2BYP) == 0)
1719 clock /= m2;
1720 if ((mc & CC_T2MC_M3BYP) == 0)
1721 clock /= m3;
1722
1723 return (clock);
1724 }
1725 }
1726
1727 /**
1728 * Some chips could have multiple host interfaces, however only one will be active.
1729 * For a given chip. Depending pkgopt and cc_chipst return the active host interface.
1730 */
1731 uint
si_chip_hostif(si_t * sih)1732 si_chip_hostif(si_t *sih)
1733 {
1734 uint hosti = 0;
1735
1736 switch (CHIPID(sih->chip)) {
1737 case BCM43018_CHIP_ID:
1738 case BCM43430_CHIP_ID:
1739 hosti = CHIP_HOSTIF_SDIOMODE;
1740 break;
1741 case BCM43012_CHIP_ID:
1742 hosti = CHIP_HOSTIF_SDIOMODE;
1743 break;
1744 CASE_BCM43602_CHIP:
1745 hosti = CHIP_HOSTIF_PCIEMODE;
1746 break;
1747
1748 case BCM4360_CHIP_ID:
1749 /* chippkg bit-0 == 0 is PCIE only pkgs
1750 * chippkg bit-0 == 1 has both PCIE and USB cores enabled
1751 */
1752 if ((sih->chippkg & 0x1) && (sih->chipst & CST4360_MODE_USB))
1753 hosti = CHIP_HOSTIF_USBMODE;
1754 else
1755 hosti = CHIP_HOSTIF_PCIEMODE;
1756
1757 break;
1758
1759 case BCM4335_CHIP_ID:
1760 /* TBD: like in 4360, do we need to check pkg? */
1761 if (CST4335_CHIPMODE_USB20D(sih->chipst))
1762 hosti = CHIP_HOSTIF_USBMODE;
1763 else if (CST4335_CHIPMODE_SDIOD(sih->chipst))
1764 hosti = CHIP_HOSTIF_SDIOMODE;
1765 else
1766 hosti = CHIP_HOSTIF_PCIEMODE;
1767 break;
1768
1769 CASE_BCM4345_CHIP:
1770 if (CST4345_CHIPMODE_USB20D(sih->chipst) || CST4345_CHIPMODE_HSIC(sih->chipst))
1771 hosti = CHIP_HOSTIF_USBMODE;
1772 else if (CST4345_CHIPMODE_SDIOD(sih->chipst))
1773 hosti = CHIP_HOSTIF_SDIOMODE;
1774 else if (CST4345_CHIPMODE_PCIE(sih->chipst))
1775 hosti = CHIP_HOSTIF_PCIEMODE;
1776 break;
1777
1778 case BCM4349_CHIP_GRPID:
1779 case BCM53573_CHIP_GRPID:
1780 if (CST4349_CHIPMODE_SDIOD(sih->chipst))
1781 hosti = CHIP_HOSTIF_SDIOMODE;
1782 else if (CST4349_CHIPMODE_PCIE(sih->chipst))
1783 hosti = CHIP_HOSTIF_PCIEMODE;
1784 break;
1785 case BCM4347_CHIP_ID:
1786 if (CST4347_CHIPMODE_SDIOD(sih->chipst))
1787 hosti = CHIP_HOSTIF_SDIOMODE;
1788 else if (CST4347_CHIPMODE_PCIE(sih->chipst))
1789 hosti = CHIP_HOSTIF_PCIEMODE;
1790 break;
1791
1792 case BCM4350_CHIP_ID:
1793 case BCM4354_CHIP_ID:
1794 case BCM43556_CHIP_ID:
1795 case BCM43558_CHIP_ID:
1796 case BCM43566_CHIP_ID:
1797 case BCM43568_CHIP_ID:
1798 case BCM43569_CHIP_ID:
1799 case BCM43570_CHIP_ID:
1800 case BCM4358_CHIP_ID:
1801 if (CST4350_CHIPMODE_USB20D(sih->chipst) ||
1802 CST4350_CHIPMODE_HSIC20D(sih->chipst) ||
1803 CST4350_CHIPMODE_USB30D(sih->chipst) ||
1804 CST4350_CHIPMODE_USB30D_WL(sih->chipst) ||
1805 CST4350_CHIPMODE_HSIC30D(sih->chipst))
1806 hosti = CHIP_HOSTIF_USBMODE;
1807 else if (CST4350_CHIPMODE_SDIOD(sih->chipst))
1808 hosti = CHIP_HOSTIF_SDIOMODE;
1809 else if (CST4350_CHIPMODE_PCIE(sih->chipst))
1810 hosti = CHIP_HOSTIF_PCIEMODE;
1811 break;
1812
1813 default:
1814 break;
1815 }
1816
1817 return hosti;
1818 }
1819
1820
1821 /** set chip watchdog reset timer to fire in 'ticks' */
1822 void
si_watchdog(si_t * sih,uint ticks)1823 si_watchdog(si_t *sih, uint ticks)
1824 {
1825 uint nb, maxt;
1826 uint pmu_wdt = 1;
1827
1828
1829 if (PMUCTL_ENAB(sih) && pmu_wdt) {
1830 nb = (CCREV(sih->ccrev) < 26) ? 16 : ((CCREV(sih->ccrev) >= 37) ? 32 : 24);
1831 /* The mips compiler uses the sllv instruction,
1832 * so we specially handle the 32-bit case.
1833 */
1834 if (nb == 32)
1835 maxt = 0xffffffff;
1836 else
1837 maxt = ((1 << nb) - 1);
1838
1839 if (ticks == 1)
1840 ticks = 2;
1841 else if (ticks > maxt)
1842 ticks = maxt;
1843 if (CHIPID(sih->chip) == BCM43012_CHIP_ID) {
1844 PMU_REG_NEW(sih, min_res_mask, ~0, DEFAULT_43012_MIN_RES_MASK);
1845 PMU_REG_NEW(sih, watchdog_res_mask, ~0, DEFAULT_43012_MIN_RES_MASK);
1846 PMU_REG_NEW(sih, pmustatus, PST_WDRESET, PST_WDRESET);
1847 PMU_REG_NEW(sih, pmucontrol_ext, PCTL_EXT_FASTLPO_SWENAB, 0);
1848 SPINWAIT((PMU_REG(sih, pmustatus, 0, 0) & PST_ILPFASTLPO),
1849 PMU_MAX_TRANSITION_DLY);
1850 }
1851
1852 pmu_corereg(sih, SI_CC_IDX, pmuwatchdog, ~0, ticks);
1853 } else {
1854 maxt = (1 << 28) - 1;
1855 if (ticks > maxt)
1856 ticks = maxt;
1857
1858 si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, watchdog), ~0, ticks);
1859 }
1860 }
1861
1862 /** trigger watchdog reset after ms milliseconds */
1863 void
si_watchdog_ms(si_t * sih,uint32 ms)1864 si_watchdog_ms(si_t *sih, uint32 ms)
1865 {
1866 si_watchdog(sih, wd_msticks * ms);
1867 }
1868
si_watchdog_msticks(void)1869 uint32 si_watchdog_msticks(void)
1870 {
1871 return wd_msticks;
1872 }
1873
1874 bool
si_taclear(si_t * sih,bool details)1875 si_taclear(si_t *sih, bool details)
1876 {
1877 return FALSE;
1878 }
1879
1880
1881
1882 /** return the slow clock source - LPO, XTAL, or PCI */
1883 static uint
si_slowclk_src(si_info_t * sii)1884 si_slowclk_src(si_info_t *sii)
1885 {
1886 chipcregs_t *cc;
1887
1888 ASSERT(SI_FAST(sii) || si_coreid(&sii->pub) == CC_CORE_ID);
1889
1890 if (CCREV(sii->pub.ccrev) < 6) {
1891 if ((BUSTYPE(sii->pub.bustype) == PCI_BUS) &&
1892 (OSL_PCI_READ_CONFIG(sii->osh, PCI_GPIO_OUT, sizeof(uint32)) &
1893 PCI_CFG_GPIO_SCS))
1894 return (SCC_SS_PCI);
1895 else
1896 return (SCC_SS_XTAL);
1897 } else if (CCREV(sii->pub.ccrev) < 10) {
1898 cc = (chipcregs_t *)si_setcoreidx(&sii->pub, sii->curidx);
1899 ASSERT(cc);
1900 return (R_REG(sii->osh, &cc->slow_clk_ctl) & SCC_SS_MASK);
1901 } else /* Insta-clock */
1902 return (SCC_SS_XTAL);
1903 }
1904
1905 /** return the ILP (slowclock) min or max frequency */
1906 static uint
si_slowclk_freq(si_info_t * sii,bool max_freq,chipcregs_t * cc)1907 si_slowclk_freq(si_info_t *sii, bool max_freq, chipcregs_t *cc)
1908 {
1909 uint32 slowclk;
1910 uint div;
1911
1912 ASSERT(SI_FAST(sii) || si_coreid(&sii->pub) == CC_CORE_ID);
1913
1914 /* shouldn't be here unless we've established the chip has dynamic clk control */
1915 ASSERT(R_REG(sii->osh, &cc->capabilities) & CC_CAP_PWR_CTL);
1916
1917 slowclk = si_slowclk_src(sii);
1918 if (CCREV(sii->pub.ccrev) < 6) {
1919 if (slowclk == SCC_SS_PCI)
1920 return (max_freq ? (PCIMAXFREQ / 64) : (PCIMINFREQ / 64));
1921 else
1922 return (max_freq ? (XTALMAXFREQ / 32) : (XTALMINFREQ / 32));
1923 } else if (CCREV(sii->pub.ccrev) < 10) {
1924 div = 4 *
1925 (((R_REG(sii->osh, &cc->slow_clk_ctl) & SCC_CD_MASK) >> SCC_CD_SHIFT) + 1);
1926 if (slowclk == SCC_SS_LPO)
1927 return (max_freq ? LPOMAXFREQ : LPOMINFREQ);
1928 else if (slowclk == SCC_SS_XTAL)
1929 return (max_freq ? (XTALMAXFREQ / div) : (XTALMINFREQ / div));
1930 else if (slowclk == SCC_SS_PCI)
1931 return (max_freq ? (PCIMAXFREQ / div) : (PCIMINFREQ / div));
1932 else
1933 ASSERT(0);
1934 } else {
1935 /* Chipc rev 10 is InstaClock */
1936 div = R_REG(sii->osh, &cc->system_clk_ctl) >> SYCC_CD_SHIFT;
1937 div = 4 * (div + 1);
1938 return (max_freq ? XTALMAXFREQ : (XTALMINFREQ / div));
1939 }
1940 return (0);
1941 }
1942
1943 static void
si_clkctl_setdelay(si_info_t * sii,void * chipcregs)1944 si_clkctl_setdelay(si_info_t *sii, void *chipcregs)
1945 {
1946 chipcregs_t *cc = (chipcregs_t *)chipcregs;
1947 uint slowmaxfreq, pll_delay, slowclk;
1948 uint pll_on_delay, fref_sel_delay;
1949
1950 pll_delay = PLL_DELAY;
1951
1952 /* If the slow clock is not sourced by the xtal then add the xtal_on_delay
1953 * since the xtal will also be powered down by dynamic clk control logic.
1954 */
1955
1956 slowclk = si_slowclk_src(sii);
1957 if (slowclk != SCC_SS_XTAL)
1958 pll_delay += XTAL_ON_DELAY;
1959
1960 /* Starting with 4318 it is ILP that is used for the delays */
1961 slowmaxfreq = si_slowclk_freq(sii, (CCREV(sii->pub.ccrev) >= 10) ? FALSE : TRUE, cc);
1962
1963 pll_on_delay = ((slowmaxfreq * pll_delay) + 999999) / 1000000;
1964 fref_sel_delay = ((slowmaxfreq * FREF_DELAY) + 999999) / 1000000;
1965
1966 W_REG(sii->osh, &cc->pll_on_delay, pll_on_delay);
1967 W_REG(sii->osh, &cc->fref_sel_delay, fref_sel_delay);
1968 }
1969
1970 /** initialize power control delay registers */
1971 void
si_clkctl_init(si_t * sih)1972 si_clkctl_init(si_t *sih)
1973 {
1974 si_info_t *sii;
1975 uint origidx = 0;
1976 chipcregs_t *cc;
1977 bool fast;
1978
1979 if (!CCCTL_ENAB(sih))
1980 return;
1981
1982 sii = SI_INFO(sih);
1983 fast = SI_FAST(sii);
1984 if (!fast) {
1985 origidx = sii->curidx;
1986 if ((cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0)) == NULL)
1987 return;
1988 } else if ((cc = (chipcregs_t *)CCREGS_FAST(sii)) == NULL)
1989 return;
1990 ASSERT(cc != NULL);
1991
1992 /* set all Instaclk chip ILP to 1 MHz */
1993 if (CCREV(sih->ccrev) >= 10)
1994 SET_REG(sii->osh, &cc->system_clk_ctl, SYCC_CD_MASK,
1995 (ILP_DIV_1MHZ << SYCC_CD_SHIFT));
1996
1997 si_clkctl_setdelay(sii, (void *)(uintptr)cc);
1998
1999 OSL_DELAY(20000);
2000
2001 if (!fast)
2002 si_setcoreidx(sih, origidx);
2003 }
2004
2005
2006 /** change logical "focus" to the gpio core for optimized access */
2007 volatile void *
si_gpiosetcore(si_t * sih)2008 si_gpiosetcore(si_t *sih)
2009 {
2010 return (si_setcoreidx(sih, SI_CC_IDX));
2011 }
2012
2013 /**
2014 * mask & set gpiocontrol bits.
2015 * If a gpiocontrol bit is set to 0, chipcommon controls the corresponding GPIO pin.
2016 * If a gpiocontrol bit is set to 1, the GPIO pin is no longer a GPIO and becomes dedicated
2017 * to some chip-specific purpose.
2018 */
2019 uint32
si_gpiocontrol(si_t * sih,uint32 mask,uint32 val,uint8 priority)2020 si_gpiocontrol(si_t *sih, uint32 mask, uint32 val, uint8 priority)
2021 {
2022 uint regoff;
2023
2024 regoff = 0;
2025
2026 /* gpios could be shared on router platforms
2027 * ignore reservation if it's high priority (e.g., test apps)
2028 */
2029 if ((priority != GPIO_HI_PRIORITY) &&
2030 (BUSTYPE(sih->bustype) == SI_BUS) && (val || mask)) {
2031 mask = priority ? (si_gpioreservation & mask) :
2032 ((si_gpioreservation | mask) & ~(si_gpioreservation));
2033 val &= mask;
2034 }
2035
2036 regoff = OFFSETOF(chipcregs_t, gpiocontrol);
2037 return (si_corereg(sih, SI_CC_IDX, regoff, mask, val));
2038 }
2039
2040 /** mask&set gpio output enable bits */
2041 uint32
si_gpioouten(si_t * sih,uint32 mask,uint32 val,uint8 priority)2042 si_gpioouten(si_t *sih, uint32 mask, uint32 val, uint8 priority)
2043 {
2044 uint regoff;
2045
2046 regoff = 0;
2047
2048 /* gpios could be shared on router platforms
2049 * ignore reservation if it's high priority (e.g., test apps)
2050 */
2051 if ((priority != GPIO_HI_PRIORITY) &&
2052 (BUSTYPE(sih->bustype) == SI_BUS) && (val || mask)) {
2053 mask = priority ? (si_gpioreservation & mask) :
2054 ((si_gpioreservation | mask) & ~(si_gpioreservation));
2055 val &= mask;
2056 }
2057
2058 regoff = OFFSETOF(chipcregs_t, gpioouten);
2059 return (si_corereg(sih, SI_CC_IDX, regoff, mask, val));
2060 }
2061
2062 /** mask&set gpio output bits */
2063 uint32
si_gpioout(si_t * sih,uint32 mask,uint32 val,uint8 priority)2064 si_gpioout(si_t *sih, uint32 mask, uint32 val, uint8 priority)
2065 {
2066 uint regoff;
2067
2068 regoff = 0;
2069
2070 /* gpios could be shared on router platforms
2071 * ignore reservation if it's high priority (e.g., test apps)
2072 */
2073 if ((priority != GPIO_HI_PRIORITY) &&
2074 (BUSTYPE(sih->bustype) == SI_BUS) && (val || mask)) {
2075 mask = priority ? (si_gpioreservation & mask) :
2076 ((si_gpioreservation | mask) & ~(si_gpioreservation));
2077 val &= mask;
2078 }
2079
2080 regoff = OFFSETOF(chipcregs_t, gpioout);
2081 return (si_corereg(sih, SI_CC_IDX, regoff, mask, val));
2082 }
2083
2084 /** reserve one gpio */
2085 uint32
si_gpioreserve(si_t * sih,uint32 gpio_bitmask,uint8 priority)2086 si_gpioreserve(si_t *sih, uint32 gpio_bitmask, uint8 priority)
2087 {
2088 /* only cores on SI_BUS share GPIO's and only applcation users need to
2089 * reserve/release GPIO
2090 */
2091 if ((BUSTYPE(sih->bustype) != SI_BUS) || (!priority)) {
2092 ASSERT((BUSTYPE(sih->bustype) == SI_BUS) && (priority));
2093 return 0xffffffff;
2094 }
2095 /* make sure only one bit is set */
2096 if ((!gpio_bitmask) || ((gpio_bitmask) & (gpio_bitmask - 1))) {
2097 ASSERT((gpio_bitmask) && !((gpio_bitmask) & (gpio_bitmask - 1)));
2098 return 0xffffffff;
2099 }
2100
2101 /* already reserved */
2102 if (si_gpioreservation & gpio_bitmask)
2103 return 0xffffffff;
2104 /* set reservation */
2105 si_gpioreservation |= gpio_bitmask;
2106
2107 return si_gpioreservation;
2108 }
2109
2110 /**
2111 * release one gpio.
2112 *
2113 * releasing the gpio doesn't change the current value on the GPIO last write value
2114 * persists till someone overwrites it.
2115 */
2116 uint32
si_gpiorelease(si_t * sih,uint32 gpio_bitmask,uint8 priority)2117 si_gpiorelease(si_t *sih, uint32 gpio_bitmask, uint8 priority)
2118 {
2119 /* only cores on SI_BUS share GPIO's and only applcation users need to
2120 * reserve/release GPIO
2121 */
2122 if ((BUSTYPE(sih->bustype) != SI_BUS) || (!priority)) {
2123 ASSERT((BUSTYPE(sih->bustype) == SI_BUS) && (priority));
2124 return 0xffffffff;
2125 }
2126 /* make sure only one bit is set */
2127 if ((!gpio_bitmask) || ((gpio_bitmask) & (gpio_bitmask - 1))) {
2128 ASSERT((gpio_bitmask) && !((gpio_bitmask) & (gpio_bitmask - 1)));
2129 return 0xffffffff;
2130 }
2131
2132 /* already released */
2133 if (!(si_gpioreservation & gpio_bitmask))
2134 return 0xffffffff;
2135
2136 /* clear reservation */
2137 si_gpioreservation &= ~gpio_bitmask;
2138
2139 return si_gpioreservation;
2140 }
2141
2142 /* return the current gpioin register value */
2143 uint32
si_gpioin(si_t * sih)2144 si_gpioin(si_t *sih)
2145 {
2146 uint regoff;
2147
2148 regoff = OFFSETOF(chipcregs_t, gpioin);
2149 return (si_corereg(sih, SI_CC_IDX, regoff, 0, 0));
2150 }
2151
2152 /* mask&set gpio interrupt polarity bits */
2153 uint32
si_gpiointpolarity(si_t * sih,uint32 mask,uint32 val,uint8 priority)2154 si_gpiointpolarity(si_t *sih, uint32 mask, uint32 val, uint8 priority)
2155 {
2156 uint regoff;
2157
2158 /* gpios could be shared on router platforms */
2159 if ((BUSTYPE(sih->bustype) == SI_BUS) && (val || mask)) {
2160 mask = priority ? (si_gpioreservation & mask) :
2161 ((si_gpioreservation | mask) & ~(si_gpioreservation));
2162 val &= mask;
2163 }
2164
2165 regoff = OFFSETOF(chipcregs_t, gpiointpolarity);
2166 return (si_corereg(sih, SI_CC_IDX, regoff, mask, val));
2167 }
2168
2169 /* mask&set gpio interrupt mask bits */
2170 uint32
si_gpiointmask(si_t * sih,uint32 mask,uint32 val,uint8 priority)2171 si_gpiointmask(si_t *sih, uint32 mask, uint32 val, uint8 priority)
2172 {
2173 uint regoff;
2174
2175 /* gpios could be shared on router platforms */
2176 if ((BUSTYPE(sih->bustype) == SI_BUS) && (val || mask)) {
2177 mask = priority ? (si_gpioreservation & mask) :
2178 ((si_gpioreservation | mask) & ~(si_gpioreservation));
2179 val &= mask;
2180 }
2181
2182 regoff = OFFSETOF(chipcregs_t, gpiointmask);
2183 return (si_corereg(sih, SI_CC_IDX, regoff, mask, val));
2184 }
2185
2186 uint32
si_gpioeventintmask(si_t * sih,uint32 mask,uint32 val,uint8 priority)2187 si_gpioeventintmask(si_t *sih, uint32 mask, uint32 val, uint8 priority)
2188 {
2189 uint regoff;
2190 /* gpios could be shared on router platforms */
2191 if ((BUSTYPE(sih->bustype) == SI_BUS) && (val || mask)) {
2192 mask = priority ? (si_gpioreservation & mask) :
2193 ((si_gpioreservation | mask) & ~(si_gpioreservation));
2194 val &= mask;
2195 }
2196 regoff = OFFSETOF(chipcregs_t, gpioeventintmask);
2197 return (si_corereg(sih, SI_CC_IDX, regoff, mask, val));
2198 }
2199
2200 /* assign the gpio to an led */
2201 uint32
si_gpioled(si_t * sih,uint32 mask,uint32 val)2202 si_gpioled(si_t *sih, uint32 mask, uint32 val)
2203 {
2204 if (CCREV(sih->ccrev) < 16)
2205 return 0xffffffff;
2206
2207 /* gpio led powersave reg */
2208 return (si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, gpiotimeroutmask), mask, val));
2209 }
2210
2211 /* mask&set gpio timer val */
2212 uint32
si_gpiotimerval(si_t * sih,uint32 mask,uint32 gpiotimerval)2213 si_gpiotimerval(si_t *sih, uint32 mask, uint32 gpiotimerval)
2214 {
2215 if (CCREV(sih->ccrev) < 16)
2216 return 0xffffffff;
2217
2218 return (si_corereg(sih, SI_CC_IDX,
2219 OFFSETOF(chipcregs_t, gpiotimerval), mask, gpiotimerval));
2220 }
2221
2222 uint32
si_gpiopull(si_t * sih,bool updown,uint32 mask,uint32 val)2223 si_gpiopull(si_t *sih, bool updown, uint32 mask, uint32 val)
2224 {
2225 uint offs;
2226
2227 if (CCREV(sih->ccrev) < 20)
2228 return 0xffffffff;
2229
2230 offs = (updown ? OFFSETOF(chipcregs_t, gpiopulldown) : OFFSETOF(chipcregs_t, gpiopullup));
2231 return (si_corereg(sih, SI_CC_IDX, offs, mask, val));
2232 }
2233
2234 uint32
si_gpioevent(si_t * sih,uint regtype,uint32 mask,uint32 val)2235 si_gpioevent(si_t *sih, uint regtype, uint32 mask, uint32 val)
2236 {
2237 uint offs;
2238
2239 if (CCREV(sih->ccrev) < 11)
2240 return 0xffffffff;
2241
2242 if (regtype == GPIO_REGEVT)
2243 offs = OFFSETOF(chipcregs_t, gpioevent);
2244 else if (regtype == GPIO_REGEVT_INTMSK)
2245 offs = OFFSETOF(chipcregs_t, gpioeventintmask);
2246 else if (regtype == GPIO_REGEVT_INTPOL)
2247 offs = OFFSETOF(chipcregs_t, gpioeventintpolarity);
2248 else
2249 return 0xffffffff;
2250
2251 return (si_corereg(sih, SI_CC_IDX, offs, mask, val));
2252 }
2253
2254 uint32
si_gpio_int_enable(si_t * sih,bool enable)2255 si_gpio_int_enable(si_t *sih, bool enable)
2256 {
2257 uint offs;
2258
2259 if (CCREV(sih->ccrev) < 11)
2260 return 0xffffffff;
2261
2262 offs = OFFSETOF(chipcregs_t, intmask);
2263 return (si_corereg(sih, SI_CC_IDX, offs, CI_GPIO, (enable ? CI_GPIO : 0)));
2264 }
2265
2266 /** Return the size of the specified SYSMEM bank */
2267 static uint
sysmem_banksize(si_info_t * sii,sysmemregs_t * regs,uint8 idx)2268 sysmem_banksize(si_info_t *sii, sysmemregs_t *regs, uint8 idx)
2269 {
2270 uint banksize, bankinfo;
2271 uint bankidx = idx;
2272
2273 W_REG(sii->osh, ®s->bankidx, bankidx);
2274 bankinfo = R_REG(sii->osh, ®s->bankinfo);
2275 banksize = SYSMEM_BANKINFO_SZBASE * ((bankinfo & SYSMEM_BANKINFO_SZMASK) + 1);
2276 return banksize;
2277 }
2278
2279 /** Return the RAM size of the SYSMEM core */
2280 uint32
si_sysmem_size(si_t * sih)2281 si_sysmem_size(si_t *sih)
2282 {
2283 si_info_t *sii = SI_INFO(sih);
2284 uint origidx;
2285 uint intr_val = 0;
2286
2287 sysmemregs_t *regs;
2288 bool wasup;
2289 uint32 coreinfo;
2290 uint memsize = 0;
2291 uint8 i;
2292 uint nb, nrb;
2293
2294 /* Block ints and save current core */
2295 INTR_OFF(sii, intr_val);
2296 origidx = si_coreidx(sih);
2297
2298 /* Switch to SYSMEM core */
2299 if (!(regs = si_setcore(sih, SYSMEM_CORE_ID, 0)))
2300 goto done;
2301
2302 /* Get info for determining size */
2303 if (!(wasup = si_iscoreup(sih)))
2304 si_core_reset(sih, 0, 0);
2305 coreinfo = R_REG(sii->osh, ®s->coreinfo);
2306
2307 /* Number of ROM banks, SW need to skip the ROM banks. */
2308 nrb = (coreinfo & SYSMEM_SRCI_ROMNB_MASK) >> SYSMEM_SRCI_ROMNB_SHIFT;
2309
2310 nb = (coreinfo & SYSMEM_SRCI_SRNB_MASK) >> SYSMEM_SRCI_SRNB_SHIFT;
2311 for (i = 0; i < nb; i++)
2312 memsize += sysmem_banksize(sii, regs, i + nrb);
2313
2314 si_setcoreidx(sih, origidx);
2315
2316 done:
2317 INTR_RESTORE(sii, intr_val);
2318
2319 return memsize;
2320 }
2321
2322 /** Return the size of the specified SOCRAM bank */
2323 static uint
socram_banksize(si_info_t * sii,sbsocramregs_t * regs,uint8 idx,uint8 mem_type)2324 socram_banksize(si_info_t *sii, sbsocramregs_t *regs, uint8 idx, uint8 mem_type)
2325 {
2326 uint banksize, bankinfo;
2327 uint bankidx = idx | (mem_type << SOCRAM_BANKIDX_MEMTYPE_SHIFT);
2328
2329 ASSERT(mem_type <= SOCRAM_MEMTYPE_DEVRAM);
2330
2331 W_REG(sii->osh, ®s->bankidx, bankidx);
2332 bankinfo = R_REG(sii->osh, ®s->bankinfo);
2333 banksize = SOCRAM_BANKINFO_SZBASE * ((bankinfo & SOCRAM_BANKINFO_SZMASK) + 1);
2334 return banksize;
2335 }
2336
si_socram_set_bankpda(si_t * sih,uint32 bankidx,uint32 bankpda)2337 void si_socram_set_bankpda(si_t *sih, uint32 bankidx, uint32 bankpda)
2338 {
2339 si_info_t *sii = SI_INFO(sih);
2340 uint origidx;
2341 uint intr_val = 0;
2342 sbsocramregs_t *regs;
2343 bool wasup;
2344 uint corerev;
2345
2346 /* Block ints and save current core */
2347 INTR_OFF(sii, intr_val);
2348 origidx = si_coreidx(sih);
2349
2350 /* Switch to SOCRAM core */
2351 if (!(regs = si_setcore(sih, SOCRAM_CORE_ID, 0)))
2352 goto done;
2353
2354 if (!(wasup = si_iscoreup(sih)))
2355 si_core_reset(sih, 0, 0);
2356
2357 corerev = si_corerev(sih);
2358 if (corerev >= 16) {
2359 W_REG(sii->osh, ®s->bankidx, bankidx);
2360 W_REG(sii->osh, ®s->bankpda, bankpda);
2361 }
2362
2363 /* Return to previous state and core */
2364 if (!wasup)
2365 si_core_disable(sih, 0);
2366 si_setcoreidx(sih, origidx);
2367
2368 done:
2369 INTR_RESTORE(sii, intr_val);
2370 }
2371
2372 void
si_socdevram(si_t * sih,bool set,uint8 * enable,uint8 * protect,uint8 * remap)2373 si_socdevram(si_t *sih, bool set, uint8 *enable, uint8 *protect, uint8 *remap)
2374 {
2375 si_info_t *sii = SI_INFO(sih);
2376 uint origidx;
2377 uint intr_val = 0;
2378 sbsocramregs_t *regs;
2379 bool wasup;
2380 uint corerev;
2381
2382 /* Block ints and save current core */
2383 INTR_OFF(sii, intr_val);
2384 origidx = si_coreidx(sih);
2385
2386 if (!set)
2387 *enable = *protect = *remap = 0;
2388
2389 /* Switch to SOCRAM core */
2390 if (!(regs = si_setcore(sih, SOCRAM_CORE_ID, 0)))
2391 goto done;
2392
2393 /* Get info for determining size */
2394 if (!(wasup = si_iscoreup(sih)))
2395 si_core_reset(sih, 0, 0);
2396
2397 corerev = si_corerev(sih);
2398 if (corerev >= 10) {
2399 uint32 extcinfo;
2400 uint8 nb;
2401 uint8 i;
2402 uint32 bankidx, bankinfo;
2403
2404 extcinfo = R_REG(sii->osh, ®s->extracoreinfo);
2405 nb = ((extcinfo & SOCRAM_DEVRAMBANK_MASK) >> SOCRAM_DEVRAMBANK_SHIFT);
2406 for (i = 0; i < nb; i++) {
2407 bankidx = i | (SOCRAM_MEMTYPE_DEVRAM << SOCRAM_BANKIDX_MEMTYPE_SHIFT);
2408 W_REG(sii->osh, ®s->bankidx, bankidx);
2409 bankinfo = R_REG(sii->osh, ®s->bankinfo);
2410 if (set) {
2411 bankinfo &= ~SOCRAM_BANKINFO_DEVRAMSEL_MASK;
2412 bankinfo &= ~SOCRAM_BANKINFO_DEVRAMPRO_MASK;
2413 bankinfo &= ~SOCRAM_BANKINFO_DEVRAMREMAP_MASK;
2414 if (*enable) {
2415 bankinfo |= (1 << SOCRAM_BANKINFO_DEVRAMSEL_SHIFT);
2416 if (*protect)
2417 bankinfo |= (1 << SOCRAM_BANKINFO_DEVRAMPRO_SHIFT);
2418 if ((corerev >= 16) && *remap)
2419 bankinfo |=
2420 (1 << SOCRAM_BANKINFO_DEVRAMREMAP_SHIFT);
2421 }
2422 W_REG(sii->osh, ®s->bankinfo, bankinfo);
2423 } else if (i == 0) {
2424 if (bankinfo & SOCRAM_BANKINFO_DEVRAMSEL_MASK) {
2425 *enable = 1;
2426 if (bankinfo & SOCRAM_BANKINFO_DEVRAMPRO_MASK)
2427 *protect = 1;
2428 if (bankinfo & SOCRAM_BANKINFO_DEVRAMREMAP_MASK)
2429 *remap = 1;
2430 }
2431 }
2432 }
2433 }
2434
2435 /* Return to previous state and core */
2436 if (!wasup)
2437 si_core_disable(sih, 0);
2438 si_setcoreidx(sih, origidx);
2439
2440 done:
2441 INTR_RESTORE(sii, intr_val);
2442 }
2443
2444 bool
si_socdevram_remap_isenb(si_t * sih)2445 si_socdevram_remap_isenb(si_t *sih)
2446 {
2447 si_info_t *sii = SI_INFO(sih);
2448 uint origidx;
2449 uint intr_val = 0;
2450 sbsocramregs_t *regs;
2451 bool wasup, remap = FALSE;
2452 uint corerev;
2453 uint32 extcinfo;
2454 uint8 nb;
2455 uint8 i;
2456 uint32 bankidx, bankinfo;
2457
2458 /* Block ints and save current core */
2459 INTR_OFF(sii, intr_val);
2460 origidx = si_coreidx(sih);
2461
2462 /* Switch to SOCRAM core */
2463 if (!(regs = si_setcore(sih, SOCRAM_CORE_ID, 0)))
2464 goto done;
2465
2466 /* Get info for determining size */
2467 if (!(wasup = si_iscoreup(sih)))
2468 si_core_reset(sih, 0, 0);
2469
2470 corerev = si_corerev(sih);
2471 if (corerev >= 16) {
2472 extcinfo = R_REG(sii->osh, ®s->extracoreinfo);
2473 nb = ((extcinfo & SOCRAM_DEVRAMBANK_MASK) >> SOCRAM_DEVRAMBANK_SHIFT);
2474 for (i = 0; i < nb; i++) {
2475 bankidx = i | (SOCRAM_MEMTYPE_DEVRAM << SOCRAM_BANKIDX_MEMTYPE_SHIFT);
2476 W_REG(sii->osh, ®s->bankidx, bankidx);
2477 bankinfo = R_REG(sii->osh, ®s->bankinfo);
2478 if (bankinfo & SOCRAM_BANKINFO_DEVRAMREMAP_MASK) {
2479 remap = TRUE;
2480 break;
2481 }
2482 }
2483 }
2484
2485 /* Return to previous state and core */
2486 if (!wasup)
2487 si_core_disable(sih, 0);
2488 si_setcoreidx(sih, origidx);
2489
2490 done:
2491 INTR_RESTORE(sii, intr_val);
2492 return remap;
2493 }
2494
2495 bool
si_socdevram_pkg(si_t * sih)2496 si_socdevram_pkg(si_t *sih)
2497 {
2498 if (si_socdevram_size(sih) > 0)
2499 return TRUE;
2500 else
2501 return FALSE;
2502 }
2503
2504 uint32
si_socdevram_size(si_t * sih)2505 si_socdevram_size(si_t *sih)
2506 {
2507 si_info_t *sii = SI_INFO(sih);
2508 uint origidx;
2509 uint intr_val = 0;
2510 uint32 memsize = 0;
2511 sbsocramregs_t *regs;
2512 bool wasup;
2513 uint corerev;
2514
2515 /* Block ints and save current core */
2516 INTR_OFF(sii, intr_val);
2517 origidx = si_coreidx(sih);
2518
2519 /* Switch to SOCRAM core */
2520 if (!(regs = si_setcore(sih, SOCRAM_CORE_ID, 0)))
2521 goto done;
2522
2523 /* Get info for determining size */
2524 if (!(wasup = si_iscoreup(sih)))
2525 si_core_reset(sih, 0, 0);
2526
2527 corerev = si_corerev(sih);
2528 if (corerev >= 10) {
2529 uint32 extcinfo;
2530 uint8 nb;
2531 uint8 i;
2532
2533 extcinfo = R_REG(sii->osh, ®s->extracoreinfo);
2534 nb = (((extcinfo & SOCRAM_DEVRAMBANK_MASK) >> SOCRAM_DEVRAMBANK_SHIFT));
2535 for (i = 0; i < nb; i++)
2536 memsize += socram_banksize(sii, regs, i, SOCRAM_MEMTYPE_DEVRAM);
2537 }
2538
2539 /* Return to previous state and core */
2540 if (!wasup)
2541 si_core_disable(sih, 0);
2542 si_setcoreidx(sih, origidx);
2543
2544 done:
2545 INTR_RESTORE(sii, intr_val);
2546
2547 return memsize;
2548 }
2549
2550 uint32
si_socdevram_remap_size(si_t * sih)2551 si_socdevram_remap_size(si_t *sih)
2552 {
2553 si_info_t *sii = SI_INFO(sih);
2554 uint origidx;
2555 uint intr_val = 0;
2556 uint32 memsize = 0, banksz;
2557 sbsocramregs_t *regs;
2558 bool wasup;
2559 uint corerev;
2560 uint32 extcinfo;
2561 uint8 nb;
2562 uint8 i;
2563 uint32 bankidx, bankinfo;
2564
2565 /* Block ints and save current core */
2566 INTR_OFF(sii, intr_val);
2567 origidx = si_coreidx(sih);
2568
2569 /* Switch to SOCRAM core */
2570 if (!(regs = si_setcore(sih, SOCRAM_CORE_ID, 0)))
2571 goto done;
2572
2573 /* Get info for determining size */
2574 if (!(wasup = si_iscoreup(sih)))
2575 si_core_reset(sih, 0, 0);
2576
2577 corerev = si_corerev(sih);
2578 if (corerev >= 16) {
2579 extcinfo = R_REG(sii->osh, ®s->extracoreinfo);
2580 nb = (((extcinfo & SOCRAM_DEVRAMBANK_MASK) >> SOCRAM_DEVRAMBANK_SHIFT));
2581
2582 /*
2583 * FIX: A0 Issue: Max addressable is 512KB, instead 640KB
2584 * Only four banks are accessible to ARM
2585 */
2586 if ((corerev == 16) && (nb == 5))
2587 nb = 4;
2588
2589 for (i = 0; i < nb; i++) {
2590 bankidx = i | (SOCRAM_MEMTYPE_DEVRAM << SOCRAM_BANKIDX_MEMTYPE_SHIFT);
2591 W_REG(sii->osh, ®s->bankidx, bankidx);
2592 bankinfo = R_REG(sii->osh, ®s->bankinfo);
2593 if (bankinfo & SOCRAM_BANKINFO_DEVRAMREMAP_MASK) {
2594 banksz = socram_banksize(sii, regs, i, SOCRAM_MEMTYPE_DEVRAM);
2595 memsize += banksz;
2596 } else {
2597 /* Account only consecutive banks for now */
2598 break;
2599 }
2600 }
2601 }
2602
2603 /* Return to previous state and core */
2604 if (!wasup)
2605 si_core_disable(sih, 0);
2606 si_setcoreidx(sih, origidx);
2607
2608 done:
2609 INTR_RESTORE(sii, intr_val);
2610
2611 return memsize;
2612 }
2613
2614 /** Return the RAM size of the SOCRAM core */
2615 uint32
si_socram_size(si_t * sih)2616 si_socram_size(si_t *sih)
2617 {
2618 si_info_t *sii = SI_INFO(sih);
2619 uint origidx;
2620 uint intr_val = 0;
2621
2622 sbsocramregs_t *regs;
2623 bool wasup;
2624 uint corerev;
2625 uint32 coreinfo;
2626 uint memsize = 0;
2627
2628 /* Block ints and save current core */
2629 INTR_OFF(sii, intr_val);
2630 origidx = si_coreidx(sih);
2631
2632 /* Switch to SOCRAM core */
2633 if (!(regs = si_setcore(sih, SOCRAM_CORE_ID, 0)))
2634 goto done;
2635
2636 /* Get info for determining size */
2637 if (!(wasup = si_iscoreup(sih)))
2638 si_core_reset(sih, 0, 0);
2639 corerev = si_corerev(sih);
2640 coreinfo = R_REG(sii->osh, ®s->coreinfo);
2641
2642 /* Calculate size from coreinfo based on rev */
2643 if (corerev == 0)
2644 memsize = 1 << (16 + (coreinfo & SRCI_MS0_MASK));
2645 else if (corerev < 3) {
2646 memsize = 1 << (SR_BSZ_BASE + (coreinfo & SRCI_SRBSZ_MASK));
2647 memsize *= (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT;
2648 } else if ((corerev <= 7) || (corerev == 12)) {
2649 uint nb = (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT;
2650 uint bsz = (coreinfo & SRCI_SRBSZ_MASK);
2651 uint lss = (coreinfo & SRCI_LSS_MASK) >> SRCI_LSS_SHIFT;
2652 if (lss != 0)
2653 nb --;
2654 memsize = nb * (1 << (bsz + SR_BSZ_BASE));
2655 if (lss != 0)
2656 memsize += (1 << ((lss - 1) + SR_BSZ_BASE));
2657 } else {
2658 uint8 i;
2659 uint nb;
2660 /* length of SRAM Banks increased for corerev greater than 23 */
2661 if (corerev >= 23) {
2662 nb = (coreinfo & (SRCI_SRNB_MASK | SRCI_SRNB_MASK_EXT)) >> SRCI_SRNB_SHIFT;
2663 } else {
2664 nb = (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT;
2665 }
2666 for (i = 0; i < nb; i++)
2667 memsize += socram_banksize(sii, regs, i, SOCRAM_MEMTYPE_RAM);
2668 }
2669
2670 /* Return to previous state and core */
2671 if (!wasup)
2672 si_core_disable(sih, 0);
2673 si_setcoreidx(sih, origidx);
2674
2675 done:
2676 INTR_RESTORE(sii, intr_val);
2677
2678 return memsize;
2679 }
2680
2681
2682 /** Return the TCM-RAM size of the ARMCR4 core. */
2683 uint32
si_tcm_size(si_t * sih)2684 si_tcm_size(si_t *sih)
2685 {
2686 si_info_t *sii = SI_INFO(sih);
2687 uint origidx;
2688 uint intr_val = 0;
2689 volatile uint8 *regs;
2690 bool wasup;
2691 uint32 corecap;
2692 uint memsize = 0;
2693 uint32 nab = 0;
2694 uint32 nbb = 0;
2695 uint32 totb = 0;
2696 uint32 bxinfo = 0;
2697 uint32 idx = 0;
2698 volatile uint32 *arm_cap_reg;
2699 volatile uint32 *arm_bidx;
2700 volatile uint32 *arm_binfo;
2701
2702 /* Block ints and save current core */
2703 INTR_OFF(sii, intr_val);
2704 origidx = si_coreidx(sih);
2705
2706 /* Switch to CR4 core */
2707 if (!(regs = si_setcore(sih, ARMCR4_CORE_ID, 0)))
2708 goto done;
2709
2710 /* Get info for determining size. If in reset, come out of reset,
2711 * but remain in halt
2712 */
2713 if (!(wasup = si_iscoreup(sih)))
2714 si_core_reset(sih, SICF_CPUHALT, SICF_CPUHALT);
2715
2716 arm_cap_reg = (volatile uint32 *)(regs + SI_CR4_CAP);
2717 corecap = R_REG(sii->osh, arm_cap_reg);
2718
2719 nab = (corecap & ARMCR4_TCBANB_MASK) >> ARMCR4_TCBANB_SHIFT;
2720 nbb = (corecap & ARMCR4_TCBBNB_MASK) >> ARMCR4_TCBBNB_SHIFT;
2721 totb = nab + nbb;
2722
2723 arm_bidx = (volatile uint32 *)(regs + SI_CR4_BANKIDX);
2724 arm_binfo = (volatile uint32 *)(regs + SI_CR4_BANKINFO);
2725 for (idx = 0; idx < totb; idx++) {
2726 W_REG(sii->osh, arm_bidx, idx);
2727
2728 bxinfo = R_REG(sii->osh, arm_binfo);
2729 memsize += ((bxinfo & ARMCR4_BSZ_MASK) + 1) * ARMCR4_BSZ_MULT;
2730 }
2731
2732 /* Return to previous state and core */
2733 if (!wasup)
2734 si_core_disable(sih, 0);
2735 si_setcoreidx(sih, origidx);
2736
2737 done:
2738 INTR_RESTORE(sii, intr_val);
2739
2740 return memsize;
2741 }
2742
2743 bool
si_has_flops(si_t * sih)2744 si_has_flops(si_t *sih)
2745 {
2746 uint origidx, cr4_rev;
2747
2748 /* Find out CR4 core revision */
2749 origidx = si_coreidx(sih);
2750 if (si_setcore(sih, ARMCR4_CORE_ID, 0)) {
2751 cr4_rev = si_corerev(sih);
2752 si_setcoreidx(sih, origidx);
2753
2754 if (cr4_rev == 1 || cr4_rev >= 3)
2755 return TRUE;
2756 }
2757 return FALSE;
2758 }
2759
2760 uint32
si_socram_srmem_size(si_t * sih)2761 si_socram_srmem_size(si_t *sih)
2762 {
2763 si_info_t *sii = SI_INFO(sih);
2764 uint origidx;
2765 uint intr_val = 0;
2766
2767 sbsocramregs_t *regs;
2768 bool wasup;
2769 uint corerev;
2770 uint32 coreinfo;
2771 uint memsize = 0;
2772
2773 if ((CHIPID(sih->chip) == BCM4334_CHIP_ID) && (CHIPREV(sih->chiprev) < 2)) {
2774 return (32 * 1024);
2775 }
2776
2777 if (CHIPID(sih->chip) == BCM43430_CHIP_ID ||
2778 CHIPID(sih->chip) == BCM43018_CHIP_ID) {
2779 return (64 * 1024);
2780 }
2781
2782 /* Block ints and save current core */
2783 INTR_OFF(sii, intr_val);
2784 origidx = si_coreidx(sih);
2785
2786 /* Switch to SOCRAM core */
2787 if (!(regs = si_setcore(sih, SOCRAM_CORE_ID, 0)))
2788 goto done;
2789
2790 /* Get info for determining size */
2791 if (!(wasup = si_iscoreup(sih)))
2792 si_core_reset(sih, 0, 0);
2793 corerev = si_corerev(sih);
2794 coreinfo = R_REG(sii->osh, ®s->coreinfo);
2795
2796 /* Calculate size from coreinfo based on rev */
2797 if (corerev >= 16) {
2798 uint8 i;
2799 uint nb = (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT;
2800 for (i = 0; i < nb; i++) {
2801 W_REG(sii->osh, ®s->bankidx, i);
2802 if (R_REG(sii->osh, ®s->bankinfo) & SOCRAM_BANKINFO_RETNTRAM_MASK)
2803 memsize += socram_banksize(sii, regs, i, SOCRAM_MEMTYPE_RAM);
2804 }
2805 }
2806
2807 /* Return to previous state and core */
2808 if (!wasup)
2809 si_core_disable(sih, 0);
2810 si_setcoreidx(sih, origidx);
2811
2812 done:
2813 INTR_RESTORE(sii, intr_val);
2814
2815 return memsize;
2816 }
2817
2818
2819 #if !defined(_CFEZ_) || defined(CFG_WL)
2820 void
si_btcgpiowar(si_t * sih)2821 si_btcgpiowar(si_t *sih)
2822 {
2823 si_info_t *sii = SI_INFO(sih);
2824 uint origidx;
2825 uint intr_val = 0;
2826 chipcregs_t *cc;
2827
2828 /* Make sure that there is ChipCommon core present &&
2829 * UART_TX is strapped to 1
2830 */
2831 if (!(sih->cccaps & CC_CAP_UARTGPIO))
2832 return;
2833
2834 /* si_corereg cannot be used as we have to guarantee 8-bit read/writes */
2835 INTR_OFF(sii, intr_val);
2836
2837 origidx = si_coreidx(sih);
2838
2839 cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0);
2840 ASSERT(cc != NULL);
2841
2842 W_REG(sii->osh, &cc->uart0mcr, R_REG(sii->osh, &cc->uart0mcr) | 0x04);
2843
2844 /* restore the original index */
2845 si_setcoreidx(sih, origidx);
2846
2847 INTR_RESTORE(sii, intr_val);
2848 }
2849
2850 void
si_chipcontrl_btshd0_4331(si_t * sih,bool on)2851 si_chipcontrl_btshd0_4331(si_t *sih, bool on)
2852 {
2853 si_info_t *sii = SI_INFO(sih);
2854 chipcregs_t *cc;
2855 uint origidx;
2856 uint32 val;
2857 uint intr_val = 0;
2858
2859 INTR_OFF(sii, intr_val);
2860
2861 origidx = si_coreidx(sih);
2862
2863 if ((cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0)) == NULL) {
2864 SI_ERROR(("%s: Failed to find CORE ID!\n", __FUNCTION__));
2865 return;
2866 }
2867
2868 val = R_REG(sii->osh, &cc->chipcontrol);
2869
2870 /* bt_shd0 controls are same for 4331 chiprevs 0 and 1, packages 12x9 and 12x12 */
2871 if (on) {
2872 /* Enable bt_shd0 on gpio4: */
2873 val |= (CCTRL4331_BT_SHD0_ON_GPIO4);
2874 W_REG(sii->osh, &cc->chipcontrol, val);
2875 } else {
2876 val &= ~(CCTRL4331_BT_SHD0_ON_GPIO4);
2877 W_REG(sii->osh, &cc->chipcontrol, val);
2878 }
2879
2880 /* restore the original index */
2881 si_setcoreidx(sih, origidx);
2882
2883 INTR_RESTORE(sii, intr_val);
2884 }
2885
2886 void
si_chipcontrl_restore(si_t * sih,uint32 val)2887 si_chipcontrl_restore(si_t *sih, uint32 val)
2888 {
2889 si_info_t *sii = SI_INFO(sih);
2890 chipcregs_t *cc;
2891 uint origidx = si_coreidx(sih);
2892
2893 if ((cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0)) == NULL) {
2894 SI_ERROR(("%s: Failed to find CORE ID!\n", __FUNCTION__));
2895 return;
2896 }
2897 W_REG(sii->osh, &cc->chipcontrol, val);
2898 si_setcoreidx(sih, origidx);
2899 }
2900
2901 uint32
si_chipcontrl_read(si_t * sih)2902 si_chipcontrl_read(si_t *sih)
2903 {
2904 si_info_t *sii = SI_INFO(sih);
2905 chipcregs_t *cc;
2906 uint origidx = si_coreidx(sih);
2907 uint32 val;
2908
2909 if ((cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0)) == NULL) {
2910 SI_ERROR(("%s: Failed to find CORE ID!\n", __FUNCTION__));
2911 return -1;
2912 }
2913 val = R_REG(sii->osh, &cc->chipcontrol);
2914 si_setcoreidx(sih, origidx);
2915 return val;
2916 }
2917
2918 void
si_chipcontrl_epa4331(si_t * sih,bool on)2919 si_chipcontrl_epa4331(si_t *sih, bool on)
2920 {
2921 si_info_t *sii = SI_INFO(sih);
2922 chipcregs_t *cc;
2923 uint origidx = si_coreidx(sih);
2924 uint32 val;
2925
2926 if ((cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0)) == NULL) {
2927 SI_ERROR(("%s: Failed to find CORE ID!\n", __FUNCTION__));
2928 return;
2929 }
2930 val = R_REG(sii->osh, &cc->chipcontrol);
2931
2932 if (on) {
2933 if (sih->chippkg == 9 || sih->chippkg == 0xb) {
2934 val |= (CCTRL4331_EXTPA_EN | CCTRL4331_EXTPA_ON_GPIO2_5);
2935 /* Ext PA Controls for 4331 12x9 Package */
2936 W_REG(sii->osh, &cc->chipcontrol, val);
2937 } else {
2938 /* Ext PA Controls for 4331 12x12 Package */
2939 if (CHIPREV(sih->chiprev) > 0) {
2940 W_REG(sii->osh, &cc->chipcontrol, val |
2941 (CCTRL4331_EXTPA_EN) | (CCTRL4331_EXTPA_EN2));
2942 } else {
2943 W_REG(sii->osh, &cc->chipcontrol, val | (CCTRL4331_EXTPA_EN));
2944 }
2945 }
2946 } else {
2947 val &= ~(CCTRL4331_EXTPA_EN | CCTRL4331_EXTPA_EN2 | CCTRL4331_EXTPA_ON_GPIO2_5);
2948 W_REG(sii->osh, &cc->chipcontrol, val);
2949 }
2950
2951 si_setcoreidx(sih, origidx);
2952 }
2953
2954 /** switch muxed pins, on: SROM, off: FEMCTRL. Called for a family of ac chips, not just 4360. */
2955 void
si_chipcontrl_srom4360(si_t * sih,bool on)2956 si_chipcontrl_srom4360(si_t *sih, bool on)
2957 {
2958 si_info_t *sii = SI_INFO(sih);
2959 chipcregs_t *cc;
2960 uint origidx = si_coreidx(sih);
2961 uint32 val;
2962
2963 if ((cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0)) == NULL) {
2964 SI_ERROR(("%s: Failed to find CORE ID!\n", __FUNCTION__));
2965 return;
2966 }
2967 val = R_REG(sii->osh, &cc->chipcontrol);
2968
2969 if (on) {
2970 val &= ~(CCTRL4360_SECI_MODE |
2971 CCTRL4360_BTSWCTRL_MODE |
2972 CCTRL4360_EXTRA_FEMCTRL_MODE |
2973 CCTRL4360_BT_LGCY_MODE |
2974 CCTRL4360_CORE2FEMCTRL4_ON);
2975
2976 W_REG(sii->osh, &cc->chipcontrol, val);
2977 } else {
2978 }
2979
2980 si_setcoreidx(sih, origidx);
2981 }
2982
2983 void
si_clk_srom4365(si_t * sih)2984 si_clk_srom4365(si_t *sih)
2985 {
2986 si_info_t *sii = SI_INFO(sih);
2987 chipcregs_t *cc;
2988 uint origidx = si_coreidx(sih);
2989 uint32 val;
2990
2991 if ((cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0)) == NULL) {
2992 SI_ERROR(("%s: Failed to find CORE ID!\n", __FUNCTION__));
2993 return;
2994 }
2995 val = R_REG(sii->osh, &cc->clkdiv2);
2996 W_REG(sii->osh, &cc->clkdiv2, ((val&~0xf) | 0x4));
2997
2998 si_setcoreidx(sih, origidx);
2999 }
3000
3001 void
si_chipcontrl_epa4331_wowl(si_t * sih,bool enter_wowl)3002 si_chipcontrl_epa4331_wowl(si_t *sih, bool enter_wowl)
3003 {
3004 si_info_t *sii;
3005 chipcregs_t *cc;
3006 uint origidx;
3007 uint32 val;
3008 bool sel_chip;
3009
3010 sel_chip = (CHIPID(sih->chip) == BCM4331_CHIP_ID) ||
3011 (CHIPID(sih->chip) == BCM43431_CHIP_ID);
3012 sel_chip &= ((sih->chippkg == 9 || sih->chippkg == 0xb));
3013
3014 if (!sel_chip)
3015 return;
3016
3017 sii = SI_INFO(sih);
3018 origidx = si_coreidx(sih);
3019
3020 if ((cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0)) == NULL) {
3021 SI_ERROR(("%s: Failed to find CORE ID!\n", __FUNCTION__));
3022 return;
3023 }
3024
3025 val = R_REG(sii->osh, &cc->chipcontrol);
3026
3027 if (enter_wowl) {
3028 val |= CCTRL4331_EXTPA_EN;
3029 W_REG(sii->osh, &cc->chipcontrol, val);
3030 } else {
3031 val |= (CCTRL4331_EXTPA_EN | CCTRL4331_EXTPA_ON_GPIO2_5);
3032 W_REG(sii->osh, &cc->chipcontrol, val);
3033 }
3034 si_setcoreidx(sih, origidx);
3035 }
3036 #endif
3037
3038 uint
si_pll_reset(si_t * sih)3039 si_pll_reset(si_t *sih)
3040 {
3041 uint err = 0;
3042
3043 return (err);
3044 }
3045
3046 /** Enable BT-COEX & Ex-PA for 4313 */
3047 void
si_epa_4313war(si_t * sih)3048 si_epa_4313war(si_t *sih)
3049 {
3050 si_info_t *sii = SI_INFO(sih);
3051 chipcregs_t *cc;
3052 uint origidx = si_coreidx(sih);
3053
3054 if ((cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0)) == NULL) {
3055 SI_ERROR(("%s: Failed to find CORE ID!\n", __FUNCTION__));
3056 return;
3057 }
3058
3059 /* EPA Fix */
3060 W_REG(sii->osh, &cc->gpiocontrol,
3061 R_REG(sii->osh, &cc->gpiocontrol) | GPIO_CTRL_EPA_EN_MASK);
3062
3063 si_setcoreidx(sih, origidx);
3064 }
3065
3066 void
si_clk_pmu_htavail_set(si_t * sih,bool set_clear)3067 si_clk_pmu_htavail_set(si_t *sih, bool set_clear)
3068 {
3069 }
3070
3071 void
si_pmu_avb_clk_set(si_t * sih,osl_t * osh,bool set_flag)3072 si_pmu_avb_clk_set(si_t *sih, osl_t *osh, bool set_flag)
3073 {
3074 }
3075
3076 /** Re-enable synth_pwrsw resource in min_res_mask for 4313 */
3077 void
si_pmu_synth_pwrsw_4313_war(si_t * sih)3078 si_pmu_synth_pwrsw_4313_war(si_t *sih)
3079 {
3080 }
3081
3082 /** WL/BT control for 4313 btcombo boards >= P250 */
3083 void
si_btcombo_p250_4313_war(si_t * sih)3084 si_btcombo_p250_4313_war(si_t *sih)
3085 {
3086 si_info_t *sii = SI_INFO(sih);
3087 chipcregs_t *cc;
3088 uint origidx = si_coreidx(sih);
3089
3090 if ((cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0)) == NULL) {
3091 SI_ERROR(("%s: Failed to find CORE ID!\n", __FUNCTION__));
3092 return;
3093 }
3094 W_REG(sii->osh, &cc->gpiocontrol,
3095 R_REG(sii->osh, &cc->gpiocontrol) | GPIO_CTRL_5_6_EN_MASK);
3096
3097 W_REG(sii->osh, &cc->gpioouten,
3098 R_REG(sii->osh, &cc->gpioouten) | GPIO_CTRL_5_6_EN_MASK);
3099
3100 si_setcoreidx(sih, origidx);
3101 }
3102 void
si_btc_enable_chipcontrol(si_t * sih)3103 si_btc_enable_chipcontrol(si_t *sih)
3104 {
3105 si_info_t *sii = SI_INFO(sih);
3106 chipcregs_t *cc;
3107 uint origidx = si_coreidx(sih);
3108
3109 if ((cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0)) == NULL) {
3110 SI_ERROR(("%s: Failed to find CORE ID!\n", __FUNCTION__));
3111 return;
3112 }
3113
3114 /* BT fix */
3115 W_REG(sii->osh, &cc->chipcontrol,
3116 R_REG(sii->osh, &cc->chipcontrol) | CC_BTCOEX_EN_MASK);
3117
3118 si_setcoreidx(sih, origidx);
3119 }
3120 void
si_btcombo_43228_war(si_t * sih)3121 si_btcombo_43228_war(si_t *sih)
3122 {
3123 si_info_t *sii = SI_INFO(sih);
3124 chipcregs_t *cc;
3125 uint origidx = si_coreidx(sih);
3126
3127 if ((cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0)) == NULL) {
3128 SI_ERROR(("%s: Failed to find CORE ID!\n", __FUNCTION__));
3129 return;
3130 }
3131
3132 W_REG(sii->osh, &cc->gpioouten, GPIO_CTRL_7_6_EN_MASK);
3133 W_REG(sii->osh, &cc->gpioout, GPIO_OUT_7_EN_MASK);
3134
3135 si_setcoreidx(sih, origidx);
3136 }
3137
3138 /** cache device removed state */
si_set_device_removed(si_t * sih,bool status)3139 void si_set_device_removed(si_t *sih, bool status)
3140 {
3141 si_info_t *sii = SI_INFO(sih);
3142
3143 sii->device_removed = status;
3144 }
3145
3146 /** check if the device is removed */
3147 bool
si_deviceremoved(si_t * sih)3148 si_deviceremoved(si_t *sih)
3149 {
3150 uint32 w;
3151 si_info_t *sii = SI_INFO(sih);
3152
3153 if (sii->device_removed) {
3154 return TRUE;
3155 }
3156
3157 switch (BUSTYPE(sih->bustype)) {
3158 case PCI_BUS:
3159 ASSERT(SI_INFO(sih)->osh != NULL);
3160 w = OSL_PCI_READ_CONFIG(SI_INFO(sih)->osh, PCI_CFG_VID, sizeof(uint32));
3161 if ((w & 0xFFFF) != VENDOR_BROADCOM)
3162 return TRUE;
3163 break;
3164 }
3165 return FALSE;
3166 }
3167
3168 bool
si_is_warmboot(void)3169 si_is_warmboot(void)
3170 {
3171
3172 #ifdef BCMULP
3173 return (boot_type == WARM_BOOT);
3174 #else
3175 return FALSE;
3176 #endif
3177 }
3178
3179 bool
si_is_sprom_available(si_t * sih)3180 si_is_sprom_available(si_t *sih)
3181 {
3182 if (CCREV(sih->ccrev) >= 31) {
3183 si_info_t *sii;
3184 uint origidx;
3185 chipcregs_t *cc;
3186 uint32 sromctrl;
3187
3188 if ((sih->cccaps & CC_CAP_SROM) == 0)
3189 return FALSE;
3190
3191 sii = SI_INFO(sih);
3192 origidx = sii->curidx;
3193 cc = si_setcoreidx(sih, SI_CC_IDX);
3194 ASSERT(cc);
3195 sromctrl = R_REG(sii->osh, &cc->sromcontrol);
3196 si_setcoreidx(sih, origidx);
3197 return (sromctrl & SRC_PRESENT);
3198 }
3199
3200 switch (CHIPID(sih->chip)) {
3201 case BCM43018_CHIP_ID:
3202 case BCM43430_CHIP_ID:
3203 return FALSE;
3204 case BCM4336_CHIP_ID:
3205 case BCM43362_CHIP_ID:
3206 return (sih->chipst & CST4336_SPROM_PRESENT) != 0;
3207 case BCM4330_CHIP_ID:
3208 return (sih->chipst & CST4330_SPROM_PRESENT) != 0;
3209 case BCM4313_CHIP_ID:
3210 return (sih->chipst & CST4313_SPROM_PRESENT) != 0;
3211 case BCM4331_CHIP_ID:
3212 case BCM43431_CHIP_ID:
3213 return (sih->chipst & CST4331_SPROM_PRESENT) != 0;
3214 case BCM43239_CHIP_ID:
3215 return ((sih->chipst & CST43239_SPROM_MASK) &&
3216 !(sih->chipst & CST43239_SFLASH_MASK));
3217 case BCM4324_CHIP_ID:
3218 case BCM43242_CHIP_ID:
3219 return ((sih->chipst & CST4324_SPROM_MASK) &&
3220 !(sih->chipst & CST4324_SFLASH_MASK));
3221 case BCM4335_CHIP_ID:
3222 CASE_BCM4345_CHIP:
3223 return ((sih->chipst & CST4335_SPROM_MASK) &&
3224 !(sih->chipst & CST4335_SFLASH_MASK));
3225 case BCM4349_CHIP_GRPID:
3226 return (sih->chipst & CST4349_SPROM_PRESENT) != 0;
3227 case BCM53573_CHIP_GRPID:
3228 return FALSE; /* SPROM PRESENT is not defined for 53573 as of now */
3229 case BCM4347_CHIP_ID:
3230 return (sih->chipst & CST4347_SPROM_PRESENT) != 0;
3231 break;
3232 case BCM4350_CHIP_ID:
3233 case BCM4354_CHIP_ID:
3234 case BCM43556_CHIP_ID:
3235 case BCM43558_CHIP_ID:
3236 case BCM43566_CHIP_ID:
3237 case BCM43568_CHIP_ID:
3238 case BCM43569_CHIP_ID:
3239 case BCM43570_CHIP_ID:
3240 case BCM4358_CHIP_ID:
3241 return (sih->chipst & CST4350_SPROM_PRESENT) != 0;
3242 CASE_BCM43602_CHIP:
3243 return (sih->chipst & CST43602_SPROM_PRESENT) != 0;
3244 case BCM43131_CHIP_ID:
3245 case BCM43217_CHIP_ID:
3246 case BCM43227_CHIP_ID:
3247 case BCM43228_CHIP_ID:
3248 case BCM43428_CHIP_ID:
3249 return (sih->chipst & CST43228_OTP_PRESENT) != CST43228_OTP_PRESENT;
3250 case BCM43012_CHIP_ID:
3251 return FALSE;
3252 default:
3253 return TRUE;
3254 }
3255 }
3256
3257
si_get_sromctl(si_t * sih)3258 uint32 si_get_sromctl(si_t *sih)
3259 {
3260 chipcregs_t *cc;
3261 uint origidx = si_coreidx(sih);
3262 uint32 sromctl;
3263 osl_t *osh = si_osh(sih);
3264
3265 cc = si_setcoreidx(sih, SI_CC_IDX);
3266 ASSERT((uintptr)cc);
3267
3268 sromctl = R_REG(osh, &cc->sromcontrol);
3269
3270 /* return to the original core */
3271 si_setcoreidx(sih, origidx);
3272 return sromctl;
3273 }
3274
si_set_sromctl(si_t * sih,uint32 value)3275 int si_set_sromctl(si_t *sih, uint32 value)
3276 {
3277 chipcregs_t *cc;
3278 uint origidx = si_coreidx(sih);
3279 osl_t *osh = si_osh(sih);
3280 int ret = BCME_OK;
3281
3282 cc = si_setcoreidx(sih, SI_CC_IDX);
3283 ASSERT((uintptr)cc);
3284
3285 /* get chipcommon rev */
3286 if (si_corerev(sih) >= 32) {
3287 /* SpromCtrl is only accessible if CoreCapabilities.SpromSupported and
3288 * SpromPresent is 1.
3289 */
3290 if ((R_REG(osh, &cc->capabilities) & CC_CAP_SROM) != 0 &&
3291 (R_REG(osh, &cc->sromcontrol) & SRC_PRESENT)) {
3292 W_REG(osh, &cc->sromcontrol, value);
3293 } else {
3294 ret = BCME_NODEVICE;
3295 }
3296 } else {
3297 ret = BCME_UNSUPPORTED;
3298 }
3299
3300 /* return to the original core */
3301 si_setcoreidx(sih, origidx);
3302
3303 return ret;
3304 }
3305
3306 uint
si_core_wrapperreg(si_t * sih,uint32 coreidx,uint32 offset,uint32 mask,uint32 val)3307 si_core_wrapperreg(si_t *sih, uint32 coreidx, uint32 offset, uint32 mask, uint32 val)
3308 {
3309 uint origidx, intr_val = 0;
3310 uint ret_val;
3311 si_info_t *sii = SI_INFO(sih);
3312
3313 origidx = si_coreidx(sih);
3314
3315 INTR_OFF(sii, intr_val);
3316 si_setcoreidx(sih, coreidx);
3317
3318 ret_val = si_wrapperreg(sih, offset, mask, val);
3319
3320 /* return to the original core */
3321 si_setcoreidx(sih, origidx);
3322 INTR_RESTORE(sii, intr_val);
3323 return ret_val;
3324 }
3325
3326
3327 /* cleanup the timer from the host when ARM is been halted
3328 * without a chance for ARM cleanup its resources
3329 * If left not cleanup, Intr from a software timer can still
3330 * request HT clk when ARM is halted.
3331 */
3332 uint32
si_pmu_res_req_timer_clr(si_t * sih)3333 si_pmu_res_req_timer_clr(si_t *sih)
3334 {
3335 uint32 mask;
3336
3337 mask = PRRT_REQ_ACTIVE | PRRT_INTEN | PRRT_HT_REQ;
3338 mask <<= 14;
3339 /* clear mask bits */
3340 pmu_corereg(sih, SI_CC_IDX, res_req_timer, mask, 0);
3341 /* readback to ensure write completes */
3342 return pmu_corereg(sih, SI_CC_IDX, res_req_timer, 0, 0);
3343 }
3344
3345 /** turn on/off rfldo */
3346 void
si_pmu_rfldo(si_t * sih,bool on)3347 si_pmu_rfldo(si_t *sih, bool on)
3348 {
3349 }
3350
3351
3352 #ifdef SURVIVE_PERST_ENAB
3353 static uint32
si_pcie_survive_perst(si_t * sih,uint32 mask,uint32 val)3354 si_pcie_survive_perst(si_t *sih, uint32 mask, uint32 val)
3355 {
3356 si_info_t *sii;
3357
3358 sii = SI_INFO(sih);
3359
3360 if (!PCIE(sii))
3361 return (0);
3362
3363 return pcie_survive_perst(sii->pch, mask, val);
3364 }
3365
3366 static void
si_watchdog_reset(si_t * sih)3367 si_watchdog_reset(si_t *sih)
3368 {
3369 uint32 i;
3370
3371 /* issue a watchdog reset */
3372 pmu_corereg(sih, SI_CC_IDX, pmuwatchdog, 2, 2);
3373 /* do busy wait for 20ms */
3374 for (i = 0; i < 2000; i++) {
3375 OSL_DELAY(10);
3376 }
3377 }
3378 #endif /* SURVIVE_PERST_ENAB */
3379
3380 void
si_survive_perst_war(si_t * sih,bool reset,uint32 sperst_mask,uint32 sperst_val)3381 si_survive_perst_war(si_t *sih, bool reset, uint32 sperst_mask, uint32 sperst_val)
3382 {
3383 #ifdef SURVIVE_PERST_ENAB
3384 if (BUSTYPE(sih->bustype) != PCI_BUS)
3385 return;
3386
3387 if ((CHIPID(sih->chip) != BCM4360_CHIP_ID && CHIPID(sih->chip) != BCM4352_CHIP_ID) ||
3388 (CHIPREV(sih->chiprev) >= 4))
3389 return;
3390
3391 if (reset) {
3392 si_info_t *sii = SI_INFO(sih);
3393 uint32 bar0win, bar0win_after;
3394
3395 /* save the bar0win */
3396 bar0win = OSL_PCI_READ_CONFIG(sii->osh, PCI_BAR0_WIN, sizeof(uint32));
3397
3398 si_watchdog_reset(sih);
3399
3400 bar0win_after = OSL_PCI_READ_CONFIG(sii->osh, PCI_BAR0_WIN, sizeof(uint32));
3401 if (bar0win_after != bar0win) {
3402 SI_ERROR(("%s: bar0win before %08x, bar0win after %08x\n",
3403 __FUNCTION__, bar0win, bar0win_after));
3404 OSL_PCI_WRITE_CONFIG(sii->osh, PCI_BAR0_WIN, sizeof(uint32), bar0win);
3405 }
3406 }
3407 if (sperst_mask) {
3408 /* enable survive perst */
3409 si_pcie_survive_perst(sih, sperst_mask, sperst_val);
3410 }
3411 #endif /* SURVIVE_PERST_ENAB */
3412 }
3413
3414 /* Caller of this function should make sure is on PCIE core
3415 * Used in pciedev.c.
3416 */
3417 void
si_pcie_disable_oobselltr(si_t * sih)3418 si_pcie_disable_oobselltr(si_t *sih)
3419 {
3420 ASSERT(si_coreid(sih) == PCIE2_CORE_ID);
3421 si_wrapperreg(sih, AI_OOBSELIND30, ~0, 0);
3422 }
3423
3424 void
si_pcie_ltr_war(si_t * sih)3425 si_pcie_ltr_war(si_t *sih)
3426 {
3427 }
3428
3429 void
si_pcie_hw_LTR_war(si_t * sih)3430 si_pcie_hw_LTR_war(si_t *sih)
3431 {
3432 }
3433
3434 void
si_pciedev_reg_pm_clk_period(si_t * sih)3435 si_pciedev_reg_pm_clk_period(si_t *sih)
3436 {
3437 }
3438
3439 void
si_pciedev_crwlpciegen2(si_t * sih)3440 si_pciedev_crwlpciegen2(si_t *sih)
3441 {
3442 }
3443
3444 void
si_pcie_prep_D3(si_t * sih,bool enter_D3)3445 si_pcie_prep_D3(si_t *sih, bool enter_D3)
3446 {
3447 }
3448
3449
3450 #ifdef BCM_BACKPLANE_TIMEOUT
3451 uint32
si_clear_backplane_to_fast(si_t * sih,void * addr)3452 si_clear_backplane_to_fast(si_t *sih, void * addr)
3453 {
3454 if (CHIPTYPE(sih->socitype) == SOCI_AI) {
3455 return ai_clear_backplane_to_fast(sih, addr);
3456 }
3457
3458 return 0;
3459 }
3460
si_get_axi_errlog_info(si_t * sih)3461 const si_axi_error_info_t * si_get_axi_errlog_info(si_t * sih)
3462 {
3463 if (CHIPTYPE(sih->socitype) == SOCI_AI) {
3464 return (const si_axi_error_info_t *)sih->err_info;
3465 }
3466
3467 return NULL;
3468 }
3469
si_reset_axi_errlog_info(si_t * sih)3470 void si_reset_axi_errlog_info(si_t * sih)
3471 {
3472 sih->err_info->count = 0;
3473 }
3474 #endif /* BCM_BACKPLANE_TIMEOUT */
3475
3476 #if defined(AXI_TIMEOUTS) || defined(BCM_BACKPLANE_TIMEOUT)
3477 uint32
si_clear_backplane_to_per_core(si_t * sih,uint coreid,uint coreunit,void * wrap)3478 si_clear_backplane_to_per_core(si_t *sih, uint coreid, uint coreunit, void * wrap)
3479 {
3480 if (CHIPTYPE(sih->socitype) == SOCI_AI) {
3481 return ai_clear_backplane_to_per_core(sih, coreid, coreunit, wrap);
3482 }
3483
3484 return AXI_WRAP_STS_NONE;
3485 }
3486 #endif /* AXI_TIMEOUTS || BCM_BACKPLANE_TIMEOUT */
3487
3488 uint32
si_clear_backplane_to(si_t * sih)3489 si_clear_backplane_to(si_t *sih)
3490 {
3491 if (CHIPTYPE(sih->socitype) == SOCI_AI) {
3492 return ai_clear_backplane_to(sih);
3493 }
3494
3495 return 0;
3496 }
3497
3498 /*
3499 * This routine adds the AXI timeouts for
3500 * chipcommon, pcie and ARM slave wrappers
3501 */
3502 void
si_slave_wrapper_add(si_t * sih)3503 si_slave_wrapper_add(si_t *sih)
3504 {
3505 #if defined(AXI_TIMEOUTS) || defined(BCM_BACKPLANE_TIMEOUT)
3506 /* Enable only for AXI */
3507 if (CHIPTYPE(sih->socitype) != SOCI_AI) {
3508 return;
3509 }
3510
3511 if (CHIPID(sih->chip) == BCM4345_CHIP_ID && CHIPREV(sih->chiprev) >= 6) {
3512 si_info_t *sii = SI_INFO(sih);
3513
3514 int wrapper_idx = (int)sii->axi_num_wrappers - 1;
3515
3516 ASSERT(wrapper_idx >= 0); /* axi_wrapper[] not initialised */
3517 do {
3518 if (sii->axi_wrapper[wrapper_idx].wrapper_type == AI_SLAVE_WRAPPER &&
3519 sii->axi_wrapper[wrapper_idx].cid == 0xfff) {
3520 sii->axi_wrapper[wrapper_idx].wrapper_addr = 0x1810b000;
3521 break;
3522 }
3523 } while (wrapper_idx-- > 0);
3524 ASSERT(wrapper_idx >= 0); /* all addresses valid for the chiprev under test */
3525 }
3526
3527 /* All required slave wrappers are added in ai_scan */
3528 ai_enable_backplane_timeouts(sih);
3529 #endif /* AXI_TIMEOUTS || BCM_BACKPLANE_TIMEOUT */
3530 }
3531
3532
3533 void
si_pll_sr_reinit(si_t * sih)3534 si_pll_sr_reinit(si_t *sih)
3535 {
3536 }
3537
3538
3539 /* Programming d11 core oob settings for 4364
3540 * WARs for HW4364-237 and HW4364-166
3541 */
3542 void
si_config_4364_d11_oob(si_t * sih,uint coreid)3543 si_config_4364_d11_oob(si_t *sih, uint coreid)
3544 {
3545 uint save_idx;
3546
3547 save_idx = si_coreidx(sih);
3548 si_setcore(sih, coreid, 0);
3549 si_wrapperreg(sih, AI_OOBSELINC30, ~0, 0x81828180);
3550 si_wrapperreg(sih, AI_OOBSELINC74, ~0, 0x87868183);
3551 si_wrapperreg(sih, AI_OOBSELOUTB74, ~0, 0x84858484);
3552 si_setcore(sih, coreid, 1);
3553 si_wrapperreg(sih, AI_OOBSELINC30, ~0, 0x81828180);
3554 si_wrapperreg(sih, AI_OOBSELINC74, ~0, 0x87868184);
3555 si_wrapperreg(sih, AI_OOBSELOUTB74, ~0, 0x84868484);
3556 si_setcoreidx(sih, save_idx);
3557 }
3558
3559 void
si_pll_closeloop(si_t * sih)3560 si_pll_closeloop(si_t *sih)
3561 {
3562 #if defined(SAVERESTORE)
3563 uint32 data;
3564
3565 /* disable PLL open loop operation */
3566 switch (CHIPID(sih->chip)) {
3567 #ifdef SAVERESTORE
3568 case BCM43018_CHIP_ID:
3569 case BCM43430_CHIP_ID:
3570 if (SR_ENAB() && sr_isenab(sih)) {
3571 /* read back the pll openloop state */
3572 data = si_pmu_pllcontrol(sih, PMU1_PLL0_PLLCTL8, 0, 0);
3573 /* current mode is openloop (possible POR) */
3574 if ((data & PMU1_PLLCTL8_OPENLOOP_MASK) != 0) {
3575 si_pmu_pllcontrol(sih, PMU1_PLL0_PLLCTL8,
3576 PMU1_PLLCTL8_OPENLOOP_MASK, 0);
3577 si_pmu_pllupd(sih);
3578 }
3579 }
3580 break;
3581 #endif /* SAVERESTORE */
3582 default:
3583 /* any unsupported chip bail */
3584 return;
3585 }
3586 #endif
3587 }
3588
3589 void
si_update_macclk_mul_fact(si_t * sih,uint32 mul_fact)3590 si_update_macclk_mul_fact(si_t *sih, uint32 mul_fact)
3591 {
3592 si_info_t *sii = SI_INFO(sih);
3593 sii->macclk_mul_fact = mul_fact;
3594 }
3595
3596 uint32
si_get_macclk_mul_fact(si_t * sih)3597 si_get_macclk_mul_fact(si_t *sih)
3598 {
3599 si_info_t *sii = SI_INFO(sih);
3600 return sii->macclk_mul_fact;
3601 }
3602
3603
3604 #if defined(BCMSRPWR) && !defined(BCMSRPWR_DISABLED)
3605 bool _bcmsrpwr = TRUE;
3606 #else
3607 bool _bcmsrpwr = FALSE;
3608 #endif
3609
3610 uint32
si_srpwr_request(si_t * sih,uint32 mask,uint32 val)3611 si_srpwr_request(si_t *sih, uint32 mask, uint32 val)
3612 {
3613 uint32 r, offset = OFFSETOF(chipcregs_t, powerctl); /* Same 0x1e8 per core */
3614 uint cidx = (BUSTYPE(sih->bustype) == SI_BUS) ? SI_CC_IDX : sih->buscoreidx;
3615
3616 if (mask || val) {
3617 mask <<= SRPWR_REQON_SHIFT;
3618 val <<= SRPWR_REQON_SHIFT;
3619
3620 r = ((si_corereg(sih, cidx, offset, 0, 0) & ~mask) | val);
3621 r = si_corereg(sih, cidx, offset, ~0, r);
3622 } else {
3623 r = si_corereg(sih, cidx, offset, 0, 0);
3624 }
3625
3626 return r;
3627 }
3628
3629 uint32
si_srpwr_stat_spinwait(si_t * sih,uint32 mask,uint32 val)3630 si_srpwr_stat_spinwait(si_t *sih, uint32 mask, uint32 val)
3631 {
3632 uint32 r, offset = OFFSETOF(chipcregs_t, powerctl); /* Same 0x1e8 per core */
3633 uint cidx = (BUSTYPE(sih->bustype) == SI_BUS) ? SI_CC_IDX : sih->buscoreidx;
3634
3635 ASSERT(mask);
3636 ASSERT(val);
3637
3638 /* spinwait on pwrstatus */
3639 mask <<= SRPWR_STATUS_SHIFT;
3640 val <<= SRPWR_STATUS_SHIFT;
3641
3642 SPINWAIT(((si_corereg(sih, cidx, offset, 0, 0) & mask) != val),
3643 PMU_MAX_TRANSITION_DLY);
3644 ASSERT((si_corereg(sih, cidx, offset, 0, 0) & mask) == val);
3645
3646 r = si_corereg(sih, cidx, offset, 0, 0) & mask;
3647 r = (r >> SRPWR_STATUS_SHIFT) & SRPWR_DMN_ALL_MASK;
3648
3649 return r;
3650 }
3651
3652 uint32
si_srpwr_stat(si_t * sih)3653 si_srpwr_stat(si_t *sih)
3654 {
3655 uint32 r, offset = OFFSETOF(chipcregs_t, powerctl); /* Same 0x1e8 per core */
3656 uint cidx = (BUSTYPE(sih->bustype) == SI_BUS) ? SI_CC_IDX : sih->buscoreidx;
3657
3658 r = si_corereg(sih, cidx, offset, 0, 0);
3659 r = (r >> SRPWR_STATUS_SHIFT) & SRPWR_DMN_ALL_MASK;
3660
3661 return r;
3662 }
3663
3664 uint32
si_srpwr_domain(si_t * sih)3665 si_srpwr_domain(si_t *sih)
3666 {
3667 uint32 r, offset = OFFSETOF(chipcregs_t, powerctl); /* Same 0x1e8 per core */
3668 uint cidx = (BUSTYPE(sih->bustype) == SI_BUS) ? SI_CC_IDX : sih->buscoreidx;
3669
3670 r = si_corereg(sih, cidx, offset, 0, 0);
3671 r = (r >> SRPWR_DMN_SHIFT) & SRPWR_DMN_ALL_MASK;
3672
3673 return r;
3674 }
3675
3676 /* Utility API to read/write the raw registers with absolute address.
3677 * This function can be invoked from either FW or host driver.
3678 */
3679 uint32
si_raw_reg(si_t * sih,uint32 reg,uint32 val,uint32 wrire_req)3680 si_raw_reg(si_t *sih, uint32 reg, uint32 val, uint32 wrire_req)
3681 {
3682 si_info_t *sii = SI_INFO(sih);
3683 uint32 address_space = reg & ~0xFFF;
3684 volatile uint32 * addr = (void*)(uintptr)(reg);
3685 uint32 prev_value = 0;
3686 uint32 cfg_reg = 0;
3687
3688 if (sii == NULL) {
3689 return 0;
3690 }
3691
3692 /* No need to translate the absolute address on SI bus */
3693 if (BUSTYPE(sih->bustype) == SI_BUS) {
3694 goto skip_cfg;
3695 }
3696
3697 /* This API supports only the PCI host interface */
3698 if (BUSTYPE(sih->bustype) != PCI_BUS) {
3699 return ID32_INVALID;
3700 }
3701
3702 if (PCIE_GEN2(sii)) {
3703 /* Use BAR0 Secondary window is PCIe Gen2.
3704 * Set the secondary BAR0 Window to current register of interest
3705 */
3706 addr = (volatile uint32*)(((volatile uint8*)sii->curmap) +
3707 PCI_SEC_BAR0_WIN_OFFSET + (reg & 0xfff));
3708 cfg_reg = PCIE2_BAR0_CORE2_WIN;
3709
3710 } else {
3711 /* PCIe Gen1 do not have secondary BAR0 window.
3712 * reuse the BAR0 WIN2
3713 */
3714 addr = (volatile uint32*)(((volatile uint8*)sii->curmap) +
3715 PCI_BAR0_WIN2_OFFSET + (reg & 0xfff));
3716 cfg_reg = PCI_BAR0_WIN2;
3717 }
3718
3719 prev_value = OSL_PCI_READ_CONFIG(sii->osh, cfg_reg, 4);
3720
3721 if (prev_value != address_space) {
3722 OSL_PCI_WRITE_CONFIG(sii->osh, cfg_reg,
3723 sizeof(uint32), address_space);
3724 } else {
3725 prev_value = 0;
3726 }
3727
3728 skip_cfg:
3729 if (wrire_req) {
3730 W_REG(sii->osh, addr, val);
3731 } else {
3732 val = R_REG(sii->osh, addr);
3733 }
3734
3735 if (prev_value) {
3736 /* Restore BAR0 WIN2 for PCIE GEN1 devices */
3737 OSL_PCI_WRITE_CONFIG(sii->osh,
3738 cfg_reg, sizeof(uint32), prev_value);
3739 }
3740
3741 return val;
3742 }
3743