/************ DEBUG ***********/ MV_VOID mvIdmaRegs(MV_U32 chan) { mvOsPrintf("\t IDMA #%d Registers:\n", chan); mvOsPrintf("IDMA_BYTE_COUNT_REG : 0x%X = 0x%08x\n", IDMA_BYTE_COUNT_REG(chan), MV_REG_READ(IDMA_BYTE_COUNT_REG(chan))); mvOsPrintf("IDMA_SRC_ADDR_REG : 0x%X = 0x%08x\n", IDMA_SRC_ADDR_REG(chan), MV_REG_READ(IDMA_SRC_ADDR_REG(chan))); mvOsPrintf("IDMA_DST_ADDR_REG : 0x%X = 0x%08x\n", IDMA_DST_ADDR_REG(chan), MV_REG_READ(IDMA_DST_ADDR_REG(chan))); mvOsPrintf("IDMA_NEXT_DESC_PTR_REG : 0x%X = 0x%08x\n", IDMA_NEXT_DESC_PTR_REG(chan), MV_REG_READ(IDMA_NEXT_DESC_PTR_REG(chan))); mvOsPrintf("IDMA_CURR_DESC_PTR_REG : 0x%X = 0x%08x\n", IDMA_CURR_DESC_PTR_REG(chan), MV_REG_READ(IDMA_CURR_DESC_PTR_REG(chan))); mvOsPrintf("IDMA_CTRL_LOW_REG : 0x%X = 0x%08x\n", IDMA_CTRL_LOW_REG(chan), MV_REG_READ(IDMA_CTRL_LOW_REG(chan))); mvOsPrintf("IDMA_CTRL_HIGH_REG : 0x%X = 0x%08x\n", IDMA_CTRL_HIGH_REG(chan), MV_REG_READ(IDMA_CTRL_HIGH_REG(chan))); mvOsPrintf("IDMA_CAUSE_REG : 0x%X = 0x%08x\n", IDMA_CAUSE_REG, MV_REG_READ(IDMA_CAUSE_REG)); mvOsPrintf("IDMA_MASK_REG : 0x%X = 0x%08x\n", IDMA_MASK_REG, MV_REG_READ(IDMA_MASK_REG)); }
int mv_dma_init(void) { #if defined(CONFIG_MV78200) || defined(CONFIG_MV632X) if (MV_FALSE == mvSocUnitIsMappedToThisCpu(IDMA)) { printk(KERN_INFO"IDMA is not mapped to this CPU\n"); return -ENODEV; } #endif printk(KERN_INFO "Use IDMA channels %d and %d for enhancing the following function:\n", CPY_CHAN1, CPY_CHAN2); #ifdef CONFIG_MV_IDMA_COPYUSER printk(KERN_INFO " o Copy From/To user space operations.\n"); #endif #ifdef CONFIG_MV_IDMA_MEMCOPY printk(KERN_INFO " o memcpy() and memmove() operations.\n"); #endif #ifdef CONFIG_MV_IDMA_MEMZERO printk(KERN_INFO " o memzero() operations.\n"); #endif #ifdef CONFIG_MV_IDMA_MEMZERO DPRINTK(KERN_ERR "ZERO buffer address 0x%08x\n", (u32)dmaMemInitBuff); asm_memzero(dmaMemInitBuff, sizeof(dmaMemInitBuff)); dmac_flush_range(dmaMemInitBuff, dmaMemInitBuff + sizeof(dmaMemInitBuff)); #endif MV_REG_WRITE(IDMA_BYTE_COUNT_REG(CPY_CHAN1), 0); MV_REG_WRITE(IDMA_CURR_DESC_PTR_REG(CPY_CHAN1), 0); MV_REG_WRITE(IDMA_CTRL_HIGH_REG(CPY_CHAN1), ICCHR_ENDIAN_LITTLE #ifdef MV_CPU_LE | ICCHR_DESC_BYTE_SWAP_EN #endif ); MV_REG_WRITE(IDMA_CTRL_LOW_REG(CPY_CHAN1), CPY_IDMA_CTRL_LOW_VALUE); MV_REG_WRITE(IDMA_BYTE_COUNT_REG(CPY_CHAN2), 0); MV_REG_WRITE(IDMA_CURR_DESC_PTR_REG(CPY_CHAN2), 0); MV_REG_WRITE(IDMA_CTRL_HIGH_REG(CPY_CHAN2), ICCHR_ENDIAN_LITTLE #ifdef MV_CPU_LE | ICCHR_DESC_BYTE_SWAP_EN #endif ); MV_REG_WRITE(IDMA_CTRL_LOW_REG(CPY_CHAN2), CPY_IDMA_CTRL_LOW_VALUE); current_dma_channel = CPY_CHAN1; dma_proc_entry = create_proc_entry("dma_copy", S_IFREG | S_IRUGO, 0); dma_proc_entry->read_proc = dma_read_proc; // dma_proc_entry->write_proc = dma_write_proc; dma_proc_entry->nlink = 1; idma_init = 1; return 0; }
/******************************************************************************* * mvDmaMemInit - Initialize a memory buffer with a given 64bit value pattern * * DESCRIPTION: * This function initiates IDMA channel, according to function parameters, * in order to perform DMA transaction for the purpose of initializing a * memory buffer with a user supplied pattern. * This routine supports both chain and none chained DMA modes. * To use the function in chain mode just set phyNextDesc parameter with * chain second descriptor address (the first one is given in other * function paarameters). Otherwise (none chain mode) set it to NULL. * To gain maximum performance the user is asked to keep the following * restrictions: * 1) Selected engine is available (not busy). * 1) This module does not take into consideration CPU MMU issues. * In order for the IDMA engine to access the appropreate source * and destination, address parameters must be given in system * physical mode. * 2) This API does not take care of cache coherency issues. The source, * destination and in case of chain the descriptor list are assumed * to be cache coherent. * 3) No chain mode support. * 4) Parameters validity. For example, does size parameter exceeds * maximum byte count of descriptor mode (16M or 64K). * * INPUT: * chan - DMA channel number. See MV_DMA_CHANNEL enumerator. * ptrnPtr - Physical source address of the 64bit pattern * startPtr - Physical destinaation address to start with * size - The total number of bytes to transfer. * * OUTPUT: * None. * * RETURS: * MV_OK. * *******************************************************************************/ MV_STATUS mvDmaMemInit(MV_U32 chan, MV_U32 ptrnPtr, MV_U32 startPtr, MV_U32 size) { /* Set byte count register */ MV_REG_WRITE(IDMA_BYTE_COUNT_REG(chan), size); /* Set source address register */ MV_REG_WRITE(IDMA_SRC_ADDR_REG(chan), ptrnPtr); /* Set destination address register */ MV_REG_WRITE(IDMA_DST_ADDR_REG(chan), startPtr); /* Lock the Source address in dma operation */ MV_REG_BIT_SET(IDMA_CTRL_LOW_REG(chan), ICCLR_SRC_HOLD); /* Start DMA */ MV_REG_BIT_SET(IDMA_CTRL_LOW_REG(chan), ICCLR_CHAN_ENABLE); return MV_OK; }
/******************************************************************************* * mvDmaTransfer - Transfer data from source to destination * * DESCRIPTION: * This function initiates IDMA channel, according to function parameters, * in order to perform DMA transaction. * This routine supports both chain and none chained DMA modes. * To use the function in chain mode just set phyNextDesc parameter with * chain second descriptor address (the first one is given in other * function paarameters). Otherwise (none chain mode) set it to NULL. * To gain maximum performance the user is asked to keep the following * restrictions: * 1) Selected engine is available (not busy). * 1) This module does not take into consideration CPU MMU issues. * In order for the IDMA engine to access the appropreate source * and destination, address parameters must be given in system * physical mode. * 2) This API does not take care of cache coherency issues. The source, * destination and in case of chain the descriptor list are assumed * to be cache coherent. * 3) In case of chain mode, the API does not align the user descriptor * chain. Instead, the user must make sure the descriptor chain is * aligned according to IDMA rquirements. * 4) Parameters validity. For example, does size parameter exceeds * maximum byte count of descriptor mode (16M or 64K). * * INPUT: * chan - DMA channel number. See MV_DMA_CHANNEL enumerator. * phySrc - Physical source address. * phyDst - Physical destination address. * size - The total number of bytes to transfer. * *pPhyNextDesc - Physical address pointer to 2nd descriptor in chain. * In case of none chain mode set it to NULL. * * OUTPUT: * None. * * RETURS: * MV_OK. * *******************************************************************************/ MV_STATUS mvDmaTransfer(MV_U32 chan, MV_U32 phySrc, MV_U32 phyDst, MV_U32 size, MV_U32 phyNextDescPtr) { /* Set byte count register */ MV_REG_WRITE(IDMA_BYTE_COUNT_REG(chan), size); /* Set source address register */ MV_REG_WRITE(IDMA_SRC_ADDR_REG(chan), phySrc); /* Set destination address register */ MV_REG_WRITE(IDMA_DST_ADDR_REG(chan), phyDst); if (0 != phyNextDescPtr) { /* Chain mode. Set next descriptor register */ MV_REG_WRITE(IDMA_NEXT_DESC_PTR_REG(chan), phyNextDescPtr); } /* Start DMA */ MV_REG_BIT_SET(IDMA_CTRL_LOW_REG(chan), ICCLR_CHAN_ENABLE); return MV_OK; }