[PDK-5981]DSS and CAL: Fix Static Analysis Issues
[processor-sdk/pdk.git] / packages / ti / drv / cal / src / drv / cal_drvProc.c
1 /*
2  *  Copyright (c) Texas Instruments Incorporated 2018
3  *
4  *  Redistribution and use in source and binary forms, with or without
5  *  modification, are permitted provided that the following conditions
6  *  are met:
7  *
8  *    Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  *
11  *    Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the
14  *    distribution.
15  *
16  *    Neither the name of Texas Instruments Incorporated nor the names of
17  *    its contributors may be used to endorse or promote products derived
18  *    from this software without specific prior written permission.
19  *
20  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23  *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24  *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25  *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26  *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
33 /**
34  *  \file cal_drvProc.c
35  *
36  *  \brief File containing the CAL capture driver process related functions.
37  *
38  */
40 /* ========================================================================== */
41 /*                             Include Files                                  */
42 /* ========================================================================== */
44 #include <ti/drv/cal/src/drv/cal_drvPriv.h>
46 /* ========================================================================== */
47 /*                           Macros & Typedefs                                */
48 /* ========================================================================== */
50 /* None */
52 /* ========================================================================== */
53 /*                         Structure Declarations                             */
54 /* ========================================================================== */
56 /* None */
58 /* ========================================================================== */
59 /*                          Function Declarations                             */
60 /* ========================================================================== */
62 /* None */
64 /* ========================================================================== */
65 /*                            Global Variables                                */
66 /* ========================================================================== */
68 /* None */
70 /* ========================================================================== */
71 /*                          Function Definitions                              */
72 /* ========================================================================== */
74 /**
75  *  \brief Extern function to be implemented by driver to provide a new frame
76  *  buffers from application to the core.
77  */
78 Cal_CoreFrame *calDrvCaptCoreReqFrameCb(void  *drvData,
79                                         uint32_t streamId,
80                                         uint32_t chId)
81 {
82     uintptr_t cookie;
83     CalDrv_CaptChObj   *chObj;
84     CalDrv_CaptInstObj *instObj;
85     CalDrv_CaptQueObj  *qObj;
86     Cal_CoreFrame      *coreFrm = NULL;
88     instObj = (CalDrv_CaptInstObj *) drvData;
89     GT_assert(CalTrace, (NULL != instObj));
90     GT_assert(CalTrace, (streamId < CAL_CAPT_MAX_STREAMS));
91     GT_assert(CalTrace, (chId < instObj->createPrms.numCh));
93     /* Get channel specific object in the required instance */
94     chObj = &instObj->chObj[streamId][chId];
96     cookie = HwiP_disable();
98     qObj = (CalDrv_CaptQueObj *) Fvid2Utils_dequeue(chObj->bmObj.reqQ);
99     if(NULL != qObj)
100     {
101         /*
102          * Buffer available in request queue
103          */
104         /* Copy the address and increment credit */
105         qObj->coreFrm.addr[0] = qObj->frm->addr[0];
106         qObj->coreFrm.addr[1] = qObj->frm->addr[1];
107         qObj->coreFrm.addr[2] = qObj->frm->addr[2];
108         qObj->coreFrm.addr[3] = qObj->frm->addr[3];
109         qObj->coreFrm.addr[4] = qObj->frm->addr[4];
110         qObj->coreFrm.addr[5] = qObj->frm->addr[5];
111         qObj->coreFrm.rtParams   = qObj->frm->perFrameCfg;
112         qObj->coreFrm.dropFrm = (uint32_t) FALSE;
113         /* If app passes NULL pointer, then drop the frame */
114         if (0x0U == qObj->coreFrm.addr[0])
115         {
116             qObj->coreFrm.dropFrm = (uint32_t) TRUE;
117         }
119         qObj->creditCnt++;
120         coreFrm = &qObj->coreFrm;
121         Fvid2Utils_queue(chObj->bmObj.curQ, &qObj->qElem, qObj);
122         GT_1trace(CalTrace, GT_DEBUG,
123               "CaptDrv: Queued buffer 0x%0.8x to core\r\n", coreFrm->addr[0]);
124     }
125     else
126     {
127         /*
128          * No more buffers available in request queue - decide what to do
129          * based on buffer capture mode
130          */
131         if(CAL_CAPT_BCM_LAST_FRM_REPEAT == instObj->createPrms.bufCaptMode)
132         {
133             /* Repeat the last frame queued to the core */
134             qObj = (CalDrv_CaptQueObj *)
135                    Fvid2Utils_peakTail(chObj->bmObj.curQ);
136             /* This can't return NULL unless there is a bug in the buffer
137              * management */
138             GT_assert(CalTrace, (NULL != qObj));
139             qObj->creditCnt++;
140             coreFrm = &qObj->coreFrm;
141             GT_1trace(CalTrace, GT_DEBUG,
142               "CaptDrv: Queued buffer 0x%0.8x to core\r\n", coreFrm->addr[0]);
143         }
144         else if(CAL_CAPT_BCM_CIRCULAR_FRM_REPEAT ==
145                 instObj->createPrms.bufCaptMode)
146         {
147             /*
148              * Repeat the oldest frame queued to the core and make it at
149              * the last element in the current queue
150              */
151             qObj = (CalDrv_CaptQueObj *)
152                    Fvid2Utils_dequeue(chObj->bmObj.curQ);
153             /* This can't return NULL unless there is a bug in the buffer
154              * management */
155             GT_assert(CalTrace, (NULL != qObj));
156             qObj->creditCnt++;
157             coreFrm = &qObj->coreFrm;
159             /* Queue back to the start */
160             Fvid2Utils_queue(chObj->bmObj.curQ, &qObj->qElem, qObj);
161             GT_1trace(CalTrace, GT_DEBUG,
162               "CaptDrv: Queued buffer 0x%0.8x to core\r\n", coreFrm->addr[0]);
163         }
164         else
165         {
166             GT_assert(CalTrace, FALSE);
167         }
168     }
170     HwiP_restore(cookie);
172     GT_assert(CalTrace, (NULL != coreFrm));
173     return (coreFrm);
176 /**
177  *  \brief Extern callback function to be implemented by driver to free
178  *  up buffers to the application specified by the core.
179  */
180 int32_t calDrvCaptCoreFrameDoneCb(void *drvData, const Cal_CoreFrame *coreFrm)
182     uintptr_t cookie;
183     uint32_t curQCnt, reqQCnt;
184     uint64_t curTimeStamp;
185     Bool   frmQueuedToDoneQ = FALSE;
186     CalDrv_CaptChObj   *chObj;
187     CalDrv_CaptInstObj *instObj;
188     CalDrv_CaptQueObj  *qObj, *qObjTemp;
189     Cal_CaptRtParams   *rtPrms;
190     uint32_t              isWrDescValid;
192     instObj = (CalDrv_CaptInstObj *) drvData;
193     GT_assert(CalTrace, (NULL != instObj));
194     GT_assert(CalTrace, (NULL != coreFrm));
195     GT_assert(CalTrace, (coreFrm->streamId < CAL_CAPT_MAX_STREAMS));
196     GT_assert(CalTrace, (coreFrm->chId < instObj->createPrms.numCh));
197     GT_assert(CalTrace, (coreFrm->fid < FVID2_MAX_FIELDS));
199     /* Get channel specific object in the required instance */
200     chObj = &instObj->chObj[coreFrm->streamId][coreFrm->chId];
202     cookie = HwiP_disable();
204     GT_assert(CalTrace, (NULL != instObj->getTimeStamp));
205     curTimeStamp = instObj->getTimeStamp(NULL);
206     GT_1trace(CalTrace, GT_DEBUG,
207               "CaptDrv: Buffer 0x%0.8x capture done\r\n", coreFrm->addr[0]);
209     /* Update channel statistics */
210     chObj->stat.captFrmCount++;
211     chObj->stat.fldCount[coreFrm->fid]++;
212     if((chObj->bmObj.isProgressive == FALSE) &&
213        (chObj->stat.lastFid == coreFrm->fid))
214     {
215         chObj->stat.fidRepeatCount++;
216     }
217     chObj->stat.lastFid = coreFrm->fid;
218     chObj->stat.lastFrmTimeStamp = (uint32_t) (curTimeStamp / 1000U);
219     isWrDescValid = (uint32_t) TRUE;
220     if ((uint32_t) TRUE == isWrDescValid)
221     {
222         if(coreFrm->width > chObj->stat.maxRecvFrmWidth)
223         {
224             chObj->stat.maxRecvFrmWidth = coreFrm->width;
225         }
226         if(coreFrm->height > chObj->stat.maxRecvFrmHeight)
227         {
228             chObj->stat.maxRecvFrmHeight = coreFrm->height;
229         }
230         /* Init min values for the first frame capture */
231         if(chObj->stat.captFrmCount == 1U)
232         {
233             chObj->stat.minRecvFrmWidth  = coreFrm->width;
234             chObj->stat.minRecvFrmHeight = coreFrm->height;
235         }
236         else
237         {
238             if(coreFrm->width < chObj->stat.minRecvFrmWidth)
239             {
240                 chObj->stat.minRecvFrmWidth = coreFrm->width;
241             }
242             if(coreFrm->height < chObj->stat.minRecvFrmHeight)
243             {
244                 chObj->stat.minRecvFrmHeight = coreFrm->height;
245             }
246         }
247         chObj->stat.lastFrmWidth     = coreFrm->width;
248         chObj->stat.lastFrmHeight    = coreFrm->height;
249     }
251     /* Get reference of the queue head */
252     qObj = (CalDrv_CaptQueObj *) coreFrm->drvData;
253     GT_assert(CalTrace, (NULL != qObj));
255     /* Decrement credit count as frame capture is complete - credit can't
256      * be zero */
257     GT_assert(CalTrace, (qObj->creditCnt > 0U));
258     qObj->creditCnt--;
259     if(qObj->creditCnt > 0U)
260     {
261         chObj->stat.repeatFrmCount++;
262     }
264     GT_assert(CalTrace, (NULL != qObj->frm));
265     qObj->frm->status = coreFrm->status;
267     if(CAL_CAPT_BCM_LAST_FRM_REPEAT == instObj->createPrms.bufCaptMode)
268     {
269         /* Get the current queue counts */
270         curQCnt = Fvid2Utils_getNumQElem(chObj->bmObj.curQ);
271         reqQCnt = Fvid2Utils_getNumQElem(chObj->bmObj.reqQ);
273         if(0U == qObj->creditCnt)
274         {
275             qObjTemp = (CalDrv_CaptQueObj *)
276                        Fvid2Utils_dequeue(chObj->bmObj.curQ);
277             /* Head node and core frame should match */
278             GT_assert(CalTrace, (qObj == qObjTemp));
280             /* In last frame repeat mode, we could return all the frames to
281              * the application if credit becomes 0 and there are some more
282              * request in the current or request queue. Current queue is
283              * checked for 1 element as the current frame is still present
284              * in the queue. */
285             if((curQCnt > 1U) || (reqQCnt > 0U))
286             {
287                 GT_1trace(CalTrace, GT_DEBUG,
288                           "CaptDrv: Dequeued buffer 0x%0.8x\r\n",
289                           coreFrm->addr[0]);
291                 qObj->coreFrm.addr[0] = 0x0U;
292                 qObj->coreFrm.addr[1] = 0x0U;
293                 qObj->coreFrm.addr[2] = 0x0U;
294                 qObj->coreFrm.dropFrm    = (uint32_t) FALSE;
296                 /* Updated runtime parameters */
297                 GT_assert(CalTrace, (NULL != qObj->frm));
298                 qObj->frm->fid = qObj->coreFrm.fid;
299                 if(NULL != qObj->frm->perFrameCfg)
300                 {
301                     rtPrms = (Cal_CaptRtParams *) qObj->frm->perFrameCfg;
302                     rtPrms->capturedOutWidth  = qObj->coreFrm.width;
303                     rtPrms->capturedOutHeight = qObj->coreFrm.height;
304                 }
306                 /* Return the frame to done queue */
307                 GT_assert(CalTrace, (NULL != qObj->frm));
308                 qObj->frm->timeStamp64 = curTimeStamp;
309                 Fvid2Utils_queue(
310                     instObj->doneQ[coreFrm->streamId],
311                     &qObj->qElem,
312                     qObj);
313                 frmQueuedToDoneQ = (Bool) TRUE;
314             }
315             /* In last frame repeat mode, if credit becomes 0 and there are
316              * no more request in the current and request queues, take this
317              * request and queue it back to request queue so that when
318              * the core asks for next buffer, we repeat the frame
319              * automatically. This is needed because the user could
320              * queue a request in between and this frame will end-up
321              * in the current queue!!
322              * Also increment the repeat frame counter here. */
323             else if((curQCnt == 1U) && (reqQCnt == 0U))
324             {
325                 chObj->stat.repeatFrmCount++;
326                 Fvid2Utils_queue(chObj->bmObj.reqQ, &qObj->qElem, qObj);
327             }
328             else
329             {
330                 /* This can't happen as curQCnt can't be zero!! */
331                 GT_assert(CalTrace, FALSE);
332             }
333         }
334     }
335     else if(CAL_CAPT_BCM_CIRCULAR_FRM_REPEAT ==
336             instObj->createPrms.bufCaptMode)
337     {
338         /* Do nothing, just increment repeat count */
339         if(0U == qObj->creditCnt)
340         {
341             chObj->stat.repeatFrmCount++;
342         }
343     }
344     else
345     {
346         GT_assert(CalTrace, FALSE);
347     }
349     HwiP_restore(cookie);
351     if(NULL != instObj->fdmCbPrms.fdmCbFxn)
352     {
353         /* Give callback to application if frame is put in done queue */
354         /* TODO - handle multi-channel case!! */
355         if((Bool) TRUE == frmQueuedToDoneQ)
356         {
357             instObj->fdmCbPrms.fdmCbFxn(instObj->fdmCbPrms.fdmData);
358         }
359     }
361     return (FVID2_SOK);