dma.h
字号:
static __inline__ void set_dma_device_addr(unsigned int dmanr, unsigned int a){#ifdef DMA_DEBUG printk("set_dma_device_addr(dmanr=%d,a=%x)\n", dmanr, a);#endif dma_device_address[dmanr] = a;}/* * NOTE 2: "count" represents _bytes_. */static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count){ volatile unsigned short *dmawp;#ifdef DMA_DEBUG printk("set_dma_count(dmanr=%d,count=%d)\n", dmanr, count);#endif dmawp = (unsigned short *) dma_base_addr[dmanr]; dmawp[MCFDMA_BCR] = (unsigned short)count;}/* * Get DMA residue count. After a DMA transfer, this * should return zero. Reading this while a DMA transfer is * still in progress will return unpredictable results. * Otherwise, it returns the number of _bytes_ left to transfer. */static __inline__ int get_dma_residue(unsigned int dmanr){ volatile unsigned short *dmawp; unsigned short count;#ifdef DMA_DEBUG printk("get_dma_residue(dmanr=%d)\n", dmanr);#endif dmawp = (unsigned short *) dma_base_addr[dmanr]; count = dmawp[MCFDMA_BCR]; return((int) count);}#else /* CONFIG_M5272 is defined *//* * The MCF5272 DMA controller is very different than the controller defined above * in terms of register mapping. For instance, with the exception of the 16-bit * interrupt register (IRQ#85, for reference), all of the registers are 32-bit. * * The big difference, however, is the lack of device-requested DMA. All modes * are dual address transfer, and there is no 'device' setup or direction bit. * You can DMA between a device and memory, between memory and memory, or even between * two devices directly, with any combination of incrementing and non-incrementing * addresses you choose. This puts a crimp in distinguishing between the 'device * address' set up by set_dma_device_addr. * * Therefore, there are two options. One is to use set_dma_addr and set_dma_device_addr, * which will act exactly as above in -- it will look to see if the source is set to * autoincrement, and if so it will make the source use the set_dma_addr value and the * destination the set_dma_device_addr value. Otherwise the source will be set to the * set_dma_device_addr value and the destination will get the set_dma_addr value. * * The other is to use the provided set_dma_src_addr and set_dma_dest_addr functions * and make it explicit. Depending on what you're doing, one of these two should work * for you, but don't mix them in the same transfer setup. *//* enable/disable a specific DMA channel */static __inline__ void enable_dma(unsigned int dmanr){ volatile unsigned int *dmalp;#ifdef DMA_DEBUG printk("enable_dma(dmanr=%d)\n", dmanr);#endif dmalp = (unsigned int *) dma_base_addr[dmanr]; dmalp[MCFDMA_DMR] |= MCFDMA_DMR_EN;}static __inline__ void disable_dma(unsigned int dmanr){ volatile unsigned int *dmalp;#ifdef DMA_DEBUG printk("disable_dma(dmanr=%d)\n", dmanr);#endif dmalp = (unsigned int *) dma_base_addr[dmanr]; /* Turn off external requests, and stop any DMA in progress */ dmalp[MCFDMA_DMR] &= ~MCFDMA_DMR_EN; dmalp[MCFDMA_DMR] |= MCFDMA_DMR_RESET;}/* * Clear the 'DMA Pointer Flip Flop'. * Write 0 for LSB/MSB, 1 for MSB/LSB access. * Use this once to initialize the FF to a known state. * After that, keep track of it. :-) * --- In order to do that, the DMA routines below should --- * --- only be used while interrupts are disabled! --- * * This is a NOP for ColdFire. Provide a stub for compatibility. */static __inline__ void clear_dma_ff(unsigned int dmanr){}/* set mode (above) for a specific DMA channel */static __inline__ void set_dma_mode(unsigned int dmanr, char mode){ volatile unsigned int *dmalp; volatile unsigned short *dmawp;#ifdef DMA_DEBUG printk("set_dma_mode(dmanr=%d,mode=%d)\n", dmanr, mode);#endif dmalp = (unsigned int *) dma_base_addr[dmanr]; dmawp = (unsigned short *) dma_base_addr[dmanr]; // Clear config errors dmalp[MCFDMA_DMR] |= MCFDMA_DMR_RESET; // Set command register dmalp[MCFDMA_DMR] = MCFDMA_DMR_RQM_DUAL | // Mandatory Request Mode setting MCFDMA_DMR_DSTT_SD | // Set up addressing types; set to supervisor-data. MCFDMA_DMR_SRCT_SD | // Set up addressing types; set to supervisor-data. // source static-address-mode ((mode & DMA_MODE_SRC_SA_BIT) ? MCFDMA_DMR_SRCM_SA : MCFDMA_DMR_SRCM_IA) | // dest static-address-mode ((mode & DMA_MODE_DES_SA_BIT) ? MCFDMA_DMR_DSTM_SA : MCFDMA_DMR_DSTM_IA) | // burst, 32 bit, 16 bit or 8 bit transfers are separately configurable on the MCF5272 (((mode & DMA_MODE_SSIZE_MASK) >> DMA_MODE_SSIZE_OFF) << MCFDMA_DMR_DSTS_OFF) | (((mode & DMA_MODE_SSIZE_MASK) >> DMA_MODE_SSIZE_OFF) << MCFDMA_DMR_SRCS_OFF); dmawp[MCFDMA_DIR] |= MCFDMA_DIR_ASCEN; /* Enable completion interrupts */ #ifdef DEBUG_DMA printk("%s(%d): dmanr=%d DMR[%x]=%x DIR[%x]=%x\n", __FILE__, __LINE__, dmanr, (int) &dmalp[MCFDMA_DMR], dmabp[MCFDMA_DMR], (int) &dmawp[MCFDMA_DIR], dmawp[MCFDMA_DIR]);#endif}/* Set transfer address for specific DMA channel */static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int a){ volatile unsigned int *dmalp;#ifdef DMA_DEBUG printk("set_dma_addr(dmanr=%d,a=%x)\n", dmanr, a);#endif dmalp = (unsigned int *) dma_base_addr[dmanr]; // Determine which address registers are used for memory/device accesses if (dmalp[MCFDMA_DMR] & MCFDMA_DMR_SRCM) { // Source incrementing, must be memory dmalp[MCFDMA_DSAR] = a; // Set dest address, must be device dmalp[MCFDMA_DDAR] = dma_device_address[dmanr]; } else { // Destination incrementing, must be memory dmalp[MCFDMA_DDAR] = a; // Set source address, must be device dmalp[MCFDMA_DSAR] = dma_device_address[dmanr]; }#ifdef DEBUG_DMA printk("%s(%d): dmanr=%d DMR[%x]=%x SAR[%x]=%08x DAR[%x]=%08x\n", __FILE__, __LINE__, dmanr, (int) &dmawp[MCFDMA_DMR], dmawp[MCFDMA_DMR], (int) &dmalp[MCFDMA_DSAR], dmalp[MCFDMA_DSAR], (int) &dmalp[MCFDMA_DDAR], dmalp[MCFDMA_DDAR]);#endif}/* * Specific for Coldfire - sets device address. * Should be called after the mode set call, and before set DMA address. */static __inline__ void set_dma_device_addr(unsigned int dmanr, unsigned int a){#ifdef DMA_DEBUG printk("set_dma_device_addr(dmanr=%d,a=%x)\n", dmanr, a);#endif dma_device_address[dmanr] = a;}/* * NOTE 2: "count" represents _bytes_. * * NOTE 3: While a 32-bit register, "count" is only a maximum 24-bit value. */static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count){ volatile unsigned int *dmalp; #ifdef DMA_DEBUG printk("set_dma_count(dmanr=%d,count=%d)\n", dmanr, count);#endif dmalp = (unsigned int *) dma_base_addr[dmanr]; dmalp[MCFDMA_DBCR] = count;}/* * Get DMA residue count. After a DMA transfer, this * should return zero. Reading this while a DMA transfer is * still in progress will return unpredictable results. * Otherwise, it returns the number of _bytes_ left to transfer. */static __inline__ int get_dma_residue(unsigned int dmanr){ volatile unsigned int *dmalp; unsigned int count;#ifdef DMA_DEBUG printk("get_dma_residue(dmanr=%d)\n", dmanr);#endif dmalp = (unsigned int *) dma_base_addr[dmanr]; count = dmalp[MCFDMA_DBCR]; return(count);}#endif /* !defined(CONFIG_M5272) */#endif /* CONFIG_COLDFIRE */ #define MAX_DMA_CHANNELS 8/* Don't define MAX_DMA_ADDRESS; it's useless on the m68k/coldfire and any occurrence should be flagged as an error. *//* under 2.4 it is actually needed by the new bootmem allocator */#define MAX_DMA_ADDRESS PAGE_OFFSET/* These are in kernel/dma.c: */extern int request_dma(unsigned int dmanr, const char *device_id); /* reserve a DMA channel */extern void free_dma(unsigned int dmanr); /* release it again */ #endif /* _M68K_DMA_H */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -