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 "camera_buffer_manager.h"
14 #include "camera_buffer.h"
15 #include "camera_device_manager.h"
16 #include "buffer_queue.h"
17 
18 #define HDF_LOG_TAG HDF_CAMERA_QUEUE
19 
BufferQueueStop(struct BufferQueue * queue)20 void BufferQueueStop(struct BufferQueue *queue)
21 {
22     uint32_t i;
23 
24     if (OsalAtomicRead(&queue->driverOwnCount) != 0) {
25         for (i = 0; i < queue->numBuffers; ++i) {
26             if (queue->buffers[i]->state == BUFFER_STATE_ACTIVE) {
27                 CameraBufferDone(queue->buffers[i], BUFFER_STATE_ERROR);
28             }
29         }
30         HDF_LOGI("%s: Expect zero, driverOwnCount = %{public}d", __func__, OsalAtomicRead(&queue->driverOwnCount));
31     }
32 
33     queue->flags &= ~QUEUE_STATE_STREAMING;
34     queue->flags &= ~QUEUE_STATE_STREAMING_CALLED;
35     queue->queuedCount = 0;
36     queue->flags &= ~QUEUE_STATE_ERROR;
37 
38     DListHeadInit(&queue->queuedList);
39     DListHeadInit(&queue->doneList);
40     OsalAtomicSet(&queue->driverOwnCount, 0);
41     wake_up_interruptible(&queue->doneWait);
42 
43     for (i = 0; i < queue->numBuffers; ++i) {
44         struct CameraBuffer *buffer = queue->buffers[i];
45         CameraBufferSyncForUser(buffer);
46         buffer->flags &= ~BUFFER_PREPARED;
47         buffer->state = BUFFER_STATE_DEQUEUED;
48     }
49 }
50 
BufferQueueCheckMmapOps(struct BufferQueue * queue)51 static int32_t BufferQueueCheckMmapOps(struct BufferQueue *queue)
52 {
53     if (((queue->ioModes & MEMTYPE_MMAP) == 0) || (queue->memOps->mmapAlloc == NULL) ||
54         (queue->memOps->mmapFree == NULL) || (queue->memOps->mmap == NULL)) {
55         return HDF_FAILURE;
56     }
57     return HDF_SUCCESS;
58 }
59 
BufferQueueCheckUserPtrOps(struct BufferQueue * queue)60 static int32_t BufferQueueCheckUserPtrOps(struct BufferQueue *queue)
61 {
62     if (((queue->ioModes & MEMTYPE_USERPTR) == 0) || (queue->memOps->allocUserPtr == NULL) ||
63         (queue->memOps->freeUserPtr == NULL)) {
64         return HDF_FAILURE;
65     }
66     return HDF_SUCCESS;
67 }
68 
BufferQueueCheckDmaBufOps(struct BufferQueue * queue)69 static int32_t BufferQueueCheckDmaBufOps(struct BufferQueue *queue)
70 {
71     if (((queue->ioModes & MEMTYPE_DMABUF) == 0) || (queue->memOps->attachDmaBuf == NULL) ||
72         (queue->memOps->detachDmaBuf == NULL) || (queue->memOps->mapDmaBuf == NULL) ||
73         (queue->memOps->unmapDmaBuf == NULL)) {
74         return HDF_FAILURE;
75     }
76     return HDF_SUCCESS;
77 }
78 
BufferQueueCheckMemOps(struct BufferQueue * queue,enum CameraMemType memType)79 int32_t BufferQueueCheckMemOps(struct BufferQueue *queue, enum CameraMemType memType)
80 {
81     if (memType != MEMTYPE_MMAP && memType != MEMTYPE_USERPTR && memType != MEMTYPE_DMABUF) {
82         HDF_LOGE("%s: memType is fault!", __func__);
83         return HDF_ERR_INVALID_PARAM;
84     }
85     if (memType == MEMTYPE_MMAP && BufferQueueCheckMmapOps(queue) != HDF_SUCCESS) {
86         HDF_LOGE("%s: MMAP for current setup unsupported!", __func__);
87         return HDF_ERR_NOT_SUPPORT;
88     }
89     if (memType == MEMTYPE_USERPTR && BufferQueueCheckUserPtrOps(queue) != HDF_SUCCESS) {
90         HDF_LOGE("%s: USERPTR for current setup unsupported!", __func__);
91         return HDF_ERR_NOT_SUPPORT;
92     }
93     if (memType == MEMTYPE_DMABUF && BufferQueueCheckDmaBufOps(queue) != HDF_SUCCESS) {
94         HDF_LOGE("%s: DMABUF for current setup unsupported!", __func__);
95         return HDF_ERR_NOT_SUPPORT;
96     }
97     return HDF_SUCCESS;
98 }
99 
BufferQueueFree(struct BufferQueue * queue,uint32_t count)100 static int32_t BufferQueueFree(struct BufferQueue *queue, uint32_t count)
101 {
102     uint32_t i;
103     struct CameraBuffer *buffer = NULL;
104 
105     if (queue->numBuffers < count) {
106         HDF_LOGE("%s: count out of range!", __func__);
107         return HDF_ERR_INVALID_PARAM;
108     }
109 
110     for (i = queue->numBuffers - count; i < queue->numBuffers; ++i) {
111         buffer = queue->buffers[i];
112         if (buffer == NULL) {
113             continue;
114         }
115         if (buffer->state == BUFFER_STATE_PREPARING) {
116             HDF_LOGE("%s: Can free buffer. Buffer is preparing!", __func__);
117             return HDF_FAILURE;
118         }
119         CameraBufferFree(buffer);
120         OsalMemFree(buffer);
121         queue->buffers[i] = NULL;
122     }
123 
124     queue->numBuffers -= count;
125     if (queue->numBuffers == 0) {
126         queue->memType = MEMTYPE_UNKNOWN;
127         DListHeadInit(&queue->queuedList);
128     }
129     return HDF_SUCCESS;
130 }
131 
BufferQueueReleaseBuffers(struct BufferQueue * queue,struct UserCameraReq * userRequest)132 int32_t BufferQueueReleaseBuffers(struct BufferQueue *queue, struct UserCameraReq *userRequest)
133 {
134     int32_t ret = 0;
135 
136     userRequest->capabilities = queue->ioModes;
137     if ((queue->flags & QUEUE_STATE_STREAMING) != 0) {
138         HDF_LOGE("%s: Queue is streaming", __func__);
139         return HDF_FAILURE;
140     }
141     if (((queue->flags & QUEUE_STATE_WAITING_DEQUEUE) != 0) && userRequest->count != 0) {
142         HDF_LOGE("%s: Queue is waiting dequeue", __func__);
143         return HDF_FAILURE;
144     }
145 
146     if (userRequest->count == 0 || queue->numBuffers != 0 ||
147         (queue->memType != MEMTYPE_UNKNOWN && queue->memType != userRequest->memType)) {
148         OsalMutexLock(&queue->mmapLock);
149         BufferQueueStop(queue);
150         ret = BufferQueueFree(queue, queue->numBuffers);
151         OsalMutexUnlock(&queue->mmapLock);
152     }
153     return ret;
154 }
155 
BufferQueueAllocBuffers(struct BufferQueue * queue,uint32_t memType,uint32_t numBuffers,uint32_t numPlanes,const uint32_t planeSizes[])156 static int32_t BufferQueueAllocBuffers(struct BufferQueue *queue, uint32_t memType,
157     uint32_t numBuffers, uint32_t numPlanes, const uint32_t planeSizes[])
158 {
159     uint32_t bufferId;
160     uint32_t planeId;
161     struct CameraBuffer *buffer = NULL;
162     int32_t ret;
163 
164     numBuffers = numBuffers < (MAX_FRAME - queue->numBuffers) ? numBuffers : (MAX_FRAME - queue->numBuffers);
165     for (bufferId = 0; bufferId < numBuffers; ++bufferId) {
166         buffer = OsalMemCalloc(queue->bufferSize);
167         if (buffer == NULL) {
168             HDF_LOGE("%s: Memory alloc failed", __func__);
169             break;
170         }
171         buffer->state = BUFFER_STATE_DEQUEUED;
172         buffer->bufferQueue = queue;
173         buffer->numPlanes = numPlanes;
174         buffer->id = queue->numBuffers + bufferId;
175         buffer->memType = memType;
176         if (queue->memType != MEMTYPE_DMABUF) {
177             buffer->flags |= BUFFER_NEED_USER_SYNC;
178             buffer->flags |= BUFFER_NEED_DEVICE_SYNC;
179         }
180         for (planeId = 0; planeId < numPlanes; ++planeId) {
181             buffer->planes[planeId].length = planeSizes[planeId];
182             buffer->planes[planeId].minLength = planeSizes[planeId];
183         }
184         queue->buffers[buffer->id] = buffer;
185         if (memType == MEMTYPE_MMAP) {
186             ret = CameraBufferAllocMmapPlanes(buffer);
187             if (ret != HDF_SUCCESS) {
188                 HDF_LOGE("%s: Mmap alloc failed", __func__);
189                 queue->buffers[buffer->id] = NULL;
190                 OsalMemFree(buffer);
191                 break;
192             }
193             CameraBufferSetupOffsets(buffer);
194         }
195     }
196     HDF_LOGI("%s: allocated %{public}d buffers and %{public}d planes", __func__, bufferId, planeId);
197 
198     return bufferId;
199 }
200 
BufferQueueRequestBuffers(struct BufferQueue * queue,struct UserCameraReq * userRequest,uint32_t numBuffers,uint32_t numPlanes,uint32_t planeSizes[])201 int32_t BufferQueueRequestBuffers(struct BufferQueue *queue, struct UserCameraReq *userRequest,
202     uint32_t numBuffers, uint32_t numPlanes, uint32_t planeSizes[])
203 {
204     int32_t ret;
205     uint32_t allocatedBuffers;
206 
207     allocatedBuffers = BufferQueueAllocBuffers(queue, userRequest->memType, numBuffers, numPlanes, planeSizes);
208     ret = allocatedBuffers < queue->minBuffersNeeded ? HDF_FAILURE : HDF_SUCCESS;
209     if (allocatedBuffers == 0) {
210         HDF_LOGE("%s: allocatedBuffers wrong", __func__);
211         return HDF_FAILURE;
212     }
213     if (ret == HDF_SUCCESS && allocatedBuffers < numBuffers) {
214         numBuffers = allocatedBuffers;
215         numPlanes = 0;
216         ret = queue->queueOps->queueSetup != NULL ? queue->queueOps->queueSetup(queue, &numBuffers,
217             &numPlanes, planeSizes) : HDF_SUCCESS;
218         if (ret == HDF_SUCCESS && allocatedBuffers < numBuffers) {
219             ret = HDF_FAILURE;
220         }
221     }
222 
223     OsalMutexLock(&queue->mmapLock);
224     queue->numBuffers = allocatedBuffers;
225     if (ret != HDF_SUCCESS) {
226         BufferQueueFree(queue, queue->numBuffers);
227         OsalMutexUnlock(&queue->mmapLock);
228         return ret;
229     }
230     OsalMutexUnlock(&queue->mmapLock);
231     userRequest->count = allocatedBuffers;
232     queue->flags |= QUEUE_STATE_WAITING_BUFFERS;
233     return HDF_SUCCESS;
234 }
235 
BufferQueueStart(struct BufferQueue * queue)236 int32_t BufferQueueStart(struct BufferQueue *queue)
237 {
238     struct CameraBuffer *buffer = NULL;
239     int32_t ret;
240 
241     struct BufferQueueImp *queueImp = container_of(queue, struct BufferQueueImp, queue);
242     struct StreamDevice *streamDev = container_of(queueImp, struct StreamDevice, queueImp);
243 
244     DLIST_FOR_EACH_ENTRY(buffer, &queue->queuedList, struct CameraBuffer, queueEntry) {
245         CameraBufferEnqueue(buffer);
246     }
247     queue->flags |= QUEUE_STATE_STREAMING_CALLED;
248     if (streamDev->streamOps->startStreaming == NULL) {
249         return HDF_FAILURE;
250     }
251 
252     ret = streamDev->streamOps->startStreaming(streamDev);
253     if (ret == HDF_SUCCESS) {
254         return ret;
255     }
256     queue->flags &= ~QUEUE_STATE_STREAMING_CALLED;
257 
258     if (OsalAtomicRead(&queue->driverOwnCount) != 0) {
259         for (uint32_t i = 0; i < queue->numBuffers; ++i) {
260             buffer = queue->buffers[i];
261             if (buffer->state == BUFFER_STATE_ACTIVE) {
262                 CameraBufferDone(buffer, BUFFER_STATE_QUEUED);
263             }
264         }
265         HDF_LOGW("%s: driver count must be zero: %{public}d", __func__, OsalAtomicRead(&queue->driverOwnCount));
266     }
267     if (!DListIsEmpty(&queue->doneList)) {
268         HDF_LOGW("%s: doneList is not empty", __func__);
269     }
270     return ret;
271 }
272 
BufferQueuePrepare(struct BufferQueue * queue,struct UserCameraBuffer * userBuffer)273 int32_t BufferQueuePrepare(struct BufferQueue *queue, struct UserCameraBuffer *userBuffer)
274 {
275     struct CameraBuffer *buffer = NULL;
276     int32_t ret;
277 
278     if (userBuffer->id >= queue->numBuffers) {
279         HDF_LOGE("%s: buffer index out of range", __func__);
280         return HDF_ERR_INVALID_PARAM;
281     }
282     if (queue->buffers[userBuffer->id] == NULL) {
283         HDF_LOGE("%s: buffer is NULL", __func__);
284         return HDF_FAILURE;
285     }
286     if (userBuffer->memType != queue->memType) {
287         HDF_LOGE("%s: invalid memory type: userBuffer memType = %{public}u, queue memType = %{public}u",
288             __func__, userBuffer->memType, queue->memType);
289         return HDF_FAILURE;
290     }
291 
292     buffer = queue->buffers[userBuffer->id];
293     ret = CameraBufferCheckPlanes(buffer, userBuffer);
294     if (ret != HDF_SUCCESS) {
295         return ret;
296     }
297     if (buffer->state != BUFFER_STATE_DEQUEUED) {
298         HDF_LOGE("%s: buffer is not in dequeued state", __func__);
299         return HDF_FAILURE;
300     }
301 
302     if ((buffer->flags & BUFFER_PREPARED) == 0) {
303         CameraBufferSetCacheSync(queue, buffer);
304         ret = CameraBufferCheckPlaneLength(buffer, userBuffer);
305         if (ret != HDF_SUCCESS) {
306             return ret;
307         }
308     }
309     return ret;
310 }
311