xref: /openbsd-src/sys/dev/fdt/dwpcie.c (revision 46035553bfdd96e63c94e32da0210227ec2e3cf1)
1 /*	$OpenBSD: dwpcie.c,v 1.24 2020/12/28 12:24:31 kettenis 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 /* Amlogic G12A registers */
105 #define PCIE_CFG0		0x0000
106 #define  PCIE_CFG0_APP_LTSSM_EN			(1 << 7)
107 #define PCIE_STATUS12		0x0030
108 #define  PCIE_STATUS12_RDLH_LINK_UP		(1 << 16)
109 #define  PCIE_STATUS12_LTSSM_MASK		(0x1f << 10)
110 #define  PCIE_STATUS12_LTSSM_UP			(0x11 << 10)
111 #define  PCIE_STATUS12_SMLH_LINK_UP		(1 << 6)
112 
113 /* NXP i.MX8MQ registers */
114 #define PCIE_RC_LCR				0x7c
115 #define  PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN1		0x1
116 #define  PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN2		0x2
117 #define  PCIE_RC_LCR_MAX_LINK_SPEEDS_MASK		0xf
118 #define  PCIE_RC_LCR_L1EL_MASK				(0x7 << 15)
119 #define  PCIE_RC_LCR_L1EL_64US				(0x6 << 15)
120 
121 #define IOMUXC_GPR12				0x30
122 #define  IMX8MQ_GPR_PCIE2_DEVICE_TYPE_MASK		(0xf << 8)
123 #define  IMX8MQ_GPR_PCIE2_DEVICE_TYPE_RC		(0x4 << 8)
124 #define  IMX8MQ_GPR_PCIE1_DEVICE_TYPE_MASK		(0xf << 12)
125 #define  IMX8MQ_GPR_PCIE1_DEVICE_TYPE_RC		(0x4 << 12)
126 #define IOMUXC_GPR14				0x38
127 #define IOMUXC_GPR16				0x40
128 #define  IMX8MQ_GPR_PCIE_REF_USE_PAD			(1 << 9)
129 #define  IMX8MQ_GPR_PCIE_CLK_REQ_OVERRIDE_EN		(1 << 10)
130 #define  IMX8MQ_GPR_PCIE_CLK_REQ_OVERRIDE		(1 << 11)
131 #define  IMX8MM_GPR_PCIE_SSC_EN				(1 << 16)
132 #define  IMX8MM_GPR_PCIE_POWER_OFF			(1 << 17)
133 #define  IMX8MM_GPR_PCIE_CMN_RST			(1 << 18)
134 #define  IMX8MM_GPR_PCIE_AUX_EN				(1 << 19)
135 #define  IMX8MM_GPR_PCIE_REF_CLK_MASK			(0x3 << 24)
136 #define  IMX8MM_GPR_PCIE_REF_CLK_PLL			(0x3 << 24)
137 #define  IMX8MM_GPR_PCIE_REF_CLK_EXT			(0x2 << 24)
138 
139 #define IMX8MM_PCIE_PHY_CMN_REG62			0x188
140 #define  IMX8MM_PCIE_PHY_CMN_REG62_PLL_CLK_OUT			0x08
141 #define IMX8MM_PCIE_PHY_CMN_REG64			0x190
142 #define  IMX8MM_PCIE_PHY_CMN_REG64_AUX_RX_TX_TERM		0x8c
143 #define IMX8MM_PCIE_PHY_CMN_REG75			0x1d4
144 #define  IMX8MM_PCIE_PHY_CMN_REG75_PLL_DONE			0x3
145 #define IMX8MM_PCIE_PHY_TRSV_REG5			0x414
146 #define  IMX8MM_PCIE_PHY_TRSV_REG5_GEN1_DEEMP			0x2d
147 #define IMX8MM_PCIE_PHY_TRSV_REG6			0x418
148 #define  IMX8MM_PCIE_PHY_TRSV_REG6_GEN2_DEEMP			0xf
149 
150 #define ANATOP_PLLOUT_CTL			0x74
151 #define  ANATOP_PLLOUT_CTL_CKE				(1 << 4)
152 #define  ANATOP_PLLOUT_CTL_SEL_SYSPLL1			0xb
153 #define  ANATOP_PLLOUT_CTL_SEL_MASK			0xf
154 #define ANATOP_PLLOUT_DIV			0x7c
155 #define  ANATOP_PLLOUT_DIV_SYSPLL1			0x7
156 
157 #define HREAD4(sc, reg)							\
158 	(bus_space_read_4((sc)->sc_iot, (sc)->sc_ioh, (reg)))
159 #define HWRITE4(sc, reg, val)						\
160 	bus_space_write_4((sc)->sc_iot, (sc)->sc_ioh, (reg), (val))
161 #define HSET4(sc, reg, bits)						\
162 	HWRITE4((sc), (reg), HREAD4((sc), (reg)) | (bits))
163 #define HCLR4(sc, reg, bits)						\
164 	HWRITE4((sc), (reg), HREAD4((sc), (reg)) & ~(bits))
165 
166 struct dwpcie_range {
167 	uint32_t		flags;
168 	uint64_t		pci_base;
169 	uint64_t		phys_base;
170 	uint64_t		size;
171 };
172 
173 struct dwpcie_softc {
174 	struct device		sc_dev;
175 	bus_space_tag_t		sc_iot;
176 	bus_space_handle_t	sc_ioh;
177 	bus_space_handle_t	sc_cfg0_ioh;
178 	bus_space_handle_t	sc_cfg1_ioh;
179 	bus_dma_tag_t		sc_dmat;
180 
181 	bus_addr_t		sc_ctrl_base;
182 	bus_size_t		sc_ctrl_size;
183 	bus_addr_t		sc_cfg0_base;
184 	bus_size_t		sc_cfg0_size;
185 	bus_addr_t		sc_cfg1_base;
186 	bus_size_t		sc_cfg1_size;
187 
188 	bus_addr_t		sc_glue_base;
189 	bus_size_t		sc_glue_size;
190 	bus_space_handle_t	sc_glue_ioh;
191 
192 	bus_addr_t		sc_io_base;
193 	bus_addr_t		sc_io_bus_addr;
194 	bus_size_t		sc_io_size;
195 	bus_addr_t		sc_mem_base;
196 	bus_addr_t		sc_mem_bus_addr;
197 	bus_size_t		sc_mem_size;
198 
199 	int			sc_node;
200 	int			sc_acells;
201 	int			sc_scells;
202 	int			sc_pacells;
203 	int			sc_pscells;
204 	struct dwpcie_range	*sc_ranges;
205 	int			sc_nranges;
206 
207 	struct bus_space	sc_bus_iot;
208 	struct bus_space	sc_bus_memt;
209 
210 	struct arm64_pci_chipset sc_pc;
211 	int			sc_bus;
212 
213 	int			sc_num_viewport;
214 	bus_addr_t		sc_atu_base;
215 	int			sc_atu_unroll;
216 
217 	void			*sc_ih;
218 };
219 
220 int dwpcie_match(struct device *, void *, void *);
221 void dwpcie_attach(struct device *, struct device *, void *);
222 
223 struct cfattach	dwpcie_ca = {
224 	sizeof (struct dwpcie_softc), dwpcie_match, dwpcie_attach
225 };
226 
227 struct cfdriver dwpcie_cd = {
228 	NULL, "dwpcie", DV_DULL
229 };
230 
231 int
232 dwpcie_match(struct device *parent, void *match, void *aux)
233 {
234 	struct fdt_attach_args *faa = aux;
235 
236 	return (OF_is_compatible(faa->fa_node, "amlogic,g12a-pcie") ||
237 	    OF_is_compatible(faa->fa_node, "marvell,armada8k-pcie") ||
238 	    OF_is_compatible(faa->fa_node, "fsl,imx8mm-pcie") ||
239 	    OF_is_compatible(faa->fa_node, "fsl,imx8mq-pcie"));
240 }
241 
242 void	dwpcie_attach_deferred(struct device *);
243 
244 void	dwpcie_atu_config(struct dwpcie_softc *, int, int,
245 	    uint64_t, uint64_t, uint64_t);
246 void	dwpcie_link_config(struct dwpcie_softc *);
247 int	dwpcie_link_up(struct dwpcie_softc *);
248 
249 int	dwpcie_armada8k_init(struct dwpcie_softc *);
250 int	dwpcie_armada8k_link_up(struct dwpcie_softc *);
251 int	dwpcie_armada8k_intr(void *);
252 
253 int	dwpcie_g12a_init(struct dwpcie_softc *);
254 int	dwpcie_g12a_link_up(struct dwpcie_softc *);
255 
256 int	dwpcie_imx8mq_init(struct dwpcie_softc *);
257 int	dwpcie_imx8mq_intr(void *);
258 
259 void	dwpcie_attach_hook(struct device *, struct device *,
260 	    struct pcibus_attach_args *);
261 int	dwpcie_bus_maxdevs(void *, int);
262 pcitag_t dwpcie_make_tag(void *, int, int, int);
263 void	dwpcie_decompose_tag(void *, pcitag_t, int *, int *, int *);
264 int	dwpcie_conf_size(void *, pcitag_t);
265 pcireg_t dwpcie_conf_read(void *, pcitag_t, int);
266 void	dwpcie_conf_write(void *, pcitag_t, int, pcireg_t);
267 
268 int	dwpcie_intr_map(struct pci_attach_args *, pci_intr_handle_t *);
269 const char *dwpcie_intr_string(void *, pci_intr_handle_t);
270 void	*dwpcie_intr_establish(void *, pci_intr_handle_t, int,
271 	    struct cpu_info *, int (*)(void *), void *, char *);
272 void	dwpcie_intr_disestablish(void *, void *);
273 
274 int	dwpcie_bs_iomap(bus_space_tag_t, bus_addr_t, bus_size_t, int,
275 	    bus_space_handle_t *);
276 int	dwpcie_bs_memmap(bus_space_tag_t, bus_addr_t, bus_size_t, int,
277 	    bus_space_handle_t *);
278 
279 void
280 dwpcie_attach(struct device *parent, struct device *self, void *aux)
281 {
282 	struct dwpcie_softc *sc = (struct dwpcie_softc *)self;
283 	struct fdt_attach_args *faa = aux;
284 	uint32_t *ranges;
285 	int i, j, nranges, rangeslen;
286 	int config, glue;
287 
288 	if (faa->fa_nreg < 2) {
289 		printf(": no registers\n");
290 		return;
291 	}
292 
293 	sc->sc_ctrl_base = faa->fa_reg[0].addr;
294 	sc->sc_ctrl_size = faa->fa_reg[0].size;
295 
296 	config = OF_getindex(faa->fa_node, "config", "reg-names");
297 	if (config < 0 || config >= faa->fa_nreg) {
298 		printf(": no config registers\n");
299 		return;
300 	}
301 
302 	sc->sc_cfg0_base = faa->fa_reg[config].addr;
303 	sc->sc_cfg0_size = faa->fa_reg[config].size / 2;
304 	sc->sc_cfg0_base = faa->fa_reg[config].addr + sc->sc_cfg0_size;
305 	sc->sc_cfg1_size = sc->sc_cfg0_size;
306 
307 	if (OF_is_compatible(faa->fa_node, "amlogic,g12a-pcie")) {
308 		glue = OF_getindex(faa->fa_node, "cfg", "reg-names");
309 		if (glue < 0 || glue >= faa->fa_nreg) {
310 			printf(": no glue registers\n");
311 			return;
312 		}
313 
314 		sc->sc_glue_base = faa->fa_reg[glue].addr;
315 		sc->sc_glue_size = faa->fa_reg[glue].size;
316 	}
317 
318 	sc->sc_iot = faa->fa_iot;
319 	sc->sc_dmat = faa->fa_dmat;
320 	sc->sc_node = faa->fa_node;
321 
322 	sc->sc_acells = OF_getpropint(sc->sc_node, "#address-cells",
323 	    faa->fa_acells);
324 	sc->sc_scells = OF_getpropint(sc->sc_node, "#size-cells",
325 	    faa->fa_scells);
326 	sc->sc_pacells = faa->fa_acells;
327 	sc->sc_pscells = faa->fa_scells;
328 
329 	rangeslen = OF_getproplen(sc->sc_node, "ranges");
330 	if (rangeslen <= 0 || (rangeslen % sizeof(uint32_t)) ||
331 	     (rangeslen / sizeof(uint32_t)) % (sc->sc_acells +
332 	     sc->sc_pacells + sc->sc_scells)) {
333 		printf(": invalid ranges property\n");
334 		return;
335 	}
336 
337 	ranges = malloc(rangeslen, M_TEMP, M_WAITOK);
338 	OF_getpropintarray(sc->sc_node, "ranges", ranges,
339 	    rangeslen);
340 
341 	nranges = (rangeslen / sizeof(uint32_t)) /
342 	    (sc->sc_acells + sc->sc_pacells + sc->sc_scells);
343 	sc->sc_ranges = mallocarray(nranges,
344 	    sizeof(struct dwpcie_range), M_TEMP, M_WAITOK);
345 	sc->sc_nranges = nranges;
346 
347 	for (i = 0, j = 0; i < sc->sc_nranges; i++) {
348 		sc->sc_ranges[i].flags = ranges[j++];
349 		sc->sc_ranges[i].pci_base = ranges[j++];
350 		if (sc->sc_acells - 1 == 2) {
351 			sc->sc_ranges[i].pci_base <<= 32;
352 			sc->sc_ranges[i].pci_base |= ranges[j++];
353 		}
354 		sc->sc_ranges[i].phys_base = ranges[j++];
355 		if (sc->sc_pacells == 2) {
356 			sc->sc_ranges[i].phys_base <<= 32;
357 			sc->sc_ranges[i].phys_base |= ranges[j++];
358 		}
359 		sc->sc_ranges[i].size = ranges[j++];
360 		if (sc->sc_scells == 2) {
361 			sc->sc_ranges[i].size <<= 32;
362 			sc->sc_ranges[i].size |= ranges[j++];
363 		}
364 	}
365 
366 	free(ranges, M_TEMP, rangeslen);
367 
368 	if (bus_space_map(sc->sc_iot, sc->sc_ctrl_base,
369 	    sc->sc_ctrl_size, 0, &sc->sc_ioh)) {
370 		free(sc->sc_ranges, M_TEMP, sc->sc_nranges *
371 		    sizeof(struct dwpcie_range));
372 		printf(": can't map ctrl registers\n");
373 		return;
374 	}
375 
376 	if (bus_space_map(sc->sc_iot, sc->sc_cfg0_base,
377 	    sc->sc_cfg1_size, 0, &sc->sc_cfg0_ioh)) {
378 		bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_ctrl_size);
379 		free(sc->sc_ranges, M_TEMP, sc->sc_nranges *
380 		    sizeof(struct dwpcie_range));
381 		printf(": can't map config registers\n");
382 		return;
383 	}
384 
385 	if (bus_space_map(sc->sc_iot, sc->sc_cfg1_base,
386 	    sc->sc_cfg1_size, 0, &sc->sc_cfg1_ioh)) {
387 		bus_space_unmap(sc->sc_iot, sc->sc_cfg0_ioh, sc->sc_cfg0_size);
388 		bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_ctrl_size);
389 		free(sc->sc_ranges, M_TEMP, sc->sc_nranges *
390 		    sizeof(struct dwpcie_range));
391 		printf(": can't map config registers\n");
392 		return;
393 	}
394 
395 	sc->sc_num_viewport = OF_getpropint(sc->sc_node, "num-viewport", 2);
396 
397 	printf("\n");
398 
399 	pinctrl_byname(sc->sc_node, "default");
400 	clock_set_assigned(sc->sc_node);
401 
402 	config_defer(self, dwpcie_attach_deferred);
403 }
404 
405 void
406 dwpcie_attach_deferred(struct device *self)
407 {
408 	struct dwpcie_softc *sc = (struct dwpcie_softc *)self;
409 	struct pcibus_attach_args pba;
410 	bus_addr_t iobase, iolimit;
411 	bus_addr_t membase, memlimit;
412 	uint32_t bus_range[2];
413 	pcireg_t bir, blr, csr;
414 	int i, error = 0;
415 
416 	if (OF_is_compatible(sc->sc_node, "marvell,armada8k-pcie"))
417 		error = dwpcie_armada8k_init(sc);
418 	if (OF_is_compatible(sc->sc_node, "amlogic,g12a-pcie"))
419 		error = dwpcie_g12a_init(sc);
420 	if (OF_is_compatible(sc->sc_node, "fsl,imx8mm-pcie") ||
421 	    OF_is_compatible(sc->sc_node, "fsl,imx8mq-pcie"))
422 		error = dwpcie_imx8mq_init(sc);
423 	if (error != 0) {
424 		bus_space_unmap(sc->sc_iot, sc->sc_cfg1_ioh, sc->sc_cfg1_size);
425 		bus_space_unmap(sc->sc_iot, sc->sc_cfg0_ioh, sc->sc_cfg0_size);
426 		bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_ctrl_size);
427 		free(sc->sc_ranges, M_TEMP, sc->sc_nranges *
428 		    sizeof(struct dwpcie_range));
429 		printf("%s: can't initialize hardware\n",
430 		    sc->sc_dev.dv_xname);
431 		return;
432 	}
433 
434 	if (HREAD4(sc, IATU_VIEWPORT) == 0xffffffff) {
435 		sc->sc_atu_base = 0x300000;
436 		sc->sc_atu_unroll = 1;
437 	}
438 
439 	/* Set up address translation for I/O space. */
440 	sc->sc_io_bus_addr = sc->sc_mem_bus_addr = -1;
441 	for (i = 0; i < sc->sc_nranges; i++) {
442 		if ((sc->sc_ranges[i].flags & 0x03000000) == 0x01000000 &&
443 		    sc->sc_ranges[i].size > 0) {
444 			sc->sc_io_base = sc->sc_ranges[i].phys_base;
445 			sc->sc_io_bus_addr = sc->sc_ranges[i].pci_base;
446 			sc->sc_io_size = sc->sc_ranges[i].size;
447 		}
448 		if ((sc->sc_ranges[i].flags & 0x03000000) == 0x02000000 &&
449 		    sc->sc_ranges[i].size > 0) {
450 			sc->sc_mem_base = sc->sc_ranges[i].phys_base;
451 			sc->sc_mem_bus_addr = sc->sc_ranges[i].pci_base;
452 			sc->sc_mem_size = sc->sc_ranges[i].size;
453 		}
454 	}
455 
456 	dwpcie_atu_config(sc, IATU_VIEWPORT_INDEX0,
457 	    IATU_REGION_CTRL_1_TYPE_MEM, sc->sc_mem_base,
458 	    sc->sc_mem_bus_addr, sc->sc_mem_size);
459 	if (sc->sc_num_viewport > 2)
460 		dwpcie_atu_config(sc, IATU_VIEWPORT_INDEX2,
461 		    IATU_REGION_CTRL_1_TYPE_IO, sc->sc_io_base,
462 		    sc->sc_io_bus_addr, sc->sc_io_size);
463 
464 	/* Enable modification of read-only bits. */
465 	HSET4(sc, MISC_CONTROL_1, MISC_CONTROL_1_DBI_RO_WR_EN);
466 
467 	/* A Root Port is a PCI-PCI Bridge. */
468 	HWRITE4(sc, PCI_CLASS_REG,
469 	    PCI_CLASS_BRIDGE << PCI_CLASS_SHIFT |
470 	    PCI_SUBCLASS_BRIDGE_PCI << PCI_SUBCLASS_SHIFT);
471 
472 	/* Clear BAR as U-Boot seems to leave garbage in it. */
473 	HWRITE4(sc, PCI_MAPREG_START, PCI_MAPREG_MEM_TYPE_64BIT);
474 	HWRITE4(sc, PCI_MAPREG_START + 4, 0);
475 
476 	/* Make sure read-only bits are write-protected. */
477 	HCLR4(sc, MISC_CONTROL_1, MISC_CONTROL_1_DBI_RO_WR_EN);
478 
479 	/* Set up bus range. */
480 	if (OF_getpropintarray(sc->sc_node, "bus-range", bus_range,
481 	    sizeof(bus_range)) != sizeof(bus_range) ||
482 	    bus_range[0] >= 32 || bus_range[1] >= 32) {
483 		bus_range[0] = 0;
484 		bus_range[1] = 31;
485 	}
486 	sc->sc_bus = bus_range[0];
487 
488 	/* Initialize bus range. */
489 	bir = bus_range[0];
490 	bir |= ((bus_range[0] + 1) << 8);
491 	bir |= (bus_range[1] << 16);
492 	HWRITE4(sc, PPB_REG_BUSINFO, bir);
493 
494 	/* Initialize I/O window. */
495 	iobase = sc->sc_io_bus_addr;
496 	iolimit = iobase + sc->sc_io_size - 1;
497 	blr = iolimit & PPB_IO_MASK;
498 	blr |= (iobase >> PPB_IO_SHIFT);
499 	HWRITE4(sc, PPB_REG_IOSTATUS, blr);
500 	blr = (iobase & 0xffff0000) >> 16;
501 	blr |= iolimit & 0xffff0000;
502 	HWRITE4(sc, PPB_REG_IO_HI, blr);
503 
504 	/* Initialize memory mapped I/O window. */
505 	membase = sc->sc_mem_bus_addr;
506 	memlimit = membase + sc->sc_mem_size - 1;
507 	blr = memlimit & PPB_MEM_MASK;
508 	blr |= (membase >> PPB_MEM_SHIFT);
509 	HWRITE4(sc, PPB_REG_MEM, blr);
510 
511 	/* Reset prefetchable memory mapped I/O window. */
512 	HWRITE4(sc, PPB_REG_PREFMEM, 0x0000ffff);
513 	HWRITE4(sc, PPB_REG_PREFBASE_HI32, 0);
514 	HWRITE4(sc, PPB_REG_PREFLIM_HI32, 0);
515 
516 	csr = PCI_COMMAND_MASTER_ENABLE;
517 	if (iolimit > iobase)
518 		csr |= PCI_COMMAND_IO_ENABLE;
519 	if (memlimit > membase)
520 		csr |= PCI_COMMAND_MEM_ENABLE;
521 	HWRITE4(sc, PCI_COMMAND_STATUS_REG, csr);
522 
523 	memcpy(&sc->sc_bus_iot, sc->sc_iot, sizeof(sc->sc_bus_iot));
524 	sc->sc_bus_iot.bus_private = sc;
525 	sc->sc_bus_iot._space_map = dwpcie_bs_iomap;
526 	memcpy(&sc->sc_bus_memt, sc->sc_iot, sizeof(sc->sc_bus_memt));
527 	sc->sc_bus_memt.bus_private = sc;
528 	sc->sc_bus_memt._space_map = dwpcie_bs_memmap;
529 
530 	sc->sc_pc.pc_conf_v = sc;
531 	sc->sc_pc.pc_attach_hook = dwpcie_attach_hook;
532 	sc->sc_pc.pc_bus_maxdevs = dwpcie_bus_maxdevs;
533 	sc->sc_pc.pc_make_tag = dwpcie_make_tag;
534 	sc->sc_pc.pc_decompose_tag = dwpcie_decompose_tag;
535 	sc->sc_pc.pc_conf_size = dwpcie_conf_size;
536 	sc->sc_pc.pc_conf_read = dwpcie_conf_read;
537 	sc->sc_pc.pc_conf_write = dwpcie_conf_write;
538 
539 	sc->sc_pc.pc_intr_v = sc;
540 	sc->sc_pc.pc_intr_map = dwpcie_intr_map;
541 	sc->sc_pc.pc_intr_map_msi = _pci_intr_map_msi;
542 	sc->sc_pc.pc_intr_map_msix = _pci_intr_map_msix;
543 	sc->sc_pc.pc_intr_string = dwpcie_intr_string;
544 	sc->sc_pc.pc_intr_establish = dwpcie_intr_establish;
545 	sc->sc_pc.pc_intr_disestablish = dwpcie_intr_disestablish;
546 
547 	memset(&pba, 0, sizeof(pba));
548 	pba.pba_busname = "pci";
549 	pba.pba_iot = &sc->sc_bus_iot;
550 	pba.pba_memt = &sc->sc_bus_memt;
551 	pba.pba_dmat = sc->sc_dmat;
552 	pba.pba_pc = &sc->sc_pc;
553 	pba.pba_domain = pci_ndomains++;
554 	pba.pba_bus = sc->sc_bus;
555 	if (OF_is_compatible(sc->sc_node, "marvell,armada8k-pcie"))
556 		pba.pba_flags |= PCI_FLAGS_MSI_ENABLED;
557 
558 	config_found(self, &pba, NULL);
559 }
560 
561 void
562 dwpcie_link_config(struct dwpcie_softc *sc)
563 {
564 	uint32_t mode, width, reg;
565 	int lanes;
566 
567 	lanes = OF_getpropint(sc->sc_node, "num-lanes", 0);
568 
569 	switch (lanes) {
570 	case 1:
571 		mode = PCIE_PORT_LINK_CTRL_LANES_1;
572 		width = PCIE_LINK_WIDTH_SPEED_CTRL_LANES_1;
573 		break;
574 	case 2:
575 		mode = PCIE_PORT_LINK_CTRL_LANES_2;
576 		width = PCIE_LINK_WIDTH_SPEED_CTRL_LANES_2;
577 		break;
578 	case 4:
579 		mode = PCIE_PORT_LINK_CTRL_LANES_4;
580 		width = PCIE_LINK_WIDTH_SPEED_CTRL_LANES_4;
581 		break;
582 	case 8:
583 		mode = PCIE_PORT_LINK_CTRL_LANES_8;
584 		width = PCIE_LINK_WIDTH_SPEED_CTRL_LANES_8;
585 		break;
586 	default:
587 		printf("%s: %d lanes not supported\n", __func__, lanes);
588 		return;
589 	}
590 
591 	reg = HREAD4(sc, PCIE_PORT_LINK_CTRL);
592 	reg &= ~PCIE_PORT_LINK_CTRL_LANES_MASK;
593 	reg |= mode;
594 	HWRITE4(sc, PCIE_PORT_LINK_CTRL, reg);
595 
596 	reg = HREAD4(sc, PCIE_LINK_WIDTH_SPEED_CTRL);
597 	reg &= ~PCIE_LINK_WIDTH_SPEED_CTRL_LANES_MASK;
598 	reg |= width;
599 	HWRITE4(sc, PCIE_LINK_WIDTH_SPEED_CTRL, reg);
600 
601 	reg = HREAD4(sc, PCIE_LINK_WIDTH_SPEED_CTRL);
602 	reg |= PCIE_LINK_WIDTH_SPEED_CTRL_CHANGE;
603 	HWRITE4(sc, PCIE_LINK_WIDTH_SPEED_CTRL, reg);
604 }
605 
606 int
607 dwpcie_armada8k_init(struct dwpcie_softc *sc)
608 {
609 	uint32_t reg;
610 	int timo;
611 
612 	clock_enable_all(sc->sc_node);
613 
614 	dwpcie_link_config(sc);
615 
616 	if (!dwpcie_armada8k_link_up(sc)) {
617 		reg = HREAD4(sc, PCIE_GLOBAL_CTRL);
618 		reg &= ~PCIE_GLOBAL_CTRL_APP_LTSSM_EN;
619 		HWRITE4(sc, PCIE_GLOBAL_CTRL, reg);
620 	}
621 
622 	/* Enable Root Complex mode. */
623 	reg = HREAD4(sc, PCIE_GLOBAL_CTRL);
624 	reg &= ~PCIE_GLOBAL_CTRL_DEVICE_TYPE_MASK;
625 	reg |= PCIE_GLOBAL_CTRL_DEVICE_TYPE_RC;
626 	HWRITE4(sc, PCIE_GLOBAL_CTRL, reg);
627 
628 	HWRITE4(sc, PCIE_ARCACHE_TRC, PCIE_ARCACHE_TRC_DEFAULT);
629 	HWRITE4(sc, PCIE_AWCACHE_TRC, PCIE_AWCACHE_TRC_DEFAULT);
630 	reg = HREAD4(sc, PCIE_ARUSER);
631 	reg &= ~PCIE_AXUSER_DOMAIN_MASK;
632 	reg |= PCIE_AXUSER_DOMAIN_OUTER_SHARABLE;
633 	HWRITE4(sc, PCIE_ARUSER, reg);
634 	reg = HREAD4(sc, PCIE_AWUSER);
635 	reg &= ~PCIE_AXUSER_DOMAIN_MASK;
636 	reg |= PCIE_AXUSER_DOMAIN_OUTER_SHARABLE;
637 	HWRITE4(sc, PCIE_AWUSER, reg);
638 
639 	if (!dwpcie_armada8k_link_up(sc)) {
640 		reg = HREAD4(sc, PCIE_GLOBAL_CTRL);
641 		reg |= PCIE_GLOBAL_CTRL_APP_LTSSM_EN;
642 		HWRITE4(sc, PCIE_GLOBAL_CTRL, reg);
643 	}
644 
645 	for (timo = 40; timo > 0; timo--) {
646 		if (dwpcie_armada8k_link_up(sc))
647 			break;
648 		delay(1000);
649 	}
650 	if (timo == 0)
651 		return ETIMEDOUT;
652 
653 	sc->sc_ih = fdt_intr_establish(sc->sc_node, IPL_AUDIO | IPL_MPSAFE,
654 	    dwpcie_armada8k_intr, sc, sc->sc_dev.dv_xname);
655 
656 	/* Unmask INTx interrupts. */
657 	HWRITE4(sc, PCIE_GLOBAL_INT_MASK,
658 	    PCIE_GLOBAL_INT_MASK_INT_A | PCIE_GLOBAL_INT_MASK_INT_B |
659 	    PCIE_GLOBAL_INT_MASK_INT_C | PCIE_GLOBAL_INT_MASK_INT_D);
660 
661 	return 0;
662 }
663 
664 int
665 dwpcie_armada8k_link_up(struct dwpcie_softc *sc)
666 {
667 	uint32_t reg, mask;
668 
669 	mask = PCIE_GLOBAL_STATUS_RDLH_LINK_UP;
670 	mask |= PCIE_GLOBAL_STATUS_PHY_LINK_UP;
671 	reg = HREAD4(sc, PCIE_GLOBAL_STATUS);
672 	return ((reg & mask) == mask);
673 }
674 
675 int
676 dwpcie_armada8k_intr(void *arg)
677 {
678 	struct dwpcie_softc *sc = arg;
679 	uint32_t cause;
680 
681 	/* Acknowledge interrupts. */
682 	cause = HREAD4(sc, PCIE_GLOBAL_INT_CAUSE);
683 	HWRITE4(sc, PCIE_GLOBAL_INT_CAUSE, cause);
684 
685 	/* INTx interrupt, so not really ours. */
686 	return 0;
687 }
688 
689 int
690 dwpcie_g12a_init(struct dwpcie_softc *sc)
691 {
692 	uint32_t *reset_gpio;
693 	ssize_t reset_gpiolen;
694 	uint32_t reg;
695 	int timo;
696 
697 	reset_gpiolen = OF_getproplen(sc->sc_node, "reset-gpios");
698 	if (reset_gpiolen <= 0)
699 		return ENXIO;
700 
701 	if (bus_space_map(sc->sc_iot, sc->sc_glue_base,
702 	    sc->sc_glue_size, 0, &sc->sc_glue_ioh))
703 		return ENOMEM;
704 
705 	power_domain_enable(sc->sc_node);
706 
707 	phy_enable(sc->sc_node, "pcie");
708 
709 	reset_assert_all(sc->sc_node);
710 	delay(500);
711 	reset_deassert_all(sc->sc_node);
712 	delay(500);
713 
714 	clock_set_frequency(sc->sc_node, "port", 100000000UL);
715 	clock_enable_all(sc->sc_node);
716 
717 	reset_gpio = malloc(reset_gpiolen, M_TEMP, M_WAITOK);
718 	OF_getpropintarray(sc->sc_node, "reset-gpios", reset_gpio,
719 	    reset_gpiolen);
720 	gpio_controller_config_pin(reset_gpio, GPIO_CONFIG_OUTPUT);
721 	gpio_controller_set_pin(reset_gpio, 1);
722 
723 	dwpcie_link_config(sc);
724 
725 	reg = bus_space_read_4(sc->sc_iot, sc->sc_glue_ioh, PCIE_CFG0);
726 	reg |= PCIE_CFG0_APP_LTSSM_EN;
727 	bus_space_write_4(sc->sc_iot, sc->sc_glue_ioh, PCIE_CFG0, reg);
728 
729 	gpio_controller_set_pin(reset_gpio, 1);
730 	delay(500);
731 	gpio_controller_set_pin(reset_gpio, 0);
732 
733 	free(reset_gpio, M_TEMP, reset_gpiolen);
734 
735 	for (timo = 40; timo > 0; timo--) {
736 		if (dwpcie_g12a_link_up(sc))
737 			break;
738 		delay(1000);
739 	}
740 	if (timo == 0)
741 		return ETIMEDOUT;
742 
743 	return 0;
744 }
745 
746 int
747 dwpcie_g12a_link_up(struct dwpcie_softc *sc)
748 {
749 	uint32_t reg;
750 
751 	reg = bus_space_read_4(sc->sc_iot, sc->sc_glue_ioh, PCIE_STATUS12);
752 	if ((reg & PCIE_STATUS12_SMLH_LINK_UP) &&
753 	    (reg & PCIE_STATUS12_RDLH_LINK_UP) &&
754 	    (reg & PCIE_STATUS12_LTSSM_MASK) == PCIE_STATUS12_LTSSM_UP)
755 		return 1;
756 	return 0;
757 }
758 
759 int
760 dwpcie_imx8mq_init(struct dwpcie_softc *sc)
761 {
762 	uint32_t *clkreq_gpio, *disable_gpio, *reset_gpio;
763 	ssize_t clkreq_gpiolen, disable_gpiolen, reset_gpiolen;
764 	struct regmap *anatop, *gpr, *phy;
765 	uint32_t off, reg;
766 	int error, timo;
767 
768 	if (OF_is_compatible(sc->sc_node, "fsl,imx8mm-pcie")) {
769 		anatop = regmap_bycompatible("fsl,imx8mm-anatop");
770 		gpr = regmap_bycompatible("fsl,imx8mm-iomuxc-gpr");
771 		phy = regmap_bycompatible("fsl,imx7d-pcie-phy");
772 		KASSERT(phy != NULL);
773 	} else {
774 		anatop = regmap_bycompatible("fsl,imx8mq-anatop");
775 		gpr = regmap_bycompatible("fsl,imx8mq-iomuxc-gpr");
776 	}
777 	KASSERT(anatop != NULL);
778 	KASSERT(gpr != NULL);
779 
780 	clkreq_gpiolen = OF_getproplen(sc->sc_node, "clkreq-gpio");
781 	disable_gpiolen = OF_getproplen(sc->sc_node, "disable-gpio");
782 	reset_gpiolen = OF_getproplen(sc->sc_node, "reset-gpio");
783 
784 	if (clkreq_gpiolen > 0) {
785 		clkreq_gpio = malloc(clkreq_gpiolen, M_TEMP, M_WAITOK);
786 		OF_getpropintarray(sc->sc_node, "clkreq-gpio", clkreq_gpio,
787 		    clkreq_gpiolen);
788 		gpio_controller_config_pin(clkreq_gpio, GPIO_CONFIG_OUTPUT);
789 		gpio_controller_set_pin(clkreq_gpio, 1);
790 	}
791 
792 	if (disable_gpiolen > 0) {
793 		disable_gpio = malloc(disable_gpiolen, M_TEMP, M_WAITOK);
794 		OF_getpropintarray(sc->sc_node, "disable-gpio", disable_gpio,
795 		    disable_gpiolen);
796 		gpio_controller_config_pin(disable_gpio, GPIO_CONFIG_OUTPUT);
797 		gpio_controller_set_pin(disable_gpio, 0);
798 	}
799 
800 	if (reset_gpiolen > 0) {
801 		reset_gpio = malloc(reset_gpiolen, M_TEMP, M_WAITOK);
802 		OF_getpropintarray(sc->sc_node, "reset-gpio", reset_gpio,
803 		    reset_gpiolen);
804 		gpio_controller_config_pin(reset_gpio, GPIO_CONFIG_OUTPUT);
805 		gpio_controller_set_pin(reset_gpio, 1);
806 	}
807 
808 	power_domain_enable(sc->sc_node);
809 	reset_assert(sc->sc_node, "pciephy");
810 	reset_assert(sc->sc_node, "apps");
811 
812 	reg = regmap_read_4(gpr, IOMUXC_GPR12);
813 	if (OF_getpropint(sc->sc_node, "ctrl-id", 0) == 0) {
814 		off = IOMUXC_GPR14;
815 		reg &= ~IMX8MQ_GPR_PCIE1_DEVICE_TYPE_MASK;
816 		reg |= IMX8MQ_GPR_PCIE1_DEVICE_TYPE_RC;
817 	} else {
818 		off = IOMUXC_GPR16;
819 		reg &= ~IMX8MQ_GPR_PCIE2_DEVICE_TYPE_MASK;
820 		reg |= IMX8MQ_GPR_PCIE2_DEVICE_TYPE_RC;
821 	}
822 	regmap_write_4(gpr, IOMUXC_GPR12, reg);
823 
824 	if (OF_is_compatible(sc->sc_node, "fsl,imx8mm-pcie")) {
825 		if (OF_getproplen(sc->sc_node, "ext_osc") == 0 ||
826 		    OF_getpropint(sc->sc_node, "ext_osc", 0)) {
827 			reg = regmap_read_4(gpr, off);
828 			reg &= ~(IMX8MQ_GPR_PCIE_REF_USE_PAD |
829 			    IMX8MM_GPR_PCIE_SSC_EN |
830 			    IMX8MM_GPR_PCIE_POWER_OFF |
831 			    IMX8MM_GPR_PCIE_REF_CLK_MASK);
832 			reg |= (IMX8MM_GPR_PCIE_AUX_EN |
833 			    IMX8MM_GPR_PCIE_REF_CLK_EXT);
834 			regmap_write_4(gpr, off, reg);
835 			delay(100);
836 			reg = regmap_read_4(gpr, off);
837 			reg |= IMX8MM_GPR_PCIE_CMN_RST;
838 			regmap_write_4(gpr, off, reg);
839 			delay(200);
840 		} else {
841 			reg = regmap_read_4(gpr, off);
842 			reg &= ~(IMX8MQ_GPR_PCIE_REF_USE_PAD |
843 			    IMX8MM_GPR_PCIE_SSC_EN |
844 			    IMX8MM_GPR_PCIE_POWER_OFF |
845 			    IMX8MM_GPR_PCIE_REF_CLK_MASK);
846 			reg |= (IMX8MM_GPR_PCIE_AUX_EN |
847 			    IMX8MM_GPR_PCIE_REF_CLK_PLL);
848 			regmap_write_4(gpr, off, reg);
849 			delay(100);
850 			regmap_write_4(phy, IMX8MM_PCIE_PHY_CMN_REG62,
851 			    IMX8MM_PCIE_PHY_CMN_REG62_PLL_CLK_OUT);
852 			regmap_write_4(phy, IMX8MM_PCIE_PHY_CMN_REG64,
853 			    IMX8MM_PCIE_PHY_CMN_REG64_AUX_RX_TX_TERM);
854 			reg = regmap_read_4(gpr, off);
855 			reg |= IMX8MM_GPR_PCIE_CMN_RST;
856 			regmap_write_4(gpr, off, reg);
857 			delay(200);
858 			regmap_write_4(phy, IMX8MM_PCIE_PHY_TRSV_REG5,
859 			    IMX8MM_PCIE_PHY_TRSV_REG5_GEN1_DEEMP);
860 			regmap_write_4(phy, IMX8MM_PCIE_PHY_TRSV_REG6,
861 			    IMX8MM_PCIE_PHY_TRSV_REG6_GEN2_DEEMP);
862 		}
863 	} else {
864 		if (OF_getproplen(sc->sc_node, "ext_osc") == 0 ||
865 		    OF_getpropint(sc->sc_node, "ext_osc", 0)) {
866 			reg = regmap_read_4(gpr, off);
867 			reg |= IMX8MQ_GPR_PCIE_REF_USE_PAD;
868 			regmap_write_4(gpr, off, reg);
869 		} else {
870 			reg = regmap_read_4(gpr, off);
871 			reg &= ~IMX8MQ_GPR_PCIE_REF_USE_PAD;
872 			regmap_write_4(gpr, off, reg);
873 
874 			regmap_write_4(anatop, ANATOP_PLLOUT_CTL,
875 			    ANATOP_PLLOUT_CTL_CKE |
876 			    ANATOP_PLLOUT_CTL_SEL_SYSPLL1);
877 			regmap_write_4(anatop, ANATOP_PLLOUT_DIV,
878 			    ANATOP_PLLOUT_DIV_SYSPLL1);
879 		}
880 	}
881 
882 	clock_enable(sc->sc_node, "pcie_phy");
883 	clock_enable(sc->sc_node, "pcie_bus");
884 	clock_enable(sc->sc_node, "pcie");
885 	clock_enable(sc->sc_node, "pcie_aux");
886 
887 	/* Allow clocks to stabilize. */
888 	delay(200);
889 
890 	if (reset_gpiolen > 0) {
891 		gpio_controller_set_pin(reset_gpio, 1);
892 		delay(100000);
893 		gpio_controller_set_pin(reset_gpio, 0);
894 	}
895 
896 	reset_deassert(sc->sc_node, "pciephy");
897 
898 	if (OF_is_compatible(sc->sc_node, "fsl,imx8mm-pcie")) {
899 		for (timo = 2000; timo > 0; timo--) {
900 			if (regmap_read_4(phy, IMX8MM_PCIE_PHY_CMN_REG75) ==
901 			    IMX8MM_PCIE_PHY_CMN_REG75_PLL_DONE)
902 				break;
903 			delay(10);
904 		}
905 		if (timo == 0) {
906 			error = ETIMEDOUT;
907 			goto err;
908 		}
909 	}
910 
911 	reg = HREAD4(sc, 0x100000 + PCIE_RC_LCR);
912 	reg &= ~PCIE_RC_LCR_L1EL_MASK;
913 	reg |= PCIE_RC_LCR_L1EL_64US;
914 	HWRITE4(sc, 0x100000 + PCIE_RC_LCR, reg);
915 
916 	dwpcie_link_config(sc);
917 
918 	reg = HREAD4(sc, PCIE_RC_LCR);
919 	reg &= ~PCIE_RC_LCR_MAX_LINK_SPEEDS_MASK;
920 	reg |= PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN1;
921 	HWRITE4(sc, PCIE_RC_LCR, reg);
922 
923 	reset_deassert(sc->sc_node, "apps");
924 
925 	for (timo = 20000; timo > 0; timo--) {
926 		if (dwpcie_link_up(sc))
927 			break;
928 		delay(10);
929 	}
930 	if (timo == 0) {
931 		error = ETIMEDOUT;
932 		goto err;
933 	}
934 
935 	if (OF_getpropint(sc->sc_node, "fsl,max-link-speed", 1) >= 2) {
936 		reg = HREAD4(sc, PCIE_RC_LCR);
937 		reg &= ~PCIE_RC_LCR_MAX_LINK_SPEEDS_MASK;
938 		reg |= PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN2;
939 		HWRITE4(sc, PCIE_RC_LCR, reg);
940 
941 		reg = HREAD4(sc, PCIE_LINK_WIDTH_SPEED_CTRL);
942 		reg |= PCIE_LINK_WIDTH_SPEED_CTRL_CHANGE;
943 		HWRITE4(sc, PCIE_LINK_WIDTH_SPEED_CTRL, reg);
944 
945 		for (timo = 20000; timo > 0; timo--) {
946 			if (dwpcie_link_up(sc))
947 				break;
948 			delay(10);
949 		}
950 		if (timo == 0) {
951 			error = ETIMEDOUT;
952 			goto err;
953 		}
954 	}
955 
956 	sc->sc_ih = fdt_intr_establish(sc->sc_node, IPL_AUDIO | IPL_MPSAFE,
957 	    dwpcie_imx8mq_intr, sc, sc->sc_dev.dv_xname);
958 
959 	/* Unmask INTx interrupts. */
960 	HWRITE4(sc, PCIE_GLOBAL_INT_MASK,
961 	    PCIE_GLOBAL_INT_MASK_INT_A | PCIE_GLOBAL_INT_MASK_INT_B |
962 	    PCIE_GLOBAL_INT_MASK_INT_C | PCIE_GLOBAL_INT_MASK_INT_D);
963 
964 	error = 0;
965 err:
966 	if (clkreq_gpiolen > 0)
967 		free(clkreq_gpio, M_TEMP, clkreq_gpiolen);
968 	if (disable_gpiolen > 0)
969 		free(disable_gpio, M_TEMP, disable_gpiolen);
970 	if (reset_gpiolen > 0)
971 		free(reset_gpio, M_TEMP, reset_gpiolen);
972 	return error;
973 }
974 
975 int
976 dwpcie_imx8mq_intr(void *arg)
977 {
978 	struct dwpcie_softc *sc = arg;
979 	uint32_t cause;
980 
981 	/* Acknowledge interrupts. */
982 	cause = HREAD4(sc, PCIE_GLOBAL_INT_CAUSE);
983 	HWRITE4(sc, PCIE_GLOBAL_INT_CAUSE, cause);
984 
985 	/* INTx interrupt, so not really ours. */
986 	return 0;
987 }
988 
989 void
990 dwpcie_atu_config(struct dwpcie_softc *sc, int index, int type,
991     uint64_t cpu_addr, uint64_t pci_addr, uint64_t size)
992 {
993 	uint32_t reg, off;
994 	int timo;
995 
996 	off = sc->sc_atu_base + IATU_OFFSET_UNROLL(index);
997 	if (!sc->sc_atu_unroll) {
998 		off = IATU_OFFSET_VIEWPORT;
999 		HWRITE4(sc, IATU_VIEWPORT, index);
1000 	}
1001 
1002 	HWRITE4(sc, off + IATU_LWR_BASE_ADDR, cpu_addr);
1003 	HWRITE4(sc, off + IATU_UPPER_BASE_ADDR, cpu_addr >> 32);
1004 	HWRITE4(sc, off + IATU_LIMIT_ADDR, cpu_addr + size - 1);
1005 	HWRITE4(sc, off + IATU_LWR_TARGET_ADDR, pci_addr);
1006 	HWRITE4(sc, off + IATU_UPPER_TARGET_ADDR, pci_addr >> 32);
1007 	HWRITE4(sc, off + IATU_REGION_CTRL_1, type);
1008 	HWRITE4(sc, off + IATU_REGION_CTRL_2, IATU_REGION_CTRL_2_REGION_EN);
1009 
1010 	for (timo = 5; timo > 0; timo--) {
1011 		reg = HREAD4(sc, off + IATU_REGION_CTRL_2);
1012 		if (reg & IATU_REGION_CTRL_2_REGION_EN)
1013 			break;
1014 		delay(9000);
1015 	}
1016 	if (timo == 0)
1017 		printf("%s:%d: timeout\n", __func__, __LINE__);
1018 }
1019 
1020 int
1021 dwpcie_link_up(struct dwpcie_softc *sc)
1022 {
1023 	uint32_t reg;
1024 
1025 	reg = HREAD4(sc, PCIE_PHY_DEBUG_R1);
1026 	if ((reg & PCIE_PHY_DEBUG_R1_XMLH_LINK_UP) != 0 &&
1027 	    (reg & PCIE_PHY_DEBUG_R1_XMLH_LINK_IN_TRAINING) == 0)
1028 		return 1;
1029 	return 0;
1030 }
1031 
1032 void
1033 dwpcie_attach_hook(struct device *parent, struct device *self,
1034     struct pcibus_attach_args *pba)
1035 {
1036 }
1037 
1038 int
1039 dwpcie_bus_maxdevs(void *v, int bus)
1040 {
1041 	struct dwpcie_softc *sc = v;
1042 
1043 	if (bus == sc->sc_bus || bus == sc->sc_bus + 1)
1044 		return 1;
1045 	return 32;
1046 }
1047 
1048 pcitag_t
1049 dwpcie_make_tag(void *v, int bus, int device, int function)
1050 {
1051 	return ((bus << 24) | (device << 19) | (function << 16));
1052 }
1053 
1054 void
1055 dwpcie_decompose_tag(void *v, pcitag_t tag, int *bp, int *dp, int *fp)
1056 {
1057 	if (bp != NULL)
1058 		*bp = (tag >> 24) & 0xff;
1059 	if (dp != NULL)
1060 		*dp = (tag >> 19) & 0x1f;
1061 	if (fp != NULL)
1062 		*fp = (tag >> 16) & 0x7;
1063 }
1064 
1065 int
1066 dwpcie_conf_size(void *v, pcitag_t tag)
1067 {
1068 	return PCIE_CONFIG_SPACE_SIZE;
1069 }
1070 
1071 pcireg_t
1072 dwpcie_conf_read(void *v, pcitag_t tag, int reg)
1073 {
1074 	struct dwpcie_softc *sc = v;
1075 	int bus, dev, fn;
1076 	uint32_t ret;
1077 
1078 	dwpcie_decompose_tag(sc, tag, &bus, &dev, &fn);
1079 	if (bus == sc->sc_bus) {
1080 		KASSERT(dev == 0);
1081 		return HREAD4(sc, tag | reg);
1082 	}
1083 
1084 	if (bus == sc->sc_bus + 1) {
1085 		dwpcie_atu_config(sc, IATU_VIEWPORT_INDEX1,
1086 		    IATU_REGION_CTRL_1_TYPE_CFG0,
1087 		    sc->sc_cfg0_base, tag, sc->sc_cfg0_size);
1088 		ret = bus_space_read_4(sc->sc_iot, sc->sc_cfg0_ioh, reg);
1089 	} else {
1090 		dwpcie_atu_config(sc, IATU_VIEWPORT_INDEX1,
1091 		    IATU_REGION_CTRL_1_TYPE_CFG1,
1092 		    sc->sc_cfg1_base, tag, sc->sc_cfg1_size);
1093 		ret = bus_space_read_4(sc->sc_iot, sc->sc_cfg1_ioh, reg);
1094 	}
1095 	if (sc->sc_num_viewport <= 2)
1096 		dwpcie_atu_config(sc, IATU_VIEWPORT_INDEX1,
1097 		    IATU_REGION_CTRL_1_TYPE_IO, sc->sc_io_base,
1098 		    sc->sc_io_bus_addr, sc->sc_io_size);
1099 
1100 	return ret;
1101 }
1102 
1103 void
1104 dwpcie_conf_write(void *v, pcitag_t tag, int reg, pcireg_t data)
1105 {
1106 	struct dwpcie_softc *sc = v;
1107 	int bus, dev, fn;
1108 
1109 	dwpcie_decompose_tag(sc, tag, &bus, &dev, &fn);
1110 	if (bus == sc->sc_bus) {
1111 		KASSERT(dev == 0);
1112 		HWRITE4(sc, tag | reg, data);
1113 		return;
1114 	}
1115 
1116 	if (bus == sc->sc_bus + 1) {
1117 		dwpcie_atu_config(sc, IATU_VIEWPORT_INDEX1,
1118 		    IATU_REGION_CTRL_1_TYPE_CFG0,
1119 		    sc->sc_cfg0_base, tag, sc->sc_cfg0_size);
1120 		bus_space_write_4(sc->sc_iot, sc->sc_cfg0_ioh, reg, data);
1121 	} else {
1122 		dwpcie_atu_config(sc, IATU_VIEWPORT_INDEX1,
1123 		    IATU_REGION_CTRL_1_TYPE_CFG1,
1124 		    sc->sc_cfg1_base, tag, sc->sc_cfg1_size);
1125 		bus_space_write_4(sc->sc_iot, sc->sc_cfg1_ioh, reg, data);
1126 	}
1127 	if (sc->sc_num_viewport <= 2)
1128 		dwpcie_atu_config(sc, IATU_VIEWPORT_INDEX1,
1129 		    IATU_REGION_CTRL_1_TYPE_IO, sc->sc_io_base,
1130 		    sc->sc_io_bus_addr, sc->sc_io_size);
1131 }
1132 
1133 int
1134 dwpcie_intr_map(struct pci_attach_args *pa, pci_intr_handle_t *ihp)
1135 {
1136 	int pin = pa->pa_rawintrpin;
1137 
1138 	if (pin == 0 || pin > PCI_INTERRUPT_PIN_MAX)
1139 		return -1;
1140 
1141 	if (pa->pa_tag == 0)
1142 		return -1;
1143 
1144 	ihp->ih_pc = pa->pa_pc;
1145 	ihp->ih_tag = pa->pa_intrtag;
1146 	ihp->ih_intrpin = pa->pa_intrpin;
1147 	ihp->ih_type = PCI_INTX;
1148 
1149 	return 0;
1150 }
1151 
1152 const char *
1153 dwpcie_intr_string(void *v, pci_intr_handle_t ih)
1154 {
1155 	switch (ih.ih_type) {
1156 	case PCI_MSI:
1157 		return "msi";
1158 	case PCI_MSIX:
1159 		return "msix";
1160 	}
1161 
1162 	return "intx";
1163 }
1164 
1165 void *
1166 dwpcie_intr_establish(void *v, pci_intr_handle_t ih, int level,
1167     struct cpu_info *ci, int (*func)(void *), void *arg, char *name)
1168 {
1169 	struct dwpcie_softc *sc = v;
1170 	void *cookie;
1171 
1172 	KASSERT(ih.ih_type != PCI_NONE);
1173 
1174 	if (ih.ih_type != PCI_INTX) {
1175 		uint64_t addr, data;
1176 
1177 		/* Assume hardware passes Requester ID as sideband data. */
1178 		data = pci_requester_id(ih.ih_pc, ih.ih_tag);
1179 		cookie = fdt_intr_establish_msi_cpu(sc->sc_node, &addr,
1180 		    &data, level, ci, func, arg, (void *)name);
1181 		if (cookie == NULL)
1182 			return NULL;
1183 
1184 		/* TODO: translate address to the PCI device's view */
1185 
1186 		if (ih.ih_type == PCI_MSIX) {
1187 			pci_msix_enable(ih.ih_pc, ih.ih_tag,
1188 			    &sc->sc_bus_memt, ih.ih_intrpin, addr, data);
1189 		} else
1190 			pci_msi_enable(ih.ih_pc, ih.ih_tag, addr, data);
1191 	} else {
1192 		int bus, dev, fn;
1193 		uint32_t reg[4];
1194 
1195 		dwpcie_decompose_tag(sc, ih.ih_tag, &bus, &dev, &fn);
1196 
1197 		reg[0] = bus << 16 | dev << 11 | fn << 8;
1198 		reg[1] = reg[2] = 0;
1199 		reg[3] = ih.ih_intrpin;
1200 
1201 		cookie = fdt_intr_establish_imap_cpu(sc->sc_node, reg,
1202 		    sizeof(reg), level, ci, func, arg, name);
1203 	}
1204 
1205 	return cookie;
1206 }
1207 
1208 void
1209 dwpcie_intr_disestablish(void *v, void *cookie)
1210 {
1211 	panic("%s", __func__);
1212 }
1213 
1214 int
1215 dwpcie_bs_iomap(bus_space_tag_t t, bus_addr_t addr, bus_size_t size,
1216     int flags, bus_space_handle_t *bshp)
1217 {
1218 	struct dwpcie_softc *sc = t->bus_private;
1219 	int i;
1220 
1221 	for (i = 0; i < sc->sc_nranges; i++) {
1222 		uint64_t pci_start = sc->sc_ranges[i].pci_base;
1223 		uint64_t pci_end = pci_start + sc->sc_ranges[i].size;
1224 		uint64_t phys_start = sc->sc_ranges[i].phys_base;
1225 
1226 		if ((sc->sc_ranges[i].flags & 0x03000000) == 0x01000000 &&
1227 		    addr >= pci_start && addr + size <= pci_end) {
1228 			return bus_space_map(sc->sc_iot,
1229 			    addr - pci_start + phys_start, size, flags, bshp);
1230 		}
1231 	}
1232 
1233 	return ENXIO;
1234 }
1235 
1236 int
1237 dwpcie_bs_memmap(bus_space_tag_t t, bus_addr_t addr, bus_size_t size,
1238     int flags, bus_space_handle_t *bshp)
1239 {
1240 	struct dwpcie_softc *sc = t->bus_private;
1241 	int i;
1242 
1243 	for (i = 0; i < sc->sc_nranges; i++) {
1244 		uint64_t pci_start = sc->sc_ranges[i].pci_base;
1245 		uint64_t pci_end = pci_start + sc->sc_ranges[i].size;
1246 		uint64_t phys_start = sc->sc_ranges[i].phys_base;
1247 
1248 		if ((sc->sc_ranges[i].flags & 0x03000000) == 0x02000000 &&
1249 		    addr >= pci_start && addr + size <= pci_end) {
1250 			return bus_space_map(sc->sc_iot,
1251 			    addr - pci_start + phys_start, size, flags, bshp);
1252 		}
1253 	}
1254 
1255 	return ENXIO;
1256 }
1257