summaryrefslogtreecommitdiff
path: root/sys/arch/armv7/sunxi/sxiccmu.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch/armv7/sunxi/sxiccmu.c')
-rw-r--r--sys/arch/armv7/sunxi/sxiccmu.c56
1 files changed, 34 insertions, 22 deletions
diff --git a/sys/arch/armv7/sunxi/sxiccmu.c b/sys/arch/armv7/sunxi/sxiccmu.c
index 5adf894d4e5..791189d39c9 100644
--- a/sys/arch/armv7/sunxi/sxiccmu.c
+++ b/sys/arch/armv7/sunxi/sxiccmu.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sxiccmu.c,v 1.20 2016/10/07 18:52:36 patrick Exp $ */
+/* $OpenBSD: sxiccmu.c,v 1.21 2016/10/09 11:14:22 kettenis Exp $ */
/*
* Copyright (c) 2007,2009 Dale Rahn <drahn@openbsd.org>
* Copyright (c) 2013 Artturi Alm
@@ -28,13 +28,14 @@
#include <arm/cpufunc.h>
#include <machine/bus.h>
+#include <machine/fdt.h>
#include <machine/intr.h>
-#include <armv7/armv7/armv7var.h>
#include <armv7/sunxi/sunxireg.h>
#include <dev/ofw/openfirm.h>
#include <dev/ofw/ofw_clock.h>
+#include <dev/ofw/fdt.h>
#ifdef DEBUG_CCMU
#define DPRINTF(x) do { printf x; } while (0)
@@ -64,10 +65,11 @@ struct sxiccmu_softc {
struct reset_device sc_rd;
};
+int sxiccmu_match(struct device *, void *, void *);
void sxiccmu_attach(struct device *, struct device *, void *);
struct cfattach sxiccmu_ca = {
- sizeof (struct sxiccmu_softc), NULL, sxiccmu_attach
+ sizeof (struct sxiccmu_softc), sxiccmu_match, sxiccmu_attach
};
struct cfdriver sxiccmu_cd = {
@@ -81,39 +83,49 @@ int sxiccmu_ccu_set_frequency(void *, uint32_t *, uint32_t);
void sxiccmu_ccu_enable(void *, uint32_t *, int);
void sxiccmu_ccu_reset(void *, uint32_t *, int);
-void
-sxiccmu_attach(struct device *parent, struct device *self, void *args)
+int
+sxiccmu_match(struct device *parent, void *match, void *aux)
{
- struct sxiccmu_softc *sc = (struct sxiccmu_softc *)self;
- struct armv7_attach_args *aa = args;
- int node;
+ struct fdt_attach_args *faa = aux;
- sc->sc_iot = aa->aa_iot;
+ if (faa->fa_node == OF_finddevice("/clocks")) {
+ int node = OF_parent(faa->fa_node);
- if (bus_space_map(sc->sc_iot, aa->aa_dev->mem[0].addr,
- aa->aa_dev->mem[0].size, 0, &sc->sc_ioh))
- panic("sxiccmu_attach: bus_space_map failed!");
+ return (OF_is_compatible(node, "allwinner,sun4i-a10") ||
+ OF_is_compatible(node, "allwinner,sun5i-a10s") ||
+ OF_is_compatible(node, "allwinner,sun5i-r8") ||
+ OF_is_compatible(node, "allwinner,sun7i-a20") ||
+ OF_is_compatible(node, "allwinner,sun8i-h3"));
+ }
- node = OF_finddevice("/clocks");
- if (node == -1)
- panic("%s: can't find clocks", __func__);
+ return OF_is_compatible(faa->fa_node, "allwinner,sun8i-h3-ccu");
+}
- printf("\n");
+void
+sxiccmu_attach(struct device *parent, struct device *self, void *aux)
+{
+ struct sxiccmu_softc *sc = (struct sxiccmu_softc *)self;
+ struct fdt_attach_args *faa = aux;
+ int node = faa->fa_node;
- for (node = OF_child(node); node; node = OF_peer(node))
- sxiccmu_attach_clock(sc, node);
+ sc->sc_iot = faa->fa_iot;
+ if (faa->fa_nreg > 0 && bus_space_map(sc->sc_iot,
+ faa->fa_reg[0].addr, faa->fa_reg[0].size, 0, &sc->sc_ioh))
+ panic("%s: bus_space_map failed!", __func__);
- node = OF_finddevice("/soc/clock@01c20000");
- if (node == -1)
- return;
+ printf("\n");
if (OF_is_compatible(node, "allwinner,sun8i-h3-ccu")) {
+ KASSERT(faa->fa_nreg > 0);
sc->sc_gates = sun8i_h3_gates;
sc->sc_ngates = nitems(sun8i_h3_gates);
sc->sc_resets = sun8i_h3_resets;
sc->sc_nresets = nitems(sun8i_h3_resets);
+ } else {
+ for (node = OF_child(node); node; node = OF_peer(node))
+ sxiccmu_attach_clock(sc, node);
}
-
+
if (sc->sc_gates) {
sc->sc_cd.cd_node = node;
sc->sc_cd.cd_cookie = sc;