aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/bcm27xx/patches-4.19/950-0310-staging-bcm2835_codec-Fix-handling-of-VB2_MEMORY_DMA.patch
blob: 7e3373e4891ee5463e4aaf77e98ef9c7c451b3ff (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
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
From 0df32e2f563123166c20677f022d4a0f825c5df2 Mon Sep 17 00:00:00 2001
From: Dave Stevenson <dave.stevenson@raspberrypi.org>
Date: Fri, 15 Feb 2019 11:38:45 +0000
Subject: [PATCH] staging: bcm2835_codec: Fix handling of
 VB2_MEMORY_DMABUF buffers

If the queue is configured as VB2_MEMORY_DMABUF then vb2_core_expbuf
fails as it ensures the queue is defined as VB2_MEMORY_MMAP.

Correct the handling so that we unmap the buffer from vcsm and the
VPU on cleanup, and then correctly get the dma buf of the new buffer.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.org>
---
 .../bcm2835-codec/bcm2835-v4l2-codec.c        | 80 +++++++++++++------
 .../vc04_services/vchiq-mmal/mmal-vchiq.c     | 21 +++--
 .../vc04_services/vchiq-mmal/mmal-vchiq.h     |  2 +
 3 files changed, 73 insertions(+), 30 deletions(-)

--- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c
+++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c
@@ -1852,6 +1852,18 @@ static int bcm2835_codec_queue_setup(str
 	return 0;
 }
 
+static int bcm2835_codec_mmal_buf_cleanup(struct mmal_buffer *mmal_buf)
+{
+	mmal_vchi_buffer_cleanup(mmal_buf);
+
+	if (mmal_buf->dma_buf) {
+		dma_buf_put(mmal_buf->dma_buf);
+		mmal_buf->dma_buf = NULL;
+	}
+
+	return 0;
+}
+
 static int bcm2835_codec_buf_init(struct vb2_buffer *vb)
 {
 	struct bcm2835_codec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
@@ -1880,6 +1892,7 @@ static int bcm2835_codec_buf_prepare(str
 						   vb);
 	struct m2m_mmal_buffer *buf = container_of(m2m, struct m2m_mmal_buffer,
 						   m2m);
+	struct dma_buf *dma_buf;
 	int ret;
 
 	v4l2_dbg(4, debug, &ctx->dev->v4l2_dev, "%s: type: %d ptr %p\n",
@@ -1906,20 +1919,48 @@ static int bcm2835_codec_buf_prepare(str
 	if (!V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type))
 		vb2_set_plane_payload(vb, 0, q_data->sizeimage);
 
-	/*
-	 * We want to do this at init, but vb2_core_expbuf checks that the
-	 * index < q->num_buffers, and q->num_buffers only gets updated once
-	 * all the buffers are allocated.
-	 */
-	if (!buf->mmal.dma_buf) {
-		ret = vb2_core_expbuf_dmabuf(vb->vb2_queue,
-					     vb->vb2_queue->type, vb->index, 0,
-					     O_CLOEXEC, &buf->mmal.dma_buf);
-		if (ret)
-			v4l2_err(&ctx->dev->v4l2_dev, "%s: Failed to expbuf idx %d, ret %d\n",
-				 __func__, vb->index, ret);
-	} else {
+	switch (vb->memory) {
+	case VB2_MEMORY_DMABUF:
+		dma_buf = dma_buf_get(vb->planes[0].m.fd);
+
+		if (dma_buf != buf->mmal.dma_buf) {
+			/* dmabuf either hasn't already been mapped, or it has
+			 * changed.
+			 */
+			if (buf->mmal.dma_buf) {
+				v4l2_err(&ctx->dev->v4l2_dev,
+					 "%s Buffer changed - why did the core not call cleanup?\n",
+					 __func__);
+				bcm2835_codec_mmal_buf_cleanup(&buf->mmal);
+			}
+
+			buf->mmal.dma_buf = dma_buf;
+		}
 		ret = 0;
+		break;
+	case VB2_MEMORY_MMAP:
+		/*
+		 * We want to do this at init, but vb2_core_expbuf checks that
+		 * the index < q->num_buffers, and q->num_buffers only gets
+		 * updated once all the buffers are allocated.
+		 */
+		if (!buf->mmal.dma_buf) {
+			ret = vb2_core_expbuf_dmabuf(vb->vb2_queue,
+						     vb->vb2_queue->type,
+						     vb->index, 0,
+						     O_CLOEXEC,
+						     &buf->mmal.dma_buf);
+			if (ret)
+				v4l2_err(&ctx->dev->v4l2_dev,
+					 "%s: Failed to expbuf idx %d, ret %d\n",
+					 __func__, vb->index, ret);
+		} else {
+			ret = 0;
+		}
+		break;
+	default:
+		ret = -EINVAL;
+		break;
 	}
 
 	return ret;
@@ -1948,12 +1989,7 @@ static void bcm2835_codec_buffer_cleanup
 	v4l2_dbg(2, debug, &ctx->dev->v4l2_dev, "%s: ctx:%p, vb %p\n",
 		 __func__, ctx, vb);
 
-	mmal_vchi_buffer_cleanup(&buf->mmal);
-
-	if (buf->mmal.dma_buf) {
-		dma_buf_put(buf->mmal.dma_buf);
-		buf->mmal.dma_buf = NULL;
-	}
+	bcm2835_codec_mmal_buf_cleanup(&buf->mmal);
 }
 
 static int bcm2835_codec_start_streaming(struct vb2_queue *q,
@@ -2067,11 +2103,7 @@ static void bcm2835_codec_stop_streaming
 		m2m = container_of(vb2, struct v4l2_m2m_buffer, vb);
 		buf = container_of(m2m, struct m2m_mmal_buffer, m2m);
 
-		mmal_vchi_buffer_cleanup(&buf->mmal);
-		if (buf->mmal.dma_buf) {
-			dma_buf_put(buf->mmal.dma_buf);
-			buf->mmal.dma_buf = NULL;
-		}
+		bcm2835_codec_mmal_buf_cleanup(&buf->mmal);
 	}
 
 	/* If both ports disabled, then disable the component */
--- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c
+++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c
@@ -1785,13 +1785,9 @@ int mmal_vchi_buffer_init(struct vchiq_m
 }
 EXPORT_SYMBOL_GPL(mmal_vchi_buffer_init);
 
-int mmal_vchi_buffer_cleanup(struct mmal_buffer *buf)
+int mmal_vchi_buffer_unmap(struct mmal_buffer *buf)
 {
-	struct mmal_msg_context *msg_context = buf->msg_context;
-
-	if (msg_context)
-		release_msg_context(msg_context);
-	buf->msg_context = NULL;
+	int ret = 0;
 
 	if (buf->vcsm_handle) {
 		int ret;
@@ -1803,6 +1799,19 @@ int mmal_vchi_buffer_cleanup(struct mmal
 			pr_err("%s: vcsm_free failed, ret %d\n", __func__, ret);
 		buf->vcsm_handle = 0;
 	}
+	return ret;
+}
+EXPORT_SYMBOL_GPL(mmal_vchi_buffer_unmap);
+
+int mmal_vchi_buffer_cleanup(struct mmal_buffer *buf)
+{
+	struct mmal_msg_context *msg_context = buf->msg_context;
+
+	if (msg_context)
+		release_msg_context(msg_context);
+	buf->msg_context = NULL;
+
+	mmal_vchi_buffer_unmap(buf);
 	return 0;
 }
 EXPORT_SYMBOL_GPL(mmal_vchi_buffer_cleanup);
--- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.h
+++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.h
@@ -167,6 +167,8 @@ int vchiq_mmal_submit_buffer(struct vchi
 			     struct vchiq_mmal_port *port,
 			     struct mmal_buffer *buf);
 
+int mmal_vchi_buffer_unmap(struct mmal_buffer *buf);
+
 int mmal_vchi_buffer_init(struct vchiq_mmal_instance *instance,
 			  struct mmal_buffer *buf);
 int mmal_vchi_buffer_cleanup(struct mmal_buffer *buf);