1 /*
2  * Copyright (c) 2010 Broadcom Corporation
3  *
4  * Permission to use, copy, modify, and/or distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16 
17 #include <linux/delay.h>
18 #include <linux/kernel.h>
19 #include <linux/string.h>
20 #include <bcmdefs.h>
21 #include <linux/module.h>
22 #include <linux/pci.h>
23 #include <bcmutils.h>
24 #include <siutils.h>
25 #include <bcmdevs.h>
26 #include <hndsoc.h>
27 #include <sbchipc.h>
28 #include <pci_core.h>
29 #include <pcie_core.h>
30 #include <nicpci.h>
31 #include <bcmnvram.h>
32 #include <bcmsrom.h>
33 #include <pcicfg.h>
34 #include <sbsocram.h>
35 #ifdef BCMSDIO
36 #include <bcmsdh.h>
37 #include <sdio.h>
38 #include <sbsdio.h>
39 #include <sbhnddma.h>
40 #include <sbsdpcmdev.h>
41 #include <bcmsdpcm.h>
42 #endif				/* BCMSDIO */
43 #include <hndpmu.h>
44 
45 /* this file now contains only definitions for sb functions, only necessary
46 *for devices using Sonics backplanes (bcm4329)
47 */
48 
49 /* if an amba SDIO device is supported, please further restrict the inclusion
50  * of this file
51  */
52 #ifdef BCMSDIO
53 #include "siutils_priv.h"
54 #endif
55 
56 /* local prototypes */
57 static si_info_t *si_doattach(si_info_t *sii, uint devid, void *regs,
58 			      uint bustype, void *sdh, char **vars,
59 			      uint *varsz);
60 static bool si_buscore_prep(si_info_t *sii, uint bustype, uint devid,
61 			    void *sdh);
62 static bool si_buscore_setup(si_info_t *sii, chipcregs_t *cc, uint bustype,
63 			     u32 savewin, uint *origidx, void *regs);
64 static void si_nvram_process(si_info_t *sii, char *pvars);
65 
66 /* dev path concatenation util */
67 static char *si_devpathvar(si_t *sih, char *var, int len, const char *name);
68 static bool _si_clkctl_cc(si_info_t *sii, uint mode);
69 static bool si_ispcie(si_info_t *sii);
70 static uint socram_banksize(si_info_t *sii, sbsocramregs_t *r,
71 					u8 idx, u8 mtype);
72 
73 /* global variable to indicate reservation/release of gpio's */
74 static u32 si_gpioreservation;
75 
76 /*
77  * Allocate a si handle.
78  * devid - pci device id (used to determine chip#)
79  * osh - opaque OS handle
80  * regs - virtual address of initial core registers
81  * bustype - pci/sb/sdio/etc
82  * vars - pointer to a pointer area for "environment" variables
83  * varsz - pointer to int to return the size of the vars
84  */
si_attach(uint devid,void * regs,uint bustype,void * sdh,char ** vars,uint * varsz)85 si_t *si_attach(uint devid, void *regs, uint bustype,
86 		void *sdh, char **vars, uint *varsz)
87 {
88 	si_info_t *sii;
89 
90 	/* alloc si_info_t */
91 	sii = kmalloc(sizeof(si_info_t), GFP_ATOMIC);
92 	if (sii == NULL) {
93 		SI_ERROR(("si_attach: malloc failed!\n"));
94 		return NULL;
95 	}
96 
97 	if (si_doattach(sii, devid, regs, bustype, sdh, vars, varsz) ==
98 	    NULL) {
99 		kfree(sii);
100 		return NULL;
101 	}
102 	sii->vars = vars ? *vars : NULL;
103 	sii->varsz = varsz ? *varsz : 0;
104 
105 	return (si_t *) sii;
106 }
107 
108 /* global kernel resource */
109 static si_info_t ksii;
110 
si_buscore_prep(si_info_t * sii,uint bustype,uint devid,void * sdh)111 static bool si_buscore_prep(si_info_t *sii, uint bustype, uint devid,
112 			    void *sdh)
113 {
114 
115 #ifndef BRCM_FULLMAC
116 	/* kludge to enable the clock on the 4306 which lacks a slowclock */
117 	if (bustype == PCI_BUS && !si_ispcie(sii))
118 		si_clkctl_xtal(&sii->pub, XTAL | PLL, ON);
119 #endif
120 
121 #if defined(BCMSDIO)
122 	if (bustype == SDIO_BUS) {
123 		int err;
124 		u8 clkset;
125 
126 		/* Try forcing SDIO core to do ALPAvail request only */
127 		clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_ALP_AVAIL_REQ;
128 		bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR,
129 				 clkset, &err);
130 		if (!err) {
131 			u8 clkval;
132 
133 			/* If register supported, wait for ALPAvail and then force ALP */
134 			clkval =
135 			    bcmsdh_cfg_read(sdh, SDIO_FUNC_1,
136 					    SBSDIO_FUNC1_CHIPCLKCSR, NULL);
137 			if ((clkval & ~SBSDIO_AVBITS) == clkset) {
138 				SPINWAIT(((clkval =
139 					   bcmsdh_cfg_read(sdh, SDIO_FUNC_1,
140 							   SBSDIO_FUNC1_CHIPCLKCSR,
141 							   NULL)),
142 					  !SBSDIO_ALPAV(clkval)),
143 					 PMU_MAX_TRANSITION_DLY);
144 				if (!SBSDIO_ALPAV(clkval)) {
145 					SI_ERROR(("timeout on ALPAV wait, clkval 0x%02x\n", clkval));
146 					return false;
147 				}
148 				clkset =
149 				    SBSDIO_FORCE_HW_CLKREQ_OFF |
150 				    SBSDIO_FORCE_ALP;
151 				bcmsdh_cfg_write(sdh, SDIO_FUNC_1,
152 						 SBSDIO_FUNC1_CHIPCLKCSR,
153 						 clkset, &err);
154 				udelay(65);
155 			}
156 		}
157 
158 		/* Also, disable the extra SDIO pull-ups */
159 		bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_SDIOPULLUP, 0,
160 				 NULL);
161 	}
162 #endif				/* defined(BCMSDIO) */
163 
164 	return true;
165 }
166 
si_buscore_setup(si_info_t * sii,chipcregs_t * cc,uint bustype,u32 savewin,uint * origidx,void * regs)167 static bool si_buscore_setup(si_info_t *sii, chipcregs_t *cc, uint bustype,
168 			     u32 savewin, uint *origidx, void *regs)
169 {
170 	bool pci, pcie;
171 	uint i;
172 	uint pciidx, pcieidx, pcirev, pcierev;
173 
174 	cc = si_setcoreidx(&sii->pub, SI_CC_IDX);
175 	ASSERT(cc);
176 
177 	/* get chipcommon rev */
178 	sii->pub.ccrev = (int)si_corerev(&sii->pub);
179 
180 	/* get chipcommon chipstatus */
181 	if (sii->pub.ccrev >= 11)
182 		sii->pub.chipst = R_REG(&cc->chipstatus);
183 
184 	/* get chipcommon capabilites */
185 	sii->pub.cccaps = R_REG(&cc->capabilities);
186 	/* get chipcommon extended capabilities */
187 
188 #ifndef BRCM_FULLMAC
189 	if (sii->pub.ccrev >= 35)
190 		sii->pub.cccaps_ext = R_REG(&cc->capabilities_ext);
191 #endif
192 	/* get pmu rev and caps */
193 	if (sii->pub.cccaps & CC_CAP_PMU) {
194 		sii->pub.pmucaps = R_REG(&cc->pmucapabilities);
195 		sii->pub.pmurev = sii->pub.pmucaps & PCAP_REV_MASK;
196 	}
197 
198 	/*
199 	   SI_MSG(("Chipc: rev %d, caps 0x%x, chipst 0x%x pmurev %d, pmucaps 0x%x\n",
200 	   sii->pub.ccrev, sii->pub.cccaps, sii->pub.chipst, sii->pub.pmurev,
201 	   sii->pub.pmucaps));
202 	 */
203 
204 	/* figure out bus/orignal core idx */
205 	sii->pub.buscoretype = NODEV_CORE_ID;
206 	sii->pub.buscorerev = NOREV;
207 	sii->pub.buscoreidx = BADIDX;
208 
209 	pci = pcie = false;
210 	pcirev = pcierev = NOREV;
211 	pciidx = pcieidx = BADIDX;
212 
213 	for (i = 0; i < sii->numcores; i++) {
214 		uint cid, crev;
215 
216 		si_setcoreidx(&sii->pub, i);
217 		cid = si_coreid(&sii->pub);
218 		crev = si_corerev(&sii->pub);
219 
220 		/* Display cores found */
221 		SI_VMSG(("CORE[%d]: id 0x%x rev %d base 0x%x regs 0x%p\n",
222 			 i, cid, crev, sii->coresba[i], sii->regs[i]));
223 
224 		if (bustype == PCI_BUS) {
225 			if (cid == PCI_CORE_ID) {
226 				pciidx = i;
227 				pcirev = crev;
228 				pci = true;
229 			} else if (cid == PCIE_CORE_ID) {
230 				pcieidx = i;
231 				pcierev = crev;
232 				pcie = true;
233 			}
234 		}
235 #ifdef BCMSDIO
236 		else if (((bustype == SDIO_BUS) ||
237 			  (bustype == SPI_BUS)) &&
238 			 ((cid == PCMCIA_CORE_ID) || (cid == SDIOD_CORE_ID))) {
239 			sii->pub.buscorerev = crev;
240 			sii->pub.buscoretype = cid;
241 			sii->pub.buscoreidx = i;
242 		}
243 #endif				/* BCMSDIO */
244 
245 		/* find the core idx before entering this func. */
246 		if ((savewin && (savewin == sii->coresba[i])) ||
247 		    (regs == sii->regs[i]))
248 			*origidx = i;
249 	}
250 
251 #ifdef BRCM_FULLMAC
252 	SI_MSG(("Buscore id/type/rev %d/0x%x/%d\n", sii->pub.buscoreidx,
253 		sii->pub.buscoretype, sii->pub.buscorerev));
254 
255 	/* Make sure any on-chip ARM is off (in case strapping is wrong),
256 	* or downloaded code was
257 	* already running.
258 	*/
259 	if ((bustype == SDIO_BUS) || (bustype == SPI_BUS)) {
260 		if (si_setcore(&sii->pub, ARM7S_CORE_ID, 0) ||
261 			si_setcore(&sii->pub, ARMCM3_CORE_ID, 0))
262 			si_core_disable(&sii->pub, 0);
263 	}
264 #else
265 	if (pci && pcie) {
266 		if (si_ispcie(sii))
267 			pci = false;
268 		else
269 			pcie = false;
270 	}
271 	if (pci) {
272 		sii->pub.buscoretype = PCI_CORE_ID;
273 		sii->pub.buscorerev = pcirev;
274 		sii->pub.buscoreidx = pciidx;
275 	} else if (pcie) {
276 		sii->pub.buscoretype = PCIE_CORE_ID;
277 		sii->pub.buscorerev = pcierev;
278 		sii->pub.buscoreidx = pcieidx;
279 	}
280 
281 	SI_VMSG(("Buscore id/type/rev %d/0x%x/%d\n", sii->pub.buscoreidx,
282 		 sii->pub.buscoretype, sii->pub.buscorerev));
283 
284 	/* fixup necessary chip/core configurations */
285 	if (sii->pub.bustype == PCI_BUS) {
286 		if (SI_FAST(sii)) {
287 			if (!sii->pch) {
288 				sii->pch = (void *)pcicore_init(
289 					&sii->pub, sii->pbus,
290 					(void *)PCIEREGS(sii));
291 				if (sii->pch == NULL)
292 					return false;
293 			}
294 		}
295 		if (si_pci_fixcfg(&sii->pub)) {
296 			SI_ERROR(("si_doattach: sb_pci_fixcfg failed\n"));
297 			return false;
298 		}
299 	}
300 #endif
301 	/* return to the original core */
302 	si_setcoreidx(&sii->pub, *origidx);
303 
304 	return true;
305 }
306 
si_nvram_process(si_info_t * sii,char * pvars)307 static __used void si_nvram_process(si_info_t *sii, char *pvars)
308 {
309 	uint w = 0;
310 
311 	/* get boardtype and boardrev */
312 	switch (sii->pub.bustype) {
313 	case PCI_BUS:
314 		/* do a pci config read to get subsystem id and subvendor id */
315 		pci_read_config_dword(sii->pbus, PCI_CFG_SVID, &w);
316 		/* Let nvram variables override subsystem Vend/ID */
317 		sii->pub.boardvendor = (u16)si_getdevpathintvar(&sii->pub,
318 			"boardvendor");
319 		if (sii->pub.boardvendor == 0)
320 			sii->pub.boardvendor = w & 0xffff;
321 		else
322 			SI_ERROR(("Overriding boardvendor: 0x%x instead of 0x%x\n", sii->pub.boardvendor, w & 0xffff));
323 		sii->pub.boardtype = (u16)si_getdevpathintvar(&sii->pub,
324 			"boardtype");
325 		if (sii->pub.boardtype == 0)
326 			sii->pub.boardtype = (w >> 16) & 0xffff;
327 		else
328 			SI_ERROR(("Overriding boardtype: 0x%x instead of 0x%x\n", sii->pub.boardtype, (w >> 16) & 0xffff));
329 		break;
330 
331 #ifdef BCMSDIO
332 	case SDIO_BUS:
333 #endif
334 		sii->pub.boardvendor = getintvar(pvars, "manfid");
335 		sii->pub.boardtype = getintvar(pvars, "prodid");
336 		break;
337 
338 #ifdef BCMSDIO
339 	case SPI_BUS:
340 		sii->pub.boardvendor = VENDOR_BROADCOM;
341 		sii->pub.boardtype = SPI_BOARD;
342 		break;
343 #endif
344 
345 	case SI_BUS:
346 	case JTAG_BUS:
347 		sii->pub.boardvendor = VENDOR_BROADCOM;
348 		sii->pub.boardtype = getintvar(pvars, "prodid");
349 		if (pvars == NULL || (sii->pub.boardtype == 0)) {
350 			sii->pub.boardtype = getintvar(NULL, "boardtype");
351 			if (sii->pub.boardtype == 0)
352 				sii->pub.boardtype = 0xffff;
353 		}
354 		break;
355 	}
356 
357 	if (sii->pub.boardtype == 0) {
358 		SI_ERROR(("si_doattach: unknown board type\n"));
359 		ASSERT(sii->pub.boardtype);
360 	}
361 
362 	sii->pub.boardflags = getintvar(pvars, "boardflags");
363 }
364 
365 /* this is will make Sonics calls directly, since Sonics is no longer supported in the Si abstraction */
366 /* this has been customized for the bcm 4329 ONLY */
367 #ifdef BCMSDIO
si_doattach(si_info_t * sii,uint devid,void * regs,uint bustype,void * pbus,char ** vars,uint * varsz)368 static si_info_t *si_doattach(si_info_t *sii, uint devid,
369 			      void *regs, uint bustype, void *pbus,
370 			      char **vars, uint *varsz)
371 {
372 	struct si_pub *sih = &sii->pub;
373 	u32 w, savewin;
374 	chipcregs_t *cc;
375 	char *pvars = NULL;
376 	uint origidx;
377 
378 	ASSERT(GOODREGS(regs));
379 
380 	memset((unsigned char *) sii, 0, sizeof(si_info_t));
381 
382 	savewin = 0;
383 
384 	sih->buscoreidx = BADIDX;
385 
386 	sii->curmap = regs;
387 	sii->pbus = pbus;
388 
389 	/* find Chipcommon address */
390 	cc = (chipcregs_t *) sii->curmap;
391 	sih->bustype = bustype;
392 
393 	/* bus/core/clk setup for register access */
394 	if (!si_buscore_prep(sii, bustype, devid, pbus)) {
395 		SI_ERROR(("si_doattach: si_core_clk_prep failed %d\n",
396 			  bustype));
397 		return NULL;
398 	}
399 
400 	/* ChipID recognition.
401 	 *   We assume we can read chipid at offset 0 from the regs arg.
402 	 *   If we add other chiptypes (or if we need to support old sdio hosts w/o chipcommon),
403 	 *   some way of recognizing them needs to be added here.
404 	 */
405 	w = R_REG(&cc->chipid);
406 	sih->socitype = (w & CID_TYPE_MASK) >> CID_TYPE_SHIFT;
407 	/* Might as wll fill in chip id rev & pkg */
408 	sih->chip = w & CID_ID_MASK;
409 	sih->chiprev = (w & CID_REV_MASK) >> CID_REV_SHIFT;
410 	sih->chippkg = (w & CID_PKG_MASK) >> CID_PKG_SHIFT;
411 
412 	if ((sih->chip == BCM4329_CHIP_ID) &&
413 		(sih->chippkg != BCM4329_289PIN_PKG_ID))
414 			sih->chippkg = BCM4329_182PIN_PKG_ID;
415 
416 	sih->issim = IS_SIM(sih->chippkg);
417 
418 	/* scan for cores */
419 	/* SI_MSG(("Found chip type SB (0x%08x)\n", w)); */
420 	sb_scan(&sii->pub, regs, devid);
421 
422 	/* no cores found, bail out */
423 	if (sii->numcores == 0) {
424 		SI_ERROR(("si_doattach: could not find any cores\n"));
425 		return NULL;
426 	}
427 	/* bus/core/clk setup */
428 	origidx = SI_CC_IDX;
429 	if (!si_buscore_setup(sii, cc, bustype, savewin, &origidx, regs)) {
430 		SI_ERROR(("si_doattach: si_buscore_setup failed\n"));
431 		goto exit;
432 	}
433 
434 #ifdef BRCM_FULLMAC
435 	pvars = NULL;
436 #else
437 	/* Init nvram from flash if it exists */
438 	nvram_init((void *)&(sii->pub));
439 
440 	/* Init nvram from sprom/otp if they exist */
441 	if (srom_var_init
442 	    (&sii->pub, bustype, regs, sii->osh, vars, varsz)) {
443 		SI_ERROR(("si_doattach: srom_var_init failed: bad srom\n"));
444 		goto exit;
445 	}
446 	pvars = vars ? *vars : NULL;
447 	si_nvram_process(sii, pvars);
448 #endif
449 
450 	/* === NVRAM, clock is ready === */
451 
452 #ifdef BRCM_FULLMAC
453 	if (sii->pub.ccrev >= 20) {
454 #endif
455 	cc = (chipcregs_t *) si_setcore(sih, CC_CORE_ID, 0);
456 	W_REG(&cc->gpiopullup, 0);
457 	W_REG(&cc->gpiopulldown, 0);
458 	sb_setcoreidx(sih, origidx);
459 #ifdef BRCM_FULLMAC
460 	}
461 #endif
462 
463 #ifndef BRCM_FULLMAC
464 	/* PMU specific initializations */
465 	if (PMUCTL_ENAB(sih)) {
466 		u32 xtalfreq;
467 		si_pmu_init(sih);
468 		si_pmu_chip_init(sih);
469 		xtalfreq = getintvar(pvars, "xtalfreq");
470 		/* If xtalfreq var not available, try to measure it */
471 		if (xtalfreq == 0)
472 			xtalfreq = si_pmu_measure_alpclk(sih);
473 		si_pmu_pll_init(sih, xtalfreq);
474 		si_pmu_res_init(sih);
475 		si_pmu_swreg_init(sih);
476 	}
477 
478 	/* setup the GPIO based LED powersave register */
479 	w = getintvar(pvars, "leddc");
480 	if (w == 0)
481 		w = DEFAULT_GPIOTIMERVAL;
482 	sb_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, gpiotimerval), ~0, w);
483 
484 #ifdef BCMDBG
485 	/* clear any previous epidiag-induced target abort */
486 	sb_taclear(sih, false);
487 #endif				/* BCMDBG */
488 #endif
489 
490 	return sii;
491 
492  exit:
493 	return NULL;
494 }
495 
496 #else				/* BCMSDIO */
si_doattach(si_info_t * sii,uint devid,void * regs,uint bustype,void * pbus,char ** vars,uint * varsz)497 static si_info_t *si_doattach(si_info_t *sii, uint devid,
498 			      void *regs, uint bustype, void *pbus,
499 			      char **vars, uint *varsz)
500 {
501 	struct si_pub *sih = &sii->pub;
502 	u32 w, savewin;
503 	chipcregs_t *cc;
504 	char *pvars = NULL;
505 	uint origidx;
506 
507 	ASSERT(GOODREGS(regs));
508 
509 	memset((unsigned char *) sii, 0, sizeof(si_info_t));
510 
511 	savewin = 0;
512 
513 	sih->buscoreidx = BADIDX;
514 
515 	sii->curmap = regs;
516 	sii->pbus = pbus;
517 
518 	/* check to see if we are a si core mimic'ing a pci core */
519 	if (bustype == PCI_BUS) {
520 		pci_read_config_dword(sii->pbus, PCI_SPROM_CONTROL,  &w);
521 		if (w == 0xffffffff) {
522 			SI_ERROR(("%s: incoming bus is PCI but it's a lie, "
523 				" switching to SI devid:0x%x\n",
524 				__func__, devid));
525 			bustype = SI_BUS;
526 		}
527 	}
528 
529 	/* find Chipcommon address */
530 	if (bustype == PCI_BUS) {
531 		pci_read_config_dword(sii->pbus, PCI_BAR0_WIN, &savewin);
532 		if (!GOODCOREADDR(savewin, SI_ENUM_BASE))
533 			savewin = SI_ENUM_BASE;
534 		pci_write_config_dword(sii->pbus, PCI_BAR0_WIN,
535 				       SI_ENUM_BASE);
536 		cc = (chipcregs_t *) regs;
537 	} else {
538 		cc = (chipcregs_t *) REG_MAP(SI_ENUM_BASE, SI_CORE_SIZE);
539 	}
540 
541 	sih->bustype = bustype;
542 
543 	/* bus/core/clk setup for register access */
544 	if (!si_buscore_prep(sii, bustype, devid, pbus)) {
545 		SI_ERROR(("si_doattach: si_core_clk_prep failed %d\n",
546 			  bustype));
547 		return NULL;
548 	}
549 
550 	/* ChipID recognition.
551 	 *   We assume we can read chipid at offset 0 from the regs arg.
552 	 *   If we add other chiptypes (or if we need to support old sdio hosts w/o chipcommon),
553 	 *   some way of recognizing them needs to be added here.
554 	 */
555 	w = R_REG(&cc->chipid);
556 	sih->socitype = (w & CID_TYPE_MASK) >> CID_TYPE_SHIFT;
557 	/* Might as wll fill in chip id rev & pkg */
558 	sih->chip = w & CID_ID_MASK;
559 	sih->chiprev = (w & CID_REV_MASK) >> CID_REV_SHIFT;
560 	sih->chippkg = (w & CID_PKG_MASK) >> CID_PKG_SHIFT;
561 
562 	sih->issim = IS_SIM(sih->chippkg);
563 
564 	/* scan for cores */
565 	if (sii->pub.socitype == SOCI_AI) {
566 		SI_MSG(("Found chip type AI (0x%08x)\n", w));
567 		/* pass chipc address instead of original core base */
568 		ai_scan(&sii->pub, (void *)cc, devid);
569 	} else {
570 		SI_ERROR(("Found chip of unknown type (0x%08x)\n", w));
571 		return NULL;
572 	}
573 	/* no cores found, bail out */
574 	if (sii->numcores == 0) {
575 		SI_ERROR(("si_doattach: could not find any cores\n"));
576 		return NULL;
577 	}
578 	/* bus/core/clk setup */
579 	origidx = SI_CC_IDX;
580 	if (!si_buscore_setup(sii, cc, bustype, savewin, &origidx, regs)) {
581 		SI_ERROR(("si_doattach: si_buscore_setup failed\n"));
582 		goto exit;
583 	}
584 
585 	/* assume current core is CC */
586 	if ((sii->pub.ccrev == 0x25)
587 	    &&
588 	    ((sih->chip == BCM43236_CHIP_ID
589 	      || sih->chip == BCM43235_CHIP_ID
590 	      || sih->chip == BCM43238_CHIP_ID)
591 	     && (sii->pub.chiprev <= 2))) {
592 
593 		if ((cc->chipstatus & CST43236_BP_CLK) != 0) {
594 			uint clkdiv;
595 			clkdiv = R_REG(&cc->clkdiv);
596 			/* otp_clk_div is even number, 120/14 < 9mhz */
597 			clkdiv = (clkdiv & ~CLKD_OTP) | (14 << CLKD_OTP_SHIFT);
598 			W_REG(&cc->clkdiv, clkdiv);
599 			SI_ERROR(("%s: set clkdiv to %x\n", __func__, clkdiv));
600 		}
601 		udelay(10);
602 	}
603 
604 	/* Init nvram from flash if it exists */
605 	nvram_init((void *)&(sii->pub));
606 
607 	/* Init nvram from sprom/otp if they exist */
608 	if (srom_var_init
609 	    (&sii->pub, bustype, regs, vars, varsz)) {
610 		SI_ERROR(("si_doattach: srom_var_init failed: bad srom\n"));
611 		goto exit;
612 	}
613 	pvars = vars ? *vars : NULL;
614 	si_nvram_process(sii, pvars);
615 
616 	/* === NVRAM, clock is ready === */
617 	cc = (chipcregs_t *) si_setcore(sih, CC_CORE_ID, 0);
618 	W_REG(&cc->gpiopullup, 0);
619 	W_REG(&cc->gpiopulldown, 0);
620 	si_setcoreidx(sih, origidx);
621 
622 	/* PMU specific initializations */
623 	if (PMUCTL_ENAB(sih)) {
624 		u32 xtalfreq;
625 		si_pmu_init(sih);
626 		si_pmu_chip_init(sih);
627 		xtalfreq = getintvar(pvars, "xtalfreq");
628 		/* If xtalfreq var not available, try to measure it */
629 		if (xtalfreq == 0)
630 			xtalfreq = si_pmu_measure_alpclk(sih);
631 		si_pmu_pll_init(sih, xtalfreq);
632 		si_pmu_res_init(sih);
633 		si_pmu_swreg_init(sih);
634 	}
635 
636 	/* setup the GPIO based LED powersave register */
637 	w = getintvar(pvars, "leddc");
638 	if (w == 0)
639 		w = DEFAULT_GPIOTIMERVAL;
640 	si_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, gpiotimerval), ~0, w);
641 
642 	if (PCIE(sii)) {
643 		ASSERT(sii->pch != NULL);
644 		pcicore_attach(sii->pch, pvars, SI_DOATTACH);
645 	}
646 
647 	if ((sih->chip == BCM43224_CHIP_ID) ||
648 	    (sih->chip == BCM43421_CHIP_ID)) {
649 		/* enable 12 mA drive strenth for 43224 and set chipControl register bit 15 */
650 		if (sih->chiprev == 0) {
651 			SI_MSG(("Applying 43224A0 WARs\n"));
652 			si_corereg(sih, SI_CC_IDX,
653 				   offsetof(chipcregs_t, chipcontrol),
654 				   CCTRL43224_GPIO_TOGGLE,
655 				   CCTRL43224_GPIO_TOGGLE);
656 			si_pmu_chipcontrol(sih, 0, CCTRL_43224A0_12MA_LED_DRIVE,
657 					   CCTRL_43224A0_12MA_LED_DRIVE);
658 		}
659 		if (sih->chiprev >= 1) {
660 			SI_MSG(("Applying 43224B0+ WARs\n"));
661 			si_pmu_chipcontrol(sih, 0, CCTRL_43224B0_12MA_LED_DRIVE,
662 					   CCTRL_43224B0_12MA_LED_DRIVE);
663 		}
664 	}
665 
666 	if (sih->chip == BCM4313_CHIP_ID) {
667 		/* enable 12 mA drive strenth for 4313 and set chipControl register bit 1 */
668 		SI_MSG(("Applying 4313 WARs\n"));
669 		si_pmu_chipcontrol(sih, 0, CCTRL_4313_12MA_LED_DRIVE,
670 				   CCTRL_4313_12MA_LED_DRIVE);
671 	}
672 
673 	if (sih->chip == BCM4331_CHIP_ID) {
674 		/* Enable Ext PA lines depending on chip package option */
675 		si_chipcontrl_epa4331(sih, true);
676 	}
677 
678 	return sii;
679  exit:
680 	if (sih->bustype == PCI_BUS) {
681 		if (sii->pch)
682 			pcicore_deinit(sii->pch);
683 		sii->pch = NULL;
684 	}
685 
686 	return NULL;
687 }
688 #endif				/* BCMSDIO */
689 
690 /* may be called with core in reset */
si_detach(si_t * sih)691 void si_detach(si_t *sih)
692 {
693 	si_info_t *sii;
694 	uint idx;
695 
696 	struct si_pub *si_local = NULL;
697 	memcpy(&si_local, &sih, sizeof(si_t **));
698 
699 	sii = SI_INFO(sih);
700 
701 	if (sii == NULL)
702 		return;
703 
704 	if (sih->bustype == SI_BUS)
705 		for (idx = 0; idx < SI_MAXCORES; idx++)
706 			if (sii->regs[idx]) {
707 				iounmap(sii->regs[idx]);
708 				sii->regs[idx] = NULL;
709 			}
710 
711 #ifndef BRCM_FULLMAC
712 	nvram_exit((void *)si_local);	/* free up nvram buffers */
713 
714 	if (sih->bustype == PCI_BUS) {
715 		if (sii->pch)
716 			pcicore_deinit(sii->pch);
717 		sii->pch = NULL;
718 	}
719 #endif
720 #if !defined(BCMBUSTYPE) || (BCMBUSTYPE == SI_BUS)
721 	if (sii != &ksii)
722 #endif				/* !BCMBUSTYPE || (BCMBUSTYPE == SI_BUS) */
723 		kfree(sii);
724 }
725 
726 /* register driver interrupt disabling and restoring callback functions */
727 void
si_register_intr_callback(si_t * sih,void * intrsoff_fn,void * intrsrestore_fn,void * intrsenabled_fn,void * intr_arg)728 si_register_intr_callback(si_t *sih, void *intrsoff_fn, void *intrsrestore_fn,
729 			  void *intrsenabled_fn, void *intr_arg)
730 {
731 	si_info_t *sii;
732 
733 	sii = SI_INFO(sih);
734 	sii->intr_arg = intr_arg;
735 	sii->intrsoff_fn = (si_intrsoff_t) intrsoff_fn;
736 	sii->intrsrestore_fn = (si_intrsrestore_t) intrsrestore_fn;
737 	sii->intrsenabled_fn = (si_intrsenabled_t) intrsenabled_fn;
738 	/* save current core id.  when this function called, the current core
739 	 * must be the core which provides driver functions(il, et, wl, etc.)
740 	 */
741 	sii->dev_coreid = sii->coreid[sii->curidx];
742 }
743 
si_deregister_intr_callback(si_t * sih)744 void si_deregister_intr_callback(si_t *sih)
745 {
746 	si_info_t *sii;
747 
748 	sii = SI_INFO(sih);
749 	sii->intrsoff_fn = NULL;
750 }
751 
si_flag(si_t * sih)752 uint si_flag(si_t *sih)
753 {
754 	if (sih->socitype == SOCI_AI)
755 		return ai_flag(sih);
756 	else {
757 		ASSERT(0);
758 		return 0;
759 	}
760 }
761 
si_setint(si_t * sih,int siflag)762 void si_setint(si_t *sih, int siflag)
763 {
764 	if (sih->socitype == SOCI_AI)
765 		ai_setint(sih, siflag);
766 	else
767 		ASSERT(0);
768 }
769 
770 #ifndef BCMSDIO
si_coreid(si_t * sih)771 uint si_coreid(si_t *sih)
772 {
773 	si_info_t *sii;
774 
775 	sii = SI_INFO(sih);
776 	return sii->coreid[sii->curidx];
777 }
778 #endif
779 
si_coreidx(si_t * sih)780 uint si_coreidx(si_t *sih)
781 {
782 	si_info_t *sii;
783 
784 	sii = SI_INFO(sih);
785 	return sii->curidx;
786 }
787 
si_backplane64(si_t * sih)788 bool si_backplane64(si_t *sih)
789 {
790 	return (sih->cccaps & CC_CAP_BKPLN64) != 0;
791 }
792 
793 #ifndef BCMSDIO
si_corerev(si_t * sih)794 uint si_corerev(si_t *sih)
795 {
796 	if (sih->socitype == SOCI_AI)
797 		return ai_corerev(sih);
798 	else {
799 		ASSERT(0);
800 		return 0;
801 	}
802 }
803 #endif
804 
805 /* return index of coreid or BADIDX if not found */
si_findcoreidx(si_t * sih,uint coreid,uint coreunit)806 uint si_findcoreidx(si_t *sih, uint coreid, uint coreunit)
807 {
808 	si_info_t *sii;
809 	uint found;
810 	uint i;
811 
812 	sii = SI_INFO(sih);
813 
814 	found = 0;
815 
816 	for (i = 0; i < sii->numcores; i++)
817 		if (sii->coreid[i] == coreid) {
818 			if (found == coreunit)
819 				return i;
820 			found++;
821 		}
822 
823 	return BADIDX;
824 }
825 
826 /*
827  * This function changes logical "focus" to the indicated core;
828  * must be called with interrupts off.
829  * Moreover, callers should keep interrupts off during switching out of and back to d11 core
830  */
si_setcore(si_t * sih,uint coreid,uint coreunit)831 void *si_setcore(si_t *sih, uint coreid, uint coreunit)
832 {
833 	uint idx;
834 
835 	idx = si_findcoreidx(sih, coreid, coreunit);
836 	if (!GOODIDX(idx))
837 		return NULL;
838 
839 	if (sih->socitype == SOCI_AI)
840 		return ai_setcoreidx(sih, idx);
841 	else {
842 #ifdef BCMSDIO
843 		return sb_setcoreidx(sih, idx);
844 #else
845 		ASSERT(0);
846 		return NULL;
847 #endif
848 	}
849 }
850 
851 #ifndef BCMSDIO
si_setcoreidx(si_t * sih,uint coreidx)852 void *si_setcoreidx(si_t *sih, uint coreidx)
853 {
854 	if (sih->socitype == SOCI_AI)
855 		return ai_setcoreidx(sih, coreidx);
856 	else {
857 		ASSERT(0);
858 		return NULL;
859 	}
860 }
861 #endif
862 
863 /* Turn off interrupt as required by sb_setcore, before switch core */
si_switch_core(si_t * sih,uint coreid,uint * origidx,uint * intr_val)864 void *si_switch_core(si_t *sih, uint coreid, uint *origidx, uint *intr_val)
865 {
866 	void *cc;
867 	si_info_t *sii;
868 
869 	sii = SI_INFO(sih);
870 
871 	if (SI_FAST(sii)) {
872 		/* Overloading the origidx variable to remember the coreid,
873 		 * this works because the core ids cannot be confused with
874 		 * core indices.
875 		 */
876 		*origidx = coreid;
877 		if (coreid == CC_CORE_ID)
878 			return (void *)CCREGS_FAST(sii);
879 		else if (coreid == sih->buscoretype)
880 			return (void *)PCIEREGS(sii);
881 	}
882 	INTR_OFF(sii, *intr_val);
883 	*origidx = sii->curidx;
884 	cc = si_setcore(sih, coreid, 0);
885 	ASSERT(cc != NULL);
886 
887 	return cc;
888 }
889 
890 /* restore coreidx and restore interrupt */
si_restore_core(si_t * sih,uint coreid,uint intr_val)891 void si_restore_core(si_t *sih, uint coreid, uint intr_val)
892 {
893 	si_info_t *sii;
894 
895 	sii = SI_INFO(sih);
896 	if (SI_FAST(sii)
897 	    && ((coreid == CC_CORE_ID) || (coreid == sih->buscoretype)))
898 		return;
899 
900 	si_setcoreidx(sih, coreid);
901 	INTR_RESTORE(sii, intr_val);
902 }
903 
si_core_cflags(si_t * sih,u32 mask,u32 val)904 u32 si_core_cflags(si_t *sih, u32 mask, u32 val)
905 {
906 	if (sih->socitype == SOCI_AI)
907 		return ai_core_cflags(sih, mask, val);
908 	else {
909 		ASSERT(0);
910 		return 0;
911 	}
912 }
913 
si_core_sflags(si_t * sih,u32 mask,u32 val)914 u32 si_core_sflags(si_t *sih, u32 mask, u32 val)
915 {
916 	if (sih->socitype == SOCI_AI)
917 		return ai_core_sflags(sih, mask, val);
918 	else {
919 		ASSERT(0);
920 		return 0;
921 	}
922 }
923 
si_iscoreup(si_t * sih)924 bool si_iscoreup(si_t *sih)
925 {
926 	if (sih->socitype == SOCI_AI)
927 		return ai_iscoreup(sih);
928 	else {
929 #ifdef BCMSDIO
930 		return sb_iscoreup(sih);
931 #else
932 		ASSERT(0);
933 		return false;
934 #endif
935 	}
936 }
937 
si_write_wrapperreg(si_t * sih,u32 offset,u32 val)938 void si_write_wrapperreg(si_t *sih, u32 offset, u32 val)
939 {
940 	/* only for 4319, no requirement for SOCI_SB */
941 	if (sih->socitype == SOCI_AI) {
942 		ai_write_wrap_reg(sih, offset, val);
943 	}
944 }
945 
si_corereg(si_t * sih,uint coreidx,uint regoff,uint mask,uint val)946 uint si_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, uint val)
947 {
948 
949 	if (sih->socitype == SOCI_AI)
950 		return ai_corereg(sih, coreidx, regoff, mask, val);
951 	else {
952 #ifdef BCMSDIO
953 		return sb_corereg(sih, coreidx, regoff, mask, val);
954 #else
955 		ASSERT(0);
956 		return 0;
957 #endif
958 	}
959 }
960 
si_core_disable(si_t * sih,u32 bits)961 void si_core_disable(si_t *sih, u32 bits)
962 {
963 
964 	if (sih->socitype == SOCI_AI)
965 		ai_core_disable(sih, bits);
966 #ifdef BCMSDIO
967 	else
968 		sb_core_disable(sih, bits);
969 #endif
970 }
971 
si_core_reset(si_t * sih,u32 bits,u32 resetbits)972 void si_core_reset(si_t *sih, u32 bits, u32 resetbits)
973 {
974 	if (sih->socitype == SOCI_AI)
975 		ai_core_reset(sih, bits, resetbits);
976 #ifdef BCMSDIO
977 	else
978 		sb_core_reset(sih, bits, resetbits);
979 #endif
980 }
981 
si_alp_clock(si_t * sih)982 u32 si_alp_clock(si_t *sih)
983 {
984 	if (PMUCTL_ENAB(sih))
985 		return si_pmu_alp_clock(sih);
986 
987 	return ALP_CLOCK;
988 }
989 
si_ilp_clock(si_t * sih)990 u32 si_ilp_clock(si_t *sih)
991 {
992 	if (PMUCTL_ENAB(sih))
993 		return si_pmu_ilp_clock(sih);
994 
995 	return ILP_CLOCK;
996 }
997 
998 /* set chip watchdog reset timer to fire in 'ticks' */
999 #ifdef BRCM_FULLMAC
1000 void
si_watchdog(si_t * sih,uint ticks)1001 si_watchdog(si_t *sih, uint ticks)
1002 {
1003 	if (PMUCTL_ENAB(sih)) {
1004 
1005 		if ((sih->chip == BCM4319_CHIP_ID) && (sih->chiprev == 0) &&
1006 			(ticks != 0)) {
1007 			si_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t,
1008 			clk_ctl_st), ~0, 0x2);
1009 			si_setcore(sih, USB20D_CORE_ID, 0);
1010 			si_core_disable(sih, 1);
1011 			si_setcore(sih, CC_CORE_ID, 0);
1012 		}
1013 
1014 		if (ticks == 1)
1015 			ticks = 2;
1016 		si_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, pmuwatchdog),
1017 			~0, ticks);
1018 	} else {
1019 		/* instant NMI */
1020 		si_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, watchdog),
1021 			~0, ticks);
1022 	}
1023 }
1024 #else
si_watchdog(si_t * sih,uint ticks)1025 void si_watchdog(si_t *sih, uint ticks)
1026 {
1027 	uint nb, maxt;
1028 
1029 	if (PMUCTL_ENAB(sih)) {
1030 
1031 		if ((sih->chip == BCM4319_CHIP_ID) &&
1032 		    (sih->chiprev == 0) && (ticks != 0)) {
1033 			si_corereg(sih, SI_CC_IDX,
1034 				   offsetof(chipcregs_t, clk_ctl_st), ~0, 0x2);
1035 			si_setcore(sih, USB20D_CORE_ID, 0);
1036 			si_core_disable(sih, 1);
1037 			si_setcore(sih, CC_CORE_ID, 0);
1038 		}
1039 
1040 		nb = (sih->ccrev < 26) ? 16 : ((sih->ccrev >= 37) ? 32 : 24);
1041 		/* The mips compiler uses the sllv instruction,
1042 		 * so we specially handle the 32-bit case.
1043 		 */
1044 		if (nb == 32)
1045 			maxt = 0xffffffff;
1046 		else
1047 			maxt = ((1 << nb) - 1);
1048 
1049 		if (ticks == 1)
1050 			ticks = 2;
1051 		else if (ticks > maxt)
1052 			ticks = maxt;
1053 
1054 		si_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, pmuwatchdog),
1055 			   ~0, ticks);
1056 	} else {
1057 		/* make sure we come up in fast clock mode; or if clearing, clear clock */
1058 		si_clkctl_cc(sih, ticks ? CLK_FAST : CLK_DYNAMIC);
1059 		maxt = (1 << 28) - 1;
1060 		if (ticks > maxt)
1061 			ticks = maxt;
1062 
1063 		si_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, watchdog), ~0,
1064 			   ticks);
1065 	}
1066 }
1067 #endif
1068 
1069 /* return the slow clock source - LPO, XTAL, or PCI */
si_slowclk_src(si_info_t * sii)1070 static uint si_slowclk_src(si_info_t *sii)
1071 {
1072 	chipcregs_t *cc;
1073 	u32 val;
1074 
1075 	ASSERT(SI_FAST(sii) || si_coreid(&sii->pub) == CC_CORE_ID);
1076 
1077 	if (sii->pub.ccrev < 6) {
1078 		if (sii->pub.bustype == PCI_BUS) {
1079 			pci_read_config_dword(sii->pbus, PCI_GPIO_OUT,
1080 					      &val);
1081 			if (val & PCI_CFG_GPIO_SCS)
1082 				return SCC_SS_PCI;
1083 		}
1084 		return SCC_SS_XTAL;
1085 	} else if (sii->pub.ccrev < 10) {
1086 		cc = (chipcregs_t *) si_setcoreidx(&sii->pub, sii->curidx);
1087 		return R_REG(&cc->slow_clk_ctl) & SCC_SS_MASK;
1088 	} else			/* Insta-clock */
1089 		return SCC_SS_XTAL;
1090 }
1091 
1092 /* return the ILP (slowclock) min or max frequency */
si_slowclk_freq(si_info_t * sii,bool max_freq,chipcregs_t * cc)1093 static uint si_slowclk_freq(si_info_t *sii, bool max_freq, chipcregs_t *cc)
1094 {
1095 	u32 slowclk;
1096 	uint div;
1097 
1098 	ASSERT(SI_FAST(sii) || si_coreid(&sii->pub) == CC_CORE_ID);
1099 
1100 	/* shouldn't be here unless we've established the chip has dynamic clk control */
1101 	ASSERT(R_REG(&cc->capabilities) & CC_CAP_PWR_CTL);
1102 
1103 	slowclk = si_slowclk_src(sii);
1104 	if (sii->pub.ccrev < 6) {
1105 		if (slowclk == SCC_SS_PCI)
1106 			return max_freq ? (PCIMAXFREQ / 64)
1107 				: (PCIMINFREQ / 64);
1108 		else
1109 			return max_freq ? (XTALMAXFREQ / 32)
1110 				: (XTALMINFREQ / 32);
1111 	} else if (sii->pub.ccrev < 10) {
1112 		div = 4 *
1113 		    (((R_REG(&cc->slow_clk_ctl) & SCC_CD_MASK) >>
1114 		      SCC_CD_SHIFT) + 1);
1115 		if (slowclk == SCC_SS_LPO)
1116 			return max_freq ? LPOMAXFREQ : LPOMINFREQ;
1117 		else if (slowclk == SCC_SS_XTAL)
1118 			return max_freq ? (XTALMAXFREQ / div)
1119 				: (XTALMINFREQ / div);
1120 		else if (slowclk == SCC_SS_PCI)
1121 			return max_freq ? (PCIMAXFREQ / div)
1122 				: (PCIMINFREQ / div);
1123 		else
1124 			ASSERT(0);
1125 	} else {
1126 		/* Chipc rev 10 is InstaClock */
1127 		div = R_REG(&cc->system_clk_ctl) >> SYCC_CD_SHIFT;
1128 		div = 4 * (div + 1);
1129 		return max_freq ? XTALMAXFREQ : (XTALMINFREQ / div);
1130 	}
1131 	return 0;
1132 }
1133 
si_clkctl_setdelay(si_info_t * sii,void * chipcregs)1134 static void si_clkctl_setdelay(si_info_t *sii, void *chipcregs)
1135 {
1136 	chipcregs_t *cc = (chipcregs_t *) chipcregs;
1137 	uint slowmaxfreq, pll_delay, slowclk;
1138 	uint pll_on_delay, fref_sel_delay;
1139 
1140 	pll_delay = PLL_DELAY;
1141 
1142 	/* If the slow clock is not sourced by the xtal then add the xtal_on_delay
1143 	 * since the xtal will also be powered down by dynamic clk control logic.
1144 	 */
1145 
1146 	slowclk = si_slowclk_src(sii);
1147 	if (slowclk != SCC_SS_XTAL)
1148 		pll_delay += XTAL_ON_DELAY;
1149 
1150 	/* Starting with 4318 it is ILP that is used for the delays */
1151 	slowmaxfreq =
1152 	    si_slowclk_freq(sii, (sii->pub.ccrev >= 10) ? false : true, cc);
1153 
1154 	pll_on_delay = ((slowmaxfreq * pll_delay) + 999999) / 1000000;
1155 	fref_sel_delay = ((slowmaxfreq * FREF_DELAY) + 999999) / 1000000;
1156 
1157 	W_REG(&cc->pll_on_delay, pll_on_delay);
1158 	W_REG(&cc->fref_sel_delay, fref_sel_delay);
1159 }
1160 
1161 /* initialize power control delay registers */
si_clkctl_init(si_t * sih)1162 void si_clkctl_init(si_t *sih)
1163 {
1164 	si_info_t *sii;
1165 	uint origidx = 0;
1166 	chipcregs_t *cc;
1167 	bool fast;
1168 
1169 	if (!CCCTL_ENAB(sih))
1170 		return;
1171 
1172 	sii = SI_INFO(sih);
1173 	fast = SI_FAST(sii);
1174 	if (!fast) {
1175 		origidx = sii->curidx;
1176 		cc = (chipcregs_t *) si_setcore(sih, CC_CORE_ID, 0);
1177 		if (cc == NULL)
1178 			return;
1179 	} else {
1180 		cc = (chipcregs_t *) CCREGS_FAST(sii);
1181 		if (cc == NULL)
1182 			return;
1183 	}
1184 	ASSERT(cc != NULL);
1185 
1186 	/* set all Instaclk chip ILP to 1 MHz */
1187 	if (sih->ccrev >= 10)
1188 		SET_REG(&cc->system_clk_ctl, SYCC_CD_MASK,
1189 			(ILP_DIV_1MHZ << SYCC_CD_SHIFT));
1190 
1191 	si_clkctl_setdelay(sii, (void *)cc);
1192 
1193 	if (!fast)
1194 		si_setcoreidx(sih, origidx);
1195 }
1196 
1197 /* return the value suitable for writing to the dot11 core FAST_PWRUP_DELAY register */
si_clkctl_fast_pwrup_delay(si_t * sih)1198 u16 si_clkctl_fast_pwrup_delay(si_t *sih)
1199 {
1200 	si_info_t *sii;
1201 	uint origidx = 0;
1202 	chipcregs_t *cc;
1203 	uint slowminfreq;
1204 	u16 fpdelay;
1205 	uint intr_val = 0;
1206 	bool fast;
1207 
1208 	sii = SI_INFO(sih);
1209 	if (PMUCTL_ENAB(sih)) {
1210 		INTR_OFF(sii, intr_val);
1211 		fpdelay = si_pmu_fast_pwrup_delay(sih);
1212 		INTR_RESTORE(sii, intr_val);
1213 		return fpdelay;
1214 	}
1215 
1216 	if (!CCCTL_ENAB(sih))
1217 		return 0;
1218 
1219 	fast = SI_FAST(sii);
1220 	fpdelay = 0;
1221 	if (!fast) {
1222 		origidx = sii->curidx;
1223 		INTR_OFF(sii, intr_val);
1224 		cc = (chipcregs_t *) si_setcore(sih, CC_CORE_ID, 0);
1225 		if (cc == NULL)
1226 			goto done;
1227 	} else {
1228 		cc = (chipcregs_t *) CCREGS_FAST(sii);
1229 		if (cc == NULL)
1230 			goto done;
1231 	}
1232 	ASSERT(cc != NULL);
1233 
1234 	slowminfreq = si_slowclk_freq(sii, false, cc);
1235 	fpdelay = (((R_REG(&cc->pll_on_delay) + 2) * 1000000) +
1236 		   (slowminfreq - 1)) / slowminfreq;
1237 
1238  done:
1239 	if (!fast) {
1240 		si_setcoreidx(sih, origidx);
1241 		INTR_RESTORE(sii, intr_val);
1242 	}
1243 	return fpdelay;
1244 }
1245 
1246 /* turn primary xtal and/or pll off/on */
si_clkctl_xtal(si_t * sih,uint what,bool on)1247 int si_clkctl_xtal(si_t *sih, uint what, bool on)
1248 {
1249 	si_info_t *sii;
1250 	u32 in, out, outen;
1251 
1252 	sii = SI_INFO(sih);
1253 
1254 	switch (sih->bustype) {
1255 
1256 #ifdef BCMSDIO
1257 	case SDIO_BUS:
1258 		return -1;
1259 #endif				/* BCMSDIO */
1260 
1261 	case PCI_BUS:
1262 		/* pcie core doesn't have any mapping to control the xtal pu */
1263 		if (PCIE(sii))
1264 			return -1;
1265 
1266 		pci_read_config_dword(sii->pbus, PCI_GPIO_IN, &in);
1267 		pci_read_config_dword(sii->pbus, PCI_GPIO_OUT, &out);
1268 		pci_read_config_dword(sii->pbus, PCI_GPIO_OUTEN, &outen);
1269 
1270 		/*
1271 		 * Avoid glitching the clock if GPRS is already using it.
1272 		 * We can't actually read the state of the PLLPD so we infer it
1273 		 * by the value of XTAL_PU which *is* readable via gpioin.
1274 		 */
1275 		if (on && (in & PCI_CFG_GPIO_XTAL))
1276 			return 0;
1277 
1278 		if (what & XTAL)
1279 			outen |= PCI_CFG_GPIO_XTAL;
1280 		if (what & PLL)
1281 			outen |= PCI_CFG_GPIO_PLL;
1282 
1283 		if (on) {
1284 			/* turn primary xtal on */
1285 			if (what & XTAL) {
1286 				out |= PCI_CFG_GPIO_XTAL;
1287 				if (what & PLL)
1288 					out |= PCI_CFG_GPIO_PLL;
1289 				pci_write_config_dword(sii->pbus,
1290 						       PCI_GPIO_OUT, out);
1291 				pci_write_config_dword(sii->pbus,
1292 						       PCI_GPIO_OUTEN, outen);
1293 				udelay(XTAL_ON_DELAY);
1294 			}
1295 
1296 			/* turn pll on */
1297 			if (what & PLL) {
1298 				out &= ~PCI_CFG_GPIO_PLL;
1299 				pci_write_config_dword(sii->pbus,
1300 						       PCI_GPIO_OUT, out);
1301 				mdelay(2);
1302 			}
1303 		} else {
1304 			if (what & XTAL)
1305 				out &= ~PCI_CFG_GPIO_XTAL;
1306 			if (what & PLL)
1307 				out |= PCI_CFG_GPIO_PLL;
1308 			pci_write_config_dword(sii->pbus,
1309 					       PCI_GPIO_OUT, out);
1310 			pci_write_config_dword(sii->pbus,
1311 					       PCI_GPIO_OUTEN, outen);
1312 		}
1313 
1314 	default:
1315 		return -1;
1316 	}
1317 
1318 	return 0;
1319 }
1320 
1321 /*
1322  *  clock control policy function through chipcommon
1323  *
1324  *    set dynamic clk control mode (forceslow, forcefast, dynamic)
1325  *    returns true if we are forcing fast clock
1326  *    this is a wrapper over the next internal function
1327  *      to allow flexible policy settings for outside caller
1328  */
si_clkctl_cc(si_t * sih,uint mode)1329 bool si_clkctl_cc(si_t *sih, uint mode)
1330 {
1331 	si_info_t *sii;
1332 
1333 	sii = SI_INFO(sih);
1334 
1335 	/* chipcommon cores prior to rev6 don't support dynamic clock control */
1336 	if (sih->ccrev < 6)
1337 		return false;
1338 
1339 	if (PCI_FORCEHT(sii))
1340 		return mode == CLK_FAST;
1341 
1342 	return _si_clkctl_cc(sii, mode);
1343 }
1344 
1345 /* clk control mechanism through chipcommon, no policy checking */
_si_clkctl_cc(si_info_t * sii,uint mode)1346 static bool _si_clkctl_cc(si_info_t *sii, uint mode)
1347 {
1348 	uint origidx = 0;
1349 	chipcregs_t *cc;
1350 	u32 scc;
1351 	uint intr_val = 0;
1352 	bool fast = SI_FAST(sii);
1353 
1354 	/* chipcommon cores prior to rev6 don't support dynamic clock control */
1355 	if (sii->pub.ccrev < 6)
1356 		return false;
1357 
1358 	/* Chips with ccrev 10 are EOL and they don't have SYCC_HR which we use below */
1359 	ASSERT(sii->pub.ccrev != 10);
1360 
1361 	if (!fast) {
1362 		INTR_OFF(sii, intr_val);
1363 		origidx = sii->curidx;
1364 
1365 		if ((sii->pub.bustype == SI_BUS) &&
1366 		    si_setcore(&sii->pub, MIPS33_CORE_ID, 0) &&
1367 		    (si_corerev(&sii->pub) <= 7) && (sii->pub.ccrev >= 10))
1368 			goto done;
1369 
1370 		cc = (chipcregs_t *) si_setcore(&sii->pub, CC_CORE_ID, 0);
1371 	} else {
1372 		cc = (chipcregs_t *) CCREGS_FAST(sii);
1373 		if (cc == NULL)
1374 			goto done;
1375 	}
1376 	ASSERT(cc != NULL);
1377 
1378 	if (!CCCTL_ENAB(&sii->pub) && (sii->pub.ccrev < 20))
1379 		goto done;
1380 
1381 	switch (mode) {
1382 	case CLK_FAST:		/* FORCEHT, fast (pll) clock */
1383 		if (sii->pub.ccrev < 10) {
1384 			/* don't forget to force xtal back on before we clear SCC_DYN_XTAL.. */
1385 			si_clkctl_xtal(&sii->pub, XTAL, ON);
1386 			SET_REG(&cc->slow_clk_ctl,
1387 				(SCC_XC | SCC_FS | SCC_IP), SCC_IP);
1388 		} else if (sii->pub.ccrev < 20) {
1389 			OR_REG(&cc->system_clk_ctl, SYCC_HR);
1390 		} else {
1391 			OR_REG(&cc->clk_ctl_st, CCS_FORCEHT);
1392 		}
1393 
1394 		/* wait for the PLL */
1395 		if (PMUCTL_ENAB(&sii->pub)) {
1396 			u32 htavail = CCS_HTAVAIL;
1397 			SPINWAIT(((R_REG(&cc->clk_ctl_st) & htavail)
1398 				  == 0), PMU_MAX_TRANSITION_DLY);
1399 			ASSERT(R_REG(&cc->clk_ctl_st) & htavail);
1400 		} else {
1401 			udelay(PLL_DELAY);
1402 		}
1403 		break;
1404 
1405 	case CLK_DYNAMIC:	/* enable dynamic clock control */
1406 		if (sii->pub.ccrev < 10) {
1407 			scc = R_REG(&cc->slow_clk_ctl);
1408 			scc &= ~(SCC_FS | SCC_IP | SCC_XC);
1409 			if ((scc & SCC_SS_MASK) != SCC_SS_XTAL)
1410 				scc |= SCC_XC;
1411 			W_REG(&cc->slow_clk_ctl, scc);
1412 
1413 			/* for dynamic control, we have to release our xtal_pu "force on" */
1414 			if (scc & SCC_XC)
1415 				si_clkctl_xtal(&sii->pub, XTAL, OFF);
1416 		} else if (sii->pub.ccrev < 20) {
1417 			/* Instaclock */
1418 			AND_REG(&cc->system_clk_ctl, ~SYCC_HR);
1419 		} else {
1420 			AND_REG(&cc->clk_ctl_st, ~CCS_FORCEHT);
1421 		}
1422 		break;
1423 
1424 	default:
1425 		ASSERT(0);
1426 	}
1427 
1428  done:
1429 	if (!fast) {
1430 		si_setcoreidx(&sii->pub, origidx);
1431 		INTR_RESTORE(sii, intr_val);
1432 	}
1433 	return mode == CLK_FAST;
1434 }
1435 
1436 /* Build device path. Support SI, PCI, and JTAG for now. */
si_devpath(si_t * sih,char * path,int size)1437 int si_devpath(si_t *sih, char *path, int size)
1438 {
1439 	int slen;
1440 
1441 	ASSERT(path != NULL);
1442 	ASSERT(size >= SI_DEVPATH_BUFSZ);
1443 
1444 	if (!path || size <= 0)
1445 		return -1;
1446 
1447 	switch (sih->bustype) {
1448 	case SI_BUS:
1449 	case JTAG_BUS:
1450 		slen = snprintf(path, (size_t) size, "sb/%u/", si_coreidx(sih));
1451 		break;
1452 	case PCI_BUS:
1453 		ASSERT((SI_INFO(sih))->pbus != NULL);
1454 		slen = snprintf(path, (size_t) size, "pci/%u/%u/",
1455 			((struct pci_dev *)((SI_INFO(sih))->pbus))->bus->number,
1456 			PCI_SLOT(
1457 			    ((struct pci_dev *)((SI_INFO(sih))->pbus))->devfn));
1458 		break;
1459 
1460 #ifdef BCMSDIO
1461 	case SDIO_BUS:
1462 		SI_ERROR(("si_devpath: device 0 assumed\n"));
1463 		slen = snprintf(path, (size_t) size, "sd/%u/", si_coreidx(sih));
1464 		break;
1465 #endif
1466 	default:
1467 		slen = -1;
1468 		ASSERT(0);
1469 		break;
1470 	}
1471 
1472 	if (slen < 0 || slen >= size) {
1473 		path[0] = '\0';
1474 		return -1;
1475 	}
1476 
1477 	return 0;
1478 }
1479 
1480 /* Get a variable, but only if it has a devpath prefix */
si_getdevpathvar(si_t * sih,const char * name)1481 char *si_getdevpathvar(si_t *sih, const char *name)
1482 {
1483 	char varname[SI_DEVPATH_BUFSZ + 32];
1484 
1485 	si_devpathvar(sih, varname, sizeof(varname), name);
1486 
1487 	return getvar(NULL, varname);
1488 }
1489 
1490 /* Get a variable, but only if it has a devpath prefix */
si_getdevpathintvar(si_t * sih,const char * name)1491 int si_getdevpathintvar(si_t *sih, const char *name)
1492 {
1493 #if defined(BCMBUSTYPE) && (BCMBUSTYPE == SI_BUS)
1494 	return getintvar(NULL, name);
1495 #else
1496 	char varname[SI_DEVPATH_BUFSZ + 32];
1497 
1498 	si_devpathvar(sih, varname, sizeof(varname), name);
1499 
1500 	return getintvar(NULL, varname);
1501 #endif
1502 }
1503 
si_getnvramflvar(si_t * sih,const char * name)1504 char *si_getnvramflvar(si_t *sih, const char *name)
1505 {
1506 	return getvar(NULL, name);
1507 }
1508 
1509 /* Concatenate the dev path with a varname into the given 'var' buffer
1510  * and return the 'var' pointer.
1511  * Nothing is done to the arguments if len == 0 or var is NULL, var is still returned.
1512  * On overflow, the first char will be set to '\0'.
1513  */
si_devpathvar(si_t * sih,char * var,int len,const char * name)1514 static char *si_devpathvar(si_t *sih, char *var, int len, const char *name)
1515 {
1516 	uint path_len;
1517 
1518 	if (!var || len <= 0)
1519 		return var;
1520 
1521 	if (si_devpath(sih, var, len) == 0) {
1522 		path_len = strlen(var);
1523 
1524 		if (strlen(name) + 1 > (uint) (len - path_len))
1525 			var[0] = '\0';
1526 		else
1527 			strncpy(var + path_len, name, len - path_len - 1);
1528 	}
1529 
1530 	return var;
1531 }
1532 
1533 /* return true if PCIE capability exists in the pci config space */
si_ispcie(si_info_t * sii)1534 static __used bool si_ispcie(si_info_t *sii)
1535 {
1536 	u8 cap_ptr;
1537 
1538 	if (sii->pub.bustype != PCI_BUS)
1539 		return false;
1540 
1541 	cap_ptr =
1542 	    pcicore_find_pci_capability(sii->pbus, PCI_CAP_PCIECAP_ID, NULL,
1543 					NULL);
1544 	if (!cap_ptr)
1545 		return false;
1546 
1547 	return true;
1548 }
1549 
1550 #ifdef BCMSDIO
1551 /* initialize the sdio core */
si_sdio_init(si_t * sih)1552 void si_sdio_init(si_t *sih)
1553 {
1554 	si_info_t *sii = SI_INFO(sih);
1555 
1556 	if (((sih->buscoretype == PCMCIA_CORE_ID) && (sih->buscorerev >= 8)) ||
1557 	    (sih->buscoretype == SDIOD_CORE_ID)) {
1558 		uint idx;
1559 		sdpcmd_regs_t *sdpregs;
1560 
1561 		/* get the current core index */
1562 		idx = sii->curidx;
1563 		ASSERT(idx == si_findcoreidx(sih, D11_CORE_ID, 0));
1564 
1565 		/* switch to sdio core */
1566 		sdpregs = (sdpcmd_regs_t *) si_setcore(sih, PCMCIA_CORE_ID, 0);
1567 		if (!sdpregs)
1568 			sdpregs =
1569 			    (sdpcmd_regs_t *) si_setcore(sih, SDIOD_CORE_ID, 0);
1570 		ASSERT(sdpregs);
1571 
1572 		SI_MSG(("si_sdio_init: For PCMCIA/SDIO Corerev %d, enable ints from core %d " "through SD core %d (%p)\n", sih->buscorerev, idx, sii->curidx, sdpregs));
1573 
1574 		/* enable backplane error and core interrupts */
1575 		W_REG(&sdpregs->hostintmask, I_SBINT);
1576 		W_REG(&sdpregs->sbintmask,
1577 		      (I_SB_SERR | I_SB_RESPERR | (1 << idx)));
1578 
1579 		/* switch back to previous core */
1580 		si_setcoreidx(sih, idx);
1581 	}
1582 
1583 	/* enable interrupts */
1584 	bcmsdh_intr_enable(sii->pbus);
1585 
1586 }
1587 #endif				/* BCMSDIO */
1588 
si_pci_war16165(si_t * sih)1589 bool si_pci_war16165(si_t *sih)
1590 {
1591 	si_info_t *sii;
1592 
1593 	sii = SI_INFO(sih);
1594 
1595 	return PCI(sii) && (sih->buscorerev <= 10);
1596 }
1597 
si_pci_up(si_t * sih)1598 void si_pci_up(si_t *sih)
1599 {
1600 	si_info_t *sii;
1601 
1602 	sii = SI_INFO(sih);
1603 
1604 	/* if not pci bus, we're done */
1605 	if (sih->bustype != PCI_BUS)
1606 		return;
1607 
1608 	if (PCI_FORCEHT(sii))
1609 		_si_clkctl_cc(sii, CLK_FAST);
1610 
1611 	if (PCIE(sii))
1612 		pcicore_up(sii->pch, SI_PCIUP);
1613 
1614 }
1615 
1616 /* Unconfigure and/or apply various WARs when system is going to sleep mode */
si_pci_sleep(si_t * sih)1617 void si_pci_sleep(si_t *sih)
1618 {
1619 	si_info_t *sii;
1620 
1621 	sii = SI_INFO(sih);
1622 
1623 	pcicore_sleep(sii->pch);
1624 }
1625 
1626 /* Unconfigure and/or apply various WARs when going down */
si_pci_down(si_t * sih)1627 void si_pci_down(si_t *sih)
1628 {
1629 	si_info_t *sii;
1630 
1631 	sii = SI_INFO(sih);
1632 
1633 	/* if not pci bus, we're done */
1634 	if (sih->bustype != PCI_BUS)
1635 		return;
1636 
1637 	/* release FORCEHT since chip is going to "down" state */
1638 	if (PCI_FORCEHT(sii))
1639 		_si_clkctl_cc(sii, CLK_DYNAMIC);
1640 
1641 	pcicore_down(sii->pch, SI_PCIDOWN);
1642 }
1643 
1644 /*
1645  * Configure the pci core for pci client (NIC) action
1646  * coremask is the bitvec of cores by index to be enabled.
1647  */
si_pci_setup(si_t * sih,uint coremask)1648 void si_pci_setup(si_t *sih, uint coremask)
1649 {
1650 	si_info_t *sii;
1651 	struct sbpciregs *pciregs = NULL;
1652 	u32 siflag = 0, w;
1653 	uint idx = 0;
1654 
1655 	sii = SI_INFO(sih);
1656 
1657 	if (sii->pub.bustype != PCI_BUS)
1658 		return;
1659 
1660 	ASSERT(PCI(sii) || PCIE(sii));
1661 	ASSERT(sii->pub.buscoreidx != BADIDX);
1662 
1663 	if (PCI(sii)) {
1664 		/* get current core index */
1665 		idx = sii->curidx;
1666 
1667 		/* we interrupt on this backplane flag number */
1668 		siflag = si_flag(sih);
1669 
1670 		/* switch over to pci core */
1671 		pciregs = (struct sbpciregs *)si_setcoreidx(sih, sii->pub.buscoreidx);
1672 	}
1673 
1674 	/*
1675 	 * Enable sb->pci interrupts.  Assume
1676 	 * PCI rev 2.3 support was added in pci core rev 6 and things changed..
1677 	 */
1678 	if (PCIE(sii) || (PCI(sii) && ((sii->pub.buscorerev) >= 6))) {
1679 		/* pci config write to set this core bit in PCIIntMask */
1680 		pci_read_config_dword(sii->pbus, PCI_INT_MASK, &w);
1681 		w |= (coremask << PCI_SBIM_SHIFT);
1682 		pci_write_config_dword(sii->pbus, PCI_INT_MASK, w);
1683 	} else {
1684 		/* set sbintvec bit for our flag number */
1685 		si_setint(sih, siflag);
1686 	}
1687 
1688 	if (PCI(sii)) {
1689 		OR_REG(&pciregs->sbtopci2,
1690 		       (SBTOPCI_PREF | SBTOPCI_BURST));
1691 		if (sii->pub.buscorerev >= 11) {
1692 			OR_REG(&pciregs->sbtopci2,
1693 			       SBTOPCI_RC_READMULTI);
1694 			w = R_REG(&pciregs->clkrun);
1695 			W_REG(&pciregs->clkrun,
1696 			      (w | PCI_CLKRUN_DSBL));
1697 			w = R_REG(&pciregs->clkrun);
1698 		}
1699 
1700 		/* switch back to previous core */
1701 		si_setcoreidx(sih, idx);
1702 	}
1703 }
1704 
1705 /*
1706  * Fixup SROMless PCI device's configuration.
1707  * The current core may be changed upon return.
1708  */
si_pci_fixcfg(si_t * sih)1709 int si_pci_fixcfg(si_t *sih)
1710 {
1711 	uint origidx, pciidx;
1712 	struct sbpciregs *pciregs = NULL;
1713 	sbpcieregs_t *pcieregs = NULL;
1714 	void *regs = NULL;
1715 	u16 val16, *reg16 = NULL;
1716 
1717 	si_info_t *sii = SI_INFO(sih);
1718 
1719 	ASSERT(sii->pub.bustype == PCI_BUS);
1720 
1721 	/* Fixup PI in SROM shadow area to enable the correct PCI core access */
1722 	/* save the current index */
1723 	origidx = si_coreidx(&sii->pub);
1724 
1725 	/* check 'pi' is correct and fix it if not */
1726 	if (sii->pub.buscoretype == PCIE_CORE_ID) {
1727 		pcieregs =
1728 		    (sbpcieregs_t *) si_setcore(&sii->pub, PCIE_CORE_ID, 0);
1729 		regs = pcieregs;
1730 		ASSERT(pcieregs != NULL);
1731 		reg16 = &pcieregs->sprom[SRSH_PI_OFFSET];
1732 	} else if (sii->pub.buscoretype == PCI_CORE_ID) {
1733 		pciregs = (struct sbpciregs *)si_setcore(&sii->pub, PCI_CORE_ID, 0);
1734 		regs = pciregs;
1735 		ASSERT(pciregs != NULL);
1736 		reg16 = &pciregs->sprom[SRSH_PI_OFFSET];
1737 	}
1738 	pciidx = si_coreidx(&sii->pub);
1739 	val16 = R_REG(reg16);
1740 	if (((val16 & SRSH_PI_MASK) >> SRSH_PI_SHIFT) != (u16) pciidx) {
1741 		val16 =
1742 		    (u16) (pciidx << SRSH_PI_SHIFT) | (val16 &
1743 							  ~SRSH_PI_MASK);
1744 		W_REG(reg16, val16);
1745 	}
1746 
1747 	/* restore the original index */
1748 	si_setcoreidx(&sii->pub, origidx);
1749 
1750 	pcicore_hwup(sii->pch);
1751 	return 0;
1752 }
1753 
1754 /* mask&set gpiocontrol bits */
si_gpiocontrol(si_t * sih,u32 mask,u32 val,u8 priority)1755 u32 si_gpiocontrol(si_t *sih, u32 mask, u32 val, u8 priority)
1756 {
1757 	uint regoff;
1758 
1759 	regoff = 0;
1760 
1761 	/* gpios could be shared on router platforms
1762 	 * ignore reservation if it's high priority (e.g., test apps)
1763 	 */
1764 	if ((priority != GPIO_HI_PRIORITY) &&
1765 	    (sih->bustype == SI_BUS) && (val || mask)) {
1766 		mask = priority ? (si_gpioreservation & mask) :
1767 		    ((si_gpioreservation | mask) & ~(si_gpioreservation));
1768 		val &= mask;
1769 	}
1770 
1771 	regoff = offsetof(chipcregs_t, gpiocontrol);
1772 	return si_corereg(sih, SI_CC_IDX, regoff, mask, val);
1773 }
1774 
1775 /* Return the size of the specified SOCRAM bank */
1776 static uint
socram_banksize(si_info_t * sii,sbsocramregs_t * regs,u8 index,u8 mem_type)1777 socram_banksize(si_info_t *sii, sbsocramregs_t *regs, u8 index,
1778 		u8 mem_type)
1779 {
1780 	uint banksize, bankinfo;
1781 	uint bankidx = index | (mem_type << SOCRAM_BANKIDX_MEMTYPE_SHIFT);
1782 
1783 	ASSERT(mem_type <= SOCRAM_MEMTYPE_DEVRAM);
1784 
1785 	W_REG(&regs->bankidx, bankidx);
1786 	bankinfo = R_REG(&regs->bankinfo);
1787 	banksize =
1788 	    SOCRAM_BANKINFO_SZBASE * ((bankinfo & SOCRAM_BANKINFO_SZMASK) + 1);
1789 	return banksize;
1790 }
1791 
1792 /* Return the RAM size of the SOCRAM core */
si_socram_size(si_t * sih)1793 u32 si_socram_size(si_t *sih)
1794 {
1795 	si_info_t *sii;
1796 	uint origidx;
1797 	uint intr_val = 0;
1798 
1799 	sbsocramregs_t *regs;
1800 	bool wasup;
1801 	uint corerev;
1802 	u32 coreinfo;
1803 	uint memsize = 0;
1804 
1805 	sii = SI_INFO(sih);
1806 
1807 	/* Block ints and save current core */
1808 	INTR_OFF(sii, intr_val);
1809 	origidx = si_coreidx(sih);
1810 
1811 	/* Switch to SOCRAM core */
1812 	regs = si_setcore(sih, SOCRAM_CORE_ID, 0);
1813 	if (!regs)
1814 		goto done;
1815 
1816 	/* Get info for determining size */
1817 	wasup = si_iscoreup(sih);
1818 	if (!wasup)
1819 		si_core_reset(sih, 0, 0);
1820 	corerev = si_corerev(sih);
1821 	coreinfo = R_REG(&regs->coreinfo);
1822 
1823 	/* Calculate size from coreinfo based on rev */
1824 	if (corerev == 0)
1825 		memsize = 1 << (16 + (coreinfo & SRCI_MS0_MASK));
1826 	else if (corerev < 3) {
1827 		memsize = 1 << (SR_BSZ_BASE + (coreinfo & SRCI_SRBSZ_MASK));
1828 		memsize *= (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT;
1829 	} else if ((corerev <= 7) || (corerev == 12)) {
1830 		uint nb = (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT;
1831 		uint bsz = (coreinfo & SRCI_SRBSZ_MASK);
1832 		uint lss = (coreinfo & SRCI_LSS_MASK) >> SRCI_LSS_SHIFT;
1833 		if (lss != 0)
1834 			nb--;
1835 		memsize = nb * (1 << (bsz + SR_BSZ_BASE));
1836 		if (lss != 0)
1837 			memsize += (1 << ((lss - 1) + SR_BSZ_BASE));
1838 	} else {
1839 		u8 i;
1840 		uint nb = (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT;
1841 		for (i = 0; i < nb; i++)
1842 			memsize +=
1843 			    socram_banksize(sii, regs, i, SOCRAM_MEMTYPE_RAM);
1844 	}
1845 
1846 	/* Return to previous state and core */
1847 	if (!wasup)
1848 		si_core_disable(sih, 0);
1849 	si_setcoreidx(sih, origidx);
1850 
1851  done:
1852 	INTR_RESTORE(sii, intr_val);
1853 
1854 	return memsize;
1855 }
1856 
si_chipcontrl_epa4331(si_t * sih,bool on)1857 void si_chipcontrl_epa4331(si_t *sih, bool on)
1858 {
1859 	si_info_t *sii;
1860 	chipcregs_t *cc;
1861 	uint origidx;
1862 	u32 val;
1863 
1864 	sii = SI_INFO(sih);
1865 	origidx = si_coreidx(sih);
1866 
1867 	cc = (chipcregs_t *) si_setcore(sih, CC_CORE_ID, 0);
1868 
1869 	val = R_REG(&cc->chipcontrol);
1870 
1871 	if (on) {
1872 		if (sih->chippkg == 9 || sih->chippkg == 0xb) {
1873 			/* Ext PA Controls for 4331 12x9 Package */
1874 			W_REG(&cc->chipcontrol, val |
1875 			      (CCTRL4331_EXTPA_EN |
1876 			       CCTRL4331_EXTPA_ON_GPIO2_5));
1877 		} else {
1878 			/* Ext PA Controls for 4331 12x12 Package */
1879 			W_REG(&cc->chipcontrol,
1880 			      val | (CCTRL4331_EXTPA_EN));
1881 		}
1882 	} else {
1883 		val &= ~(CCTRL4331_EXTPA_EN | CCTRL4331_EXTPA_ON_GPIO2_5);
1884 		W_REG(&cc->chipcontrol, val);
1885 	}
1886 
1887 	si_setcoreidx(sih, origidx);
1888 }
1889 
1890 /* Enable BT-COEX & Ex-PA for 4313 */
si_epa_4313war(si_t * sih)1891 void si_epa_4313war(si_t *sih)
1892 {
1893 	si_info_t *sii;
1894 	chipcregs_t *cc;
1895 	uint origidx;
1896 
1897 	sii = SI_INFO(sih);
1898 	origidx = si_coreidx(sih);
1899 
1900 	cc = (chipcregs_t *) si_setcore(sih, CC_CORE_ID, 0);
1901 
1902 	/* EPA Fix */
1903 	W_REG(&cc->gpiocontrol,
1904 	      R_REG(&cc->gpiocontrol) | GPIO_CTRL_EPA_EN_MASK);
1905 
1906 	si_setcoreidx(sih, origidx);
1907 }
1908 
1909 /* check if the device is removed */
si_deviceremoved(si_t * sih)1910 bool si_deviceremoved(si_t *sih)
1911 {
1912 	u32 w;
1913 	si_info_t *sii;
1914 
1915 	sii = SI_INFO(sih);
1916 
1917 	switch (sih->bustype) {
1918 	case PCI_BUS:
1919 		ASSERT(sii->pbus != NULL);
1920 		pci_read_config_dword(sii->pbus, PCI_CFG_VID, &w);
1921 		if ((w & 0xFFFF) != VENDOR_BROADCOM)
1922 			return true;
1923 		break;
1924 	}
1925 	return false;
1926 }
1927 
si_is_sprom_available(si_t * sih)1928 bool si_is_sprom_available(si_t *sih)
1929 {
1930 	if (sih->ccrev >= 31) {
1931 		si_info_t *sii;
1932 		uint origidx;
1933 		chipcregs_t *cc;
1934 		u32 sromctrl;
1935 
1936 		if ((sih->cccaps & CC_CAP_SROM) == 0)
1937 			return false;
1938 
1939 		sii = SI_INFO(sih);
1940 		origidx = sii->curidx;
1941 		cc = si_setcoreidx(sih, SI_CC_IDX);
1942 		sromctrl = R_REG(&cc->sromcontrol);
1943 		si_setcoreidx(sih, origidx);
1944 		return sromctrl & SRC_PRESENT;
1945 	}
1946 
1947 	switch (sih->chip) {
1948 	case BCM4329_CHIP_ID:
1949 		return (sih->chipst & CST4329_SPROM_SEL) != 0;
1950 	case BCM4319_CHIP_ID:
1951 		return (sih->chipst & CST4319_SPROM_SEL) != 0;
1952 	case BCM4336_CHIP_ID:
1953 		return (sih->chipst & CST4336_SPROM_PRESENT) != 0;
1954 	case BCM4330_CHIP_ID:
1955 		return (sih->chipst & CST4330_SPROM_PRESENT) != 0;
1956 	case BCM4313_CHIP_ID:
1957 		return (sih->chipst & CST4313_SPROM_PRESENT) != 0;
1958 	case BCM4331_CHIP_ID:
1959 		return (sih->chipst & CST4331_SPROM_PRESENT) != 0;
1960 	default:
1961 		return true;
1962 	}
1963 }
1964 
si_is_otp_disabled(si_t * sih)1965 bool si_is_otp_disabled(si_t *sih)
1966 {
1967 	switch (sih->chip) {
1968 	case BCM4329_CHIP_ID:
1969 		return (sih->chipst & CST4329_SPROM_OTP_SEL_MASK) ==
1970 		    CST4329_OTP_PWRDN;
1971 	case BCM4319_CHIP_ID:
1972 		return (sih->chipst & CST4319_SPROM_OTP_SEL_MASK) ==
1973 		    CST4319_OTP_PWRDN;
1974 	case BCM4336_CHIP_ID:
1975 		return (sih->chipst & CST4336_OTP_PRESENT) == 0;
1976 	case BCM4330_CHIP_ID:
1977 		return (sih->chipst & CST4330_OTP_PRESENT) == 0;
1978 	case BCM4313_CHIP_ID:
1979 		return (sih->chipst & CST4313_OTP_PRESENT) == 0;
1980 		/* These chips always have their OTP on */
1981 	case BCM43224_CHIP_ID:
1982 	case BCM43225_CHIP_ID:
1983 	case BCM43421_CHIP_ID:
1984 	case BCM43235_CHIP_ID:
1985 	case BCM43236_CHIP_ID:
1986 	case BCM43238_CHIP_ID:
1987 	case BCM4331_CHIP_ID:
1988 	default:
1989 		return false;
1990 	}
1991 }
1992 
si_is_otp_powered(si_t * sih)1993 bool si_is_otp_powered(si_t *sih)
1994 {
1995 	if (PMUCTL_ENAB(sih))
1996 		return si_pmu_is_otp_powered(sih);
1997 	return true;
1998 }
1999 
si_otp_power(si_t * sih,bool on)2000 void si_otp_power(si_t *sih, bool on)
2001 {
2002 	if (PMUCTL_ENAB(sih))
2003 		si_pmu_otp_power(sih, on);
2004 	udelay(1000);
2005 }
2006 
2007