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