summaryrefslogtreecommitdiff
path: root/sys/arch/armv7/imx/imx.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch/armv7/imx/imx.c')
-rw-r--r--sys/arch/armv7/imx/imx.c201
1 files changed, 201 insertions, 0 deletions
diff --git a/sys/arch/armv7/imx/imx.c b/sys/arch/armv7/imx/imx.c
new file mode 100644
index 00000000000..99014634976
--- /dev/null
+++ b/sys/arch/armv7/imx/imx.c
@@ -0,0 +1,201 @@
+/* $OpenBSD: imx.c,v 1.1 2013/09/06 20:45:53 patrick Exp $ */
+/*
+ * Copyright (c) 2005,2008 Dale Rahn <drahn@openbsd.com>
+ * Copyright (c) 2012-2013 Patrick Wildt <patrick@blueri.se>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+#include <sys/malloc.h>
+#include <sys/reboot.h>
+#define _ARM32_BUS_DMA_PRIVATE
+#include <machine/bus.h>
+#include <arch/arm/armv7/armv7var.h>
+#include <armv7/imx/imxvar.h>
+
+struct arm32_bus_dma_tag imx_bus_dma_tag = {
+ 0,
+ 0,
+ NULL,
+ _bus_dmamap_create,
+ _bus_dmamap_destroy,
+ _bus_dmamap_load,
+ _bus_dmamap_load_mbuf,
+ _bus_dmamap_load_uio,
+ _bus_dmamap_load_raw,
+ _bus_dmamap_unload,
+ _bus_dmamap_sync,
+ _bus_dmamem_alloc,
+ _bus_dmamem_free,
+ _bus_dmamem_map,
+ _bus_dmamem_unmap,
+ _bus_dmamem_mmap,
+};
+
+struct board_dev {
+ char *name;
+ int unit;
+};
+
+struct board_dev phyflex_imx6_devs[] = {
+ { "imxccm", 0 },
+ { "imxiomuxc", 0 },
+ { "imxdog", 0 },
+ { "imxocotp", 0 },
+ { "imxuart", 3 },
+ { "imxgpio", 0 },
+ { "imxgpio", 1 },
+ { "imxgpio", 2 },
+ { "imxgpio", 3 },
+ { "imxgpio", 4 },
+ { "imxgpio", 5 },
+ { "imxgpio", 6 },
+ { "imxesdhc", 1 },
+ { "imxesdhc", 2 },
+ { "ehci", 0 },
+ { "imxenet", 0 },
+ { "ahci", 0 },
+ { NULL, 0 }
+};
+
+struct board_dev sabrelite_devs[] = {
+ { "imxccm", 0 },
+ { "imxiomuxc", 0 },
+ { "imxdog", 0 },
+ { "imxocotp", 0 },
+ { "imxuart", 1 },
+ { "imxgpio", 0 },
+ { "imxgpio", 1 },
+ { "imxgpio", 2 },
+ { "imxgpio", 3 },
+ { "imxgpio", 4 },
+ { "imxgpio", 5 },
+ { "imxgpio", 6 },
+ { "imxesdhc", 2 },
+ { "imxesdhc", 3 },
+ { "ehci", 0 },
+ { "imxenet", 0 },
+ { "ahci", 0 },
+ { NULL, 0 }
+};
+
+struct board_dev *board_devs;
+
+struct imx_dev *imx_devs = NULL;
+
+struct imx_softc {
+ struct device sc_dv;
+};
+
+int imx_match(struct device *, void *, void *);
+void imx_attach(struct device *, struct device *, void *);
+int imx_submatch(struct device *, void *, void *);
+
+struct cfattach imx_ca = {
+ sizeof(struct imx_softc), imx_match, imx_attach, NULL,
+ config_activate_children
+};
+
+struct cfdriver imx_cd = {
+ NULL, "imx", DV_DULL
+};
+
+int
+imx_match(struct device *parent, void *cfdata, void *aux)
+{
+ return (1);
+}
+
+void
+imx_attach(struct device *parent, struct device *self, void *aux)
+{
+ struct board_dev *bd;
+
+ switch (board_id) {
+ case BOARD_ID_IMX6_PHYFLEX:
+ printf(": PhyFLEX-i.MX6\n");
+ imx6_init();
+ board_devs = phyflex_imx6_devs;
+ break;
+ case BOARD_ID_IMX6_SABRELITE:
+ printf(": i.MX6 SABRE Lite\n");
+ imx6_init();
+ board_devs = sabrelite_devs;
+ break;
+ default:
+ printf("\n");
+ panic("%s: board type 0x%x unknown", __func__, board_id);
+ }
+
+ /* Directly configure on-board devices (dev* in config file). */
+ for (bd = board_devs; bd->name != NULL; bd++) {
+ struct imx_dev *id = imx_find_dev(bd->name, bd->unit);
+ struct imx_attach_args ia;
+
+ if (id == NULL)
+ printf("%s: device %s unit %d not found\n",
+ self->dv_xname, bd->name, bd->unit);
+
+ memset(&ia, 0, sizeof(ia));
+ ia.ia_dev = id;
+ ia.ia_iot = &armv7_bs_tag;
+ ia.ia_dmat = &imx_bus_dma_tag;
+
+ if (config_found_sm(self, &ia, NULL, imx_submatch) == NULL)
+ printf("%s: device %s unit %d not configured\n",
+ self->dv_xname, bd->name, bd->unit);
+ }
+}
+
+/*
+ * We do direct configuration of devices on this SoC "bus", so we
+ * never call the child device's match function at all (it can be
+ * NULL in the struct cfattach).
+ */
+int
+imx_submatch(struct device *parent, void *child, void *aux)
+{
+ struct cfdata *cf = child;
+ struct imx_attach_args *ia = aux;
+
+ if (strcmp(cf->cf_driver->cd_name, ia->ia_dev->name) == 0)
+ return (1);
+
+ /* "These are not the droids you are looking for." */
+ return (0);
+}
+
+void
+imx_set_devs(struct imx_dev *devs)
+{
+ imx_devs = devs;
+}
+
+struct imx_dev *
+imx_find_dev(const char *name, int unit)
+{
+ struct imx_dev *id;
+
+ if (imx_devs == NULL)
+ panic("%s: imx_devs == NULL", __func__);
+
+ for (id = imx_devs; id->name != NULL; id++) {
+ if (id->unit == unit && strcmp(id->name, name) == 0)
+ return (id);
+ }
+
+ return (NULL);
+}