iop3xx-adma.h
来自「linux 内核源代码」· C头文件 代码 · 共 893 行 · 第 1/2 页
H
893 行
}static inline u32iop3xx_desc_init_xor(struct iop3xx_desc_aau *hw_desc, int src_cnt, int int_en){ int i, shift; u32 edcr; union { u32 value; struct iop3xx_aau_desc_ctrl field; } u_desc_ctrl; u_desc_ctrl.value = 0; switch (src_cnt) { case 25 ... 32: u_desc_ctrl.field.blk_ctrl = 0x3; /* use EDCR[2:0] */ edcr = 0; shift = 1; for (i = 24; i < src_cnt; i++) { edcr |= (1 << shift); shift += 3; } hw_desc->src_edc[AAU_EDCR2_IDX].e_desc_ctrl = edcr; src_cnt = 24; /* fall through */ case 17 ... 24: if (!u_desc_ctrl.field.blk_ctrl) { hw_desc->src_edc[AAU_EDCR2_IDX].e_desc_ctrl = 0; u_desc_ctrl.field.blk_ctrl = 0x3; /* use EDCR[2:0] */ } edcr = 0; shift = 1; for (i = 16; i < src_cnt; i++) { edcr |= (1 << shift); shift += 3; } hw_desc->src_edc[AAU_EDCR1_IDX].e_desc_ctrl = edcr; src_cnt = 16; /* fall through */ case 9 ... 16: if (!u_desc_ctrl.field.blk_ctrl) u_desc_ctrl.field.blk_ctrl = 0x2; /* use EDCR0 */ edcr = 0; shift = 1; for (i = 8; i < src_cnt; i++) { edcr |= (1 << shift); shift += 3; } hw_desc->src_edc[AAU_EDCR0_IDX].e_desc_ctrl = edcr; src_cnt = 8; /* fall through */ case 2 ... 8: shift = 1; for (i = 0; i < src_cnt; i++) { u_desc_ctrl.value |= (1 << shift); shift += 3; } if (!u_desc_ctrl.field.blk_ctrl && src_cnt > 4) u_desc_ctrl.field.blk_ctrl = 0x1; /* use mini-desc */ } u_desc_ctrl.field.dest_write_en = 1; u_desc_ctrl.field.blk1_cmd_ctrl = 0x7; /* direct fill */ u_desc_ctrl.field.int_en = int_en; hw_desc->desc_ctrl = u_desc_ctrl.value; return u_desc_ctrl.value;}static inline voidiop_desc_init_xor(struct iop_adma_desc_slot *desc, int src_cnt, int int_en){ iop3xx_desc_init_xor(desc->hw_desc, src_cnt, int_en);}/* return the number of operations */static inline intiop_desc_init_zero_sum(struct iop_adma_desc_slot *desc, int src_cnt, int int_en){ int slot_cnt = desc->slot_cnt, slots_per_op = desc->slots_per_op; struct iop3xx_desc_aau *hw_desc, *prev_hw_desc, *iter; union { u32 value; struct iop3xx_aau_desc_ctrl field; } u_desc_ctrl; int i, j; hw_desc = desc->hw_desc; for (i = 0, j = 0; (slot_cnt -= slots_per_op) >= 0; i += slots_per_op, j++) { iter = iop_hw_desc_slot_idx(hw_desc, i); u_desc_ctrl.value = iop3xx_desc_init_xor(iter, src_cnt, int_en); u_desc_ctrl.field.dest_write_en = 0; u_desc_ctrl.field.zero_result_en = 1; u_desc_ctrl.field.int_en = int_en; iter->desc_ctrl = u_desc_ctrl.value; /* for the subsequent descriptors preserve the store queue * and chain them together */ if (i) { prev_hw_desc = iop_hw_desc_slot_idx(hw_desc, i - slots_per_op); prev_hw_desc->next_desc = (u32) (desc->async_tx.phys + (i << 5)); } } return j;}static inline voidiop_desc_init_null_xor(struct iop_adma_desc_slot *desc, int src_cnt, int int_en){ struct iop3xx_desc_aau *hw_desc = desc->hw_desc; union { u32 value; struct iop3xx_aau_desc_ctrl field; } u_desc_ctrl; u_desc_ctrl.value = 0; switch (src_cnt) { case 25 ... 32: u_desc_ctrl.field.blk_ctrl = 0x3; /* use EDCR[2:0] */ hw_desc->src_edc[AAU_EDCR2_IDX].e_desc_ctrl = 0; /* fall through */ case 17 ... 24: if (!u_desc_ctrl.field.blk_ctrl) { hw_desc->src_edc[AAU_EDCR2_IDX].e_desc_ctrl = 0; u_desc_ctrl.field.blk_ctrl = 0x3; /* use EDCR[2:0] */ } hw_desc->src_edc[AAU_EDCR1_IDX].e_desc_ctrl = 0; /* fall through */ case 9 ... 16: if (!u_desc_ctrl.field.blk_ctrl) u_desc_ctrl.field.blk_ctrl = 0x2; /* use EDCR0 */ hw_desc->src_edc[AAU_EDCR0_IDX].e_desc_ctrl = 0; /* fall through */ case 1 ... 8: if (!u_desc_ctrl.field.blk_ctrl && src_cnt > 4) u_desc_ctrl.field.blk_ctrl = 0x1; /* use mini-desc */ } u_desc_ctrl.field.dest_write_en = 0; u_desc_ctrl.field.int_en = int_en; hw_desc->desc_ctrl = u_desc_ctrl.value;}static inline void iop_desc_set_byte_count(struct iop_adma_desc_slot *desc, struct iop_adma_chan *chan, u32 byte_count){ union iop3xx_desc hw_desc = { .ptr = desc->hw_desc, }; switch (chan->device->id) { case DMA0_ID: case DMA1_ID: hw_desc.dma->byte_count = byte_count; break; case AAU_ID: hw_desc.aau->byte_count = byte_count; break; default: BUG(); }}static inline voidiop_desc_init_interrupt(struct iop_adma_desc_slot *desc, struct iop_adma_chan *chan){ union iop3xx_desc hw_desc = { .ptr = desc->hw_desc, }; switch (chan->device->id) { case DMA0_ID: case DMA1_ID: iop_desc_init_memcpy(desc, 1); hw_desc.dma->byte_count = 0; hw_desc.dma->dest_addr = 0; hw_desc.dma->src_addr = 0; break; case AAU_ID: iop_desc_init_null_xor(desc, 2, 1); hw_desc.aau->byte_count = 0; hw_desc.aau->dest_addr = 0; hw_desc.aau->src[0] = 0; hw_desc.aau->src[1] = 0; break; default: BUG(); }}static inline voidiop_desc_set_zero_sum_byte_count(struct iop_adma_desc_slot *desc, u32 len){ int slots_per_op = desc->slots_per_op; struct iop3xx_desc_aau *hw_desc = desc->hw_desc, *iter; int i = 0; if (len <= IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT) { hw_desc->byte_count = len; } else { do { iter = iop_hw_desc_slot_idx(hw_desc, i); iter->byte_count = IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT; len -= IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT; i += slots_per_op; } while (len > IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT); if (len) { iter = iop_hw_desc_slot_idx(hw_desc, i); iter->byte_count = len; } }}static inline void iop_desc_set_dest_addr(struct iop_adma_desc_slot *desc, struct iop_adma_chan *chan, dma_addr_t addr){ union iop3xx_desc hw_desc = { .ptr = desc->hw_desc, }; switch (chan->device->id) { case DMA0_ID: case DMA1_ID: hw_desc.dma->dest_addr = addr; break; case AAU_ID: hw_desc.aau->dest_addr = addr; break; default: BUG(); }}static inline void iop_desc_set_memcpy_src_addr(struct iop_adma_desc_slot *desc, dma_addr_t addr){ struct iop3xx_desc_dma *hw_desc = desc->hw_desc; hw_desc->src_addr = addr;}static inline voidiop_desc_set_zero_sum_src_addr(struct iop_adma_desc_slot *desc, int src_idx, dma_addr_t addr){ struct iop3xx_desc_aau *hw_desc = desc->hw_desc, *iter; int slot_cnt = desc->slot_cnt, slots_per_op = desc->slots_per_op; int i; for (i = 0; (slot_cnt -= slots_per_op) >= 0; i += slots_per_op, addr += IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT) { iter = iop_hw_desc_slot_idx(hw_desc, i); iop3xx_aau_desc_set_src_addr(iter, src_idx, addr); }}static inline void iop_desc_set_xor_src_addr(struct iop_adma_desc_slot *desc, int src_idx, dma_addr_t addr){ struct iop3xx_desc_aau *hw_desc = desc->hw_desc, *iter; int slot_cnt = desc->slot_cnt, slots_per_op = desc->slots_per_op; int i; for (i = 0; (slot_cnt -= slots_per_op) >= 0; i += slots_per_op, addr += IOP_ADMA_XOR_MAX_BYTE_COUNT) { iter = iop_hw_desc_slot_idx(hw_desc, i); iop3xx_aau_desc_set_src_addr(iter, src_idx, addr); }}static inline void iop_desc_set_next_desc(struct iop_adma_desc_slot *desc, u32 next_desc_addr){ /* hw_desc->next_desc is the same location for all channels */ union iop3xx_desc hw_desc = { .ptr = desc->hw_desc, }; BUG_ON(hw_desc.dma->next_desc); hw_desc.dma->next_desc = next_desc_addr;}static inline u32 iop_desc_get_next_desc(struct iop_adma_desc_slot *desc){ /* hw_desc->next_desc is the same location for all channels */ union iop3xx_desc hw_desc = { .ptr = desc->hw_desc, }; return hw_desc.dma->next_desc;}static inline void iop_desc_clear_next_desc(struct iop_adma_desc_slot *desc){ /* hw_desc->next_desc is the same location for all channels */ union iop3xx_desc hw_desc = { .ptr = desc->hw_desc, }; hw_desc.dma->next_desc = 0;}static inline void iop_desc_set_block_fill_val(struct iop_adma_desc_slot *desc, u32 val){ struct iop3xx_desc_aau *hw_desc = desc->hw_desc; hw_desc->src[0] = val;}static inline int iop_desc_get_zero_result(struct iop_adma_desc_slot *desc){ struct iop3xx_desc_aau *hw_desc = desc->hw_desc; struct iop3xx_aau_desc_ctrl desc_ctrl = hw_desc->desc_ctrl_field; BUG_ON(!(desc_ctrl.tx_complete && desc_ctrl.zero_result_en)); return desc_ctrl.zero_result_err;}static inline void iop_chan_append(struct iop_adma_chan *chan){ u32 dma_chan_ctrl; /* workaround dropped interrupts on 3xx */ mod_timer(&chan->cleanup_watchdog, jiffies + msecs_to_jiffies(3)); dma_chan_ctrl = __raw_readl(DMA_CCR(chan)); dma_chan_ctrl |= 0x2; __raw_writel(dma_chan_ctrl, DMA_CCR(chan));}static inline void iop_chan_idle(int busy, struct iop_adma_chan *chan){ if (!busy) del_timer(&chan->cleanup_watchdog);}static inline u32 iop_chan_get_status(struct iop_adma_chan *chan){ return __raw_readl(DMA_CSR(chan));}static inline void iop_chan_disable(struct iop_adma_chan *chan){ u32 dma_chan_ctrl = __raw_readl(DMA_CCR(chan)); dma_chan_ctrl &= ~1; __raw_writel(dma_chan_ctrl, DMA_CCR(chan));}static inline void iop_chan_enable(struct iop_adma_chan *chan){ u32 dma_chan_ctrl = __raw_readl(DMA_CCR(chan)); dma_chan_ctrl |= 1; __raw_writel(dma_chan_ctrl, DMA_CCR(chan));}static inline void iop_adma_device_clear_eot_status(struct iop_adma_chan *chan){ u32 status = __raw_readl(DMA_CSR(chan)); status &= (1 << 9); __raw_writel(status, DMA_CSR(chan));}static inline void iop_adma_device_clear_eoc_status(struct iop_adma_chan *chan){ u32 status = __raw_readl(DMA_CSR(chan)); status &= (1 << 8); __raw_writel(status, DMA_CSR(chan));}static inline void iop_adma_device_clear_err_status(struct iop_adma_chan *chan){ u32 status = __raw_readl(DMA_CSR(chan)); switch (chan->device->id) { case DMA0_ID: case DMA1_ID: status &= (1 << 5) | (1 << 3) | (1 << 2) | (1 << 1); break; case AAU_ID: status &= (1 << 5); break; default: BUG(); } __raw_writel(status, DMA_CSR(chan));}static inline intiop_is_err_int_parity(unsigned long status, struct iop_adma_chan *chan){ return 0;}static inline intiop_is_err_mcu_abort(unsigned long status, struct iop_adma_chan *chan){ return 0;}static inline intiop_is_err_int_tabort(unsigned long status, struct iop_adma_chan *chan){ return 0;}static inline intiop_is_err_int_mabort(unsigned long status, struct iop_adma_chan *chan){ return test_bit(5, &status);}static inline intiop_is_err_pci_tabort(unsigned long status, struct iop_adma_chan *chan){ switch (chan->device->id) { case DMA0_ID: case DMA1_ID: return test_bit(2, &status); default: return 0; }}static inline intiop_is_err_pci_mabort(unsigned long status, struct iop_adma_chan *chan){ switch (chan->device->id) { case DMA0_ID: case DMA1_ID: return test_bit(3, &status); default: return 0; }}static inline intiop_is_err_split_tx(unsigned long status, struct iop_adma_chan *chan){ switch (chan->device->id) { case DMA0_ID: case DMA1_ID: return test_bit(1, &status); default: return 0; }}#endif /* _ADMA_H */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?