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