/******************************************************************************* * mvDmaCommandSet - Set command to DMA channel * * DESCRIPTION: * DMA channel can be started, idel, paused and restarted. * Paused can be set only if channel is active. * Start can be set only if channel is idle. * Restart can be set only if channel is paused. * Stop activate the channel abort which cause the DMA to aborts in the * middle of a transaction. * * INPUT: * chan - IDMA channel number. See MV_DMA_CHANNEL enumerator. * command - Requested command. See MV_COMMAND enumerator. * * OUTPUT: * None. * * RETURN: * MV_ERROR if requested command can not be set. * *******************************************************************************/ MV_STATUS mvDmaCommandSet(MV_U32 chan, MV_COMMAND command) { MV_U32 ctrlLow; MV_U32 dmaStatus; /* Read control low register */ ctrlLow = MV_REG_READ(IDMA_CTRL_LOW_REG(chan)); /* Get current DMA status */ dmaStatus = mvDmaStateGet(chan); if ((command == MV_START) && (dmaStatus == MV_IDLE)) { /* To start, set DMA channel enable bit */ ctrlLow |= ICCLR_CHAN_ENABLE; } else if ((command == MV_PAUSE) && (dmaStatus == MV_ACTIVE)) { /* To pause, reset DMA channel enable bit */ ctrlLow &= ~ICCLR_CHAN_ENABLE; } else if ((command == MV_RESTART) && (dmaStatus == MV_PAUSED)) { /* To restart, set DMA channel enable bit */ ctrlLow |= ICCLR_CHAN_ENABLE; } else if (command == MV_STOP) { /* To stop, set DMA channel abort bit */ ctrlLow |= ICCLR_CHANNEL_ABORT; } else { DB(mvOsPrintf("mvDmaCommandSet: ERR. Can not set command %d in \ status %d\n", command, dmaStatus)); return MV_ERROR; } /* Write control word to register */ MV_REG_WRITE(IDMA_CTRL_LOW_REG(chan), ctrlLow); /* If comman is stop, ensure channel is stopped */ if (command == MV_STOP) { while(MV_IDLE != mvDmaStateGet(chan)); } return MV_OK; }
unsigned int wait_for_idma(MV_U32 channel) { u32 timeout = 0; /* wait for completion */ while( mvDmaStateGet(channel) != MV_IDLE ) { DPRINTK(" ctrl low is %x \n", MV_REG_READ(IDMA_CTRL_LOW_REG(channel))); //udelay(1); #ifdef RT_DEBUG dma_wait_loops++; #endif if(timeout++ > CPY_DMA_TIMEOUT) { printk("dma_copy: IDMA %d timed out , ctrl low is %x \n", channel, MV_REG_READ(IDMA_CTRL_LOW_REG(channel))); return 1; } } DPRINTK("IDMA complete in %x \n", timeout); return 0; }