KeyStone Resource Manager June 2012 What is resource manager? • LLD for global Resource management – static assignment of the device resources to DSP cores (also called RM LLD) – ARM cores assignment is different • Modules resource management - Individual modules (QMSS, CPPI, PA, EDMA) controls the usage of their resources with or without the resource management LLD • In this presentation we will cover both! resource management LLD RM LLD Module • Motivation – with the introduction of multiple core types KeyStone devices (DSP only, DSP + ARM, ARM only) there was a need to share resources between different device types – to minimize the modifications to the code for different platform. The RM module enables usage of the same code across different devices. Encapsulates the modification in the platform code and not the applications code • Implementation – hard partition of resources between DSP cores and ARM cores (also refer as host or kernel) and – soft run-time authorization APIs register with the LLD modules. (In Linux, there is device tree structure that encapsulates the available resources) • Example: loading the QMSS firmware can be part of the ARM code (for the ARM only device), the DSP code (for DSP only device). For the hybrid devices, the integrator decides who does the firmware, but in all cases, the same application is used. • Built as backward compatible to DSP only cores device (6678) What does RM LLD Module Do? • The RM LLD answers Two questions – Can I (the DSP core) configure the following resource? – Can I (the DSP core) use the following resource? • The permissions are statically defined during compilation time and loaded with all the constants • A single core “master” builds a table structure with permissions and distributes it to all cores “slave“ • ARM available resources are defined in the device tree Application and resource manager RM Initialize-Start Sequence • One (and only one) DSP core initializes RM • Remaining DSP cores start RM • Initialization and starting roles decided by application via the RM function invoked on the DSP core – Rm_init – Core initializes RM – Rm_start – Core starts RM • No RM control or data messages passed between initializing core and starting cores – All resource information communicated via permission tables located in MSMCSRAM or DDR • After DSP cores init and start all cores assume the same role – Handle permission requests from LLDs by checking shared permission tables Role of RM Initializing Core • Rm_init invoked by application – Pointer to device resource table permissions passed as argument – Must be invoked prior to any QMSS, CPPI, and PA functions • RM_init algorithm – Rm_init sets all resources to deny all initialization and usage accesses – Rm_init copies all permissions specified by the input resource table into the internal permission tables – The internal permission tables MUST be placed in shared memory – Rm_init sets the “permissions valid” flag in a global RM sync variable located in shared memory – Flag used by RM start cores – Register with LLDs using RM handle 8 Role of RM Starting Cores • Rm_start invoked by application prior to any QMSS, CPPI, and PA functions • Rm_start Algorithm – pends on global RM sync object waiting for RM server to complete update of internal permission tables – Pend is not blocking – Tasks can preempt and interrupts can be serviced – When global RM sync object has “permissions valid” written RM starting core will invalidate all internal permission tables and load new tables – Register with LLDs using RM handle • RM run time algorithm – Service permission requests 9 Rm_init () • Rm_Result Rm_init ( const Rm_Resource * rmResourceTable ) Initializes the Resource Manager low level driver. Describes what are the resources that are available. For example, 6678 does not have AIF resources Called only once in the system Parameters: [in] rmResourceTable Resource table defined by application. Post condition: RM LLD global permissions are set in the table Return values: Success - RM_OK Failure RM_ERROR_PERMISSION_TABLE_POPULATION_FAILED Rm_start () • Rm_Result Rm_start ( void ) • Description This function waits for the Resource Manager master to populate the global permissions table based on a global sync object. Once the global sync object has been written by the master core this function will invalidate all permissions tables. Since the permissions table are static, and will not change through the system up-time, a single invalidation at the start will suffice. • This function can be called on all core besides that which called Rm_init. Calling this function on said cores will act as a blocking synchronization point. • Return values: Success - RM_OK Failure - RM_FAILURE RM Initialization Sequence RM Initializing DSP Rm_init MSMCSRAM Internal Permission Tables Set all tracked resources to permission denied RM Sync Object RM Starting DSPs Poll RM Sync Object waiting for permissions to be populated by Server Rm_start Copy integrator defined resource table to internal permission tables Set RM Sync Object to “Permissions Populated” Server has completed permission population Invalidate entire permissions table. No further invalidates required. RM rmHandle QMSS CPPI PA RM QMSS CPPI PA Rm_getHandle Rm_getHandle qmssGblCfgParams.qmRmHandle = rmHandle Qmss_init (&qmInitConfig, &qmssGblCfgParams) startCfg.rmHandle = rmHandle Cppi_init(…) Cppi_startCfg(&startCfg) Pa_create(…) Qmss_startCfg(&startCfg) rmHandle startCfg.rmHandle = rmHandle Cppi_startCfg(&startCfg) Pa_create(…) Pa_startCfg(&startCfg) Pa_startCfg(&startCfg) 12 Supported LLD Resource • QMSS LLD – – – – – – – – • PDSP firmware download Queues (open/close) Memory Regions initialization Linking RAM control Linking RAM indices initialization Accumulator channels (open/close) QOS clusters (open/close) QOS queues (open/close) CPPI LLD – Transmit channels (open/close) – Receive channels (open/close) – Flows (open/close) • PA LLD – Firmware download – Look-up table entries RM Dependency and Backwards Compatibility • QMSS, CPPI, and PA now depend on RM at compile time – Only require path to rm/rm_public_lld.h header to compile • Rm_public_lld.h defines resource permission request/response mechanism between RM and LLDs. – Not dependent upon RM library • Utilization of RM requires registration with QMSS, CPPI, and PA LLDs – New _startCfg API added to QMSS, CPPI and PA LLDs • RM handle registered with LLD via _startCfg – Handle provides callout function pointers to RM permission checking APIs • If _startCfg not invoked, RM not registered and application operates without RM • Existing applications that utilize QMSS, CPPI, and PA do not require any modifications when moving to PDK that contains RM – Existing applications did not and will continue to not utilize RM • Backwards compatible with existing customer applications Permission Granularity • Permissions for single resource consists of initialization and usage permissions – 32-bit field for each permission type, one for each player • Four distinct permission states possible per resource – Allowed to configure and use • DSP and Host share a resource • No Host in the SoC – DSP has full access to everything – Allowed to use but not configure • Resources that are initialized by the Host but can be used by the DSP – Example: QMSS memory regions – region could be inserted (init) by Host and used by DSP – Not allowed to configure or use • Resources that Host must have full control of – Example: QMSS and PA firmware – Do not want DSP downloading firmware after Host has already performed this action – Allowed to configure but not use • never done in practice, just covers all bases Modules resource management Why resource management? • Multiple threads, multiple cores may compete on the same resources: – High layer utility packages such as NRT and IPC use physical resources. Resource manager ensures that multiple packages will not use the same physical resources – Multiple applications use physical resources. Resource management ensures that multiple applications will not use the same physical resources, and if they do, they will be aware of it • The amount of physical resources is limited How resources can be managed? • Explicitly by static fixed assigning of resource to process/thread – – – – Semaphores Interrupts GPIOs Memory (to certain extend) • Implicitly by resource manager function part of the LLD – – – – QMSS queues PKTDMA buffers and memories PA look-up-table rows DMA channels Fixed Assignment- Semaphores • Explicit assigning of semaphores to threads #define PLATFORM_CPPI_HW_SEM 1 CPPI Driver - Used by OSAL layer #define PLATFORM_QMSS_HW_SEM 2 QMSS Driver - Used by OSAL Layer #define PLATFORM_SPI_HW_SEM 3 SPI BUS arbitration - Used by platform library All other semaphore are under the integrator control Pre-Define Interrupts/Events • Explicit assigning of interrupts and events to NIMU #define PLATFORM_ETH_EVENTID 48 Ethernet Switch event - Used by NIMU library #define PLATFORM_ETH_INTERRUPT 7 Ethernet Switch Interrupt - Used by NIMU library All other interrupts and events are under the integrator control Expectations from Resource manager • Static Platform dependent Resources available – Don’t need to change the application code between platform or when moving to next generation. Modify one source file and rebuild • Dynamic distribution of resources as needed within the static definitions – Open and close type API • Non-blocking response when a resource is not available – Error message if the resource can not be assigned to the caller – Indication if the resource was already asked and given to a different player or if the resource is assigned to the requester Requirements of resource management function • Objects that can be accessed by all threads on all cores – Shared memory • Mechanism to prevent “race conditions” – Using hardware semaphores to protect access • Mechanism to prevent incoherency – Disable cache and pre-fetching, or write back and invalidate cache and pre-fetch • Allocation and initialization of shared structure is done by the init function (each module has one, called only once) Open resource flow Open New Resource RM local permission table Does this core have permission to use the resource? NO Return Error Yes Continue Execution Global Module structure Is there available resource? yes No Return assigned flag continue execution Assign resource to the request Continue Execution QMSS Examples Program Accumulator • • • • • • Qmss_Result Qmss_programAccumulator ( Qmss_PdspId pdspId, Qmss_AccCmdCfg * cfg ) Description This function programs the accumulator with values passed in the cfg structure Parameters: [in] pdspId Accumulator to program Qmss_PdspId_PDSP1 selects firmware downloaded to PDSP 1 Qmss_PdspId_PDSP2 selects firmware downloaded to PDSP 2 [in] cfg Initialization structure that contains accumulator configurable fields Post condition: Accumulator channel is programmed. Return values: Value reported by accumulator Success - QMSS_ACC_SOK Failure - QMSS_NOT_INITIALIZED Failure QMSS_INVALID_PARAM Failure - Accumulator status - QMSS_ACC_IDLE, QMSS_ACC_INVALID_COMMAND, QMSS_ACC_INVALID_CHANNEL, QMSS_ACC_CHANNEL_NOT_ACTIVE, QMSS_ACC_CHANNEL_ALREADY_ACTIVE, QMSS_ACC_INVALID_QUEUE_NUMBER, QMSS_RESOURCE_INIT_DENIED Insert Memory Region • • • • • • Qmss_Result Qmss_insertMemoryRegion ( Qmss_MemRegInfo * memRegCfg ) Description This function is used to configure memory region at runtime. The function configures specified memory region with descriptor base address, descriptor size and the number of descriptors. Parameters: memRegCfg Pointer to the memory region configuration structure allocated by caller. Descriptor memory address should be a global address Precondition: Qmss_init function should be called before calling this function. Memory Region specified should not have been configured before. Return values: Success - Inserted Memory region index. Range is 0 to 19. Failure - QMSS_INVALID_PARAM Failure - QMSS_NOT_INITIALIZED Failure - QMSS_MEMREGION_ALREADY_INITIALIZED Failure - QMSS_MEMREGION_INVALID_PARAM Failure - QMSS_MAX_DESCRIPTORS_CONFIGURED Failure - QMSS_MEMREGION_INVALID_INDEX Failure - QMSS_MEMREGION_OVERLAP Failure - QMSS_QUEUE_OPEN_ERROR Failure - QMSS_RESOURCE_MEMORY_REGION_INIT_DENIED Failure - QMSS_RESOURCE_LINKING_RAM_INIT_DENIED Queue Open • • • • • Qmss_QueueHnd Qmss_queueOpen ( Qmss_QueueType queType, int32_t queNum, uint8_t * isAllocated ) Description This function opens the requested queue. A queue can be opened in two ways: 1) If "queNum" is set to QMSS_PARAM_NOT_SPECIFIED, then a new available queue of type "queType" is allocated. 2) If "queNum" is a valid queue number i.e., >= 0, then a queue is allocated if free else a handle to a previously opened queue is returned. In this case "queType" parameter is not used. Parameters: [in] queType Specifies the type of queue that should be opened. [in] queNum Specifies the queue number that should be opened. [out] isAllocated Indicates whether the requested queue is a new queue allocation(1). or was already allocated. If the queue was previously allocated this parameter returns the reference count. Return values: Success - Queue Handle. Used as an input parameter for operation on this queue. Failure - QMSS_RESOURCE_USE_DENIED Failure - <0 QOS Cluster definition • • • • • • • • • • Qmss_Result Qmss_setQosQueueBase ( uint32_t queueNum ) Description This function is used to set the QoS ingress base queue number. The QoS ingress queue are restricted to a set of 64 starting at a fixed base which must be a multiple of 32. Each device has a block of queues reserved for this purpose. It is defined in CSL as QMSS_TRAFFIC_SHAPING_QUEUE_BASE and QMSS_MAX_TRAFFIC_SHAPING_QUEUE. On some devices, the QMSS_MAX_TRAFFIC_SHAPING_QUEUE may be limited to something less than 64. If more queues are needed, then the traffic shaping/QoS subsystem allows any range of general purpose queues used. In other words, QMSS_TRAFFIC_SHAPING_QUEUE_BASE is just a suggestion. If general queues are used, they should be reserved through Qmss_queueOpen, similar to example code in test_descAlloc.c inside QOS_TEST. **No validation is done on the input parameters**. Parameters: [in] queueNum Base queue number Return values: Success - QCMD_RETCODE_SUCCESS Failure - Command buffer return status - QMSS_QCMD_INVALID_COMMAND, QMSS_QCMD_INVALID_INDEX, QMSS_QCMD_INVALID_OPTION, QMSS_RESOURCE_INIT_DENIED CPPI Examples Channel Open • • • • • • • • Cppi_ChHnd Cppi_txChannelOpen ( Cppi_Handle hnd, Cppi_TxChInitCfg * cfg, uint8_t * isAllocated ) Description This function opens a CPPI transmit channel. The channel can be opened in two ways: 1) If channel number in cfg structure is set to CPPI_PARAM_NOT_SPECIFIED, then a new available channel is allocated. 2) If channel number in cfg structure is a valid channel i.e., >= 0, then the channel is allocated if free else a handle to a previously opened channel is returned. The channel is configured only if it is a new channel allocation. Parameters: [in] hnd handle returned by Cppi_open API. [in] cfg Tx channel configuration specifying scheduler priority for the channel, channel number, channel enable, PS and EPIB filtering control, special AIF Monolithic Mode. [out] isAllocated Indicates whether the requested channel number is a new channel allocation(1). or was already allocated. If the channel was previously allocated this parameter returns the reference count. Precondition: Cppi_open function should be called before calling this function. Post condition: Transmit channel is allocated and configured. Return values: Success - Channel Handle. Used as a input parameter in all other channel related APIs. Failure - NULL Flow • • • • • • • • • Cppi_FlowHnd Cppi_configureRxFlow ( Cppi_Handle hnd, Cppi_RxFlowCfg * cfg, uint8_t * isAllocated ) Description This function configures a receive flow. The flow can be configured in two ways: 1) If flow ID number in cfg structure is set to CPPI_PARAM_NOT_SPECIFIED, then a new available flow is allocated. 2) If flow ID number is cfg structure is a valid flow i.e., >= 0, then the flow is allocated if free else a handle to a previously opened flow is returned. The flow is configured only if it is a new flow allocation. Parameters: [in] hnd handle returned by Cppi_open API. [in] cfg Rx flow configuration [out] isAllocated Indicates whether the requested flow is a new flow allocation(1). or was already allocated. If the flow was previously allocated this parameter returns the reference count. Precondition: Cppi_open function should be called before calling this function. Post condition: Rx flow is allocated and configured. Return values: Success - Flow Handle. Failure - NULL PA Examples PA Functions Return Values #define pa_OK 0 #define pa_ERR_CONFIG -10 #define pa_INSUFFICIENT_CMD_BUFFER_SIZE -11 #define pa_INVALID_CMD_REPLY_DEST -12 #define pa_DUP_ENTRY -13 #define pa_INVALID_DUP_ENTRY -14 (A duplicate active entry was found in the L2/L3 table.) #define pa_INVALID_TABLE_MORE_SPECIFIC_ENTRY_PRESENT -15 #define pa_INVALID_MPLS_LABEL -16 #define pa_HANDLE_TABLE_FULL -17 #define pa_INVALID_INPUT_HANDLE -18 #define pa_HANDLE_INACTIVE -19 #define pa_INVALID_IP_FLOW -20 #define pa_WARN_ACTIVE_HANDLE_ACKED -21 #define pa_LUT_ENTRY_FAILED -22 #define pa_RESUBMIT_COMMAND -23 #define pa_SYSTEM_STATE_INVALID -24 #define pa_INVALID_LUT1_INDEX -25 #define pa_WARN_LNK_CNT_UNSYNC -26 #define pa_CMDSET_TOO_BIG -27 #define pa_INVALID_LUT_INST -28 #define pa_RESOURCE_INIT_DENIED -29 #define pa_RESOURCE_USE_DENIED -30 #define pa_FIRMWARE_REVISION_DIFFERENCE -31 Download Image (firmware) • paReturn_t Pa_downloadImage ( Pa_Handle iHandle, int modId, void * image, int sizeBytes ) • Pa_downloadImage downloads a PDSP image to a sub-system with the packet processing modules in reset. • This function is used to download an executable PDSP image to the specific packet processing module. See section table PDSP image for a description of PDSP images provided by this module • Parameters: • [in] iHandle The driver instance handle • [in] modId The PDSP number (0-5) • [in] image The image to download • [in] sizeBytes The size of the image • Return values: Value (Function Return Values) • Precondition: The packet processing modules must be in reset. See Pa_resetControl. Add a line in a LUT • paReturn_t Pa_addMac ( Pa_Handle iHandle, int index, paEthInfo_t * ethInfo, paRouteInfo_t * routeInfo, paRouteInfo_t * nextRtFail, paHandleL2L3_t * handle, paCmd_t cmd, uint16_t * cmdSize, paCmdReply_t * reply, int * cmdDest ) • This function is used to add or replace an entry into the L2 On return the command buffer (cmd) contains a formatted command for the sub-system. The destination for the command is provided in cmdDest. The module user must send the formatted command to the sub-system. The sub-system will generate a reply and this reply must be sent back to this module through the Pa_forwardResult API. Parameters: [in] iHandle The driver instance handle [in] index Specify the index of the LUT1 entry (0-63). Set to pa_LUT1_INDEX_NOT_SPECIFIED if not specified [in] ethInfo Value paEthInfo_t [in] routeInfo Match packet routing information [in] nextRtFail Routing information for subsequent match failures [out] handle Pointer to L2 Handle [out] cmd Where the created command is placed [in,out] cmdSize Input the size of cmd buffer, on output the actual size used. Command buffer minimum size requirements [in] reply Where the sub-system sends the command reply [out] cmdDest Value (Command/Transmit Packet Destinations) Return values: Value (Function Return Values) EDMA RM module RM LLD functionality is part of the EDMA release DMA Resource Management • EDMA3 has its own resource manager module Similar to the RM LLD, but this is dynamic (by function call) and not static • The resources are defined by the resource manager, the driver code requests resources. The driver and the RM are tied together • For devices with multiple EDMA controller, only ONE resource manager module can be created for each hardware instance, 6678 has three hardware instances DMA Resource Management - Continue • DMA resource manager has three types of APIs: – Configuration APIs :create, open, delete, close – Basic management: allocate and free resources, connect and unconnect TCC (transfer completion code, or callback function upon transfer completion) – Advanced Management: map logical channels, set and get PaRAM, map PaRAM to EDMA and QDMA channels, manipulate TCC and more Initialization RM API EDMA3_RM_Result EDMA3_RM_create (uint32_t phyCtrllerInstId, const EDMA3_RM_GblConfigParams *gblCfgParams, const void *miscParam) Create EDMA3 Resource Manager Object. Gives list of hardware resources part of the hardware instance. (For example, EDMA3_0 is different than EDMA3_1 or 2) EDMA3_RM_Result EDMA3_RM_delete (uint32_t phyCtrllerInstId, const void *param) EDMA3_RM_Handle EDMA3_RM_open (uint32_t phyCtrllerInstId, const EDMA3_RM_Param *initParam, EDMA3_RM_Result *errorCode) Open EDMA3 Resource Manager Instance. The parameters specify the resources that are under this instance control. EDMA3_RM_Result EDMA3_RM_close (EDMA3_RM_Handle hEdmaResMgr, const void *param) For a description of the parameter structures, see EDMA3 Resource Manager User Guide, part of the edma3 release Basic EDMA RM API EDMA3_RM_Result EDMA3_RM_registerTccCb (EDMA3_RM_Handle hEdmaResMgr, const EDMA3_RM_ResDesc *channelObj, uint32_t tcc, EDMA3_RM_TccCallback tccCb, void *cbData) Registers a transfer completion handler for a specific DMA/QDMA channel. EDMA3_RM_Result EDMA3_RM_unregisterTccCb (EDMA3_RM_Handle hEdmaResMgr, const EDMA3_RM_ResDesc *channelObj) Unregister the previously registered callback function against a DMA/QDMA channel. EDMA3_RM_Result EDMA3_RM_allocResource (EDMA3_RM_Handle hEdmaResMgr, EDMA3_RM_ResDesc *resObj) This API is used to allocate specified EDMA3 Resources like DMA/QDMA channel, PaRAM Set or TCC. EDMA3_RM_Result EDMA3_RM_freeResource (EDMA3_RM_Handle hEdmaResMgr, const EDMA3_RM_ResDesc *resObj) This API is used to free previously allocated EDMA3 Resources like DMA/QDMA channel, PaRAM Set or TCC. EDMA3_RM_Result EDMA3_RM_allocContiguousResource (EDMA3_RM_Handle hEdmaResMgr, EDMA3_RM_ResDesc *firstResIdObj, uint32_t numResources) Allocate a contiguous region of specified EDMA3 Resource like DMA channel, QDMA channel, PaRAM Set or TCC. EDMA3_RM_Result EDMA3_RM_freeContiguousResource (EDMA3_RM_Handle hEdmaResMgr, EDMA3_RM_ResDesc *firstResIdObj, uint32_t numResources) Free a contiguous region of specified EDMA3 Resource like DMA channel, QDMA channel, PaRAM Set or TCC, previously allocated. For a description of the parameter structures, see EDMA3 Resource Manager User Guide, part of the edma3 release Advance EDMA RM API – Partial list EDMA3_RM_Result EDMA3_RM_allocLogicalChannel (EDMA3_RM_Handle hEdmaResMgr, EDMA3_RM_ResDesc *lChObj, uint32_t *pParam, uint32_t *pTcc) Request a DMA/QDMA/Link channel. EDMA3_RM_Result EDMA3_RM_freeLogicalChannel (EDMA3_RM_Handle hEdmaResMgr, EDMA3_RM_ResDesc *lChObj) This API is used to free the specified channel (DMA/QDMA/Link) and its associated resources (PaRAM Set, TCC etc). EDMA3_RM_Result EDMA3_RM_mapEdmaChannel (EDMA3_RM_Handle hEdmaResMgr, uint32_t channelId, uint32_t paRAMId) Bind the resources DMA Channel and PaRAM Set. Both the DMA channel and the PaRAM set should be previously allocated. If they are not, this API will result in error. EDMA3_RM_Result EDMA3_RM_mapQdmaChannel (EDMA3_RM_Handle hEdmaResMgr, uint32_t channelId, uint32_t paRAMId, EDMA3_RM_QdmaTrigWord trigWord) Bind the resources QDMA Channel and PaRAM Set. Also, Set the trigger word for the QDMA channel. Both the QDMA channel and the PaRAM set should be previously allocated. If they are not, this API will result in error. For a description of the parameter structures, see EDMA3 Resource Manager User Guide, part of the edma3 release EDMA Examples EDMA driver and EDMA RM EDMA3_DRV_Result EDMA3_DRV_requestChannel ( EDMA3_DRV_Handle hEdma, uint32_t * pLCh, uint32_t * pTcc, EDMA3_RM_EventQueue evtQueue, EDMA3_RM_TccCallback tccCb, void * cbData ) Request a DMA/QDMA/Link channel. Each channel (DMA/QDMA/Link) must be requested before initiating a DMA transfer on that channel. This API is used to allocate a logical channel (DMA/QDMA/Link) along with the associated resources. For DMA and QDMA channels, TCC and PaRAM Set are also allocated along with the requested channel. User can also specify a specific TCC which needs to be allocated with the DMA/QDMA channel or else can request any available TCC. For Link channels, ONLY a PaRAM Set is allocated and the allocated PaRAM Set number is returned as the logical channel no. A TCC code can also be specified while making the request. This TCC code will be copied to the LINK field of the allocated PaRAM Set and will be associated with the Link channel. User can request a specific logical channel - DMA, QDMA and Link, by passing the channel id in 'pLCh'. Note that the channel id is the same as the actual resource id in case of DMA channels and Link channels. For DMA channels, channel id lies between 0 and (max dma channels - 1). For Link channels, channel id lies between (max dma channels) and (max param sets - 1). To allocate specific QDMA channels, user SHOULD use the defines EDMA3_DRV_QDMA_CHANNEL_X mentioned above. User can also request ANY available logical channel by specifying the below mentioned values in '*pLCh': a) EDMA3_DRV_DMA_CHANNEL_ANY: For DMA channels b) EDMA3_DRV_QDMA_CHANNEL_ANY: For QDMA channels, and c) EDMA3_DRV_LINK_CHANNEL: For Link channels. Normally user should use this value to request link channels (PaRAM Sets used for linking purpose only), unless he wants to use some specific link channels (PaRAM Sets) which is also allowed. d) EDMA3_DRV_LINK_CHANNEL_WITH_TCC: For Link channels. User should use this value to request link channels with TCC code. This API internally uses EDMA3_RM_allocResource () to allocate the desired resources (DMA/QDMA channel, PaRAM Set and TCC). For More Information • For more information on the RM module, refer to the wiki https://twiki.dal.design.ti.com/bin/view/ASP/DSPS/Germantwn/ResourceManager • For more information on the EDMA RM and drivers refer to the edma release of mcsdk edma3_XX\packages\ti\sdo\edma3\rm\docs\ EDMA3_RM_User_Guide.pdf edma3_XX\packages\ti\sdo\edma3\drv\docs\ EDMA3_Driver_User_Guide.pdf And to the html files in the same location • View the complete C66x Multicore SOC Online Training for KeyStone Devices, including details on the individual modules. • For questions regarding topics covered in this training, visit the support forums at the TI E2E Community website.