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