93dbba1cc07216791f7067c99a73380d98c2ad35
[oweals/openwrt.git] /
1 From d3c99e301ac57e6c1a5e13b341baacd7182a5763 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 277/703] 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/vc04_services/vchiq-mmal/Kconfig  |  1 +
13  .../vc04_services/vchiq-mmal/mmal-common.h    |  4 ++
14  .../vc04_services/vchiq-mmal/mmal-vchiq.c     | 66 ++++++++++++++++++-
15  .../vc04_services/vchiq-mmal/mmal-vchiq.h     |  1 +
16  4 files changed, 70 insertions(+), 2 deletions(-)
17
18 --- a/drivers/staging/vc04_services/vchiq-mmal/Kconfig
19 +++ b/drivers/staging/vc04_services/vchiq-mmal/Kconfig
20 @@ -2,6 +2,7 @@ config BCM2835_VCHIQ_MMAL
21         tristate "BCM2835 MMAL VCHIQ service"
22         depends on (ARCH_BCM2835 || COMPILE_TEST)
23         select BCM2835_VCHIQ
24 +       select BCM_VC_SM_CMA
25         help
26           Enables the MMAL API over VCHIQ 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 @@ -51,6 +51,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 +       int 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,12 @@
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  #define USE_VCHIQ_ARM
54  #include "interface/vchi/vchi.h"
55  
56 @@ -424,8 +427,13 @@ buffer_from_host(struct vchiq_mmal_insta
57  
58         /* buffer header */
59         m.u.buffer_from_host.buffer_header.cmd = 0;
60 -       m.u.buffer_from_host.buffer_header.data =
61 -               (u32)(unsigned long)buf->buffer;
62 +       if (port->zero_copy) {
63 +               m.u.buffer_from_host.buffer_header.data = buf->vc_handle;
64 +       } else {
65 +               m.u.buffer_from_host.buffer_header.data =
66 +                       (u32)(unsigned long)buf->buffer;
67 +       }
68 +
69         m.u.buffer_from_host.buffer_header.alloc_size = buf->buffer_size;
70         if (port->type == MMAL_PORT_TYPE_OUTPUT) {
71                 m.u.buffer_from_host.buffer_header.length = 0;
72 @@ -590,6 +598,22 @@ static void buffer_to_host_cb(struct vch
73  
74                 msg_context->u.bulk.status = msg->h.status;
75  
76 +       } else if (msg->u.buffer_from_host.is_zero_copy) {
77 +               /*
78 +                * Zero copy buffer, so nothing to do.
79 +                * Copy buffer info and make callback.
80 +                */
81 +               msg_context->u.bulk.buffer_used =
82 +                               msg->u.buffer_from_host.buffer_header.length;
83 +               msg_context->u.bulk.mmal_flags =
84 +                               msg->u.buffer_from_host.buffer_header.flags;
85 +               msg_context->u.bulk.dts =
86 +                               msg->u.buffer_from_host.buffer_header.dts;
87 +               msg_context->u.bulk.pts =
88 +                               msg->u.buffer_from_host.buffer_header.pts;
89 +               msg_context->u.bulk.cmd =
90 +                               msg->u.buffer_from_host.buffer_header.cmd;
91 +
92         } else if (msg->u.buffer_from_host.buffer_header.length == 0) {
93                 /* empty buffer */
94                 if (msg->u.buffer_from_host.buffer_header.flags &
95 @@ -1537,6 +1561,9 @@ int vchiq_mmal_port_parameter_set(struct
96  
97         mutex_unlock(&instance->vchiq_mutex);
98  
99 +       if (parameter == MMAL_PARAMETER_ZERO_COPY && !ret)
100 +               port->zero_copy = !!(*(bool *)value);
101 +
102         return ret;
103  }
104  EXPORT_SYMBOL_GPL(vchiq_mmal_port_parameter_set);
105 @@ -1705,6 +1732,31 @@ int vchiq_mmal_submit_buffer(struct vchi
106         unsigned long flags = 0;
107         int ret;
108  
109 +       /*
110 +        * We really want to do this in mmal_vchi_buffer_init but can't as
111 +        * videobuf2 won't let us have the dmabuf there.
112 +        */
113 +       if (port->zero_copy && buffer->dma_buf && !buffer->vcsm_handle) {
114 +               pr_debug("%s: import dmabuf %p\n", __func__, buffer->dma_buf);
115 +               ret = vc_sm_cma_import_dmabuf(buffer->dma_buf,
116 +                                             &buffer->vcsm_handle);
117 +               if (ret) {
118 +                       pr_err("%s: vc_sm_import_dmabuf_fd failed, ret %d\n",
119 +                              __func__, ret);
120 +                       return ret;
121 +               }
122 +
123 +               buffer->vc_handle = vc_sm_cma_int_handle(buffer->vcsm_handle);
124 +               if (!buffer->vc_handle) {
125 +                       pr_err("%s: vc_sm_int_handle failed %d\n",
126 +                              __func__, ret);
127 +                       vc_sm_cma_free(buffer->vcsm_handle);
128 +                       return ret;
129 +               }
130 +               pr_debug("%s: import dmabuf %p - got vc handle %08X\n",
131 +                        __func__, buffer->dma_buf, buffer->vc_handle);
132 +       }
133 +
134         ret = buffer_from_host(instance, port, buffer);
135         if (ret == -EINVAL) {
136                 /* Port is disabled. Queue for when it is enabled. */
137 @@ -1738,6 +1790,16 @@ int mmal_vchi_buffer_cleanup(struct mmal
138                 release_msg_context(msg_context);
139         buf->msg_context = NULL;
140  
141 +       if (buf->vcsm_handle) {
142 +               int ret;
143 +
144 +               pr_debug("%s: vc_sm_cma_free on handle %08X\n", __func__,
145 +                        buf->vcsm_handle);
146 +               ret = vc_sm_cma_free(buf->vcsm_handle);
147 +               if (ret)
148 +                       pr_err("%s: vcsm_free failed, ret %d\n", __func__, ret);
149 +               buf->vcsm_handle = 0;
150 +       }
151         return 0;
152  }
153  EXPORT_SYMBOL_GPL(mmal_vchi_buffer_cleanup);
154 --- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.h
155 +++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.h
156 @@ -49,6 +49,7 @@ typedef void (*vchiq_mmal_buffer_cb)(
157  
158  struct vchiq_mmal_port {
159         u32 enabled:1;
160 +       u32 zero_copy:1;
161         u32 handle;
162         u32 type; /* port type, cached to use on port info set */
163         u32 index; /* port index, cached to use on port info set */