|
@@ -363,3 +363,118 @@ static inline int iop_desc_is_pq(struct iop_adma_desc_slot *desc)
|
|
|
}
|
|
|
|
|
|
static inline void
|
|
|
+iop_desc_init_pq_zero_sum(struct iop_adma_desc_slot *desc, int src_cnt,
|
|
|
+ unsigned long flags)
|
|
|
+{
|
|
|
+ struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc;
|
|
|
+ union {
|
|
|
+ u32 value;
|
|
|
+ struct iop13xx_adma_desc_ctrl field;
|
|
|
+ } u_desc_ctrl;
|
|
|
+
|
|
|
+ u_desc_ctrl.value = 0;
|
|
|
+ u_desc_ctrl.field.src_select = src_cnt - 1;
|
|
|
+ u_desc_ctrl.field.xfer_dir = 3; /* local to internal bus */
|
|
|
+ u_desc_ctrl.field.zero_result = 1;
|
|
|
+ u_desc_ctrl.field.status_write_back_en = 1;
|
|
|
+ u_desc_ctrl.field.pq_xfer_en = 1;
|
|
|
+ u_desc_ctrl.field.p_xfer_dis = !!(flags & DMA_PREP_PQ_DISABLE_P);
|
|
|
+ u_desc_ctrl.field.int_en = flags & DMA_PREP_INTERRUPT;
|
|
|
+ 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)
|
|
|
+{
|
|
|
+ struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc;
|
|
|
+ hw_desc->byte_count = byte_count;
|
|
|
+}
|
|
|
+
|
|
|
+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 iop13xx_adma_desc_hw *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;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+#define iop_desc_set_pq_zero_sum_byte_count iop_desc_set_zero_sum_byte_count
|
|
|
+
|
|
|
+static inline void iop_desc_set_dest_addr(struct iop_adma_desc_slot *desc,
|
|
|
+ struct iop_adma_chan *chan,
|
|
|
+ dma_addr_t addr)
|
|
|
+{
|
|
|
+ struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc;
|
|
|
+ hw_desc->dest_addr = addr;
|
|
|
+ hw_desc->upper_dest_addr = 0;
|
|
|
+}
|
|
|
+
|
|
|
+static inline void
|
|
|
+iop_desc_set_pq_addr(struct iop_adma_desc_slot *desc, dma_addr_t *addr)
|
|
|
+{
|
|
|
+ struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc;
|
|
|
+
|
|
|
+ hw_desc->dest_addr = addr[0];
|
|
|
+ hw_desc->q_dest_addr = addr[1];
|
|
|
+ hw_desc->upper_dest_addr = 0;
|
|
|
+}
|
|
|
+
|
|
|
+static inline void iop_desc_set_memcpy_src_addr(struct iop_adma_desc_slot *desc,
|
|
|
+ dma_addr_t addr)
|
|
|
+{
|
|
|
+ struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc;
|
|
|
+ hw_desc->src[0].src_addr = addr;
|
|
|
+ hw_desc->src[0].upper_src_addr = 0;
|
|
|
+}
|
|
|
+
|
|
|
+static inline void iop_desc_set_xor_src_addr(struct iop_adma_desc_slot *desc,
|
|
|
+ int src_idx, dma_addr_t addr)
|
|
|
+{
|
|
|
+ int slot_cnt = desc->slot_cnt, slots_per_op = desc->slots_per_op;
|
|
|
+ struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc, *iter;
|
|
|
+ int i = 0;
|
|
|
+
|
|
|
+ do {
|
|
|
+ iter = iop_hw_desc_slot_idx(hw_desc, i);
|
|
|
+ iter->src[src_idx].src_addr = addr;
|
|
|
+ iter->src[src_idx].upper_src_addr = 0;
|
|
|
+ slot_cnt -= slots_per_op;
|
|
|
+ if (slot_cnt) {
|
|
|
+ i += slots_per_op;
|
|
|
+ addr += IOP_ADMA_XOR_MAX_BYTE_COUNT;
|
|
|
+ }
|
|
|
+ } while (slot_cnt);
|
|
|
+}
|
|
|
+
|
|
|
+static inline void
|
|
|
+iop_desc_set_pq_src_addr(struct iop_adma_desc_slot *desc, int src_idx,
|
|
|
+ dma_addr_t addr, unsigned char coef)
|
|
|
+{
|
|
|
+ int slot_cnt = desc->slot_cnt, slots_per_op = desc->slots_per_op;
|
|
|
+ struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc, *iter;
|
|
|
+ struct iop13xx_adma_src *src;
|
|
|
+ int i = 0;
|
|
|
+
|
|
|
+ do {
|
|
|
+ iter = iop_hw_desc_slot_idx(hw_desc, i);
|
|
|
+ src = &iter->src[src_idx];
|
|
|
+ src->src_addr = addr;
|
|
|
+ src->pq_upper_src_addr = 0;
|
|
|
+ src->pq_dmlt = coef;
|