Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 20 Aug 2017 16:52:27 +0000 (UTC)
From:      Marius Strobl <marius@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org
Subject:   svn commit: r322724 - in stable/10/sys: arm/broadcom/bcm2835 conf dev/usb/controller dev/usb/net
Message-ID:  <201708201652.v7KGqRNo014303@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
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 ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201708201652.v7KGqRNo014303>