Page MenuHomeFreeBSD

D22301.id.diff
No OneTemporary

D22301.id.diff

Index: head/sys/arm/broadcom/bcm2835/bcm2835_dma.c
===================================================================
--- head/sys/arm/broadcom/bcm2835/bcm2835_dma.c
+++ head/sys/arm/broadcom/bcm2835/bcm2835_dma.c
@@ -169,7 +169,7 @@
return;
addr = (bus_addr_t*)arg;
- *addr = PHYS_TO_VCBUS(segs[0].ds_addr);
+ *addr = ARMC_TO_VCBUS(segs[0].ds_addr);
}
static void
@@ -247,8 +247,12 @@
if ((reg & bcm_dma_channel_mask) != 0)
device_printf(dev, "statuses are not cleared\n");
- /* Allocate DMA chunks control blocks */
- /* p.40 of spec - control block should be 32-bit aligned */
+ /*
+ * Allocate DMA chunks control blocks based on p.40 of the peripheral
+ * spec - control block should be 32-bit aligned. The DMA controller
+ * has a full 32-bit register dedicated to this address, so we do not
+ * need to bother with the per-SoC peripheral restrictions.
+ */
err = bus_dma_tag_create(bus_get_dma_tag(dev),
1, 0, BUS_SPACE_MAXADDR_32BIT,
BUS_SPACE_MAXADDR, NULL, NULL,
@@ -561,14 +565,9 @@
return (-1);
cb = sc->sc_dma_ch[ch].cb;
- if (BCM2835_ARM_IS_IO(src))
- cb->src = IO_TO_VCBUS(src);
- else
- cb->src = PHYS_TO_VCBUS(src);
- if (BCM2835_ARM_IS_IO(dst))
- cb->dst = IO_TO_VCBUS(dst);
- else
- cb->dst = PHYS_TO_VCBUS(dst);
+ cb->src = ARMC_TO_VCBUS(src);
+ cb->dst = ARMC_TO_VCBUS(dst);
+
cb->len = len;
bus_dmamap_sync(sc->sc_dma_tag,
Index: head/sys/arm/broadcom/bcm2835/bcm2835_ft5406.c
===================================================================
--- head/sys/arm/broadcom/bcm2835/bcm2835_ft5406.c
+++ head/sys/arm/broadcom/bcm2835/bcm2835_ft5406.c
@@ -227,7 +227,7 @@
return;
}
- touchbuf = VCBUS_TO_PHYS(msg.body.resp.address);
+ touchbuf = VCBUS_TO_ARMC(msg.body.resp.address);
sc->touch_buf = (uint8_t*)pmap_mapdev(touchbuf, FT5406_WINDOW_SIZE);
/* 60Hz */
Index: head/sys/arm/broadcom/bcm2835/bcm2835_mbox.c
===================================================================
--- head/sys/arm/broadcom/bcm2835/bcm2835_mbox.c
+++ head/sys/arm/broadcom/bcm2835/bcm2835_mbox.c
@@ -303,7 +303,7 @@
if (err)
return;
addr = (bus_addr_t *)arg;
- *addr = PHYS_TO_VCBUS(segs[0].ds_addr);
+ *addr = ARMC_TO_VCBUS(segs[0].ds_addr);
}
static void *
@@ -314,7 +314,7 @@
int err;
err = bus_dma_tag_create(bus_get_dma_tag(dev), 16, 0,
- BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
+ bcm283x_dmabus_peripheral_lowaddr(), BUS_SPACE_MAXADDR, NULL, NULL,
len, 1, len, 0, NULL, NULL, tag);
if (err != 0) {
device_printf(dev, "can't create DMA tag\n");
@@ -554,7 +554,7 @@
fb->xoffset = msg.offset.body.resp.x;
fb->yoffset = msg.offset.body.resp.y;
fb->pitch = msg.pitch.body.resp.pitch;
- fb->base = VCBUS_TO_PHYS(msg.buffer.body.resp.fb_address);
+ fb->base = VCBUS_TO_ARMC(msg.buffer.body.resp.fb_address);
fb->size = msg.buffer.body.resp.fb_size;
}
Index: head/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c
===================================================================
--- head/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c
+++ head/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c
@@ -61,6 +61,7 @@
#ifdef NOTYET
#include <arm/broadcom/bcm2835/bcm2835_clkman.h>
#endif
+#include <arm/broadcom/bcm2835/bcm2835_vcbus.h>
#define BCM2835_DEFAULT_SDHCI_FREQ 50
#define BCM2838_DEFAULT_SDHCI_FREQ 100
@@ -330,7 +331,7 @@
/* Allocate bus_dma resources. */
err = bus_dma_tag_create(bus_get_dma_tag(dev),
- 1, 0, BUS_SPACE_MAXADDR_32BIT,
+ 1, 0, bcm283x_dmabus_peripheral_lowaddr(),
BUS_SPACE_MAXADDR, NULL, NULL,
BCM_DMA_MAXSIZE, ALLOCATED_DMA_SEGS, BCM_SDHCI_BUFFER_SIZE,
BUS_DMA_ALLOCNOW, NULL, NULL,
Index: head/sys/arm/broadcom/bcm2835/bcm2835_vcbus.h
===================================================================
--- head/sys/arm/broadcom/bcm2835/bcm2835_vcbus.h
+++ head/sys/arm/broadcom/bcm2835/bcm2835_vcbus.h
@@ -35,47 +35,40 @@
#ifndef _BCM2835_VCBUS_H_
#define _BCM2835_VCBUS_H_
-/*
- * ARM64 define its SOC options in opt_soc.h
- */
-#if defined(__aarch64__)
-#include "opt_soc.h"
-#endif
-
#define BCM2835_VCBUS_SDRAM_CACHED 0x40000000
-#define BCM2835_VCBUS_IO_BASE 0x7E000000
#define BCM2835_VCBUS_SDRAM_UNCACHED 0xC0000000
-#if defined(SOC_BCM2835)
#define BCM2835_ARM_IO_BASE 0x20000000
+#define BCM2835_VCBUS_IO_BASE 0x7E000000
#define BCM2835_VCBUS_SDRAM_BASE BCM2835_VCBUS_SDRAM_CACHED
-#else
-#define BCM2835_ARM_IO_BASE 0x3f000000
-#define BCM2835_VCBUS_SDRAM_BASE BCM2835_VCBUS_SDRAM_UNCACHED
-#endif
-#define BCM2835_ARM_IO_SIZE 0x01000000
-/*
- * Convert physical address to VC bus address. Should be used
- * when submitting address over mailbox interface
- */
-#define PHYS_TO_VCBUS(pa) ((pa) + BCM2835_VCBUS_SDRAM_BASE)
+#define BCM2837_ARM_IO_BASE 0x3f000000
+#define BCM2837_VCBUS_IO_BASE BCM2835_VCBUS_IO_BASE
+#define BCM2837_VCBUS_SDRAM_BASE BCM2835_VCBUS_SDRAM_UNCACHED
-/* Check whether pa bellong top IO window */
-#define BCM2835_ARM_IS_IO(pa) (((pa) >= BCM2835_ARM_IO_BASE) && \
- ((pa) < BCM2835_ARM_IO_BASE + BCM2835_ARM_IO_SIZE))
+#define BCM2838_ARM_IO_BASE 0xfe000000
+#define BCM2838_VCBUS_IO_BASE BCM2835_VCBUS_IO_BASE
+#define BCM2838_VCBUS_SDRAM_BASE BCM2835_VCBUS_SDRAM_UNCACHED
/*
- * Convert physical address in IO space to VC bus address.
+ * Max allowed SDRAM mapping for most peripherals. The Raspberry Pi 4 has more
+ * than 1 GB of SDRAM, but only the lowest 1 GB is mapped into the "Legacy
+ * Master view" of the address space accessible by the DMA engine. Technically,
+ * we can slide this window around to whatever similarly sized range is
+ * convenient, but this is the most useful window given how busdma(9) works and
+ * that the window must be reconfigured for all channels in a given DMA engine.
+ * The DMA lite engine's window can be configured separately from the 30-bit DMA
+ * engine.
*/
-#define IO_TO_VCBUS(pa) ((pa - BCM2835_ARM_IO_BASE) + \
- BCM2835_VCBUS_IO_BASE)
+#define BCM2838_PERIPH_MAXADDR 0x3fffffff
-/*
- * Convert address from VC bus space to physical. Should be used
- * when address is returned by VC over mailbox interface. e.g.
- * framebuffer base
- */
-#define VCBUS_TO_PHYS(vca) ((vca) & ~(BCM2835_VCBUS_SDRAM_BASE))
+#define BCM28XX_ARM_IO_SIZE 0x01000000
+
+vm_paddr_t bcm283x_armc_to_vcbus(vm_paddr_t pa);
+vm_paddr_t bcm283x_vcbus_to_armc(vm_paddr_t vca);
+bus_addr_t bcm283x_dmabus_peripheral_lowaddr(void);
+
+#define ARMC_TO_VCBUS(pa) bcm283x_armc_to_vcbus(pa)
+#define VCBUS_TO_ARMC(vca) bcm283x_vcbus_to_armc(vca)
#endif /* _BCM2835_VCBUS_H_ */
Index: head/sys/arm/broadcom/bcm2835/bcm2835_vcbus.c
===================================================================
--- head/sys/arm/broadcom/bcm2835/bcm2835_vcbus.c
+++ head/sys/arm/broadcom/bcm2835/bcm2835_vcbus.c
@@ -0,0 +1,263 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 2019 Kyle Evans <kevans@FreeBSD.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*
+ * This file contains facilities for runtime determination of address space
+ * mappings for use in DMA/mailbox interactions. This is only used for the
+ * arm64 SoC because the 32-bit SoC used the same mappings.
+ */
+#if defined (__aarch64__)
+#include "opt_soc.h"
+#endif
+
+#include <sys/types.h>
+#include <sys/systm.h>
+
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <machine/bus.h>
+
+#include <arm/broadcom/bcm2835/bcm2835_vcbus.h>
+
+/*
+ * This structure describes mappings that need to take place when transforming
+ * ARM core addresses into vcbus addresses for use with the DMA/mailbox
+ * interfaces. Currently, we only deal with peripheral/SDRAM address spaces
+ * here.
+ *
+ * The SDRAM address space is consistently mapped starting at 0 and extends to
+ * the size of the installed SDRAM.
+ *
+ * Peripherals are mapped further up at spots that vary per-SOC.
+ */
+struct bcm283x_memory_mapping {
+ vm_paddr_t armc_start;
+ vm_paddr_t armc_size;
+ vm_paddr_t vcbus_start;
+};
+
+#if defined(SOC_BCM2835) || defined(SOC_BCM2836)
+static struct bcm283x_memory_mapping bcm2835_memmap[] = {
+ {
+ /* SDRAM */
+ .armc_start = 0x00000000,
+ .armc_size = BCM2835_ARM_IO_BASE,
+ .vcbus_start = BCM2835_VCBUS_SDRAM_BASE,
+ },
+ {
+ /* Peripherals */
+ .armc_start = BCM2835_ARM_IO_BASE,
+ .armc_size = BCM28XX_ARM_IO_SIZE,
+ .vcbus_start = BCM2835_VCBUS_IO_BASE,
+ },
+ { 0, 0, 0 },
+};
+#endif
+
+#ifdef SOC_BRCM_BCM2837
+static struct bcm283x_memory_mapping bcm2837_memmap[] = {
+ {
+ /* SDRAM */
+ .armc_start = 0x00000000,
+ .armc_size = BCM2837_ARM_IO_BASE,
+ .vcbus_start = BCM2837_VCBUS_SDRAM_BASE,
+ },
+ {
+ /* Peripherals */
+ .armc_start = BCM2837_ARM_IO_BASE,
+ .armc_size = BCM28XX_ARM_IO_SIZE,
+ .vcbus_start = BCM2837_VCBUS_IO_BASE,
+ },
+ { 0, 0, 0 },
+};
+#endif
+
+#ifdef SOC_BRCM_BCM2838
+
+/*
+ * The BCM2838 supports up to 4GB of SDRAM, but unfortunately we can still only
+ * map the first 1GB into the "legacy master view" (vcbus) address space. Thus,
+ * peripherals can still only access the lower end of SDRAM. For this reason,
+ * we also capture the main-peripheral busdma restriction below.
+ */
+static struct bcm283x_memory_mapping bcm2838_memmap[] = {
+ {
+ /* SDRAM */
+ .armc_start = 0x00000000,
+ .armc_size = 0x40000000,
+ .vcbus_start = BCM2838_VCBUS_SDRAM_BASE,
+ },
+ {
+ /* Main peripherals */
+ .armc_start = BCM2838_ARM_IO_BASE,
+ .armc_size = BCM28XX_ARM_IO_SIZE,
+ .vcbus_start = BCM2838_VCBUS_IO_BASE,
+ },
+ { 0, 0, 0 },
+};
+#endif
+
+static struct bcm283x_memory_soc_cfg {
+ struct bcm283x_memory_mapping *memmap;
+ const char *soc_compat;
+ bus_addr_t busdma_lowaddr;
+} bcm283x_memory_configs[] = {
+#ifdef SOC_BCM2835
+ {
+ .memmap = bcm2835_memmap,
+ .soc_compat = "brcm,bcm2835",
+ .busdma_lowaddr = BUS_SPACE_MAXADDR_32BIT,
+ },
+#endif
+#ifdef SOC_BCM2836
+ {
+ .memmap = bcm2835_memmap,
+ .soc_compat = "brcm,bcm2836",
+ .busdma_lowaddr = BUS_SPACE_MAXADDR_32BIT,
+ },
+
+#endif
+#ifdef SOC_BRCM_BCM2837
+ {
+ .memmap = bcm2837_memmap,
+ .soc_compat = "brcm,bcm2837",
+ .busdma_lowaddr = BUS_SPACE_MAXADDR_32BIT,
+ },
+#endif
+#ifdef SOC_BRCM_BCM2838
+ {
+ .memmap = bcm2838_memmap,
+ .soc_compat = "brcm,bcm2838",
+ .busdma_lowaddr = BCM2838_PERIPH_MAXADDR,
+ },
+#endif
+};
+
+static struct bcm283x_memory_soc_cfg *booted_soc_memcfg;
+
+static struct bcm283x_memory_soc_cfg *
+bcm283x_get_current_memcfg(void)
+{
+ phandle_t root;
+ int i;
+
+ /* We'll cache it once we decide, because it won't change per-boot. */
+ if (booted_soc_memcfg != NULL)
+ return (booted_soc_memcfg);
+
+ KASSERT(nitems(bcm283x_memory_configs) != 0,
+ ("No SOC memory configurations enabled!"));
+
+ root = OF_finddevice("/");
+ for (i = 0; i < nitems(bcm283x_memory_configs); ++i) {
+ booted_soc_memcfg = &bcm283x_memory_configs[i];
+ printf("Checking root against %s\n",
+ booted_soc_memcfg->soc_compat);
+ if (ofw_bus_node_is_compatible(root,
+ booted_soc_memcfg->soc_compat))
+ return (booted_soc_memcfg);
+ }
+
+ /*
+ * The kernel doesn't fit the board; we can't really make a reasonable
+ * guess, as these SOC are different enough that something will blow up
+ * later.
+ */
+ panic("No suitable SOC memory configuration found.");
+}
+
+#define BCM283X_MEMMAP_ISTERM(ent) \
+ ((ent)->armc_start == 0 && (ent)->armc_size == 0 && \
+ (ent)->vcbus_start == 0)
+
+vm_paddr_t
+bcm283x_armc_to_vcbus(vm_paddr_t pa)
+{
+ struct bcm283x_memory_soc_cfg *cfg;
+ struct bcm283x_memory_mapping *map, *ment;
+
+ /* Guaranteed not NULL if we haven't panicked yet. */
+ cfg = bcm283x_get_current_memcfg();
+ map = cfg->memmap;
+ for (ment = map; !BCM283X_MEMMAP_ISTERM(ment); ++ment) {
+ if (pa >= ment->armc_start &&
+ pa < ment->armc_start + ment->armc_size) {
+ return (pa - ment->armc_start) + ment->vcbus_start;
+ }
+ }
+
+ /*
+ * Assume 1:1 mapping for anything else, but complain about it on
+ * verbose boots.
+ */
+ if (bootverbose)
+ printf("bcm283x_vcbus: No armc -> vcbus mapping found: %jx\n",
+ (uintmax_t)pa);
+ return (pa);
+}
+
+vm_paddr_t
+bcm283x_vcbus_to_armc(vm_paddr_t vca)
+{
+ struct bcm283x_memory_soc_cfg *cfg;
+ struct bcm283x_memory_mapping *map, *ment;
+
+ /* Guaranteed not NULL if we haven't panicked yet. */
+ cfg = bcm283x_get_current_memcfg();
+ map = cfg->memmap;
+ for (ment = map; !BCM283X_MEMMAP_ISTERM(ment); ++ment) {
+ if (vca >= ment->vcbus_start &&
+ vca < ment->vcbus_start + ment->armc_size) {
+ return (vca - ment->vcbus_start) + ment->armc_start;
+ }
+ }
+
+ /*
+ * Assume 1:1 mapping for anything else, but complain about it on
+ * verbose boots.
+ */
+ if (bootverbose)
+ printf("bcm283x_vcbus: No vcbus -> armc mapping found: %jx\n",
+ (uintmax_t)vca);
+ return (vca);
+}
+
+bus_addr_t
+bcm283x_dmabus_peripheral_lowaddr(void)
+{
+ struct bcm283x_memory_soc_cfg *cfg;
+
+ cfg = bcm283x_get_current_memcfg();
+ return (cfg->busdma_lowaddr);
+}
Index: head/sys/arm/broadcom/bcm2835/files.bcm283x
===================================================================
--- head/sys/arm/broadcom/bcm2835/files.bcm283x
+++ head/sys/arm/broadcom/bcm2835/files.bcm283x
@@ -14,6 +14,7 @@
arm/broadcom/bcm2835/bcm2835_sdhci.c optional sdhci
arm/broadcom/bcm2835/bcm2835_sdhost.c optional sdhci
arm/broadcom/bcm2835/bcm2835_spi.c optional bcm2835_spi
+arm/broadcom/bcm2835/bcm2835_vcbus.c standard
arm/broadcom/bcm2835/bcm2835_vcio.c standard
arm/broadcom/bcm2835/bcm2835_wdog.c standard
arm/broadcom/bcm2835/bcm283x_dwc_fdt.c optional dwcotg fdt
Index: head/sys/conf/files.arm64
===================================================================
--- head/sys/conf/files.arm64
+++ head/sys/conf/files.arm64
@@ -101,6 +101,7 @@
arm/broadcom/bcm2835/bcm2835_sdhci.c optional sdhci soc_brcm_bcm2837 fdt | sdhci soc_brcm_bcm2838 fdt
arm/broadcom/bcm2835/bcm2835_sdhost.c optional sdhci soc_brcm_bcm2837 fdt | sdhci soc_brcm_bcm2838 fdt
arm/broadcom/bcm2835/bcm2835_spi.c optional bcm2835_spi fdt
+arm/broadcom/bcm2835/bcm2835_vcbus.c optional soc_brcm_bcm2837 fdt | soc_brcm_bcm2838 fdt
arm/broadcom/bcm2835/bcm2835_vcio.c optional soc_brcm_bcm2837 fdt | soc_brcm_bcm2838 fdt
arm/broadcom/bcm2835/bcm2835_wdog.c optional soc_brcm_bcm2837 fdt | soc_brcm_bcm2838 fdt
arm/broadcom/bcm2835/bcm2836.c optional soc_brcm_bcm2837 fdt | soc_brcm_bcm2838 fdt

File Metadata

Mime Type
text/plain
Expires
Sat, Sep 26, 6:02 PM (9 h, 20 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
39682080
Default Alt Text
D22301.id.diff (15 KB)

Event Timeline