1/*
2 * Low-Level PCI and SI support for BCM47xx
3 *
4 * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved.
5 *
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
13 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
15 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
16 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 *
18 * $Id: hndpci.c 401759 2013-05-13 16:08:08Z $
19 */
20
21#include <bcm_cfg.h>
22#include <typedefs.h>
23#include <osl.h>
24#include <pcicfg.h>
25#include <bcmdevs.h>
26#include <hndsoc.h>
27#include <bcmutils.h>
28#include <siutils.h>
29#include <pci_core.h>
30#include <pcie_core.h>
31#include <bcmendian.h>
32#include <bcmnvram.h>
33#include <hndcpu.h>
34#include <hndpci.h>
35#include <nicpci.h>
36#include <sbchipc.h>
37
38/* For now we need some real Silicon Backplane utils */
39#include "siutils_priv.h"
40
41/* debug/trace */
42#ifdef BCMDBG_PCI
43#define	PCI_MSG(args)	printf args
44#else
45#define	PCI_MSG(args)
46#endif
47
48/* to free some function memory after boot */
49#ifndef linux
50#define __init
51#endif /* linux */
52
53/* Emulated configuration space */
54typedef struct {
55	int	n;
56	uint	size[PCI_BAR_MAX];
57} si_bar_cfg_t;
58static pci_config_regs si_config_regs[SI_MAXCORES];
59static si_bar_cfg_t si_bar_cfg[SI_MAXCORES];
60
61/* Links to emulated and real PCI configuration spaces */
62#define MAXFUNCS	2
63typedef struct {
64	pci_config_regs *emu;	/* emulated PCI config */
65	pci_config_regs *pci;	/* real PCI config */
66	si_bar_cfg_t *bar;	/* region sizes */
67} si_pci_cfg_t;
68static si_pci_cfg_t si_pci_cfg[SI_MAXCORES][MAXFUNCS];
69
70/* Special emulated config space for non-existing device */
71static pci_config_regs si_pci_null = { 0xffff, 0xffff };
72
73/* Banned cores */
74static uint16 pci_ban[SI_MAXCORES] = { 0 };
75static uint pci_banned = 0;
76
77/* CardBus mode */
78static bool cardbus = FALSE;
79
80/* The OS's enumerated bus numbers for supported PCI/PCIe core units */
81static uint pci_busid[SI_PCI_MAXCORES] = { 0, };
82
83static uint32 pci_membase_cfg[SI_PCI_MAXCORES] = {
84	SI_PCI_CFG,
85};
86
87static uint32 pci_membase[SI_PCI_MAXCORES] = {
88	SI_PCI_DMA,
89};
90
91static uint32 pci_membase_1G[SI_PCI_MAXCORES] = {
92	SI_PCI_DMA,
93};
94
95/* Disable PCI host core */
96static bool pci_disabled[SI_PCI_MAXCORES] = {	FALSE };
97
98/* Host bridge slot #, default to 0 */
99static uint8 pci_hbslot = 0;
100
101/* Internal macros */
102#define PCI_SLOTAD_MAP	16	/* SLOT<n> mapps to AD<n+16> */
103#define PCI_HBSBCFG_REV	8	/* MIN corerev to access host bridge PCI cfg space from SB */
104
105/* Functions for accessing external PCI configuration space, Assume one-hot slot wiring */
106#define PCI_SLOT_MAX	16	/* Max. PCI Slots */
107
108static void
109hndpci_set_busid(uint busid)
110{	int i;
111
112	for (i = 0; i < SI_PCI_MAXCORES; i++) {
113		if (pci_busid[i] == 0) {
114			pci_busid[i] = busid;
115			printf("PCI/PCIe coreunit %d is set to bus %d.\n", i, pci_busid[i]);
116			return;
117		}
118		if (busid == pci_busid[i])
119			return;
120	}
121}
122
123static int
124hndpci_pci_coreunit(uint bus)
125{	int i;
126
127	ASSERT(bus >= 1);
128	for (i = SI_PCI_MAXCORES - 1; i >= 0; i--) {
129		if (pci_busid[i] && bus >= pci_busid[i])
130			return i;
131	}
132	return -1;
133}
134
135bool
136hndpci_is_hostbridge(uint bus, uint dev)
137{	uint i;
138
139	ASSERT(bus >= 1);
140	if (dev != pci_hbslot)
141		return FALSE;
142
143	for (i = 0; i < SI_PCI_MAXCORES; i++)
144		if (bus == pci_busid[i])
145			return TRUE;
146
147	return FALSE;
148}
149
150uint32 hndpci_get_membase(uint bus)
151{
152	int coreunit;
153
154	coreunit = hndpci_pci_coreunit(bus);
155	ASSERT(coreunit >= 0);
156	ASSERT(pci_membase[coreunit]);
157	return pci_membase[coreunit];
158}
159
160static uint32
161config_cmd(si_t *sih, uint coreunit, uint bus, uint dev, uint func, uint off)
162{
163	uint coreidx;
164	sbpciregs_t *pci;
165	uint32 addr = 0, *sbtopci1;
166	osl_t *osh;
167
168	/* CardBusMode supports only one device */
169	if (cardbus && dev > 1)
170		return 0;
171
172	osh = si_osh(sih);
173
174	coreidx = si_coreidx(sih);
175	pci = (sbpciregs_t *)si_setcore(sih, PCI_CORE_ID, coreunit);
176
177	if (pci) {
178		sbtopci1 = &pci->sbtopci1;
179	} else {
180		sbpcieregs_t *pcie;
181
182		pcie = (sbpcieregs_t *)si_setcore(sih, PCIE_CORE_ID, coreunit);
183
184		/* Issue config commands only when the data link is up (atleast
185		 * one external pcie device is present).
186		 */
187		if (pcie && (dev < 2) &&
188		    (pcie_readreg(sih, pcie, PCIE_PCIEREGS,
189		    PCIE_DLLP_LSREG) & PCIE_DLLP_LSREG_LINKUP)) {
190			sbtopci1 = &pcie->sbtopcie1;
191		} else {
192			si_setcoreidx(sih, coreidx);
193			return 0;
194		}
195	}
196
197
198	/* Type 0 transaction */
199	if (!hndpci_is_hostbridge(bus, dev)) {
200		/* Skip unwired slots */
201		if (dev < PCI_SLOT_MAX) {
202			/* Slide the PCI window to the appropriate slot */
203			if (pci) {
204				uint32 win;
205
206				win = (SBTOPCI_CFG0 |
207					((1 << (dev + PCI_SLOTAD_MAP)) & SBTOPCI1_MASK));
208				W_REG(osh, sbtopci1, win);
209				addr = (pci_membase_cfg[coreunit] |
210					((1 << (dev + PCI_SLOTAD_MAP)) & ~SBTOPCI1_MASK) |
211					(func << PCICFG_FUN_SHIFT) |
212					(off & ~3));
213			} else {
214				W_REG(osh, sbtopci1, SBTOPCI_CFG0);
215				addr = (pci_membase_cfg[coreunit] |
216					(dev << PCIECFG_SLOT_SHIFT) |
217					(func << PCIECFG_FUN_SHIFT) |
218					(off & ~3));
219			}
220		}
221	} else {
222		/* Type 1 transaction */
223		W_REG(osh, sbtopci1, SBTOPCI_CFG1);
224		addr = (pci_membase_cfg[coreunit] |
225			(pci ? PCI_CONFIG_ADDR(bus, dev, func, (off & ~3)) :
226			PCIE_CONFIG_ADDR((bus - 1), dev, func, (off & ~3))));
227	}
228
229	si_setcoreidx(sih, coreidx);
230
231	return addr;
232}
233
234/**
235 * Read host bridge PCI config registers from Silicon Backplane ( >= rev8 ).
236 *
237 * It returns TRUE to indicate that access to the host bridge's pci config
238 * from SI is ok, and values in 'addr' and 'val' are valid.
239 *
240 * It can only read registers at multiple of 4-bytes. Callers must pick up
241 * needed bytes from 'val' based on 'off' value. Value in 'addr' reflects
242 * the register address where value in 'val' is read.
243 */
244static bool
245si_pcihb_read_config(si_t *sih, uint coreunit, uint bus, uint dev, uint func,
246	uint off, uint32 **addr, uint32 *val)
247{
248	sbpciregs_t *pci;
249	osl_t *osh;
250	uint coreidx;
251	bool ret = FALSE;
252
253	/* sanity check */
254	ASSERT(hndpci_is_hostbridge(bus, dev));
255
256	/* we support only two functions on device 0 */
257	if (func > 1)
258		return FALSE;
259
260	osh = si_osh(sih);
261
262	/* read pci config when core rev >= 8 */
263	coreidx = si_coreidx(sih);
264	pci = (sbpciregs_t *)si_setcore(sih, PCI_CORE_ID, coreunit);
265	if (pci) {
266		if (si_corerev(sih) >= PCI_HBSBCFG_REV) {
267			*addr = (uint32 *)&pci->pcicfg[func][off >> 2];
268			*val = R_REG(osh, *addr);
269			ret = TRUE;
270		}
271	} else {
272		sbpcieregs_t *pcie;
273
274		/* read pcie config */
275		pcie = (sbpcieregs_t *)si_setcore(sih, PCIE_CORE_ID, coreunit);
276		if (pcie != NULL) {
277			/* accesses to config registers with offsets >= 256
278			 * requires indirect access.
279			 */
280			if (off >= 256)
281				*val = pcie_readreg(sih, pcie, PCIE_CONFIGREGS,
282				                    PCIE_CONFIG_INDADDR(func, off));
283			else {
284				*addr = (uint32 *)&pcie->pciecfg[func][off >> 2];
285				*val = R_REG(osh, *addr);
286			}
287			ret = TRUE;
288		}
289	}
290
291	si_setcoreidx(sih, coreidx);
292
293	return ret;
294}
295
296int
297extpci_read_config(si_t *sih, uint bus, uint dev, uint func, uint off, void *buf, int len)
298{
299	uint32 addr = 0, *reg = NULL, val;
300	int ret = 0;
301	int coreunit = hndpci_pci_coreunit(bus);
302
303	if (coreunit < 0)
304		return -1;
305
306	/*
307	 * Set value to -1 when:
308	 *	flag 'pci_disabled' is true;
309	 *	value of 'addr' is zero;
310	 *	REG_MAP() fails;
311	 *	BUSPROBE() fails;
312	 */
313	if (pci_disabled[coreunit])
314		val = 0xffffffff;
315	else if (hndpci_is_hostbridge(bus, dev)) {
316		if (!si_pcihb_read_config(sih, coreunit, bus, dev, func, off, &reg, &val))
317			return -1;
318	} else if (((addr = config_cmd(sih, coreunit, bus, dev, func, off)) == 0) ||
319	         ((reg = (uint32 *)REG_MAP(addr, len)) == 0) ||
320	         (BUSPROBE(val, reg) != 0)) {
321		PCI_MSG(("%s: Failed to read!\n", __FUNCTION__));
322		val = 0xffffffff;
323	}
324
325	PCI_MSG(("%s: 0x%x <= 0x%p(0x%x), len %d, off 0x%x, buf 0x%p\n",
326	       __FUNCTION__, val, reg, addr, len, off, buf));
327
328	val >>= 8 * (off & 3);
329	if (len == 4)
330		*((uint32 *)buf) = val;
331	else if (len == 2)
332		*((uint16 *)buf) = (uint16) val;
333	else if (len == 1)
334		*((uint8 *)buf) = (uint8) val;
335	else
336		ret = -1;
337
338	if (reg && addr)
339		REG_UNMAP(reg);
340
341	return ret;
342}
343
344int
345extpci_write_config(si_t *sih, uint bus, uint dev, uint func, uint off, void *buf, int len)
346{
347	osl_t *osh;
348	uint32 addr = 0, *reg = NULL, val;
349	int ret = 0;
350	bool is_hostbridge;
351	int coreunit = hndpci_pci_coreunit(bus);
352
353	if (coreunit < 0)
354		return -1;
355
356	osh = si_osh(sih);
357
358	/*
359	 * Ignore write attempt when:
360	 *	flag 'pci_disabled' is true;
361	 *	value of 'addr' is zero;
362	 *	REG_MAP() fails;
363	 *	BUSPROBE() fails;
364	 */
365	if (pci_disabled[coreunit])
366		return 0;
367	if ((is_hostbridge = hndpci_is_hostbridge(bus, dev))) {
368		if (!si_pcihb_read_config(sih, coreunit, bus, dev, func, off, &reg, &val))
369			return -1;
370	} else if (((addr = config_cmd(sih, coreunit, bus, dev, func, off)) == 0) ||
371	         ((reg = (uint32 *)REG_MAP(addr, len)) == 0) ||
372	         (BUSPROBE(val, reg) != 0)) {
373		PCI_MSG(("%s: Failed to write!\n", __FUNCTION__));
374		goto done;
375	}
376
377	if (len == 4)
378		val = *((uint32 *)buf);
379	else if (len == 2) {
380		val &= ~(0xffff << (8 * (off & 3)));
381		val |= *((uint16 *)buf) << (8 * (off & 3));
382	} else if (len == 1) {
383		val &= ~(0xff << (8 * (off & 3)));
384		val |= *((uint8 *)buf) << (8 * (off & 3));
385	} else {
386		ret = -1;
387		goto done;
388	}
389
390	PCI_MSG(("%s: 0x%x => 0x%p\n", __FUNCTION__, val, reg));
391
392	if (is_hostbridge && reg == NULL) {
393		sbpcieregs_t *pcie;
394		uint coreidx;
395
396		coreidx = si_coreidx(sih);
397
398		/* read pcie config */
399		pcie = (sbpcieregs_t *)si_setcore(sih, PCIE_CORE_ID, coreunit);
400		if (pcie != NULL)
401			/* accesses to config registers with offsets >= 256
402			 * requires indirect access.
403			 */
404			pcie_writereg(sih, pcie, PCIE_CONFIGREGS,
405			              PCIE_CONFIG_INDADDR(func, off), val);
406
407		si_setcoreidx(sih, coreidx);
408	} else {
409		W_REG(osh, reg, val);
410
411		if ((CHIPID(sih->chip) == BCM4716_CHIP_ID) ||
412		    (CHIPID(sih->chip) == BCM4748_CHIP_ID))
413			(void)R_REG(osh, reg);
414	}
415
416
417done:
418	if (reg && addr)
419		REG_UNMAP(reg);
420
421	return ret;
422}
423
424/**
425 * Must access emulated PCI configuration at these locations even when
426 * the real PCI config space exists and is accessible.
427 *
428 * PCI_CFG_VID (0x00)
429 * PCI_CFG_DID (0x02)
430 * PCI_CFG_PROGIF (0x09)
431 * PCI_CFG_SUBCL  (0x0a)
432 * PCI_CFG_BASECL (0x0b)
433 * PCI_CFG_HDR (0x0e)
434 * PCI_CFG_INT (0x3c)
435 * PCI_CFG_PIN (0x3d)
436 */
437#define FORCE_EMUCFG(off, len) \
438	((off == PCI_CFG_VID) || (off == PCI_CFG_DID) || \
439	 (off == PCI_CFG_PROGIF) || \
440	 (off == PCI_CFG_SUBCL) || (off == PCI_CFG_BASECL) || \
441	 (off == PCI_CFG_HDR) || \
442	 (off == PCI_CFG_INT) || (off == PCI_CFG_PIN))
443
444/** Sync the emulation registers and the real PCI config registers. */
445static void
446si_pcid_read_config(si_t *sih, uint coreidx, si_pci_cfg_t *cfg, uint off, uint len)
447{
448	osl_t *osh;
449	uint oldidx;
450
451	ASSERT(cfg);
452	ASSERT(cfg->emu);
453	ASSERT(cfg->pci);
454
455	/* decide if real PCI config register access is necessary */
456	if (FORCE_EMUCFG(off, len))
457		return;
458
459	osh = si_osh(sih);
460
461	/* access to the real pci config space only when the core is up */
462	oldidx = si_coreidx(sih);
463	si_setcoreidx(sih, coreidx);
464	if (si_iscoreup(sih)) {
465		if (len == 4)
466			*(uint32 *)((ulong)cfg->emu + off) =
467			        htol32(R_REG(osh, (uint32 *)((ulong)cfg->pci + off)));
468		else if (len == 2)
469			*(uint16 *)((ulong)cfg->emu + off) =
470			        htol16(R_REG(osh, (uint16 *)((ulong)cfg->pci + off)));
471		else if (len == 1)
472			*(uint8 *)((ulong)cfg->emu + off) =
473			        R_REG(osh, (uint8 *)((ulong)cfg->pci + off));
474	}
475	si_setcoreidx(sih, oldidx);
476}
477
478static void
479si_pcid_write_config(si_t *sih, uint coreidx, si_pci_cfg_t *cfg, uint off, uint len)
480{
481	osl_t *osh;
482	uint oldidx;
483
484	ASSERT(cfg);
485	ASSERT(cfg->emu);
486	ASSERT(cfg->pci);
487
488	osh = si_osh(sih);
489
490	/* decide if real PCI config register access is necessary */
491	if (FORCE_EMUCFG(off, len))
492		return;
493
494	/* access to the real pci config space only when the core is up */
495	oldidx = si_coreidx(sih);
496	si_setcoreidx(sih, coreidx);
497	if (si_iscoreup(sih)) {
498		if (len == 4)
499			W_REG(osh, (uint32 *)((ulong)cfg->pci + off),
500			      ltoh32(*(uint32 *)((ulong)cfg->emu + off)));
501		else if (len == 2)
502			W_REG(osh, (uint16 *)((ulong)cfg->pci + off),
503			      ltoh16(*(uint16 *)((ulong)cfg->emu + off)));
504		else if (len == 1)
505			W_REG(osh, (uint8 *)((ulong)cfg->pci + off),
506			      *(uint8 *)((ulong)cfg->emu + off));
507	}
508	si_setcoreidx(sih, oldidx);
509}
510
511/*
512 * Functions for accessing translated SI configuration space
513 */
514static int
515si_read_config(si_t *sih, uint bus, uint dev, uint func, uint off, void *buf, int len)
516{
517	pci_config_regs *cfg;
518
519	if (dev >= SI_MAXCORES || func >= MAXFUNCS || (off + len) > sizeof(pci_config_regs))
520		return -1;
521
522	cfg = si_pci_cfg[dev][func].emu;
523
524	ASSERT(ISALIGNED(off, len));
525	ASSERT(ISALIGNED(buf, len));
526
527	/* use special config space if the device does not exist */
528	if (!cfg)
529		cfg = &si_pci_null;
530	/* sync emulation with real PCI config if necessary */
531	else if (si_pci_cfg[dev][func].pci)
532		si_pcid_read_config(sih, dev, &si_pci_cfg[dev][func], off, len);
533
534	if (len == 4)
535		*((uint32 *)buf) = ltoh32(*((uint32 *)((ulong) cfg + off)));
536	else if (len == 2)
537		*((uint16 *)buf) = ltoh16(*((uint16 *)((ulong) cfg + off)));
538	else if (len == 1)
539		*((uint8 *)buf) = *((uint8 *)((ulong) cfg + off));
540	else
541		return -1;
542
543	return 0;
544}
545
546static int
547si_write_config(si_t *sih, uint bus, uint dev, uint func, uint off, void *buf, int len)
548{
549	uint coreidx;
550	void *regs;
551	pci_config_regs *cfg;
552	osl_t *osh;
553	si_bar_cfg_t *bar;
554
555	if (dev >= SI_MAXCORES || func >= MAXFUNCS || (off + len) > sizeof(pci_config_regs))
556		return -1;
557	cfg = si_pci_cfg[dev][func].emu;
558	if (!cfg)
559		return -1;
560
561	ASSERT(ISALIGNED(off, len));
562	ASSERT(ISALIGNED(buf, len));
563
564	osh = si_osh(sih);
565
566	if (cfg->header_type == PCI_HEADER_BRIDGE) {
567		uint busid = 0;
568		if (off == OFFSETOF(ppb_config_regs, prim_bus) && len >= 2)
569			busid = (*((uint16 *)buf) & 0xff00) >> 8;
570		else if (off == OFFSETOF(ppb_config_regs, sec_bus))
571			busid = *((uint8 *)buf);
572		if (busid)
573			hndpci_set_busid(busid);
574	}
575
576	/* Emulate BAR sizing */
577	if (off >= OFFSETOF(pci_config_regs, base[0]) &&
578	    off <= OFFSETOF(pci_config_regs, base[3]) &&
579	    len == 4 && *((uint32 *)buf) == ~0) {
580		coreidx = si_coreidx(sih);
581		if ((regs = si_setcoreidx(sih, dev))) {
582			bar = si_pci_cfg[dev][func].bar;
583			/* Highest numbered address match register */
584			if (off == OFFSETOF(pci_config_regs, base[0]))
585				cfg->base[0] = ~(bar->size[0] - 1);
586			else if (off == OFFSETOF(pci_config_regs, base[1]) && bar->n >= 1)
587				cfg->base[1] = ~(bar->size[1] - 1);
588			else if (off == OFFSETOF(pci_config_regs, base[2]) && bar->n >= 2)
589				cfg->base[2] = ~(bar->size[2] - 1);
590			else if (off == OFFSETOF(pci_config_regs, base[3]) && bar->n >= 3)
591				cfg->base[3] = ~(bar->size[3] - 1);
592		}
593		si_setcoreidx(sih, coreidx);
594	} else if (len == 4)
595		*((uint32 *)((ulong) cfg + off)) = htol32(*((uint32 *)buf));
596	else if (len == 2)
597		*((uint16 *)((ulong) cfg + off)) = htol16(*((uint16 *)buf));
598	else if (len == 1)
599		*((uint8 *)((ulong) cfg + off)) = *((uint8 *)buf);
600	else
601		return -1;
602
603	/* sync emulation with real PCI config if necessary */
604	if (si_pci_cfg[dev][func].pci)
605		si_pcid_write_config(sih, dev, &si_pci_cfg[dev][func], off, len);
606
607	return 0;
608}
609
610int
611hndpci_read_config(si_t *sih, uint bus, uint dev, uint func, uint off, void *buf, int len)
612{
613	if (bus == 0)
614		return si_read_config(sih, bus, dev, func, off, buf, len);
615	else
616		return extpci_read_config(sih, bus, dev, func, off, buf, len);
617}
618
619int
620hndpci_write_config(si_t *sih, uint bus, uint dev, uint func, uint off, void *buf, int len)
621{
622	if (bus == 0)
623		return si_write_config(sih, bus, dev, func, off, buf, len);
624	else
625		return extpci_write_config(sih, bus, dev, func, off, buf, len);
626}
627
628void
629hndpci_ban(uint16 core)
630{
631	if (pci_banned < ARRAYSIZE(pci_ban))
632		pci_ban[pci_banned++] = core;
633}
634
635/** return cap_offset if requested capability exists in the PCI config space */
636uint8
637hndpci_find_pci_capability(si_t *sih, uint bus, uint dev, uint func,
638                           uint8 req_cap_id, uchar *buf, uint32 *buflen)
639{
640	uint8 cap_id;
641	uint8 cap_ptr = 0;
642	uint32 bufsize;
643	uint8 byte_val;
644
645	/* check for Header type 0 */
646	hndpci_read_config(sih, bus, dev, func, PCI_CFG_HDR, &byte_val, sizeof(uint8));
647	if ((byte_val & 0x7f) != PCI_HEADER_NORMAL)
648		return (cap_ptr);
649
650	/* check if the capability pointer field exists */
651	hndpci_read_config(sih, bus, dev, func, PCI_CFG_STAT, &byte_val, sizeof(uint8));
652	if (!(byte_val & PCI_CAPPTR_PRESENT))
653		return (cap_ptr);
654
655	/* check if the capability pointer is 0x00 */
656	hndpci_read_config(sih, bus, dev, func, PCI_CFG_CAPPTR, &cap_ptr, sizeof(uint8));
657	if (cap_ptr == 0x00)
658		return (cap_ptr);
659
660	/* loop thr'u the capability list and see if the requested capabilty exists */
661	hndpci_read_config(sih, bus, dev, func, cap_ptr, &cap_id, sizeof(uint8));
662	while (cap_id != req_cap_id) {
663		hndpci_read_config(sih, bus, dev, func, cap_ptr + 1, &cap_ptr, sizeof(uint8));
664		if (cap_ptr == 0x00)
665			return (cap_ptr);
666		hndpci_read_config(sih, bus, dev, func, cap_ptr, &cap_id, sizeof(uint8));
667	}
668
669	/* found the caller requested capability */
670	if ((buf != NULL) && (buflen != NULL)) {
671		uint8 cap_data;
672
673		bufsize = *buflen;
674		if (!bufsize)
675			return (cap_ptr);
676
677		*buflen = 0;
678
679		/* copy the cpability data excluding cap ID and next ptr */
680		cap_data = cap_ptr + 2;
681		if ((bufsize + cap_data)  > SZPCR)
682			bufsize = SZPCR - cap_data;
683		*buflen = bufsize;
684		while (bufsize--) {
685			hndpci_read_config(sih, bus, dev, func, cap_data, buf, sizeof(uint8));
686			cap_data++;
687			buf++;
688		}
689	}
690
691	return (cap_ptr);
692}
693
694
695/**
696 * Initialize PCI core.
697 * Return 0 after a successful initialization.
698 * Otherwise return -1 to indicate there is no PCI core and
699 * return 1 to indicate PCI core is disabled.
700 */
701int __init
702BCMATTACHFN(hndpci_init_pci)(si_t *sih, uint coreunit)
703{
704	uint chip, chiprev, chippkg, host;
705	uint32 boardflags;
706	sbpciregs_t *pci;
707	sbpcieregs_t *pcie = NULL;
708	uint32 val;
709	int ret = 0;
710	const char *hbslot;
711	osl_t *osh;
712	int bus;
713
714	chip = sih->chip;
715	chiprev = sih->chiprev;
716	chippkg = sih->chippkg;
717
718	osh = si_osh(sih);
719
720	pci = (sbpciregs_t *)si_setcore(sih, PCI_CORE_ID, coreunit);
721	if (pci == NULL) {
722		pcie = (sbpcieregs_t *)si_setcore(sih, PCIE_CORE_ID, coreunit);
723		if (pcie == NULL) {
724			printf("PCI: no core\n");
725			pci_disabled[coreunit] = TRUE;
726			return -1;
727		}
728	}
729
730	if ((CHIPID(chip) == BCM4706_CHIP_ID) && (coreunit == 1)) {
731		/* Check if PCIE 1 is disabled */
732		if (sih->chipst & CST4706_PCIE1_DISABLE) {
733			pci_disabled[coreunit] = TRUE;
734			host = 0;
735			PCI_MSG(("PCIE port %d is disabled\n", port));
736		}
737	}
738
739	boardflags = (uint32)getintvar(NULL, "boardflags");
740
741	/*
742	 * The NOPCI boardflag indicates we should not touch the PCI core,
743	 * it may not be bonded out or the pins may be floating.
744	 * The 200-pin BCM4712 package does not bond out PCI, and routers
745	 * based on it did not use the boardflag.
746	 */
747	if ((boardflags & BFL_NOPCI) ||
748	    ((chip == BCM4712_CHIP_ID) &&
749	     ((chippkg == BCM4712SMALL_PKG_ID) || (chippkg == BCM4712MID_PKG_ID)))) {
750		pci_disabled[coreunit] = TRUE;
751		host = 0;
752	} else {
753		/* Enable the core */
754		si_core_reset(sih, 0, 0);
755
756		/* Figure out if it is in host mode:
757		 * In host mode, it returns 0, in client mode, this register access will trap
758		 * Trap handler must be implemented to support this like hndrte_mips.c
759		 */
760		host = !BUSPROBE(val, (pci ? &pci->control : &pcie->control));
761	}
762
763	if (!host) {
764		ret = 1;
765
766		/* Disable PCI interrupts in client mode */
767		si_setint(sih, -1);
768
769		/* Disable the PCI bridge in client mode */
770		hndpci_ban(pci? PCI_CORE_ID : PCIE_CORE_ID);
771
772		/* Make sure the core is disabled */
773		si_core_disable(sih, 0);
774
775		/* On 4716 (and other AXI chips?) make sure the slave wrapper
776		 * is also put in reset.
777		 */
778		if ((chip == BCM4716_CHIP_ID) || (chip == BCM4748_CHIP_ID) ||
779			(chip == BCM4706_CHIP_ID)) {
780			uint32 *resetctrl;
781
782			resetctrl = (uint32 *)OSL_UNCACHED(SI_WRAP_BASE + (9 * SI_CORE_SIZE) +
783			                                   AI_RESETCTRL);
784			W_REG(osh, resetctrl, AIRC_RESET);
785		}
786
787		printf("PCI: Disabled\n");
788	} else {
789		printf("PCI: Initializing host\n");
790
791		/* Disable PCI SBReqeustTimeout for BCM4785 rev. < 2 */
792		if (chip == BCM4785_CHIP_ID && chiprev < 2) {
793			sbconfig_t *sb;
794			sb = (sbconfig_t *)((ulong) pci + SBCONFIGOFF);
795			AND_REG(osh, &sb->sbimconfiglow, ~0x00000070);
796			sb_commit(sih);
797		}
798
799		if (pci) {
800			/* Reset the external PCI bus and enable the clock */
801			W_REG(osh, &pci->control, 0x5);	/* enable tristate drivers */
802			W_REG(osh, &pci->control, 0xd);	/* enable the PCI clock */
803			OSL_DELAY(150);			/* delay > 100 us */
804			W_REG(osh, &pci->control, 0xf);	/* deassert PCI reset */
805			/* Use internal arbiter and park REQ/GRNT at external master 0
806			 * We will set it later after the bus has been probed
807			 */
808			W_REG(osh, &pci->arbcontrol, PCI_INT_ARB);
809			OSL_DELAY(1);			/* delay 1 us */
810		} else {
811			printf("PCI: Reset RC\n");
812			OSL_DELAY(3000);
813			W_REG(osh, &pcie->control, PCIE_RST_OE);
814			OSL_DELAY(50000);		/* delay 50 ms */
815			W_REG(osh, &pcie->control, PCIE_RST | PCIE_RST_OE);
816		}
817
818		/* Enable CardBusMode */
819		cardbus = getintvar(NULL, "cardbus") == 1;
820		if (cardbus) {
821			printf("PCI: Enabling CardBus\n");
822			/* GPIO 1 resets the CardBus device on bcm94710ap */
823			si_gpioout(sih, 1, 1, GPIO_DRV_PRIORITY);
824			si_gpioouten(sih, 1, 1, GPIO_DRV_PRIORITY);
825			W_REG(osh, &pci->sprom[0], R_REG(osh, &pci->sprom[0]) | 0x400);
826		}
827
828		/* Host bridge slot # nvram overwrite */
829		if ((hbslot = nvram_get("pcihbslot"))) {
830			pci_hbslot = bcm_strtoul(hbslot, NULL, 0);
831			ASSERT(pci_hbslot < PCI_MAX_DEVICES);
832		}
833
834		bus = pci_busid[coreunit] = coreunit + 1;
835		if (pci) {
836			/* 64 MB I/O access window */
837			W_REG(osh, &pci->sbtopci0, SBTOPCI_IO);
838			/* 64 MB configuration access window */
839			W_REG(osh, &pci->sbtopci1, SBTOPCI_CFG0);
840			/* 1 GB memory access window */
841			W_REG(osh, &pci->sbtopci2, SBTOPCI_MEM | SI_PCI_DMA);
842		} else {
843			uint8 cap_ptr, root_ctrl, root_cap, dev;
844			uint16 val16;
845
846			/* 64 MB I/O access window. On 4716, use
847			 * sbtopcie0 to access the device registers. We
848			 * can't use address match 2 (1 GB window) region
849			 * as mips can't generate 64-bit address on the
850			 * backplane.
851			 */
852			if ((chip == BCM4716_CHIP_ID) || (chip == BCM4748_CHIP_ID))
853				W_REG(osh, &pcie->sbtopcie0, SBTOPCIE_MEM |
854					(pci_membase[coreunit] = SI_PCI_MEM));
855			else if (chip == BCM4706_CHIP_ID) {
856				if (coreunit == 0) {
857					pci_membase[coreunit] = SI_PCI_MEM;
858					pci_membase_1G[coreunit] = SI_PCIE_DMA_H32;
859				} else if (coreunit == 1) {
860					pci_membase_cfg[coreunit] = SI_PCI1_CFG;
861					pci_membase[coreunit] = SI_PCI1_MEM;
862					pci_membase_1G[coreunit] = SI_PCIE1_DMA_H32;
863				}
864				W_REG(osh, &pcie->sbtopcie0,
865					SBTOPCIE_MEM | SBTOPCIE_PF | SBTOPCIE_WR_BURST |
866					pci_membase[coreunit]);
867			}
868			else
869				W_REG(osh, &pcie->sbtopcie0, SBTOPCIE_IO);
870
871			/* 64 MB configuration access window */
872			W_REG(osh, &pcie->sbtopcie1, SBTOPCIE_CFG0);
873
874			/* 1 GB memory access window */
875			W_REG(osh, &pcie->sbtopcie2, SBTOPCIE_MEM |
876				pci_membase_1G[coreunit]);
877
878			/* As per PCI Express Base Spec 1.1 we need to wait for
879			 * at least 100 ms from the end of a reset (cold/warm/hot)
880			 * before issuing configuration requests to PCI Express
881			 * devices.
882			 */
883			OSL_DELAY(100000);
884
885			/* If the root port is capable of returning Config Request
886			 * Retry Status (CRS) Completion Status to software then
887			 * enable the feature.
888			 */
889			cap_ptr = hndpci_find_pci_capability(sih, bus, pci_hbslot, 0,
890			                                     PCI_CAP_PCIECAP_ID, NULL, NULL);
891			ASSERT(cap_ptr);
892
893			root_cap = cap_ptr + OFFSETOF(pciconfig_cap_pcie, root_cap);
894			hndpci_read_config(sih, bus, pci_hbslot, 0, root_cap,
895			                   &val16, sizeof(uint16));
896			if (val16 & PCIE_RC_CRS_VISIBILITY) {
897				/* Enable CRS software visibility */
898				root_ctrl = cap_ptr + OFFSETOF(pciconfig_cap_pcie, root_ctrl);
899				val16 = PCIE_RC_CRS_EN;
900				hndpci_write_config(sih, bus, pci_hbslot, 0, root_ctrl,
901				                    &val16, sizeof(uint16));
902
903				/* Initiate a configuration request to read the vendor id
904				 * field of the device function's config space header after
905				 * 100 ms wait time from the end of Reset. If the device is
906				 * not done with its internal initialization, it must at
907				 * least return a completion TLP, with a completion status
908				 * of "Configuration Request Retry Status (CRS)". The root
909				 * complex must complete the request to the host by returning
910				 * a read-data value of 0001h for the Vendor ID field and
911				 * all 1s for any additional bytes included in the request.
912				 * Poll using the config reads for max wait time of 1 sec or
913				 * until we receive the successful completion status. Repeat
914				 * the procedure for all the devices.
915				 */
916				for (dev = pci_hbslot + 1; dev < PCI_MAX_DEVICES; dev++) {
917					SPINWAIT((hndpci_read_config(sih, bus, dev, 0,
918					         PCI_CFG_VID, &val16, sizeof(val16)),
919					         (val16 == 0x1)), 1000000);
920					if (val16 == 0x1)
921						printf("PCI: Broken device in slot %d\n", dev);
922				}
923			}
924		}
925
926		if ((chip == BCM4706_CHIP_ID) || (chip == BCM4716_CHIP_ID)) {
927			uint16 val16;
928			hndpci_read_config(sih, bus, pci_hbslot, 0, PCI_CFG_DEVCTRL,
929			                   &val16, sizeof(val16));
930			val16 |= (2 << 5);	/* Max payload size of 512 */
931			val16 |= (2 << 12);	/* MRRS 512 */
932			hndpci_write_config(sih, bus, pci_hbslot, 0, PCI_CFG_DEVCTRL,
933			                    &val16, sizeof(val16));
934		}
935
936		/* Enable PCI bridge BAR0 memory & master access */
937		val = PCI_CMD_MASTER | PCI_CMD_MEMORY;
938		hndpci_write_config(sih, bus, pci_hbslot, 0, PCI_CFG_CMD, &val, sizeof(val));
939
940		/* Enable PCI interrupts */
941		if (pci)
942			W_REG(osh, &pci->intmask, PCI_INTA);
943		else
944			W_REG(osh, &pcie->intmask, PCI_INTA);
945	}
946
947	/* Reset busid to 0. Bus number will be assigned by OS later */
948	pci_busid[coreunit] = 0;
949	return ret;
950}
951
952void
953hndpci_arb_park(si_t *sih, uint parkid)
954{
955	sbpciregs_t *pci;
956	uint pcirev;
957	uint32  arb;
958
959	pci = (sbpciregs_t *)si_setcore(sih, PCI_CORE_ID, 0);
960	if ((pci == NULL) || pci_disabled[0]) {
961		/* Should not happen */
962		PCI_MSG(("%s: no PCI core\n", __FUNCTION__));
963		return;
964	}
965
966	pcirev = si_corerev(sih);
967
968	/* Nothing to do, not supported for these revs */
969	if (pcirev < 8)
970		return;
971
972	/* Get parkid from NVRAM */
973	if (parkid == PCI_PARK_NVRAM) {
974		parkid = getintvar(NULL, "parkid");
975		if (getvar(NULL, "parkid") == NULL)
976			/* Not present in NVRAM use defaults */
977			parkid = (pcirev >= 11) ? PCI11_PARKID_LAST : PCI_PARKID_LAST;
978	}
979
980	/* Check the parkid is valid, if not set it to default */
981	if (parkid > ((pcirev >= 11) ? PCI11_PARKID_LAST : PCI_PARKID_LAST)) {
982		printf("%s: Invalid parkid %d\n", __FUNCTION__, parkid);
983		parkid = (pcirev >= 11) ? PCI11_PARKID_LAST : PCI_PARKID_LAST;
984	}
985
986	/* Now set the parkid */
987	arb = R_REG(si_osh(sih), &pci->arbcontrol);
988	arb &= ~PCI_PARKID_MASK;
989	arb |= parkid << PCI_PARKID_SHIFT;
990	W_REG(si_osh(sih), &pci->arbcontrol, arb);
991	OSL_DELAY(1);
992}
993
994int
995hndpci_deinit_pci(si_t *sih, uint coreunit)
996{
997	int coreidx;
998	sbpciregs_t *pci;
999	sbpcieregs_t *pcie = NULL;
1000
1001	if (pci_disabled[coreunit])
1002		return 0;
1003
1004	coreidx = si_coreidx(sih);
1005	pci = (sbpciregs_t *)si_setcore(sih, PCI_CORE_ID, coreunit);
1006	if (pci == NULL) {
1007		pcie = (sbpcieregs_t *)si_setcore(sih, PCIE_CORE_ID, coreunit);
1008		if (pcie == NULL) {
1009			printf("PCI: no core\n");
1010			return -1;
1011		}
1012	}
1013
1014	if (pci)
1015			W_REG(si_osh(sih), &pci->control, PCI_RST_OE);
1016	else
1017			W_REG(si_osh(sih), &pcie->control, PCIE_RST_OE);
1018
1019	si_core_disable(sih, 0);
1020	si_setcoreidx(sih, coreidx);
1021	return 0;
1022}
1023
1024/** Deinitialize PCI cores */
1025void
1026hndpci_deinit(si_t *sih)
1027{
1028	int coreunit;
1029
1030	for (coreunit = 0; coreunit < SI_PCI_MAXCORES; coreunit++)
1031		hndpci_deinit_pci(sih, coreunit);
1032}
1033
1034/** Get the PCI region address and size information */
1035static void __init
1036BCMATTACHFN(hndpci_init_regions)(si_t *sih, uint func, pci_config_regs *cfg, si_bar_cfg_t *bar)
1037{
1038	bool issb = sih->socitype == SOCI_SB;
1039	uint i, n;
1040
1041	if ((si_coreid(sih) == USB20H_CORE_ID) ||
1042		(si_coreid(sih) == NS_USB20_CORE_ID)) {
1043		uint32 base, base1;
1044
1045		base = htol32(si_addrspace(sih, 0));
1046		if (issb) {
1047			base1 = base + 0x800;	/* OHCI/EHCI */
1048		} else {
1049			/* In AI chips EHCI is addrspace 0, OHCI is 1 */
1050			base1 = base;
1051			if (((CHIPID(sih->chip) == BCM5357_CHIP_ID) ||
1052				(CHIPID(sih->chip) == BCM4749_CHIP_ID)) &&
1053			    CHIPREV(sih->chiprev) == 0)
1054				base = 0x18009000;
1055			else
1056				base = htol32(si_addrspace(sih, 1));
1057		}
1058
1059		i = bar->n = 1;
1060		cfg->base[0] = func == 0 ? base : base1;
1061		bar->size[0] = issb ? 0x800 : 0x1000;
1062	} else {
1063		bar->n = n = si_numaddrspaces(sih);
1064		for (i = 0; i < n; i++) {
1065			int size = si_addrspacesize(sih, i);
1066
1067			if (size) {
1068				cfg->base[i] = htol32(si_addrspace(sih, i));
1069				bar->size[i] = size;
1070			}
1071		}
1072	}
1073	for (; i < PCI_BAR_MAX; i++) {
1074		cfg->base[i] = 0;
1075		bar->size[i] = 0;
1076	}
1077}
1078
1079/**
1080 * Construct PCI config spaces for SB cores to be accessed as if they were PCI devices.
1081 */
1082void __init
1083BCMATTACHFN(hndpci_init_cores)(si_t *sih)
1084{
1085	uint chiprev, coreidx, i;
1086	pci_config_regs *cfg, *pci;
1087	si_bar_cfg_t *bar;
1088	void *regs;
1089	osl_t *osh;
1090	uint16 vendor, device;
1091	uint16 coreid;
1092	uint8 class, subclass, progif;
1093	uint dev;
1094	uint8 header;
1095	uint func;
1096
1097	chiprev = sih->chiprev;
1098	coreidx = si_coreidx(sih);
1099
1100	osh = si_osh(sih);
1101
1102	/* Scan the SI bus */
1103	bzero(si_config_regs, sizeof(si_config_regs));
1104	bzero(si_bar_cfg, sizeof(si_bar_cfg));
1105	bzero(si_pci_cfg, sizeof(si_pci_cfg));
1106	memset(&si_pci_null, -1, sizeof(si_pci_null));
1107	cfg = si_config_regs;
1108	bar = si_bar_cfg;
1109	for (dev = 0; dev < SI_MAXCORES; dev ++) {
1110		/* Check if the core exists */
1111		if (!(regs = si_setcoreidx(sih, dev)))
1112			continue;
1113
1114		/* Check if this core is banned */
1115		coreid = si_coreid(sih);
1116		for (i = 0; i < pci_banned; i++)
1117			if (coreid == pci_ban[i])
1118				break;
1119		if (i < pci_banned)
1120			continue;
1121
1122		if (coreid == USB20H_CORE_ID) {
1123			if (((CHIPID(sih->chip) == BCM5357_CHIP_ID) ||
1124				(CHIPID(sih->chip) == BCM4749_CHIP_ID)) &&
1125				(sih->chippkg == BCM5357_PKG_ID)) {
1126				printf("PCI: skip disabled USB20H\n");
1127				continue;
1128			}
1129		}
1130
1131		if ((CHIPID(sih->chip) == BCM4706_CHIP_ID)) {
1132			if (coreid == GMAC_CORE_ID) {
1133				/* Only GMAC core 0 is used by 4706 */
1134				if (si_coreunit(sih) > 0) {
1135					continue;
1136				}
1137			}
1138		}
1139
1140		for (func = 0; func < MAXFUNCS; ++func) {
1141			/* Make sure we won't go beyond the limit */
1142			if (cfg >= &si_config_regs[SI_MAXCORES]) {
1143				printf("PCI: too many emulated devices\n");
1144				goto done;
1145			}
1146
1147			/* Convert core id to pci id */
1148			if (si_corepciid(sih, func, &vendor, &device, &class, &subclass,
1149			                 &progif, &header))
1150				continue;
1151
1152			/*
1153			 * Differentiate real PCI config from emulated.
1154			 * non zero 'pci' indicate there is a real PCI config space
1155			 * for this device.
1156			 */
1157			switch (device) {
1158			case BCM47XX_GIGETH_ID:
1159				pci = (pci_config_regs *)((uint32)regs + 0x800);
1160				break;
1161			case BCM47XX_SATAXOR_ID:
1162				pci = (pci_config_regs *)((uint32)regs + 0x400);
1163				break;
1164			case BCM47XX_ATA100_ID:
1165				pci = (pci_config_regs *)((uint32)regs + 0x800);
1166				break;
1167			default:
1168				pci = NULL;
1169				break;
1170			}
1171			/* Supported translations */
1172			cfg->vendor = htol16(vendor);
1173			cfg->device = htol16(device);
1174			cfg->rev_id = chiprev;
1175			cfg->prog_if = progif;
1176			cfg->sub_class = subclass;
1177			cfg->base_class = class;
1178			cfg->header_type = header;
1179			hndpci_init_regions(sih, func, cfg, bar);
1180			/* Save core interrupt flag */
1181			cfg->int_pin = si_flag(sih);
1182			/* Save core interrupt assignment */
1183			cfg->int_line = si_irq(sih);
1184			/* Indicate there is no SROM */
1185			*((uint32 *)&cfg->sprom_control) = 0xffffffff;
1186
1187			/* Point to the PCI config spaces */
1188			si_pci_cfg[dev][func].emu = cfg;
1189			si_pci_cfg[dev][func].pci = pci;
1190			si_pci_cfg[dev][func].bar = bar;
1191			cfg ++;
1192			bar ++;
1193		}
1194	}
1195
1196done:
1197	si_setcoreidx(sih, coreidx);
1198}
1199
1200/**
1201 * Initialize PCI core and construct PCI config spaces for SI cores.
1202 * Must propagate hndpci_init_pci() return value to the caller to let
1203 * them know the PCI core initialization status.
1204 */
1205int __init
1206BCMATTACHFN(hndpci_init)(si_t *sih)
1207{
1208	int coreunit, status = 0;
1209
1210	for (coreunit = 0; coreunit < SI_PCI_MAXCORES; coreunit++)
1211		status |= hndpci_init_pci(sih, coreunit);
1212	hndpci_init_cores(sih);
1213	return status;
1214}
1215