From owner-svn-src-all@freebsd.org Sun Aug 20 16:52:29 2017 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 3D27DDDF731; Sun, 20 Aug 2017 16:52:29 +0000 (UTC) (envelope-from marius@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id E82826B701; Sun, 20 Aug 2017 16:52:28 +0000 (UTC) (envelope-from marius@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id v7KGqRhl014309; Sun, 20 Aug 2017 16:52:27 GMT (envelope-from marius@FreeBSD.org) Received: (from marius@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id v7KGqRNo014303; Sun, 20 Aug 2017 16:52:27 GMT (envelope-from marius@FreeBSD.org) Message-Id: <201708201652.v7KGqRNo014303@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: marius set sender to marius@FreeBSD.org using -f From: Marius Strobl Date: Sun, 20 Aug 2017 16:52:27 +0000 (UTC) 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 X-SVN-Group: stable-10 X-SVN-Commit-Author: marius X-SVN-Commit-Paths: in stable/10/sys: arm/broadcom/bcm2835 conf dev/usb/controller dev/usb/net X-SVN-Commit-Revision: 322724 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 20 Aug 2017 16:52:29 -0000 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 #include +#include + +#include +#include + #include #include #include @@ -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 ***