Author: marius
Date: Sun Aug 20 16:52:27 2017
New Revision: 322724
URL: https://svnweb.freebsd.org/changeset/base/322724

Log:
  MFC: r266470, r273546, r276017, r277932, r279153, r279778, r279780, r278797,
       r278861, r280283, r280284, r280294, r280452, r280558, r280571, r281863,
       r282049, r282357, r282440, r282441, r282358, r282359, r283550, r283918,
       r290171, r290667, r290381, r290533, r290666, r292483, r295659, r297545,
       r298305, r298383, r298428, r306489, r306557, r307067, r307068, r307087,
       r307088, r307089, r307091, r307092, r307093, r307098, r307115, r307154,
       r307240, r307241, r315967, r316476
  
  Unbreak BCM2835/RPI-B support by bringing it in line with stable/11 and
  head:
  
  - Optimise reading of pending interrupt registers.
  
  - Fix a bug where some DTS layouts could cause the premature ending of the
    search (i.e. without returning any result) and you would end up with a
    random MAC address.
  
  - Reduce the diff between head and arm_intrng with the bcm2835 interrupt
    controller.
  
  - Allow the retrieving of the reserved pins state.
  
  - Add support to the bcm2835 mailbox driver to work before interrupts are
    enabled. This will be needed to enable the power on devices early on in the
    boot process.
  
  - Add support for enabling the USB on the Raspberry Pi boards when it hasn't
    been done by U-Boot. This allows the USB to work when we load the kernel
    directly.
  
  - Call config_intrhook_disestablish on failure of the bcm2835 fb and fbd intr
    hooks. With this we can get through the boot even if these functions fail.
  
  - Add the structures needed to get/set the power state. These can be used
    when, for example, we boot without U-Boot and wish to enable USB, or to
    suspend an unneeded device.
  
  - Add a mask to match only the relative base address of BSC controllers.
  
  - Move the code to set the device power to the bcm2835 mailbox driver so it
    can be reused by other drivers.
  
  - Add the SOC_BCM2835 and SOC_BCM2836 options for the arm kernel and add the
    former to std.bcm2835.
  
  - Add a helper function to read clock frequencies from videocore and use this
    to get the default frequency of the sdhci device.
  
  - Add partial support for the Raspberry Pi 2.
  
  - Remove a debug #error from the bcm2835 sdhci driver.
  
  - Fetch the SDHCI frequency from videocore (our prefered source) and only if
    it fails, fetch the clock-frequency from DTB. If both methods fail, use the
    hardcoded default.
  
  - Pass the supplied buffer length instead of a fixed size.
  
  - Add the routines to query and setup the framebuffer state using the
    BCM2835_MBOX_CHAN_PROP channel.  The old channel (BCM2835_MBOX_CHAN_FB)
    seems deprecated on recent firmware versions and is causing a freeze on
    RPi 2.
  
  - Fix DMA on RPi 2. BCM2836 has a different base address for peripherals.
  
  - Enable DMA for sdhci on RPi 2 (BCM2836).
  
  - Add a missing wakeup when releasing ownership of the SPI hardware.
  
  - Fix framebuffer compatibility with new RPi firmware.
  
  - Refactor bcm2835_cpufreq to use bcm2835_mbox_property API.
  
  - Fix the sc(4) framebuffer driver on RPi 2.
  
  - Fix the vt(4) framebuffer driver on RPi 2.
  
  - Remove unused mutex and softc variables.
  
  - Refactor mailbox property API to make it usable for /dev/vcio driver.
  
  - Replace semaphore-base locking with sleep/wait synchronization.
  
  - Fix infinite loop if response from VideoCore never received.
  
  - Set have_message in interrupt to handle "response before READ" case.
  
  - Serialize access to property channel when using bcm2835_mbox_property.
  
  - Force framebuffer virtual viewport to be the same as physical.
  
  - Use proper type of tag in bcm2835_mbox_fb_init.
  
  - bcm2835_cpufreq: Only attach driver if we correcly match on the machine
    compatible string.
  
  - Add dev.fb.X.resync sysctl to resync ARM framebuffer with VideoCore.
  
  - Do not use DMA channels used by GPU.
  
  - Define local-intc for BCM2836 platform (RPI2) and make BCM2835 intc
    a child of it.
  
  - Fix build for Pi kernels with syscons enabled.
  
  - Use VM_MEMATTR_WRITE_COMBINING memattr for mmap(2) on framebuffer.
  
  - Make intc driver compatible with upstream DTS.
  
  - Make Rapsberry Pi watchdog driver compatible with upstream DTS.
  
  - Make sure intc is attached before interrupt consumers.
  
  - Make framebuffer driver compatible with upstream DT.
  
  - Add one more heuristic to determine MAC address of the SMSC device.
  
  - Add compatibility strings from upstream DT.
  
  - Fix spelling mistake, BCM2835_PASWORD -> BCM2835_PASSWORD.
  
  Approved by:  re (kib)

Added:
  stable/10/sys/arm/broadcom/bcm2835/bcm2836.c
     - copied unchanged from r280558, head/sys/arm/broadcom/bcm2835/bcm2836.c
  stable/10/sys/arm/broadcom/bcm2835/bcm2836.h
     - copied unchanged from r280558, head/sys/arm/broadcom/bcm2835/bcm2836.h
  stable/10/sys/arm/broadcom/bcm2835/bcm283x_dwc_fdt.c
     - copied, changed from r279778, 
head/sys/arm/broadcom/bcm2835/bcm283x_dwc_fdt.c
  stable/10/sys/arm/broadcom/bcm2835/files.bcm2836
     - copied unchanged from r280558, 
head/sys/arm/broadcom/bcm2835/files.bcm2836
  stable/10/sys/arm/broadcom/bcm2835/std.bcm2836
     - copied unchanged from r280558, head/sys/arm/broadcom/bcm2835/std.bcm2836
  stable/10/sys/dev/usb/controller/dwc_otg_fdt.h
     - copied unchanged from r279778, head/sys/dev/usb/controller/dwc_otg_fdt.h
Modified:
  stable/10/sys/arm/broadcom/bcm2835/bcm2835_bsc.c
  stable/10/sys/arm/broadcom/bcm2835/bcm2835_bscvar.h
  stable/10/sys/arm/broadcom/bcm2835/bcm2835_common.c
  stable/10/sys/arm/broadcom/bcm2835/bcm2835_cpufreq.c
  stable/10/sys/arm/broadcom/bcm2835/bcm2835_dma.c
  stable/10/sys/arm/broadcom/bcm2835/bcm2835_dma.h
  stable/10/sys/arm/broadcom/bcm2835/bcm2835_fb.c
  stable/10/sys/arm/broadcom/bcm2835/bcm2835_fbd.c
  stable/10/sys/arm/broadcom/bcm2835/bcm2835_gpio.c
  stable/10/sys/arm/broadcom/bcm2835/bcm2835_intr.c
  stable/10/sys/arm/broadcom/bcm2835/bcm2835_machdep.c
  stable/10/sys/arm/broadcom/bcm2835/bcm2835_mbox.c
  stable/10/sys/arm/broadcom/bcm2835/bcm2835_mbox_prop.h
  stable/10/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c
  stable/10/sys/arm/broadcom/bcm2835/bcm2835_spi.c
  stable/10/sys/arm/broadcom/bcm2835/bcm2835_vcbus.h
  stable/10/sys/arm/broadcom/bcm2835/bcm2835_wdog.c
  stable/10/sys/arm/broadcom/bcm2835/files.bcm2835
  stable/10/sys/arm/broadcom/bcm2835/std.bcm2835
  stable/10/sys/conf/options.arm
  stable/10/sys/dev/usb/controller/dwc_otg_fdt.c
  stable/10/sys/dev/usb/net/if_smsc.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/arm/broadcom/bcm2835/bcm2835_bsc.c
==============================================================================
--- stable/10/sys/arm/broadcom/bcm2835/bcm2835_bsc.c    Sun Aug 20 11:18:16 
2017        (r322723)
+++ stable/10/sys/arm/broadcom/bcm2835/bcm2835_bsc.c    Sun Aug 20 16:52:27 
2017        (r322724)
@@ -52,6 +52,13 @@ __FBSDID("$FreeBSD$");
 
 #include "iicbus_if.h"
 
+static struct ofw_compat_data compat_data[] = {
+       {"broadcom,bcm2835-bsc",        1},
+       {"brcm,bcm2708-i2c",            1},
+       {"brcm,bcm2835-i2c",            1},
+       {NULL,                          0}
+};
+
 static void bcm_bsc_intr(void *);
 static int bcm_bsc_detach(device_t);
 
@@ -214,7 +221,7 @@ bcm_bsc_probe(device_t dev)
        if (!ofw_bus_status_okay(dev))
                return (ENXIO);
 
-       if (!ofw_bus_is_compatible(dev, "broadcom,bcm2835-bsc"))
+       if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
                return (ENXIO);
 
        device_set_desc(dev, "BCM2708/2835 BSC controller");
@@ -247,7 +254,7 @@ bcm_bsc_attach(device_t dev)
        /* Check the unit we are attaching by its base address. */
        start = rman_get_start(sc->sc_mem_res);
        for (i = 0; i < nitems(bcm_bsc_pins); i++) {
-               if (bcm_bsc_pins[i].start == start)
+               if (bcm_bsc_pins[i].start == (start & BCM_BSC_BASE_MASK))
                        break;
        }
        if (i == nitems(bcm_bsc_pins)) {

Modified: stable/10/sys/arm/broadcom/bcm2835/bcm2835_bscvar.h
==============================================================================
--- stable/10/sys/arm/broadcom/bcm2835/bcm2835_bscvar.h Sun Aug 20 11:18:16 
2017        (r322723)
+++ stable/10/sys/arm/broadcom/bcm2835/bcm2835_bscvar.h Sun Aug 20 16:52:27 
2017        (r322724)
@@ -35,9 +35,10 @@ struct {
        uint32_t        scl;
        unsigned long   start;
 } bcm_bsc_pins[] = {
-       { 0, 1, 0x20205000 },   /* BSC0 GPIO pins and base address. */
-       { 2, 3, 0x20804000 }    /* BSC1 GPIO pins and base address. */
+       { 0, 1, 0x205000 },     /* BSC0 GPIO pins and base address. */
+       { 2, 3, 0x804000 }      /* BSC1 GPIO pins and base address. */
 };
+#define        BCM_BSC_BASE_MASK       0x00ffffff
 
 struct bcm_bsc_softc {
        device_t                sc_dev;

Modified: stable/10/sys/arm/broadcom/bcm2835/bcm2835_common.c
==============================================================================
--- stable/10/sys/arm/broadcom/bcm2835/bcm2835_common.c Sun Aug 20 11:18:16 
2017        (r322723)
+++ stable/10/sys/arm/broadcom/bcm2835/bcm2835_common.c Sun Aug 20 16:52:27 
2017        (r322724)
@@ -58,14 +58,22 @@ fdt_intc_decode_ic(phandle_t node, pcell_t *intr, int 
     int *pol)
 {
 
-       if (!fdt_is_compatible(node, "broadcom,bcm2835-armctrl-ic"))
-               return (ENXIO);
-
-       *interrupt = fdt32_to_cpu(intr[0]);
-       *trig = INTR_TRIGGER_CONFORM;
-       *pol = INTR_POLARITY_CONFORM;
-
-       return (0);
+       if (fdt_is_compatible(node, "broadcom,bcm2835-armctrl-ic") ||
+           fdt_is_compatible(node, "brcm,bcm2836-armctrl-ic")) {
+               *interrupt = fdt32_to_cpu(intr[0]);
+               *trig = INTR_TRIGGER_CONFORM;
+               *pol = INTR_POLARITY_CONFORM;
+               return (0);
+       }
+#ifdef SOC_BCM2836
+       if (fdt_is_compatible(node, "brcm,bcm2836-l1-intc")) {
+               *interrupt = fdt32_to_cpu(intr[0]) + 72;
+               *trig = INTR_TRIGGER_CONFORM;
+               *pol = INTR_POLARITY_CONFORM;
+               return (0);
+       }
+#endif
+       return (ENXIO);
 }
 
 

Modified: stable/10/sys/arm/broadcom/bcm2835/bcm2835_cpufreq.c
==============================================================================
--- stable/10/sys/arm/broadcom/bcm2835/bcm2835_cpufreq.c        Sun Aug 20 
11:18:16 2017        (r322723)
+++ stable/10/sys/arm/broadcom/bcm2835/bcm2835_cpufreq.c        Sun Aug 20 
16:52:27 2017        (r322724)
@@ -44,6 +44,11 @@ __FBSDID("$FreeBSD$");
 #include <machine/cpu.h>
 #include <machine/intr.h>
 
+#include <dev/fdt/fdt_common.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
 #include <arm/broadcom/bcm2835/bcm2835_mbox.h>
 #include <arm/broadcom/bcm2835/bcm2835_mbox_prop.h>
 #include <arm/broadcom/bcm2835/bcm2835_vcbus.h>
@@ -108,17 +113,17 @@ struct bcm2835_cpufreq_softc {
        int             voltage_sdram_p;
        int             turbo_mode;
 
-       /* mbox buffer (physical address) */
-       bus_dma_tag_t   dma_tag;
-       bus_dmamap_t    dma_map;
-       bus_size_t      dma_size;
-       void            *dma_buf;
-       bus_addr_t      dma_phys;
-
        /* initial hook for waiting mbox intr */
        struct intr_config_hook init_hook;
 };
 
+static struct ofw_compat_data compat_data[] = {
+       { "broadcom,bcm2835-vc",        1 },
+       { "broadcom,bcm2708-vc",        1 },
+       { "brcm,bcm2709",       1 },
+       { NULL, 0 }
+};
+
 static int cpufreq_verbose = 0;
 TUNABLE_INT("hw.bcm2835.cpufreq.verbose", &cpufreq_verbose);
 static int cpufreq_lowest_freq = DEFAULT_LOWEST_FREQ;
@@ -144,84 +149,10 @@ bcm2835_dump(const void *data, int len)
 #endif
 
 static int
-bcm2835_mbox_call_prop(struct bcm2835_cpufreq_softc *sc)
-{
-       struct bcm2835_mbox_hdr *msg = (struct bcm2835_mbox_hdr *)sc->dma_buf;
-       struct bcm2835_mbox_tag_hdr *tag, *last;
-       uint8_t *up;
-       device_t mbox;
-       size_t hdr_size;
-       int idx;
-       int err;
-
-       /*
-        * For multiple calls, locking is not here. The caller must have
-        * VC semaphore.
-        */
-
-       /* get mbox device */
-       mbox = devclass_get_device(devclass_find("mbox"), 0);
-       if (mbox == NULL) {
-               device_printf(sc->dev, "can't find mbox\n");
-               return (-1);
-       }
-
-       /* go mailbox property */
-#ifdef PROP_DEBUG
-       bcm2835_dump(msg, 64);
-#endif
-       bus_dmamap_sync(sc->dma_tag, sc->dma_map,
-           BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
-       MBOX_WRITE(mbox, BCM2835_MBOX_CHAN_PROP, (uint32_t)sc->dma_phys);
-       MBOX_READ(mbox, BCM2835_MBOX_CHAN_PROP, &err);
-       bus_dmamap_sync(sc->dma_tag, sc->dma_map, BUS_DMASYNC_POSTREAD);
-#ifdef PROP_DEBUG
-       bcm2835_dump(msg, 64);
-#endif
-
-       /* check response code */
-       if (msg->code != BCM2835_MBOX_CODE_RESP_SUCCESS) {
-               device_printf(sc->dev, "mbox response error\n");
-               return (-1);
-       }
-
-       /* tag = first tag */
-       up = (uint8_t *)msg;
-       hdr_size = sizeof(struct bcm2835_mbox_hdr);
-       tag = (struct bcm2835_mbox_tag_hdr *)(up + hdr_size);
-       /* last = end of buffer specified by header */
-       last = (struct bcm2835_mbox_tag_hdr *)(up + msg->buf_size);
-
-       /* loop unitl end tag (=0x0) */
-       hdr_size = sizeof(struct bcm2835_mbox_tag_hdr);
-       for (idx = 0; tag->tag != 0; idx++) {
-               if ((tag->val_len & BCM2835_MBOX_TAG_VAL_LEN_RESPONSE) == 0) {
-                       device_printf(sc->dev, "tag%d response error\n", idx);
-                       return (-1);
-               }
-               /* clear response bit */
-               tag->val_len &= ~BCM2835_MBOX_TAG_VAL_LEN_RESPONSE;
-
-               /* get next tag */
-               up = (uint8_t *)tag;
-               tag = (struct bcm2835_mbox_tag_hdr *)(up + hdr_size +
-                   tag->val_buf_size);
-
-               /* check buffer size of header */
-               if (tag > last) {
-                       device_printf(sc->dev, "mbox buffer size error\n");
-                       return (-1);
-               }
-       }
-
-       return (0);
-}
-
-static int
 bcm2835_cpufreq_get_clock_rate(struct bcm2835_cpufreq_softc *sc,
     uint32_t clock_id)
 {
-       struct msg_get_clock_rate *msg;
+       struct msg_get_clock_rate msg;
        int rate;
        int err;
 
@@ -239,26 +170,18 @@ bcm2835_cpufreq_get_clock_rate(struct bcm2835_cpufreq_
         *       u32: rate (in Hz)
         */
 
-       /* using DMA buffer for VC */
-       msg = (struct msg_get_clock_rate *)sc->dma_buf;
-       if (sizeof(*msg) > sc->dma_size) {
-               device_printf(sc->dev, "DMA size overflow (%zu>%lu)\n",
-                   sizeof(*msg), sc->dma_size);
-               return (MSG_ERROR);
-       }
-
        /* setup single tag buffer */
-       memset(msg, 0, sizeof(*msg));
-       msg->hdr.buf_size = sizeof(*msg);
-       msg->hdr.code = BCM2835_MBOX_CODE_REQ;
-       msg->tag_hdr.tag = BCM2835_MBOX_TAG_GET_CLOCK_RATE;
-       msg->tag_hdr.val_buf_size = sizeof(msg->body);
-       msg->tag_hdr.val_len = sizeof(msg->body.req);
-       msg->body.req.clock_id = clock_id;
-       msg->end_tag = 0;
+       memset(&msg, 0, sizeof(msg));
+       msg.hdr.buf_size = sizeof(msg);
+       msg.hdr.code = BCM2835_MBOX_CODE_REQ;
+       msg.tag_hdr.tag = BCM2835_MBOX_TAG_GET_CLOCK_RATE;
+       msg.tag_hdr.val_buf_size = sizeof(msg.body);
+       msg.tag_hdr.val_len = sizeof(msg.body.req);
+       msg.body.req.clock_id = clock_id;
+       msg.end_tag = 0;
 
        /* call mailbox property */
-       err = bcm2835_mbox_call_prop(sc);
+       err = bcm2835_mbox_property(&msg, sizeof(msg));
        if (err) {
                device_printf(sc->dev, "can't get clock rate (id=%u)\n",
                    clock_id);
@@ -266,7 +189,7 @@ bcm2835_cpufreq_get_clock_rate(struct bcm2835_cpufreq_
        }
 
        /* result (Hz) */
-       rate = (int)msg->body.resp.rate_hz;
+       rate = (int)msg.body.resp.rate_hz;
        DPRINTF("clock = %d(Hz)\n", rate);
        return (rate);
 }
@@ -275,7 +198,7 @@ static int
 bcm2835_cpufreq_get_max_clock_rate(struct bcm2835_cpufreq_softc *sc,
     uint32_t clock_id)
 {
-       struct msg_get_max_clock_rate *msg;
+       struct msg_get_max_clock_rate msg;
        int rate;
        int err;
 
@@ -293,26 +216,18 @@ bcm2835_cpufreq_get_max_clock_rate(struct bcm2835_cpuf
         *       u32: rate (in Hz)
         */
 
-       /* using DMA buffer for VC */
-       msg = (struct msg_get_max_clock_rate *)sc->dma_buf;
-       if (sizeof(*msg) > sc->dma_size) {
-               device_printf(sc->dev, "DMA size overflow (%zu>%lu)\n",
-                   sizeof(*msg), sc->dma_size);
-               return (MSG_ERROR);
-       }
-
        /* setup single tag buffer */
-       memset(msg, 0, sizeof(*msg));
-       msg->hdr.buf_size = sizeof(*msg);
-       msg->hdr.code = BCM2835_MBOX_CODE_REQ;
-       msg->tag_hdr.tag = BCM2835_MBOX_TAG_GET_MAX_CLOCK_RATE;
-       msg->tag_hdr.val_buf_size = sizeof(msg->body);
-       msg->tag_hdr.val_len = sizeof(msg->body.req);
-       msg->body.req.clock_id = clock_id;
-       msg->end_tag = 0;
+       memset(&msg, 0, sizeof(msg));
+       msg.hdr.buf_size = sizeof(msg);
+       msg.hdr.code = BCM2835_MBOX_CODE_REQ;
+       msg.tag_hdr.tag = BCM2835_MBOX_TAG_GET_MAX_CLOCK_RATE;
+       msg.tag_hdr.val_buf_size = sizeof(msg.body);
+       msg.tag_hdr.val_len = sizeof(msg.body.req);
+       msg.body.req.clock_id = clock_id;
+       msg.end_tag = 0;
 
        /* call mailbox property */
-       err = bcm2835_mbox_call_prop(sc);
+       err = bcm2835_mbox_property(&msg, sizeof(msg));
        if (err) {
                device_printf(sc->dev, "can't get max clock rate (id=%u)\n",
                    clock_id);
@@ -320,7 +235,7 @@ bcm2835_cpufreq_get_max_clock_rate(struct bcm2835_cpuf
        }
 
        /* result (Hz) */
-       rate = (int)msg->body.resp.rate_hz;
+       rate = (int)msg.body.resp.rate_hz;
        DPRINTF("clock = %d(Hz)\n", rate);
        return (rate);
 }
@@ -329,7 +244,7 @@ static int
 bcm2835_cpufreq_get_min_clock_rate(struct bcm2835_cpufreq_softc *sc,
     uint32_t clock_id)
 {
-       struct msg_get_min_clock_rate *msg;
+       struct msg_get_min_clock_rate msg;
        int rate;
        int err;
 
@@ -347,26 +262,18 @@ bcm2835_cpufreq_get_min_clock_rate(struct bcm2835_cpuf
         *       u32: rate (in Hz)
         */
 
-       /* using DMA buffer for VC */
-       msg = (struct msg_get_min_clock_rate *)sc->dma_buf;
-       if (sizeof(*msg) > sc->dma_size) {
-               device_printf(sc->dev, "DMA size overflow (%zu>%lu)\n",
-                   sizeof(*msg), sc->dma_size);
-               return (MSG_ERROR);
-       }
-
        /* setup single tag buffer */
-       memset(msg, 0, sizeof(*msg));
-       msg->hdr.buf_size = sizeof(*msg);
-       msg->hdr.code = BCM2835_MBOX_CODE_REQ;
-       msg->tag_hdr.tag = BCM2835_MBOX_TAG_GET_MIN_CLOCK_RATE;
-       msg->tag_hdr.val_buf_size = sizeof(msg->body);
-       msg->tag_hdr.val_len = sizeof(msg->body.req);
-       msg->body.req.clock_id = clock_id;
-       msg->end_tag = 0;
+       memset(&msg, 0, sizeof(msg));
+       msg.hdr.buf_size = sizeof(msg);
+       msg.hdr.code = BCM2835_MBOX_CODE_REQ;
+       msg.tag_hdr.tag = BCM2835_MBOX_TAG_GET_MIN_CLOCK_RATE;
+       msg.tag_hdr.val_buf_size = sizeof(msg.body);
+       msg.tag_hdr.val_len = sizeof(msg.body.req);
+       msg.body.req.clock_id = clock_id;
+       msg.end_tag = 0;
 
        /* call mailbox property */
-       err = bcm2835_mbox_call_prop(sc);
+       err = bcm2835_mbox_property(&msg, sizeof(msg));
        if (err) {
                device_printf(sc->dev, "can't get min clock rate (id=%u)\n",
                    clock_id);
@@ -374,7 +281,7 @@ bcm2835_cpufreq_get_min_clock_rate(struct bcm2835_cpuf
        }
 
        /* result (Hz) */
-       rate = (int)msg->body.resp.rate_hz;
+       rate = (int)msg.body.resp.rate_hz;
        DPRINTF("clock = %d(Hz)\n", rate);
        return (rate);
 }
@@ -383,7 +290,7 @@ static int
 bcm2835_cpufreq_set_clock_rate(struct bcm2835_cpufreq_softc *sc,
     uint32_t clock_id, uint32_t rate_hz)
 {
-       struct msg_set_clock_rate *msg;
+       struct msg_set_clock_rate msg;
        int rate;
        int err;
 
@@ -402,27 +309,19 @@ bcm2835_cpufreq_set_clock_rate(struct bcm2835_cpufreq_
         *       u32: rate (in Hz)
         */
 
-       /* using DMA buffer for VC */
-       msg = (struct msg_set_clock_rate *)sc->dma_buf;
-       if (sizeof(*msg) > sc->dma_size) {
-               device_printf(sc->dev, "DMA size overflow (%zu>%lu)\n",
-                   sizeof(*msg), sc->dma_size);
-               return (MSG_ERROR);
-       }
-
        /* setup single tag buffer */
-       memset(msg, 0, sizeof(*msg));
-       msg->hdr.buf_size = sizeof(*msg);
-       msg->hdr.code = BCM2835_MBOX_CODE_REQ;
-       msg->tag_hdr.tag = BCM2835_MBOX_TAG_SET_CLOCK_RATE;
-       msg->tag_hdr.val_buf_size = sizeof(msg->body);
-       msg->tag_hdr.val_len = sizeof(msg->body.req);
-       msg->body.req.clock_id = clock_id;
-       msg->body.req.rate_hz = rate_hz;
-       msg->end_tag = 0;
+       memset(&msg, 0, sizeof(msg));
+       msg.hdr.buf_size = sizeof(msg);
+       msg.hdr.code = BCM2835_MBOX_CODE_REQ;
+       msg.tag_hdr.tag = BCM2835_MBOX_TAG_SET_CLOCK_RATE;
+       msg.tag_hdr.val_buf_size = sizeof(msg.body);
+       msg.tag_hdr.val_len = sizeof(msg.body.req);
+       msg.body.req.clock_id = clock_id;
+       msg.body.req.rate_hz = rate_hz;
+       msg.end_tag = 0;
 
        /* call mailbox property */
-       err = bcm2835_mbox_call_prop(sc);
+       err = bcm2835_mbox_property(&msg, sizeof(msg));
        if (err) {
                device_printf(sc->dev, "can't set clock rate (id=%u)\n",
                    clock_id);
@@ -440,18 +339,18 @@ bcm2835_cpufreq_set_clock_rate(struct bcm2835_cpufreq_
                 */
 
                /* setup single tag buffer */
-               memset(msg, 0, sizeof(*msg));
-               msg->hdr.buf_size = sizeof(*msg);
-               msg->hdr.code = BCM2835_MBOX_CODE_REQ;
-               msg->tag_hdr.tag = BCM2835_MBOX_TAG_SET_CLOCK_RATE;
-               msg->tag_hdr.val_buf_size = sizeof(msg->body);
-               msg->tag_hdr.val_len = sizeof(msg->body.req);
-               msg->body.req.clock_id = clock_id;
-               msg->body.req.rate_hz = rate_hz;
-               msg->end_tag = 0;
+               memset(&msg, 0, sizeof(msg));
+               msg.hdr.buf_size = sizeof(msg);
+               msg.hdr.code = BCM2835_MBOX_CODE_REQ;
+               msg.tag_hdr.tag = BCM2835_MBOX_TAG_SET_CLOCK_RATE;
+               msg.tag_hdr.val_buf_size = sizeof(msg.body);
+               msg.tag_hdr.val_len = sizeof(msg.body.req);
+               msg.body.req.clock_id = clock_id;
+               msg.body.req.rate_hz = rate_hz;
+               msg.end_tag = 0;
 
                /* call mailbox property */
-               err = bcm2835_mbox_call_prop(sc);
+               err = bcm2835_mbox_property(&msg, sizeof(msg));
                if (err) {
                        device_printf(sc->dev,
                            "can't set clock rate (id=%u)\n", clock_id);
@@ -460,7 +359,7 @@ bcm2835_cpufreq_set_clock_rate(struct bcm2835_cpufreq_
        }
 
        /* result (Hz) */
-       rate = (int)msg->body.resp.rate_hz;
+       rate = (int)msg.body.resp.rate_hz;
        DPRINTF("clock = %d(Hz)\n", rate);
        return (rate);
 }
@@ -468,7 +367,7 @@ bcm2835_cpufreq_set_clock_rate(struct bcm2835_cpufreq_
 static int
 bcm2835_cpufreq_get_turbo(struct bcm2835_cpufreq_softc *sc)
 {
-       struct msg_get_turbo *msg;
+       struct msg_get_turbo msg;
        int level;
        int err;
 
@@ -486,33 +385,25 @@ bcm2835_cpufreq_get_turbo(struct bcm2835_cpufreq_softc
         *       u32: level
         */
 
-       /* using DMA buffer for VC */
-       msg = (struct msg_get_turbo *)sc->dma_buf;
-       if (sizeof(*msg) > sc->dma_size) {
-               device_printf(sc->dev, "DMA size overflow (%zu>%lu)\n",
-                   sizeof(*msg), sc->dma_size);
-               return (MSG_ERROR);
-       }
-
        /* setup single tag buffer */
-       memset(msg, 0, sizeof(*msg));
-       msg->hdr.buf_size = sizeof(*msg);
-       msg->hdr.code = BCM2835_MBOX_CODE_REQ;
-       msg->tag_hdr.tag = BCM2835_MBOX_TAG_GET_TURBO;
-       msg->tag_hdr.val_buf_size = sizeof(msg->body);
-       msg->tag_hdr.val_len = sizeof(msg->body.req);
-       msg->body.req.id = 0;
-       msg->end_tag = 0;
+       memset(&msg, 0, sizeof(msg));
+       msg.hdr.buf_size = sizeof(msg);
+       msg.hdr.code = BCM2835_MBOX_CODE_REQ;
+       msg.tag_hdr.tag = BCM2835_MBOX_TAG_GET_TURBO;
+       msg.tag_hdr.val_buf_size = sizeof(msg.body);
+       msg.tag_hdr.val_len = sizeof(msg.body.req);
+       msg.body.req.id = 0;
+       msg.end_tag = 0;
 
        /* call mailbox property */
-       err = bcm2835_mbox_call_prop(sc);
+       err = bcm2835_mbox_property(&msg, sizeof(msg));
        if (err) {
                device_printf(sc->dev, "can't get turbo\n");
                return (MSG_ERROR);
        }
 
        /* result 0=non-turbo, 1=turbo */
-       level = (int)msg->body.resp.level;
+       level = (int)msg.body.resp.level;
        DPRINTF("level = %d\n", level);
        return (level);
 }
@@ -520,7 +411,7 @@ bcm2835_cpufreq_get_turbo(struct bcm2835_cpufreq_softc
 static int
 bcm2835_cpufreq_set_turbo(struct bcm2835_cpufreq_softc *sc, uint32_t level)
 {
-       struct msg_set_turbo *msg;
+       struct msg_set_turbo msg;
        int value;
        int err;
 
@@ -539,38 +430,30 @@ bcm2835_cpufreq_set_turbo(struct bcm2835_cpufreq_softc
         *       u32: level
         */
 
-       /* using DMA buffer for VC */
-       msg = (struct msg_set_turbo *)sc->dma_buf;
-       if (sizeof(*msg) > sc->dma_size) {
-               device_printf(sc->dev, "DMA size overflow (%zu>%lu)\n",
-                   sizeof(*msg), sc->dma_size);
-               return (MSG_ERROR);
-       }
-
        /* replace unknown value to OFF */
        if (level != BCM2835_MBOX_TURBO_ON && level != BCM2835_MBOX_TURBO_OFF)
                level = BCM2835_MBOX_TURBO_OFF;
 
        /* setup single tag buffer */
-       memset(msg, 0, sizeof(*msg));
-       msg->hdr.buf_size = sizeof(*msg);
-       msg->hdr.code = BCM2835_MBOX_CODE_REQ;
-       msg->tag_hdr.tag = BCM2835_MBOX_TAG_SET_TURBO;
-       msg->tag_hdr.val_buf_size = sizeof(msg->body);
-       msg->tag_hdr.val_len = sizeof(msg->body.req);
-       msg->body.req.id = 0;
-       msg->body.req.level = level;
-       msg->end_tag = 0;
+       memset(&msg, 0, sizeof(msg));
+       msg.hdr.buf_size = sizeof(msg);
+       msg.hdr.code = BCM2835_MBOX_CODE_REQ;
+       msg.tag_hdr.tag = BCM2835_MBOX_TAG_SET_TURBO;
+       msg.tag_hdr.val_buf_size = sizeof(msg.body);
+       msg.tag_hdr.val_len = sizeof(msg.body.req);
+       msg.body.req.id = 0;
+       msg.body.req.level = level;
+       msg.end_tag = 0;
 
        /* call mailbox property */
-       err = bcm2835_mbox_call_prop(sc);
+       err = bcm2835_mbox_property(&msg, sizeof(msg));
        if (err) {
                device_printf(sc->dev, "can't set turbo\n");
                return (MSG_ERROR);
        }
 
        /* result 0=non-turbo, 1=turbo */
-       value = (int)msg->body.resp.level;
+       value = (int)msg.body.resp.level;
        DPRINTF("level = %d\n", value);
        return (value);
 }
@@ -579,7 +462,7 @@ static int
 bcm2835_cpufreq_get_voltage(struct bcm2835_cpufreq_softc *sc,
     uint32_t voltage_id)
 {
-       struct msg_get_voltage *msg;
+       struct msg_get_voltage msg;
        int value;
        int err;
 
@@ -597,33 +480,25 @@ bcm2835_cpufreq_get_voltage(struct bcm2835_cpufreq_sof
         *       u32: value (offset from 1.2V in units of 0.025V)
         */
 
-       /* using DMA buffer for VC */
-       msg = (struct msg_get_voltage *)sc->dma_buf;
-       if (sizeof(*msg) > sc->dma_size) {
-               device_printf(sc->dev, "DMA size overflow (%zu>%lu)\n",
-                   sizeof(*msg), sc->dma_size);
-               return (MSG_ERROR);
-       }
-
        /* setup single tag buffer */
-       memset(msg, 0, sizeof(*msg));
-       msg->hdr.buf_size = sizeof(*msg);
-       msg->hdr.code = BCM2835_MBOX_CODE_REQ;
-       msg->tag_hdr.tag = BCM2835_MBOX_TAG_GET_VOLTAGE;
-       msg->tag_hdr.val_buf_size = sizeof(msg->body);
-       msg->tag_hdr.val_len = sizeof(msg->body.req);
-       msg->body.req.voltage_id = voltage_id;
-       msg->end_tag = 0;
+       memset(&msg, 0, sizeof(msg));
+       msg.hdr.buf_size = sizeof(msg);
+       msg.hdr.code = BCM2835_MBOX_CODE_REQ;
+       msg.tag_hdr.tag = BCM2835_MBOX_TAG_GET_VOLTAGE;
+       msg.tag_hdr.val_buf_size = sizeof(msg.body);
+       msg.tag_hdr.val_len = sizeof(msg.body.req);
+       msg.body.req.voltage_id = voltage_id;
+       msg.end_tag = 0;
 
        /* call mailbox property */
-       err = bcm2835_mbox_call_prop(sc);
+       err = bcm2835_mbox_property(&msg, sizeof(msg));
        if (err) {
                device_printf(sc->dev, "can't get voltage\n");
                return (MSG_ERROR);
        }
 
        /* result (offset from 1.2V) */
-       value = (int)msg->body.resp.value;
+       value = (int)msg.body.resp.value;
        DPRINTF("value = %d\n", value);
        return (value);
 }
@@ -632,7 +507,7 @@ static int
 bcm2835_cpufreq_get_max_voltage(struct bcm2835_cpufreq_softc *sc,
     uint32_t voltage_id)
 {
-       struct msg_get_max_voltage *msg;
+       struct msg_get_max_voltage msg;
        int value;
        int err;
 
@@ -650,33 +525,25 @@ bcm2835_cpufreq_get_max_voltage(struct bcm2835_cpufreq
         *       u32: value (offset from 1.2V in units of 0.025V)
         */
 
-       /* using DMA buffer for VC */
-       msg = (struct msg_get_max_voltage *)sc->dma_buf;
-       if (sizeof(*msg) > sc->dma_size) {
-               device_printf(sc->dev, "DMA size overflow (%zu>%lu)\n",
-                   sizeof(*msg), sc->dma_size);
-               return (MSG_ERROR);
-       }
-
        /* setup single tag buffer */
-       memset(msg, 0, sizeof(*msg));
-       msg->hdr.buf_size = sizeof(*msg);
-       msg->hdr.code = BCM2835_MBOX_CODE_REQ;
-       msg->tag_hdr.tag = BCM2835_MBOX_TAG_GET_MAX_VOLTAGE;
-       msg->tag_hdr.val_buf_size = sizeof(msg->body);
-       msg->tag_hdr.val_len = sizeof(msg->body.req);
-       msg->body.req.voltage_id = voltage_id;
-       msg->end_tag = 0;
+       memset(&msg, 0, sizeof(msg));
+       msg.hdr.buf_size = sizeof(msg);
+       msg.hdr.code = BCM2835_MBOX_CODE_REQ;
+       msg.tag_hdr.tag = BCM2835_MBOX_TAG_GET_MAX_VOLTAGE;
+       msg.tag_hdr.val_buf_size = sizeof(msg.body);
+       msg.tag_hdr.val_len = sizeof(msg.body.req);
+       msg.body.req.voltage_id = voltage_id;
+       msg.end_tag = 0;
 
        /* call mailbox property */
-       err = bcm2835_mbox_call_prop(sc);
+       err = bcm2835_mbox_property(&msg, sizeof(msg));
        if (err) {
                device_printf(sc->dev, "can't get max voltage\n");
                return (MSG_ERROR);
        }
 
        /* result (offset from 1.2V) */
-       value = (int)msg->body.resp.value;
+       value = (int)msg.body.resp.value;
        DPRINTF("value = %d\n", value);
        return (value);
 }
@@ -684,7 +551,7 @@ static int
 bcm2835_cpufreq_get_min_voltage(struct bcm2835_cpufreq_softc *sc,
     uint32_t voltage_id)
 {
-       struct msg_get_min_voltage *msg;
+       struct msg_get_min_voltage msg;
        int value;
        int err;
 
@@ -702,33 +569,25 @@ bcm2835_cpufreq_get_min_voltage(struct bcm2835_cpufreq
         *       u32: value (offset from 1.2V in units of 0.025V)
         */
 
-       /* using DMA buffer for VC */
-       msg = (struct msg_get_min_voltage *)sc->dma_buf;
-       if (sizeof(*msg) > sc->dma_size) {
-               device_printf(sc->dev, "DMA size overflow (%zu>%lu)\n",
-                   sizeof(*msg), sc->dma_size);
-               return (MSG_ERROR);
-       }
-
        /* setup single tag buffer */
-       memset(msg, 0, sizeof(*msg));
-       msg->hdr.buf_size = sizeof(*msg);
-       msg->hdr.code = BCM2835_MBOX_CODE_REQ;
-       msg->tag_hdr.tag = BCM2835_MBOX_TAG_GET_MIN_VOLTAGE;
-       msg->tag_hdr.val_buf_size = sizeof(msg->body);
-       msg->tag_hdr.val_len = sizeof(msg->body.req);
-       msg->body.req.voltage_id = voltage_id;
-       msg->end_tag = 0;
+       memset(&msg, 0, sizeof(msg));
+       msg.hdr.buf_size = sizeof(msg);
+       msg.hdr.code = BCM2835_MBOX_CODE_REQ;
+       msg.tag_hdr.tag = BCM2835_MBOX_TAG_GET_MIN_VOLTAGE;
+       msg.tag_hdr.val_buf_size = sizeof(msg.body);
+       msg.tag_hdr.val_len = sizeof(msg.body.req);
+       msg.body.req.voltage_id = voltage_id;
+       msg.end_tag = 0;
 
        /* call mailbox property */
-       err = bcm2835_mbox_call_prop(sc);
+       err = bcm2835_mbox_property(&msg, sizeof(msg));
        if (err) {
                device_printf(sc->dev, "can't get min voltage\n");
                return (MSG_ERROR);
        }
 
        /* result (offset from 1.2V) */
-       value = (int)msg->body.resp.value;
+       value = (int)msg.body.resp.value;
        DPRINTF("value = %d\n", value);
        return (value);
 }
@@ -737,7 +596,7 @@ static int
 bcm2835_cpufreq_set_voltage(struct bcm2835_cpufreq_softc *sc,
     uint32_t voltage_id, int32_t value)
 {
-       struct msg_set_voltage *msg;
+       struct msg_set_voltage msg;
        int err;
 
        /*
@@ -766,34 +625,26 @@ bcm2835_cpufreq_set_voltage(struct bcm2835_cpufreq_sof
                return (MSG_ERROR);
        }
 
-       /* using DMA buffer for VC */
-       msg = (struct msg_set_voltage *)sc->dma_buf;
-       if (sizeof(*msg) > sc->dma_size) {
-               device_printf(sc->dev, "DMA size overflow (%zu>%lu)\n",
-                   sizeof(*msg), sc->dma_size);
-               return (MSG_ERROR);
-       }
-
        /* setup single tag buffer */
-       memset(msg, 0, sizeof(*msg));
-       msg->hdr.buf_size = sizeof(*msg);
-       msg->hdr.code = BCM2835_MBOX_CODE_REQ;
-       msg->tag_hdr.tag = BCM2835_MBOX_TAG_SET_VOLTAGE;
-       msg->tag_hdr.val_buf_size = sizeof(msg->body);
-       msg->tag_hdr.val_len = sizeof(msg->body.req);
-       msg->body.req.voltage_id = voltage_id;
-       msg->body.req.value = (uint32_t)value;
-       msg->end_tag = 0;
+       memset(&msg, 0, sizeof(msg));
+       msg.hdr.buf_size = sizeof(msg);
+       msg.hdr.code = BCM2835_MBOX_CODE_REQ;
+       msg.tag_hdr.tag = BCM2835_MBOX_TAG_SET_VOLTAGE;
+       msg.tag_hdr.val_buf_size = sizeof(msg.body);
+       msg.tag_hdr.val_len = sizeof(msg.body.req);
+       msg.body.req.voltage_id = voltage_id;
+       msg.body.req.value = (uint32_t)value;
+       msg.end_tag = 0;
 
        /* call mailbox property */
-       err = bcm2835_mbox_call_prop(sc);
+       err = bcm2835_mbox_property(&msg, sizeof(msg));
        if (err) {
                device_printf(sc->dev, "can't set voltage\n");
                return (MSG_ERROR);
        }
 
        /* result (offset from 1.2V) */
-       value = (int)msg->body.resp.value;
+       value = (int)msg.body.resp.value;
        DPRINTF("value = %d\n", value);
        return (value);
 }
@@ -801,7 +652,7 @@ bcm2835_cpufreq_set_voltage(struct bcm2835_cpufreq_sof
 static int
 bcm2835_cpufreq_get_temperature(struct bcm2835_cpufreq_softc *sc)
 {
-       struct msg_get_temperature *msg;
+       struct msg_get_temperature msg;
        int value;
        int err;
 
@@ -819,33 +670,25 @@ bcm2835_cpufreq_get_temperature(struct bcm2835_cpufreq
         *       u32: value
         */
 
-       /* using DMA buffer for VC */
-       msg = (struct msg_get_temperature *)sc->dma_buf;
-       if (sizeof(*msg) > sc->dma_size) {
-               device_printf(sc->dev, "DMA size overflow (%zu>%lu)\n",
-                   sizeof(*msg), sc->dma_size);
-               return (MSG_ERROR);
-       }
-
        /* setup single tag buffer */
-       memset(msg, 0, sizeof(*msg));
-       msg->hdr.buf_size = sizeof(*msg);
-       msg->hdr.code = BCM2835_MBOX_CODE_REQ;
-       msg->tag_hdr.tag = BCM2835_MBOX_TAG_GET_TEMPERATURE;
-       msg->tag_hdr.val_buf_size = sizeof(msg->body);
-       msg->tag_hdr.val_len = sizeof(msg->body.req);
-       msg->body.req.temperature_id = 0;
-       msg->end_tag = 0;
+       memset(&msg, 0, sizeof(msg));
+       msg.hdr.buf_size = sizeof(msg);
+       msg.hdr.code = BCM2835_MBOX_CODE_REQ;
+       msg.tag_hdr.tag = BCM2835_MBOX_TAG_GET_TEMPERATURE;
+       msg.tag_hdr.val_buf_size = sizeof(msg.body);
+       msg.tag_hdr.val_len = sizeof(msg.body.req);
+       msg.body.req.temperature_id = 0;
+       msg.end_tag = 0;
 
        /* call mailbox property */
-       err = bcm2835_mbox_call_prop(sc);
+       err = bcm2835_mbox_property(&msg, sizeof(msg));
        if (err) {
                device_printf(sc->dev, "can't get temperature\n");
                return (MSG_ERROR);
        }
 
        /* result (temperature of degree C) */
-       value = (int)msg->body.resp.value;
+       value = (int)msg.body.resp.value;
        DPRINTF("value = %d\n", value);
        return (value);
 }
@@ -1406,7 +1249,17 @@ bcm2835_cpufreq_init(void *arg)
 static void
 bcm2835_cpufreq_identify(driver_t *driver, device_t parent)
 {
+       const struct ofw_compat_data *compat;
+       phandle_t root;
 
+       root = OF_finddevice("/");
+       for (compat = compat_data; compat->ocd_str != NULL; compat++)
+               if (fdt_is_compatible(root, compat->ocd_str))
+                       break;
+
+       if (compat->ocd_data == 0)
+               return;
+
        DPRINTF("driver=%p, parent=%p\n", driver, parent);
        if (device_find_child(parent, "bcm2835_cpufreq", -1) != NULL)
                return;
@@ -1422,23 +1275,11 @@ bcm2835_cpufreq_probe(device_t dev)
        return (0);
 }
 
-static void
-bcm2835_cpufreq_cb(void *arg, bus_dma_segment_t *segs, int nseg, int err)
-{
-       bus_addr_t *addr;
-
-       if (err)
-               return;
-       addr = (bus_addr_t *)arg;
-       *addr = PHYS_TO_VCBUS(segs[0].ds_addr);
-}
-
 static int
 bcm2835_cpufreq_attach(device_t dev)
 {
        struct bcm2835_cpufreq_softc *sc;
        struct sysctl_oid *oid;
-       int err;
 
        /* set self dev */
        sc = device_get_softc(dev);
@@ -1454,41 +1295,6 @@ bcm2835_cpufreq_attach(device_t dev)
        sc->max_voltage_core = 0;
        sc->min_voltage_core = 0;
 
-       /* create VC mbox buffer */
-       sc->dma_size = PAGE_SIZE;
-       err = bus_dma_tag_create(
-           bus_get_dma_tag(sc->dev),
-           PAGE_SIZE, 0,               /* alignment, boundary */
-           BUS_SPACE_MAXADDR_32BIT,    /* lowaddr */
-           BUS_SPACE_MAXADDR,          /* highaddr */
-           NULL, NULL,                 /* filter, filterarg */
-           sc->dma_size, 1,            /* maxsize, nsegments */
-           sc->dma_size, 0,            /* maxsegsize, flags */
-           NULL, NULL,                 /* lockfunc, lockarg */
-           &sc->dma_tag);
-       if (err) {
-               device_printf(dev, "can't create DMA tag\n");
-               return (ENXIO);
-       }
-
-       err = bus_dmamem_alloc(sc->dma_tag, (void **)&sc->dma_buf, 0,
-           &sc->dma_map);
-       if (err) {
-               bus_dma_tag_destroy(sc->dma_tag);
-               device_printf(dev, "can't allocate dmamem\n");
-               return (ENXIO);
-       }
-
-       err = bus_dmamap_load(sc->dma_tag, sc->dma_map, sc->dma_buf,
-           sc->dma_size, bcm2835_cpufreq_cb, &sc->dma_phys, 0);
-       if (err) {
-               bus_dmamem_free(sc->dma_tag, sc->dma_buf, sc->dma_map);
-               bus_dma_tag_destroy(sc->dma_tag);
-               device_printf(dev, "can't load DMA map\n");
-               return (ENXIO);
-       }
-       /* OK, ready to use VC buffer */
-
        /* setup sysctl at first device */
        if (device_get_unit(dev) == 0) {
                sysctl_ctx_init(&bcm2835_sysctl_ctx);
@@ -1558,9 +1364,6 @@ bcm2835_cpufreq_attach(device_t dev)
        sc->init_hook.ich_arg = sc;
 
        if (config_intrhook_establish(&sc->init_hook) != 0) {
-               bus_dmamap_unload(sc->dma_tag, sc->dma_map);
-               bus_dmamem_free(sc->dma_tag, sc->dma_buf, sc->dma_map);
-               bus_dma_tag_destroy(sc->dma_tag);
                device_printf(dev, "config_intrhook_establish failed\n");
                return (ENOMEM);
        }
@@ -1579,13 +1382,6 @@ bcm2835_cpufreq_detach(device_t dev)
        sc = device_get_softc(dev);
 
        sema_destroy(&vc_sema);
-
-       if (sc->dma_phys != 0)
-               bus_dmamap_unload(sc->dma_tag, sc->dma_map);
-       if (sc->dma_buf != NULL)
-               bus_dmamem_free(sc->dma_tag, sc->dma_buf, sc->dma_map);
-       if (sc->dma_tag != NULL)
-               bus_dma_tag_destroy(sc->dma_tag);
 
        return (cpufreq_unregister(dev));
 }

Modified: stable/10/sys/arm/broadcom/bcm2835/bcm2835_dma.c
==============================================================================
--- stable/10/sys/arm/broadcom/bcm2835/bcm2835_dma.c    Sun Aug 20 11:18:16 
2017        (r322723)
+++ stable/10/sys/arm/broadcom/bcm2835/bcm2835_dma.c    Sun Aug 20 16:52:27 
2017        (r322724)
@@ -104,6 +104,15 @@ __FBSDID("$FreeBSD$");
 /* relative offset from BCM_VC_DMA0_BASE (p.39) */
 #define        BCM_DMA_CH(n)           (0x100*(n))
 
+/* channels used by GPU */
+#define        BCM_DMA_CH_BULK         0
+#define        BCM_DMA_CH_FAST1        2
+#define        BCM_DMA_CH_FAST2        3
+
+#define        BCM_DMA_CH_GPU_MASK     ((1 << BCM_DMA_CH_BULK) |       \
+                                (1 << BCM_DMA_CH_FAST1) |      \
+                                (1 << BCM_DMA_CH_FAST2))
+
 /* DMA Control Block - 256bit aligned (p.40) */
 struct bcm_dma_cb {
        uint32_t info;          /* Transfer Information */
@@ -143,7 +152,14 @@ struct bcm_dma_softc {
 };
 
 static struct bcm_dma_softc *bcm_dma_sc = NULL;
+static uint32_t bcm_dma_channel_mask;
 
+static struct ofw_compat_data compat_data[] = {
+       {"broadcom,bcm2835-dma",        1},
+       {"brcm,bcm2835-dma",            1},
+       {NULL,                          0}
+};
+
 static void
 bcm_dmamap_cb(void *arg, bus_dma_segment_t *segs,
        int nseg, int err)
@@ -205,16 +221,32 @@ static int
 bcm_dma_init(device_t dev)
 {
        struct bcm_dma_softc *sc = device_get_softc(dev);
-       uint32_t mask;
+       uint32_t reg;
        struct bcm_dma_ch *ch;
        void *cb_virt;
        vm_paddr_t cb_phys;
        int err;
        int i;
 
-       /* disable and clear interrupt status */
-       bus_write_4(sc->sc_mem, BCM_DMA_ENABLE, 0);
-       bus_write_4(sc->sc_mem, BCM_DMA_INT_STATUS, 0);
+       /*
+        * Only channels set in bcm_dma_channel_mask can be controlled by us.
+        * The others are out of our control as well as the corresponding bits
+        * in both BCM_DMA_ENABLE and BCM_DMA_INT_STATUS global registers. As
+        * these registers are RW ones, there is no safe way how to write only
+        * the bits which can be controlled by us.
+        *
+        * Fortunately, after reset, all channels are enabled in BCM_DMA_ENABLE
+        * register and all statuses are cleared in BCM_DMA_INT_STATUS one.
+        * Not touching these registers is a trade off between correct
+        * initialization which does not count on anything and not messing up
+        * something we have no control over.
+        */
+       reg = bus_read_4(sc->sc_mem, BCM_DMA_ENABLE);
+       if ((reg & bcm_dma_channel_mask) != bcm_dma_channel_mask)
+               device_printf(dev, "channels are not enabled\n");
+       reg = bus_read_4(sc->sc_mem, BCM_DMA_INT_STATUS);
+       if ((reg & bcm_dma_channel_mask) != 0)
+               device_printf(dev, "statuses are not cleared\n");
 

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
_______________________________________________
svn-src-stable-10@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-stable-10
To unsubscribe, send any mail to "svn-src-stable-10-unsubscr...@freebsd.org"

Reply via email to