5bd32d11841e468fac1cea653b55cef4c0e006dc
[oweals/openwrt.git] /
1 From d103cd3b55e4285f2c0ad937cf31bea9ebaa4d21 Mon Sep 17 00:00:00 2001
2 From: Dave Stevenson <dave.stevenson@raspberrypi.org>
3 Date: Fri, 15 Feb 2019 11:38:45 +0000
4 Subject: [PATCH 364/703] staging: bcm2835_codec: Fix handling of
5  VB2_MEMORY_DMABUF buffers
6
7 If the queue is configured as VB2_MEMORY_DMABUF then vb2_core_expbuf
8 fails as it ensures the queue is defined as VB2_MEMORY_MMAP.
9
10 Correct the handling so that we unmap the buffer from vcsm and the
11 VPU on cleanup, and then correctly get the dma buf of the new buffer.
12
13 Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.org>
14 ---
15  .../bcm2835-codec/bcm2835-v4l2-codec.c        | 80 +++++++++++++------
16  .../vc04_services/vchiq-mmal/mmal-vchiq.c     | 21 +++--
17  .../vc04_services/vchiq-mmal/mmal-vchiq.h     |  2 +
18  3 files changed, 73 insertions(+), 30 deletions(-)
19
20 --- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c
21 +++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c
22 @@ -1852,6 +1852,18 @@ static int bcm2835_codec_queue_setup(str
23         return 0;
24  }
25  
26 +static int bcm2835_codec_mmal_buf_cleanup(struct mmal_buffer *mmal_buf)
27 +{
28 +       mmal_vchi_buffer_cleanup(mmal_buf);
29 +
30 +       if (mmal_buf->dma_buf) {
31 +               dma_buf_put(mmal_buf->dma_buf);
32 +               mmal_buf->dma_buf = NULL;
33 +       }
34 +
35 +       return 0;
36 +}
37 +
38  static int bcm2835_codec_buf_init(struct vb2_buffer *vb)
39  {
40         struct bcm2835_codec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
41 @@ -1880,6 +1892,7 @@ static int bcm2835_codec_buf_prepare(str
42                                                    vb);
43         struct m2m_mmal_buffer *buf = container_of(m2m, struct m2m_mmal_buffer,
44                                                    m2m);
45 +       struct dma_buf *dma_buf;
46         int ret;
47  
48         v4l2_dbg(4, debug, &ctx->dev->v4l2_dev, "%s: type: %d ptr %p\n",
49 @@ -1906,20 +1919,48 @@ static int bcm2835_codec_buf_prepare(str
50         if (!V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type))
51                 vb2_set_plane_payload(vb, 0, q_data->sizeimage);
52  
53 -       /*
54 -        * We want to do this at init, but vb2_core_expbuf checks that the
55 -        * index < q->num_buffers, and q->num_buffers only gets updated once
56 -        * all the buffers are allocated.
57 -        */
58 -       if (!buf->mmal.dma_buf) {
59 -               ret = vb2_core_expbuf_dmabuf(vb->vb2_queue,
60 -                                            vb->vb2_queue->type, vb->index, 0,
61 -                                            O_CLOEXEC, &buf->mmal.dma_buf);
62 -               if (ret)
63 -                       v4l2_err(&ctx->dev->v4l2_dev, "%s: Failed to expbuf idx %d, ret %d\n",
64 -                                __func__, vb->index, ret);
65 -       } else {
66 +       switch (vb->memory) {
67 +       case VB2_MEMORY_DMABUF:
68 +               dma_buf = dma_buf_get(vb->planes[0].m.fd);
69 +
70 +               if (dma_buf != buf->mmal.dma_buf) {
71 +                       /* dmabuf either hasn't already been mapped, or it has
72 +                        * changed.
73 +                        */
74 +                       if (buf->mmal.dma_buf) {
75 +                               v4l2_err(&ctx->dev->v4l2_dev,
76 +                                        "%s Buffer changed - why did the core not call cleanup?\n",
77 +                                        __func__);
78 +                               bcm2835_codec_mmal_buf_cleanup(&buf->mmal);
79 +                       }
80 +
81 +                       buf->mmal.dma_buf = dma_buf;
82 +               }
83                 ret = 0;
84 +               break;
85 +       case VB2_MEMORY_MMAP:
86 +               /*
87 +                * We want to do this at init, but vb2_core_expbuf checks that
88 +                * the index < q->num_buffers, and q->num_buffers only gets
89 +                * updated once all the buffers are allocated.
90 +                */
91 +               if (!buf->mmal.dma_buf) {
92 +                       ret = vb2_core_expbuf_dmabuf(vb->vb2_queue,
93 +                                                    vb->vb2_queue->type,
94 +                                                    vb->index, 0,
95 +                                                    O_CLOEXEC,
96 +                                                    &buf->mmal.dma_buf);
97 +                       if (ret)
98 +                               v4l2_err(&ctx->dev->v4l2_dev,
99 +                                        "%s: Failed to expbuf idx %d, ret %d\n",
100 +                                        __func__, vb->index, ret);
101 +               } else {
102 +                       ret = 0;
103 +               }
104 +               break;
105 +       default:
106 +               ret = -EINVAL;
107 +               break;
108         }
109  
110         return ret;
111 @@ -1948,12 +1989,7 @@ static void bcm2835_codec_buffer_cleanup
112         v4l2_dbg(2, debug, &ctx->dev->v4l2_dev, "%s: ctx:%p, vb %p\n",
113                  __func__, ctx, vb);
114  
115 -       mmal_vchi_buffer_cleanup(&buf->mmal);
116 -
117 -       if (buf->mmal.dma_buf) {
118 -               dma_buf_put(buf->mmal.dma_buf);
119 -               buf->mmal.dma_buf = NULL;
120 -       }
121 +       bcm2835_codec_mmal_buf_cleanup(&buf->mmal);
122  }
123  
124  static int bcm2835_codec_start_streaming(struct vb2_queue *q,
125 @@ -2067,11 +2103,7 @@ static void bcm2835_codec_stop_streaming
126                 m2m = container_of(vb2, struct v4l2_m2m_buffer, vb);
127                 buf = container_of(m2m, struct m2m_mmal_buffer, m2m);
128  
129 -               mmal_vchi_buffer_cleanup(&buf->mmal);
130 -               if (buf->mmal.dma_buf) {
131 -                       dma_buf_put(buf->mmal.dma_buf);
132 -                       buf->mmal.dma_buf = NULL;
133 -               }
134 +               bcm2835_codec_mmal_buf_cleanup(&buf->mmal);
135         }
136  
137         /* If both ports disabled, then disable the component */
138 --- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c
139 +++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c
140 @@ -1785,13 +1785,9 @@ int mmal_vchi_buffer_init(struct vchiq_m
141  }
142  EXPORT_SYMBOL_GPL(mmal_vchi_buffer_init);
143  
144 -int mmal_vchi_buffer_cleanup(struct mmal_buffer *buf)
145 +int mmal_vchi_buffer_unmap(struct mmal_buffer *buf)
146  {
147 -       struct mmal_msg_context *msg_context = buf->msg_context;
148 -
149 -       if (msg_context)
150 -               release_msg_context(msg_context);
151 -       buf->msg_context = NULL;
152 +       int ret = 0;
153  
154         if (buf->vcsm_handle) {
155                 int ret;
156 @@ -1803,6 +1799,19 @@ int mmal_vchi_buffer_cleanup(struct mmal
157                         pr_err("%s: vcsm_free failed, ret %d\n", __func__, ret);
158                 buf->vcsm_handle = 0;
159         }
160 +       return ret;
161 +}
162 +EXPORT_SYMBOL_GPL(mmal_vchi_buffer_unmap);
163 +
164 +int mmal_vchi_buffer_cleanup(struct mmal_buffer *buf)
165 +{
166 +       struct mmal_msg_context *msg_context = buf->msg_context;
167 +
168 +       if (msg_context)
169 +               release_msg_context(msg_context);
170 +       buf->msg_context = NULL;
171 +
172 +       mmal_vchi_buffer_unmap(buf);
173         return 0;
174  }
175  EXPORT_SYMBOL_GPL(mmal_vchi_buffer_cleanup);
176 --- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.h
177 +++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.h
178 @@ -167,6 +167,8 @@ int vchiq_mmal_submit_buffer(struct vchi
179                              struct vchiq_mmal_port *port,
180                              struct mmal_buffer *buf);
181  
182 +int mmal_vchi_buffer_unmap(struct mmal_buffer *buf);
183 +
184  int mmal_vchi_buffer_init(struct vchiq_mmal_instance *instance,
185                           struct mmal_buffer *buf);
186  int mmal_vchi_buffer_cleanup(struct mmal_buffer *buf);