1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 *
4 * HDF is dual licensed: you can use it either under the terms of
5 * the GPL, or the BSD license, at your option.
6 * See the LICENSE file in the root of this repository for complete details.
7 */
8
9 #include <securec.h>
10 #include <hdf_log.h>
11 #include <osal_mem.h>
12 #include "osal_uaccess.h"
13 #include "buffer_queue.h"
14 #include "camera_buffer_manager.h"
15
16 #define HDF_LOG_TAG HDF_CAMERA_BUFFER_MANAGER
17 struct BufferQueue *g_queueForMmap = NULL;
18
CameraBufferDone(struct CameraBuffer * buffer,enum BufferState state)19 void CameraBufferDone(struct CameraBuffer *buffer, enum BufferState state)
20 {
21 struct BufferQueue *queue = buffer->bufferQueue;
22 uint32_t flags;
23
24 if (buffer->state != BUFFER_STATE_ACTIVE) {
25 return;
26 }
27
28 if (state != BUFFER_STATE_DONE && state != BUFFER_STATE_ERROR && state != BUFFER_STATE_QUEUED) {
29 state = BUFFER_STATE_ERROR;
30 }
31 HDF_LOGI("%s: Done processing on buffer %{public}u!", __func__, buffer->id);
32
33 if (state != BUFFER_STATE_QUEUED) {
34 CameraBufferSyncForUser(buffer);
35 }
36 OsalSpinLockIrqSave(&queue->doneLock, &flags);
37 buffer->state = state;
38 if (state != BUFFER_STATE_QUEUED) {
39 DListInsertTail(&buffer->doneEntry, &queue->doneList);
40 }
41
42 OsalAtomicDec(&queue->driverOwnCount);
43 OsalSpinUnlockIrqRestore(&queue->doneLock, &flags);
44 if (state != BUFFER_STATE_QUEUED) {
45 wake_up(&queue->doneWait);
46 }
47 }
48
BufferQueueFindPlaneByOffset(struct BufferQueue * queue,unsigned long off,uint32_t * bufferId,uint32_t * planeId)49 int32_t BufferQueueFindPlaneByOffset(struct BufferQueue *queue,
50 unsigned long off, uint32_t *bufferId, uint32_t *planeId)
51 {
52 struct CameraBuffer *buffer = NULL;
53 uint32_t bufferCnt;
54 uint32_t planeCnt;
55
56 if (queue == NULL || bufferId == NULL || planeId == NULL) {
57 return HDF_ERR_INVALID_PARAM;
58 }
59
60 for (bufferCnt = 0; bufferCnt < queue->numBuffers; ++bufferCnt) {
61 buffer = queue->buffers[bufferCnt];
62 for (planeCnt = 0; planeCnt < buffer->numPlanes; ++planeCnt) {
63 if (buffer->planes[planeCnt].memory.offset == off) {
64 *bufferId = bufferCnt;
65 *planeId = planeCnt;
66 return HDF_SUCCESS;
67 }
68 }
69 }
70
71 return HDF_FAILURE;
72 }
73
CameraBufferGetPlaneVaddr(struct CameraBuffer * buffer,uint32_t planeId)74 void *CameraBufferGetPlaneVaddr(struct CameraBuffer *buffer, uint32_t planeId)
75 {
76 struct BufferQueue *queue = buffer->bufferQueue;
77 if (planeId >= buffer->numPlanes || buffer->planes[planeId].memPriv == NULL) {
78 return NULL;
79 }
80
81 if (queue->memOps->getVaddr != NULL) {
82 return queue->memOps->getVaddr(buffer->planes[planeId].memPriv);
83 }
84
85 return NULL;
86 }
87
88 /* init queue */
BufferQueueInit(struct BufferQueue * queue)89 int32_t BufferQueueInit(struct BufferQueue *queue)
90 {
91 if (queue == NULL) {
92 HDF_LOGE("%s: queue ptr is null", __func__);
93 return HDF_ERR_INVALID_PARAM;
94 }
95
96 if (queue->queueIsInit == true) {
97 return HDF_SUCCESS;
98 }
99
100 if (queue->queueOps == NULL || queue->memOps == NULL || queue->ioModes == 0) {
101 HDF_LOGE("%s: queueOps/memOps is null or ioModes is 0", __func__);
102 return HDF_FAILURE;
103 }
104
105 if (queue->queueOps->queueSetup == NULL || queue->queueOps->queueBuffer == NULL) {
106 HDF_LOGE("%s: queueSetup or queueBuffer is null", __func__);
107 return HDF_FAILURE;
108 }
109
110 if (queue->bufferSize == 0) {
111 queue->bufferSize = sizeof(struct CameraBuffer);
112 }
113 queue->memType = MEMTYPE_UNKNOWN;
114 DListHeadInit(&queue->queuedList);
115 DListHeadInit(&queue->doneList);
116 OsalSpinInit(&queue->doneLock);
117 OsalMutexInit(&queue->mmapLock);
118 init_waitqueue_head(&queue->doneWait);
119 MemoryAdapterQueueImpInit(queue);
120 queue->queueIsInit = true;
121
122 return HDF_SUCCESS;
123 }
124
125 /* request buffers */
BufferQueueRequest(struct BufferQueue * queue,struct UserCameraReq * userRequest)126 int32_t BufferQueueRequest(struct BufferQueue *queue, struct UserCameraReq *userRequest)
127 {
128 uint32_t numBuffers;
129 uint32_t numPlanes = 0;
130 uint32_t planeSizes[MAX_PLANES] = { 0 };
131 uint32_t i;
132 int32_t ret;
133
134 ret = BufferQueueCheckMemOps(queue, userRequest->memType);
135 if (ret != HDF_SUCCESS) {
136 HDF_LOGE("%s: BufferQueueCheckMemOps failed, ret = %{public}d", __func__, ret);
137 return HDF_FAILURE;
138 }
139 if (BufferQueueReleaseBuffers(queue, userRequest) != HDF_SUCCESS) {
140 return HDF_FAILURE;
141 }
142 if (userRequest->count == 0) {
143 return HDF_SUCCESS;
144 }
145 if (queue->minBuffersNeeded > MAX_FRAME) {
146 HDF_LOGW("%s: Buffer needed is too many", __func__);
147 }
148
149 numBuffers = userRequest->count > queue->minBuffersNeeded ? userRequest->count : queue->minBuffersNeeded;
150 numBuffers = numBuffers > MAX_FRAME ? MAX_FRAME : numBuffers;
151 queue->memType = userRequest->memType;
152 ret = queue->queueOps->queueSetup != NULL ? queue->queueOps->queueSetup(queue, &numBuffers,
153 &numPlanes, planeSizes) : HDF_SUCCESS;
154 if (ret != HDF_SUCCESS) {
155 HDF_LOGE("%s: queue setup failed", __func__);
156 return ret;
157 }
158 if (numPlanes == 0) {
159 HDF_LOGE("%s: numPlanes cannot be zero", __func__);
160 return HDF_FAILURE;
161 }
162 for (i = 0; i < numPlanes; ++i) {
163 if (planeSizes[i] == 0) {
164 return HDF_FAILURE;
165 }
166 }
167
168 ret = BufferQueueRequestBuffers(queue, userRequest, numBuffers, numPlanes, planeSizes);
169 if (ret != HDF_SUCCESS) {
170 return ret;
171 }
172
173 return HDF_SUCCESS;
174 }
175
176 /* query buffer */
BufferQueueQueryBuffer(struct BufferQueue * queue,struct UserCameraBuffer * userBuffer)177 int32_t BufferQueueQueryBuffer(struct BufferQueue *queue, struct UserCameraBuffer *userBuffer)
178 {
179 struct CameraBuffer *buffer = NULL;
180 int32_t ret;
181
182 if (userBuffer->id >= queue->numBuffers) {
183 HDF_LOGE("%s: user buffer id cannot >= queue numBuffers", __func__);
184 return HDF_FAILURE;
185 }
186
187 buffer = queue->buffers[userBuffer->id];
188 ret = CameraBufferCheckPlanes(buffer, userBuffer);
189 if (ret == HDF_SUCCESS) {
190 CameraBufferToUserBuffer(buffer, userBuffer);
191 }
192
193 return ret;
194 }
195
196 /* return buffer */
BufferQueueReturnBuffer(struct BufferQueue * queue,struct UserCameraBuffer * userBuffer)197 int32_t BufferQueueReturnBuffer(struct BufferQueue *queue, struct UserCameraBuffer *userBuffer)
198 {
199 if (userBuffer == NULL) {
200 return HDF_ERR_INVALID_PARAM;
201 }
202 struct CameraBuffer *buffer = NULL;
203 int32_t ret;
204 ret = BufferQueuePrepare(queue, userBuffer);
205 if (ret != HDF_SUCCESS) {
206 return ret;
207 }
208 if ((queue->flags & QUEUE_STATE_ERROR) != 0) {
209 HDF_LOGE("%s: fatal error occurred on queue", __func__);
210 return HDF_FAILURE;
211 }
212 buffer = queue->buffers[userBuffer->id];
213 if (buffer->state != BUFFER_STATE_DEQUEUED) {
214 HDF_LOGE("%s: invalid buffer state", __func__);
215 return HDF_FAILURE;
216 }
217 if ((buffer->flags & BUFFER_PREPARED) == 0) {
218 ret = CameraBufferFromUserBuffer(buffer, userBuffer);
219 if (ret != HDF_SUCCESS) {
220 HDF_LOGE("%s: Buffer prepare failed", __func__);
221 return ret;
222 }
223 }
224 CameraBufferQueueBuffer(buffer);
225 CameraBufferToUserBuffer(buffer, userBuffer);
226
227 if ((queue->flags & QUEUE_STATE_STREAMING) != 0 && (queue->flags & QUEUE_STATE_STREAMING_CALLED) == 0 &&
228 (queue->queuedCount >= queue->minBuffersNeeded)) {
229 ret = BufferQueueStart(queue);
230 if (ret != HDF_SUCCESS) {
231 HDF_LOGE("%s: BufferQueueStart failed", __func__);
232 return ret;
233 }
234 }
235 return HDF_SUCCESS;
236 }
237
WaitForDoneBuffer(struct BufferQueue * queue,uint32_t blocking)238 static int32_t WaitForDoneBuffer(struct BufferQueue *queue, uint32_t blocking)
239 {
240 while (true) {
241 if ((queue->flags & QUEUE_STATE_WAITING_DEQUEUE) != 0 || (queue->flags & QUEUE_STATE_STREAMING) == 0 ||
242 (queue->flags & QUEUE_STATE_ERROR) != 0 || (queue->flags & QUEUE_STATE_LAST_BUFFER_DEQUEUED) != 0) {
243 return HDF_FAILURE;
244 }
245
246 if (!DListIsEmpty(&queue->doneList)) {
247 break;
248 }
249
250 if (blocking == 0) {
251 return HDF_FAILURE;
252 }
253 queue->flags |= QUEUE_STATE_WAITING_DEQUEUE;
254
255 MemoryAdapterDriverMutexLock(queue);
256 int32_t ret = wait_event_interruptible(queue->doneWait, !DListIsEmpty(&queue->doneList) ||
257 (queue->flags & QUEUE_STATE_STREAMING) == 0 || (queue->flags & QUEUE_STATE_ERROR) != 0);
258 MemoryAdapterDriverMutexUnLock(queue);
259
260 queue->flags &= ~QUEUE_STATE_WAITING_DEQUEUE;
261 if (ret != 0) {
262 HDF_LOGE("%s: wait function failed", __func__);
263 return HDF_FAILURE;
264 }
265 }
266
267 return HDF_SUCCESS;
268 }
269
GetDoneBuffer(struct BufferQueue * queue,struct CameraBuffer ** buffer,struct UserCameraBuffer * userBuffer)270 static int32_t GetDoneBuffer(struct BufferQueue *queue,
271 struct CameraBuffer **buffer, struct UserCameraBuffer *userBuffer)
272 {
273 uint32_t flags;
274 int32_t ret;
275
276 ret = WaitForDoneBuffer(queue, userBuffer->flags & USER_BUFFER_BLOCKING);
277 if (ret == HDF_FAILURE) {
278 return ret;
279 }
280 OsalSpinLockIrqSave(&queue->doneLock, &flags);
281 *buffer = DLIST_FIRST_ENTRY(&queue->doneList, struct CameraBuffer, doneEntry);
282 ret = CameraBufferCheckPlanes(*buffer, userBuffer);
283 if (ret == HDF_SUCCESS) {
284 DListRemove(&(*buffer)->doneEntry);
285 }
286 OsalSpinUnlockIrqRestore(&queue->doneLock, &flags);
287
288 return ret;
289 }
290
291 /* acquire buffer */
BufferQueueAcquireBuffer(struct BufferQueue * queue,struct UserCameraBuffer * userBuffer)292 int32_t BufferQueueAcquireBuffer(struct BufferQueue *queue, struct UserCameraBuffer *userBuffer)
293 {
294 struct CameraBuffer *buffer = NULL;
295 int32_t ret;
296
297 if (userBuffer == NULL) {
298 return HDF_FAILURE;
299 }
300 ret = GetDoneBuffer(queue, &buffer, userBuffer);
301 if (ret != HDF_SUCCESS) {
302 HDF_LOGE("%s: get buffer from doneList failed", __func__);
303 return ret;
304 }
305 switch (buffer->state) {
306 case BUFFER_STATE_DONE:
307 HDF_LOGE("%s: return done buffer", __func__);
308 break;
309 case BUFFER_STATE_ERROR:
310 HDF_LOGE("%s: return done buffer with error", __func__);
311 break;
312 default:
313 HDF_LOGE("%s: invalid buffer state", __func__);
314 return HDF_FAILURE;
315 }
316 buffer->flags &= ~BUFFER_PREPARED;
317
318 CameraBufferToUserBuffer(buffer, userBuffer);
319 DListRemove(&buffer->queueEntry);
320 queue->queuedCount--;
321 buffer->state = BUFFER_STATE_DEQUEUED;
322 userBuffer->flags |= USER_BUFFER_DONE;
323
324 return ret;
325 }
326
327 /* stream on */
BufferQueueStreamOn(struct BufferQueue * queue)328 int32_t BufferQueueStreamOn(struct BufferQueue *queue)
329 {
330 if ((queue->flags & QUEUE_STATE_STREAMING) != 0 || (queue->numBuffers) == 0 ||
331 (queue->numBuffers < queue->minBuffersNeeded)) {
332 return HDF_FAILURE;
333 }
334
335 if (queue->queuedCount >= queue->minBuffersNeeded) {
336 int32_t ret = BufferQueueStart(queue);
337 if (ret != HDF_SUCCESS) {
338 HDF_LOGE("%s: BufferQueueStart failed", __func__);
339 return ret;
340 }
341 }
342 queue->flags |= QUEUE_STATE_STREAMING;
343 return HDF_SUCCESS;
344 }
345
346 /* stream off */
BufferQueueStreamOff(struct BufferQueue * queue)347 int32_t BufferQueueStreamOff(struct BufferQueue *queue)
348 {
349 BufferQueueStop(queue);
350
351 queue->flags |= QUEUE_STATE_WAITING_BUFFERS;
352 queue->flags &= ~QUEUE_STATE_LAST_BUFFER_DEQUEUED;
353 HDF_LOGD("%s: stream off success", __func__);
354
355 return HDF_SUCCESS;
356 }
357
BufferQueueSetQueueForMmap(struct BufferQueue * queue)358 void BufferQueueSetQueueForMmap(struct BufferQueue *queue)
359 {
360 g_queueForMmap = queue;
361 }
362
BufferQueueGetQueueForMmap(void)363 struct BufferQueue *BufferQueueGetQueueForMmap(void)
364 {
365 return g_queueForMmap;
366 }
367