예제 #1
0
void dmacHw_initiateTransfer(dmacHw_HANDLE_t handle,	
			     dmacHw_CONFIG_t *pConfig,	
			     void *pDescriptor	
    ) {
	dmacHw_DESC_RING_t *pRing;
	dmacHw_DESC_t *pProg;
	dmacHw_CBLK_t *pCblk;

	pCblk = dmacHw_HANDLE_TO_CBLK(handle);
	pRing = dmacHw_GET_DESC_RING(pDescriptor);

	if (CHANNEL_BUSY(pCblk->module, pCblk->channel)) {
		
		return;
	}

	if (pCblk->varDataStarted) {
		if (pCblk->descUpdated) {
			pCblk->descUpdated = 0;
			pProg =
			    (dmacHw_DESC_t *) ((uint32_t)
					       dmacHw_REG_LLP(pCblk->module,
							      pCblk->channel) +
					       pRing->virt2PhyOffset);

			
			if (!(pProg->ctl.hi & dmacHw_REG_CTL_DONE)) {
				dmacHw_SET_SAR(pCblk->module, pCblk->channel,
					       pProg->sar);
				dmacHw_SET_DAR(pCblk->module, pCblk->channel,
					       pProg->dar);
				dmacHw_REG_CTL_LO(pCblk->module,
						  pCblk->channel) =
				    pProg->ctl.lo;
				dmacHw_REG_CTL_HI(pCblk->module,
						  pCblk->channel) =
				    pProg->ctl.hi;
			} else if (pProg == (dmacHw_DESC_t *) pRing->pEnd->llp) {
				
				return;
			} else {
				dmacHw_ASSERT(0);
			}
		} else {
			return;
		}
	} else {
		if (pConfig->transferMode == dmacHw_TRANSFER_MODE_PERIODIC) {
			
			pProg = pRing->pHead;
			
			dmacHw_NEXT_DESC(pRing, pHead);
		} else {
			
			if (pRing->pEnd == NULL) {
				return;
			}

			pProg = pRing->pProg;
			if (pConfig->transferMode ==
			    dmacHw_TRANSFER_MODE_CONTINUOUS) {
				
				dmacHw_ASSERT((dmacHw_DESC_t *) pRing->pEnd->
					      llp == pRing->pProg);
				
				dmacHw_ASSERT((dmacHw_DESC_t *) pRing->pProg ==
					      pRing->pHead);
				
				do {
					pRing->pProg->ctl.lo |=
					    (dmacHw_REG_CTL_LLP_DST_EN |
					     dmacHw_REG_CTL_LLP_SRC_EN);
					pRing->pProg =
					    (dmacHw_DESC_t *) pRing->pProg->llp;
				} while (pRing->pProg != pRing->pHead);
			} else {
				
				while (pRing->pProg != pRing->pEnd) {
					pRing->pProg->ctl.lo |=
					    (dmacHw_REG_CTL_LLP_DST_EN |
					     dmacHw_REG_CTL_LLP_SRC_EN);
					pRing->pProg =
					    (dmacHw_DESC_t *) pRing->pProg->llp;
				}
			}
		}

		
		dmacHw_SET_SAR(pCblk->module, pCblk->channel, pProg->sar);
		dmacHw_SET_DAR(pCblk->module, pCblk->channel, pProg->dar);
		dmacHw_SET_LLP(pCblk->module, pCblk->channel,
			       (uint32_t) pProg - pRing->virt2PhyOffset);
		dmacHw_REG_CTL_LO(pCblk->module, pCblk->channel) =
		    pProg->ctl.lo;
		dmacHw_REG_CTL_HI(pCblk->module, pCblk->channel) =
		    pProg->ctl.hi;
		if (pRing->pEnd) {
			
			pRing->pProg = (dmacHw_DESC_t *) pRing->pEnd->llp;
		}
		
		pRing->pEnd = (dmacHw_DESC_t *) NULL;
	}
	
	dmacHw_DMA_START(pCblk->module, pCblk->channel);
}
예제 #2
0
static void DisplayRegisterContents(int module,	/*   [ IN ] DMA Controller unit  (0-1) */
				    int channel,	/*   [ IN ] DMA Channel          (0-7) / -1(all) */
				    int (*fpPrint) (const char *, ...)	/*   [ IN ] Callback to the print function */
    ) {
	int chan;

	(*fpPrint) ("Displaying register content \n\n");
	(*fpPrint) ("Module %d: Interrupt raw transfer              0x%X\n",
		    module, (uint32_t) (dmacHw_REG_INT_RAW_TRAN(module)));
	(*fpPrint) ("Module %d: Interrupt raw block                 0x%X\n",
		    module, (uint32_t) (dmacHw_REG_INT_RAW_BLOCK(module)));
	(*fpPrint) ("Module %d: Interrupt raw src transfer          0x%X\n",
		    module, (uint32_t) (dmacHw_REG_INT_RAW_STRAN(module)));
	(*fpPrint) ("Module %d: Interrupt raw dst transfer          0x%X\n",
		    module, (uint32_t) (dmacHw_REG_INT_RAW_DTRAN(module)));
	(*fpPrint) ("Module %d: Interrupt raw error                 0x%X\n",
		    module, (uint32_t) (dmacHw_REG_INT_RAW_ERROR(module)));
	(*fpPrint) ("--------------------------------------------------\n");
	(*fpPrint) ("Module %d: Interrupt stat transfer             0x%X\n",
		    module, (uint32_t) (dmacHw_REG_INT_STAT_TRAN(module)));
	(*fpPrint) ("Module %d: Interrupt stat block                0x%X\n",
		    module, (uint32_t) (dmacHw_REG_INT_STAT_BLOCK(module)));
	(*fpPrint) ("Module %d: Interrupt stat src transfer         0x%X\n",
		    module, (uint32_t) (dmacHw_REG_INT_STAT_STRAN(module)));
	(*fpPrint) ("Module %d: Interrupt stat dst transfer         0x%X\n",
		    module, (uint32_t) (dmacHw_REG_INT_STAT_DTRAN(module)));
	(*fpPrint) ("Module %d: Interrupt stat error                0x%X\n",
		    module, (uint32_t) (dmacHw_REG_INT_STAT_ERROR(module)));
	(*fpPrint) ("--------------------------------------------------\n");
	(*fpPrint) ("Module %d: Interrupt mask transfer             0x%X\n",
		    module, (uint32_t) (dmacHw_REG_INT_MASK_TRAN(module)));
	(*fpPrint) ("Module %d: Interrupt mask block                0x%X\n",
		    module, (uint32_t) (dmacHw_REG_INT_MASK_BLOCK(module)));
	(*fpPrint) ("Module %d: Interrupt mask src transfer         0x%X\n",
		    module, (uint32_t) (dmacHw_REG_INT_MASK_STRAN(module)));
	(*fpPrint) ("Module %d: Interrupt mask dst transfer         0x%X\n",
		    module, (uint32_t) (dmacHw_REG_INT_MASK_DTRAN(module)));
	(*fpPrint) ("Module %d: Interrupt mask error                0x%X\n",
		    module, (uint32_t) (dmacHw_REG_INT_MASK_ERROR(module)));
	(*fpPrint) ("--------------------------------------------------\n");
	(*fpPrint) ("Module %d: Interrupt clear transfer            0x%X\n",
		    module, (uint32_t) (dmacHw_REG_INT_CLEAR_TRAN(module)));
	(*fpPrint) ("Module %d: Interrupt clear block               0x%X\n",
		    module, (uint32_t) (dmacHw_REG_INT_CLEAR_BLOCK(module)));
	(*fpPrint) ("Module %d: Interrupt clear src transfer        0x%X\n",
		    module, (uint32_t) (dmacHw_REG_INT_CLEAR_STRAN(module)));
	(*fpPrint) ("Module %d: Interrupt clear dst transfer        0x%X\n",
		    module, (uint32_t) (dmacHw_REG_INT_CLEAR_DTRAN(module)));
	(*fpPrint) ("Module %d: Interrupt clear error               0x%X\n",
		    module, (uint32_t) (dmacHw_REG_INT_CLEAR_ERROR(module)));
	(*fpPrint) ("--------------------------------------------------\n");
	(*fpPrint) ("Module %d: SW source req                       0x%X\n",
		    module, (uint32_t) (dmacHw_REG_SW_HS_SRC_REQ(module)));
	(*fpPrint) ("Module %d: SW dest req                         0x%X\n",
		    module, (uint32_t) (dmacHw_REG_SW_HS_DST_REQ(module)));
	(*fpPrint) ("Module %d: SW source signal                    0x%X\n",
		    module, (uint32_t) (dmacHw_REG_SW_HS_SRC_SGL_REQ(module)));
	(*fpPrint) ("Module %d: SW dest signal                      0x%X\n",
		    module, (uint32_t) (dmacHw_REG_SW_HS_DST_SGL_REQ(module)));
	(*fpPrint) ("Module %d: SW source last                      0x%X\n",
		    module, (uint32_t) (dmacHw_REG_SW_HS_SRC_LST_REQ(module)));
	(*fpPrint) ("Module %d: SW dest last                        0x%X\n",
		    module, (uint32_t) (dmacHw_REG_SW_HS_DST_LST_REQ(module)));
	(*fpPrint) ("--------------------------------------------------\n");
	(*fpPrint) ("Module %d: misc config                         0x%X\n",
		    module, (uint32_t) (dmacHw_REG_MISC_CFG(module)));
	(*fpPrint) ("Module %d: misc channel enable                 0x%X\n",
		    module, (uint32_t) (dmacHw_REG_MISC_CH_ENABLE(module)));
	(*fpPrint) ("Module %d: misc ID                             0x%X\n",
		    module, (uint32_t) (dmacHw_REG_MISC_ID(module)));
	(*fpPrint) ("Module %d: misc test                           0x%X\n",
		    module, (uint32_t) (dmacHw_REG_MISC_TEST(module)));

	if (channel == -1) {
		for (chan = 0; chan < 8; chan++) {
			(*fpPrint)
			    ("--------------------------------------------------\n");
			(*fpPrint)
			    ("Module %d: Channel %d Source                   0x%X\n",
			     module, chan,
			     (uint32_t) (dmacHw_REG_SAR(module, chan)));
			(*fpPrint)
			    ("Module %d: Channel %d Destination              0x%X\n",
			     module, chan,
			     (uint32_t) (dmacHw_REG_DAR(module, chan)));
			(*fpPrint)
			    ("Module %d: Channel %d LLP                      0x%X\n",
			     module, chan,
			     (uint32_t) (dmacHw_REG_LLP(module, chan)));
			(*fpPrint)
			    ("Module %d: Channel %d Control (LO)             0x%X\n",
			     module, chan,
			     (uint32_t) (dmacHw_REG_CTL_LO(module, chan)));
			(*fpPrint)
			    ("Module %d: Channel %d Control (HI)             0x%X\n",
			     module, chan,
			     (uint32_t) (dmacHw_REG_CTL_HI(module, chan)));
			(*fpPrint)
			    ("Module %d: Channel %d Source Stats             0x%X\n",
			     module, chan,
			     (uint32_t) (dmacHw_REG_SSTAT(module, chan)));
			(*fpPrint)
			    ("Module %d: Channel %d Dest Stats               0x%X\n",
			     module, chan,
			     (uint32_t) (dmacHw_REG_DSTAT(module, chan)));
			(*fpPrint)
			    ("Module %d: Channel %d Source Stats Addr        0x%X\n",
			     module, chan,
			     (uint32_t) (dmacHw_REG_SSTATAR(module, chan)));
			(*fpPrint)
			    ("Module %d: Channel %d Dest Stats Addr          0x%X\n",
			     module, chan,
			     (uint32_t) (dmacHw_REG_DSTATAR(module, chan)));
			(*fpPrint)
			    ("Module %d: Channel %d Config (LO)              0x%X\n",
			     module, chan,
			     (uint32_t) (dmacHw_REG_CFG_LO(module, chan)));
			(*fpPrint)
			    ("Module %d: Channel %d Config (HI)              0x%X\n",
			     module, chan,
			     (uint32_t) (dmacHw_REG_CFG_HI(module, chan)));
		}
	} else {
		chan = channel;
		(*fpPrint)
		    ("--------------------------------------------------\n");
		(*fpPrint)
		    ("Module %d: Channel %d Source                   0x%X\n",
		     module, chan, (uint32_t) (dmacHw_REG_SAR(module, chan)));
		(*fpPrint)
		    ("Module %d: Channel %d Destination              0x%X\n",
		     module, chan, (uint32_t) (dmacHw_REG_DAR(module, chan)));
		(*fpPrint)
		    ("Module %d: Channel %d LLP                      0x%X\n",
		     module, chan, (uint32_t) (dmacHw_REG_LLP(module, chan)));
		(*fpPrint)
		    ("Module %d: Channel %d Control (LO)             0x%X\n",
		     module, chan,
		     (uint32_t) (dmacHw_REG_CTL_LO(module, chan)));
		(*fpPrint)
		    ("Module %d: Channel %d Control (HI)             0x%X\n",
		     module, chan,
		     (uint32_t) (dmacHw_REG_CTL_HI(module, chan)));
		(*fpPrint)
		    ("Module %d: Channel %d Source Stats             0x%X\n",
		     module, chan, (uint32_t) (dmacHw_REG_SSTAT(module, chan)));
		(*fpPrint)
		    ("Module %d: Channel %d Dest Stats               0x%X\n",
		     module, chan, (uint32_t) (dmacHw_REG_DSTAT(module, chan)));
		(*fpPrint)
		    ("Module %d: Channel %d Source Stats Addr        0x%X\n",
		     module, chan,
		     (uint32_t) (dmacHw_REG_SSTATAR(module, chan)));
		(*fpPrint)
		    ("Module %d: Channel %d Dest Stats Addr          0x%X\n",
		     module, chan,
		     (uint32_t) (dmacHw_REG_DSTATAR(module, chan)));
		(*fpPrint)
		    ("Module %d: Channel %d Config (LO)              0x%X\n",
		     module, chan,
		     (uint32_t) (dmacHw_REG_CFG_LO(module, chan)));
		(*fpPrint)
		    ("Module %d: Channel %d Config (HI)              0x%X\n",
		     module, chan,
		     (uint32_t) (dmacHw_REG_CFG_HI(module, chan)));
	}
}
예제 #3
0
파일: dmacHw.c 프로젝트: BinVul/linux2.6.32
void dmacHw_initiateTransfer(dmacHw_HANDLE_t handle,	/*   [ IN ] DMA Channel handle */
			     dmacHw_CONFIG_t *pConfig,	/*   [ IN ] Configuration settings */
			     void *pDescriptor	/*   [ IN ] Descriptor buffer */
    ) {
	dmacHw_DESC_RING_t *pRing;
	dmacHw_DESC_t *pProg;
	dmacHw_CBLK_t *pCblk;

	pCblk = dmacHw_HANDLE_TO_CBLK(handle);
	pRing = dmacHw_GET_DESC_RING(pDescriptor);

	if (CHANNEL_BUSY(pCblk->module, pCblk->channel)) {
		/* Not safe yet to program the channel */
		return;
	}

	if (pCblk->varDataStarted) {
		if (pCblk->descUpdated) {
			pCblk->descUpdated = 0;
			pProg =
			    (dmacHw_DESC_t *) ((uint32_t)
					       dmacHw_REG_LLP(pCblk->module,
							      pCblk->channel) +
					       pRing->virt2PhyOffset);

			/* Load descriptor if not loaded */
			if (!(pProg->ctl.hi & dmacHw_REG_CTL_DONE)) {
				dmacHw_SET_SAR(pCblk->module, pCblk->channel,
					       pProg->sar);
				dmacHw_SET_DAR(pCblk->module, pCblk->channel,
					       pProg->dar);
				dmacHw_REG_CTL_LO(pCblk->module,
						  pCblk->channel) =
				    pProg->ctl.lo;
				dmacHw_REG_CTL_HI(pCblk->module,
						  pCblk->channel) =
				    pProg->ctl.hi;
			} else if (pProg == (dmacHw_DESC_t *) pRing->pEnd->llp) {
				/* Return as end descriptor is processed */
				return;
			} else {
				dmacHw_ASSERT(0);
			}
		} else {
			return;
		}
	} else {
		if (pConfig->transferMode == dmacHw_TRANSFER_MODE_PERIODIC) {
			/* Do not make a single chain, rather process one descriptor at a time */
			pProg = pRing->pHead;
			/* Point to the next descriptor for next iteration */
			dmacHw_NEXT_DESC(pRing, pHead);
		} else {
			/* Return if no more pending descriptor */
			if (pRing->pEnd == NULL) {
				return;
			}

			pProg = pRing->pProg;
			if (pConfig->transferMode ==
			    dmacHw_TRANSFER_MODE_CONTINUOUS) {
				/* Make sure a complete ring can be formed */
				dmacHw_ASSERT((dmacHw_DESC_t *) pRing->pEnd->
					      llp == pRing->pProg);
				/* Make sure pProg pointing to the pHead */
				dmacHw_ASSERT((dmacHw_DESC_t *) pRing->pProg ==
					      pRing->pHead);
				/* Make a complete ring */
				do {
					pRing->pProg->ctl.lo |=
					    (dmacHw_REG_CTL_LLP_DST_EN |
					     dmacHw_REG_CTL_LLP_SRC_EN);
					pRing->pProg =
					    (dmacHw_DESC_t *) pRing->pProg->llp;
				} while (pRing->pProg != pRing->pHead);
			} else {
				/* Make a single long chain */
				while (pRing->pProg != pRing->pEnd) {
					pRing->pProg->ctl.lo |=
					    (dmacHw_REG_CTL_LLP_DST_EN |
					     dmacHw_REG_CTL_LLP_SRC_EN);
					pRing->pProg =
					    (dmacHw_DESC_t *) pRing->pProg->llp;
				}
			}
		}

		/* Program the channel registers */
		dmacHw_SET_SAR(pCblk->module, pCblk->channel, pProg->sar);
		dmacHw_SET_DAR(pCblk->module, pCblk->channel, pProg->dar);
		dmacHw_SET_LLP(pCblk->module, pCblk->channel,
			       (uint32_t) pProg - pRing->virt2PhyOffset);
		dmacHw_REG_CTL_LO(pCblk->module, pCblk->channel) =
		    pProg->ctl.lo;
		dmacHw_REG_CTL_HI(pCblk->module, pCblk->channel) =
		    pProg->ctl.hi;
		if (pRing->pEnd) {
			/* Remember the descriptor to use next */
			pRing->pProg = (dmacHw_DESC_t *) pRing->pEnd->llp;
		}
		/* Indicate no more pending descriptor  */
		pRing->pEnd = (dmacHw_DESC_t *) NULL;
	}
	/* Start DMA operation */
	dmacHw_DMA_START(pCblk->module, pCblk->channel);
}