62cce8a94e0772dc20edac241263e57e65258672
[openwrt/staging/981213.git] /
1 From 511b809d5b227b179acca537cba85e2bdff87b94 Mon Sep 17 00:00:00 2001
2 From: Dave Stevenson <dave.stevenson@raspberrypi.org>
3 Date: Tue, 25 Sep 2018 16:07:55 +0100
4 Subject: [PATCH] staging: vc04_services: Use vc-sm-cma to support zero
5 copy
6
7 With the vc-sm-cma driver we can support zero copy of buffers between
8 the kernel and VPU. Add this support to vchiq-mmal.
9
10 Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.org>
11
12 staging: vc-sm-cma: Use a void* pointer as the handle within the kernel
13
14 The driver was using an unsigned int as the handle to the outside world,
15 and doing a nasty cast to the struct dmabuf when handed it back.
16 This breaks badly with a 64 bit kernel where the pointer doesn't fit
17 in an unsigned int.
18
19 Switch to using a void* within the kernel. Reality is that it is
20 a struct dma_buf*, but advertising it as such to other drivers seems
21 to encourage the use of it as such, and I'm not sure on the implications
22 of that.
23
24 Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.org>
25 ---
26 .../staging/vc04_services/vchiq-mmal/Kconfig | 1 +
27 .../vc04_services/vchiq-mmal/mmal-common.h | 4 ++
28 .../vc04_services/vchiq-mmal/mmal-vchiq.c | 66 ++++++++++++++++++-
29 .../vc04_services/vchiq-mmal/mmal-vchiq.h | 1 +
30 4 files changed, 70 insertions(+), 2 deletions(-)
31
32 --- a/drivers/staging/vc04_services/vchiq-mmal/Kconfig
33 +++ b/drivers/staging/vc04_services/vchiq-mmal/Kconfig
34 @@ -2,6 +2,7 @@ config BCM2835_VCHIQ_MMAL
35 tristate "BCM2835 MMAL VCHIQ service"
36 depends on (ARCH_BCM2835 || COMPILE_TEST)
37 select BCM2835_VCHIQ
38 + select BCM_VC_SM_CMA
39 help
40 Enables the MMAL API over VCHIQ as used for the
41 majority of the multimedia services on VideoCore.
42 --- a/drivers/staging/vc04_services/vchiq-mmal/mmal-common.h
43 +++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-common.h
44 @@ -50,6 +50,10 @@ struct mmal_buffer {
45
46 struct mmal_msg_context *msg_context;
47
48 + struct dma_buf *dma_buf;/* Exported dmabuf fd from videobuf2 */
49 + void *vcsm_handle; /* VCSM handle having imported the dmabuf */
50 + u32 vc_handle; /* VC handle to that dmabuf */
51 +
52 u32 cmd; /* MMAL command. 0=data. */
53 unsigned long length;
54 u32 mmal_flags;
55 --- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c
56 +++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c
57 @@ -26,9 +26,12 @@
58 #include <media/videobuf2-vmalloc.h>
59
60 #include "mmal-common.h"
61 +#include "mmal-parameters.h"
62 #include "mmal-vchiq.h"
63 #include "mmal-msg.h"
64
65 +#include "vc-sm-cma/vc_sm_knl.h"
66 +
67 #define USE_VCHIQ_ARM
68 #include "interface/vchi/vchi.h"
69
70 @@ -424,8 +427,13 @@ buffer_from_host(struct vchiq_mmal_insta
71
72 /* buffer header */
73 m.u.buffer_from_host.buffer_header.cmd = 0;
74 - m.u.buffer_from_host.buffer_header.data =
75 - (u32)(unsigned long)buf->buffer;
76 + if (port->zero_copy) {
77 + m.u.buffer_from_host.buffer_header.data = buf->vc_handle;
78 + } else {
79 + m.u.buffer_from_host.buffer_header.data =
80 + (u32)(unsigned long)buf->buffer;
81 + }
82 +
83 m.u.buffer_from_host.buffer_header.alloc_size = buf->buffer_size;
84 if (port->type == MMAL_PORT_TYPE_OUTPUT) {
85 m.u.buffer_from_host.buffer_header.length = 0;
86 @@ -590,6 +598,22 @@ static void buffer_to_host_cb(struct vch
87
88 msg_context->u.bulk.status = msg->h.status;
89
90 + } else if (msg->u.buffer_from_host.is_zero_copy) {
91 + /*
92 + * Zero copy buffer, so nothing to do.
93 + * Copy buffer info and make callback.
94 + */
95 + msg_context->u.bulk.buffer_used =
96 + msg->u.buffer_from_host.buffer_header.length;
97 + msg_context->u.bulk.mmal_flags =
98 + msg->u.buffer_from_host.buffer_header.flags;
99 + msg_context->u.bulk.dts =
100 + msg->u.buffer_from_host.buffer_header.dts;
101 + msg_context->u.bulk.pts =
102 + msg->u.buffer_from_host.buffer_header.pts;
103 + msg_context->u.bulk.cmd =
104 + msg->u.buffer_from_host.buffer_header.cmd;
105 +
106 } else if (msg->u.buffer_from_host.buffer_header.length == 0) {
107 /* empty buffer */
108 if (msg->u.buffer_from_host.buffer_header.flags &
109 @@ -1537,6 +1561,9 @@ int vchiq_mmal_port_parameter_set(struct
110
111 mutex_unlock(&instance->vchiq_mutex);
112
113 + if (parameter == MMAL_PARAMETER_ZERO_COPY && !ret)
114 + port->zero_copy = !!(*(bool *)value);
115 +
116 return ret;
117 }
118 EXPORT_SYMBOL_GPL(vchiq_mmal_port_parameter_set);
119 @@ -1705,6 +1732,31 @@ int vchiq_mmal_submit_buffer(struct vchi
120 unsigned long flags = 0;
121 int ret;
122
123 + /*
124 + * We really want to do this in mmal_vchi_buffer_init but can't as
125 + * videobuf2 won't let us have the dmabuf there.
126 + */
127 + if (port->zero_copy && buffer->dma_buf && !buffer->vcsm_handle) {
128 + pr_debug("%s: import dmabuf %p\n", __func__, buffer->dma_buf);
129 + ret = vc_sm_cma_import_dmabuf(buffer->dma_buf,
130 + &buffer->vcsm_handle);
131 + if (ret) {
132 + pr_err("%s: vc_sm_import_dmabuf_fd failed, ret %d\n",
133 + __func__, ret);
134 + return ret;
135 + }
136 +
137 + buffer->vc_handle = vc_sm_cma_int_handle(buffer->vcsm_handle);
138 + if (!buffer->vc_handle) {
139 + pr_err("%s: vc_sm_int_handle failed %d\n",
140 + __func__, ret);
141 + vc_sm_cma_free(buffer->vcsm_handle);
142 + return ret;
143 + }
144 + pr_debug("%s: import dmabuf %p - got vc handle %08X\n",
145 + __func__, buffer->dma_buf, buffer->vc_handle);
146 + }
147 +
148 ret = buffer_from_host(instance, port, buffer);
149 if (ret == -EINVAL) {
150 /* Port is disabled. Queue for when it is enabled. */
151 @@ -1738,6 +1790,16 @@ int mmal_vchi_buffer_cleanup(struct mmal
152 release_msg_context(msg_context);
153 buf->msg_context = NULL;
154
155 + if (buf->vcsm_handle) {
156 + int ret;
157 +
158 + pr_debug("%s: vc_sm_cma_free on handle %p\n", __func__,
159 + buf->vcsm_handle);
160 + ret = vc_sm_cma_free(buf->vcsm_handle);
161 + if (ret)
162 + pr_err("%s: vcsm_free failed, ret %d\n", __func__, ret);
163 + buf->vcsm_handle = 0;
164 + }
165 return 0;
166 }
167 EXPORT_SYMBOL_GPL(mmal_vchi_buffer_cleanup);
168 --- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.h
169 +++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.h
170 @@ -49,6 +49,7 @@ typedef void (*vchiq_mmal_buffer_cb)(
171
172 struct vchiq_mmal_port {
173 u32 enabled:1;
174 + u32 zero_copy:1;
175 u32 handle;
176 u32 type; /* port type, cached to use on port info set */
177 u32 index; /* port index, cached to use on port info set */