欢迎来到虫虫下载站 | 资源下载 资源专辑 关于我们
虫虫下载站

dma.h

Linux Kernel 2.6.9 for OMAP1710
H
第 1 页 / 共 2 页
字号:
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 + -