6a58041e9403dcac7b9a49d1a79104c41c754710
[openwrt/staging/blocktrron.git] /
1 From 7de61a52d473ac56e3ab1431da52cb2c3a0476f6 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: mmal-vchiq: 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 mmal-vchiq.
9
10 Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
11 ---
12 .../staging/vc04_services/vchiq-mmal/Kconfig | 1 +
13 .../vc04_services/vchiq-mmal/mmal-common.h | 4 ++
14 .../vc04_services/vchiq-mmal/mmal-vchiq.c | 65 ++++++++++++++++++-
15 .../vc04_services/vchiq-mmal/mmal-vchiq.h | 1 +
16 4 files changed, 69 insertions(+), 2 deletions(-)
17
18 --- a/drivers/staging/vc04_services/vchiq-mmal/Kconfig
19 +++ b/drivers/staging/vc04_services/vchiq-mmal/Kconfig
20 @@ -1,6 +1,7 @@
21 config BCM2835_VCHIQ_MMAL
22 tristate "BCM2835 MMAL VCHIQ service"
23 depends on BCM2835_VCHIQ
24 + select BCM_VC_SM_CMA
25 help
26 Enables the MMAL API over VCHIQ interface as used for the
27 majority of the multimedia services on VideoCore.
28 --- a/drivers/staging/vc04_services/vchiq-mmal/mmal-common.h
29 +++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-common.h
30 @@ -50,6 +50,10 @@ struct mmal_buffer {
31
32 struct mmal_msg_context *msg_context;
33
34 + struct dma_buf *dma_buf;/* Exported dmabuf fd from videobuf2 */
35 + void *vcsm_handle; /* VCSM handle having imported the dmabuf */
36 + u32 vc_handle; /* VC handle to that dmabuf */
37 +
38 u32 cmd; /* MMAL command. 0=data. */
39 unsigned long length;
40 u32 mmal_flags;
41 --- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c
42 +++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c
43 @@ -27,9 +27,11 @@
44 #include <media/videobuf2-vmalloc.h>
45
46 #include "mmal-common.h"
47 +#include "mmal-parameters.h"
48 #include "mmal-vchiq.h"
49 #include "mmal-msg.h"
50
51 +#include "vc-sm-cma/vc_sm_knl.h"
52 /*
53 * maximum number of components supported.
54 * This matches the maximum permitted by default on the VPU
55 @@ -419,8 +421,13 @@ buffer_from_host(struct vchiq_mmal_insta
56
57 /* buffer header */
58 m.u.buffer_from_host.buffer_header.cmd = 0;
59 - m.u.buffer_from_host.buffer_header.data =
60 - (u32)(unsigned long)buf->buffer;
61 + if (port->zero_copy) {
62 + m.u.buffer_from_host.buffer_header.data = buf->vc_handle;
63 + } else {
64 + m.u.buffer_from_host.buffer_header.data =
65 + (u32)(unsigned long)buf->buffer;
66 + }
67 +
68 m.u.buffer_from_host.buffer_header.alloc_size = buf->buffer_size;
69 if (port->type == MMAL_PORT_TYPE_OUTPUT) {
70 m.u.buffer_from_host.buffer_header.length = 0;
71 @@ -586,6 +593,22 @@ static void buffer_to_host_cb(struct vch
72
73 msg_context->u.bulk.status = msg->h.status;
74
75 + } else if (msg->u.buffer_from_host.is_zero_copy) {
76 + /*
77 + * Zero copy buffer, so nothing to do.
78 + * Copy buffer info and make callback.
79 + */
80 + msg_context->u.bulk.buffer_used =
81 + msg->u.buffer_from_host.buffer_header.length;
82 + msg_context->u.bulk.mmal_flags =
83 + msg->u.buffer_from_host.buffer_header.flags;
84 + msg_context->u.bulk.dts =
85 + msg->u.buffer_from_host.buffer_header.dts;
86 + msg_context->u.bulk.pts =
87 + msg->u.buffer_from_host.buffer_header.pts;
88 + msg_context->u.bulk.cmd =
89 + msg->u.buffer_from_host.buffer_header.cmd;
90 +
91 } else if (msg->u.buffer_from_host.buffer_header.length == 0) {
92 /* empty buffer */
93 if (msg->u.buffer_from_host.buffer_header.flags &
94 @@ -1530,6 +1553,9 @@ int vchiq_mmal_port_parameter_set(struct
95
96 mutex_unlock(&instance->vchiq_mutex);
97
98 + if (parameter == MMAL_PARAMETER_ZERO_COPY && !ret)
99 + port->zero_copy = !!(*(bool *)value);
100 +
101 return ret;
102 }
103 EXPORT_SYMBOL_GPL(vchiq_mmal_port_parameter_set);
104 @@ -1698,6 +1724,31 @@ int vchiq_mmal_submit_buffer(struct vchi
105 unsigned long flags = 0;
106 int ret;
107
108 + /*
109 + * We really want to do this in mmal_vchi_buffer_init but can't as
110 + * videobuf2 won't let us have the dmabuf there.
111 + */
112 + if (port->zero_copy && buffer->dma_buf && !buffer->vcsm_handle) {
113 + pr_debug("%s: import dmabuf %p\n", __func__, buffer->dma_buf);
114 + ret = vc_sm_cma_import_dmabuf(buffer->dma_buf,
115 + &buffer->vcsm_handle);
116 + if (ret) {
117 + pr_err("%s: vc_sm_import_dmabuf_fd failed, ret %d\n",
118 + __func__, ret);
119 + return ret;
120 + }
121 +
122 + buffer->vc_handle = vc_sm_cma_int_handle(buffer->vcsm_handle);
123 + if (!buffer->vc_handle) {
124 + pr_err("%s: vc_sm_int_handle failed %d\n",
125 + __func__, ret);
126 + vc_sm_cma_free(buffer->vcsm_handle);
127 + return ret;
128 + }
129 + pr_debug("%s: import dmabuf %p - got vc handle %08X\n",
130 + __func__, buffer->dma_buf, buffer->vc_handle);
131 + }
132 +
133 ret = buffer_from_host(instance, port, buffer);
134 if (ret == -EINVAL) {
135 /* Port is disabled. Queue for when it is enabled. */
136 @@ -1731,6 +1782,16 @@ int mmal_vchi_buffer_cleanup(struct mmal
137 release_msg_context(msg_context);
138 buf->msg_context = NULL;
139
140 + if (buf->vcsm_handle) {
141 + int ret;
142 +
143 + pr_debug("%s: vc_sm_cma_free on handle %p\n", __func__,
144 + buf->vcsm_handle);
145 + ret = vc_sm_cma_free(buf->vcsm_handle);
146 + if (ret)
147 + pr_err("%s: vcsm_free failed, ret %d\n", __func__, ret);
148 + buf->vcsm_handle = 0;
149 + }
150 return 0;
151 }
152 EXPORT_SYMBOL_GPL(mmal_vchi_buffer_cleanup);
153 --- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.h
154 +++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.h
155 @@ -49,6 +49,7 @@ typedef void (*vchiq_mmal_buffer_cb)(
156
157 struct vchiq_mmal_port {
158 u32 enabled:1;
159 + u32 zero_copy:1;
160 u32 handle;
161 u32 type; /* port type, cached to use on port info set */
162 u32 index; /* port index, cached to use on port info set */