source: svn/trunk/newcon3bcm2_21bu/magnum/portinginterface/ape/7552/bape_resources.c

Last change on this file was 2, checked in by jglee, 11 years ago

first commit

  • Property svn:executable set to *
File size: 14.2 KB
Line 
1/***************************************************************************
2 *     Copyright (c) 2006-2011, Broadcom Corporation
3 *     All Rights Reserved
4 *     Confidential Property of Broadcom Corporation
5 *
6 *  THIS SOFTWARE MAY ONLY BE USED SUBJECT TO AN EXECUTED SOFTWARE LICENSE
7 *  AGREEMENT  BETWEEN THE USER AND BROADCOM.  YOU HAVE NO RIGHT TO USE OR
8 *  EXPLOIT THIS MATERIAL EXCEPT SUBJECT TO THE TERMS OF SUCH AN AGREEMENT.
9 *
10 * $brcm_Workfile: bape_resources.c $
11 * $brcm_Revision: Hydra_Software_Devel/10 $
12 * $brcm_Date: 11/14/11 3:41p $
13 *
14 * Module Description: Audio Decoder Interface
15 *
16 * Revision History:
17 *
18 * $brcm_Log: /magnum/portinginterface/ape/7422/bape_resources.c $
19 *
20 * Hydra_Software_Devel/10   11/14/11 3:41p gskerl
21 * SW7429-18: Merging 7429 changes back to main branch.
22 *
23 * Hydra_Software_Devel/SW7429-18/1   10/21/11 6:29p jgarrett
24 * SW7429-18: Initial compileable version for 7429
25 *
26 * Hydra_Software_Devel/9   9/19/11 3:24p gskerl
27 * SW7231-129: Renamed BAPE_P_GarbageCollect() to
28 * BAPE_P_ReleaseUnusedPathResources() and made it a non-static function.
29 *
30 * Hydra_Software_Devel/8   4/16/11 12:16p jgarrett
31 * SW7425-371: Removing tab characters
32 *
33 * Hydra_Software_Devel/7   4/14/11 6:18p jgarrett
34 * SW7231-125: Adding debug for buffer allocation
35 *
36 * Hydra_Software_Devel/6   4/6/11 1:23a jgarrett
37 * SW35330-35: Merge to main branch
38 *
39 * Hydra_Software_Devel/SW35330-35/2   4/5/11 7:13p jgarrett
40 * SW35330-35: PCM Playback working on 35230
41 *
42 * Hydra_Software_Devel/SW35330-35/1   4/5/11 12:50p jgarrett
43 * SW35330-35: FMM Abstraction refactoring to support DTV
44 *
45 * Hydra_Software_Devel/5   3/11/11 6:02p jgarrett
46 * SW7422-146: Decoder supports external inputs
47 *
48 * Hydra_Software_Devel/4   3/4/11 10:37a jgarrett
49 * SW7422-146: Fixing crash on start/stop/start
50 *
51 * Hydra_Software_Devel/3   2/28/11 1:28p jgarrett
52 * SW7422-146: Filter graph reworked to remove mixer dependencies
53 *
54 * Hydra_Software_Devel/2   2/22/11 5:43p jgarrett
55 * SW7422-146: Implemented type renaming based on filter graph review
56 * comments
57 *
58 * Hydra_Software_Devel/1   12/16/10 4:05p jgarrett
59 * SW7422-146: Initial compilable APE for 7422
60 *
61 ***************************************************************************/
62
63#include "bstd.h"
64#include "bkni.h"
65#include "bape.h"
66#include "bape_priv.h"
67#include "bchp_aud_fmm_dp_ctrl0.h"
68#include "bchp_aud_fmm_src_ctrl0.h"
69#include "bchp_aud_fmm_bf_ctrl.h"
70
71BDBG_MODULE(bape_resources);
72
73/***************************************************************************
74  The resource pools are managed in a simple manner to permit grouping and
75  attempt to avoid fragmentation of resources.  For any given resource,
76  if only one channel pair is required (not grouped), resources are allocated
77  from the bottom of the pool (0..n).  For grouped resources, they are
78  allocated from the top of the pool (n..0). 
79***************************************************************************/
80
81void BAPE_P_ReleaseUnusedPathResources(BAPE_Handle handle)
82{
83    unsigned i;
84
85#if BAPE_CHIP_MAX_DECODERS > 0
86    for ( i = 0; i < BAPE_CHIP_MAX_DECODERS; i++ )
87    {
88        if ( NULL != handle->decoders[i] )
89        {
90            BAPE_PathNode_P_ReleasePathResources(&handle->decoders[i]->node);
91        }
92    }
93#endif
94#if BAPE_CHIP_MAX_INPUT_CAPTURES > 0
95    for ( i = 0; i < BAPE_CHIP_MAX_INPUT_CAPTURES; i++ )
96    {
97        if ( NULL != handle->inputCaptures[i] )
98        {
99            BAPE_PathNode_P_ReleasePathResources(&handle->inputCaptures[i]->node);
100        }
101    }
102#endif
103#if BAPE_CHIP_MAX_PLAYBACKS > 0
104    for ( i = 0; i < BAPE_CHIP_MAX_PLAYBACKS; i++ )
105    {
106        if ( NULL != handle->playbacks[i] )
107        {
108            BAPE_PathNode_P_ReleasePathResources(&handle->playbacks[i]->node);
109        }
110    }
111#endif
112}
113
114BERR_Code BAPE_P_AllocateInputBuffers(BAPE_Handle handle, BAPE_Connector input)
115{
116    unsigned i;
117    bool needToAllocate=false;
118
119    BDBG_OBJECT_ASSERT(handle, BAPE_Device);
120    BDBG_OBJECT_ASSERT(input, BAPE_PathConnector);
121    BDBG_ASSERT(input->useBufferPool);
122
123    /* Make sure we actually need buffers.  This may be called multiple times. */
124    for ( i = 0; i < BAPE_ChannelPair_eMax; i++ )
125    {
126        if ( (i < input->numChannelPairs && NULL == input->pBuffers[i]) ||
127             (i >= input->numChannelPairs && NULL != input->pBuffers[i]) )
128        {
129            needToAllocate=true;
130            BDBG_MSG(("Need to allocate buffers for %s %s", input->pParent->pName, input->pName));
131            BAPE_P_FreeInputBuffers(handle, input);
132            break;
133        }
134    }
135
136    /* Buffers are already sufficient */
137    if ( false == needToAllocate )
138    {
139        BDBG_MSG(("Do not need to allocate buffers for %s %s", input->pParent->pName, input->pName));
140        return BERR_SUCCESS;
141    }
142
143    for ( i = 0; i < input->numChannelPairs; i++ )
144    {
145        BAPE_BufferType type;
146        BDBG_ASSERT(NULL == input->pBuffers[i]);
147        type = input->compressed?BAPE_BufferType_eCompressed:BAPE_BufferType_ePcm;
148       
149        BDBG_MSG(("Allocate buffer %u for %s %s", i, input->pParent->pName, input->pName));
150        input->pBuffers[i] = BAPE_P_AllocateBuffer(handle, type);
151        if ( NULL == input->pBuffers[i] )
152        {
153            return BERR_TRACE(BERR_OUT_OF_DEVICE_MEMORY);
154        }
155    }
156
157    return BERR_SUCCESS;
158}
159
160void BAPE_P_FreeInputBuffers(BAPE_Handle handle, BAPE_Connector input)
161{
162    unsigned i;
163
164    BDBG_OBJECT_ASSERT(handle, BAPE_Device);
165    BDBG_OBJECT_ASSERT(input, BAPE_PathConnector);
166    BDBG_ASSERT(input->useBufferPool);
167
168    BDBG_MSG(("Free buffers forr %s %s", input->pParent->pName, input->pName));
169    for ( i = 0; i < input->numChannelPairs; i++ )
170    {
171        if ( NULL != input->pBuffers[i] )
172        {
173            BDBG_MSG(("Free buffer %u for %s %s", i, input->pParent->pName, input->pName));
174            BAPE_P_FreeBuffer(handle, input->pBuffers[i]);
175            input->pBuffers[i] = NULL;
176        }
177    }
178}
179
180/***************************************************************************
181Summary:
182Allocate buffers from the resource pool
183***************************************************************************/
184BAPE_BufferNode *BAPE_P_AllocateBuffer(
185    BAPE_Handle handle,
186    BAPE_BufferType type
187    )
188{
189    BAPE_BufferNode *pNode;
190    BDBG_OBJECT_ASSERT(handle, BAPE_Device);
191
192    switch ( type )
193    {
194    case BAPE_BufferType_ePcm:
195        pNode = BLST_S_FIRST(&handle->pcmBufferList);
196        if ( pNode )
197        {
198            BLST_S_REMOVE_HEAD(&handle->pcmBufferList, node);
199        }
200        else
201        {
202            BDBG_ERR(("Insufficient PCM buffers available.  Please add additional buffers in BAPE_Settings."));
203        }
204        break;
205    case BAPE_BufferType_eCompressed:
206        pNode = BLST_S_FIRST(&handle->compressedBufferList);
207        if ( pNode )
208        {
209            BLST_S_REMOVE_HEAD(&handle->compressedBufferList, node);
210        }
211        else
212        {
213            BDBG_ERR(("Insufficient compressed buffers available.  Please add additional buffers in BAPE_Settings."));
214        }
215        break;
216    default:
217        BDBG_ASSERT(type == BAPE_BufferType_eCompressed ||  type == BAPE_BufferType_ePcm);
218        pNode = NULL;
219        break;
220    }
221
222    return pNode;
223}
224
225/***************************************************************************
226Summary:
227Release buffers to the resource pool
228***************************************************************************/
229void BAPE_P_FreeBuffer(
230    BAPE_Handle handle,
231    BAPE_BufferNode *pNode
232    )
233{
234    BDBG_OBJECT_ASSERT(handle, BAPE_Device);
235    BDBG_OBJECT_ASSERT(pNode, BAPE_BufferNode);
236    switch ( pNode->type )
237    {
238    case BAPE_BufferType_eCompressed:
239        BLST_S_INSERT_HEAD(&handle->compressedBufferList, pNode, node);
240        break;
241    case BAPE_BufferType_ePcm:
242        BLST_S_INSERT_HEAD(&handle->pcmBufferList, pNode, node);
243        break;
244    default:
245        BDBG_ASSERT(pNode->type == BAPE_BufferType_eCompressed || pNode->type == BAPE_BufferType_ePcm);
246        return;
247    }
248}
249
250static BERR_Code BAPE_P_AllocateResourceGroup(BAPE_Handle handle, bool *pResourceArray, unsigned arraySize, unsigned numRequired, unsigned *pFirstResource)
251{
252    unsigned i, j, attempt;
253
254    BDBG_OBJECT_ASSERT(handle, BAPE_Device);
255    BDBG_ASSERT(NULL != pResourceArray);
256    BDBG_ASSERT(arraySize > 0);
257    BDBG_ASSERT(numRequired > 0);
258    BDBG_ASSERT(NULL != pFirstResource);
259
260    /* Try twice to acquire resources and garbage collect in between if resources are unavailable */
261    for ( attempt=0; attempt<2; attempt++ )
262    {
263        /* Allocate grouped resources from the bottom of the pool and un-grouped resources from the top */
264        if ( numRequired > 1 )
265        {
266            /* Grouped */
267            for ( i = arraySize-1; i >= numRequired; i-- )
268            {
269                bool success = true;
270                for ( j = 0; j < numRequired; j++ )
271                {
272                    if ( pResourceArray[i-j] )
273                    {
274                        success = false;
275                        break;
276                    }
277                }
278                if ( !success )
279                {
280                    /* Not enough consecutive resources */
281                    continue;
282                }
283                /* mark them as used */
284                for ( j = 0; j < numRequired; j++ )
285                {
286                    pResourceArray[i-j] = true;
287                }
288                *pFirstResource = i - (numRequired-1);
289                return BERR_SUCCESS;
290            }
291        }
292        else
293        {
294            /* Ungrouped */
295            for ( i = 0; i < arraySize; i++ )
296            {
297                if ( !pResourceArray[i] )
298                {
299                    /* We found an available resource.  Mark it as used. */
300                    pResourceArray[i] = true;
301                    *pFirstResource = i;
302                    return BERR_SUCCESS;
303                }
304            }
305        }
306
307        /* If we reached here, the attempt failed.  Try to garbage collect. */
308        BAPE_P_ReleaseUnusedPathResources(handle);
309    }
310
311    return BERR_TRACE(BERR_NOT_SUPPORTED);
312}
313
314static BERR_Code BAPE_P_GetFmmResourceArray(BAPE_Handle handle, BAPE_FmmResourceType resourceType, bool **ppArray, unsigned *pSize)
315{
316    bool *pResourceArray;
317    unsigned arraySize;
318    BERR_Code errCode = BERR_SUCCESS;
319
320    BDBG_OBJECT_ASSERT(handle, BAPE_Device);
321    BDBG_ASSERT(NULL != ppArray);
322    BDBG_ASSERT(NULL != pSize);
323
324    switch ( resourceType )
325    {
326    case BAPE_FmmResourceType_eSfifo:
327        pResourceArray = handle->sfifoAllocated;
328        arraySize = BAPE_CHIP_MAX_SFIFOS;
329        break;
330    case BAPE_FmmResourceType_eDfifo:
331        pResourceArray = handle->dfifoAllocated;
332        arraySize = BAPE_CHIP_MAX_DFIFOS;
333        break;
334    case BAPE_FmmResourceType_eSrc:
335        pResourceArray = handle->srcAllocated;
336        arraySize = BAPE_CHIP_MAX_SRCS;
337        break;
338    case BAPE_FmmResourceType_eMixer:
339        pResourceArray = handle->mixerAllocated;
340        arraySize = BAPE_CHIP_MAX_MIXERS;
341        break;
342    case BAPE_FmmResourceType_ePlayback:
343        pResourceArray = handle->playbackAllocated;
344        arraySize = BAPE_CHIP_MAX_MIXER_PLAYBACKS;
345        break;
346    case BAPE_FmmResourceType_eDummysink:
347        pResourceArray = handle->dummysinkAllocated;
348        arraySize = BAPE_CHIP_MAX_DUMMYSINKS;
349        break;
350    case BAPE_FmmResourceType_eLoopback:
351        pResourceArray = handle->loopbackAllocated;
352        arraySize = BAPE_CHIP_MAX_LOOPBACKS;
353        break; 
354#if BAPE_CHIP_MAX_FS > 0
355    case BAPE_FmmResourceType_eFs:
356        pResourceArray = handle->fsAllocated;
357        arraySize = BAPE_CHIP_MAX_FS;
358        break;
359#endif
360    case BAPE_FmmResourceType_eAdaptiveRate:
361        pResourceArray = handle->adaptRateAllocated;
362        arraySize = BAPE_CHIP_MAX_ADAPTRATE_CONTROLLERS;
363        break;
364    default:
365        BDBG_ERR(("Unrecognized resource type %u", resourceType));
366        errCode = BERR_TRACE(BERR_INVALID_PARAMETER);
367        pResourceArray = NULL;
368        arraySize = 0;
369        break;
370    }
371    *ppArray = pResourceArray;
372    *pSize = arraySize;
373    return errCode;
374}
375
376BERR_Code BAPE_P_AllocateFmmResource_tagged(BAPE_Handle handle, BAPE_FmmResourceType resourceType, unsigned numChannelPairs, unsigned *pFirstResource, const char *pFile, unsigned line)
377{
378    bool *pResourceArray=NULL;
379    unsigned arraySize=0;
380    BERR_Code errCode;
381
382    BDBG_MSG(("Allocate resource %s:%u type %u num %u", pFile, line, resourceType, numChannelPairs));
383
384    BDBG_OBJECT_ASSERT(handle, BAPE_Device);
385    BDBG_ASSERT(numChannelPairs > 0);
386    BDBG_ASSERT(NULL != pFirstResource);
387
388    /* TODO: Add resource tracking to determine current and max resource usage since BAPE_Open() */
389
390    errCode = BAPE_P_GetFmmResourceArray(handle, resourceType, &pResourceArray, &arraySize);
391    if ( errCode )
392    {
393        return BERR_TRACE(errCode);
394    }
395
396    errCode = BAPE_P_AllocateResourceGroup(handle, pResourceArray, arraySize, numChannelPairs, pFirstResource);
397    if ( errCode )
398    {
399        return BERR_TRACE(errCode);
400    }
401
402    return BERR_SUCCESS;
403}
404
405static void BAPE_P_FreeResourceGroup(BAPE_Handle handle, bool *pResourceArray, unsigned arraySize, unsigned numResources, unsigned firstResource)
406{
407    unsigned i;
408   
409    BDBG_OBJECT_ASSERT(handle, BAPE_Device);
410    BDBG_ASSERT(NULL != pResourceArray);
411    BDBG_ASSERT(arraySize > 0);
412    BDBG_ASSERT(numResources > 0);
413    BDBG_ASSERT((firstResource + numResources) <= arraySize);
414   
415    for ( i = 0; i < numResources; i++ )
416    {
417        /* Ensure the resource isn't being freed twice */
418        BDBG_ASSERT(pResourceArray[firstResource+i] == true);
419        pResourceArray[firstResource+i] = false;
420    }
421}
422
423void BAPE_P_FreeFmmResource(BAPE_Handle handle, BAPE_FmmResourceType resourceType, unsigned numChannelPairs, unsigned firstResource)
424{
425    bool *pResourceArray=NULL;
426    unsigned arraySize=0;
427    BERR_Code errCode;
428   
429    BDBG_OBJECT_ASSERT(handle, BAPE_Device);
430    BDBG_ASSERT(numChannelPairs > 0);
431   
432    /* TODO: Add resource tracking to determine current and max resource usage since BAPE_Open() */
433   
434    errCode = BAPE_P_GetFmmResourceArray(handle, resourceType, &pResourceArray, &arraySize);
435    if ( errCode )
436    {
437        (void)BERR_TRACE(errCode);
438        return;
439    }
440   
441    BAPE_P_FreeResourceGroup(handle, pResourceArray, arraySize, numChannelPairs, firstResource);
442}
443
Note: See TracBrowser for help on using the repository browser.