d3d401e4620498e598097ae1fcaaf1aa1463fa5a
[mfp/fcdev.git] / packages / ti / sdo / fc / edmamgr / edmamgr.c
1 /*
2  * Copyright (c) 2013, Texas Instruments Incorporated
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 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 "AS IS"
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
33 #include <xdc/std.h>
34 #include <ti/xdais/ires.h>
36 #include <ti/sdo/fc/rman/rman.h>
38 #include "edmamgr.h"
39 #include "edmamgr_heap.h"
41 static IRES_ProtocolRevision _iresEDMA3ChanRevision =
42         IRES_EDMA3CHAN_PROTOCOLREVISION_2_0_0;
44 #define EDMA_MGR_MAX_NUM_CHANNELS     32
46 EdmaMgr_Channel EdmaMgr_channels[EDMA_MGR_MAX_NUM_CHANNELS];
48 extern __FAR__ int32_t *ti_sdo_fc_edmamgr_region2Instance;
49 extern __FAR__ EDMA3_GblConfigParams *ti_sdo_fc_edmamgr_edma3GblConfigParams;
50 extern __FAR__ EDMA3_InstanceInitConfig *ti_sdo_fc_edmamgr_edma3RegionConfig;
52 /*********************************************************************************
53  * FUNCTION PURPOSE: Init EdmaMgr resources
54  *********************************************************************************
55   DESCRIPTION:      This function initializes RMAN resouces
57   Parameters :      Inputs: proc_id          : core ID
58                             edma_config      : pointer to EDMA3 instance init
59                                                configuration
60                     Output: EdmaMgr_SUCCESS if initialization successful;
61                             Error code otherwise
62  *********************************************************************************/
63 int32_t EdmaMgr_init(int32_t proc_id, void *edma_config)
64 {
65     IRES_Status ires_status;
66     uint32_t edmaInstanceId;
67     int32_t i;
69     if (proc_id < 0 || proc_id >= EDMA3_MAX_REGIONS) {
70         return EdmaMgr_ERROR_INVARG;
71     }
73     if (ti_sdo_fc_edmamgr_region2Instance != NULL) {
74         edmaInstanceId = ti_sdo_fc_edmamgr_region2Instance[proc_id];
76         if (ti_sdo_fc_edmamgr_edma3GblConfigParams != NULL) {
77             EDMA3_PARAMS.globalConfig =
78                     (EDMA3_GblConfigParams *) &
79                     ti_sdo_fc_edmamgr_edma3GblConfigParams[edmaInstanceId];
80         }
81         else if (EDMA3_PARAMS.globalConfig == NULL) {
82             return EdmaMgr_ERROR_INVCFG;
83         }
85         if (edma_config != NULL) {
86             EDMA3_InstanceInitConfig *custom_config =
87                     (EDMA3_InstanceInitConfig *) edma_config;
89             EDMA3_PARAMS.regionConfig =
90                     (EDMA3_InstanceInitConfig *) &
91                     custom_config[EDMA3_MAX_REGIONS * edmaInstanceId + proc_id];
92         }
93         else if (ti_sdo_fc_edmamgr_edma3RegionConfig != NULL) {
94             EDMA3_PARAMS.regionConfig =
95                     (EDMA3_InstanceInitConfig *) &
96                     ti_sdo_fc_edmamgr_edma3RegionConfig[EDMA3_MAX_REGIONS *
97                     edmaInstanceId + proc_id];
98         }
99         else if (EDMA3_PARAMS.regionConfig == NULL) {
100             return EdmaMgr_ERROR_INVCFG;
101         }
102     }
103     else if (EDMA3_PARAMS.globalConfig || EDMA3_PARAMS.regionConfig == NULL) {
104         return EdmaMgr_ERROR_INVCFG;
105     }
107     EdmaMgr_heap_create();
109     RMAN_PARAMS.allocFxn = &EdmaMgr_heap_alloc;
110     RMAN_PARAMS.freeFxn = &EdmaMgr_heap_free;
111     EDMA3_PARAMS.allocFxn = &EdmaMgr_heap_alloc;
112     EDMA3_PARAMS.freeFxn = &EdmaMgr_heap_free;
113     ECPY_CFG_PARAMS.allocFxn = &EdmaMgr_heap_alloc;
114     ECPY_CFG_PARAMS.freeFxn = &EdmaMgr_heap_free;
116     /* specify EDMA instance ID */
117     ti_sdo_fc_edma3_EDMA3_physicalId = edmaInstanceId;
119     /* RMAN init */
120     ires_status = RMAN_init();
122     if (IRES_OK != ires_status) {
123         return EdmaMgr_ERROR_RMANINIT;
124     }
126     memset(EdmaMgr_channels, 0,
127             EDMA_MGR_MAX_NUM_CHANNELS * sizeof(EdmaMgr_Channel));
128     for (i = 0; i < EDMA_MGR_MAX_NUM_CHANNELS; i++) {
129         EdmaMgr_channels[i].edmaArgs.size = sizeof(IRES_EDMA3CHAN_ProtocolArgs);
130         EdmaMgr_channels[i].edmaArgs.mode = IRES_PERSISTENT;
131         EdmaMgr_channels[i].edmaArgs.numTccs = 1;
132         EdmaMgr_channels[i].edmaArgs.paRamIndex = IRES_EDMA3CHAN_PARAM_ANY;
133         EdmaMgr_channels[i].edmaArgs.tccIndex = IRES_EDMA3CHAN_TCC_ANY;
134         EdmaMgr_channels[i].edmaArgs.qdmaChan = IRES_EDMA3CHAN_CHAN_NONE;
135         EdmaMgr_channels[i].edmaArgs.edmaChan = IRES_EDMA3CHAN_EDMACHAN_ANY;
136         EdmaMgr_channels[i].edmaArgs.contiguousAllocation = TRUE;
137         EdmaMgr_channels[i].edmaArgs.shadowPaRamsAllocation = FALSE;
138         EdmaMgr_channels[i].edmaArgs.numPaRams = 0;
139     }
140     return EdmaMgr_SUCCESS;
143 /*********************************************************************************
144  * FUNCTION PURPOSE: Allocate EdmaMgr handle
145  *********************************************************************************
146   DESCRIPTION:      This function allocates an EDMA channel
148   Parameters :      Inputs: max_linked_transfer  : maximum number of linked
149                                                    transfers required for the
150                                                    channel.
152                     Output: Valid EdmaMgr handle on success;
153                             NULL handle if there is an error.
154  *********************************************************************************/
155 EdmaMgr_Handle EdmaMgr_alloc(int32_t max_linked_transfers)
157     IRES_ResourceDescriptor resDesc;
158     IRES_Status ires_status;
159     int32_t scratchId = -1;
160     int32_t i;
162     /* Find free channel */
163     for (i = 0; i < EDMA_MGR_MAX_NUM_CHANNELS; i++)
164         if (EdmaMgr_channels[i].edmaArgs.numPaRams == 0)
165             break;
167     if (i >= EDMA_MGR_MAX_NUM_CHANNELS)
168         return ((EdmaMgr_Handle)NULL);
170     EdmaMgr_channels[i].edmaArgs.numPaRams = max_linked_transfers;
172     /* Prepare IRES resource descriptor */
173     resDesc.resourceName = IRES_EDMA3CHAN_PROTOCOLNAME;
174     resDesc.revision = &_iresEDMA3ChanRevision;
175     resDesc.protocolArgs = (IRES_ProtocolArgs *)&(EdmaMgr_channels[i].edmaArgs);
176     resDesc.handle = (IRES_Handle)EdmaMgr_channels[i].edmaHandle;
178     /* Allocate EDMA Resources */
179     ires_status =
180             RMAN_allocateResources((Int)EdmaMgr_channels, &resDesc, 1,
181             scratchId);
182     if (ires_status != IRES_OK) {
183         EdmaMgr_channels[i].edmaArgs.numPaRams = 0;
184         return ((EdmaMgr_Handle)NULL);
185     }
186     EdmaMgr_channels[i].edmaHandle = (IRES_EDMA3CHAN_Handle) resDesc.handle;
188     /* Create ECPY handle */
189     EdmaMgr_channels[i].ecpyHandle =
190             ECPY_createHandle((IRES_EDMA3CHAN2_Handle)resDesc.handle,
191             (IALG_Handle)&EdmaMgr_channels[i]);
192     if (EdmaMgr_channels[i].ecpyHandle == NULL) {
193         RMAN_freeAllocatedResources((Int)EdmaMgr_channels, &resDesc, 1,
194                 scratchId);
195         EdmaMgr_channels[i].edmaHandle = NULL;
196         EdmaMgr_channels[i].edmaArgs.numPaRams = 0;
197         return ((EdmaMgr_Handle)NULL);
198     }
199     EdmaMgr_channels[i].xferPending = FALSE;
201     /* HW assign */
202     ECPY_activate(EdmaMgr_channels[i].ecpyHandle);
203     ECPY_setEarlyCompletionMode(EdmaMgr_channels[i].ecpyHandle, FALSE);
205     return ((EdmaMgr_Handle)&EdmaMgr_channels[i]);
208 /*********************************************************************************
209  * FUNCTION PURPOSE: Free EdmaMgr handle
210  *********************************************************************************
211   DESCRIPTION:      This function frees an EDMA channel
213   Parameters :      Inputs: h   : EdmaMgr handle
215                     Output: EdmaMgr_SUCCESS if free is successful;
216                             Error code otherwise.
217  *********************************************************************************/
218 int32_t EdmaMgr_free(EdmaMgr_Handle h)
220     EdmaMgr_Channel *chan = (EdmaMgr_Channel *)h;
221     IRES_ResourceDescriptor resDesc;
222     IRES_Status ires_status;
223     int32_t scratchId = -1;
224     int32_t i, ret_val = EdmaMgr_SUCCESS;
226     /* Verify that this is a valid handle? */
227     for (i = 0; i < EDMA_MGR_MAX_NUM_CHANNELS; i++)
228         if (chan == &EdmaMgr_channels[i])
229             break;
231     if (i >= EDMA_MGR_MAX_NUM_CHANNELS)
232         return EdmaMgr_ERROR_INVHANDLE;
234     /* Make sure all transfers have completed */
235     EdmaMgr_wait(h);
237     /* Prepare IRES resource descriptor */
238     resDesc.resourceName = IRES_EDMA3CHAN_PROTOCOLNAME;
239     resDesc.revision = &_iresEDMA3ChanRevision;
240     resDesc.protocolArgs = (IRES_ProtocolArgs *)&(chan->edmaArgs);
241     resDesc.handle = (IRES_Handle)chan->edmaHandle;
243     ECPY_deleteHandle(chan->ecpyHandle);
245     ires_status =
246             RMAN_freeAllocatedResources((Int)EdmaMgr_channels, &resDesc, 1,
247             scratchId);
248     if (ires_status != IRES_OK) {
249         ret_val = EdmaMgr_ERROR_FREE;
250     }
252     chan->ecpyHandle = NULL;
253     chan->edmaHandle = NULL;
254     chan->xferPending = FALSE;
256     chan->edmaArgs.numPaRams = 0;
258     return ret_val;