static void omap24xxcam_dmahw_transfer_chain(void __iomem *base, int dmach, int free_dmach) { int prev_dmach, ch; if (dmach == 0) prev_dmach = NUM_CAMDMA_CHANNELS - 1; else prev_dmach = dmach - 1; omap24xxcam_reg_out(base, CAMDMA_CLNK_CTRL(prev_dmach), CAMDMA_CLNK_CTRL_ENABLE_LNK | dmach); /* Did we chain the DMA transfer before the previous one * finished? */ ch = (dmach + free_dmach) % NUM_CAMDMA_CHANNELS; while (!(omap24xxcam_reg_in(base, CAMDMA_CCR(ch)) & CAMDMA_CCR_ENABLE)) { if (ch == dmach) { /* The previous transfer has ended and this one * hasn't started, so we must not have chained * to the previous one in time. We'll have to * start it now. */ omap24xxcam_dmahw_transfer_start(base, dmach); break; } else ch = (ch + 1) % NUM_CAMDMA_CHANNELS; } }
/* Abort all chained DMA transfers. After all transfers have been * aborted and the DMA controller is idle, the completion routines for * any aborted transfers will be called in sequence. The DMA * controller may not be idle after this routine completes, because * the completion routines might start new transfers. */ static void omap24xxcam_dmahw_abort_ch(void __iomem *base, int dmach) { /* mask all interrupts from this channel */ omap24xxcam_reg_out(base, CAMDMA_CICR(dmach), 0); /* unlink this channel */ omap24xxcam_reg_merge(base, CAMDMA_CLNK_CTRL(dmach), 0, CAMDMA_CLNK_CTRL_ENABLE_LNK); /* disable this channel */ omap24xxcam_reg_merge(base, CAMDMA_CCR(dmach), 0, CAMDMA_CCR_ENABLE); }
static void omap24xxcam_dmahw_abort_ch(unsigned long base, int dmach) { omap24xxcam_reg_out(base, CAMDMA_CICR(dmach), 0); omap24xxcam_reg_merge(base, CAMDMA_CLNK_CTRL(dmach), 0, CAMDMA_CLNK_CTRL_ENABLE_LNK); omap24xxcam_reg_merge(base, CAMDMA_CCR(dmach), 0, CAMDMA_CCR_ENABLE); }
static void omap24xxcam_dmahw_transfer_setup(void __iomem *base, int dmach, dma_addr_t start, u32 len) { omap24xxcam_reg_out(base, CAMDMA_CCR(dmach), CAMDMA_CCR_SEL_SRC_DST_SYNC | CAMDMA_CCR_BS | CAMDMA_CCR_DST_AMODE_POST_INC | CAMDMA_CCR_SRC_AMODE_POST_INC | CAMDMA_CCR_FS | CAMDMA_CCR_WR_ACTIVE | CAMDMA_CCR_RD_ACTIVE | CAMDMA_CCR_SYNCHRO_CAMERA); omap24xxcam_reg_out(base, CAMDMA_CLNK_CTRL(dmach), 0); omap24xxcam_reg_out(base, CAMDMA_CEN(dmach), len); omap24xxcam_reg_out(base, CAMDMA_CFN(dmach), 1); omap24xxcam_reg_out(base, CAMDMA_CSDP(dmach), CAMDMA_CSDP_WRITE_MODE_POSTED | CAMDMA_CSDP_DST_BURST_EN_32 | CAMDMA_CSDP_DST_PACKED | CAMDMA_CSDP_SRC_BURST_EN_32 | CAMDMA_CSDP_SRC_PACKED | CAMDMA_CSDP_DATA_TYPE_8BITS); omap24xxcam_reg_out(base, CAMDMA_CSSA(dmach), 0); omap24xxcam_reg_out(base, CAMDMA_CDSA(dmach), start); omap24xxcam_reg_out(base, CAMDMA_CSEI(dmach), 0); omap24xxcam_reg_out(base, CAMDMA_CSFI(dmach), DMA_THRESHOLD); omap24xxcam_reg_out(base, CAMDMA_CDEI(dmach), 0); omap24xxcam_reg_out(base, CAMDMA_CDFI(dmach), 0); omap24xxcam_reg_out(base, CAMDMA_CSR(dmach), CAMDMA_CSR_MISALIGNED_ERR | CAMDMA_CSR_SECURE_ERR | CAMDMA_CSR_TRANS_ERR | CAMDMA_CSR_BLOCK | CAMDMA_CSR_DROP); omap24xxcam_reg_out(base, CAMDMA_CICR(dmach), CAMDMA_CICR_MISALIGNED_ERR_IE | CAMDMA_CICR_SECURE_ERR_IE | CAMDMA_CICR_TRANS_ERR_IE | CAMDMA_CICR_BLOCK_IE | CAMDMA_CICR_DROP_IE); }
static void omap24xxcam_dmahw_transfer_chain(unsigned long base, int dmach, int free_dmach) { int prev_dmach, ch; if (dmach == 0) prev_dmach = NUM_CAMDMA_CHANNELS - 1; else prev_dmach = dmach - 1; omap24xxcam_reg_out(base, CAMDMA_CLNK_CTRL(prev_dmach), CAMDMA_CLNK_CTRL_ENABLE_LNK | dmach); ch = (dmach + free_dmach) % NUM_CAMDMA_CHANNELS; while (!(omap24xxcam_reg_in(base, CAMDMA_CCR(ch)) & CAMDMA_CCR_ENABLE)) { if (ch == dmach) { omap24xxcam_dmahw_transfer_start(base, dmach); break; } else ch = (ch + 1) % NUM_CAMDMA_CHANNELS; } }