summaryrefslogtreecommitdiffstats
path: root/sys/dev/fdt/dwpcie.c
diff options
context:
space:
mode:
authorkettenis <kettenis@openbsd.org>2018-04-09 21:55:25 +0000
committerkettenis <kettenis@openbsd.org>2018-04-09 21:55:25 +0000
commitf2c2f0618ccba33f556b7072c02253658228d9bd (patch)
tree33e18893f324138dd9385becd87a42a4ca0b0cf7 /sys/dev/fdt/dwpcie.c
parentregen (diff)
downloadwireguard-openbsd-f2c2f0618ccba33f556b7072c02253658228d9bd.tar.xz
wireguard-openbsd-f2c2f0618ccba33f556b7072c02253658228d9bd.zip
Implement support for INTx interrupts on Marvell ARMADA 7K & 8K.
Diffstat (limited to 'sys/dev/fdt/dwpcie.c')
-rw-r--r--sys/dev/fdt/dwpcie.c38
1 files changed, 37 insertions, 1 deletions
diff --git a/sys/dev/fdt/dwpcie.c b/sys/dev/fdt/dwpcie.c
index f0cb1e80774..37881e5b2ac 100644
--- a/sys/dev/fdt/dwpcie.c
+++ b/sys/dev/fdt/dwpcie.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: dwpcie.c,v 1.4 2018/04/09 18:35:13 kettenis Exp $ */
+/* $OpenBSD: dwpcie.c,v 1.5 2018/04/09 21:55:25 kettenis Exp $ */
/*
* Copyright (c) 2018 Mark Kettenis <kettenis@openbsd.org>
*
@@ -57,6 +57,12 @@
#define PCIE_GLOBAL_STATUS_RDLH_LINK_UP (1 << 1)
#define PCIE_GLOBAL_STATUS_PHY_LINK_UP (1 << 9)
#define PCIE_PM_STATUS 0x8014
+#define PCIE_GLOBAL_INT_CAUSE 0x801c
+#define PCIE_GLOBAL_INT_MASK 0x8020
+#define PCIE_GLOBAL_INT_MASK_INT_A (1 << 9)
+#define PCIE_GLOBAL_INT_MASK_INT_B (1 << 10)
+#define PCIE_GLOBAL_INT_MASK_INT_C (1 << 11)
+#define PCIE_GLOBAL_INT_MASK_INT_D (1 << 12)
#define PCIE_ARCACHE_TRC 0x8050
#define PCIE_ARCACHE_TRC_DEFAULT 0x3511
#define PCIE_AWCACHE_TRC 0x8054
@@ -107,6 +113,8 @@ struct dwpcie_softc {
char sc_ioex_name[32];
char sc_memex_name[32];
int sc_bus;
+
+ void *sc_ih;
};
int dwpcie_match(struct device *, void *, void *);
@@ -130,6 +138,7 @@ dwpcie_match(struct device *parent, void *match, void *aux)
void dwpcie_armada8k_init(struct dwpcie_softc *);
int dwpcie_armada8k_link_up(struct dwpcie_softc *);
+int dwpcie_armada8k_intr(void *);
void dwpcie_attach_hook(struct device *, struct device *,
struct pcibus_attach_args *);
@@ -149,6 +158,9 @@ void *dwpcie_intr_establish(void *, pci_intr_handle_t, int,
int (*)(void *), void *, char *);
void dwpcie_intr_disestablish(void *, void *);
+void *dwpcie_armada8k_intr_establish(void *, pci_intr_handle_t, int,
+ int (*)(void *), void *, char *);
+
void
dwpcie_attach(struct device *parent, struct device *self, void *aux)
{
@@ -365,6 +377,14 @@ dwpcie_armada8k_init(struct dwpcie_softc *sc)
break;
delay(1000);
}
+
+ sc->sc_ih = arm_intr_establish_fdt(sc->sc_node, IPL_AUDIO | IPL_MPSAFE,
+ dwpcie_armada8k_intr, sc, sc->sc_dev.dv_xname);
+
+ /* Unmask INTx interrupts. */
+ HWRITE4(sc, PCIE_GLOBAL_INT_MASK,
+ PCIE_GLOBAL_INT_MASK_INT_A | PCIE_GLOBAL_INT_MASK_INT_B |
+ PCIE_GLOBAL_INT_MASK_INT_C | PCIE_GLOBAL_INT_MASK_INT_D);
}
int
@@ -378,6 +398,20 @@ dwpcie_armada8k_link_up(struct dwpcie_softc *sc)
return ((reg & mask) == mask);
}
+int
+dwpcie_armada8k_intr(void *arg)
+{
+ struct dwpcie_softc *sc = arg;
+ uint32_t cause;
+
+ /* Acknowledge interrupts. */
+ cause = HREAD4(sc, PCIE_GLOBAL_INT_CAUSE);
+ HWRITE4(sc, PCIE_GLOBAL_INT_CAUSE, cause);
+
+ /* INTx interrupt, so not really ours. */
+ return 0;
+}
+
void
dwpcie_atu_config(struct dwpcie_softc *sc, pcitag_t tag, int type)
{
@@ -487,6 +521,7 @@ dwpcie_intr_map(struct pci_attach_args *pa, pci_intr_handle_t *ihp)
ih->ih_pc = pa->pa_pc;
ih->ih_tag = pa->pa_intrtag;
ih->ih_intrpin = pa->pa_intrpin;
+ ih->ih_msi = 0;
*ihp = (pci_intr_handle_t)ih;
return 0;
@@ -590,4 +625,5 @@ dwpcie_intr_establish(void *v, pci_intr_handle_t ihp, int level,
void
dwpcie_intr_disestablish(void *v, void *cookie)
{
+ panic("%s", __func__);
}