Skip to content

Clean up the VCHIQ 2711 DMA support #3629

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 22, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 4 additions & 19 deletions arch/arm/boot/dts/bcm2711-rpi.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
/ {
soc {
/delete-node/ v3d@7ec00000;
/delete-node/ mailbox@7e00b840;
};

__overrides__ {
Expand Down Expand Up @@ -88,12 +87,6 @@
brcm,dma-channel-mask = <0x7800>;
};

vchiq: mailbox@7e00b840 {
compatible = "brcm,bcm2711-vchiq";
reg = <0 0x7e00b840 0x0 0x3c>;
interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
};

xhci: xhci@7e9c0000 {
compatible = "generic-xhci";
status = "disabled";
Expand Down Expand Up @@ -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>;
Expand All @@ -149,6 +130,10 @@
brcm,dma-channel-mask = <0x7000>;
};

&vchiq {
compatible = "brcm,bcm2711-vchiq";
};

&firmwarekms {
interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>;
};
Expand Down
39 changes: 25 additions & 14 deletions drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@
#include <soc/bcm2835/raspberrypi-firmware.h>

#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"
Expand Down Expand Up @@ -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);

Expand All @@ -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;
Expand All @@ -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);
Expand All @@ -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)
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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);
}

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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
Expand Down
14 changes: 0 additions & 14 deletions drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down