summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2021-07-26 16:47:53 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2021-07-26 16:47:53 +0000
commit56723366f46f73851957e45bb0626922be30a797 (patch)
tree9e0b8a59992549ce6c2e40ddf55cf9ec582e43c0 /sys/arch
parent0a4c9f5c6b60c09862655b38b05b0024ad4dbd4a (diff)
Adjust driver for device tree binding changes.
Diffstat (limited to 'sys/arch')
-rw-r--r--sys/arch/arm64/dev/aplpcie.c82
1 files changed, 65 insertions, 17 deletions
diff --git a/sys/arch/arm64/dev/aplpcie.c b/sys/arch/arm64/dev/aplpcie.c
index 737459cd20b..ab8b5a9ed19 100644
--- a/sys/arch/arm64/dev/aplpcie.c
+++ b/sys/arch/arm64/dev/aplpcie.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: aplpcie.c,v 1.3 2021/06/11 12:23:52 kettenis Exp $ */
+/* $OpenBSD: aplpcie.c,v 1.4 2021/07/26 16:47:52 kettenis Exp $ */
/*
* Copyright (c) 2021 Mark Kettenis <kettenis@openbsd.org>
*
@@ -89,6 +89,8 @@ struct aplpcie_softc {
int sc_msi;
bus_addr_t sc_msi_doorbell;
+ uint32_t sc_msi_range[2];
+ struct interrupt_controller sc_msi_ic;
};
int aplpcie_match(struct device *, void *, void *);
@@ -107,7 +109,7 @@ aplpcie_match(struct device *parent, void *match, void *aux)
{
struct fdt_attach_args *faa = aux;
- return OF_is_compatible(faa->fa_node, "apple,pcie-m1");
+ return OF_is_compatible(faa->fa_node, "apple,pcie");
}
void aplpcie_attach_hook(struct device *, struct device *,
@@ -131,6 +133,10 @@ int aplpcie_bs_iomap(bus_space_tag_t, bus_addr_t, bus_size_t, int,
int aplpcie_bs_memmap(bus_space_tag_t, bus_addr_t, bus_size_t, int,
bus_space_handle_t *);
+void *aplpcie_intr_establish_msi(void *, uint64_t *, uint64_t *,
+ int, struct cpu_info *, int (*)(void *), void *, char *);
+void aplpcie_intr_disestablish_msi(void *);
+
void
aplpcie_attach(struct device *parent, struct device *self, void *aux)
{
@@ -140,22 +146,26 @@ aplpcie_attach(struct device *parent, struct device *self, void *aux)
uint32_t *ranges;
int i, j, nranges, rangeslen;
uint32_t bus_range[2];
-
- if (faa->fa_nreg < 6) {
- printf(": no registers\n");
- return;
- }
+ uint32_t msi_range[2];
+ char name[32];
+ int idx;
sc->sc_iot = faa->fa_iot;
- if (bus_space_map(sc->sc_iot, faa->fa_reg[0].addr,
- faa->fa_reg[0].size, 0, &sc->sc_ioh)) {
+
+ idx = OF_getindex(faa->fa_node, "config", "reg-names");
+ if (idx < 0 || idx >= faa->fa_nreg ||
+ bus_space_map(sc->sc_iot, faa->fa_reg[i].addr,
+ faa->fa_reg[i].size, 0, &sc->sc_ioh)) {
printf(": can't map registers\n");
return;
}
- for (i = 3; i < 6; i++) {
- if (bus_space_map(sc->sc_iot, faa->fa_reg[i].addr,
- faa->fa_reg[i].size, 0, &sc->sc_port_ioh[i - 3])) {
+ for (i = 0; i < 3; i++) {
+ snprintf(name, sizeof(name), "port%d", i);
+ idx = OF_getindex(faa->fa_node, name, "reg-names");
+ if (idx < 0 || idx > faa->fa_nreg ||
+ bus_space_map(sc->sc_iot, faa->fa_reg[idx].addr,
+ faa->fa_reg[idx].size, 0, &sc->sc_port_ioh[i])) {
printf(": can't map registers\n");
return;
}
@@ -163,10 +173,14 @@ aplpcie_attach(struct device *parent, struct device *self, void *aux)
sc->sc_dmat = faa->fa_dmat;
sc->sc_node = faa->fa_node;
- printf("\n");
sc->sc_msi_doorbell =
OF_getpropint64(sc->sc_node, "msi-doorbell", 0xffff000ULL);
+ if (OF_getpropintarray(sc->sc_node, "msi-ranges", sc->sc_msi_range,
+ sizeof(sc->sc_msi_range)) != sizeof(msi_range)) {
+ printf(": invalid msi-ranges property\n");
+ return;
+ }
/*
* Set things up such that we can share the 32 available MSIs
@@ -228,6 +242,8 @@ aplpcie_attach(struct device *parent, struct device *self, void *aux)
free(ranges, M_TEMP, rangeslen);
+ printf("\n");
+
/* Create extents for our address spaces. */
sc->sc_busex = extent_create("pcibus", 0, 255,
M_DEVBUF, NULL, 0, EX_WAITOK | EX_FILLED);
@@ -302,6 +318,13 @@ aplpcie_attach(struct device *parent, struct device *self, void *aux)
pba.pba_bus = sc->sc_bus;
pba.pba_flags |= PCI_FLAGS_MSI_ENABLED;
+ sc->sc_msi_ic.ic_node = sc->sc_node;
+ sc->sc_msi_ic.ic_cookie = sc;
+ sc->sc_msi_ic.ic_establish_msi = aplpcie_intr_establish_msi;
+ sc->sc_msi_ic.ic_disestablish = aplpcie_intr_disestablish_msi;
+ sc->sc_msi_ic.ic_barrier = intr_barrier;
+ fdt_intr_register(&sc->sc_msi_ic);
+
config_found(self, &pba, NULL);
}
@@ -444,10 +467,8 @@ aplpcie_intr_establish(void *v, pci_intr_handle_t ih, int level,
if (ih.ih_type != PCI_INTX) {
uint64_t addr, data;
- data = sc->sc_msi++;
- addr = sc->sc_msi_doorbell;
- cookie = fdt_intr_establish_idx_cpu(sc->sc_node, 3 + data,
- level, ci, func, arg, (void *)name);
+ cookie = fdt_intr_establish_msi_cpu(sc->sc_node, &addr,
+ &data, level, ci, func, arg, name);
if (cookie == NULL)
return NULL;
@@ -478,6 +499,33 @@ aplpcie_intr_disestablish(void *v, void *cookie)
{
}
+void *
+aplpcie_intr_establish_msi(void *cookie, uint64_t *addr, uint64_t *data,
+ int level, struct cpu_info *ci, int (*func)(void *), void *arg, char *name)
+{
+ struct aplpcie_softc *sc = cookie;
+ uint32_t cells[3];
+
+ if (sc->sc_msi >= sc->sc_msi_range[1])
+ return NULL;
+
+ *addr = sc->sc_msi_doorbell;
+ *data = sc->sc_msi++;
+
+ cells[0] = 0;
+ cells[1] = sc->sc_msi_range[0] + *data;
+ cells[2] = IST_LEVEL_HIGH;
+
+ return fdt_intr_parent_establish(&sc->sc_msi_ic, cells,
+ level, ci, func, arg, name);
+}
+
+void
+aplpcie_intr_disestablish_msi(void *cookie)
+{
+ fdt_intr_parent_disestablish(cookie);
+}
+
int
aplpcie_bs_iomap(bus_space_tag_t t, bus_addr_t addr, bus_size_t size,
int flags, bus_space_handle_t *bshp)