Post Go back to editing

SHARC Linkport driver with DMA

Thread Summary

The user is trying to configure a DMA operation using a TCB list in CCES 2.10.1 with the LinkPort device driver, aiming to receive a single interrupt at the end of the list. The current driver design requires an interrupt for each TCB, which prevents the desired operation. The development team will consider this use case for future updates, but for now, the user should enable interrupts for all TCBs.
AI Generated Content

I am trying to use the linkport device driver in CCES 2.10.1 to configure a DMA operation using a TCB list. There are 5 TCBs in the list.

I configure the list so that that first 4 TCBs do _not_ request an interrupt when the XCNT is complete, and I configure the last TCB so it _does_ request an interrupt. What I am trying to do is let the DMA handle the entire list without any core involvement and then get a single interrupt when the entire list is complete. I think the hardware supports this style of operation but it appears the device driver requires an interrupt during every TCB.

If I only set the configuration for the last TCB to ENUM_DMA_CFG_XCNT_INT then I get one interrupt the first time I call adi_linkport_DMATransfer(..) but the next time I call the operation does not succeed. If I set ENUM_DMA_CFG_XCNT in every TCB everything works great but an interrupt is generated for every TCB in the list, and I don't need or want that.

My call is adi_linkport_DMATransfer(hDevice, (ADI_PDMA_DESC_LIST*) DescList, 5, ADI_PDMA_DESCRIPTOR_LIST);

Has anyone succeed with using the linkport driver with TCB list where only the last TCB interrupts? Does anyone in ADI know the driver well enough to say if this is possible. I have tried reading the driver code but I may be missing something.

Thread Notes

Parents
  • Hi,

    We are looking into this case now. We will get back to you soon.

    Best Regards,

    Santhakumari.K

  • Hi,

    We checked with our Development team. They said that the driver module has been designed in this way to provide an interrupt to core at the end of each descriptor transaction to notify the user that buffer is ready for processing.

    Please let us know if you have further clarifications.

    Best Regards,
    Santhakumari.K

  • Hi Santhakumari,

    Thank you for your answer. I believe the hardware supports having each TCB decide whether or not to cause an interrupt and I think this is a good option to support. However that's just my opinion and I appreciate the development team may think otherwise. I just wanted to make sure I wasn't missing some trick. 

    Again, thanks.

  • Hi,

    Yes, the hardware has no restrictions, and it is our software that we have developed we have taken up the model of Non blocking mode in DMA with interrupt raised for every descriptor. We will definitely think about this use case of disabling interrupt for descriptors other than the last one but as of now the model is designed in such a way that the interrupt has to be enabled for all the descriptors.

    We will look into it based on your feedback and if there is scope to update the drivers we will try to incorporate and let you know. This won’t be an immediate change so we would request you to enable interrupts for all the descriptors as of now and proceed ahead.

    Best Regards,
    Santhakumari.K

  • Hi, Santhakumari, do you have any updates for this issue?  Our application directly use ADI driver adi_linkport_2156x.c/h, we encounter some issue, to fix it, it's better enable interrupt only at the end of the descriptor list.

    Thanks.

  • Hi,

    Apologies for the delay caused.

    We have been reviewing this issue for debug. As discussed earlier, we had evaluated the statement:
    pDevice->pChannel->bProgress = true;
    and concluded that it can be removed to allow the application greater flexibility in submitting buffers as needed.
    We have now verified that removing this line from the adi_linkport_DMATransfer API resolves the issue. We are tentatively planning to remove this statement from the driver code, pending a final discussion.

    We will further analyze the potential side effects and overall impact of this change, and we will get back to you with a conclusive update by next week.

    Best Regards,
    Santhakumari.V

  • Hi, Thanks for your answer. For my side, I directly only trigger XCNT interrupt at the end of descriptor list. But your code only consider trigger at every TCB transfer finished. For my side, I directly delete the related code at CommonDMAHandler:

    /* Common DMA Handler */
    static void CommonDMAHandler(
    							ADI_LINKPORT_INFO *pInfo,
    							ADI_LINKPORT_CHANNEL *pChannel,
    							ADI_PDMA_REGS *pPDMAReg
    							)
    {
    	ADI_LINKPORT_DEVICE  *pDevice = pInfo->pDevice;
    	ADI_PDMA_DESC_LIST *pActualList = pChannel->pList;
    
    	uint32_t iStatTemp =  pInfo->pLPDMARegs->Status;
    
    	uint32_t iConfig = pPDMAReg->Config;
    
    	if((iStatTemp & (uint32_t)(BITM_DMA_STAT_IRQDONE))== ENUM_DMA_STAT_IRQDONE)
    	{
    		/*Clear the IRQDONE bit of the DMA status register*/
    		pInfo->pLPDMARegs->Status |= ENUM_DMA_STAT_IRQDONE;
    	}
    	if((iStatTemp & (uint32_t)(BITM_DMA_STAT_PIRQ))== ENUM_DMA_STAT_PIRQ)
    	{
    		/*Clear the PIRQ bit of the DMA status register*/
    		pInfo->pLPDMARegs->Status |= ENUM_DMA_STAT_PIRQ;
    	}
    
    	pDevice->pChannel->nIndex++;
       /* Check if it is the last descriptor */
    	//if((pChannel->nIndex == pChannel->nSize) && ((iConfig & BITM_DMA_CFG_FLOW) != ENUM_DMA_CFG_AUTO))
    	if((iConfig & BITM_DMA_CFG_FLOW) != ENUM_DMA_CFG_AUTO)

Reply
  • Hi, Thanks for your answer. For my side, I directly only trigger XCNT interrupt at the end of descriptor list. But your code only consider trigger at every TCB transfer finished. For my side, I directly delete the related code at CommonDMAHandler:

    /* Common DMA Handler */
    static void CommonDMAHandler(
    							ADI_LINKPORT_INFO *pInfo,
    							ADI_LINKPORT_CHANNEL *pChannel,
    							ADI_PDMA_REGS *pPDMAReg
    							)
    {
    	ADI_LINKPORT_DEVICE  *pDevice = pInfo->pDevice;
    	ADI_PDMA_DESC_LIST *pActualList = pChannel->pList;
    
    	uint32_t iStatTemp =  pInfo->pLPDMARegs->Status;
    
    	uint32_t iConfig = pPDMAReg->Config;
    
    	if((iStatTemp & (uint32_t)(BITM_DMA_STAT_IRQDONE))== ENUM_DMA_STAT_IRQDONE)
    	{
    		/*Clear the IRQDONE bit of the DMA status register*/
    		pInfo->pLPDMARegs->Status |= ENUM_DMA_STAT_IRQDONE;
    	}
    	if((iStatTemp & (uint32_t)(BITM_DMA_STAT_PIRQ))== ENUM_DMA_STAT_PIRQ)
    	{
    		/*Clear the PIRQ bit of the DMA status register*/
    		pInfo->pLPDMARegs->Status |= ENUM_DMA_STAT_PIRQ;
    	}
    
    	pDevice->pChannel->nIndex++;
       /* Check if it is the last descriptor */
    	//if((pChannel->nIndex == pChannel->nSize) && ((iConfig & BITM_DMA_CFG_FLOW) != ENUM_DMA_CFG_AUTO))
    	if((iConfig & BITM_DMA_CFG_FLOW) != ENUM_DMA_CFG_AUTO)

Children