xref: /openbsd-src/sys/dev/fdt/dwpcie.c (revision c90a81c56dcebd6a1b73fe4aff9b03385b8e63b3)
1 /*	$OpenBSD: dwpcie.c,v 1.12 2019/01/11 08:03:24 patrick Exp $	*/
2 /*
3  * Copyright (c) 2018 Mark Kettenis <kettenis@openbsd.org>
4  *
5  * Permission to use, copy, modify, and distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 
18 #include <sys/param.h>
19 #include <sys/systm.h>
20 #include <sys/device.h>
21 #include <sys/extent.h>
22 #include <sys/malloc.h>
23 
24 #include <machine/intr.h>
25 #include <machine/bus.h>
26 #include <machine/fdt.h>
27 
28 #include <dev/pci/pcidevs.h>
29 #include <dev/pci/pcireg.h>
30 #include <dev/pci/pcivar.h>
31 #include <dev/pci/ppbreg.h>
32 
33 #include <dev/ofw/openfirm.h>
34 #include <dev/ofw/ofw_clock.h>
35 #include <dev/ofw/ofw_gpio.h>
36 #include <dev/ofw/ofw_misc.h>
37 #include <dev/ofw/ofw_pinctrl.h>
38 #include <dev/ofw/ofw_power.h>
39 #include <dev/ofw/fdt.h>
40 
41 /* Registers */
42 #define PCIE_PORT_LINK_CTRL		0x710
43 #define  PCIE_PORT_LINK_CTRL_LANES_MASK			(0x3f << 16)
44 #define  PCIE_PORT_LINK_CTRL_LANES_1			(0x1 << 16)
45 #define  PCIE_PORT_LINK_CTRL_LANES_2			(0x3 << 16)
46 #define  PCIE_PORT_LINK_CTRL_LANES_4			(0x7 << 16)
47 #define  PCIE_PORT_LINK_CTRL_LANES_8			(0xf << 16)
48 #define PCIE_PHY_DEBUG_R1		0x72c
49 #define  PCIE_PHY_DEBUG_R1_XMLH_LINK_IN_TRAINING	(1 << 29)
50 #define  PCIE_PHY_DEBUG_R1_XMLH_LINK_UP			(1 << 4)
51 #define PCIE_LINK_WIDTH_SPEED_CTRL	0x80c
52 #define  PCIE_LINK_WIDTH_SPEED_CTRL_LANES_MASK		(0x1f << 8)
53 #define  PCIE_LINK_WIDTH_SPEED_CTRL_LANES_1		(0x1 << 8)
54 #define  PCIE_LINK_WIDTH_SPEED_CTRL_LANES_2		(0x2 << 8)
55 #define  PCIE_LINK_WIDTH_SPEED_CTRL_LANES_4		(0x4 << 8)
56 #define  PCIE_LINK_WIDTH_SPEED_CTRL_LANES_8		(0x8 << 8)
57 #define  PCIE_LINK_WIDTH_SPEED_CTRL_CHANGE		(1 << 17)
58 
59 #define MISC_CONTROL_1		0x8bc
60 #define  MISC_CONTROL_1_DBI_RO_WR_EN	(1 << 0)
61 #define IATU_VIEWPORT		0x900
62 #define  IATU_VIEWPORT_INDEX0		0
63 #define  IATU_VIEWPORT_INDEX1		1
64 #define  IATU_VIEWPORT_INDEX2		2
65 #define IATU_OFFSET_VIEWPORT	0x904
66 #define IATU_OFFSET_UNROLL(x)	(0x200 * (x))
67 #define IATU_REGION_CTRL_1	0x000
68 #define  IATU_REGION_CTRL_1_TYPE_MEM	0
69 #define  IATU_REGION_CTRL_1_TYPE_IO	2
70 #define  IATU_REGION_CTRL_1_TYPE_CFG0	4
71 #define  IATU_REGION_CTRL_1_TYPE_CFG1	5
72 #define IATU_REGION_CTRL_2	0x004
73 #define  IATU_REGION_CTRL_2_REGION_EN	(1U << 31)
74 #define IATU_LWR_BASE_ADDR	0x08
75 #define IATU_UPPER_BASE_ADDR	0x0c
76 #define IATU_LIMIT_ADDR		0x10
77 #define IATU_LWR_TARGET_ADDR	0x14
78 #define IATU_UPPER_TARGET_ADDR	0x18
79 
80 #define PCIE_GLOBAL_CTRL	0x8000
81 #define  PCIE_GLOBAL_CTRL_APP_LTSSM_EN		(1 << 2)
82 #define  PCIE_GLOBAL_CTRL_DEVICE_TYPE_MASK	(0xf << 4)
83 #define  PCIE_GLOBAL_CTRL_DEVICE_TYPE_RC	(0x4 << 4)
84 #define PCIE_GLOBAL_STATUS	0x8008
85 #define  PCIE_GLOBAL_STATUS_RDLH_LINK_UP	(1 << 1)
86 #define  PCIE_GLOBAL_STATUS_PHY_LINK_UP		(1 << 9)
87 #define PCIE_PM_STATUS		0x8014
88 #define PCIE_GLOBAL_INT_CAUSE	0x801c
89 #define PCIE_GLOBAL_INT_MASK	0x8020
90 #define  PCIE_GLOBAL_INT_MASK_INT_A		(1 << 9)
91 #define  PCIE_GLOBAL_INT_MASK_INT_B		(1 << 10)
92 #define  PCIE_GLOBAL_INT_MASK_INT_C		(1 << 11)
93 #define  PCIE_GLOBAL_INT_MASK_INT_D		(1 << 12)
94 #define PCIE_ARCACHE_TRC	0x8050
95 #define  PCIE_ARCACHE_TRC_DEFAULT		0x3511
96 #define PCIE_AWCACHE_TRC	0x8054
97 #define  PCIE_AWCACHE_TRC_DEFAULT		0x5311
98 #define PCIE_ARUSER		0x805c
99 #define PCIE_AWUSER		0x8060
100 #define  PCIE_AXUSER_DOMAIN_MASK		(0x3 << 4)
101 #define  PCIE_AXUSER_DOMAIN_INNER_SHARABLE	(0x1 << 4)
102 #define  PCIE_AXUSER_DOMAIN_OUTER_SHARABLE	(0x2 << 4)
103 
104 /* i.MX8MQ registers */
105 #define PCIE_RC_LCR				0x7c
106 #define  PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN1		0x1
107 #define  PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN2		0x2
108 #define  PCIE_RC_LCR_MAX_LINK_SPEEDS_MASK		0xf
109 #define  PCIE_RC_LCR_L1EL_MASK				(0x7 << 15)
110 #define  PCIE_RC_LCR_L1EL_64US				(0x6 << 15)
111 
112 #define IOMUXC_GPR12				0x30
113 #define  IMX8MQ_GPR_PCIE2_DEVICE_TYPE_MASK		(0xf << 8)
114 #define  IMX8MQ_GPR_PCIE2_DEVICE_TYPE_RC		(0x4 << 8)
115 #define  IMX8MQ_GPR_PCIE1_DEVICE_TYPE_MASK		(0xf << 12)
116 #define  IMX8MQ_GPR_PCIE1_DEVICE_TYPE_RC		(0x4 << 12)
117 #define IOMUXC_GPR14				0x38
118 #define IOMUXC_GPR16				0x40
119 #define  IMX8MQ_GPR_PCIE_REF_USE_PAD			(1 << 9)
120 #define  IMX8MQ_GPR_PCIE_CLK_REQ_OVERRIDE_EN		(1 << 10)
121 #define  IMX8MQ_GPR_PCIE_CLK_REQ_OVERRIDE		(1 << 11)
122 
123 #define ANATOP_PLLOUT_CTL			0x74
124 #define  ANATOP_PLLOUT_CTL_CKE				(1 << 4)
125 #define  ANATOP_PLLOUT_CTL_SEL_SYSPLL1			0xb
126 #define  ANATOP_PLLOUT_CTL_SEL_MASK			0xf
127 #define ANATOP_PLLOUT_DIV			0x7c
128 #define  ANATOP_PLLOUT_DIV_SYSPLL1			0x7
129 
130 #define HREAD4(sc, reg)							\
131 	(bus_space_read_4((sc)->sc_iot, (sc)->sc_ioh, (reg)))
132 #define HWRITE4(sc, reg, val)						\
133 	bus_space_write_4((sc)->sc_iot, (sc)->sc_ioh, (reg), (val))
134 #define HSET4(sc, reg, bits)						\
135 	HWRITE4((sc), (reg), HREAD4((sc), (reg)) | (bits))
136 #define HCLR4(sc, reg, bits)						\
137 	HWRITE4((sc), (reg), HREAD4((sc), (reg)) & ~(bits))
138 
139 struct dwpcie_range {
140 	uint32_t		flags;
141 	uint64_t		pci_base;
142 	uint64_t		phys_base;
143 	uint64_t		size;
144 };
145 
146 struct dwpcie_softc {
147 	struct device		sc_dev;
148 	bus_space_tag_t		sc_iot;
149 	bus_space_handle_t	sc_ioh;
150 	bus_space_handle_t	sc_cfg0_ioh;
151 	bus_space_handle_t	sc_cfg1_ioh;
152 
153 	bus_addr_t		sc_cfg0_base;
154 	bus_size_t		sc_cfg0_size;
155 	bus_addr_t		sc_cfg1_base;
156 	bus_size_t		sc_cfg1_size;
157 	bus_addr_t		sc_io_base;
158 	bus_addr_t		sc_io_bus_addr;
159 	bus_size_t		sc_io_size;
160 	bus_addr_t		sc_mem_base;
161 	bus_addr_t		sc_mem_bus_addr;
162 	bus_size_t		sc_mem_size;
163 
164 	int			sc_node;
165 	int			sc_acells;
166 	int			sc_scells;
167 	int			sc_pacells;
168 	int			sc_pscells;
169 	struct dwpcie_range	*sc_ranges;
170 	int			sc_nranges;
171 
172 	struct bus_space	sc_bus_iot;
173 	struct bus_space	sc_bus_memt;
174 
175 	struct arm64_pci_chipset sc_pc;
176 	int			sc_bus;
177 
178 	int			sc_num_viewport;
179 	bus_addr_t		sc_atu_base;
180 	int			sc_atu_unroll;
181 
182 	void			*sc_ih;
183 };
184 
185 int dwpcie_match(struct device *, void *, void *);
186 void dwpcie_attach(struct device *, struct device *, void *);
187 
188 struct cfattach	dwpcie_ca = {
189 	sizeof (struct dwpcie_softc), dwpcie_match, dwpcie_attach
190 };
191 
192 struct cfdriver dwpcie_cd = {
193 	NULL, "dwpcie", DV_DULL
194 };
195 
196 int
197 dwpcie_match(struct device *parent, void *match, void *aux)
198 {
199 	struct fdt_attach_args *faa = aux;
200 
201 	return (OF_is_compatible(faa->fa_node, "marvell,armada8k-pcie") ||
202 	    OF_is_compatible(faa->fa_node, "fsl,imx8mq-pcie"));
203 }
204 
205 void	dwpcie_atu_config(struct dwpcie_softc *, int, int,
206 	    uint64_t, uint64_t, uint64_t);
207 void	dwpcie_link_config(struct dwpcie_softc *);
208 int	dwpcie_link_up(struct dwpcie_softc *);
209 
210 void	dwpcie_armada8k_init(struct dwpcie_softc *);
211 int	dwpcie_armada8k_link_up(struct dwpcie_softc *);
212 int	dwpcie_armada8k_intr(void *);
213 
214 void	dwpcie_imx8mq_init(struct dwpcie_softc *);
215 int	dwpcie_imx8mq_intr(void *);
216 
217 void	dwpcie_attach_hook(struct device *, struct device *,
218 	    struct pcibus_attach_args *);
219 int	dwpcie_bus_maxdevs(void *, int);
220 pcitag_t dwpcie_make_tag(void *, int, int, int);
221 void	dwpcie_decompose_tag(void *, pcitag_t, int *, int *, int *);
222 int	dwpcie_conf_size(void *, pcitag_t);
223 pcireg_t dwpcie_conf_read(void *, pcitag_t, int);
224 void	dwpcie_conf_write(void *, pcitag_t, int, pcireg_t);
225 
226 int	dwpcie_intr_map(struct pci_attach_args *, pci_intr_handle_t *);
227 int	dwpcie_intr_map_msi(struct pci_attach_args *, pci_intr_handle_t *);
228 int	dwpcie_intr_map_msix(struct pci_attach_args *, int,
229 	    pci_intr_handle_t *);
230 const char *dwpcie_intr_string(void *, pci_intr_handle_t);
231 void	*dwpcie_intr_establish(void *, pci_intr_handle_t, int,
232 	    int (*)(void *), void *, char *);
233 void	dwpcie_intr_disestablish(void *, void *);
234 
235 void	*dwpcie_armada8k_intr_establish(void *, pci_intr_handle_t, int,
236 	    int (*)(void *), void *, char *);
237 
238 int	dwpcie_bs_iomap(bus_space_tag_t, bus_addr_t, bus_size_t, int,
239 	    bus_space_handle_t *);
240 int	dwpcie_bs_memmap(bus_space_tag_t, bus_addr_t, bus_size_t, int,
241 	    bus_space_handle_t *);
242 
243 void
244 dwpcie_attach(struct device *parent, struct device *self, void *aux)
245 {
246 	struct dwpcie_softc *sc = (struct dwpcie_softc *)self;
247 	struct fdt_attach_args *faa = aux;
248 	struct pcibus_attach_args pba;
249 	bus_addr_t iobase, iolimit;
250 	bus_addr_t membase, memlimit;
251 	uint32_t bus_range[2];
252 	uint32_t *ranges;
253 	int i, j, nranges, rangeslen;
254 	pcireg_t bir, blr, csr;
255 
256 	if (faa->fa_nreg < 2) {
257 		printf(": no registers\n");
258 		return;
259 	}
260 
261 	sc->sc_iot = faa->fa_iot;
262 	sc->sc_node = faa->fa_node;
263 
264 	sc->sc_acells = OF_getpropint(sc->sc_node, "#address-cells",
265 	    faa->fa_acells);
266 	sc->sc_scells = OF_getpropint(sc->sc_node, "#size-cells",
267 	    faa->fa_scells);
268 	sc->sc_pacells = faa->fa_acells;
269 	sc->sc_pscells = faa->fa_scells;
270 
271 	rangeslen = OF_getproplen(sc->sc_node, "ranges");
272 	if (rangeslen <= 0 || (rangeslen % sizeof(uint32_t)) ||
273 	     (rangeslen / sizeof(uint32_t)) % (sc->sc_acells +
274 	     sc->sc_pacells + sc->sc_scells)) {
275 		printf(": invalid ranges property\n");
276 		return;
277 	}
278 
279 	ranges = malloc(rangeslen, M_TEMP, M_WAITOK);
280 	OF_getpropintarray(sc->sc_node, "ranges", ranges,
281 	    rangeslen);
282 
283 	nranges = (rangeslen / sizeof(uint32_t)) /
284 	    (sc->sc_acells + sc->sc_pacells + sc->sc_scells);
285 	sc->sc_ranges = mallocarray(nranges,
286 	    sizeof(struct dwpcie_range), M_TEMP, M_WAITOK);
287 	sc->sc_nranges = nranges;
288 
289 	for (i = 0, j = 0; i < sc->sc_nranges; i++) {
290 		sc->sc_ranges[i].flags = ranges[j++];
291 		sc->sc_ranges[i].pci_base = ranges[j++];
292 		if (sc->sc_acells - 1 == 2) {
293 			sc->sc_ranges[i].pci_base <<= 32;
294 			sc->sc_ranges[i].pci_base |= ranges[j++];
295 		}
296 		sc->sc_ranges[i].phys_base = ranges[j++];
297 		if (sc->sc_pacells == 2) {
298 			sc->sc_ranges[i].phys_base <<= 32;
299 			sc->sc_ranges[i].phys_base |= ranges[j++];
300 		}
301 		sc->sc_ranges[i].size = ranges[j++];
302 		if (sc->sc_scells == 2) {
303 			sc->sc_ranges[i].size <<= 32;
304 			sc->sc_ranges[i].size |= ranges[j++];
305 		}
306 	}
307 
308 	free(ranges, M_TEMP, rangeslen);
309 
310 	if (bus_space_map(sc->sc_iot, faa->fa_reg[0].addr,
311 	    faa->fa_reg[0].size, 0, &sc->sc_ioh)) {
312 		printf(": can't map ctrl registers\n");
313 		return;
314 	}
315 
316 	sc->sc_cfg0_base = faa->fa_reg[1].addr;
317 	sc->sc_cfg0_size = faa->fa_reg[1].size / 2;
318 	sc->sc_cfg0_base = faa->fa_reg[1].addr + sc->sc_cfg0_size;
319 	sc->sc_cfg1_size = sc->sc_cfg0_size;
320 
321 	if (bus_space_map(sc->sc_iot, sc->sc_cfg0_base,
322 	    sc->sc_cfg1_size, 0, &sc->sc_cfg0_ioh)) {
323 		bus_space_unmap(sc->sc_iot, sc->sc_ioh, faa->fa_reg[0].size);
324 		printf(": can't map config registers\n");
325 		return;
326 	}
327 
328 	if (bus_space_map(sc->sc_iot, sc->sc_cfg1_base,
329 	    sc->sc_cfg1_size, 0, &sc->sc_cfg1_ioh)) {
330 		bus_space_unmap(sc->sc_iot, sc->sc_cfg0_ioh, sc->sc_cfg0_size);
331 		bus_space_unmap(sc->sc_iot, sc->sc_ioh, faa->fa_reg[0].size);
332 		printf(": can't map config registers\n");
333 		return;
334 	}
335 
336 	sc->sc_num_viewport = OF_getpropint(sc->sc_node, "num-viewport", 2);
337 
338 	printf("\n");
339 
340 	pinctrl_byname(sc->sc_node, "default");
341 
342 	clock_set_assigned(sc->sc_node);
343 
344 	if (OF_is_compatible(sc->sc_node, "marvell,armada8k-pcie"))
345 		dwpcie_armada8k_init(sc);
346 	if (OF_is_compatible(sc->sc_node, "fsl,imx8mq-pcie"))
347 		dwpcie_imx8mq_init(sc);
348 
349 	if (HREAD4(sc, IATU_VIEWPORT) == 0xffffffff) {
350 		sc->sc_atu_base = 0x300000;
351 		sc->sc_atu_unroll = 1;
352 	}
353 
354 	/* Set up address translation for I/O space. */
355 	sc->sc_io_bus_addr = sc->sc_mem_bus_addr = -1;
356 	for (i = 0; i < sc->sc_nranges; i++) {
357 		if ((sc->sc_ranges[i].flags & 0x03000000) == 0x01000000 &&
358 		    sc->sc_ranges[i].size > 0) {
359 			sc->sc_io_base = sc->sc_ranges[i].phys_base;
360 			sc->sc_io_bus_addr = sc->sc_ranges[i].pci_base;
361 			sc->sc_io_size = sc->sc_ranges[i].size;
362 		}
363 		if ((sc->sc_ranges[i].flags & 0x03000000) == 0x02000000 &&
364 		    sc->sc_ranges[i].size > 0) {
365 			sc->sc_mem_base = sc->sc_ranges[i].phys_base;
366 			sc->sc_mem_bus_addr = sc->sc_ranges[i].pci_base;
367 			sc->sc_mem_size = sc->sc_ranges[i].size;
368 		}
369 	}
370 
371 	dwpcie_atu_config(sc, IATU_VIEWPORT_INDEX0,
372 	    IATU_REGION_CTRL_1_TYPE_MEM, sc->sc_mem_base,
373 	    sc->sc_mem_bus_addr, sc->sc_mem_size);
374 	if (sc->sc_num_viewport > 2)
375 		dwpcie_atu_config(sc, IATU_VIEWPORT_INDEX2,
376 		    IATU_REGION_CTRL_1_TYPE_IO, sc->sc_io_base,
377 		    sc->sc_io_bus_addr, sc->sc_io_size);
378 
379 	/* Enable modification of read-only bits. */
380 	HSET4(sc, MISC_CONTROL_1, MISC_CONTROL_1_DBI_RO_WR_EN);
381 
382 	/* A Root Port is a PCI-PCI Bridge. */
383 	HWRITE4(sc, PCI_CLASS_REG,
384 	    PCI_CLASS_BRIDGE << PCI_CLASS_SHIFT |
385 	    PCI_SUBCLASS_BRIDGE_PCI << PCI_SUBCLASS_SHIFT);
386 
387 	/* Clear BAR as U-Boot seems to leave garbage in it. */
388 	HWRITE4(sc, PCI_MAPREG_START, PCI_MAPREG_MEM_TYPE_64BIT);
389 	HWRITE4(sc, PCI_MAPREG_START + 4, 0);
390 
391 	/* Make sure read-only bits are write-protected. */
392 	HCLR4(sc, MISC_CONTROL_1, MISC_CONTROL_1_DBI_RO_WR_EN);
393 
394 	/* Set up bus range. */
395 	if (OF_getpropintarray(sc->sc_node, "bus-range", bus_range,
396 	    sizeof(bus_range)) != sizeof(bus_range) ||
397 	    bus_range[0] >= 32 || bus_range[1] >= 32) {
398 		bus_range[0] = 0;
399 		bus_range[1] = 31;
400 	}
401 	sc->sc_bus = bus_range[0];
402 
403 	/* Initialize bus range. */
404 	bir = bus_range[0];
405 	bir |= ((bus_range[0] + 1) << 8);
406 	bir |= (bus_range[1] << 16);
407 	HWRITE4(sc, PPB_REG_BUSINFO, bir);
408 
409 	/* Initialize I/O window. */
410 	iobase = sc->sc_io_bus_addr;
411 	iolimit = iobase + sc->sc_io_size - 1;
412 	blr = iolimit & PPB_IO_MASK;
413 	blr |= (iobase >> PPB_IO_SHIFT);
414 	HWRITE4(sc, PPB_REG_IOSTATUS, blr);
415 	blr = (iobase & 0xffff0000) >> 16;
416 	blr |= iolimit & 0xffff0000;
417 	HWRITE4(sc, PPB_REG_IO_HI, blr);
418 
419 	/* Initialize memory mapped I/O window. */
420 	membase = sc->sc_mem_bus_addr;
421 	memlimit = membase + sc->sc_mem_size - 1;
422 	blr = memlimit & PPB_MEM_MASK;
423 	blr |= (membase >> PPB_MEM_SHIFT);
424 	HWRITE4(sc, PPB_REG_MEM, blr);
425 
426 	/* Reset prefetchable memory mapped I/O window. */
427 	HWRITE4(sc, PPB_REG_PREFMEM, 0x0000ffff);
428 	HWRITE4(sc, PPB_REG_PREFBASE_HI32, 0);
429 	HWRITE4(sc, PPB_REG_PREFLIM_HI32, 0);
430 
431 	csr = PCI_COMMAND_MASTER_ENABLE;
432 	if (iolimit > iobase)
433 		csr |= PCI_COMMAND_IO_ENABLE;
434 	if (memlimit > membase)
435 		csr |= PCI_COMMAND_MEM_ENABLE;
436 	HWRITE4(sc, PCI_COMMAND_STATUS_REG, csr);
437 
438 	memcpy(&sc->sc_bus_iot, sc->sc_iot, sizeof(sc->sc_bus_iot));
439 	sc->sc_bus_iot.bus_private = sc;
440 	sc->sc_bus_iot._space_map = dwpcie_bs_iomap;
441 	memcpy(&sc->sc_bus_memt, sc->sc_iot, sizeof(sc->sc_bus_memt));
442 	sc->sc_bus_memt.bus_private = sc;
443 	sc->sc_bus_memt._space_map = dwpcie_bs_memmap;
444 
445 	sc->sc_pc.pc_conf_v = sc;
446 	sc->sc_pc.pc_attach_hook = dwpcie_attach_hook;
447 	sc->sc_pc.pc_bus_maxdevs = dwpcie_bus_maxdevs;
448 	sc->sc_pc.pc_make_tag = dwpcie_make_tag;
449 	sc->sc_pc.pc_decompose_tag = dwpcie_decompose_tag;
450 	sc->sc_pc.pc_conf_size = dwpcie_conf_size;
451 	sc->sc_pc.pc_conf_read = dwpcie_conf_read;
452 	sc->sc_pc.pc_conf_write = dwpcie_conf_write;
453 
454 	sc->sc_pc.pc_intr_v = sc;
455 	sc->sc_pc.pc_intr_map = dwpcie_intr_map;
456 	sc->sc_pc.pc_intr_map_msi = dwpcie_intr_map_msi;
457 	sc->sc_pc.pc_intr_map_msix = dwpcie_intr_map_msix;
458 	sc->sc_pc.pc_intr_string = dwpcie_intr_string;
459 	sc->sc_pc.pc_intr_establish = dwpcie_intr_establish;
460 	sc->sc_pc.pc_intr_disestablish = dwpcie_intr_disestablish;
461 
462 	memset(&pba, 0, sizeof(pba));
463 	pba.pba_busname = "pci";
464 	pba.pba_iot = &sc->sc_bus_iot;
465 	pba.pba_memt = &sc->sc_bus_memt;
466 	pba.pba_dmat = faa->fa_dmat;
467 	pba.pba_pc = &sc->sc_pc;
468 	pba.pba_domain = pci_ndomains++;
469 	pba.pba_bus = sc->sc_bus;
470 	if (OF_is_compatible(faa->fa_node, "marvell,armada8k-pcie"))
471 		pba.pba_flags |= PCI_FLAGS_MSI_ENABLED;
472 
473 	config_found(self, &pba, NULL);
474 }
475 
476 void
477 dwpcie_link_config(struct dwpcie_softc *sc)
478 {
479 	uint32_t mode, width, reg;
480 	int lanes;
481 
482 	lanes = OF_getpropint(sc->sc_node, "num-lanes", 0);
483 
484 	switch (lanes) {
485 	case 1:
486 		mode = PCIE_PORT_LINK_CTRL_LANES_1;
487 		width = PCIE_LINK_WIDTH_SPEED_CTRL_LANES_1;
488 		break;
489 	case 2:
490 		mode = PCIE_PORT_LINK_CTRL_LANES_2;
491 		width = PCIE_LINK_WIDTH_SPEED_CTRL_LANES_2;
492 		break;
493 	case 4:
494 		mode = PCIE_PORT_LINK_CTRL_LANES_4;
495 		width = PCIE_LINK_WIDTH_SPEED_CTRL_LANES_4;
496 		break;
497 	case 8:
498 		mode = PCIE_PORT_LINK_CTRL_LANES_8;
499 		width = PCIE_LINK_WIDTH_SPEED_CTRL_LANES_8;
500 		break;
501 	default:
502 		printf("%s: %d lanes not supported\n", __func__, lanes);
503 		return;
504 	}
505 
506 	reg = HREAD4(sc, PCIE_PORT_LINK_CTRL);
507 	reg &= ~PCIE_PORT_LINK_CTRL_LANES_MASK;
508 	reg |= mode;
509 	HWRITE4(sc, PCIE_PORT_LINK_CTRL, reg);
510 
511 	reg = HREAD4(sc, PCIE_LINK_WIDTH_SPEED_CTRL);
512 	reg &= ~PCIE_LINK_WIDTH_SPEED_CTRL_LANES_MASK;
513 	reg |= width;
514 	HWRITE4(sc, PCIE_LINK_WIDTH_SPEED_CTRL, reg);
515 
516 	reg = HREAD4(sc, PCIE_LINK_WIDTH_SPEED_CTRL);
517 	reg |= PCIE_LINK_WIDTH_SPEED_CTRL_CHANGE;
518 	HWRITE4(sc, PCIE_LINK_WIDTH_SPEED_CTRL, reg);
519 }
520 
521 void
522 dwpcie_armada8k_init(struct dwpcie_softc *sc)
523 {
524 	uint32_t reg;
525 	int timo;
526 
527 	clock_enable_all(sc->sc_node);
528 
529 	dwpcie_link_config(sc);
530 
531 	if (!dwpcie_armada8k_link_up(sc)) {
532 		reg = HREAD4(sc, PCIE_GLOBAL_CTRL);
533 		reg &= ~PCIE_GLOBAL_CTRL_APP_LTSSM_EN;
534 		HWRITE4(sc, PCIE_GLOBAL_CTRL, reg);
535 	}
536 
537 	/* Enable Root Complex mode. */
538 	reg = HREAD4(sc, PCIE_GLOBAL_CTRL);
539 	reg &= ~PCIE_GLOBAL_CTRL_DEVICE_TYPE_MASK;
540 	reg |= PCIE_GLOBAL_CTRL_DEVICE_TYPE_RC;
541 	HWRITE4(sc, PCIE_GLOBAL_CTRL, reg);
542 
543 	HWRITE4(sc, PCIE_ARCACHE_TRC, PCIE_ARCACHE_TRC_DEFAULT);
544 	HWRITE4(sc, PCIE_AWCACHE_TRC, PCIE_AWCACHE_TRC_DEFAULT);
545 	reg = HREAD4(sc, PCIE_ARUSER);
546 	reg &= ~PCIE_AXUSER_DOMAIN_MASK;
547 	reg |= PCIE_AXUSER_DOMAIN_OUTER_SHARABLE;
548 	HWRITE4(sc, PCIE_ARUSER, reg);
549 	reg = HREAD4(sc, PCIE_AWUSER);
550 	reg &= ~PCIE_AXUSER_DOMAIN_MASK;
551 	reg |= PCIE_AXUSER_DOMAIN_OUTER_SHARABLE;
552 	HWRITE4(sc, PCIE_AWUSER, reg);
553 
554 	if (!dwpcie_armada8k_link_up(sc)) {
555 		reg = HREAD4(sc, PCIE_GLOBAL_CTRL);
556 		reg |= PCIE_GLOBAL_CTRL_APP_LTSSM_EN;
557 		HWRITE4(sc, PCIE_GLOBAL_CTRL, reg);
558 	}
559 
560 	for (timo = 40; timo > 0; timo--) {
561 		if (dwpcie_armada8k_link_up(sc))
562 			break;
563 		delay(1000);
564 	}
565 
566 	sc->sc_ih = fdt_intr_establish(sc->sc_node, IPL_AUDIO | IPL_MPSAFE,
567 	    dwpcie_armada8k_intr, sc, sc->sc_dev.dv_xname);
568 
569 	/* Unmask INTx interrupts. */
570 	HWRITE4(sc, PCIE_GLOBAL_INT_MASK,
571 	    PCIE_GLOBAL_INT_MASK_INT_A | PCIE_GLOBAL_INT_MASK_INT_B |
572 	    PCIE_GLOBAL_INT_MASK_INT_C | PCIE_GLOBAL_INT_MASK_INT_D);
573 }
574 
575 int
576 dwpcie_armada8k_link_up(struct dwpcie_softc *sc)
577 {
578 	uint32_t reg, mask;
579 
580 	mask = PCIE_GLOBAL_STATUS_RDLH_LINK_UP;
581 	mask |= PCIE_GLOBAL_STATUS_PHY_LINK_UP;
582 	reg = HREAD4(sc, PCIE_GLOBAL_STATUS);
583 	return ((reg & mask) == mask);
584 }
585 
586 int
587 dwpcie_armada8k_intr(void *arg)
588 {
589 	struct dwpcie_softc *sc = arg;
590 	uint32_t cause;
591 
592 	/* Acknowledge interrupts. */
593 	cause = HREAD4(sc, PCIE_GLOBAL_INT_CAUSE);
594 	HWRITE4(sc, PCIE_GLOBAL_INT_CAUSE, cause);
595 
596 	/* INTx interrupt, so not really ours. */
597 	return 0;
598 }
599 
600 void
601 dwpcie_imx8mq_init(struct dwpcie_softc *sc)
602 {
603 	uint32_t *clkreq_gpio, *disable_gpio, *reset_gpio;
604 	ssize_t clkreq_gpiolen, disable_gpiolen, reset_gpiolen;
605 	struct regmap *anatop, *gpc, *gpr;
606 	uint32_t off, reg;
607 	int timo;
608 
609 	anatop = regmap_bycompatible("fsl,imx8mq-anatop");
610 	gpc = regmap_bycompatible("fsl,imx8mq-gpc");
611 	gpr = regmap_bycompatible("fsl,imx8mq-iomuxc-gpr");
612 	KASSERT(anatop != NULL);
613 	KASSERT(gpc != NULL);
614 	KASSERT(gpr != NULL);
615 
616 	clkreq_gpiolen = OF_getproplen(sc->sc_node, "clkreq-gpio");
617 	disable_gpiolen = OF_getproplen(sc->sc_node, "disable-gpio");
618 	reset_gpiolen = OF_getproplen(sc->sc_node, "reset-gpio");
619 
620 	if (clkreq_gpiolen > 0) {
621 		clkreq_gpio = malloc(clkreq_gpiolen, M_TEMP, M_WAITOK);
622 		OF_getpropintarray(sc->sc_node, "clkreq-gpio", clkreq_gpio,
623 		    clkreq_gpiolen);
624 		gpio_controller_config_pin(clkreq_gpio, GPIO_CONFIG_OUTPUT);
625 		gpio_controller_set_pin(clkreq_gpio, 1);
626 	}
627 
628 	if (disable_gpiolen > 0) {
629 		disable_gpio = malloc(disable_gpiolen, M_TEMP, M_WAITOK);
630 		OF_getpropintarray(sc->sc_node, "disable-gpio", disable_gpio,
631 		    disable_gpiolen);
632 		gpio_controller_config_pin(disable_gpio, GPIO_CONFIG_OUTPUT);
633 		gpio_controller_set_pin(disable_gpio, 0);
634 	}
635 
636 	if (reset_gpiolen > 0) {
637 		reset_gpio = malloc(reset_gpiolen, M_TEMP, M_WAITOK);
638 		OF_getpropintarray(sc->sc_node, "reset-gpio", reset_gpio,
639 		    reset_gpiolen);
640 		gpio_controller_config_pin(reset_gpio, GPIO_CONFIG_OUTPUT);
641 		gpio_controller_set_pin(reset_gpio, 1);
642 	}
643 
644 	power_domain_enable(sc->sc_node);
645 	reset_assert(sc->sc_node, "pciephy");
646 	reset_assert(sc->sc_node, "apps");
647 
648 	reg = regmap_read_4(gpr, IOMUXC_GPR12);
649 	if (OF_getpropint(sc->sc_node, "ctrl-id", 0) == 0) {
650 		off = IOMUXC_GPR14;
651 		reg &= ~IMX8MQ_GPR_PCIE1_DEVICE_TYPE_MASK;
652 		reg |= IMX8MQ_GPR_PCIE1_DEVICE_TYPE_RC;
653 	} else {
654 		off = IOMUXC_GPR16;
655 		reg &= ~IMX8MQ_GPR_PCIE2_DEVICE_TYPE_MASK;
656 		reg |= IMX8MQ_GPR_PCIE2_DEVICE_TYPE_RC;
657 	}
658 	regmap_write_4(gpr, IOMUXC_GPR12, reg);
659 
660 	if (OF_getproplen(sc->sc_node, "ext_osc") == 0) {
661 		reg = regmap_read_4(gpr, off);
662 		reg |= IMX8MQ_GPR_PCIE_REF_USE_PAD;
663 		regmap_write_4(gpr, off, reg);
664 	} else {
665 		reg = regmap_read_4(gpr, off);
666 		reg &= ~IMX8MQ_GPR_PCIE_REF_USE_PAD;
667 		regmap_write_4(gpr, off, reg);
668 
669 		regmap_write_4(anatop, ANATOP_PLLOUT_CTL,
670 		    ANATOP_PLLOUT_CTL_CKE | ANATOP_PLLOUT_CTL_SEL_SYSPLL1);
671 		regmap_write_4(anatop, ANATOP_PLLOUT_DIV,
672 		    ANATOP_PLLOUT_DIV_SYSPLL1);
673 	}
674 
675 	clock_enable(sc->sc_node, "pcie_phy");
676 	clock_enable(sc->sc_node, "pcie_bus");
677 	clock_enable(sc->sc_node, "pcie");
678 
679 	/* Allow clocks to stabilize. */
680 	delay(200);
681 
682 	if (reset_gpiolen > 0) {
683 		gpio_controller_set_pin(reset_gpio, 1);
684 		delay(20000);
685 		gpio_controller_set_pin(reset_gpio, 0);
686 		delay(20000);
687 	}
688 
689 	reset_deassert(sc->sc_node, "pciephy");
690 
691 	reg = HREAD4(sc, 0x100000 + PCIE_RC_LCR);
692 	reg &= ~PCIE_RC_LCR_L1EL_MASK;
693 	reg |= PCIE_RC_LCR_L1EL_64US;
694 	HWRITE4(sc, 0x100000 + PCIE_RC_LCR, reg);
695 
696 	dwpcie_link_config(sc);
697 
698 	reg = HREAD4(sc, PCIE_RC_LCR);
699 	reg &= ~PCIE_RC_LCR_MAX_LINK_SPEEDS_MASK;
700 	reg |= PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN1;
701 	HWRITE4(sc, PCIE_RC_LCR, reg);
702 
703 	reset_deassert(sc->sc_node, "apps");
704 
705 	for (timo = 20000; timo > 0; timo--) {
706 		if (dwpcie_link_up(sc))
707 			break;
708 		delay(10);
709 	}
710 	if (timo == 0)
711 		printf("%s:%d: timeout\n", __func__, __LINE__);
712 
713 	if (OF_getpropint(sc->sc_node, "fsl,max-link-speed", 1) >= 2) {
714 		reg = HREAD4(sc, PCIE_RC_LCR);
715 		reg &= ~PCIE_RC_LCR_MAX_LINK_SPEEDS_MASK;
716 		reg |= PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN2;
717 		HWRITE4(sc, PCIE_RC_LCR, reg);
718 
719 		reg = HREAD4(sc, PCIE_LINK_WIDTH_SPEED_CTRL);
720 		reg |= PCIE_LINK_WIDTH_SPEED_CTRL_CHANGE;
721 		HWRITE4(sc, PCIE_LINK_WIDTH_SPEED_CTRL, reg);
722 
723 		for (timo = 20000; timo > 0; timo--) {
724 			if (dwpcie_link_up(sc))
725 				break;
726 			delay(10);
727 		}
728 		if (timo == 0)
729 			printf("%s:%d: timeout\n", __func__, __LINE__);
730 	}
731 
732 	sc->sc_ih = fdt_intr_establish(sc->sc_node, IPL_AUDIO | IPL_MPSAFE,
733 	    dwpcie_imx8mq_intr, sc, sc->sc_dev.dv_xname);
734 
735 	/* Unmask INTx interrupts. */
736 	HWRITE4(sc, PCIE_GLOBAL_INT_MASK,
737 	    PCIE_GLOBAL_INT_MASK_INT_A | PCIE_GLOBAL_INT_MASK_INT_B |
738 	    PCIE_GLOBAL_INT_MASK_INT_C | PCIE_GLOBAL_INT_MASK_INT_D);
739 
740 	if (clkreq_gpiolen > 0)
741 		free(clkreq_gpio, M_TEMP, clkreq_gpiolen);
742 	if (disable_gpiolen > 0)
743 		free(disable_gpio, M_TEMP, disable_gpiolen);
744 	if (reset_gpiolen > 0)
745 		free(reset_gpio, M_TEMP, reset_gpiolen);
746 }
747 
748 int
749 dwpcie_imx8mq_intr(void *arg)
750 {
751 	struct dwpcie_softc *sc = arg;
752 	uint32_t cause;
753 
754 	/* Acknowledge interrupts. */
755 	cause = HREAD4(sc, PCIE_GLOBAL_INT_CAUSE);
756 	HWRITE4(sc, PCIE_GLOBAL_INT_CAUSE, cause);
757 
758 	/* INTx interrupt, so not really ours. */
759 	return 0;
760 }
761 
762 void
763 dwpcie_atu_config(struct dwpcie_softc *sc, int index, int type,
764     uint64_t cpu_addr, uint64_t pci_addr, uint64_t size)
765 {
766 	uint32_t reg, off;
767 	int timo;
768 
769 	off = sc->sc_atu_base + IATU_OFFSET_UNROLL(index);
770 	if (!sc->sc_atu_unroll) {
771 		off = IATU_OFFSET_VIEWPORT;
772 		HWRITE4(sc, IATU_VIEWPORT, index);
773 	}
774 
775 	HWRITE4(sc, off + IATU_LWR_BASE_ADDR, cpu_addr);
776 	HWRITE4(sc, off + IATU_UPPER_BASE_ADDR, cpu_addr >> 32);
777 	HWRITE4(sc, off + IATU_LIMIT_ADDR, cpu_addr + size - 1);
778 	HWRITE4(sc, off + IATU_LWR_TARGET_ADDR, pci_addr);
779 	HWRITE4(sc, off + IATU_UPPER_TARGET_ADDR, pci_addr >> 32);
780 	HWRITE4(sc, off + IATU_REGION_CTRL_1, type);
781 	HWRITE4(sc, off + IATU_REGION_CTRL_2, IATU_REGION_CTRL_2_REGION_EN);
782 
783 	for (timo = 5; timo > 0; timo--) {
784 		reg = HREAD4(sc, off + IATU_REGION_CTRL_2);
785 		if (reg & IATU_REGION_CTRL_2_REGION_EN)
786 			break;
787 		delay(9000);
788 	}
789 	if (timo == 0)
790 		printf("%s:%d: timeout\n", __func__, __LINE__);
791 }
792 
793 int
794 dwpcie_link_up(struct dwpcie_softc *sc)
795 {
796 	uint32_t reg;
797 
798 	reg = HREAD4(sc, PCIE_PHY_DEBUG_R1);
799 	if ((reg & PCIE_PHY_DEBUG_R1_XMLH_LINK_UP) != 0 &&
800 	    (reg & PCIE_PHY_DEBUG_R1_XMLH_LINK_IN_TRAINING) == 0)
801 		return 1;
802 	return 0;
803 }
804 
805 void
806 dwpcie_attach_hook(struct device *parent, struct device *self,
807     struct pcibus_attach_args *pba)
808 {
809 }
810 
811 int
812 dwpcie_bus_maxdevs(void *v, int bus)
813 {
814 	struct dwpcie_softc *sc = v;
815 
816 	if (bus == sc->sc_bus || bus == sc->sc_bus + 1)
817 		return 1;
818 	return 32;
819 }
820 
821 pcitag_t
822 dwpcie_make_tag(void *v, int bus, int device, int function)
823 {
824 	return ((bus << 24) | (device << 19) | (function << 16));
825 }
826 
827 void
828 dwpcie_decompose_tag(void *v, pcitag_t tag, int *bp, int *dp, int *fp)
829 {
830 	if (bp != NULL)
831 		*bp = (tag >> 24) & 0xff;
832 	if (dp != NULL)
833 		*dp = (tag >> 19) & 0x1f;
834 	if (fp != NULL)
835 		*fp = (tag >> 16) & 0x7;
836 }
837 
838 int
839 dwpcie_conf_size(void *v, pcitag_t tag)
840 {
841 	return PCIE_CONFIG_SPACE_SIZE;
842 }
843 
844 pcireg_t
845 dwpcie_conf_read(void *v, pcitag_t tag, int reg)
846 {
847 	struct dwpcie_softc *sc = v;
848 	int bus, dev, fn;
849 	uint32_t ret;
850 
851 	dwpcie_decompose_tag(sc, tag, &bus, &dev, &fn);
852 	if (bus == sc->sc_bus) {
853 		KASSERT(dev == 0);
854 		return HREAD4(sc, tag | reg);
855 	}
856 
857 	if (bus == sc->sc_bus + 1) {
858 		dwpcie_atu_config(sc, IATU_VIEWPORT_INDEX1,
859 		    IATU_REGION_CTRL_1_TYPE_CFG0,
860 		    sc->sc_cfg0_base, tag, sc->sc_cfg0_size);
861 		ret = bus_space_read_4(sc->sc_iot, sc->sc_cfg0_ioh, reg);
862 	} else {
863 		dwpcie_atu_config(sc, IATU_VIEWPORT_INDEX1,
864 		    IATU_REGION_CTRL_1_TYPE_CFG1,
865 		    sc->sc_cfg1_base, tag, sc->sc_cfg1_size);
866 		ret = bus_space_read_4(sc->sc_iot, sc->sc_cfg1_ioh, reg);
867 	}
868 	if (sc->sc_num_viewport <= 2)
869 		dwpcie_atu_config(sc, IATU_VIEWPORT_INDEX1,
870 		    IATU_REGION_CTRL_1_TYPE_IO, sc->sc_io_base,
871 		    sc->sc_io_bus_addr, sc->sc_io_size);
872 
873 	return ret;
874 }
875 
876 void
877 dwpcie_conf_write(void *v, pcitag_t tag, int reg, pcireg_t data)
878 {
879 	struct dwpcie_softc *sc = v;
880 	int bus, dev, fn;
881 
882 	dwpcie_decompose_tag(sc, tag, &bus, &dev, &fn);
883 	if (bus == sc->sc_bus) {
884 		KASSERT(dev == 0);
885 		HWRITE4(sc, tag | reg, data);
886 		return;
887 	}
888 
889 	if (bus == sc->sc_bus + 1) {
890 		dwpcie_atu_config(sc, IATU_VIEWPORT_INDEX1,
891 		    IATU_REGION_CTRL_1_TYPE_CFG0,
892 		    sc->sc_cfg0_base, tag, sc->sc_cfg0_size);
893 		bus_space_write_4(sc->sc_iot, sc->sc_cfg0_ioh, reg, data);
894 	} else {
895 		dwpcie_atu_config(sc, IATU_VIEWPORT_INDEX1,
896 		    IATU_REGION_CTRL_1_TYPE_CFG1,
897 		    sc->sc_cfg1_base, tag, sc->sc_cfg1_size);
898 		bus_space_write_4(sc->sc_iot, sc->sc_cfg1_ioh, reg, data);
899 	}
900 	if (sc->sc_num_viewport <= 2)
901 		dwpcie_atu_config(sc, IATU_VIEWPORT_INDEX1,
902 		    IATU_REGION_CTRL_1_TYPE_IO, sc->sc_io_base,
903 		    sc->sc_io_bus_addr, sc->sc_io_size);
904 }
905 
906 struct dwpcie_intr_handle {
907 	pci_chipset_tag_t	ih_pc;
908 	pcitag_t		ih_tag;
909 	int			ih_intrpin;
910 	int			ih_msi;
911 };
912 
913 int
914 dwpcie_intr_map(struct pci_attach_args *pa, pci_intr_handle_t *ihp)
915 {
916 	struct dwpcie_intr_handle *ih;
917 	int pin = pa->pa_rawintrpin;
918 
919 	if (pin == 0 || pin > PCI_INTERRUPT_PIN_MAX)
920 		return -1;
921 
922 	if (pa->pa_tag == 0)
923 		return -1;
924 
925 	ih = malloc(sizeof(struct dwpcie_intr_handle), M_DEVBUF, M_WAITOK);
926 	ih->ih_pc = pa->pa_pc;
927 	ih->ih_tag = pa->pa_intrtag;
928 	ih->ih_intrpin = pa->pa_intrpin;
929 	ih->ih_msi = 0;
930 	*ihp = (pci_intr_handle_t)ih;
931 
932 	return 0;
933 }
934 
935 int
936 dwpcie_intr_map_msi(struct pci_attach_args *pa, pci_intr_handle_t *ihp)
937 {
938 	pci_chipset_tag_t pc = pa->pa_pc;
939 	pcitag_t tag = pa->pa_tag;
940 	struct dwpcie_intr_handle *ih;
941 
942 	if ((pa->pa_flags & PCI_FLAGS_MSI_ENABLED) == 0 ||
943 	    pci_get_capability(pc, tag, PCI_CAP_MSI, NULL, NULL) == 0)
944 		return -1;
945 
946 	ih = malloc(sizeof(struct dwpcie_intr_handle), M_DEVBUF, M_WAITOK);
947 	ih->ih_pc = pa->pa_pc;
948 	ih->ih_tag = pa->pa_tag;
949 	ih->ih_intrpin = pa->pa_intrpin;
950 	ih->ih_msi = 1;
951 	*ihp = (pci_intr_handle_t)ih;
952 
953 	return 0;
954 }
955 
956 int
957 dwpcie_intr_map_msix(struct pci_attach_args *pa, int vec,
958     pci_intr_handle_t *ihp)
959 {
960 	return -1;
961 }
962 
963 const char *
964 dwpcie_intr_string(void *v, pci_intr_handle_t ihp)
965 {
966 	struct dwpcie_intr_handle *ih = (struct dwpcie_intr_handle *)ihp;
967 
968 	if (ih->ih_msi)
969 		return "msi";
970 
971 	return "intx";
972 }
973 
974 void *
975 dwpcie_intr_establish(void *v, pci_intr_handle_t ihp, int level,
976     int (*func)(void *), void *arg, char *name)
977 {
978 	struct dwpcie_softc *sc = v;
979 	struct dwpcie_intr_handle *ih = (struct dwpcie_intr_handle *)ihp;
980 	void *cookie;
981 
982 	if (ih->ih_msi) {
983 		uint64_t addr, data;
984 		pcireg_t reg;
985 		int off;
986 
987 		/* Assume hardware passes Requester ID as sideband data. */
988 		data = pci_requester_id(ih->ih_pc, ih->ih_tag);
989 		cookie = fdt_intr_establish_msi(sc->sc_node, &addr,
990 		    &data, level, func, arg, (void *)name);
991 		if (cookie == NULL)
992 			return NULL;
993 
994 		/* TODO: translate address to the PCI device's view */
995 
996 		if (pci_get_capability(ih->ih_pc, ih->ih_tag, PCI_CAP_MSI,
997 		    &off, &reg) == 0)
998 			panic("%s: no msi capability", __func__);
999 
1000 		if (reg & PCI_MSI_MC_C64) {
1001 			pci_conf_write(ih->ih_pc, ih->ih_tag,
1002 			    off + PCI_MSI_MA, addr);
1003 			pci_conf_write(ih->ih_pc, ih->ih_tag,
1004 			    off + PCI_MSI_MAU32, addr >> 32);
1005 			pci_conf_write(ih->ih_pc, ih->ih_tag,
1006 			    off + PCI_MSI_MD64, data);
1007 		} else {
1008 			pci_conf_write(ih->ih_pc, ih->ih_tag,
1009 			    off + PCI_MSI_MA, addr);
1010 			pci_conf_write(ih->ih_pc, ih->ih_tag,
1011 			    off + PCI_MSI_MD32, data);
1012 		}
1013 		pci_conf_write(ih->ih_pc, ih->ih_tag,
1014 		    off, reg | PCI_MSI_MC_MSIE);
1015 	} else {
1016 		int bus, dev, fn;
1017 		uint32_t reg[4];
1018 
1019 		dwpcie_decompose_tag(sc, ih->ih_tag, &bus, &dev, &fn);
1020 
1021 		reg[0] = bus << 16 | dev << 11 | fn << 8;
1022 		reg[1] = reg[2] = 0;
1023 		reg[3] = ih->ih_intrpin;
1024 
1025 		cookie = fdt_intr_establish_imap(sc->sc_node, reg,
1026 		    sizeof(reg), level, func, arg, name);
1027 	}
1028 
1029 	free(ih, M_DEVBUF, sizeof(struct dwpcie_intr_handle));
1030 	return cookie;
1031 }
1032 
1033 void
1034 dwpcie_intr_disestablish(void *v, void *cookie)
1035 {
1036 	panic("%s", __func__);
1037 }
1038 
1039 int
1040 dwpcie_bs_iomap(bus_space_tag_t t, bus_addr_t addr, bus_size_t size,
1041     int flags, bus_space_handle_t *bshp)
1042 {
1043 	struct dwpcie_softc *sc = t->bus_private;
1044 	int i;
1045 
1046 	for (i = 0; i < sc->sc_nranges; i++) {
1047 		uint64_t pci_start = sc->sc_ranges[i].pci_base;
1048 		uint64_t pci_end = pci_start + sc->sc_ranges[i].size;
1049 		uint64_t phys_start = sc->sc_ranges[i].phys_base;
1050 
1051 		if ((sc->sc_ranges[i].flags & 0x03000000) == 0x01000000 &&
1052 		    addr >= pci_start && addr + size <= pci_end) {
1053 			return bus_space_map(sc->sc_iot,
1054 			    addr - pci_start + phys_start, size, flags, bshp);
1055 		}
1056 	}
1057 
1058 	return ENXIO;
1059 }
1060 
1061 int
1062 dwpcie_bs_memmap(bus_space_tag_t t, bus_addr_t addr, bus_size_t size,
1063     int flags, bus_space_handle_t *bshp)
1064 {
1065 	struct dwpcie_softc *sc = t->bus_private;
1066 	int i;
1067 
1068 	for (i = 0; i < sc->sc_nranges; i++) {
1069 		uint64_t pci_start = sc->sc_ranges[i].pci_base;
1070 		uint64_t pci_end = pci_start + sc->sc_ranges[i].size;
1071 		uint64_t phys_start = sc->sc_ranges[i].phys_base;
1072 
1073 		if ((sc->sc_ranges[i].flags & 0x03000000) == 0x02000000 &&
1074 		    addr >= pci_start && addr + size <= pci_end) {
1075 			return bus_space_map(sc->sc_iot,
1076 			    addr - pci_start + phys_start, size, flags, bshp);
1077 		}
1078 	}
1079 
1080 	return ENXIO;
1081 }
1082