Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/arm/imx Add initial support for Freescale i.MX23 ap...



details:   https://anonhg.NetBSD.org/src/rev/f660992dda98
branches:  trunk
changeset: 782795:f660992dda98
user:      jkunz <jkunz%NetBSD.org@localhost>
date:      Tue Nov 20 19:06:12 2012 +0000

description:
Add initial support for Freescale i.MX23 application processor.
Contributed by Petri Laakso.

diffstat:

 sys/arch/arm/imx/files.imx23        |    43 +
 sys/arch/arm/imx/imx23_apbdma.c     |   279 +++++++
 sys/arch/arm/imx/imx23_apbdma.h     |    87 ++
 sys/arch/arm/imx/imx23_apbdmareg.h  |    53 +
 sys/arch/arm/imx/imx23_apbh.c       |   173 ++++
 sys/arch/arm/imx/imx23_apbhdmareg.h |   201 +++++
 sys/arch/arm/imx/imx23_apbx.c       |   173 ++++
 sys/arch/arm/imx/imx23_apbxdmareg.h |    40 +
 sys/arch/arm/imx/imx23_clkctrlreg.h |   316 +++++++++
 sys/arch/arm/imx/imx23_digctlreg.h  |   568 ++++++++++++++++
 sys/arch/arm/imx/imx23_dma.c        |    39 +
 sys/arch/arm/imx/imx23_emireg.h     |   544 +++++++++++++++
 sys/arch/arm/imx/imx23_icoll.c      |   364 ++++++++++
 sys/arch/arm/imx/imx23_icollreg.h   |   362 ++++++++++
 sys/arch/arm/imx/imx23_intr.h       |    40 +
 sys/arch/arm/imx/imx23_pinctrlreg.h |  1222 +++++++++++++++++++++++++++++++++++
 sys/arch/arm/imx/imx23_plcom.c      |   116 +++
 sys/arch/arm/imx/imx23_powerreg.h   |   386 +++++++++++
 sys/arch/arm/imx/imx23_rtcreg.h     |   210 ++++++
 sys/arch/arm/imx/imx23_space.c      |   205 +++++
 sys/arch/arm/imx/imx23_ssp.c        |   509 ++++++++++++++
 sys/arch/arm/imx/imx23_sspreg.h     |   242 ++++++
 sys/arch/arm/imx/imx23_timrot.c     |   333 +++++++++
 sys/arch/arm/imx/imx23_timrotreg.h  |   191 +++++
 sys/arch/arm/imx/imx23_uartappreg.h |    40 +
 sys/arch/arm/imx/imx23_uartdbgreg.h |   243 ++++++
 sys/arch/arm/imx/imx23var.h         |    64 +
 27 files changed, 7043 insertions(+), 0 deletions(-)

diffs (truncated from 7151 to 300 lines):

diff -r e02bd0b38d1c -r f660992dda98 sys/arch/arm/imx/files.imx23
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/arch/arm/imx/files.imx23      Tue Nov 20 19:06:12 2012 +0000
@@ -0,0 +1,43 @@
+# $Id: files.imx23,v 1.1 2012/11/20 19:06:12 jkunz Exp $
+#
+# Freescale i.MX23 applications processor configuration info.
+#
+
+file   arch/arm/imx/imx23_space.c      apbh|apbx
+file   arch/arm/imx/imx23_dma.c        apbh|apbx
+
+# APBH bus interface
+device apbh {addr=0, size=0, irq=-1} : bus_space_generic
+attach apbh at mainbus
+file   arch/arm/imx/imx23_apbh.c       apbh
+
+# APBX bus interface
+device apbx {addr=0, size=0, irq=-1} : bus_space_generic
+attach apbx at mainbus
+file   arch/arm/imx/imx23_apbx.c       apbx
+
+# Interrupt controller
+include "arch/arm/pic/files.pic"
+device icoll: pic, pic_splfuncs
+attach icoll at apbh
+file   arch/arm/imx/imx23_icoll.c      icoll
+file   arch/arm/arm32/irq_dispatch.S
+
+# Synchronous serial port (for SD/MMC)
+device ssp: sdmmcbus
+attach ssp at apbh
+file   arch/arm/imx/imx23_ssp.c        ssp
+
+# PL011 Debug console
+attach plcom at apbx with imx23plcom
+file   arch/arm/imx/imx23_plcom.c      imx23plcom
+
+# Timers and rotary decoder
+device timrot
+attach timrot at apbx
+file   arch/arm/imx/imx23_timrot.c     timrot
+
+# APB{H,X} DMA
+device apbdma
+attach apbdma at apbh, apbx
+file   arch/arm/imx/imx23_apbdma.c     apbdma
diff -r e02bd0b38d1c -r f660992dda98 sys/arch/arm/imx/imx23_apbdma.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/arch/arm/imx/imx23_apbdma.c   Tue Nov 20 19:06:12 2012 +0000
@@ -0,0 +1,279 @@
+/* $Id: imx23_apbdma.c,v 1.1 2012/11/20 19:06:12 jkunz Exp $ */
+
+/*
+ * Copyright (c) 2012 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Petri Laakso.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/device.h>
+#include <sys/errno.h>
+#include <sys/kmem.h>
+#include <sys/queue.h>
+#include <sys/systm.h>
+
+#include <arm/imx/imx23_apbdmareg.h>
+#include <arm/imx/imx23_apbhdmareg.h>
+#include <arm/imx/imx23_apbxdmareg.h>
+#include <arm/imx/imx23_apbdma.h>
+#include <arm/imx/imx23var.h>
+
+static int     apbdma_match(device_t, cfdata_t, void *);
+static void    apbdma_attach(device_t, device_t, void *);
+static int     apbdma_activate(device_t, enum devact);
+
+#define APBDMA_SOFT_RST_LOOP 455 /* At least 1 us ... */
+#define DMACTRL_RD(sc, reg)                                            \
+               bus_space_read_4(sc->sc_iot, sc->sc_hdl, (reg))
+#define DMACTRL_WR(sc, reg, val)                                       \
+               bus_space_write_4(sc->sc_iot, sc->sc_hdl, (reg), (val))
+
+struct apbdma_softc {
+       device_t sc_dev;
+       bus_space_tag_t sc_iot;
+       bus_space_handle_t sc_hdl;
+       bus_dma_tag_t sc_dmat;
+       bus_dmamap_t sc_dmamp;
+       struct imx23_dma_channel *sc_channel;
+       int n_channel;
+};
+
+struct imx23_dma_cmd {
+       uint32_t next_cmd;
+       uint32_t cmd;
+       uint32_t buffer;
+       uint32_t pio[CMDPIOWORDS_MAX];
+       SIMPLEQ_ENTRY(imx23_dma_cmd) entries;
+};
+
+struct imx23_dma_channel {
+       SIMPLEQ_HEAD(simplehead, imx23_dma_cmd) head;
+       struct simplehead *headp;
+       struct apbdma_softc *sc;
+};
+
+CFATTACH_DECL3_NEW(apbdma,
+       sizeof(struct apbdma_softc),
+       apbdma_match,
+       apbdma_attach,
+       NULL,
+       apbdma_activate,
+       NULL,
+       NULL,
+       0);
+
+static void    apbdma_reset(struct apbdma_softc *);
+
+static int
+apbdma_match(device_t parent, cfdata_t match, void *aux)
+{
+       struct apb_attach_args *aa = aux;
+
+       if (aa->aa_addr == HW_APBHDMA_BASE && aa->aa_size == HW_APBHDMA_SIZE)
+                       return 1;
+
+       if (aa->aa_addr == HW_APBXDMA_BASE && aa->aa_size == HW_APBXDMA_SIZE)
+                       return 1;
+
+       return 0;
+}
+
+static void
+apbdma_attach(device_t parent, device_t self, void *aux)
+{
+       struct apb_attach_args *aa = aux;
+       struct apbdma_softc *sc = device_private(self);
+       //struct apb_softc *scp = device_private(parent);
+
+//     static int apbdma_attached = 0;
+//     struct imx23_dma_channel *chan;
+//     int i;
+       int error;
+
+//     if (apbdma_attached)
+//             return;
+
+       sc->sc_dev = self;
+       sc->sc_iot = aa->aa_iot;
+       sc->sc_dmat = aa->aa_dmat;
+
+       /*
+        * Parent bus softc has a pointer to DMA controller device_t for
+        * specific bus. As different busses need different instances of the
+        * DMA driver. The apb_softc.dmac is set up here. Now device drivers
+        * which use DMA can pass apb_softc.dmac from their parent to apbdma
+        * functions.
+        */
+       if (bus_space_map(sc->sc_iot,
+           aa->aa_addr, aa->aa_size, 0, &(sc->sc_hdl))) {
+               aprint_error_dev(sc->sc_dev, "unable to map bus space\n");
+               return;
+       }
+
+       error = bus_dmamap_create(sc->sc_dmat, PAGE_SIZE, 1,
+           PAGE_SIZE, 0, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW, &sc->sc_dmamp);
+       if (error) {
+               aprint_error_dev(sc->sc_dev,
+                       "couldn't create dma map. (error=%d)\n", error);
+               return;
+       }
+#ifdef notyet  
+       if (aa->aa_addr == HW_APBHDMA_BASE && aa->aa_size == HW_APBHDMA_SIZE) {
+               sc->sc_channel = kmem_alloc(sizeof(struct imx23_dma_channel)
+                   * APBH_DMA_N_CHANNELS, KM_SLEEP);
+               sc->n_channel = APBH_DMA_N_CHANNELS;
+       }
+
+       if (aa->aa_addr == HW_APBXDMA_BASE && aa->aa_size == HW_APBXDMA_SIZE) {
+               sc->sc_channel = kmem_alloc(sizeof(struct imx23_dma_channel)
+                   * APBX_DMA_N_CHANNELS, KM_SLEEP);
+               sc->n_channel = APBX_DMA_N_CHANNELS;
+       }
+
+       if (sc->sc_channel == NULL) {
+               aprint_error_dev(sc->sc_dev, "unable to allocate memory for"
+                   " DMA channel structures\n");
+               return;
+       }
+
+       for (i=0; i < sc->n_channel; i++) {
+               chan = (struct imx23_dma_channel *)sc->sc_channel+i;
+               chan->sc = sc;
+               SIMPLEQ_INIT(&chan->head);
+       }
+#endif
+       apbdma_reset(sc);
+//     apbdma_attached = 1;
+
+       aprint_normal("\n");
+
+       return;
+}
+
+static int
+apbdma_activate(device_t self, enum devact act)
+{
+       return EOPNOTSUPP;
+}
+
+/*
+ * Reset the APB{H,X}DMA block.
+ *
+ * Inspired by i.MX233 RM "39.3.10 Correct Way to Soft Reset a Block"
+ */
+static void
+apbdma_reset(struct apbdma_softc *sc)
+{
+       unsigned int loop;
+
+       /*
+        * Prepare for soft-reset by making sure that SFTRST is not currently
+        * asserted. Also clear CLKGATE so we can wait for its assertion below.
+        */
+       DMACTRL_WR(sc, HW_APB_CTRL0_CLR, HW_APB_CTRL0_SFTRST);
+
+       /* Wait at least a microsecond for SFTRST to deassert. */
+       loop = 0;
+       while ((DMACTRL_RD(sc, HW_APB_CTRL0) &  HW_APB_CTRL0_SFTRST) ||
+               (loop < APBDMA_SOFT_RST_LOOP))
+       {
+               loop++;
+       }
+
+       /* Clear CLKGATE so we can wait for its assertion below. */
+       DMACTRL_WR(sc, HW_APB_CTRL0_CLR, HW_APB_CTRL0_CLKGATE);
+
+       /* Soft-reset the block. */
+       DMACTRL_WR(sc, HW_APB_CTRL0_SET, HW_APB_CTRL0_SFTRST);
+
+       /* Wait until clock is in the gated state. */
+       while (!(DMACTRL_RD(sc, HW_APB_CTRL0) & HW_APB_CTRL0_CLKGATE));
+
+       /* Bring block out of reset. */
+       DMACTRL_WR(sc, HW_APB_CTRL0_CLR, HW_APB_CTRL0_SFTRST);
+
+       loop = 0;
+       while ((DMACTRL_RD(sc, HW_APB_CTRL0) & HW_APB_CTRL0_SFTRST) ||
+               (loop < APBDMA_SOFT_RST_LOOP))
+       {
+               loop++;
+       }
+         
+       DMACTRL_WR(sc, HW_APB_CTRL0_CLR, HW_APB_CTRL0_CLKGATE);
+
+        /* Wait until clock is in the NON-gated state. */
+       while (DMACTRL_RD(sc, HW_APB_CTRL0) & HW_APB_CTRL0_CLKGATE);
+
+        return;
+}
+
+/*
+ * Allocate DMA safe memory for commands.
+ */
+void *
+apbdma_dmamem_alloc(device_t dmac, int channel, bus_size_t size)
+{
+       struct apbdma_softc *sc = device_private(dmac);
+       bus_dma_segment_t segs[1];      /* bus_dmamem_free needs. */
+       int rsegs;
+       int error;
+       void *ptr = NULL;       /* bus_dmamem_unmap needs (size also) */
+
+       if (size > PAGE_SIZE)
+               return NULL;
+



Home | Main Index | Thread Index | Old Index