/*-----------------------------------------------------------------------*/
/*  Standard header includes for c environment.                          */
/*-----------------------------------------------------------------------*/

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>

/*-----------------------------------------------------------------------*/
/*  These are the include files that are needed for edma/qdma.           */
/*-----------------------------------------------------------------------*/

#include "../inc/csl_edma.h"
#include "../inc/cslr_edmacc.h"
#include "../inc/eve.h"    
#include "../inc/tistdtypes.h"
#include "../inc/eve_dma_funcs.h"


/*-----------------------------------------------------------------------*/
/*  We define a common dma_state_struct, common between EDMA and QDMA.   */
/*  This state structure will be used to hold the resources allocated    */
/*  by the use of IDMA3.X through DMAN resource negotiation. All DMA     */
/*  accesses will be done only through these allocated resources.        */
/*                                                                       */
/*  physical_chan : This member has an overloaded meaning. In case       */
/*  of QDMA, it is the actual physical QDMA channel, 0..7.               */
/*  In case of EDMA, it is the event                                     */
/*  that needs to be set in the Event enable set register. Note, that    */
/*  since DCHAMAP DMA channel map exists, we can map events and PARAMS   */
/*  in a flexible manner. We carray this as an array of size NUM_        */
/*  CHANNELS "logical" channels. So, we need to look at dma_attr, to     */
/*  decide on the attributes to interpret the meaning of physical_chan.  */
/*                                                                       */
/*  tcc_val : Each channel posts a completion interrupt, when the        */
/*  transfer has finished, and this is allocated through DMAN3. This     */
/*  is once again an array of size "NUM_CHANNELS" physical channels.     */
/*                                                                       */
/*  region_no : This is to support regional interrupt, and is more for   */
/*  documentation, of which CPU services the interrupt. There are 8      */
/*  regions of which 6 are used and 2 are unused. This is once again     */
/*  the size of the logical channels.                                    */
/*                                                                       */
/*  trig_param : This is an overloaded variable, in case of QDMA it is   */
/*  the trigger PARAM programmed in QCHMAP. In case of EDMA, you look    */
/*  up the event from the "physical_chan" and then you lookup the        */
/*  associated PARAM in DCHAMAP. It is an array that holds the addresses */
/*  of the PARAM and is of size "NUM_CHANNELS" logical channels.         */
/*                                                                       */
/*  num_channels : This is the number of logical channels, intended for  */
/*  query functions, and must be equal to "NUM_CHANNELS".                */
/*                                                                       */
/*  num_param : This is the number of PARAMS used by a given qdma/edma   */
/*  channel. If we are doing linking, chaining or both, we will need     */
/*  multiple PARAM entries so we store this information. The number      */
/*  of linked transfers that can be done on this channel equals this     */
/*  number.                                                              */
/*                                                                       */
/*  base_param : This is the parameter RAM which is the starting locn,   */
/*  where we should IDMA to, incase of linked transfers. This can be     */
/*  computed by a simple formula:                                        */
/*                                                                       */
/*  trigger_param[i]  = base_param[i] + (8 * num_param[i]).              */
/*                                                                       */
/*  DMAN3 always returns trigger_param, so base_param, should be         */
/*  computed as:                                                         */
/*                                                                       */
/*  base_param[i]  = tigger_param[i] - (8 * num_param[i])                */
/*                                                                       */
/*  dma_attr : DMA attribute of channel, is it QDMA or EDMA.             */
/*                                                                       */
/*  transfer_pending: Pointer returned by DMAN3 to maintain the status   */
/*  of each of the logical channels when pre-empted. So while issuing    */
/*  every transfer we need to make operations atomic.                    */
/*                                                                       */
/*  Note that this dma_state_struct, as such can be located anywhere     */
/*  either in internal or external memory.                               */
/*                                                                       */
/*  Based on several issues encountered during integration we would      */
/*  like to leave the system in the state we found it so that sloppy     */
/*  applications which rely on this behaviour can still work. In         */
/*  order to faciliatet this we declare:                                 */
/*                                                                       */
/*  dchmap : DMA channel map register, as many as number of logical      */
/*  channels as all channels can be EDMA channels.                       */
/*                                                                       */
/*  qchmap : QDMA channel map register, as many as number of logical     */
/*  channels as all channels can be QDMA channels.                       */
/*                                                                       */
/*  dmaqnum: DMA queue number, queue number utilized by event no N.      */
/*  Each queue specifies upto 8 events, so we will carry one DMAQNUM     */
/*  per logical channel.                                                 */
/*                                                                       */
/*  qdmaqnum: QDMA queue number if channel is qdma channel.              */
/*                                                                       */
/*  trig_word: Only applicable for QDMA channels, allowed values are     */
/*  0..7, usually last word is trigger word.                             */
/*-----------------------------------------------------------------------*/


unsigned int ed_pack2 (unsigned short hi, unsigned short lo)
{
    unsigned int ret_val;
    ret_val = (((hi << 16) & 0xFFFF0000) | (lo & 0x0000FFFF));
    return (ret_val);
}


/* ------------------------------------------------------------------ */
/* These functions "param_....()" write the transfer attributes to    */
/* the parameter ram for a given channel                              */
/*                                                                    */
/*  WORD0:  OPTIONS field.                                            */
/*  WORD1:  Sorce address (SRC).                                      */
/*  WORD2:  BCNT | ACNT. BCNT needs to be num_lines                   */
/*  ACNT is the number of 1D bytes to be transferred.                 */
/*  WORD3:  Destination address (DST).                                */
/*  WORD4:  DSTBIDX | SRBIDX.                                         */
/*  DSTBIDX: num_bytes and SRCBIDX:pitch                              */
/*  WORD5:  BCNTRLD | LINK. This is the same as BCNT.                 */ 
/*  No linking is needed and hence the link field is                  */
/*  set to 0xFFFF.                                                    */
/*  WORD6:  DSTCIDX | SRCCIDX.                                        */
/*  WORD7:  CCNT                                                      */
/*                                                                    */     
/* ------------------------------------------------------------------ */
    
void ed_params_2d_to_1d_eve
(
    DMA_State_Struct    *dma_state_struct, 
    unsigned int        chan_no, 
    unsigned int        opt_word, 
    unsigned char       *src_ptr, 
    unsigned char       *dst_ptr, 
    unsigned int        no_bytes, 
    unsigned int        no_lines, 
    unsigned int        line_pitch, 
    unsigned int        next_blk_offset,
    unsigned int        num_auto_incr
)
{
    volatile unsigned int *tparam;

    tparam     =    dma_state_struct->trig_param[chan_no];
    tparam[0]  =    (unsigned int) opt_word;
    tparam[1]  =    (unsigned int) src_ptr;
    tparam[2]  =    ed_pack2(no_lines, no_bytes);
    tparam[3]  =    (unsigned int) dst_ptr;
    tparam[4]  =    ed_pack2(no_bytes, line_pitch);
    tparam[5]  =    ed_pack2(no_lines, 0xFFFF);
    tparam[6]  =    (0x0 << 16) | (next_blk_offset);   
    tparam[7]  =    num_auto_incr;
}

void ed_params_2d_to_1d_link_eve
(
    DMA_State_Struct    *dma_state_struct, 
    unsigned int        chan_no,
    unsigned int        tparam_offset, 
    unsigned int        opt_word, 
    unsigned char       *src_ptr, 
    unsigned char       *dst_ptr, 
    unsigned int        no_bytes, 
    unsigned int        no_lines, 
    unsigned int        line_pitch, 
    unsigned int        link_addr
)
{
    volatile unsigned int *tparam;

    tparam                     =    dma_state_struct->trig_param[chan_no];
    tparam[tparam_offset + 0]  =    (unsigned int) opt_word;
    tparam[tparam_offset + 1]  =    (unsigned int) src_ptr;
    tparam[tparam_offset + 2]  =    ed_pack2(no_lines, no_bytes);
    tparam[tparam_offset + 3]  =    (unsigned int) dst_ptr;
    tparam[tparam_offset + 4]  =    ed_pack2(no_bytes, line_pitch);
    tparam[tparam_offset + 5]  =    ed_pack2(no_lines, (unsigned short) link_addr);
    tparam[tparam_offset + 6]  =    (0x0 << 16) | 0;   
    tparam[tparam_offset + 7]  =    0x1;
}




void ed_params_1d_to_2d_eve
(
    DMA_State_Struct    *dma_state_struct, 
    unsigned int        chan_no, 
    unsigned int        opt_word, 
    unsigned char       *src_ptr, 
    unsigned char       *dst_ptr, 
    unsigned int        no_bytes, 
    unsigned int        no_lines, 
    unsigned int        line_pitch, 
    unsigned int        next_blk_offset,
    unsigned int        num_auto_incr
)
{
    volatile unsigned int *tparam;

    tparam     =    dma_state_struct->trig_param[chan_no];
    tparam[0]  =    (unsigned int) opt_word;
    tparam[1]  =    (unsigned int) src_ptr;
    tparam[2]  =    ed_pack2(no_lines, no_bytes);
    tparam[3]  =    (unsigned int) dst_ptr;
    tparam[4]  =    ed_pack2(line_pitch, no_bytes);
    tparam[5]  =    ed_pack2(no_lines, 0xFFFF);
    tparam[6]  =    ((next_blk_offset) << 16) | (0x0);  
    tparam[7]  =    num_auto_incr;              
}

/* -------------------------------------------------------------------- */
/* This function assigns event numbers, transfer complete codes, queue  */
/* and register numbers to each channel.                                */
/* -------------------------------------------------------------------- */

void ed_dma_assign_channels
(
    unsigned int    *evt_no, 
    unsigned int    *tcc_no, 
    unsigned int    *que_no, 
    unsigned int    *reg_no, 
    DMA_Chan_Attr   dma_attr,
    unsigned int    num_channels
)
{
    int j;

    for (j = 0; j < num_channels; j++)
    {
       evt_no[j]         =       j % NUM_EEVTS;
       tcc_no[j]         =       j % NUM_TCCS;
       que_no[j]         =       j % NUM_QUES;  
       reg_no[j]         =       1;
       
       if (dma_attr == QDMA_CHAN)
       {
            evt_no[j]    =        j % NUM_QEVTS;
            tcc_no[j]    =        j % NUM_TCCS;
            que_no[j]    =        j % NUM_QUES;  
            reg_no[j]    =        0;
       }
    }
}



/*-----------------------------------------------------------------------*/
/*  This function accepts the resources allocated at framework level     */
/*  and populates the DMA state structure. All subseqent DMA transfers   */
/*  will refer to this for performing their transfer.                    */
/*-----------------------------------------------------------------------*/

void ed_dma_state_struct_populate
(
    CSL_EdmaccRegsOvly         edma_cc,
    DMA_State_Struct           *dma_state_struct,
    unsigned int               *evt_no,
    unsigned int               *tcc_no,
    unsigned int               *reg_no,
    unsigned int               *que_no,
    unsigned int               num_param,
    unsigned int               num_channels,
    DMA_Chan_Attr              dma_attr,
    Bool                       *trf_pend
)
{
     int   i;
     int   qu_reg_no;
     unsigned int prm_no;

    volatile unsigned int      *base_param;
    volatile unsigned int      *trig_param;

     /*-------------------------------------------------------------------*/
     /*  First assign number of channels, internal memory pointer, and    */
     /*  size.                                                            */
     /*-------------------------------------------------------------------*/

     dma_state_struct->num_channels   =   num_channels;

     /*-------------------------------------------------------------------*/
     /*  Capture the queue to TC map, 1 to 1.                             */
     /*-------------------------------------------------------------------*/

     dma_state_struct->que_tc_map = edma_cc->QUETCMAP;

     /*-------------------------------------------------------------------*/
     /*  Capture queue priority registers and QDMA event enable reg.      */
     /*-------------------------------------------------------------------*/

     dma_state_struct->que_pri   =  edma_cc->QUEPRI;

     /*-------------------------------------------------------------------*/
     /*  Capture edma event enable register lo and hi, for 64 evts.       */
     /*-------------------------------------------------------------------*/

     dma_state_struct->qeer     =  edma_cc->QEER;  
     dma_state_struct->eer      =  edma_cc->EER;  

     /*-------------------------------------------------------------------*/
     /*  Remember the QDMA channel to queue mapping.                      */
     /*-------------------------------------------------------------------*/

     dma_state_struct->qdmaqnum =  edma_cc->QDMAQNUM;

     /*-------------------------------------------------------------------*/
     /*  Now assign all vector quantities by iterating in a loop. This    */
     /*  loop iterates for as many logical channels as requested.         */
     /*-------------------------------------------------------------------*/

     for (i = 0; i < num_channels; i++)
     {

         /* --------------------------------------------------------------*/
         /* Give each channel a unique param ram entry                    */
         /* --------------------------------------------------------------*/    
         prm_no = ((i*num_param) % NUM_PRMS); 
         trig_param     =       (volatile unsigned int *) 
                               (&edma_cc->PARAMENTRY[prm_no]);

         base_param     =       trig_param  + (8 * (num_param - 1));
 

         dma_state_struct->physical_chan[i]  =   evt_no[i];
         dma_state_struct->tcc_val[i]        =   tcc_no[i];
         dma_state_struct->que_no[i]         =   que_no[i];
         dma_state_struct->region_no[i]      =   reg_no[i];
         dma_state_struct->trig_param[i]     =   trig_param;
         dma_state_struct->base_param[i]     =   base_param;
         dma_state_struct->num_param[i]      =   num_param;
         dma_state_struct->trf_pend[i]       =   trf_pend;
         dma_state_struct->dma_attr[i]       =   dma_attr;
         
         /*---------------------------------------------------------------*/
         /* Always setup QDMA trigger word to be the last word in PARAM.  */
         /*---------------------------------------------------------------*/
         
         dma_state_struct->trig_word[i]  =        7;

         if (dma_attr == EDMA_CHAN)
         {
             qu_reg_no = (evt_no[i] >> 3);
             dma_state_struct->dmaqnum[i] =  edma_cc->DMAQNUM[qu_reg_no];
             dma_state_struct->dchmap[i]  =  edma_cc->DCHMAP[evt_no[i]]; 
         }
         else
         {
             dma_state_struct->qchmap[i]  = edma_cc->QCHMAP[evt_no[i]];
         }
    }
}

/*-----------------------------------------------------------------------*/
/*  This function will perform the setup of the global registers. In     */
/*  this process we should disable interrupts and re-enable interrupts.  */
/*  For QDMA we will be setting up QCHMAP, QDMAQNUM, QRAEX, QEESR.       */
/*  Similarly for EDMA we will be setting up, DCHMAP, DMAQNUM, DRAEX,    */
/*  ESR, ESRH. Independent of QDMA and EDMA we need to set QUEPRI and    */
/*  QUETCMAP.                                                            */
/*-----------------------------------------------------------------------*/


void ed_dma_global_regs_setup
(
    CSL_EdmaccRegsOvly  edma_cc,
    DMA_State_Struct   *dma_state_struct
)
{
    unsigned int num_channels = dma_state_struct->num_channels;
 
    unsigned int        evt_no;
    unsigned int        que_no;
    unsigned int        trig_word;
    unsigned int        qu_rem;
    unsigned int        qu_shift;
    DMA_Chan_Attr       dma_attr;
    unsigned int        pa_no;


    int   i;
    int   qu_reg_no;
    volatile unsigned int        *trig_param;

    /*-------------------------------------------------------------------*/
    /*  First setup the quee to TC mapping, we setup 1 to 1 mapping and  */
    /*  this needs to be verified based on FIFO properties. For now Q0   */
    /*  submits on TC0, and similarly Q3 submits on TC3.                 */
    /*-------------------------------------------------------------------*/

    edma_cc->QUETCMAP  =
    (
        (CSL_EDMACC_CCCFG_NUM_TC_1  <<  CSL_EDMACC_QUETCMAP_TCNUMQ0_SHIFT)
      | (CSL_EDMACC_CCCFG_NUM_TC_2  <<  CSL_EDMACC_QUETCMAP_TCNUMQ1_SHIFT)
    );

    /*-------------------------------------------------------------------*/
    /*  We need to verify priority values, but for now, DDR traffic is   */
    /*  given higher priority, and co-processor commands are given le    */
    /*  sser priority. We program these without accepting user inputs    */
    /*  as this could impact performance, so we calibrate this on QT     */
    /*  and set it here.                                                 */
    /*-------------------------------------------------------------------*/

    #define CSL_QUE_PRI0     0
    #define CSL_QUE_PRI3     3

    edma_cc->QUEPRI    =
    (
        (CSL_QUE_PRI3  <<  CSL_EDMACC_QUEPRI_PRIQ0_SHIFT)
      | (CSL_QUE_PRI0  <<  CSL_EDMACC_QUEPRI_PRIQ1_SHIFT)
    );

    /*-------------------------------------------------------------------*/
    /* Also set up the threshold register though this is strictly not    */
    /* needed.                                                           */
    /*-------------------------------------------------------------------*/

    edma_cc->QWMTHRA  = (CSL_EDMACC_QWMTHRA_RESETVAL & 0xFFFF); 

    /*-------------------------------------------------------------------*/
    /*  Now iterate for each of the channels and setup the other regs.   */
    /*  based on channel attribute.                                      */
    /*-------------------------------------------------------------------*/

    for (i = 0; i < num_channels; i++)
    {
        /*---------------------------------------------------------------*/
        /*  Read specific event num, tcc, region, trigger param, base    */
        /*  param, number of paramns, trf_pend locn, dma attrib, of      */
        /*  channel, que_no for request.                                 */
        /*---------------------------------------------------------------*/

        evt_no        =    dma_state_struct->physical_chan[i];  
        que_no        =    dma_state_struct->que_no[i];
        trig_param    =    dma_state_struct->trig_param[i];     
        dma_attr      =    dma_state_struct->dma_attr[i];
        trig_word     =    dma_state_struct->trig_word[i];

        /*---------------------------------------------------------------*/
        /*  If it is EDMA channel, we setup DCHMAP, DMAQNUM, DRAE. This  */
        /*  will tie down specific PARAM to event, queue for event, and  */
        /*  region where completion interrupt must go.                   */
        /*---------------------------------------------------------------*/

        if (dma_attr == EDMA_CHAN)
        {
             #ifdef DMA_ASSERT
             assert (evt_no     >= 0);
             assert (evt_no     <= 8);
             assert (que_no     >= 0);
             assert (que_no     <= 1);
             assert (trig_param >= 0);
             assert (trig_param <= 64);
             assert (num_channels <= 16);
             #endif

             /*-----------------------------------------------------------*/
             /*  Write the corresponding param for evt no evt_no, each    */
             /*  of the 64 events has an associated register. This is     */
             /*  the difference between the current param address and     */
             /*  base PARAM address. This gives offset in bytes, 32       */
             /*  bytes makes a PARAM, so to get PARAM no, we divide       */
             /*  by 32, note DCHMAP finally ends up taking this offset    */
             /*  so we can avoid right shifting and left shifting by 5    */
             /*  as we optimize cycles.                                   */
             /*-----------------------------------------------------------*/

             pa_no = 
             (
                 (unsigned int)trig_param - 
                 (unsigned int)&edma_cc->PARAMENTRY[0]
             ) >> CSL_EDMACC_DCHMAP_PAENTRY_SHIFT; 

             edma_cc->DCHMAP[evt_no] = 
             ((unsigned int)(pa_no) << CSL_EDMACC_DCHMAP_PAENTRY_SHIFT);
             
             /*-----------------------------------------------------------*/
             /*  Queue to use for the 64 event is present in 8 regs. So   */
             /*  we determine reg_no, and offset within that register.    */
             /*  Offset within reg, is used to decide shift.              */
             /*-----------------------------------------------------------*/

             qu_reg_no = (evt_no >> 3);
             qu_rem    = (evt_no - (8 * qu_reg_no));

             #ifdef DMA_ASSERT
             assert (qu_rem >= 0);
             assert (qu_rem <= 7);
             #endif

             if (qu_rem == 0)  qu_shift = CSL_EDMACC_DMAQNUM_E0_SHIFT;
             if (qu_rem == 1)  qu_shift = CSL_EDMACC_DMAQNUM_E1_SHIFT;
             if (qu_rem == 2)  qu_shift = CSL_EDMACC_DMAQNUM_E2_SHIFT;
             if (qu_rem == 3)  qu_shift = CSL_EDMACC_DMAQNUM_E3_SHIFT;
             if (qu_rem == 4)  qu_shift = CSL_EDMACC_DMAQNUM_E4_SHIFT;
             if (qu_rem == 5)  qu_shift = CSL_EDMACC_DMAQNUM_E5_SHIFT;
             if (qu_rem == 6)  qu_shift = CSL_EDMACC_DMAQNUM_E6_SHIFT;
             if (qu_rem == 7)  qu_shift = CSL_EDMACC_DMAQNUM_E7_SHIFT;

             /*-----------------------------------------------------------*/
             /*  Now we can write in DMAQNUM, the queue number, at the    */
             /*  correct location.                                        */
             /*-----------------------------------------------------------*/

             edma_cc->DMAQNUM[qu_reg_no] |= (que_no << qu_shift); 
        }
        else
        {
             #ifdef DMA_pingSSERT
             assert (evt_no >= 0);
             assert (evt_no <= 7);
             assert (que_no >= 0);
             assert (que_no <= 1);
             assert (num_channels <= 16);
             assert (trig_word == 7);
             #endif
             
             assert (trig_word == 7);
         
             /*-----------------------------------------------------------*/
             /* For QDMA we have an associated QDMA enable register.      */
             /*-----------------------------------------------------------*/

             if (evt_no == 0)   qu_shift = CSL_EDMACC_QEESR_E0_SHIFT;
             if (evt_no == 1)   qu_shift = CSL_EDMACC_QEESR_E1_SHIFT;
             if (evt_no == 2)   qu_shift = CSL_EDMACC_QEESR_E2_SHIFT;
             if (evt_no == 3)   qu_shift = CSL_EDMACC_QEESR_E3_SHIFT;
             if (evt_no == 4)   qu_shift = CSL_EDMACC_QEESR_E4_SHIFT;
             if (evt_no == 5)   qu_shift = CSL_EDMACC_QEESR_E5_SHIFT;
             if (evt_no == 6)   qu_shift = CSL_EDMACC_QEESR_E6_SHIFT;
             if (evt_no == 7)   qu_shift = CSL_EDMACC_QEESR_E7_SHIFT;

             edma_cc->QEESR = (0x1 << qu_shift);

             /*-----------------------------------------------------------*/
             /*  For QDMA channel we write both param amd trigger word.   */
             /*-----------------------------------------------------------*/

             pa_no = 
             (
                 (unsigned int)trig_param - 
                 (unsigned int)&edma_cc->PARAMENTRY[0]
             ) >> CSL_EDMACC_QCHMAP_PAENTRY_SHIFT; 

             edma_cc->QCHMAP[evt_no] =
             (
                 ((unsigned int)(pa_no)      << CSL_EDMACC_QCHMAP_PAENTRY_SHIFT)
               | (trig_word                  << CSL_EDMACC_QCHMAP_TRWORD_SHIFT)
             );

             /*-----------------------------------------------------------*/
             /*  In QDMAQNUM, we write the queue number specified by the  */
             /*  user, as evt_no has to be one of 8 QDMA channels. We     */
             /*  also write a 1, into the region requested by user.       */
             /*-----------------------------------------------------------*/

             qu_rem   = evt_no;
             if (qu_rem == 0)  qu_shift = CSL_EDMACC_QDMAQNUM_E0_SHIFT;
             if (qu_rem == 1)  qu_shift = CSL_EDMACC_QDMAQNUM_E1_SHIFT;
             if (qu_rem == 2)  qu_shift = CSL_EDMACC_QDMAQNUM_E2_SHIFT;
             if (qu_rem == 3)  qu_shift = CSL_EDMACC_QDMAQNUM_E3_SHIFT;
             if (qu_rem == 4)  qu_shift = CSL_EDMACC_QDMAQNUM_E4_SHIFT;
             if (qu_rem == 5)  qu_shift = CSL_EDMACC_QDMAQNUM_E5_SHIFT;
             if (qu_rem == 6)  qu_shift = CSL_EDMACC_QDMAQNUM_E6_SHIFT;
             if (qu_rem == 7)  qu_shift = CSL_EDMACC_QDMAQNUM_E7_SHIFT;

             edma_cc->QDMAQNUM         |= (que_no << qu_shift); 
        }
    }
}

void ed_dma_global_regs_teardown
(
    CSL_EdmaccRegsOvly  edma_cc,
    DMA_State_Struct   *dma_state_struct
)
{
    int   i;
    int   evt_no;
    int   dma_attr;
    
    int   num_channels   = dma_state_struct->num_channels;
    
    for (i = 0; i < num_channels; i++)
    {
        dma_attr = dma_state_struct->dma_attr[i];
        evt_no   = dma_state_struct->physical_chan[i];
        
        if (dma_attr == EDMA_CHAN)
        {
            assert (evt_no <=   NUM_EEVTS);
            edma_cc->ECR   =   (0x1 << evt_no);  
        }
        else
        {
            assert (evt_no <=   NUM_QEVTS);
            edma_cc->QEECR  =   (0x1 << evt_no);
        }
    }    
}

