| @@ -1,33 +1,33 @@ | | | @@ -1,33 +1,33 @@ |
1 | /* $NetBSD: rk3399_pcie.c,v 1.7 2019/11/29 00:36:22 jmcneill Exp $ */ | | 1 | /* $NetBSD: rk3399_pcie.c,v 1.8 2019/12/07 16:00:36 jmcneill Exp $ */ |
2 | /* | | 2 | /* |
3 | * Copyright (c) 2018 Mark Kettenis <kettenis@openbsd.org> | | 3 | * Copyright (c) 2018 Mark Kettenis <kettenis@openbsd.org> |
4 | * | | 4 | * |
5 | * Permission to use, copy, modify, and distribute this software for any | | 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 | | 6 | * purpose with or without fee is hereby granted, provided that the above |
7 | * copyright notice and this permission notice appear in all copies. | | 7 | * copyright notice and this permission notice appear in all copies. |
8 | * | | 8 | * |
9 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | | 9 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
10 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | | 10 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
11 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | | 11 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
12 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | | 12 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
13 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | | 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 | | 14 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
15 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | | 15 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
16 | */ | | 16 | */ |
17 | | | 17 | |
18 | #include <sys/cdefs.h> | | 18 | #include <sys/cdefs.h> |
19 | | | 19 | |
20 | __KERNEL_RCSID(1, "$NetBSD: rk3399_pcie.c,v 1.7 2019/11/29 00:36:22 jmcneill Exp $"); | | 20 | __KERNEL_RCSID(1, "$NetBSD: rk3399_pcie.c,v 1.8 2019/12/07 16:00:36 jmcneill Exp $"); |
21 | | | 21 | |
22 | #include <sys/param.h> | | 22 | #include <sys/param.h> |
23 | #include <sys/systm.h> | | 23 | #include <sys/systm.h> |
24 | #include <sys/bitops.h> | | 24 | #include <sys/bitops.h> |
25 | #include <sys/device.h> | | 25 | #include <sys/device.h> |
26 | #include <sys/extent.h> | | 26 | #include <sys/extent.h> |
27 | #include <sys/kmem.h> | | 27 | #include <sys/kmem.h> |
28 | | | 28 | |
29 | #include <machine/intr.h> | | 29 | #include <machine/intr.h> |
30 | #include <sys/bus.h> | | 30 | #include <sys/bus.h> |
31 | #include <dev/fdt/fdtvar.h> | | 31 | #include <dev/fdt/fdtvar.h> |
32 | #include <dev/fdt/syscon.h> | | 32 | #include <dev/fdt/syscon.h> |
33 | #include <arm/cpufunc.h> | | 33 | #include <arm/cpufunc.h> |
| @@ -111,30 +111,30 @@ __KERNEL_RCSID(1, "$NetBSD: rk3399_pcie. | | | @@ -111,30 +111,30 @@ __KERNEL_RCSID(1, "$NetBSD: rk3399_pcie. |
111 | #define PCIE_ATR_HDR_IO 0x6 | | 111 | #define PCIE_ATR_HDR_IO 0x6 |
112 | #define PCIE_ATR_HDR_CFG_TYPE0 0xa | | 112 | #define PCIE_ATR_HDR_CFG_TYPE0 0xa |
113 | #define PCIE_ATR_HDR_CFG_TYPE1 0xb | | 113 | #define PCIE_ATR_HDR_CFG_TYPE1 0xb |
114 | #define PCIE_ATR_HDR_RID __BIT(23) | | 114 | #define PCIE_ATR_HDR_RID __BIT(23) |
115 | | | 115 | |
116 | /* AXI region */ | | 116 | /* AXI region */ |
117 | #define PCIE_ATR_OB_REGION0_SIZE (32 * 1024 * 1024) | | 117 | #define PCIE_ATR_OB_REGION0_SIZE (32 * 1024 * 1024) |
118 | #define PCIE_ATR_OB_REGION_SIZE (1 * 1024 * 1024) | | 118 | #define PCIE_ATR_OB_REGION_SIZE (1 * 1024 * 1024) |
119 | | | 119 | |
120 | #define HREAD4(sc, reg) \ | | 120 | #define HREAD4(sc, reg) \ |
121 | bus_space_read_4((sc)->sc_iot, (sc)->sc_ioh, (reg)) | | 121 | bus_space_read_4((sc)->sc_iot, (sc)->sc_ioh, (reg)) |
122 | #define HWRITE4(sc, reg, val) \ | | 122 | #define HWRITE4(sc, reg, val) \ |
123 | bus_space_write_4((sc)->sc_iot, (sc)->sc_ioh, (reg), (val)) | | 123 | bus_space_write_4((sc)->sc_iot, (sc)->sc_ioh, (reg), (val)) |
124 | #define AXIREAD4(sc, reg) \ | | 124 | #define AXIPEEK4(sc, reg, valp) \ |
125 | bus_space_read_4((sc)->sc_iot, (sc)->sc_axi_ioh, (reg)) | | 125 | bus_space_peek_4((sc)->sc_iot, (sc)->sc_axi_ioh, (reg), (valp)) |
126 | #define AXIWRITE4(sc, reg, val) \ | | 126 | #define AXIPOKE4(sc, reg, val) \ |
127 | bus_space_write_4((sc)->sc_iot, (sc)->sc_axi_ioh, (reg), (val)) | | 127 | bus_space_poke_4((sc)->sc_iot, (sc)->sc_axi_ioh, (reg), (val)) |
128 | | | 128 | |
129 | struct rkpcie_softc { | | 129 | struct rkpcie_softc { |
130 | struct pcihost_softc sc_phsc; | | 130 | struct pcihost_softc sc_phsc; |
131 | bus_space_tag_t sc_iot; | | 131 | bus_space_tag_t sc_iot; |
132 | bus_space_handle_t sc_ioh; | | 132 | bus_space_handle_t sc_ioh; |
133 | bus_space_handle_t sc_axi_ioh; | | 133 | bus_space_handle_t sc_axi_ioh; |
134 | bus_addr_t sc_axi_addr; | | 134 | bus_addr_t sc_axi_addr; |
135 | bus_addr_t sc_apb_addr; | | 135 | bus_addr_t sc_apb_addr; |
136 | bus_size_t sc_axi_size; | | 136 | bus_size_t sc_axi_size; |
137 | bus_size_t sc_apb_size; | | 137 | bus_size_t sc_apb_size; |
138 | }; | | 138 | }; |
139 | | | 139 | |
140 | static int rkpcie_match(device_t, cfdata_t, void *); | | 140 | static int rkpcie_match(device_t, cfdata_t, void *); |
| @@ -530,50 +530,54 @@ rkpcie_conf_read(void *v, pcitag_t tag, | | | @@ -530,50 +530,54 @@ rkpcie_conf_read(void *v, pcitag_t tag, |
530 | int bus, dev, fn; | | 530 | int bus, dev, fn; |
531 | u_int reg; | | 531 | u_int reg; |
532 | | | 532 | |
533 | KASSERT(offset >= 0); | | 533 | KASSERT(offset >= 0); |
534 | KASSERT(offset < PCI_EXTCONF_SIZE); | | 534 | KASSERT(offset < PCI_EXTCONF_SIZE); |
535 | | | 535 | |
536 | rkpcie_decompose_tag(sc, tag, &bus, &dev, &fn); | | 536 | rkpcie_decompose_tag(sc, tag, &bus, &dev, &fn); |
537 | if (!rkpcie_conf_ok(bus, dev, fn, phsc->sc_bus_min)) | | 537 | if (!rkpcie_conf_ok(bus, dev, fn, phsc->sc_bus_min)) |
538 | return 0xffffffff; | | 538 | return 0xffffffff; |
539 | reg = (bus << 20) | (dev << 15) | (fn << 12) | offset; | | 539 | reg = (bus << 20) | (dev << 15) | (fn << 12) | offset; |
540 | | | 540 | |
541 | if (bus == phsc->sc_bus_min) | | 541 | if (bus == phsc->sc_bus_min) |
542 | return HREAD4(sc, PCIE_RC_NORMAL_BASE + reg); | | 542 | return HREAD4(sc, PCIE_RC_NORMAL_BASE + reg); |
543 | else | | 543 | else { |
544 | return AXIREAD4(sc, reg); | | 544 | uint32_t val; |
| | | 545 | if (AXIPEEK4(sc, reg, &val) != 0) |
| | | 546 | return 0xffffffff; |
| | | 547 | return val; |
| | | 548 | } |
545 | } | | 549 | } |
546 | | | 550 | |
547 | void | | 551 | void |
548 | rkpcie_conf_write(void *v, pcitag_t tag, int offset, pcireg_t data) | | 552 | rkpcie_conf_write(void *v, pcitag_t tag, int offset, pcireg_t data) |
549 | { | | 553 | { |
550 | struct rkpcie_softc *sc = v; | | 554 | struct rkpcie_softc *sc = v; |
551 | struct pcihost_softc *phsc = &sc->sc_phsc; | | 555 | struct pcihost_softc *phsc = &sc->sc_phsc; |
552 | int bus, dev, fn; | | 556 | int bus, dev, fn; |
553 | u_int reg; | | 557 | u_int reg; |
554 | | | 558 | |
555 | KASSERT(offset >= 0); | | 559 | KASSERT(offset >= 0); |
556 | KASSERT(offset < PCI_EXTCONF_SIZE); | | 560 | KASSERT(offset < PCI_EXTCONF_SIZE); |
557 | | | 561 | |
558 | rkpcie_decompose_tag(sc, tag, &bus, &dev, &fn); | | 562 | rkpcie_decompose_tag(sc, tag, &bus, &dev, &fn); |
559 | if (!rkpcie_conf_ok(bus, dev, fn, phsc->sc_bus_min)) | | 563 | if (!rkpcie_conf_ok(bus, dev, fn, phsc->sc_bus_min)) |
560 | return; | | 564 | return; |
561 | reg = (bus << 20) | (dev << 15) | (fn << 12) | offset; | | 565 | reg = (bus << 20) | (dev << 15) | (fn << 12) | offset; |
562 | | | 566 | |
563 | if (bus == phsc->sc_bus_min) | | 567 | if (bus == phsc->sc_bus_min) |
564 | HWRITE4(sc, PCIE_RC_NORMAL_BASE + reg, data); | | 568 | HWRITE4(sc, PCIE_RC_NORMAL_BASE + reg, data); |
565 | else | | 569 | else |
566 | AXIWRITE4(sc, reg, data); | | 570 | AXIPOKE4(sc, reg, data); |
567 | } | | 571 | } |
568 | | | 572 | |
569 | static int | | 573 | static int |
570 | rkpcie_conf_hook(void *v, int b, int d, int f, pcireg_t id) | | 574 | rkpcie_conf_hook(void *v, int b, int d, int f, pcireg_t id) |
571 | { | | 575 | { |
572 | return (PCI_CONF_DEFAULT & ~PCI_CONF_ENABLE_BM) | PCI_CONF_MAP_ROM; | | 576 | return (PCI_CONF_DEFAULT & ~PCI_CONF_ENABLE_BM) | PCI_CONF_MAP_ROM; |
573 | } | | 577 | } |
574 | | | 578 | |
575 | /* INTx interrupt controller */ | | 579 | /* INTx interrupt controller */ |
576 | static void * | | 580 | static void * |
577 | rkpcie_intx_establish(device_t dev, u_int *specifier, int ipl, int flags, | | 581 | rkpcie_intx_establish(device_t dev, u_int *specifier, int ipl, int flags, |
578 | int (*func)(void *), void *arg) | | 582 | int (*func)(void *), void *arg) |
579 | { | | 583 | { |