From ae8855dfba8b3a5406f9efd02330d6b71c55745e Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Wed, 20 May 2020 16:36:33 +0100 Subject: [PATCH 1/2] staging: vchiq_arm: Clean up 40-bit DMA support Manage the split between addresses for the VPU and addresses for the 40-bit DMA controller with a dedicated DMA device pointer that on non- BCM2711 platforms is the same as the main VCHIQ device. This allows the VCHIQ node to stay in the usual place in the DT, and removes the ugly VC_SAFE macros. Signed-off-by: Phil Elwell --- .../interface/vchiq_arm/vchiq_2835_arm.c | 39 ++++++++++++------- .../interface/vchiq_arm/vchiq_arm.c | 14 ------- 2 files changed, 25 insertions(+), 28 deletions(-) diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c index 2dfdee1f814f15..d6a6ca9e06ec69 100644 --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c @@ -16,8 +16,6 @@ #include #define TOTAL_SLOTS (VCHIQ_SLOT_ZERO_SLOTS + 2 * 32) -#define VC_SAFE(x) (g_use_36bit_addrs ? ((u32)(x) | 0xc0000000) : (u32)(x)) -#define IS_VC_SAFE(x) (g_use_36bit_addrs ? !((x) & ~0x3fffffffull) : 1) #include "vchiq_arm.h" #include "vchiq_connected.h" @@ -71,6 +69,7 @@ static char *g_fragments_base; static char *g_free_fragments; static struct semaphore g_free_fragments_sema; static struct device *g_dev; +static struct device *g_dma_dev; static DEFINE_SEMAPHORE(g_free_fragments_mutex); @@ -87,6 +86,7 @@ free_pagelist(struct vchiq_pagelist_info *pagelistinfo, int vchiq_platform_init(struct platform_device *pdev, struct vchiq_state *state) { struct device *dev = &pdev->dev; + struct device *dma_dev = NULL; struct vchiq_drvdata *drvdata = platform_get_drvdata(pdev); struct rpi_firmware *fw = drvdata->fw; struct vchiq_slot_zero *vchiq_slot_zero; @@ -109,7 +109,23 @@ int vchiq_platform_init(struct platform_device *pdev, struct vchiq_state *state) g_cache_line_size = drvdata->cache_line_size; g_fragments_size = 2 * g_cache_line_size; - g_use_36bit_addrs = (dev->dma_pfn_offset == 0); + if (drvdata->use_36bit_addrs) { + struct device_node *dma_node = + of_find_compatible_node(NULL, NULL, "brcm,bcm2711-dma"); + + if (dma_node) { + struct platform_device *pdev; + + pdev = of_find_device_by_node(dma_node); + if (pdev) + dma_dev = &pdev->dev; + of_node_put(dma_node); + g_use_36bit_addrs = true; + } else { + dev_err(dev, "40-bit DMA controller not found\n"); + return -EINVAL; + } + } /* Allocate space for the channels in coherent memory */ slot_mem_size = PAGE_ALIGN(TOTAL_SLOTS * VCHIQ_SLOT_SIZE); @@ -122,14 +138,8 @@ int vchiq_platform_init(struct platform_device *pdev, struct vchiq_state *state) return -ENOMEM; } - if (!IS_VC_SAFE(slot_phys)) { - dev_err(dev, "allocated DMA memory %pad is not VC-safe\n", - &slot_phys); - return -ENOMEM; - } - WARN_ON(((unsigned long)slot_mem & (PAGE_SIZE - 1)) != 0); - channelbase = VC_SAFE(slot_phys); + channelbase = slot_phys; vchiq_slot_zero = vchiq_init_slots(slot_mem, slot_mem_size); if (!vchiq_slot_zero) @@ -178,6 +188,7 @@ int vchiq_platform_init(struct platform_device *pdev, struct vchiq_state *state) } g_dev = dev; + g_dma_dev = dma_dev ?: dev; g_dma_pool = dmam_pool_create("vchiq_scatter_pool", dev, VCHIQ_DMA_POOL_SIZE, g_cache_line_size, 0); @@ -255,7 +266,7 @@ vchiq_prepare_bulk_data(struct vchiq_bulk *bulk, void *offset, int size, if (!pagelistinfo) return VCHIQ_ERROR; - bulk->data = (void *)(uintptr_t)VC_SAFE(pagelistinfo->dma_addr); + bulk->data = (void *)(uintptr_t)pagelistinfo->dma_addr; /* * Store the pagelistinfo address in remote_data, @@ -354,7 +365,7 @@ static void cleanup_pagelistinfo(struct vchiq_pagelist_info *pagelistinfo) { if (pagelistinfo->scatterlist_mapped) { - dma_unmap_sg(g_dev, pagelistinfo->scatterlist, + dma_unmap_sg(g_dma_dev, pagelistinfo->scatterlist, pagelistinfo->num_pages, pagelistinfo->dma_dir); } @@ -519,7 +530,7 @@ create_pagelist(char __user *buf, size_t count, unsigned short type) count -= len; } - dma_buffers = dma_map_sg(g_dev, + dma_buffers = dma_map_sg(g_dma_dev, scatterlist, num_pages, pagelistinfo->dma_dir); @@ -569,7 +580,7 @@ create_pagelist(char __user *buf, size_t count, unsigned short type) } else { for_each_sg(scatterlist, sg, dma_buffers, i) { u32 len = sg_dma_len(sg); - u32 addr = VC_SAFE(sg_dma_address(sg)); + u32 addr = sg_dma_address(sg); u32 new_pages = (len + PAGE_SIZE - 1) >> PAGE_SHIFT; /* Note: addrs is the address + page_count - 1 diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c index d01c2d42431047..d55f038637fc4e 100644 --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c @@ -3205,22 +3205,8 @@ vchiq_register_child(struct platform_device *pdev, const char *name) child->dev.of_node = np; - /* - * We want the dma-ranges etc to be copied from a device with the - * correct dma-ranges for the VPU. - * VCHIQ on Pi4 is now under scb which doesn't get those dma-ranges. - * Take the "dma" node as going to be suitable as it sees the world - * through the same eyes as the VPU. - */ - np = of_find_node_by_path("dma"); - if (!np) - np = pdev->dev.of_node; - of_dma_configure(&child->dev, np, true); - if (np != pdev->dev.of_node) - of_node_put(np); - return child; } From e567395d7a65e08507b587787da3c1e4f99d5b46 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Wed, 20 May 2020 16:36:57 +0100 Subject: [PATCH 2/2] ARM: dts: Update for new VCHIQ BCM2711 DMA support Now that the enhanced BCM2711 DMA controller is located by compatible string and used directly for generating bulk transfer addresses, remove the workaround of moving the vchiq node. Signed-off-by: Phil Elwell --- arch/arm/boot/dts/bcm2711-rpi.dtsi | 23 ++++------------------- 1 file changed, 4 insertions(+), 19 deletions(-) diff --git a/arch/arm/boot/dts/bcm2711-rpi.dtsi b/arch/arm/boot/dts/bcm2711-rpi.dtsi index 2c55c78bd7cb31..46bcfd586f1736 100644 --- a/arch/arm/boot/dts/bcm2711-rpi.dtsi +++ b/arch/arm/boot/dts/bcm2711-rpi.dtsi @@ -4,7 +4,6 @@ / { soc { /delete-node/ v3d@7ec00000; - /delete-node/ mailbox@7e00b840; }; __overrides__ { @@ -88,12 +87,6 @@ brcm,dma-channel-mask = <0x7800>; }; - vchiq: mailbox@7e00b840 { - compatible = "brcm,bcm2711-vchiq"; - reg = <0 0x7e00b840 0x0 0x3c>; - interrupts = ; - }; - xhci: xhci@7e9c0000 { compatible = "generic-xhci"; status = "disabled"; @@ -127,18 +120,6 @@ }; }; -&vchiq { - /* Onboard audio - * This node is replicated because the original from bcm270x-rpi.dtsi - * was deleted when the vchiq node was deleted above. - */ - audio: bcm2835_audio { - compatible = "brcm,bcm2835-audio"; - brcm,pwm-channels = <8>; - status = "disabled"; - }; -}; - &dma { /* The VPU firmware uses DMA channel 11 for VCHIQ */ brcm,dma-channel-mask = <0x1f5>; @@ -149,6 +130,10 @@ brcm,dma-channel-mask = <0x7000>; }; +&vchiq { + compatible = "brcm,bcm2711-vchiq"; +}; + &firmwarekms { interrupts = ; };