aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/bcm27xx/patches-5.4/950-0746-staging-vchiq_arm-Clean-up-40-bit-DMA-support.patch
blob: 1dac504877f6c98fbcf756c01cba3b3bac68a76d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
From d8cbdaa729d5d3e9a1c18150bf4de69335a85a40 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.com>
Date: Wed, 20 May 2020 16:36:33 +0100
Subject: [PATCH] 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 <phil@raspberrypi.com>
---
 .../interface/vchiq_arm/vchiq_2835_arm.c      | 39 ++++++++++++-------
 .../interface/vchiq_arm/vchiq_arm.c           | 14 -------
 2 files changed, 25 insertions(+), 28 deletions(-)

--- 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 <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"
@@ -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
 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_
 	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_
 		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_
 	}
 
 	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_bul
 	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 -= 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
 	} 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
--- 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_dev
 
 	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;
 }