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
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.
10 Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.org>
12 staging: vc-sm-cma: Use a void* pointer as the handle within the kernel
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
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
24 Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.org>
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(-)
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)
38 + select BCM_VC_SM_CMA
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 {
46 struct mmal_msg_context *msg_context;
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 */
52 u32 cmd; /* MMAL command. 0=data. */
55 --- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c
56 +++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c
58 #include <media/videobuf2-vmalloc.h>
60 #include "mmal-common.h"
61 +#include "mmal-parameters.h"
62 #include "mmal-vchiq.h"
65 +#include "vc-sm-cma/vc_sm_knl.h"
68 #include "interface/vchi/vchi.h"
70 @@ -424,8 +427,13 @@ buffer_from_host(struct vchiq_mmal_insta
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;
79 + m.u.buffer_from_host.buffer_header.data =
80 + (u32)(unsigned long)buf->buffer;
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
88 msg_context->u.bulk.status = msg->h.status;
90 + } else if (msg->u.buffer_from_host.is_zero_copy) {
92 + * Zero copy buffer, so nothing to do.
93 + * Copy buffer info and make callback.
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;
106 } else if (msg->u.buffer_from_host.buffer_header.length == 0) {
108 if (msg->u.buffer_from_host.buffer_header.flags &
109 @@ -1537,6 +1561,9 @@ int vchiq_mmal_port_parameter_set(struct
111 mutex_unlock(&instance->vchiq_mutex);
113 + if (parameter == MMAL_PARAMETER_ZERO_COPY && !ret)
114 + port->zero_copy = !!(*(bool *)value);
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;
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.
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);
132 + pr_err("%s: vc_sm_import_dmabuf_fd failed, ret %d\n",
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",
141 + vc_sm_cma_free(buffer->vcsm_handle);
144 + pr_debug("%s: import dmabuf %p - got vc handle %08X\n",
145 + __func__, buffer->dma_buf, buffer->vc_handle);
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;
155 + if (buf->vcsm_handle) {
158 + pr_debug("%s: vc_sm_cma_free on handle %p\n", __func__,
160 + ret = vc_sm_cma_free(buf->vcsm_handle);
162 + pr_err("%s: vcsm_free failed, ret %d\n", __func__, ret);
163 + buf->vcsm_handle = 0;
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)(
172 struct vchiq_mmal_port {
176 u32 type; /* port type, cached to use on port info set */
177 u32 index; /* port index, cached to use on port info set */