//******************************************************************************
//
// Function Name:  chal_dma_get_int_status
//
// Description:    Returns the DMA controller's interrupt status
//
//******************************************************************************
void chal_dma_get_int_status(CHAL_HANDLE handle, ChalDmaIntStatus_t *intStatus)
{
    UInt32 rc;
    ChalDmaDev_t *pDmaDev = (ChalDmaDev_t *)handle;
   
    rc = CHAL_REG_READ32(pDmaDev->baseAddr + DMAC_INTTCSTAT_OFFSET);
    intStatus->tcInt |= (rc & 0xfff);
    CHAL_REG_WRITE32(pDmaDev->baseAddr + DMAC_INTTCCLEAR_OFFSET, rc);
    
    rc = CHAL_REG_READ32(pDmaDev->baseAddr + DMAC_INTERRSTAT_OFFSET);
    intStatus->errInt |= (rc & 0xfff);
    CHAL_REG_WRITE32(pDmaDev->baseAddr + DMAC_INTERRCLR_OFFSET, rc);
}
예제 #2
0
/*
 * ******************************************************************************
 *
 *  Function Name:  chal_ipc_read_mailbox
 *
 *  Description:
 *
 * ******************************************************************************
 */
BCM_ERR_CODE chal_ipc_read_mailbox (
    CHAL_IPC_HANDLE handle,
    IPC_MAILBOX_ID mailboxId,
    uint32_t *value
    )
{
   CHAL_IPC_DEV_T *device;

   BCM_DBG_ENTER();

   /* Check boundry conditions
    * IPC_MAILBOX_ID is an unsigned value and does not need to check less than zero */
   if ( mailboxId >= IPC_MAILBOX_ID_MAX )
   {
      BCM_DBG_EXIT();
      return( BCM_ERROR );
   }

   device = (CHAL_IPC_DEV_T*)handle;

   *value = CHAL_REG_READ32( device->ipc_secure_reg_base + IPCSEC_IPCMAIL0_OFFSET + mailboxId*sizeof(uint32_t) );

   BCM_DBG_EXIT();
   return( BCM_SUCCESS );
}
//******************************************************************************
//
//
// Function Name:  chal_dma_force_shutdown_chan
//
// Description:    Stop DMA transfer on the specified channel and lose all
//                 data in the FIFO
//
//******************************************************************************
void chal_dma_force_shutdown_chan(CHAL_HANDLE handle, cUInt32  channel)
{ 
    // 
    // stop the DMA channel with data loss 
    // You can disable a DMA channel in the following ways:
    // 1. Write directly to the Channel Enable bit.
    //    You lose any outstanding data in the FIFOs if you use this method.
    // 2. Use the Active and Halt bits in conjunction with the Channel Enable bit.
    // 3. Wait until the transfer completes. The channel is then automatically disabled.
    //
    //
    cUInt32 temp;
    ChalDmaDev_t *pDmaDev = (ChalDmaDev_t *)handle;
    
    temp = CHAL_REG_READ32(pDmaDev->baseAddr+DMAC_CH0CONFIG_OFFSET 
                           + CHAN_REG_INCREMENT * channel);

    //chal_dprintf(CDBG_ERRO, "chal_dma_force_shutdown_chan() temp: 0x%x\n", temp);

    temp &= ~DMAC_CH0CONFIG_E_MASK;

    CHAL_REG_WRITE32(pDmaDev->baseAddr + DMAC_CH0CONFIG_OFFSET 
                        + CHAN_REG_INCREMENT * channel, temp);

    CHAL_REG_WRITE32(pDmaDev->baseAddr + DMAC_INTTCCLEAR_OFFSET, 0x1<<channel);
    CHAL_REG_WRITE32(pDmaDev->baseAddr + DMAC_INTERRCLR_OFFSET, 0x1<<channel);

    chal_dma_mark_channel_inactive(handle, channel);
}
//******************************************************************************
//
// Function Name:  chal_dma_soft_sig_last_request
//
// Description:    Set a device to generate software single DMA request
//
//******************************************************************************
void chal_dma_soft_sig_last_request(CHAL_HANDLE handle, cUInt32 device)
{
    cUInt32 temp;
    ChalDmaDev_t *pDmaDev = (ChalDmaDev_t *)handle;
    
    temp = CHAL_REG_READ32(pDmaDev->baseAddr + DMAC_SOFTLSREQ_OFFSET);
    temp |= (0x1 << device);

    CHAL_REG_WRITE32(pDmaDev->baseAddr + DMAC_SOFTLSREQ_OFFSET, temp);
}
//******************************************************************************
//
// Function Name:  chal_dma_wait_channel
//
// Description:    Wait for a channel 
//
//******************************************************************************
void chal_dma_wait_channel(CHAL_HANDLE handle, cUInt32 channel)
{
    cUInt32 temp;
    ChalDmaDev_t *pDmaDev = (ChalDmaDev_t *)handle;
    
    do
    {
        temp = CHAL_REG_READ32(pDmaDev->baseAddr + DMAC_ENBLDCHNS_OFFSET);
    }while (temp & (0x1 << channel));
}
void chal_audio_enable_aci_auxmic( CHAL_HANDLE handle, int enable )
{
    cUInt32 regVal;
    ChalAudioCtrlBlk_t  *pCHALCb = (ChalAudioCtrlBlk_t*)handle;

    if( enable )
    {
       /* Set ACI */
       regVal = CHAL_REG_READ32((pCHALCb->aci_base+ACI_ADC_CTRL_OFFSET));
       regVal |= ACI_ADC_CTRL_AUDIORX_VREF_PWRUP_MASK;
       regVal |= ACI_ADC_CTRL_AUDIORX_BIAS_PWRUP_MASK;
       CHAL_REG_WRITE32((pCHALCb->aci_base+ACI_ADC_CTRL_OFFSET), regVal);

       /* enable AUXMIC */
       regVal = CHAL_REG_READ32((pCHALCb->auxmic_base+AUXMIC_AUXEN_OFFSET));
       regVal |= AUXMIC_AUXEN_MICAUX_EN_MASK;
       CHAL_REG_WRITE32((pCHALCb->auxmic_base+AUXMIC_AUXEN_OFFSET), regVal);

       /* Set probe cycle to continuous */
       regVal = CHAL_REG_READ32((pCHALCb->auxmic_base+AUXMIC_CMC_OFFSET));
       regVal |= AUXMIC_CMC_CONT_MSR_CTRL_MASK;
       CHAL_REG_WRITE32((pCHALCb->auxmic_base+AUXMIC_CMC_OFFSET), regVal);

       /* disable AUXMIC force power down CHAL_REG_WRITE32(0x3500E028, */
       regVal = CHAL_REG_READ32((pCHALCb->auxmic_base+AUXMIC_F_PWRDWN_OFFSET));
       regVal &= ~AUXMIC_F_PWRDWN_FORCE_PWR_DWN_MASK;
       CHAL_REG_WRITE32((pCHALCb->auxmic_base+AUXMIC_F_PWRDWN_OFFSET), regVal);
    }
    else
    {
       /* Enable AUXMIC force power down */
       regVal = CHAL_REG_READ32((pCHALCb->auxmic_base+AUXMIC_F_PWRDWN_OFFSET));
       regVal |= AUXMIC_F_PWRDWN_FORCE_PWR_DWN_MASK;
       CHAL_REG_WRITE32((pCHALCb->auxmic_base+AUXMIC_F_PWRDWN_OFFSET), regVal);

       /* Set probe cycle to discontinuous */
       regVal = CHAL_REG_READ32((pCHALCb->auxmic_base+AUXMIC_CMC_OFFSET));
       regVal &= ~AUXMIC_CMC_CONT_MSR_CTRL_MASK;
       CHAL_REG_WRITE32((pCHALCb->auxmic_base+AUXMIC_CMC_OFFSET), regVal);

       /* Disable AUXMIC */
       regVal = CHAL_REG_READ32((pCHALCb->auxmic_base+AUXMIC_AUXEN_OFFSET));
       regVal &= ~AUXMIC_AUXEN_MICAUX_EN_MASK;
       CHAL_REG_WRITE32((pCHALCb->auxmic_base+AUXMIC_AUXEN_OFFSET), regVal);

       /* Analog MIC */
       regVal = CHAL_REG_READ32((pCHALCb->aci_base+ACI_ADC_CTRL_OFFSET));
       regVal &= ~ACI_ADC_CTRL_AUDIORX_VREF_PWRUP_MASK;
       regVal &= ~ACI_ADC_CTRL_AUDIORX_BIAS_PWRUP_MASK;
       CHAL_REG_WRITE32((pCHALCb->aci_base+ACI_ADC_CTRL_OFFSET), regVal);
    }
}
void chal_audio_set_aci_auxmic_datab(CHAL_HANDLE handle,
					_Bool micOutEnable)
{
	cUInt32 regVal;
	ChalAudioCtrlBlk_t  *pCHALCb = (ChalAudioCtrlBlk_t *)handle;
	regVal = CHAL_REG_READ32((pCHALCb->aci_base+ACI_ACI_CTRL_OFFSET));
	if (micOutEnable)
		regVal |= ACI_ACI_CTRL_SW_MIC_DATAB_MASK;
	else
		regVal &= ~ACI_ACI_CTRL_SW_MIC_DATAB_MASK;
	CHAL_REG_WRITE32((pCHALCb->aci_base+ACI_ACI_CTRL_OFFSET),
					regVal);
}
//******************************************************************************
//
// Function Name:  chal_dma_shutdown_chan
//
// Description:    Terminate a DMA transfer gracefully without data lose
//
//******************************************************************************
void chal_dma_shutdown_chan(CHAL_HANDLE handle, cUInt32  channel)
{
    cUInt32 temp;
    ChalDmaDev_t *pDmaDev = (ChalDmaDev_t *)handle;
    
    //
    //  To disable a DMA channel without losing data in the FIFO:
    //  1. Set the Halt bit in the relevant channel Configuration Register.
    //     This causes any subsequent DMA requests to be ignored.
    //  2. Poll the Active bit in the relevant channel Configuration Register until 
    //     it reaches 0. This bit indicates whether there is any data in the 
    //     channel that has to be transferred.
    //  3. Clear the Channel Enable bit in the relevant channel Configuration Register.
    //
    //
    CHAL_REG_WRITE32(pDmaDev->baseAddr + DMAC_INTTCCLEAR_OFFSET, 0x1<<channel);
    CHAL_REG_WRITE32(pDmaDev->baseAddr + DMAC_INTERRCLR_OFFSET, 0x1<<channel);

    temp = CHAL_REG_READ32(pDmaDev->baseAddr+DMAC_CH0CONFIG_OFFSET 
                                       + CHAN_REG_INCREMENT * channel);
    temp |= DMAC_CH0CONFIG_H_MASK;
    CHAL_REG_WRITE32(pDmaDev->baseAddr + DMAC_CH0CONFIG_OFFSET 
                     + CHAN_REG_INCREMENT * channel, temp);

    while (temp & DMAC_CH0CONFIG_A_MASK)
    {
        temp = CHAL_REG_READ32(pDmaDev->baseAddr+DMAC_CH0CONFIG_OFFSET 
                                       + CHAN_REG_INCREMENT * channel);
    }

    temp &= ~DMAC_CH0CONFIG_E_MASK;
    CHAL_REG_WRITE32(pDmaDev->baseAddr + DMAC_CH0CONFIG_OFFSET 
                     + CHAN_REG_INCREMENT * channel, temp);
    
    chal_dma_mark_channel_inactive(handle, channel);
}
//******************************************************************************
//
// Function Name:  chal_dma_enable_dmac
//
// Description:  enable dma
//      
//******************************************************************************
void chal_dma_enable_dmac(CHAL_HANDLE handle)
{
    cUInt32 temp;
    ChalDmaDev_t *pDmaDev = (ChalDmaDev_t *)handle;
    
    temp = CHAL_REG_READ32(pDmaDev->baseAddr + DMAC_CONFIG_OFFSET);
    if (temp & DMAC_CONFIG_E_MASK)
    {
        //TRACE_Printf_Sio("Already Ensabled");
    }
    else {
        temp |= DMAC_CONFIG_E_MASK;
        CHAL_REG_WRITE32(pDmaDev->baseAddr + DMAC_CONFIG_OFFSET, temp);
    }
}
//******************************************************************************
//
// Function Name:  chal_dma_disable_dmac
//
// Description:  disable dma
//      
//******************************************************************************
void chal_dma_disable_dmac(CHAL_HANDLE handle)
{
    cUInt32 temp;
    ChalDmaDev_t *pDmaDev = (ChalDmaDev_t *)handle;
    
    temp = CHAL_REG_READ32(pDmaDev->baseAddr + DMAC_CONFIG_OFFSET); 
   
    if (!(temp & DMAC_CONFIG_E_MASK))
    {
        
    }
    else {
        temp &= ~DMAC_CONFIG_E_MASK;
        CHAL_REG_WRITE32(pDmaDev->baseAddr + DMAC_CONFIG_OFFSET, temp);
    }
}
예제 #11
0
/*
 * ******************************************************************************
 *
 *  Function Name:  chal_ipc_get_error_status
 *
 *  Description: Get ARM error status
 *
 * ******************************************************************************
 */
BCM_ERR_CODE chal_ipc_get_error_status (
    CHAL_IPC_HANDLE handle,
    uint32_t *status
    )
{
   CHAL_IPC_DEV_T *device;

   BCM_DBG_ENTER();

   device = (CHAL_IPC_DEV_T*)handle;

   *status = CHAL_REG_READ32(device->ipc_open_reg_base + IPCOPEN_IPCERR_OFFSET );

   BCM_DBG_EXIT();
   return( BCM_SUCCESS );
}
예제 #12
0
/*
 * ******************************************************************************
 *
 *  Function Name:  chal_ipc_sleep_vc
 *
 *  Description: VideoCore sleep
 *
 * ******************************************************************************
 */
BCM_ERR_CODE chal_ipc_sleep_vc (
    CHAL_IPC_HANDLE handle
    )
{
   CHAL_IPC_DEV_T *device;

   BCM_DBG_ENTER();

   device = (CHAL_IPC_DEV_T*)handle;

   CHAL_REG_WRITE32( device->ipc_secure_reg_base + IPCSEC_IPCAWAKE_OFFSET,
      CHAL_REG_READ32( device->ipc_secure_reg_base + IPCSEC_IPCAWAKE_OFFSET ) &
      ~IPCSEC_IPCAWAKE_WAKEUP_MASK );

   return BCM_SUCCESS;
}
예제 #13
0
BCM_ERR_CODE chal_ipc_query_wakeup_vc (
    CHAL_IPC_HANDLE handle,
    uint32_t *result
    )
{
   CHAL_IPC_DEV_T *device;

   BCM_DBG_ENTER();

   device = (CHAL_IPC_DEV_T*)handle;

   *result = CHAL_REG_READ32( device->ipc_secure_reg_base + IPCSEC_IPCAWAKE_OFFSET );

   BCM_DBG_EXIT();
   return( BCM_SUCCESS );
}
//******************************************************************************
//
// Function Name: chal_dma_shutdown_all_channels
//
// Description:   disable all the acitve channel and shutdown DMA controller
//
//******************************************************************************
void chal_dma_shutdown_all_channels(CHAL_HANDLE handle)
{
    cUInt32 i, temp;
    ChalDmaDev_t *pDmaDev = (ChalDmaDev_t *)handle;

    //disable all active channels
    temp = CHAL_REG_READ32(pDmaDev->baseAddr + DMAC_ENBLDCHNS_OFFSET);
    for (i=0; i < TOTAL_DMA_CHANNELS; i++)
    {
       if (temp & (0x1 << i))
       {
           chal_dma_shutdown_chan(handle,i);
           chal_dma_reset_channel(handle,i);
       }
    }

    // disable DMA controller
    chal_dma_disable_dmac(handle);
}
//******************************************************************************
//
// Function Name:  chal_dma_start_transfer
//
// Description:    Start a DMA transfer by reloading DMA registers
//
//******************************************************************************
void chal_dma_start_transfer(
    CHAL_HANDLE handle, 
    cUInt32 channel,
    cUInt32 assocChan
)
{
    cUInt32 temp;
    ChalDmaLinkNode_t *head;
    DmaChanConfig_t config;
    ChalDmaDev_t *pDmaDev = (ChalDmaDev_t *)handle;
    
    //chal_dprintf(1, "chal_dma_start_transfer, channel = %d, assocChan = %d\n", channel, assocChan);
  
    //
    // wait the channel to be free
    // You must fully initialize the channel before you enable it. Additionally, you must set the
    // Enable bit of the DMAC before you enable any channels.
    //
  
    CHAL_REG_WRITE32(pDmaDev->baseAddr + DMAC_INTTCCLEAR_OFFSET, 0x1<<channel);
    CHAL_REG_WRITE32(pDmaDev->baseAddr + DMAC_INTERRCLR_OFFSET, 0x1<<channel);
  
    do
    {
        temp = CHAL_REG_READ32(pDmaDev->baseAddr + DMAC_ENBLDCHNS_OFFSET);
    }while (temp & (0x1 << channel));
  
    if(assocChan == ASSOC_CHAN_NONE)
    {
    //
    // Mark channel active and enable DMA core 
    //
    chal_dma_mark_channel_active(handle, channel);
  
    // 
    //  1. Clear any pending interrupts on the channel you want to use.
    //     The privious channel operation might have left interrupts active.
    //  2. Write the source address into the SRC Register. 
    //  3. Write the destination address into the DEST Register. 
    //  4. Write the address of the next SRC into the NEXT Register. If the transfer 
    //     consists of a single packet of data, you must write 0 into this register.
    //  5. Write the control information into the CONTROL Register. 
    //  6. Write the channel configuration information into the CONFIG register.
    //  7. Set channel enable bit, then the DMA channel is automatically enabled.
    //
  
    head = pDmaDev->chanInfo[channel].headNode;
    }
    else
    {
        chal_dma_mark_channel_active(handle, TOTAL_DMA_CHANNELS + assocChan);
  
        head = pDmaDev->chanInfo[TOTAL_DMA_CHANNELS + assocChan].headNode;
    }
  

#if 0
    chal_dprintf(1, "chal_dma_start_transfer, head->src = 0x%x\n", head->src);
    chal_dprintf(1, "chal_dma_start_transfer, head->dst = 0x%x\n", head->dst);
    chal_dprintf(1, "chal_dma_start_transfer, head->control.DWord = 0x%x\n", head->control.DWord);
    chal_dprintf(1, "chal_dma_start_transfer, head->next = 0x%x\n", head->next);
#endif

    //
    // set up DMA for transfer
    //
    CHAL_REG_WRITE32(pDmaDev->baseAddr + DMAC_CH0CONTROL_OFFSET 
                        + CHAN_REG_INCREMENT * channel, head->control.DWord);
    CHAL_REG_WRITE32(pDmaDev->baseAddr + DMAC_CH0SRCADDR_OFFSET 
                        + CHAN_REG_INCREMENT * channel, head->src);
    CHAL_REG_WRITE32(pDmaDev->baseAddr + DMAC_CH0DESTADDR_OFFSET 
                        + CHAN_REG_INCREMENT * channel, head->dst);
    CHAL_REG_WRITE32(pDmaDev->baseAddr + DMAC_CH0LLI_OFFSET 
                        + CHAN_REG_INCREMENT * channel, head->next);

    config.DWord = CHAL_REG_READ32(pDmaDev->baseAddr+DMAC_CH0CONFIG_OFFSET 
                                       + CHAN_REG_INCREMENT * channel);

    config.ChanConfigBitField.chanEnabled = 1;

    //chal_dprintf(1, "chal_dma_start_transfer, config.DWord = 0x%x\n", config.DWord);

    CHAL_REG_WRITE32(pDmaDev->baseAddr + DMAC_CH0CONFIG_OFFSET 
                        + CHAN_REG_INCREMENT * channel, config.DWord);
}
//******************************************************************************
//
// Function Name:  chal_dma_get_channel_status
//
// Description:    Return DMAC channel status
//
//******************************************************************************
cUInt32 chal_dma_get_channel_status(CHAL_HANDLE handle)
{
    ChalDmaDev_t *pDmaDev = (ChalDmaDev_t *)handle;

    return CHAL_REG_READ32(pDmaDev->baseAddr + DMAC_ENBLDCHNS_OFFSET);
}
예제 #17
0
/*
 * ===========================================================================
 *
 *   Function Name: chal_memc_ddr3_get_clock_speed
 *
 *   Description:
 *       Get the current DDR3 clock speed in hz
 *
 * ===========================================================================
 */
MEMC_EXPORT BCM_ERR_CODE chal_memc_ddr3_get_clock_speed (
    void* generic_hdl,
    uint32_t *clock_speed_hz
)
{
    CHAL_MEMC_HANDLE handle = (CHAL_MEMC_HANDLE)generic_hdl;
    uint32_t  ddr3_ctl_base_addr;
    uint32_t  rdvalue;
    MEMC_MDIV_T  mdiv;
    uint32_t  mdiv_val;
    uint32_t  pdiv;
    uint32_t  pdiv_val;
    uint32_t  ndiv_int;
    uint32_t  ndiv_frac;
    uint32_t  xtal_freq;

    ddr3_ctl_base_addr = handle->memc_open_ddr3_ctl_base;

    if (handle->operation_mode == MEMC_OP_MODE_ASIC)
    {
       switch ( chipregHw_getStrapXtalType() )
       {
          case chipregHw_STRAP_XTAL_TYPE_13MHZ :
          {
             xtal_freq = 13*1000*1000;
             break;
          }
          case chipregHw_STRAP_XTAL_TYPE_26MHZ:
          {
            xtal_freq = 26*1000*1000;
            break;
          }
          case chipregHw_STRAP_XTAL_TYPE_19p2MHZ:
          {
            xtal_freq = 19200000;
            break;
          }
          case chipregHw_STRAP_XTAL_TYPE_38p4MHZ:
          {
            xtal_freq = 38400000;
            break;
          }
          default:
          {
             BCM_DBG_ERR (("Unsupported XTAL strap\n" ));
             *clock_speed_hz = 0;
             return (BCM_ERROR);
          }
       }

       rdvalue = CHAL_REG_READ32( ddr3_ctl_base_addr + DDR3CTL_PLL_CTL6_OFFSET );
       ndiv_int = (rdvalue & DDR3CTL_PLL_CTL6_PLL_NDIV_INT_MASK) >> DDR3CTL_PLL_CTL6_PLL_NDIV_INT_SHIFT;
       ndiv_frac = (rdvalue & DDR3CTL_PLL_CTL6_PLL_NDIV_FRAC_MASK) >> DDR3CTL_PLL_CTL6_PLL_NDIV_FRAC_SHIFT;

       rdvalue = CHAL_REG_READ32( ddr3_ctl_base_addr + DDR3CTL_PLL_CTL7_OFFSET );
       pdiv = (rdvalue & DDR3CTL_PLL_CTL7_PLL_PDIV_MASK) >> DDR3CTL_PLL_CTL7_PLL_PDIV_SHIFT;
       pdiv_val = ((pdiv == 0) ? 8 : pdiv);

       rdvalue = CHAL_REG_READ32( ddr3_ctl_base_addr + DDR3CTL_PLL_CTL2_OFFSET );
       mdiv = (rdvalue & DDR3CTL_PLL_CTL2_PLL_CH0_MDIV_MASK) >> DDR3CTL_PLL_CTL2_PLL_CH0_MDIV_SHIFT;
       mdiv_val = ((mdiv == 0) ? 256 : mdiv);

       /* Store the configured DDR clock speed */
       handle->mem_device_ddr3.dev_info.ddr_speed_hz = ((xtal_freq*ndiv_int)/pdiv_val + ((uint32_t)((xtal_freq*(uint64_t)ndiv_frac)>>20))/pdiv_val) / mdiv_val ;
    }
    else
    {
//******************************************************************************
//
// Function Name: chal_dma_config_channel
//
// Description:   Config a dma channel, i.e, in this case channel config reg
//
//******************************************************************************
cUInt32 chal_dma_config_channel(
    CHAL_HANDLE handle, 
    cUInt32 chan, 
    cUInt32 assocChan, 
    ChalDmaChanConfig_t *pConfig
)
{
    DmaChanConfig_t chanConfig;
    cUInt32 bandRequested;
    cUInt32 i, j, k, configChan;
    ChalDmaDev_t *pDmaDev = (ChalDmaDev_t *)handle;
        
    chal_dma_enable_dmac(handle);
    chal_dma_reset_channel(handle, chan);

    chanConfig.DWord = CHAL_REG_READ32(pDmaDev->baseAddr+DMAC_CH0CONFIG_OFFSET 
                                       + CHAN_REG_INCREMENT * chan);

    chanConfig.ChanConfigBitField.locked = pConfig->locked;
    chanConfig.ChanConfigBitField.tcIntMask = pConfig->tcIntMask;
    chanConfig.ChanConfigBitField.errIntMask = pConfig->errIntMask;
    chanConfig.ChanConfigBitField.flowCtrl = pConfig->flowCtrl;
    chanConfig.ChanConfigBitField.dstPeripheral = pConfig->dstPeripheral;
    chanConfig.ChanConfigBitField.srcPeripheral = pConfig->srcPeripheral;
 
    CHAL_REG_WRITE32(pDmaDev->baseAddr + DMAC_CH0CONFIG_OFFSET 
                     + CHAN_REG_INCREMENT * chan, chanConfig.DWord);

//    chal_dma_disable_dmac(handle);

    if(assocChan == ASSOC_CHAN_NONE)
    {
        configChan = chan;
    }
    else
    {
        configChan = TOTAL_DMA_CHANNELS + assocChan;
    }

    //allocate pre-allocated node
    if(pDmaDev->chanInfo[configChan].bUsed == TRUE)
    {
        pDmaDev->chanInfo[configChan].bandNum = 0;
        bandRequested = pConfig->nodeNumRequested/pDmaDev->nodeNumPerBand + 1; //always allocate at least a band 
        for(i=0;i<bandRequested;i++)
        {
            for(j=0;j<LLI_NODE_BAND_NUM; j++)
            {
               
                if(pDmaDev->LLIBand[j].bUsed == FALSE) //free band
                {
                    pDmaDev->chanInfo[configChan].chanNodeBand[i] = &pDmaDev->LLIBand[j]; //reserve the band
                    pDmaDev->chanInfo[configChan].bandNum ++;
                    pDmaDev->LLIBand[j].bUsed = TRUE; //mark it
                    break;
                }
            }
            if(j==LLI_NODE_BAND_NUM) //no more LLI node available
            {
                for(k=0;k<pDmaDev->chanInfo[configChan].bandNum;k++)
                {
                    pDmaDev->chanInfo[configChan].chanNodeBand[k]->bUsed = FALSE;
                    
                }
                pDmaDev->chanInfo[configChan].bandNum = 0; //reset count
	        	pr_err("%s - exceeded available LLI's\n", __func__);
                return 0;
            }
        }
                    
    } 
    return 1;
}