]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - processor-sdk/pdk.git/blob - packages/ti/drv/dss/src/drv/disp/dss_dispPriv.c
[DSS DRV][Bug Fix][PDK-5040]Display stops working if two pipelines are started back...
[processor-sdk/pdk.git] / packages / ti / drv / dss / src / drv / disp / dss_dispPriv.c
1 /*
2  *  Copyright (c) Texas Instruments Incorporated 2018
3  *  All rights reserved.
4  *
5  *  Redistribution and use in source and binary forms, with or without
6  *  modification, are permitted provided that the following conditions
7  *  are met:
8  *
9  *    Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  *
12  *    Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the
15  *    distribution.
16  *
17  *    Neither the name of Texas Instruments Incorporated nor the names of
18  *    its contributors may be used to endorse or promote products derived
19  *    from this software without specific prior written permission.
20  *
21  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
34 /**
35  *  \file dss_dispPriv.c
36  *
37  *  \brief File containing the DSS display driver private APIs.
38  *
39  */
41 /* ========================================================================== */
42 /*                             Include Files                                  */
43 /* ========================================================================== */
45 #include <ti/drv/dss/dss.h>
46 #include <ti/drv/dss/src/drv/common/dss_evtMgr.h>
47 #include <ti/drv/dss/src/drv/disp/dss_dispDrv.h>
48 #include <ti/drv/dss/src/drv/disp/dss_dispPriv.h>
50 /* ========================================================================== */
51 /*                           Macros & Typedefs                                */
52 /* ========================================================================== */
54 /* None */
56 /* ========================================================================== */
57 /*                         Structure Declarations                             */
58 /* ========================================================================== */
60 /* None */
62 /* ========================================================================== */
63 /*                          Function Declarations                             */
64 /* ========================================================================== */
66 static void Dss_dispErrCbFxn(const uint32_t *event,
67                              uint32_t numEvents,
68                              void *arg);
70 /* ========================================================================== */
71 /*                            Global Variables                                */
72 /* ========================================================================== */
74 Dss_DispDrvCommonObj gDss_DispDrvCommonObj;
75 Dss_DispDrvInstObj gDss_DispDrvInstObj[CSL_DSS_VID_PIPE_ID_MAX];
76 Dss_EvtMgrClientInfo gDss_DispEvtMgrClientInfo[DSS_DISP_EVT_MGR_MAX_CLIENTS];
78 /* ========================================================================== */
79 /*                          Function Definitions                              */
80 /* ========================================================================== */
82 int32_t Dss_dispDrvPrivInit(uint32_t numInst,
83                             const Dss_DispDrvInitParams *initParams)
84 {
85     int32_t  retVal = FVID2_SOK;
86     uint32_t instCnt;
87     uint32_t i, eventGroup, numHandle, numEvents, evtMgrId;
88     uint32_t enabledEvents[DSS_EVT_MGR_MAX_CLIENT_EVENTS];
89     Dss_DispDrvInstObj *instObj;
90     Dss_DispDrvCommonObj *pObj;
91     Dss_EvtMgrClientInfo *pClientInfo;
92     SemaphoreP_Params semParams;
94     /* Check for errors */
95     GT_assert(DssTrace, (numInst <= DSS_DISP_INST_MAX));
96     GT_assert(DssTrace, (NULL != initParams));
98     /* Initialize common object */
99     pObj = &gDss_DispDrvCommonObj;
100     Fvid2Utils_memset(pObj, 0U, sizeof (Dss_DispDrvCommonObj));
102     /* Initialize instance object members */
103     if(numInst > CSL_DSS_VID_PIPE_ID_MAX)
104     {
105         /* Number of instances exceeds the global variable used to store the
106          * instance object */
107         GT_0trace(DssTrace,
108                   GT_ERR,
109                   "Number of instances exceeds the global array size!!\r\n");
110         retVal = FVID2_EALLOC;
111     }
112     else
113     {
114         pObj->instObj = &gDss_DispDrvInstObj[0];
115         Fvid2Utils_memset(pObj->instObj, 0U, sizeof (gDss_DispDrvInstObj));
116         for(i=0U; i<DSS_DISP_EVT_MGR_MAX_CLIENTS; i++)
117         {
118             pClientInfo = &gDss_DispEvtMgrClientInfo[i];
119             Fvid2Utils_memset(pClientInfo, 0U, sizeof (Dss_EvtMgrClientInfo));
120         }
121     }
123     if(FVID2_SOK == retVal)
124     {
125         pObj->numInst = numInst;
126         instObj = pObj->instObj;
127         for(instCnt=0U; instCnt<numInst; instCnt++)
128         {
129             /* Copy the information */
130             instObj->drvInstId = initParams->drvInstId;
132             /* Allocate instance semaphore */
133             SemaphoreP_Params_init(&semParams);
134             semParams.mode = SemaphoreP_Mode_BINARY;
135             instObj->lockSem = SemaphoreP_create(1U, &semParams);
136             if(NULL == instObj->lockSem)
137             {
138                 GT_0trace(DssTrace,
139                           GT_ERR,
140                           "Instance semaphore create failed!!\r\n");
141                 retVal = FVID2_EALLOC;
142                 break;
143             }
145             if(FVID2_SOK == retVal)
146             {
147                 Dss_convModuletoEventGroup(&eventGroup,
148                                            instObj->drvInstId,
149                                            DSS_EVENT_GROUP_TYPE_PIPE);
150                 GT_assert(DssTrace, (DSS_EVENT_GROUP_INVALID != eventGroup));
152                 /* Register functional events */
153                 Dss_getEnabledPipeErrEvents(&enabledEvents[0U], &numEvents);
154                 evtMgrId = Dss_getEvtMgrFuncIntrId();
155                 numHandle = instObj->numRegEvtHandle;
156                 instObj->evtGroupHandle[instObj->numRegEvtHandle] =
157                             Dss_evtMgrRegister(
158                                 evtMgrId,
159                                 eventGroup,
160                                 (const uint32_t *)&enabledEvents[0U],
161                                 numEvents,
162                                 Dss_dispErrCbFxn,
163                                 (void *)&gDss_DispEvtMgrClientInfo[numHandle]);
164                 instObj->numRegEvtHandle++;
165             }
167             instObj->drvState.isInit     = TRUE;
168             instObj->drvState.isOpened   = FALSE;
169             instObj->drvState.isStarted  = FALSE;
170             instObj->drvState.isStarting = FALSE;
171             instObj->drvState.isStopping = FALSE;
173             initParams++;
174             instObj++;
175         }
176     }
178     if(FVID2_SOK != retVal)
179     {
180         /* Un initialize the internal objects if error occurs */
181         retVal += Dss_dispDrvPrivDeInit();
182     }
184     return (retVal);
187 int32_t Dss_dispDrvPrivDeInit(void)
189     int32_t retVal = FVID2_SOK;
190     uint32_t instCnt, cnt, numRegEvtHandle;
191     Dss_DispDrvInstObj *instObj;
192     Dss_DispDrvCommonObj *pObj;
194     pObj = &gDss_DispDrvCommonObj;
195     if(NULL != pObj->instObj)
196     {
197         instObj = pObj->instObj;
198         for(instCnt=0U; instCnt<pObj->numInst; instCnt++)
199         {
200             if(TRUE == instObj->drvState.isOpened)
201             {
202                 GT_0trace(DssTrace, GT_ERR,
203                           "Can't de-initialize when an instance is active\r\n");
204                 retVal = FVID2_EFAIL;
205                 break;
206             }
208             /* Delete the instance semaphore */
209             if(NULL != instObj->lockSem)
210             {
211                 SemaphoreP_delete(instObj->lockSem);
212                 instObj->lockSem = NULL;
213             }
215             instObj->drvState.isInit = FALSE;
216             numRegEvtHandle = instObj->numRegEvtHandle;
217             /* Unregister event groups and delete object */
218             for(cnt=0U; cnt<numRegEvtHandle; cnt++)
219             {
220                 retVal += Dss_evtMgrUnRegister(instObj->evtGroupHandle[cnt]);
221                 instObj->numRegEvtHandle--;
222             }
223             Fvid2Utils_memset(pObj->instObj, 0U, sizeof (Dss_DispDrvInstObj));
225             instObj++;
226         }
227         if(retVal == FVID2_SOK)
228         {
229             pObj->instObj = NULL;
230             pObj->numInst = 0U;
231         }
232     }
233     return (retVal);
236 Dss_DispDrvInstObj *Dss_dispDrvGetInstObj(uint32_t instId)
238     uint32_t instCnt;
239     Dss_DispDrvInstObj *instObj = NULL;
240     Dss_DispDrvCommonObj *pObj;
242     /* Find out the instance */
243     pObj = &gDss_DispDrvCommonObj;
244     GT_assert(DssTrace, (NULL != pObj));
245     GT_assert(DssTrace, (NULL != pObj->instObj));
246     for(instCnt=0U; instCnt<pObj->numInst; instCnt++)
247     {
248         if((TRUE == pObj->instObj[instCnt].drvState.isInit) &&
249            (pObj->instObj[instCnt].drvInstId == instId))
250         {
251             instObj = &pObj->instObj[instCnt];
252             break;
253         }
254     }
256     return (instObj);
259 int32_t Dss_dispDrvCreateInstObj(Dss_DispDrvInstObj *instObj)
261     int32_t  retVal = FVID2_SOK, tempRetVal;
262     uint32_t qCnt;
263     Dss_DispDrvBufManObj *bmObj;
264     Dss_DispDrvQueObj *qObj;
266     GT_assert(DssTrace, (NULL != instObj));
267     bmObj = &instObj->bmObj;
269     instObj->bufPrgmCbParams.bufPrgmCbFxn = NULL;
270     instObj->currStatus.queueCount = 0U;
271     instObj->currStatus.dequeueCount = 0U;
272     instObj->currStatus.dispFrmCount = 0U;
273     instObj->currStatus.repeatFrmCount = 0U;
274     instObj->currStatus.underflowCount = 0U;
275     instObj->currStatus.safetyViolationCount = 0U;
277     bmObj->isProgressive = TRUE;
278     bmObj->curFid = 0U;
279     bmObj->expectedFid = 0U;
280     bmObj->fieldMerged = TRUE;
281     bmObj->freeQ = NULL;
282     bmObj->reqQ = NULL;
283     bmObj->currQ = NULL;
284     bmObj->doneQ = NULL;
286     /* Create Queues */
287     retVal = Fvid2Utils_constructQ(&bmObj->freeLlObj);
288     GT_assert(DssTrace, (retVal == FVID2_SOK));
289     bmObj->freeQ = &bmObj->freeLlObj;
291     retVal = Fvid2Utils_constructQ(&bmObj->reqLlObj);
292     GT_assert(DssTrace, (retVal == FVID2_SOK));
293     bmObj->reqQ = &bmObj->reqLlObj;
295     retVal = Fvid2Utils_constructQ(&bmObj->curLlObj);
296     GT_assert(DssTrace, (retVal == FVID2_SOK));
297     bmObj->currQ = &bmObj->curLlObj;
299     retVal = Fvid2Utils_constructQ(&bmObj->doneLlObj);
300     GT_assert(DssTrace, (retVal == FVID2_SOK));
301     bmObj->doneQ = &bmObj->doneLlObj;
303     if(FVID2_SOK == retVal)
304     {
305         /* Initialize and queue the allocate queue object to free Q */
306         for(qCnt=0U; qCnt<DSS_DEF_QUEUE_LEN_PER_INST; qCnt++)
307         {
308             qObj = &bmObj->dispQObj[qCnt];
309             qObj->instObj = instObj;
310             qObj->frm = NULL;
311             qObj->creditCnt = 0U;
312             Fvid2Utils_queue(bmObj->freeQ, &qObj->qElem, qObj);
313         }
314     }
316     /* Deallocate if error occurs */
317     if(FVID2_SOK != retVal)
318     {
319         tempRetVal = Dss_dispDrvDeleteInstObj(instObj);
320         GT_assert(DssTrace, (FVID2_SOK == tempRetVal));
321     }
323     return (retVal);
326 int32_t Dss_dispDrvDeleteInstObj(Dss_DispDrvInstObj *instObj)
328     int32_t retVal = FVID2_SOK;
329     Dss_DispDrvQueObj *qObj;
330     Dss_DispDrvBufManObj *bmObj;
332     /* NULL pointer check */
333     GT_assert(DssTrace, (NULL != instObj));
334     bmObj = &instObj->bmObj;
336     bmObj->isProgressive = TRUE;
337     bmObj->curFid        = 0U;
338     bmObj->expectedFid   = 0U;
339     bmObj->fieldMerged   = TRUE;
341     if(NULL != bmObj->freeQ)
342     {
343         /* Free-up all the queued free queue objects */
344         do
345         {
346             qObj = (Dss_DispDrvQueObj *) Fvid2Utils_dequeue(bmObj->freeQ);
347         } while (NULL != qObj);
349         /* Delete the free Q */
350         Fvid2Utils_destructQ(bmObj->freeQ);
351         bmObj->freeQ = NULL;
352     }
354     if(NULL != bmObj->reqQ)
355     {
356         /* Free-up all object from request queue */
357         do
358         {
359             qObj = (Dss_DispDrvQueObj *) Fvid2Utils_dequeue(bmObj->reqQ);
360         } while (NULL != qObj);
362         /* Delete the request Q */
363         Fvid2Utils_destructQ(bmObj->reqQ);
364         bmObj->reqQ = NULL;
365     }
367     if(NULL != bmObj->currQ)
368     {
369         /* Free-up all object from current queue */
370         do
371         {
372             qObj = (Dss_DispDrvQueObj *) Fvid2Utils_dequeue(bmObj->currQ);
373         } while (NULL != qObj);
375         /* Delete the free Q */
376         Fvid2Utils_destructQ(bmObj->currQ);
377         bmObj->currQ = NULL;
378     }
380     if(NULL != bmObj->doneQ)
381     {
382         /* Free-up all object from done queue */
383         do
384         {
385             qObj = (Dss_DispDrvQueObj *) Fvid2Utils_dequeue(bmObj->doneQ);
386         } while (NULL != qObj);
388         /* Delete the done Q */
389         Fvid2Utils_destructQ(bmObj->doneQ);
390         bmObj->doneQ = NULL;
391     }
393     return (retVal);
396 static void Dss_dispErrCbFxn(const uint32_t *event,
397                              uint32_t numEvents,
398                              void *arg)
400     uint32_t  i, currEvent, pipeId = 0U;
401     Dss_EvtMgrClientInfo *pClientObj = (Dss_EvtMgrClientInfo *)arg;
402     uint32_t eventGroup = pClientObj->eventGroup;
403     Dss_DispDrvInstObj *instObj;
405     Dss_convEventGrouptoModule(eventGroup, &pipeId);
406     GT_assert(DssTrace, (CSL_DSS_MODULE_INVALID != pipeId));
407     instObj = &gDss_DispDrvInstObj[pipeId];
408     for(i=0U; i<numEvents; i++)
409     {
410         currEvent = event[i];
411         if(DSS_PIPE_EVENT_BUFF_UNDERFLOW == currEvent)
412         {
413            instObj->currStatus.underflowCount++;
414            if(NULL != instObj->underFlowCbParams.underFlowCbFxn)
415            {
416                instObj->underFlowCbParams.underFlowCbFxn(
417                                         instObj->underFlowCbParams.appData);
418            }
419         }
420         else
421         {
422             GT_assert(DssTrace, FALSE);
423         }
424     }
426     return;