|
@@ -718,3 +718,149 @@ iop_desc_init_interrupt(struct iop_adma_desc_slot *desc,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+static inline void
|
|
|
+iop_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);
|
|
|
+
|
|
|
+ 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 void
|
|
|
+iop_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, };
|
|
|
+
|
|
|
+ iop_paranoia(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 enum sum_check_flags
|
|
|
+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;
|
|
|
+
|
|
|
+ iop_paranoia(!(desc_ctrl.tx_complete && desc_ctrl.zero_result_en));
|
|
|
+ return desc_ctrl.zero_result_err << SUM_CHECK_P;
|
|
|
+}
|
|
|
+
|
|
|
+static inline void iop_chan_append(struct iop_adma_chan *chan)
|
|
|
+{
|
|
|
+ u32 dma_chan_ctrl;
|
|
|
+
|
|
|
+ dma_chan_ctrl = __raw_readl(DMA_CCR(chan));
|
|
|
+ dma_chan_ctrl |= 0x2;
|
|
|
+ __raw_writel(dma_chan_ctrl, DMA_CCR(chan));
|
|
|
+}
|
|
|
+
|
|
|
+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;
|