📄 bfin_dma_5xx.c
字号:
unsigned short get_dma_curr_ycount(unsigned int channel){ BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE && channel < MAX_BLACKFIN_DMA_CHANNEL)); return dma_ch[channel].regs->curr_y_count;}EXPORT_SYMBOL(get_dma_curr_ycount);unsigned long get_dma_next_desc_ptr(unsigned int channel){ BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE && channel < MAX_BLACKFIN_DMA_CHANNEL)); return dma_ch[channel].regs->next_desc_ptr;}EXPORT_SYMBOL(get_dma_next_desc_ptr);unsigned long get_dma_curr_desc_ptr(unsigned int channel){ BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE && channel < MAX_BLACKFIN_DMA_CHANNEL)); return dma_ch[channel].regs->curr_desc_ptr;}EXPORT_SYMBOL(get_dma_curr_desc_ptr);unsigned long get_dma_curr_addr(unsigned int channel){ BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE && channel < MAX_BLACKFIN_DMA_CHANNEL)); return dma_ch[channel].regs->curr_addr_ptr;}EXPORT_SYMBOL(get_dma_curr_addr);static void *__dma_memcpy(void *dest, const void *src, size_t size){ int direction; /* 1 - address decrease, 0 - address increase */ int flag_align; /* 1 - address aligned, 0 - address unaligned */ int flag_2D; /* 1 - 2D DMA needed, 0 - 1D DMA needed */ unsigned long flags; if (size <= 0) return NULL; local_irq_save(flags); if ((unsigned long)src < memory_end) blackfin_dcache_flush_range((unsigned int)src, (unsigned int)(src + size)); if ((unsigned long)dest < memory_end) blackfin_dcache_invalidate_range((unsigned int)dest, (unsigned int)(dest + size)); bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR); if ((unsigned long)src < (unsigned long)dest) direction = 1; else direction = 0; if ((((unsigned long)dest % 2) == 0) && (((unsigned long)src % 2) == 0) && ((size % 2) == 0)) flag_align = 1; else flag_align = 0; if (size > 0x10000) /* size > 64K */ flag_2D = 1; else flag_2D = 0; /* Setup destination and source start address */ if (direction) { if (flag_align) { bfin_write_MDMA_D0_START_ADDR(dest + size - 2); bfin_write_MDMA_S0_START_ADDR(src + size - 2); } else { bfin_write_MDMA_D0_START_ADDR(dest + size - 1); bfin_write_MDMA_S0_START_ADDR(src + size - 1); } } else { bfin_write_MDMA_D0_START_ADDR(dest); bfin_write_MDMA_S0_START_ADDR(src); } /* Setup destination and source xcount */ if (flag_2D) { if (flag_align) { bfin_write_MDMA_D0_X_COUNT(1024 / 2); bfin_write_MDMA_S0_X_COUNT(1024 / 2); } else { bfin_write_MDMA_D0_X_COUNT(1024); bfin_write_MDMA_S0_X_COUNT(1024); } bfin_write_MDMA_D0_Y_COUNT(size >> 10); bfin_write_MDMA_S0_Y_COUNT(size >> 10); } else { if (flag_align) { bfin_write_MDMA_D0_X_COUNT(size / 2); bfin_write_MDMA_S0_X_COUNT(size / 2); } else { bfin_write_MDMA_D0_X_COUNT(size); bfin_write_MDMA_S0_X_COUNT(size); } } /* Setup destination and source xmodify and ymodify */ if (direction) { if (flag_align) { bfin_write_MDMA_D0_X_MODIFY(-2); bfin_write_MDMA_S0_X_MODIFY(-2); if (flag_2D) { bfin_write_MDMA_D0_Y_MODIFY(-2); bfin_write_MDMA_S0_Y_MODIFY(-2); } } else { bfin_write_MDMA_D0_X_MODIFY(-1); bfin_write_MDMA_S0_X_MODIFY(-1); if (flag_2D) { bfin_write_MDMA_D0_Y_MODIFY(-1); bfin_write_MDMA_S0_Y_MODIFY(-1); } } } else { if (flag_align) { bfin_write_MDMA_D0_X_MODIFY(2); bfin_write_MDMA_S0_X_MODIFY(2); if (flag_2D) { bfin_write_MDMA_D0_Y_MODIFY(2); bfin_write_MDMA_S0_Y_MODIFY(2); } } else { bfin_write_MDMA_D0_X_MODIFY(1); bfin_write_MDMA_S0_X_MODIFY(1); if (flag_2D) { bfin_write_MDMA_D0_Y_MODIFY(1); bfin_write_MDMA_S0_Y_MODIFY(1); } } } /* Enable source DMA */ if (flag_2D) { if (flag_align) { bfin_write_MDMA_S0_CONFIG(DMAEN | DMA2D | WDSIZE_16); bfin_write_MDMA_D0_CONFIG(WNR | DI_EN | DMAEN | DMA2D | WDSIZE_16); } else { bfin_write_MDMA_S0_CONFIG(DMAEN | DMA2D); bfin_write_MDMA_D0_CONFIG(WNR | DI_EN | DMAEN | DMA2D); } } else { if (flag_align) { bfin_write_MDMA_S0_CONFIG(DMAEN | WDSIZE_16); bfin_write_MDMA_D0_CONFIG(WNR | DI_EN | DMAEN | WDSIZE_16); } else { bfin_write_MDMA_S0_CONFIG(DMAEN); bfin_write_MDMA_D0_CONFIG(WNR | DI_EN | DMAEN); } } SSYNC(); while (!(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE)) ; bfin_write_MDMA_D0_IRQ_STATUS(bfin_read_MDMA_D0_IRQ_STATUS() | (DMA_DONE | DMA_ERR)); bfin_write_MDMA_S0_CONFIG(0); bfin_write_MDMA_D0_CONFIG(0); local_irq_restore(flags); return dest;}void *dma_memcpy(void *dest, const void *src, size_t size){ size_t bulk; size_t rest; void * addr; bulk = (size >> 16) << 16; rest = size - bulk; if (bulk) __dma_memcpy(dest, src, bulk); addr = __dma_memcpy(dest+bulk, src+bulk, rest); return addr;}EXPORT_SYMBOL(dma_memcpy);void *safe_dma_memcpy(void *dest, const void *src, size_t size){ void *addr; addr = dma_memcpy(dest, src, size); return addr;}EXPORT_SYMBOL(safe_dma_memcpy);void dma_outsb(unsigned long addr, const void *buf, unsigned short len){ unsigned long flags; local_irq_save(flags); blackfin_dcache_flush_range((unsigned int)buf, (unsigned int)(buf) + len); bfin_write_MDMA_D0_START_ADDR(addr); bfin_write_MDMA_D0_X_COUNT(len); bfin_write_MDMA_D0_X_MODIFY(0); bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR); bfin_write_MDMA_S0_START_ADDR(buf); bfin_write_MDMA_S0_X_COUNT(len); bfin_write_MDMA_S0_X_MODIFY(1); bfin_write_MDMA_S0_IRQ_STATUS(DMA_DONE | DMA_ERR); bfin_write_MDMA_S0_CONFIG(DMAEN | WDSIZE_8); bfin_write_MDMA_D0_CONFIG(WNR | DI_EN | DMAEN | WDSIZE_8); SSYNC(); while (!(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE)); bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR); bfin_write_MDMA_S0_CONFIG(0); bfin_write_MDMA_D0_CONFIG(0); local_irq_restore(flags);}EXPORT_SYMBOL(dma_outsb);void dma_insb(unsigned long addr, void *buf, unsigned short len){ unsigned long flags; blackfin_dcache_invalidate_range((unsigned int)buf, (unsigned int)(buf) + len); local_irq_save(flags); bfin_write_MDMA_D0_START_ADDR(buf); bfin_write_MDMA_D0_X_COUNT(len); bfin_write_MDMA_D0_X_MODIFY(1); bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR); bfin_write_MDMA_S0_START_ADDR(addr); bfin_write_MDMA_S0_X_COUNT(len); bfin_write_MDMA_S0_X_MODIFY(0); bfin_write_MDMA_S0_IRQ_STATUS(DMA_DONE | DMA_ERR); bfin_write_MDMA_S0_CONFIG(DMAEN | WDSIZE_8); bfin_write_MDMA_D0_CONFIG(WNR | DI_EN | DMAEN | WDSIZE_8); SSYNC(); while (!(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE)); bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR); bfin_write_MDMA_S0_CONFIG(0); bfin_write_MDMA_D0_CONFIG(0); local_irq_restore(flags);}EXPORT_SYMBOL(dma_insb);void dma_outsw(unsigned long addr, const void *buf, unsigned short len){ unsigned long flags; local_irq_save(flags); blackfin_dcache_flush_range((unsigned int)buf, (unsigned int)(buf) + len * sizeof(short)); bfin_write_MDMA_D0_START_ADDR(addr); bfin_write_MDMA_D0_X_COUNT(len); bfin_write_MDMA_D0_X_MODIFY(0); bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR); bfin_write_MDMA_S0_START_ADDR(buf); bfin_write_MDMA_S0_X_COUNT(len); bfin_write_MDMA_S0_X_MODIFY(2); bfin_write_MDMA_S0_IRQ_STATUS(DMA_DONE | DMA_ERR); bfin_write_MDMA_S0_CONFIG(DMAEN | WDSIZE_16); bfin_write_MDMA_D0_CONFIG(WNR | DI_EN | DMAEN | WDSIZE_16); SSYNC(); while (!(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE)); bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR); bfin_write_MDMA_S0_CONFIG(0); bfin_write_MDMA_D0_CONFIG(0); local_irq_restore(flags);}EXPORT_SYMBOL(dma_outsw);void dma_insw(unsigned long addr, void *buf, unsigned short len){ unsigned long flags; blackfin_dcache_invalidate_range((unsigned int)buf, (unsigned int)(buf) + len * sizeof(short)); local_irq_save(flags); bfin_write_MDMA_D0_START_ADDR(buf); bfin_write_MDMA_D0_X_COUNT(len); bfin_write_MDMA_D0_X_MODIFY(2); bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR); bfin_write_MDMA_S0_START_ADDR(addr); bfin_write_MDMA_S0_X_COUNT(len); bfin_write_MDMA_S0_X_MODIFY(0); bfin_write_MDMA_S0_IRQ_STATUS(DMA_DONE | DMA_ERR); bfin_write_MDMA_S0_CONFIG(DMAEN | WDSIZE_16); bfin_write_MDMA_D0_CONFIG(WNR | DI_EN | DMAEN | WDSIZE_16); SSYNC(); while (!(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE)); bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR); bfin_write_MDMA_S0_CONFIG(0); bfin_write_MDMA_D0_CONFIG(0); local_irq_restore(flags);}EXPORT_SYMBOL(dma_insw);void dma_outsl(unsigned long addr, const void *buf, unsigned short len){ unsigned long flags; local_irq_save(flags); blackfin_dcache_flush_range((unsigned int)buf, (unsigned int)(buf) + len * sizeof(long)); bfin_write_MDMA_D0_START_ADDR(addr); bfin_write_MDMA_D0_X_COUNT(len); bfin_write_MDMA_D0_X_MODIFY(0); bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR); bfin_write_MDMA_S0_START_ADDR(buf); bfin_write_MDMA_S0_X_COUNT(len); bfin_write_MDMA_S0_X_MODIFY(4); bfin_write_MDMA_S0_IRQ_STATUS(DMA_DONE | DMA_ERR); bfin_write_MDMA_S0_CONFIG(DMAEN | WDSIZE_32); bfin_write_MDMA_D0_CONFIG(WNR | DI_EN | DMAEN | WDSIZE_32); SSYNC(); while (!(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE)); bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR); bfin_write_MDMA_S0_CONFIG(0); bfin_write_MDMA_D0_CONFIG(0); local_irq_restore(flags);}EXPORT_SYMBOL(dma_outsl);void dma_insl(unsigned long addr, void *buf, unsigned short len){ unsigned long flags; blackfin_dcache_invalidate_range((unsigned int)buf, (unsigned int)(buf) + len * sizeof(long)); local_irq_save(flags); bfin_write_MDMA_D0_START_ADDR(buf); bfin_write_MDMA_D0_X_COUNT(len); bfin_write_MDMA_D0_X_MODIFY(4); bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR); bfin_write_MDMA_S0_START_ADDR(addr); bfin_write_MDMA_S0_X_COUNT(len); bfin_write_MDMA_S0_X_MODIFY(0); bfin_write_MDMA_S0_IRQ_STATUS(DMA_DONE | DMA_ERR); bfin_write_MDMA_S0_CONFIG(DMAEN | WDSIZE_32); bfin_write_MDMA_D0_CONFIG(WNR | DI_EN | DMAEN | WDSIZE_32); SSYNC(); while (!(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE)); bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR); bfin_write_MDMA_S0_CONFIG(0); bfin_write_MDMA_D0_CONFIG(0); local_irq_restore(flags);}EXPORT_SYMBOL(dma_insl);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -