1/*	$NetBSD: rmixl_pcie.c,v 1.8 2011/07/10 23:13:22 matt Exp $	*/
2
3/*
4 * Copyright (c) 2001 Wasabi Systems, Inc.
5 * All rights reserved.
6 *
7 * Written by Jason R. Thorpe for Wasabi Systems, Inc.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 *    notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 *    notice, this list of conditions and the following disclaimer in the
16 *    documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 *    must display the following acknowledgement:
19 *	This product includes software developed for the NetBSD Project by
20 *	Wasabi Systems, Inc.
21 * 4. The name of Wasabi Systems, Inc. may not be used to endorse
22 *    or promote products derived from this software without specific prior
23 *    written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
27 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
29 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 * POSSIBILITY OF SUCH DAMAGE.
36 */
37
38/*
39 * PCI configuration support for RMI XLS SoC
40 */
41
42#include <sys/cdefs.h>
43__KERNEL_RCSID(0, "$NetBSD: rmixl_pcie.c,v 1.8 2011/07/10 23:13:22 matt Exp $");
44
45#include "opt_pci.h"
46#include "pci.h"
47
48#include <sys/cdefs.h>
49
50#include <sys/param.h>
51#include <sys/bus.h>
52#include <sys/cpu.h>
53#include <sys/device.h>
54#include <sys/extent.h>
55#include <sys/intr.h>
56#include <sys/kernel.h>		/* for 'hz' */
57#include <sys/malloc.h>
58#include <sys/systm.h>
59
60#include <uvm/uvm_extern.h>
61
62#include <mips/rmi/rmixlreg.h>
63#include <mips/rmi/rmixlvar.h>
64#include <mips/rmi/rmixl_intr.h>
65#include <mips/rmi/rmixl_pcievar.h>
66
67#include <mips/rmi/rmixl_obiovar.h>
68
69#include <dev/pci/pcivar.h>
70#include <dev/pci/pcidevs.h>
71#include <dev/pci/pciconf.h>
72
73#ifdef	PCI_NETBSD_CONFIGURE
74#include <mips/cache.h>
75#endif
76
77#ifdef PCI_DEBUG
78int rmixl_pcie_debug = PCI_DEBUG;
79# define DPRINTF(x)	do { if (rmixl_pcie_debug) printf x ; } while (0)
80#else
81# define DPRINTF(x)
82#endif
83
84#ifndef DDB
85# define STATIC static
86#else
87# define STATIC
88#endif
89
90
91/*
92 * XLS PCIe Extended Configuration Registers
93 */
94#define RMIXL_PCIE_ECFG_UESR	0x104	/* Uncorrectable Error Status Reg */
95#define RMIXL_PCIE_ECFG_UEMR	0x108	/* Uncorrectable Error Mask Reg */
96#define RMIXL_PCIE_ECFG_UEVR	0x10c	/* Uncorrectable Error seVerity Reg */
97#define  PCIE_ECFG_UEVR_DFLT	\
98		(__BITS(18,17) | __BIT(31) | __BITS(5,4) | __BIT(0))
99#define  PCIE_ECFG_UExR_RESV	(__BITS(31,21) | __BITS(11,6) | __BITS(3,1))
100#define RMIXL_PCIE_ECFG_CESR	0x110	/* Correctable Error Status Reg */
101#define RMIXL_PCIE_ECFG_CEMR	0x114	/* Correctable Error Mask Reg */
102#define  PCIE_ECFG_CExR_RESV	(__BITS(31,14) | __BITS(11,9) | __BITS(5,1))
103#define RMIXL_PCIE_ECFG_ACCR	0x118	/* Adv. Capabilities Control Reg */
104#define RMIXL_PCIE_ECFG_HLRn(n)	(0x11c + ((n) * 4))	/* Header Log Regs */
105#define RMIXL_PCIE_ECFG_RECR	0x12c	/* Root Error Command Reg */
106#define  PCIE_ECFG_RECR_RESV	__BITS(31,3)
107#define RMIXL_PCIE_ECFG_RESR	0x130	/* Root Error Status Reg */
108#define  PCIE_ECFG_RESR_RESV	__BITS(26,7)
109#define RMIXL_PCIE_ECFG_ESI	0x134	/* Error Source Identification Reg */
110#define RMIXL_PCIE_ECFG_DSNCR	0x140	/* Dev Serial Number Capability Regs */
111
112static const struct {
113	u_int offset;
114	u_int32_t rw1c;
115} pcie_ecfg_errs_tab[] = {
116	{ RMIXL_PCIE_ECFG_UESR,		(__BITS(20,12) | __BIT(4)) },
117	{ RMIXL_PCIE_ECFG_CESR,		(__BITS(20,12) | __BIT(4)) },
118	{ RMIXL_PCIE_ECFG_HLRn(0),	0 },
119	{ RMIXL_PCIE_ECFG_HLRn(1),	0 },
120	{ RMIXL_PCIE_ECFG_HLRn(2),	0 },
121	{ RMIXL_PCIE_ECFG_HLRn(3),	0 },
122	{ RMIXL_PCIE_ECFG_RESR,		__BITS(6,0) },
123	{ RMIXL_PCIE_ECFG_ESI,		0 },
124};
125#define PCIE_ECFG_ERRS_OFFTAB_NENTRIES \
126	(sizeof(pcie_ecfg_errs_tab)/sizeof(pcie_ecfg_errs_tab[0]))
127
128typedef struct rmixl_pcie_int_csr {
129	uint r0;
130	uint r1;
131} rmixl_pcie_int_csr_t;
132
133static const rmixl_pcie_int_csr_t int_enb_offset[4] = {
134	{ RMIXL_PCIE_LINK0_INT_ENABLE0, RMIXL_PCIE_LINK0_INT_ENABLE1 },
135	{ RMIXL_PCIE_LINK1_INT_ENABLE0, RMIXL_PCIE_LINK1_INT_ENABLE1 },
136	{ RMIXL_PCIE_LINK2_INT_ENABLE0, RMIXL_PCIE_LINK2_INT_ENABLE1 },
137	{ RMIXL_PCIE_LINK3_INT_ENABLE0, RMIXL_PCIE_LINK3_INT_ENABLE1 },
138};
139
140static const rmixl_pcie_int_csr_t int_sts_offset[4] = {
141	{ RMIXL_PCIE_LINK0_INT_STATUS0, RMIXL_PCIE_LINK0_INT_STATUS1 },
142	{ RMIXL_PCIE_LINK1_INT_STATUS0, RMIXL_PCIE_LINK1_INT_STATUS1 },
143	{ RMIXL_PCIE_LINK2_INT_STATUS0, RMIXL_PCIE_LINK2_INT_STATUS1 },
144	{ RMIXL_PCIE_LINK3_INT_STATUS0, RMIXL_PCIE_LINK3_INT_STATUS1 },
145};
146
147static const u_int msi_enb_offset[4] = {
148	RMIXL_PCIE_LINK0_MSI_ENABLE,
149	RMIXL_PCIE_LINK1_MSI_ENABLE,
150	RMIXL_PCIE_LINK2_MSI_ENABLE,
151	RMIXL_PCIE_LINK3_MSI_ENABLE
152};
153
154#define RMIXL_PCIE_LINK_STATUS0_ERRORS	__BITS(6,4)
155#define RMIXL_PCIE_LINK_STATUS1_ERRORS	__BITS(10,0)
156#define RMIXL_PCIE_LINK_STATUS_ERRORS					\
157		((((uint64_t)RMIXL_PCIE_LINK_STATUS1_ERRORS) << 32) |	\
158		   (uint64_t)RMIXL_PCIE_LINK_STATUS0_ERRORS)
159
160#define RMIXL_PCIE_EVCNT(sc, link, bitno, cpu)	\
161		&(sc)->sc_evcnts[link][(bitno) * (ncpu) + (cpu)]
162
163static int	rmixl_pcie_match(device_t, cfdata_t, void *);
164static void	rmixl_pcie_attach(device_t, device_t, void *);
165static void	rmixl_pcie_init(struct rmixl_pcie_softc *);
166static void	rmixl_pcie_init_ecfg(struct rmixl_pcie_softc *);
167static void	rmixl_pcie_attach_hook(struct device *, struct device *,
168		    struct pcibus_attach_args *);
169static void	rmixl_pcie_lnkcfg_4xx(rmixl_pcie_lnktab_t *, uint32_t);
170static void	rmixl_pcie_lnkcfg_408Lite(rmixl_pcie_lnktab_t *, uint32_t);
171static void	rmixl_pcie_lnkcfg_2xx(rmixl_pcie_lnktab_t *, uint32_t);
172static void	rmixl_pcie_lnkcfg_1xx(rmixl_pcie_lnktab_t *, uint32_t);
173static void	rmixl_pcie_lnkcfg(struct rmixl_pcie_softc *);
174static void	rmixl_pcie_intcfg(struct rmixl_pcie_softc *);
175static void	rmixl_pcie_errata(struct rmixl_pcie_softc *);
176static void	rmixl_conf_interrupt(void *, int, int, int, int, int *);
177static int	rmixl_pcie_bus_maxdevs(void *, int);
178static pcitag_t	rmixl_tag_to_ecfg(pcitag_t);
179static pcitag_t	rmixl_pcie_make_tag(void *, int, int, int);
180static void	rmixl_pcie_decompose_tag(void *, pcitag_t, int *, int *, int *);
181void		rmixl_pcie_tag_print(const char *restrict, void *, pcitag_t,				int, vaddr_t, u_long);
182static int	rmixl_pcie_conf_setup(struct rmixl_pcie_softc *,
183			pcitag_t, int *, bus_space_tag_t *,
184			bus_space_handle_t *);
185static pcireg_t	rmixl_pcie_conf_read(void *, pcitag_t, int);
186static void	rmixl_pcie_conf_write(void *, pcitag_t, int, pcireg_t);
187
188static int	rmixl_pcie_intr_map(const struct pci_attach_args *,
189		    pci_intr_handle_t *);
190static const char *
191		rmixl_pcie_intr_string(void *, pci_intr_handle_t);
192static const struct evcnt *
193		rmixl_pcie_intr_evcnt(void *, pci_intr_handle_t);
194static pci_intr_handle_t
195		rmixl_pcie_make_pih(u_int, u_int, u_int);
196static void	rmixl_pcie_decompose_pih(pci_intr_handle_t, u_int *, u_int *, u_int *);
197static void	rmixl_pcie_intr_disestablish(void *, void *);
198static void	*rmixl_pcie_intr_establish(void *, pci_intr_handle_t,
199		    int, int (*)(void *), void *);
200static rmixl_pcie_link_intr_t *
201		rmixl_pcie_lip_add_1(rmixl_pcie_softc_t *, u_int, int, int);
202static void	rmixl_pcie_lip_free_callout(rmixl_pcie_link_intr_t *);
203static void	rmixl_pcie_lip_free(void *);
204static int	rmixl_pcie_intr(void *);
205static void	rmixl_pcie_link_error_intr(u_int, uint32_t, uint32_t);
206#if defined(DEBUG) || defined(DDB)
207int		rmixl_pcie_error_check(void);
208#endif
209static int	_rmixl_pcie_error_check(void *);
210static int	rmixl_pcie_error_intr(void *);
211
212
213#define RMIXL_PCIE_CONCAT3(a,b,c) a ## b ## c
214#define RMIXL_PCIE_BAR_INIT(reg, bar, size, align) {			\
215	struct extent *ext = rmixl_configuration.rc_phys_ex;		\
216	u_long region_start;						\
217	uint64_t ba;							\
218	int err;							\
219									\
220	err = extent_alloc(ext, (size), (align), 0UL, EX_NOWAIT,	\
221		&region_start);						\
222	if (err != 0)							\
223		panic("%s: extent_alloc(%p, %#lx, %#lx, %#lx, %#x, %p)",\
224			__func__, ext, size, align, 0UL, EX_NOWAIT,	\
225			&region_start);					\
226	ba = (uint64_t)region_start;					\
227	ba *= (1024 * 1024);						\
228	bar = RMIXL_PCIE_CONCAT3(RMIXL_PCIE_,reg,_BAR)(ba, 1);		\
229	DPRINTF(("PCIE %s BAR was not enabled by firmware\n"		\
230		"enabling %s at phys %#" PRIxBUSADDR ", size %lu MB\n",	\
231		__STRING(reg), __STRING(reg), ba, size));		\
232	RMIXL_IOREG_WRITE(RMIXL_IO_DEV_BRIDGE + 			\
233		RMIXL_PCIE_CONCAT3(RMIXLS_SBC_PCIE_,reg,_BAR), bar);	\
234	bar = RMIXL_IOREG_READ(RMIXL_IO_DEV_BRIDGE +			\
235		RMIXL_PCIE_CONCAT3(RMIXLS_SBC_PCIE_,reg,_BAR));		\
236	DPRINTF(("%s: %s BAR %#x\n", __func__, __STRING(reg), bar));	\
237}
238
239
240#if defined(DEBUG) || defined(DDB)
241static void *rmixl_pcie_v;
242#endif
243
244CFATTACH_DECL_NEW(rmixl_pcie, sizeof(struct rmixl_pcie_softc),
245    rmixl_pcie_match, rmixl_pcie_attach, NULL, NULL);
246
247static int rmixl_pcie_found;
248
249static int
250rmixl_pcie_match(device_t parent, cfdata_t cf, void *aux)
251{
252	uint32_t r;
253
254	/*
255	 * PCIe interface exists on XLS chips only
256	 */
257	if (! cpu_rmixls(mips_options.mips_cpu))
258		return 0;
259
260	/* XXX
261	 * for now there is only one PCIe Interface on chip
262	 * this could change with furture RMI XL family designs
263	 */
264	if (rmixl_pcie_found)
265		return 0;
266
267	/* read GPIO Reset Configuration register */
268	r = RMIXL_IOREG_READ(RMIXL_IO_DEV_GPIO + RMIXL_GPIO_RESET_CFG);
269	r >>= 26;
270	r &= 3;
271	if (r != 0)
272		return 0;	/* strapped for SRIO */
273
274	return 1;
275}
276
277static void
278rmixl_pcie_attach(device_t parent, device_t self, void *aux)
279{
280	struct rmixl_pcie_softc *sc = device_private(self);
281	struct obio_attach_args *obio = aux;
282	struct rmixl_config *rcp = &rmixl_configuration;
283        struct pcibus_attach_args pba;
284	uint32_t bar;
285
286	rmixl_pcie_found = 1;
287	sc->sc_dev = self;
288
289	aprint_normal(" RMI XLS PCIe Interface\n");
290
291	mutex_init(&sc->sc_mutex, MUTEX_DEFAULT, IPL_HIGH);
292
293	rmixl_pcie_lnkcfg(sc);
294
295	rmixl_pcie_intcfg(sc);
296
297	rmixl_pcie_errata(sc);
298
299	sc->sc_29bit_dmat = obio->obio_29bit_dmat;
300	sc->sc_32bit_dmat = obio->obio_32bit_dmat;
301	sc->sc_64bit_dmat = obio->obio_64bit_dmat;
302
303	sc->sc_tmsk = obio->obio_tmsk;
304
305	/*
306	 * get PCI config space base addr from SBC PCIe CFG BAR
307	 * initialize it if necessary
308 	 */
309	bar = RMIXL_IOREG_READ(RMIXL_IO_DEV_BRIDGE + RMIXLS_SBC_PCIE_CFG_BAR);
310	DPRINTF(("%s: PCIE_CFG_BAR %#x\n", __func__, bar));
311	if ((bar & RMIXL_PCIE_CFG_BAR_ENB) == 0) {
312		u_long n = RMIXL_PCIE_CFG_SIZE / (1024 * 1024);
313		RMIXL_PCIE_BAR_INIT(CFG, bar, n, n);
314	}
315	rcp->rc_pci_cfg_pbase = (bus_addr_t)RMIXL_PCIE_CFG_BAR_TO_BA(bar);
316	rcp->rc_pci_cfg_size  = (bus_size_t)RMIXL_PCIE_CFG_SIZE;
317
318	/*
319	 * get PCIE Extended config space base addr from SBC PCIe ECFG BAR
320	 * initialize it if necessary
321 	 */
322	bar = RMIXL_IOREG_READ(RMIXL_IO_DEV_BRIDGE + RMIXLS_SBC_PCIE_ECFG_BAR);
323	DPRINTF(("%s: PCIE_ECFG_BAR %#x\n", __func__, bar));
324	if ((bar & RMIXL_PCIE_ECFG_BAR_ENB) == 0) {
325		u_long n = RMIXL_PCIE_ECFG_SIZE / (1024 * 1024);
326		RMIXL_PCIE_BAR_INIT(ECFG, bar, n, n);
327	}
328	rcp->rc_pci_ecfg_pbase = (bus_addr_t)RMIXL_PCIE_ECFG_BAR_TO_BA(bar);
329	rcp->rc_pci_ecfg_size  = (bus_size_t)RMIXL_PCIE_ECFG_SIZE;
330
331	/*
332	 * get PCI MEM space base [addr, size] from SBC PCIe MEM BAR
333	 * initialize it if necessary
334 	 */
335	bar = RMIXL_IOREG_READ(RMIXL_IO_DEV_BRIDGE + RMIXLS_SBC_PCIE_MEM_BAR);
336	DPRINTF(("%s: PCIE_MEM_BAR %#x\n", __func__, bar));
337	if ((bar & RMIXL_PCIE_MEM_BAR_ENB) == 0) {
338		u_long n = 256;				/* 256 MB */
339		RMIXL_PCIE_BAR_INIT(MEM, bar, n, n);
340	}
341	rcp->rc_pci_mem_pbase = (bus_addr_t)RMIXL_PCIE_MEM_BAR_TO_BA(bar);
342	rcp->rc_pci_mem_size  = (bus_size_t)RMIXL_PCIE_MEM_BAR_TO_SIZE(bar);
343
344	/*
345	 * get PCI IO space base [addr, size] from SBC PCIe IO BAR
346	 * initialize it if necessary
347 	 */
348	bar = RMIXL_IOREG_READ(RMIXL_IO_DEV_BRIDGE + RMIXLS_SBC_PCIE_IO_BAR);
349	DPRINTF(("%s: PCIE_IO_BAR %#x\n", __func__, bar));
350	if ((bar & RMIXL_PCIE_IO_BAR_ENB) == 0) {
351		u_long n = 32;				/* 32 MB */
352		RMIXL_PCIE_BAR_INIT(IO, bar, n, n);
353	}
354	rcp->rc_pci_io_pbase = (bus_addr_t)RMIXL_PCIE_IO_BAR_TO_BA(bar);
355	rcp->rc_pci_io_size  = (bus_size_t)RMIXL_PCIE_IO_BAR_TO_SIZE(bar);
356
357	/*
358	 * initialize the PCI CFG, ECFG bus space tags
359	 */
360	rmixl_pci_cfg_bus_mem_init(&rcp->rc_pci_cfg_memt, rcp);
361	sc->sc_pci_cfg_memt = &rcp->rc_pci_cfg_memt;
362
363	rmixl_pci_ecfg_bus_mem_init(&rcp->rc_pci_ecfg_memt, rcp);
364	sc->sc_pci_ecfg_memt = &rcp->rc_pci_ecfg_memt;
365
366	/*
367	 * initialize the PCI MEM and IO bus space tags
368	 */
369	rmixl_pci_bus_mem_init(&rcp->rc_pci_memt, rcp);
370	rmixl_pci_bus_io_init(&rcp->rc_pci_iot, rcp);
371
372	/*
373	 * initialize the extended configuration regs
374	 */
375	rmixl_pcie_init_ecfg(sc);
376
377	/*
378	 * initialize the PCI chipset tag
379	 */
380	rmixl_pcie_init(sc);
381
382	/*
383	 * attach the PCI bus
384	 */
385	memset(&pba, 0, sizeof(pba));
386	pba.pba_memt = &rcp->rc_pci_memt;
387	pba.pba_iot =  &rcp->rc_pci_iot;
388	pba.pba_dmat = sc->sc_32bit_dmat;
389	pba.pba_dmat64 = sc->sc_64bit_dmat;
390	pba.pba_pc = &sc->sc_pci_chipset;
391	pba.pba_bus = 0;
392	pba.pba_bridgetag = NULL;
393	pba.pba_intrswiz = 0;
394	pba.pba_intrtag = 0;
395	pba.pba_flags = PCI_FLAGS_IO_OKAY | PCI_FLAGS_MEM_OKAY |
396		PCI_FLAGS_MRL_OKAY | PCI_FLAGS_MRM_OKAY | PCI_FLAGS_MWI_OKAY;
397
398	(void) config_found_ia(self, "pcibus", &pba, pcibusprint);
399}
400
401/*
402 * rmixl_pcie_lnkcfg_4xx - link configs for XLS4xx and XLS6xx
403 *	use IO_AD[11] and IO_AD[10], observable in
404 *	Bits[21:20] of the GPIO Reset Configuration register
405 */
406static void
407rmixl_pcie_lnkcfg_4xx(rmixl_pcie_lnktab_t *ltp, uint32_t grcr)
408{
409	u_int index;
410	static const rmixl_pcie_lnkcfg_t lnktab_4xx[4][4] = {
411		{{ LCFG_EP, 4}, {LCFG_NO, 0}, {LCFG_NO, 0}, {LCFG_NO, 0}},
412		{{ LCFG_RC, 4}, {LCFG_NO, 0}, {LCFG_NO, 0}, {LCFG_NO, 0}},
413		{{ LCFG_EP, 1}, {LCFG_RC, 1}, {LCFG_RC, 1}, {LCFG_RC, 1}},
414		{{ LCFG_RC, 1}, {LCFG_RC, 1}, {LCFG_RC, 1}, {LCFG_RC, 1}},
415	};
416	static const char *lnkstr_4xx[4] = {
417		"1EPx4",
418		"1RCx4",
419		"1EPx1, 3RCx1",
420		"4RCx1"
421	};
422	index = (grcr >> 20) & 3;
423	ltp->ncfgs = 4;
424	ltp->cfg = lnktab_4xx[index];
425	ltp->str = lnkstr_4xx[index];
426}
427
428/*
429 * rmixl_pcie_lnkcfg_408Lite - link configs for XLS408Lite and XLS04A
430 *	use IO_AD[11] and IO_AD[10], observable in
431 *	Bits[21:20] of the GPIO Reset Configuration register
432 */
433static void
434rmixl_pcie_lnkcfg_408Lite(rmixl_pcie_lnktab_t *ltp, uint32_t grcr)
435{
436	u_int index;
437	static const rmixl_pcie_lnkcfg_t lnktab_408Lite[4][2] = {
438		{{ LCFG_EP, 4}, {LCFG_NO, 0}},
439		{{ LCFG_RC, 4}, {LCFG_NO, 0}},
440		{{ LCFG_EP, 1}, {LCFG_RC, 1}},
441		{{ LCFG_RC, 1}, {LCFG_RC, 1}},
442	};
443	static const char *lnkstr_408Lite[4] = {
444		"4EPx4",
445		"1RCx4",
446		"1EPx1, 1RCx1",
447		"2RCx1"
448	};
449
450	index = (grcr >> 20) & 3;
451	ltp->ncfgs = 2;
452	ltp->cfg = lnktab_408Lite[index];
453	ltp->str = lnkstr_408Lite[index];
454}
455
456/*
457 * rmixl_pcie_lnkcfg_2xx - link configs for XLS2xx
458 *	use IO_AD[10], observable in Bit[20] of the
459 *	GPIO Reset Configuration register
460 */
461static void
462rmixl_pcie_lnkcfg_2xx(rmixl_pcie_lnktab_t *ltp, uint32_t grcr)
463{
464	u_int index;
465	static const rmixl_pcie_lnkcfg_t lnktab_2xx[2][4] = {
466		{{ LCFG_EP, 1}, {LCFG_RC, 1}, {LCFG_RC, 1}, {LCFG_RC, 1}},
467		{{ LCFG_RC, 1}, {LCFG_RC, 1}, {LCFG_RC, 1}, {LCFG_RC, 1}}
468	};
469	static const char *lnkstr_2xx[2] = {
470		"1EPx1, 3RCx1",
471		"4RCx1",
472	};
473
474	index = (grcr >> 20) & 1;
475	ltp->ncfgs = 4;
476	ltp->cfg = lnktab_2xx[index];
477	ltp->str = lnkstr_2xx[index];
478}
479
480/*
481 * rmixl_pcie_lnkcfg_1xx - link configs for XLS1xx
482 *	use IO_AD[10], observable in Bit[20] of the
483 *	GPIO Reset Configuration register
484 */
485static void
486rmixl_pcie_lnkcfg_1xx(rmixl_pcie_lnktab_t *ltp, uint32_t grcr)
487{
488	u_int index;
489	static const rmixl_pcie_lnkcfg_t lnktab_1xx[2][2] = {
490		{{ LCFG_EP, 1}, {LCFG_RC, 1}},
491		{{ LCFG_RC, 1}, {LCFG_RC, 1}}
492	};
493	static const char *lnkstr_1xx[2] = {
494		"1EPx1, 1RCx1",
495		"2RCx1",
496	};
497
498	index = (grcr >> 20) & 1;
499	ltp->ncfgs = 2;
500	ltp->cfg = lnktab_1xx[index];
501	ltp->str = lnkstr_1xx[index];
502}
503
504/*
505 * rmixl_pcie_lnkcfg - determine PCI Express Link Configuration
506 */
507static void
508rmixl_pcie_lnkcfg(struct rmixl_pcie_softc *sc)
509{
510	uint32_t r;
511
512	/* read GPIO Reset Configuration register */
513	r = RMIXL_IOREG_READ(RMIXL_IO_DEV_GPIO + RMIXL_GPIO_RESET_CFG);
514	DPRINTF(("%s: GPIO RCR %#x\n", __func__, r));
515
516	switch (MIPS_PRID_IMPL(mips_options.mips_cpu_id)) {
517	case MIPS_XLS104:
518	case MIPS_XLS108:
519		rmixl_pcie_lnkcfg_1xx(&sc->sc_pcie_lnktab, r);
520		break;
521	case MIPS_XLS204:
522	case MIPS_XLS208:
523		rmixl_pcie_lnkcfg_2xx(&sc->sc_pcie_lnktab, r);
524		break;
525	case MIPS_XLS404LITE:
526	case MIPS_XLS408LITE:
527		rmixl_pcie_lnkcfg_408Lite(&sc->sc_pcie_lnktab, r);
528		break;
529	case MIPS_XLS404:
530	case MIPS_XLS408:
531	case MIPS_XLS416:
532	case MIPS_XLS608:
533	case MIPS_XLS616:
534		/* 6xx uses same table as 4xx */
535		rmixl_pcie_lnkcfg_4xx(&sc->sc_pcie_lnktab, r);
536		break;
537	default:
538		panic("%s: unknown RMI PRID IMPL", __func__);
539	}
540
541	aprint_normal("%s: link config %s\n",
542		device_xname(sc->sc_dev), sc->sc_pcie_lnktab.str);
543}
544
545/*
546 * rmixl_pcie_intcfg - init PCIe Link interrupt enables
547 */
548static void
549rmixl_pcie_intcfg(struct rmixl_pcie_softc *sc)
550{
551	int link;
552	size_t size;
553	rmixl_pcie_evcnt_t *ev;
554
555	DPRINTF(("%s: disable all link interrupts\n", __func__));
556	for (link=0; link < sc->sc_pcie_lnktab.ncfgs; link++) {
557		RMIXL_IOREG_WRITE(RMIXL_IO_DEV_PCIE_LE + int_enb_offset[link].r0,
558			RMIXL_PCIE_LINK_STATUS0_ERRORS);
559		RMIXL_IOREG_WRITE(RMIXL_IO_DEV_PCIE_LE + int_enb_offset[link].r1,
560			RMIXL_PCIE_LINK_STATUS1_ERRORS);
561		RMIXL_IOREG_WRITE(RMIXL_IO_DEV_PCIE_LE + msi_enb_offset[link], 0);
562		sc->sc_link_intr[link] = NULL;
563
564		/*
565		 * allocate per-cpu, per-pin interrupt event counters
566		 */
567		size = ncpu * PCI_INTERRUPT_PIN_MAX * sizeof(rmixl_pcie_evcnt_t);
568		ev = malloc(size, M_DEVBUF, M_NOWAIT);
569		if (ev == NULL)
570			panic("%s: cannot malloc evcnts\n", __func__);
571		sc->sc_evcnts[link] = ev;
572		for (int pin=PCI_INTERRUPT_PIN_A; pin <= PCI_INTERRUPT_PIN_MAX; pin++) {
573			for (int cpu=0; cpu < ncpu; cpu++) {
574				ev = RMIXL_PCIE_EVCNT(sc, link, pin - 1, cpu);
575				snprintf(ev->name, sizeof(ev->name),
576					"cpu%d, link %d, pin %d", cpu, link, pin);
577				evcnt_attach_dynamic(&ev->evcnt, EVCNT_TYPE_INTR,
578					NULL, "rmixl_pcie", ev->name);
579			}
580		}
581	}
582}
583
584static void
585rmixl_pcie_errata(struct rmixl_pcie_softc *sc)
586{
587	const mips_prid_t cpu_id = mips_options.mips_cpu_id;
588	u_int rev;
589	u_int lanes;
590	bool e391 = false;
591
592	/*
593	 * 3.9.1 PCIe Link-0 Registers Reset to Incorrect Values
594	 * check if it allies to this CPU implementation and revision
595	 */
596	rev = MIPS_PRID_REV(cpu_id);
597	switch (MIPS_PRID_IMPL(cpu_id)) {
598	case MIPS_XLS104:
599	case MIPS_XLS108:
600		break;
601	case MIPS_XLS204:
602	case MIPS_XLS208:
603		/* stepping A0 is affected */
604		if (rev == 0)
605			e391 = true;
606		break;
607	case MIPS_XLS404LITE:
608	case MIPS_XLS408LITE:
609		break;
610	case MIPS_XLS404:
611	case MIPS_XLS408:
612	case MIPS_XLS416:
613		/* steppings A0 and A1 are affected */
614		if ((rev == 0) || (rev == 1))
615			e391 = true;
616		break;
617	case MIPS_XLS608:
618	case MIPS_XLS616:
619		break;
620	default:
621		panic("unknown RMI PRID IMPL");
622        }
623
624	/*
625	 * for XLS we only need to check entry #0
626	 * this may need to change for later XL family chips
627	 */
628	lanes = sc->sc_pcie_lnktab.cfg[0].lanes;
629
630	if ((e391 != false) && ((lanes == 2) || (lanes == 4))) {
631		/*
632		 * attempt work around for errata 3.9.1
633		 * "PCIe Link-0 Registers Reset to Incorrect Values"
634		 * the registers are write-once: if the firmware already wrote,
635		 * then our writes are ignored;  hope they did it right.
636		 */
637		uint32_t queuectrl;
638		uint32_t bufdepth;
639#ifdef DIAGNOSTIC
640		uint32_t r;
641#endif
642
643		aprint_normal("%s: attempt work around for errata 3.9.1",
644			device_xname(sc->sc_dev));
645		if (lanes == 4) {
646			queuectrl = 0x00018074;
647			bufdepth  = 0x001901D1;
648		} else {
649			queuectrl = 0x00018036;
650			bufdepth  = 0x001900D9;
651		}
652
653		RMIXL_IOREG_WRITE(RMIXL_IO_DEV_PCIE_BE +
654			RMIXL_VC0_POSTED_RX_QUEUE_CTRL, queuectrl);
655		RMIXL_IOREG_WRITE(RMIXL_IO_DEV_PCIE_BE +
656			RMIXL_VC0_POSTED_BUFFER_DEPTH, bufdepth);
657
658#ifdef DIAGNOSTIC
659		r = RMIXL_IOREG_READ(RMIXL_IO_DEV_PCIE_BE +
660			RMIXL_VC0_POSTED_RX_QUEUE_CTRL);
661		printf("\nVC0_POSTED_RX_QUEUE_CTRL %#x\n", r);
662
663		r = RMIXL_IOREG_READ(RMIXL_IO_DEV_PCIE_BE +
664			RMIXL_VC0_POSTED_BUFFER_DEPTH);
665		printf("VC0_POSTED_BUFFER_DEPTH %#x\n", r);
666#endif
667	}
668}
669
670static void
671rmixl_pcie_init(struct rmixl_pcie_softc *sc)
672{
673	pci_chipset_tag_t pc = &sc->sc_pci_chipset;
674#if NPCI > 0 && defined(PCI_NETBSD_CONFIGURE)
675	struct extent *ioext, *memext;
676#endif
677
678	pc->pc_conf_v = (void *)sc;
679	pc->pc_attach_hook = rmixl_pcie_attach_hook;
680	pc->pc_bus_maxdevs = rmixl_pcie_bus_maxdevs;
681	pc->pc_make_tag = rmixl_pcie_make_tag;
682	pc->pc_decompose_tag = rmixl_pcie_decompose_tag;
683	pc->pc_conf_read = rmixl_pcie_conf_read;
684	pc->pc_conf_write = rmixl_pcie_conf_write;
685
686	pc->pc_intr_v = (void *)sc;
687	pc->pc_intr_map = rmixl_pcie_intr_map;
688	pc->pc_intr_string = rmixl_pcie_intr_string;
689	pc->pc_intr_evcnt = rmixl_pcie_intr_evcnt;
690	pc->pc_intr_establish = rmixl_pcie_intr_establish;
691	pc->pc_intr_disestablish = rmixl_pcie_intr_disestablish;
692	pc->pc_conf_interrupt = rmixl_conf_interrupt;
693
694#if NPCI > 0 && defined(PCI_NETBSD_CONFIGURE)
695	/*
696	 * Configure the PCI bus.
697	 */
698	struct rmixl_config *rcp = &rmixl_configuration;
699
700	aprint_normal("%s: configuring PCI bus\n",
701		device_xname(sc->sc_dev));
702
703	ioext  = extent_create("pciio",
704		rcp->rc_pci_io_pbase,
705		rcp->rc_pci_io_pbase + rcp->rc_pci_io_size - 1,
706		NULL, 0, EX_NOWAIT);
707
708	memext = extent_create("pcimem",
709		rcp->rc_pci_mem_pbase,
710		rcp->rc_pci_mem_pbase + rcp->rc_pci_mem_size - 1,
711		NULL, 0, EX_NOWAIT);
712
713	pci_configure_bus(pc, ioext, memext, NULL, 0,
714	    mips_cache_info.mci_dcache_align);
715
716	extent_destroy(ioext);
717	extent_destroy(memext);
718#endif
719}
720
721static void
722rmixl_pcie_init_ecfg(struct rmixl_pcie_softc *sc)
723{
724	void *v;
725	pcitag_t tag;
726	pcireg_t r;
727
728	v = sc;
729	tag = rmixl_pcie_make_tag(v, 0, 0, 0);
730
731#ifdef PCI_DEBUG
732	int i, offset;
733	static const int offtab[] =
734		{ 0, 4, 8, 0xc, 0x10, 0x14, 0x18, 0x1c,
735		  0x2c, 0x30, 0x34 };
736	for (i=0; i < sizeof(offtab)/sizeof(offtab[0]); i++) {
737		offset = 0x100 + offtab[i];
738		r = rmixl_pcie_conf_read(v, tag, offset);
739		printf("%s: %#x: %#x\n", __func__, offset, r);
740	}
741#endif
742	r = rmixl_pcie_conf_read(v, tag, 0x100);
743	if (r == -1)
744		return;	/* cannot access */
745
746	/* check pre-existing uncorrectable errs */
747	r = rmixl_pcie_conf_read(v, tag, RMIXL_PCIE_ECFG_UESR);
748	r &= ~PCIE_ECFG_UExR_RESV;
749	if (r != 0)
750		panic("%s: Uncorrectable Error Status: %#x\n",
751			__func__, r);
752
753	/* unmask all uncorrectable errs */
754	r = rmixl_pcie_conf_read(v, tag, RMIXL_PCIE_ECFG_UEMR);
755	r &= ~PCIE_ECFG_UExR_RESV;
756	rmixl_pcie_conf_write(v, tag, RMIXL_PCIE_ECFG_UEMR, r);
757
758	/* ensure default uncorrectable err severity confniguration */
759	r = rmixl_pcie_conf_read(v, tag, RMIXL_PCIE_ECFG_UEVR);
760	r &= ~PCIE_ECFG_UExR_RESV;
761	r |= PCIE_ECFG_UEVR_DFLT;
762	rmixl_pcie_conf_write(v, tag, RMIXL_PCIE_ECFG_UEVR, r);
763
764	/* check pre-existing correctable errs */
765	r = rmixl_pcie_conf_read(v, tag, RMIXL_PCIE_ECFG_CESR);
766	r &= ~PCIE_ECFG_CExR_RESV;
767#ifdef DIAGNOSTIC
768	if (r != 0)
769		aprint_normal("%s: Correctable Error Status: %#x\n",
770			device_xname(sc->sc_dev), r);
771#endif
772
773	/* unmask all correctable errs */
774	r = rmixl_pcie_conf_read(v, tag, RMIXL_PCIE_ECFG_CEMR);
775	r &= ~PCIE_ECFG_CExR_RESV;
776	rmixl_pcie_conf_write(v, tag, RMIXL_PCIE_ECFG_UEMR, r);
777
778	/* check pre-existing Root Error Status */
779	r = rmixl_pcie_conf_read(v, tag, RMIXL_PCIE_ECFG_RESR);
780	r &= ~PCIE_ECFG_RESR_RESV;
781	if (r != 0)
782		panic("%s: Root Error Status: %#x\n", __func__, r);
783			/* XXX TMP FIXME */
784
785	/* enable all Root errs */
786	r = (pcireg_t)(~PCIE_ECFG_RECR_RESV);
787	rmixl_pcie_conf_write(v, tag, RMIXL_PCIE_ECFG_RECR, r);
788
789	/*
790	 * establish ISR for PCIE Fatal Error interrupt
791	 * - for XLS4xxLite, XLS2xx, XLS1xx only
792	 */
793	switch (MIPS_PRID_IMPL(mips_options.mips_cpu_id)) {
794	case MIPS_XLS104:
795	case MIPS_XLS108:
796	case MIPS_XLS204:
797	case MIPS_XLS208:
798	case MIPS_XLS404LITE:
799	case MIPS_XLS408LITE:
800		sc->sc_fatal_ih = rmixl_intr_establish(29, sc->sc_tmsk,
801			IPL_HIGH, RMIXL_TRIG_LEVEL, RMIXL_POLR_HIGH,
802			rmixl_pcie_error_intr, v, false);
803		break;
804	default:
805		break;
806	}
807
808#if defined(DEBUG) || defined(DDB)
809	rmixl_pcie_v = v;
810#endif
811}
812
813void
814rmixl_conf_interrupt(void *v, int bus, int dev, int ipin, int swiz, int *iline)
815{
816	DPRINTF(("%s: %p, %d, %d, %d, %d, %p\n",
817		__func__, v, bus, dev, ipin, swiz, iline));
818}
819
820void
821rmixl_pcie_attach_hook(struct device *parent, struct device *self,
822	struct pcibus_attach_args *pba)
823{
824	DPRINTF(("%s: pba_bus %d, pba_bridgetag %p, pc_conf_v %p\n",
825		__func__, pba->pba_bus, pba->pba_bridgetag,
826		pba->pba_pc->pc_conf_v));
827}
828
829int
830rmixl_pcie_bus_maxdevs(void *v, int busno)
831{
832	return (32);	/* XXX depends on the family of XLS SoC */
833}
834
835/*
836 * rmixl_tag_to_ecfg - convert cfg address (generic tag) to ecfg address
837 *
838 *	39:29   (reserved)
839 *	28      Swap (0=little, 1=big endian)
840 *	27:20   Bus number
841 *	19:15   Device number
842 *	14:12   Function number
843 *	11:8    Extended Register number
844 *	7:0     Register number
845 */
846static pcitag_t
847rmixl_tag_to_ecfg(pcitag_t tag)
848{
849	KASSERT((tag & __BITS(7,0)) == 0);
850	return (tag << 4);
851}
852
853/*
854 * XLS pci tag is a 40 bit address composed thusly:
855 *	39:25   (reserved)
856 *	24      Swap (0=little, 1=big endian)
857 *	23:16   Bus number
858 *	15:11   Device number
859 *	10:8    Function number
860 *	7:0     Register number
861 *
862 * Note: this is the "native" composition for addressing CFG space, but not for ECFG space.
863 */
864pcitag_t
865rmixl_pcie_make_tag(void *v, int bus, int dev, int fun)
866{
867	return ((bus << 16) | (dev << 11) | (fun << 8));
868}
869
870void
871rmixl_pcie_decompose_tag(void *v, pcitag_t tag, int *bp, int *dp, int *fp)
872{
873	if (bp != NULL)
874		*bp = (tag >> 16) & 0xff;
875	if (dp != NULL)
876		*dp = (tag >> 11) & 0x1f;
877	if (fp != NULL)
878		*fp = (tag >> 8) & 0x7;
879}
880
881void
882rmixl_pcie_tag_print(const char *restrict s, void *v, pcitag_t tag, int offset,
883	vaddr_t va, u_long r)
884{
885	int bus, dev, fun;
886
887	rmixl_pcie_decompose_tag(v, tag, &bus, &dev, &fun);
888	printf("%s: %d/%d/%d/%d - %#" PRIxVADDR ":%#lx\n",
889		s, bus, dev, fun, offset, va, r);
890}
891
892static int
893rmixl_pcie_conf_setup(struct rmixl_pcie_softc *sc,
894	pcitag_t tag, int *offp, bus_space_tag_t *bstp,
895	bus_space_handle_t *bshp)
896{
897	struct rmixl_config *rcp = &rmixl_configuration;
898	bus_space_tag_t bst;
899	bus_space_handle_t bsh;
900	bus_size_t size;
901	pcitag_t mask;
902	bus_addr_t ba;
903	int err;
904	static bus_space_handle_t cfg_bsh;
905	static bus_addr_t cfg_oba = -1;
906	static bus_space_handle_t ecfg_bsh;
907	static bus_addr_t ecfg_oba = -1;
908
909	/*
910	 * bus space depends on offset
911	 */
912	if ((*offp >= 0) && (*offp < 0x100)) {
913		mask = __BITS(15,0);
914		bst = sc->sc_pci_cfg_memt;
915		ba = rcp->rc_pci_cfg_pbase;
916		ba += (tag & ~mask);
917		*offp += (tag & mask);
918		if (ba != cfg_oba) {
919			size = (bus_size_t)(mask + 1);
920			if (cfg_oba != -1)
921				bus_space_unmap(bst, cfg_bsh, size);
922			err = bus_space_map(bst, ba, size, 0, &cfg_bsh);
923			if (err != 0) {
924#ifdef DEBUG
925				panic("%s: bus_space_map err %d, CFG space",
926					__func__, err);	/* XXX */
927#endif
928				return -1;
929			}
930			cfg_oba = ba;
931		}
932		bsh = cfg_bsh;
933	} else if ((*offp >= 0x100) && (*offp <= 0x700)) {
934		mask = __BITS(14,0);
935		tag = rmixl_tag_to_ecfg(tag);	/* convert to ECFG format */
936		bst = sc->sc_pci_ecfg_memt;
937		ba = rcp->rc_pci_ecfg_pbase;
938		ba += (tag & ~mask);
939		*offp += (tag & mask);
940		if (ba != ecfg_oba) {
941			size = (bus_size_t)(mask + 1);
942			if (ecfg_oba != -1)
943				bus_space_unmap(bst, ecfg_bsh, size);
944			err = bus_space_map(bst, ba, size, 0, &ecfg_bsh);
945			if (err != 0) {
946#ifdef DEBUG
947				panic("%s: bus_space_map err %d, ECFG space",
948					__func__, err);	/* XXX */
949#endif
950				return -1;
951			}
952			ecfg_oba = ba;
953		}
954		bsh = ecfg_bsh;
955	} else  {
956#ifdef DEBUG
957		panic("%s: offset %#x: unknown", __func__, *offp);
958#endif
959		return -1;
960	}
961
962	*bstp = bst;
963	*bshp = bsh;
964
965	return 0;
966}
967
968pcireg_t
969rmixl_pcie_conf_read(void *v, pcitag_t tag, int offset)
970{
971	struct rmixl_pcie_softc *sc = v;
972	static bus_space_handle_t bsh;
973	bus_space_tag_t bst;
974	pcireg_t rv;
975	uint64_t cfg0;
976
977	mutex_enter(&sc->sc_mutex);
978
979	if (rmixl_pcie_conf_setup(sc, tag, &offset, &bst, &bsh) == 0) {
980		cfg0 = rmixl_cache_err_dis();
981		rv = bus_space_read_4(bst, bsh, (bus_size_t)offset);
982		if (rmixl_cache_err_check() != 0) {
983#ifdef DIAGNOSTIC
984			int bus, dev, fun;
985
986			rmixl_pcie_decompose_tag(v, tag, &bus, &dev, &fun);
987			printf("%s: %d/%d/%d, offset %#x: bad address\n",
988				__func__, bus, dev, fun, offset);
989#endif
990			rv = (pcireg_t) -1;
991		}
992		rmixl_cache_err_restore(cfg0);
993	} else {
994		rv = -1;
995	}
996
997	mutex_exit(&sc->sc_mutex);
998
999	return rv;
1000}
1001
1002void
1003rmixl_pcie_conf_write(void *v, pcitag_t tag, int offset, pcireg_t val)
1004{
1005	struct rmixl_pcie_softc *sc = v;
1006	static bus_space_handle_t bsh;
1007	bus_space_tag_t bst;
1008	uint64_t cfg0;
1009
1010	mutex_enter(&sc->sc_mutex);
1011
1012	if (rmixl_pcie_conf_setup(sc, tag, &offset, &bst, &bsh) == 0) {
1013		cfg0 = rmixl_cache_err_dis();
1014		bus_space_write_4(bst, bsh, (bus_size_t)offset, val);
1015		if (rmixl_cache_err_check() != 0) {
1016#ifdef DIAGNOSTIC
1017			int bus, dev, fun;
1018
1019			rmixl_pcie_decompose_tag(v, tag, &bus, &dev, &fun);
1020			printf("%s: %d/%d/%d, offset %#x: bad address\n",
1021				__func__, bus, dev, fun, offset);
1022#endif
1023		}
1024		rmixl_cache_err_restore(cfg0);
1025	}
1026
1027	mutex_exit(&sc->sc_mutex);
1028}
1029
1030int
1031rmixl_pcie_intr_map(const struct pci_attach_args *pa, pci_intr_handle_t *pih)
1032{
1033	int device;
1034	u_int link;
1035	u_int irq;
1036
1037	/*
1038	 * The bus is unimportant since it can change depending on the
1039	 * configuration.  We are tied to device # of PCIe bridge we are
1040	 * ultimately attached to.
1041	 */
1042	pci_decompose_tag(pa->pa_pc, pa->pa_intrtag,
1043	    NULL, &device, NULL);
1044
1045#ifdef DEBUG
1046	DPRINTF(("%s: ps_bus %d, pa_intrswiz %#x, pa_intrtag %#lx,"
1047		" pa_intrpin %d,  pa_intrline %d, pa_rawintrpin %d\n",
1048		__func__, pa->pa_bus, pa->pa_intrswiz, pa->pa_intrtag,
1049		pa->pa_intrpin, pa->pa_intrline, pa->pa_rawintrpin));
1050#endif
1051
1052	/*
1053	 * PCIe Link INT irq assignment is cpu implementation specific
1054	 */
1055	switch (MIPS_PRID_IMPL(mips_options.mips_cpu_id)) {
1056	case MIPS_XLS104:
1057	case MIPS_XLS108:
1058	case MIPS_XLS404LITE:
1059	case MIPS_XLS408LITE:
1060		if (device > 1)
1061			panic("%s: bad bus %d", __func__, device);
1062		link = device;
1063		irq = device + 26;
1064		break;
1065	case MIPS_XLS204:
1066	case MIPS_XLS208: {
1067		if (device > 3)
1068			panic("%s: bad bus %d", __func__, device);
1069		link = device;
1070		irq = device + (device & 2 ? 21 : 26);
1071		break;
1072	}
1073	case MIPS_XLS404:
1074	case MIPS_XLS408:
1075	case MIPS_XLS416:
1076	case MIPS_XLS608:
1077	case MIPS_XLS616:
1078		if (device > 3)
1079			panic("%s: bad bus %d", __func__, device);
1080		link = device;
1081		irq = device + 26;
1082		break;
1083	default:
1084		panic("%s: cpu IMPL %#x not supported\n",
1085		    __func__, MIPS_PRID_IMPL(mips_options.mips_cpu_id));
1086	}
1087
1088	if (pa->pa_intrpin != PCI_INTERRUPT_PIN_NONE)
1089		*pih = rmixl_pcie_make_pih(link, pa->pa_intrpin - 1, irq);
1090	else
1091		*pih = ~0;
1092
1093	return 0;
1094}
1095
1096const char *
1097rmixl_pcie_intr_string(void *v, pci_intr_handle_t pih)
1098{
1099	const char *name = "(illegal)";
1100	u_int link, bitno, irq;
1101
1102	rmixl_pcie_decompose_pih(pih, &link, &bitno, &irq);
1103
1104	switch (MIPS_PRID_IMPL(mips_options.mips_cpu_id)) {
1105	case MIPS_XLS104:
1106	case MIPS_XLS108:
1107	case MIPS_XLS404LITE:
1108	case MIPS_XLS408LITE:
1109		switch (irq) {
1110		case 26:
1111		case 27:
1112			name = rmixl_intr_string(RMIXL_IRT_VECTOR(irq));
1113			break;
1114		}
1115		break;
1116	case MIPS_XLS204:
1117	case MIPS_XLS208:
1118		switch (irq) {
1119		case 23:
1120		case 24:
1121		case 26:
1122		case 27:
1123			name = rmixl_intr_string(RMIXL_IRT_VECTOR(irq));
1124			break;
1125		}
1126		break;
1127	case MIPS_XLS404:
1128	case MIPS_XLS408:
1129	case MIPS_XLS416:
1130	case MIPS_XLS608:
1131	case MIPS_XLS616:
1132		switch (irq) {
1133		case 26:
1134		case 27:
1135		case 28:
1136		case 29:
1137			name = rmixl_intr_string(RMIXL_IRT_VECTOR(irq));
1138			break;
1139		}
1140		break;
1141	default:
1142		panic("%s: cpu IMPL %#x not supported\n",
1143			__func__, MIPS_PRID_IMPL(mips_options.mips_cpu_id));
1144	}
1145
1146	return name;
1147}
1148
1149const struct evcnt *
1150rmixl_pcie_intr_evcnt(void *v, pci_intr_handle_t pih)
1151{
1152	return NULL;
1153}
1154
1155static pci_intr_handle_t
1156rmixl_pcie_make_pih(u_int link, u_int bitno, u_int irq)
1157{
1158	pci_intr_handle_t pih;
1159
1160	KASSERT(link < RMIXL_PCIE_NLINKS_MAX);
1161	KASSERT(bitno < 64);
1162	KASSERT(irq < 32);
1163
1164	pih  = (irq << 10);
1165	pih |= (bitno << 4);
1166	pih |= link;
1167
1168	return pih;
1169}
1170
1171static void
1172rmixl_pcie_decompose_pih(pci_intr_handle_t pih, u_int *link, u_int *bitno, u_int *irq)
1173{
1174	*link = (u_int)(pih & 0xf);
1175	*bitno = (u_int)((pih >> 4) & 0x3f);
1176	*irq  = (u_int)(pih >> 10);
1177
1178	KASSERT(*link < RMIXL_PCIE_NLINKS_MAX);
1179	KASSERT(*bitno < 64);
1180	KASSERT(*irq < 32);
1181}
1182
1183static void
1184rmixl_pcie_intr_disestablish(void *v, void *ih)
1185{
1186	rmixl_pcie_softc_t *sc = v;
1187	rmixl_pcie_link_dispatch_t *dip = ih;
1188	rmixl_pcie_link_intr_t *lip = sc->sc_link_intr[dip->link];
1189	uint32_t r;
1190	uint32_t bit;
1191	u_int offset;
1192	u_int other;
1193	bool busy;
1194
1195	DPRINTF(("%s: link=%d pin=%d irq=%d\n",
1196		__func__, dip->link, dip->bitno + 1, dip->irq));
1197
1198	mutex_enter(&sc->sc_mutex);
1199
1200	dip->func = NULL;	/* mark unused, prevent further dispatch */
1201
1202	/*
1203	 * if no other dispatch handle is using this interrupt,
1204	 * we can disable it
1205	 */
1206	busy = false;
1207	for (int i=0; i < lip->dispatch_count; i++) {
1208		rmixl_pcie_link_dispatch_t *d = &lip->dispatch_data[i];
1209		if (d == dip)
1210			continue;
1211		if (d->bitno == dip->bitno) {
1212			busy = true;
1213			break;
1214		}
1215	}
1216	if (! busy) {
1217		if (dip->bitno < 32) {
1218			bit = 1 << dip->bitno;
1219			offset = int_enb_offset[dip->link].r0;
1220			other  = int_enb_offset[dip->link].r1;
1221		} else {
1222			bit = 1 << (dip->bitno - 32);
1223			offset = int_enb_offset[dip->link].r1;
1224			other  = int_enb_offset[dip->link].r0;
1225		}
1226
1227		/* disable this interrupt in the PCIe bridge */
1228		r = RMIXL_IOREG_READ(RMIXL_IO_DEV_PCIE_LE + offset);
1229		r &= ~bit;
1230		RMIXL_IOREG_WRITE(RMIXL_IO_DEV_PCIE_LE + offset, r);
1231
1232		/*
1233		 * if both ENABLE0 and ENABLE1 are 0
1234		 * disable the link interrupt
1235		 */
1236		if (r == 0) {
1237			/* check the other reg */
1238			if (RMIXL_IOREG_READ(RMIXL_IO_DEV_PCIE_LE + other) == 0) {
1239				DPRINTF(("%s: disable link %d\n", __func__, lip->link));
1240
1241				/* tear down interrupt on this link */
1242				rmixl_intr_disestablish(lip->ih);
1243
1244				/* commit NULL interrupt set */
1245				sc->sc_link_intr[dip->link] = NULL;
1246
1247				/* schedule delayed free of the old link interrupt set */
1248				rmixl_pcie_lip_free_callout(lip);
1249			}
1250		}
1251	}
1252
1253	mutex_exit(&sc->sc_mutex);
1254}
1255
1256static void *
1257rmixl_pcie_intr_establish(void *v, pci_intr_handle_t pih, int ipl,
1258        int (*func)(void *), void *arg)
1259{
1260	rmixl_pcie_softc_t *sc = v;
1261	u_int link, bitno, irq;
1262	uint32_t r;
1263	rmixl_pcie_link_intr_t *lip;
1264	rmixl_pcie_link_dispatch_t *dip = NULL;
1265	uint32_t bit;
1266	u_int offset;
1267
1268	if (pih == ~0) {
1269		DPRINTF(("%s: bad pih=%#lx, implies PCI_INTERRUPT_PIN_NONE\n",
1270			__func__, pih));
1271		return NULL;
1272	}
1273
1274	rmixl_pcie_decompose_pih(pih, &link, &bitno, &irq);
1275	DPRINTF(("%s: link=%d pin=%d irq=%d\n",
1276		__func__, link, bitno + 1, irq));
1277
1278	mutex_enter(&sc->sc_mutex);
1279
1280	lip = rmixl_pcie_lip_add_1(sc, link, irq, ipl);
1281	if (lip == NULL)
1282		return NULL;
1283
1284	/*
1285	 * initializae our new interrupt, the last element in dispatch_data[]
1286	 */
1287	dip = &lip->dispatch_data[lip->dispatch_count - 1];
1288	dip->link = link;
1289	dip->bitno = bitno;
1290	dip->irq = irq;
1291	dip->func = func;
1292	dip->arg = arg;
1293	dip->counts = RMIXL_PCIE_EVCNT(sc, link, bitno, 0);
1294
1295	if (bitno < 32) {
1296		offset = int_enb_offset[link].r0;
1297		bit = 1 << bitno;
1298	} else {
1299		offset = int_enb_offset[link].r1;
1300		bit = 1 << (bitno - 32);
1301	}
1302
1303	/* commit the new link interrupt set */
1304	sc->sc_link_intr[link] = lip;
1305
1306	/* enable this interrupt in the PCIe bridge */
1307	r = RMIXL_IOREG_READ(RMIXL_IO_DEV_PCIE_LE + offset);
1308	r |= bit;
1309	RMIXL_IOREG_WRITE(RMIXL_IO_DEV_PCIE_LE + offset, r);
1310
1311	mutex_exit(&sc->sc_mutex);
1312	return dip;
1313}
1314
1315rmixl_pcie_link_intr_t *
1316rmixl_pcie_lip_add_1(rmixl_pcie_softc_t *sc, u_int link, int irq, int ipl)
1317{
1318	rmixl_pcie_link_intr_t *lip_old = sc->sc_link_intr[link];
1319	rmixl_pcie_link_intr_t *lip_new;
1320	u_int dispatch_count;
1321	size_t size;
1322
1323	dispatch_count = 1;
1324	size = sizeof(rmixl_pcie_link_intr_t);
1325	if (lip_old != NULL) {
1326		/*
1327		 * count only those dispatch elements still in use
1328		 * unused ones will be pruned during copy
1329		 * i.e. we are "lazy" there is no rmixl_pcie_lip_sub_1
1330                 */
1331		for (int i=0; i < lip_old->dispatch_count; i++) {
1332			if (lip_old->dispatch_data[i].func != NULL) {
1333				dispatch_count++;
1334				size += sizeof(rmixl_pcie_link_intr_t);
1335			}
1336		}
1337	}
1338
1339	/*
1340	 * allocate and initialize link intr struct
1341	 * with one or more dispatch handles
1342	 */
1343	lip_new = malloc(size, M_DEVBUF, M_NOWAIT);
1344	if (lip_new == NULL) {
1345#ifdef DIAGNOSTIC
1346		printf("%s: cannot malloc\n", __func__);
1347#endif
1348		return NULL;
1349	}
1350
1351	if (lip_old == NULL) {
1352		/* initialize the link interrupt struct */
1353		lip_new->sc = sc;
1354		lip_new->link = link;
1355		lip_new->ipl = ipl;
1356		lip_new->ih = rmixl_intr_establish(irq, sc->sc_tmsk,
1357			ipl, RMIXL_TRIG_LEVEL, RMIXL_POLR_HIGH,
1358			rmixl_pcie_intr, lip_new, false);
1359		if (lip_new->ih == NULL)
1360			panic("%s: cannot establish irq %d", __func__, irq);
1361	} else {
1362		/*
1363		 * all intrs on a link get same ipl and sc
1364		 * first intr established sets the standard
1365		 */
1366		KASSERT(sc == lip_old->sc);
1367		if (sc != lip_old->sc) {
1368			printf("%s: sc %p mismatch\n", __func__, sc);
1369			free(lip_new, M_DEVBUF);
1370			return NULL;
1371		}
1372		KASSERT (ipl == lip_old->ipl);
1373		if (ipl != lip_old->ipl) {
1374			printf("%s: ipl %d mismatch\n", __func__, ipl);
1375			free(lip_new, M_DEVBUF);
1376			return NULL;
1377		}
1378		/*
1379		 * copy lip_old to lip_new, skipping unused dispatch elemets
1380		 */
1381		memcpy(lip_new, lip_old, sizeof(rmixl_pcie_link_intr_t));
1382		for (int j=0, i=0; i < lip_old->dispatch_count; i++) {
1383			if (lip_old->dispatch_data[i].func != NULL) {
1384				memcpy(&lip_new->dispatch_data[j],
1385					&lip_old->dispatch_data[i],
1386					sizeof(rmixl_pcie_link_dispatch_t));
1387				j++;
1388			}
1389		}
1390
1391		/*
1392		 * schedule delayed free of old link interrupt set
1393		 */
1394		rmixl_pcie_lip_free_callout(lip_old);
1395	}
1396	lip_new->dispatch_count = dispatch_count;
1397
1398	return lip_new;
1399}
1400
1401/*
1402 * delay free of the old link interrupt set
1403 * to allow anyone still using it to do so safely
1404 * XXX 2 seconds should be plenty?
1405 */
1406static void
1407rmixl_pcie_lip_free_callout(rmixl_pcie_link_intr_t *lip)
1408{
1409	callout_init(&lip->callout, 0);
1410	callout_reset(&lip->callout, 2 * hz, rmixl_pcie_lip_free, lip);
1411}
1412
1413static void
1414rmixl_pcie_lip_free(void *arg)
1415{
1416	rmixl_pcie_link_intr_t *lip = arg;
1417
1418	callout_destroy(&lip->callout);
1419	free(lip, M_DEVBUF);
1420}
1421
1422static int
1423rmixl_pcie_intr(void *arg)
1424{
1425	rmixl_pcie_link_intr_t *lip = arg;
1426	u_int link = lip->link;
1427	int rv = 0;
1428
1429	uint32_t status0 = RMIXL_IOREG_READ(RMIXL_IO_DEV_PCIE_LE + int_sts_offset[link].r0);
1430	uint32_t status1 = RMIXL_IOREG_READ(RMIXL_IO_DEV_PCIE_LE + int_sts_offset[link].r1);
1431	uint64_t status = ((uint64_t)status1 << 32) | status0;
1432	DPRINTF(("%s: %d:%#"PRIx64"\n", __func__, link, status));
1433
1434	if (status != 0) {
1435		rmixl_pcie_link_dispatch_t *dip;
1436
1437		if (status & RMIXL_PCIE_LINK_STATUS_ERRORS)
1438			rmixl_pcie_link_error_intr(link, status0, status1);
1439
1440		for (u_int i=0; i < lip->dispatch_count; i++) {
1441			dip = &lip->dispatch_data[i];
1442			int (*func)(void *) = dip->func;
1443			if (func != NULL) {
1444				uint64_t bit = 1 << dip->bitno;
1445				if ((status & bit) != 0) {
1446					(void)(*func)(dip->arg);
1447					dip->counts[cpu_index(curcpu())].evcnt.ev_count++;
1448					rv = 1;
1449				}
1450			}
1451		}
1452	}
1453
1454	return rv;
1455}
1456
1457static void
1458rmixl_pcie_link_error_intr(u_int link, uint32_t status0, uint32_t status1)
1459{
1460	printf("%s: mask %#"PRIx64"\n",
1461		__func__, RMIXL_PCIE_LINK_STATUS_ERRORS);
1462	printf("%s: PCIe Link Error: link=%d status0=%#x status1=%#x\n",
1463		__func__, link, status0, status1);
1464#if defined(DDB) && defined(DEBUG)
1465	Debugger();
1466#endif
1467}
1468
1469#if defined(DEBUG) || defined(DDB)
1470/* this function exists to facilitate call from ddb */
1471int
1472rmixl_pcie_error_check(void)
1473{
1474	if (rmixl_pcie_v != 0)
1475		return _rmixl_pcie_error_check(rmixl_pcie_v);
1476	return -1;
1477}
1478#endif
1479
1480STATIC int
1481_rmixl_pcie_error_check(void *v)
1482{
1483	int i, offset;
1484	pcireg_t r;
1485	pcitag_t tag;
1486	int err=0;
1487#ifdef DIAGNOSTIC
1488	pcireg_t regs[PCIE_ECFG_ERRS_OFFTAB_NENTRIES];
1489#endif
1490
1491	tag = rmixl_pcie_make_tag(v, 0, 0, 0);	/* XXX */
1492
1493	for (i=0; i < PCIE_ECFG_ERRS_OFFTAB_NENTRIES; i++) {
1494		offset = pcie_ecfg_errs_tab[i].offset;
1495		r = rmixl_pcie_conf_read(v, tag, offset);
1496#ifdef DIAGNOSTIC
1497		regs[i] = r;
1498#endif
1499		if (r != 0) {
1500			pcireg_t rw1c = r & pcie_ecfg_errs_tab[i].rw1c;
1501			if (rw1c != 0) {
1502				/* attempt to clear the error */
1503				rmixl_pcie_conf_write(v, tag, offset, rw1c);
1504			};
1505			if (offset == RMIXL_PCIE_ECFG_CESR)
1506				err |= 1;	/* correctable */
1507			else
1508				err |= 2;	/* uncorrectable */
1509		}
1510	}
1511#ifdef DIAGNOSTIC
1512	if (err != 0) {
1513		for (i=0; i < PCIE_ECFG_ERRS_OFFTAB_NENTRIES; i++) {
1514			offset = pcie_ecfg_errs_tab[i].offset;
1515			printf("%s: %#x: %#x\n", __func__, offset, regs[i]);
1516		}
1517	}
1518#endif
1519
1520	return err;
1521}
1522
1523static int
1524rmixl_pcie_error_intr(void *v)
1525{
1526	if (_rmixl_pcie_error_check(v) < 2)
1527		return 0;	/* correctable */
1528
1529	/* uncorrectable */
1530#if DDB
1531	Debugger();
1532#endif
1533
1534	/* XXX reset and recover? */
1535
1536	panic("%s\n", __func__);
1537}
1538
1539/*
1540 * rmixl_physaddr_init_pcie:
1541 *	called from rmixl_physaddr_init to get region addrs & sizes
1542 *	from PCIE CFG, ECFG, IO, MEM BARs
1543 */
1544void
1545rmixl_physaddr_init_pcie(struct extent *ext)
1546{
1547	u_long base;
1548	u_long size;
1549	uint32_t r;
1550
1551	r = RMIXL_IOREG_READ(RMIXLS_SBC_PCIE_CFG_BAR);
1552	if ((r & RMIXL_PCIE_CFG_BAR_ENB) != 0) {
1553		base = (u_long)(RMIXL_PCIE_CFG_BAR_TO_BA((uint64_t)r)
1554			/ (1024 * 1024));
1555		size = (u_long)RMIXL_PCIE_CFG_SIZE / (1024 * 1024);
1556		DPRINTF(("%s: %d: %s: 0x%08x -- 0x%010lx:%ld MB\n", __func__,
1557			__LINE__, "CFG", r, base * 1024 * 1024, size));
1558		if (extent_alloc_region(ext, base, size, EX_NOWAIT) != 0)
1559			panic("%s: extent_alloc_region(%p, %#lx, %#lx, %#x) "
1560				"failed", __func__, ext, base, size, EX_NOWAIT);
1561	}
1562
1563	r = RMIXL_IOREG_READ(RMIXLS_SBC_PCIE_ECFG_BAR);
1564	if ((r & RMIXL_PCIE_ECFG_BAR_ENB) != 0) {
1565		base = (u_long)(RMIXL_PCIE_ECFG_BAR_TO_BA((uint64_t)r)
1566			/ (1024 * 1024));
1567		size = (u_long)RMIXL_PCIE_ECFG_SIZE / (1024 * 1024);
1568		DPRINTF(("%s: %d: %s: 0x%08x -- 0x%010lx:%ld MB\n", __func__,
1569			__LINE__, "ECFG", r, base * 1024 * 1024, size));
1570		if (extent_alloc_region(ext, base, size, EX_NOWAIT) != 0)
1571			panic("%s: extent_alloc_region(%p, %#lx, %#lx, %#x) "
1572				"failed", __func__, ext, base, size, EX_NOWAIT);
1573	}
1574
1575	r = RMIXL_IOREG_READ(RMIXLS_SBC_PCIE_MEM_BAR);
1576	if ((r & RMIXL_PCIE_MEM_BAR_ENB) != 0) {
1577		base = (u_long)(RMIXL_PCIE_MEM_BAR_TO_BA((uint64_t)r)
1578			/ (1024 * 1024));
1579		size = (u_long)(RMIXL_PCIE_MEM_BAR_TO_SIZE((uint64_t)r)
1580			/ (1024 * 1024));
1581		DPRINTF(("%s: %d: %s: 0x%08x -- 0x%010lx:%ld MB\n", __func__,
1582			__LINE__, "MEM", r, base * 1024 * 1024, size));
1583		if (extent_alloc_region(ext, base, size, EX_NOWAIT) != 0)
1584			panic("%s: extent_alloc_region(%p, %#lx, %#lx, %#x) "
1585				"failed", __func__, ext, base, size, EX_NOWAIT);
1586	}
1587
1588	r = RMIXL_IOREG_READ(RMIXLS_SBC_PCIE_IO_BAR);
1589	if ((r & RMIXL_PCIE_IO_BAR_ENB) != 0) {
1590		base = (u_long)(RMIXL_PCIE_IO_BAR_TO_BA((uint64_t)r)
1591			/ (1024 * 1024));
1592		size = (u_long)(RMIXL_PCIE_IO_BAR_TO_SIZE((uint64_t)r)
1593			/ (1024 * 1024));
1594		DPRINTF(("%s: %d: %s: 0x%08x -- 0x%010lx:%ld MB\n", __func__,
1595			__LINE__, "IO", r, base * 1024 * 1024, size));
1596		if (extent_alloc_region(ext, base, size, EX_NOWAIT) != 0)
1597			panic("%s: extent_alloc_region(%p, %#lx, %#lx, %#x) "
1598				"failed", __func__, ext, base, size, EX_NOWAIT);
1599	}
1600}
1601