Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-only */
0002 /*
0003  * Copyright © 2006, Intel Corporation.
0004  */
0005 #ifndef _ADMA_H
0006 #define _ADMA_H
0007 #include <linux/types.h>
0008 #include <linux/io.h>
0009 #include <linux/platform_data/dma-iop32x.h>
0010 
0011 /* Memory copy units */
0012 #define DMA_CCR(chan)       (chan->mmr_base + 0x0)
0013 #define DMA_CSR(chan)       (chan->mmr_base + 0x4)
0014 #define DMA_DAR(chan)       (chan->mmr_base + 0xc)
0015 #define DMA_NDAR(chan)      (chan->mmr_base + 0x10)
0016 #define DMA_PADR(chan)      (chan->mmr_base + 0x14)
0017 #define DMA_PUADR(chan) (chan->mmr_base + 0x18)
0018 #define DMA_LADR(chan)      (chan->mmr_base + 0x1c)
0019 #define DMA_BCR(chan)       (chan->mmr_base + 0x20)
0020 #define DMA_DCR(chan)       (chan->mmr_base + 0x24)
0021 
0022 /* Application accelerator unit  */
0023 #define AAU_ACR(chan)       (chan->mmr_base + 0x0)
0024 #define AAU_ASR(chan)       (chan->mmr_base + 0x4)
0025 #define AAU_ADAR(chan)      (chan->mmr_base + 0x8)
0026 #define AAU_ANDAR(chan) (chan->mmr_base + 0xc)
0027 #define AAU_SAR(src, chan)  (chan->mmr_base + (0x10 + ((src) << 2)))
0028 #define AAU_DAR(chan)       (chan->mmr_base + 0x20)
0029 #define AAU_ABCR(chan)      (chan->mmr_base + 0x24)
0030 #define AAU_ADCR(chan)      (chan->mmr_base + 0x28)
0031 #define AAU_SAR_EDCR(src_edc)   (chan->mmr_base + (0x02c + ((src_edc-4) << 2)))
0032 #define AAU_EDCR0_IDX   8
0033 #define AAU_EDCR1_IDX   17
0034 #define AAU_EDCR2_IDX   26
0035 
0036 struct iop3xx_aau_desc_ctrl {
0037     unsigned int int_en:1;
0038     unsigned int blk1_cmd_ctrl:3;
0039     unsigned int blk2_cmd_ctrl:3;
0040     unsigned int blk3_cmd_ctrl:3;
0041     unsigned int blk4_cmd_ctrl:3;
0042     unsigned int blk5_cmd_ctrl:3;
0043     unsigned int blk6_cmd_ctrl:3;
0044     unsigned int blk7_cmd_ctrl:3;
0045     unsigned int blk8_cmd_ctrl:3;
0046     unsigned int blk_ctrl:2;
0047     unsigned int dual_xor_en:1;
0048     unsigned int tx_complete:1;
0049     unsigned int zero_result_err:1;
0050     unsigned int zero_result_en:1;
0051     unsigned int dest_write_en:1;
0052 };
0053 
0054 struct iop3xx_aau_e_desc_ctrl {
0055     unsigned int reserved:1;
0056     unsigned int blk1_cmd_ctrl:3;
0057     unsigned int blk2_cmd_ctrl:3;
0058     unsigned int blk3_cmd_ctrl:3;
0059     unsigned int blk4_cmd_ctrl:3;
0060     unsigned int blk5_cmd_ctrl:3;
0061     unsigned int blk6_cmd_ctrl:3;
0062     unsigned int blk7_cmd_ctrl:3;
0063     unsigned int blk8_cmd_ctrl:3;
0064     unsigned int reserved2:7;
0065 };
0066 
0067 struct iop3xx_dma_desc_ctrl {
0068     unsigned int pci_transaction:4;
0069     unsigned int int_en:1;
0070     unsigned int dac_cycle_en:1;
0071     unsigned int mem_to_mem_en:1;
0072     unsigned int crc_data_tx_en:1;
0073     unsigned int crc_gen_en:1;
0074     unsigned int crc_seed_dis:1;
0075     unsigned int reserved:21;
0076     unsigned int crc_tx_complete:1;
0077 };
0078 
0079 struct iop3xx_desc_dma {
0080     u32 next_desc;
0081     union {
0082         u32 pci_src_addr;
0083         u32 pci_dest_addr;
0084         u32 src_addr;
0085     };
0086     union {
0087         u32 upper_pci_src_addr;
0088         u32 upper_pci_dest_addr;
0089     };
0090     union {
0091         u32 local_pci_src_addr;
0092         u32 local_pci_dest_addr;
0093         u32 dest_addr;
0094     };
0095     u32 byte_count;
0096     union {
0097         u32 desc_ctrl;
0098         struct iop3xx_dma_desc_ctrl desc_ctrl_field;
0099     };
0100     u32 crc_addr;
0101 };
0102 
0103 struct iop3xx_desc_aau {
0104     u32 next_desc;
0105     u32 src[4];
0106     u32 dest_addr;
0107     u32 byte_count;
0108     union {
0109         u32 desc_ctrl;
0110         struct iop3xx_aau_desc_ctrl desc_ctrl_field;
0111     };
0112     union {
0113         u32 src_addr;
0114         u32 e_desc_ctrl;
0115         struct iop3xx_aau_e_desc_ctrl e_desc_ctrl_field;
0116     } src_edc[31];
0117 };
0118 
0119 struct iop3xx_aau_gfmr {
0120     unsigned int gfmr1:8;
0121     unsigned int gfmr2:8;
0122     unsigned int gfmr3:8;
0123     unsigned int gfmr4:8;
0124 };
0125 
0126 struct iop3xx_desc_pq_xor {
0127     u32 next_desc;
0128     u32 src[3];
0129     union {
0130         u32 data_mult1;
0131         struct iop3xx_aau_gfmr data_mult1_field;
0132     };
0133     u32 dest_addr;
0134     u32 byte_count;
0135     union {
0136         u32 desc_ctrl;
0137         struct iop3xx_aau_desc_ctrl desc_ctrl_field;
0138     };
0139     union {
0140         u32 src_addr;
0141         u32 e_desc_ctrl;
0142         struct iop3xx_aau_e_desc_ctrl e_desc_ctrl_field;
0143         u32 data_multiplier;
0144         struct iop3xx_aau_gfmr data_mult_field;
0145         u32 reserved;
0146     } src_edc_gfmr[19];
0147 };
0148 
0149 struct iop3xx_desc_dual_xor {
0150     u32 next_desc;
0151     u32 src0_addr;
0152     u32 src1_addr;
0153     u32 h_src_addr;
0154     u32 d_src_addr;
0155     u32 h_dest_addr;
0156     u32 byte_count;
0157     union {
0158         u32 desc_ctrl;
0159         struct iop3xx_aau_desc_ctrl desc_ctrl_field;
0160     };
0161     u32 d_dest_addr;
0162 };
0163 
0164 union iop3xx_desc {
0165     struct iop3xx_desc_aau *aau;
0166     struct iop3xx_desc_dma *dma;
0167     struct iop3xx_desc_pq_xor *pq_xor;
0168     struct iop3xx_desc_dual_xor *dual_xor;
0169     void *ptr;
0170 };
0171 
0172 /* No support for p+q operations */
0173 static inline int
0174 iop_chan_pq_slot_count(size_t len, int src_cnt, int *slots_per_op)
0175 {
0176     BUG();
0177     return 0;
0178 }
0179 
0180 static inline void
0181 iop_desc_init_pq(struct iop_adma_desc_slot *desc, int src_cnt,
0182           unsigned long flags)
0183 {
0184     BUG();
0185 }
0186 
0187 static inline void
0188 iop_desc_set_pq_addr(struct iop_adma_desc_slot *desc, dma_addr_t *addr)
0189 {
0190     BUG();
0191 }
0192 
0193 static inline void
0194 iop_desc_set_pq_src_addr(struct iop_adma_desc_slot *desc, int src_idx,
0195              dma_addr_t addr, unsigned char coef)
0196 {
0197     BUG();
0198 }
0199 
0200 static inline int
0201 iop_chan_pq_zero_sum_slot_count(size_t len, int src_cnt, int *slots_per_op)
0202 {
0203     BUG();
0204     return 0;
0205 }
0206 
0207 static inline void
0208 iop_desc_init_pq_zero_sum(struct iop_adma_desc_slot *desc, int src_cnt,
0209               unsigned long flags)
0210 {
0211     BUG();
0212 }
0213 
0214 static inline void
0215 iop_desc_set_pq_zero_sum_byte_count(struct iop_adma_desc_slot *desc, u32 len)
0216 {
0217     BUG();
0218 }
0219 
0220 #define iop_desc_set_pq_zero_sum_src_addr iop_desc_set_pq_src_addr
0221 
0222 static inline void
0223 iop_desc_set_pq_zero_sum_addr(struct iop_adma_desc_slot *desc, int pq_idx,
0224                   dma_addr_t *src)
0225 {
0226     BUG();
0227 }
0228 
0229 static inline int iop_adma_get_max_xor(void)
0230 {
0231     return 32;
0232 }
0233 
0234 static inline int iop_adma_get_max_pq(void)
0235 {
0236     BUG();
0237     return 0;
0238 }
0239 
0240 static inline u32 iop_chan_get_current_descriptor(struct iop_adma_chan *chan)
0241 {
0242     int id = chan->device->id;
0243 
0244     switch (id) {
0245     case DMA0_ID:
0246     case DMA1_ID:
0247         return __raw_readl(DMA_DAR(chan));
0248     case AAU_ID:
0249         return __raw_readl(AAU_ADAR(chan));
0250     default:
0251         BUG();
0252     }
0253     return 0;
0254 }
0255 
0256 static inline void iop_chan_set_next_descriptor(struct iop_adma_chan *chan,
0257                         u32 next_desc_addr)
0258 {
0259     int id = chan->device->id;
0260 
0261     switch (id) {
0262     case DMA0_ID:
0263     case DMA1_ID:
0264         __raw_writel(next_desc_addr, DMA_NDAR(chan));
0265         break;
0266     case AAU_ID:
0267         __raw_writel(next_desc_addr, AAU_ANDAR(chan));
0268         break;
0269     }
0270 
0271 }
0272 
0273 #define IOP_ADMA_STATUS_BUSY (1 << 10)
0274 #define IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT (1024)
0275 #define IOP_ADMA_XOR_MAX_BYTE_COUNT (16 * 1024 * 1024)
0276 #define IOP_ADMA_MAX_BYTE_COUNT (16 * 1024 * 1024)
0277 
0278 static inline int iop_chan_is_busy(struct iop_adma_chan *chan)
0279 {
0280     u32 status = __raw_readl(DMA_CSR(chan));
0281     return (status & IOP_ADMA_STATUS_BUSY) ? 1 : 0;
0282 }
0283 
0284 static inline int iop_desc_is_aligned(struct iop_adma_desc_slot *desc,
0285                     int num_slots)
0286 {
0287     /* num_slots will only ever be 1, 2, 4, or 8 */
0288     return (desc->idx & (num_slots - 1)) ? 0 : 1;
0289 }
0290 
0291 /* to do: support large (i.e. > hw max) buffer sizes */
0292 static inline int iop_chan_memcpy_slot_count(size_t len, int *slots_per_op)
0293 {
0294     *slots_per_op = 1;
0295     return 1;
0296 }
0297 
0298 /* to do: support large (i.e. > hw max) buffer sizes */
0299 static inline int iop_chan_memset_slot_count(size_t len, int *slots_per_op)
0300 {
0301     *slots_per_op = 1;
0302     return 1;
0303 }
0304 
0305 static inline int iop3xx_aau_xor_slot_count(size_t len, int src_cnt,
0306                     int *slots_per_op)
0307 {
0308     static const char slot_count_table[] = {
0309                         1, 1, 1, 1, /* 01 - 04 */
0310                         2, 2, 2, 2, /* 05 - 08 */
0311                         4, 4, 4, 4, /* 09 - 12 */
0312                         4, 4, 4, 4, /* 13 - 16 */
0313                         8, 8, 8, 8, /* 17 - 20 */
0314                         8, 8, 8, 8, /* 21 - 24 */
0315                         8, 8, 8, 8, /* 25 - 28 */
0316                         8, 8, 8, 8, /* 29 - 32 */
0317                           };
0318     *slots_per_op = slot_count_table[src_cnt - 1];
0319     return *slots_per_op;
0320 }
0321 
0322 static inline int
0323 iop_chan_interrupt_slot_count(int *slots_per_op, struct iop_adma_chan *chan)
0324 {
0325     switch (chan->device->id) {
0326     case DMA0_ID:
0327     case DMA1_ID:
0328         return iop_chan_memcpy_slot_count(0, slots_per_op);
0329     case AAU_ID:
0330         return iop3xx_aau_xor_slot_count(0, 2, slots_per_op);
0331     default:
0332         BUG();
0333     }
0334     return 0;
0335 }
0336 
0337 static inline int iop_chan_xor_slot_count(size_t len, int src_cnt,
0338                         int *slots_per_op)
0339 {
0340     int slot_cnt = iop3xx_aau_xor_slot_count(len, src_cnt, slots_per_op);
0341 
0342     if (len <= IOP_ADMA_XOR_MAX_BYTE_COUNT)
0343         return slot_cnt;
0344 
0345     len -= IOP_ADMA_XOR_MAX_BYTE_COUNT;
0346     while (len > IOP_ADMA_XOR_MAX_BYTE_COUNT) {
0347         len -= IOP_ADMA_XOR_MAX_BYTE_COUNT;
0348         slot_cnt += *slots_per_op;
0349     }
0350 
0351     slot_cnt += *slots_per_op;
0352 
0353     return slot_cnt;
0354 }
0355 
0356 /* zero sum on iop3xx is limited to 1k at a time so it requires multiple
0357  * descriptors
0358  */
0359 static inline int iop_chan_zero_sum_slot_count(size_t len, int src_cnt,
0360                         int *slots_per_op)
0361 {
0362     int slot_cnt = iop3xx_aau_xor_slot_count(len, src_cnt, slots_per_op);
0363 
0364     if (len <= IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT)
0365         return slot_cnt;
0366 
0367     len -= IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT;
0368     while (len > IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT) {
0369         len -= IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT;
0370         slot_cnt += *slots_per_op;
0371     }
0372 
0373     slot_cnt += *slots_per_op;
0374 
0375     return slot_cnt;
0376 }
0377 
0378 static inline u32 iop_desc_get_byte_count(struct iop_adma_desc_slot *desc,
0379                     struct iop_adma_chan *chan)
0380 {
0381     union iop3xx_desc hw_desc = { .ptr = desc->hw_desc, };
0382 
0383     switch (chan->device->id) {
0384     case DMA0_ID:
0385     case DMA1_ID:
0386         return hw_desc.dma->byte_count;
0387     case AAU_ID:
0388         return hw_desc.aau->byte_count;
0389     default:
0390         BUG();
0391     }
0392     return 0;
0393 }
0394 
0395 /* translate the src_idx to a descriptor word index */
0396 static inline int __desc_idx(int src_idx)
0397 {
0398     static const int desc_idx_table[] = { 0, 0, 0, 0,
0399                           0, 1, 2, 3,
0400                           5, 6, 7, 8,
0401                           9, 10, 11, 12,
0402                           14, 15, 16, 17,
0403                           18, 19, 20, 21,
0404                           23, 24, 25, 26,
0405                           27, 28, 29, 30,
0406                         };
0407 
0408     return desc_idx_table[src_idx];
0409 }
0410 
0411 static inline u32 iop_desc_get_src_addr(struct iop_adma_desc_slot *desc,
0412                     struct iop_adma_chan *chan,
0413                     int src_idx)
0414 {
0415     union iop3xx_desc hw_desc = { .ptr = desc->hw_desc, };
0416 
0417     switch (chan->device->id) {
0418     case DMA0_ID:
0419     case DMA1_ID:
0420         return hw_desc.dma->src_addr;
0421     case AAU_ID:
0422         break;
0423     default:
0424         BUG();
0425     }
0426 
0427     if (src_idx < 4)
0428         return hw_desc.aau->src[src_idx];
0429     else
0430         return hw_desc.aau->src_edc[__desc_idx(src_idx)].src_addr;
0431 }
0432 
0433 static inline void iop3xx_aau_desc_set_src_addr(struct iop3xx_desc_aau *hw_desc,
0434                     int src_idx, dma_addr_t addr)
0435 {
0436     if (src_idx < 4)
0437         hw_desc->src[src_idx] = addr;
0438     else
0439         hw_desc->src_edc[__desc_idx(src_idx)].src_addr = addr;
0440 }
0441 
0442 static inline void
0443 iop_desc_init_memcpy(struct iop_adma_desc_slot *desc, unsigned long flags)
0444 {
0445     struct iop3xx_desc_dma *hw_desc = desc->hw_desc;
0446     union {
0447         u32 value;
0448         struct iop3xx_dma_desc_ctrl field;
0449     } u_desc_ctrl;
0450 
0451     u_desc_ctrl.value = 0;
0452     u_desc_ctrl.field.mem_to_mem_en = 1;
0453     u_desc_ctrl.field.pci_transaction = 0xe; /* memory read block */
0454     u_desc_ctrl.field.int_en = flags & DMA_PREP_INTERRUPT;
0455     hw_desc->desc_ctrl = u_desc_ctrl.value;
0456     hw_desc->upper_pci_src_addr = 0;
0457     hw_desc->crc_addr = 0;
0458 }
0459 
0460 static inline void
0461 iop_desc_init_memset(struct iop_adma_desc_slot *desc, unsigned long flags)
0462 {
0463     struct iop3xx_desc_aau *hw_desc = desc->hw_desc;
0464     union {
0465         u32 value;
0466         struct iop3xx_aau_desc_ctrl field;
0467     } u_desc_ctrl;
0468 
0469     u_desc_ctrl.value = 0;
0470     u_desc_ctrl.field.blk1_cmd_ctrl = 0x2; /* memory block fill */
0471     u_desc_ctrl.field.dest_write_en = 1;
0472     u_desc_ctrl.field.int_en = flags & DMA_PREP_INTERRUPT;
0473     hw_desc->desc_ctrl = u_desc_ctrl.value;
0474 }
0475 
0476 static inline u32
0477 iop3xx_desc_init_xor(struct iop3xx_desc_aau *hw_desc, int src_cnt,
0478              unsigned long flags)
0479 {
0480     int i, shift;
0481     u32 edcr;
0482     union {
0483         u32 value;
0484         struct iop3xx_aau_desc_ctrl field;
0485     } u_desc_ctrl;
0486 
0487     u_desc_ctrl.value = 0;
0488     switch (src_cnt) {
0489     case 25 ... 32:
0490         u_desc_ctrl.field.blk_ctrl = 0x3; /* use EDCR[2:0] */
0491         edcr = 0;
0492         shift = 1;
0493         for (i = 24; i < src_cnt; i++) {
0494             edcr |= (1 << shift);
0495             shift += 3;
0496         }
0497         hw_desc->src_edc[AAU_EDCR2_IDX].e_desc_ctrl = edcr;
0498         src_cnt = 24;
0499         fallthrough;
0500     case 17 ... 24:
0501         if (!u_desc_ctrl.field.blk_ctrl) {
0502             hw_desc->src_edc[AAU_EDCR2_IDX].e_desc_ctrl = 0;
0503             u_desc_ctrl.field.blk_ctrl = 0x3; /* use EDCR[2:0] */
0504         }
0505         edcr = 0;
0506         shift = 1;
0507         for (i = 16; i < src_cnt; i++) {
0508             edcr |= (1 << shift);
0509             shift += 3;
0510         }
0511         hw_desc->src_edc[AAU_EDCR1_IDX].e_desc_ctrl = edcr;
0512         src_cnt = 16;
0513         fallthrough;
0514     case 9 ... 16:
0515         if (!u_desc_ctrl.field.blk_ctrl)
0516             u_desc_ctrl.field.blk_ctrl = 0x2; /* use EDCR0 */
0517         edcr = 0;
0518         shift = 1;
0519         for (i = 8; i < src_cnt; i++) {
0520             edcr |= (1 << shift);
0521             shift += 3;
0522         }
0523         hw_desc->src_edc[AAU_EDCR0_IDX].e_desc_ctrl = edcr;
0524         src_cnt = 8;
0525         fallthrough;
0526     case 2 ... 8:
0527         shift = 1;
0528         for (i = 0; i < src_cnt; i++) {
0529             u_desc_ctrl.value |= (1 << shift);
0530             shift += 3;
0531         }
0532 
0533         if (!u_desc_ctrl.field.blk_ctrl && src_cnt > 4)
0534             u_desc_ctrl.field.blk_ctrl = 0x1; /* use mini-desc */
0535     }
0536 
0537     u_desc_ctrl.field.dest_write_en = 1;
0538     u_desc_ctrl.field.blk1_cmd_ctrl = 0x7; /* direct fill */
0539     u_desc_ctrl.field.int_en = flags & DMA_PREP_INTERRUPT;
0540     hw_desc->desc_ctrl = u_desc_ctrl.value;
0541 
0542     return u_desc_ctrl.value;
0543 }
0544 
0545 static inline void
0546 iop_desc_init_xor(struct iop_adma_desc_slot *desc, int src_cnt,
0547           unsigned long flags)
0548 {
0549     iop3xx_desc_init_xor(desc->hw_desc, src_cnt, flags);
0550 }
0551 
0552 /* return the number of operations */
0553 static inline int
0554 iop_desc_init_zero_sum(struct iop_adma_desc_slot *desc, int src_cnt,
0555                unsigned long flags)
0556 {
0557     int slot_cnt = desc->slot_cnt, slots_per_op = desc->slots_per_op;
0558     struct iop3xx_desc_aau *hw_desc, *prev_hw_desc, *iter;
0559     union {
0560         u32 value;
0561         struct iop3xx_aau_desc_ctrl field;
0562     } u_desc_ctrl;
0563     int i, j;
0564 
0565     hw_desc = desc->hw_desc;
0566 
0567     for (i = 0, j = 0; (slot_cnt -= slots_per_op) >= 0;
0568         i += slots_per_op, j++) {
0569         iter = iop_hw_desc_slot_idx(hw_desc, i);
0570         u_desc_ctrl.value = iop3xx_desc_init_xor(iter, src_cnt, flags);
0571         u_desc_ctrl.field.dest_write_en = 0;
0572         u_desc_ctrl.field.zero_result_en = 1;
0573         u_desc_ctrl.field.int_en = flags & DMA_PREP_INTERRUPT;
0574         iter->desc_ctrl = u_desc_ctrl.value;
0575 
0576         /* for the subsequent descriptors preserve the store queue
0577          * and chain them together
0578          */
0579         if (i) {
0580             prev_hw_desc =
0581                 iop_hw_desc_slot_idx(hw_desc, i - slots_per_op);
0582             prev_hw_desc->next_desc =
0583                 (u32) (desc->async_tx.phys + (i << 5));
0584         }
0585     }
0586 
0587     return j;
0588 }
0589 
0590 static inline void
0591 iop_desc_init_null_xor(struct iop_adma_desc_slot *desc, int src_cnt,
0592                unsigned long flags)
0593 {
0594     struct iop3xx_desc_aau *hw_desc = desc->hw_desc;
0595     union {
0596         u32 value;
0597         struct iop3xx_aau_desc_ctrl field;
0598     } u_desc_ctrl;
0599 
0600     u_desc_ctrl.value = 0;
0601     switch (src_cnt) {
0602     case 25 ... 32:
0603         u_desc_ctrl.field.blk_ctrl = 0x3; /* use EDCR[2:0] */
0604         hw_desc->src_edc[AAU_EDCR2_IDX].e_desc_ctrl = 0;
0605         fallthrough;
0606     case 17 ... 24:
0607         if (!u_desc_ctrl.field.blk_ctrl) {
0608             hw_desc->src_edc[AAU_EDCR2_IDX].e_desc_ctrl = 0;
0609             u_desc_ctrl.field.blk_ctrl = 0x3; /* use EDCR[2:0] */
0610         }
0611         hw_desc->src_edc[AAU_EDCR1_IDX].e_desc_ctrl = 0;
0612         fallthrough;
0613     case 9 ... 16:
0614         if (!u_desc_ctrl.field.blk_ctrl)
0615             u_desc_ctrl.field.blk_ctrl = 0x2; /* use EDCR0 */
0616         hw_desc->src_edc[AAU_EDCR0_IDX].e_desc_ctrl = 0;
0617         fallthrough;
0618     case 1 ... 8:
0619         if (!u_desc_ctrl.field.blk_ctrl && src_cnt > 4)
0620             u_desc_ctrl.field.blk_ctrl = 0x1; /* use mini-desc */
0621     }
0622 
0623     u_desc_ctrl.field.dest_write_en = 0;
0624     u_desc_ctrl.field.int_en = flags & DMA_PREP_INTERRUPT;
0625     hw_desc->desc_ctrl = u_desc_ctrl.value;
0626 }
0627 
0628 static inline void iop_desc_set_byte_count(struct iop_adma_desc_slot *desc,
0629                     struct iop_adma_chan *chan,
0630                     u32 byte_count)
0631 {
0632     union iop3xx_desc hw_desc = { .ptr = desc->hw_desc, };
0633 
0634     switch (chan->device->id) {
0635     case DMA0_ID:
0636     case DMA1_ID:
0637         hw_desc.dma->byte_count = byte_count;
0638         break;
0639     case AAU_ID:
0640         hw_desc.aau->byte_count = byte_count;
0641         break;
0642     default:
0643         BUG();
0644     }
0645 }
0646 
0647 static inline void
0648 iop_desc_init_interrupt(struct iop_adma_desc_slot *desc,
0649             struct iop_adma_chan *chan)
0650 {
0651     union iop3xx_desc hw_desc = { .ptr = desc->hw_desc, };
0652 
0653     switch (chan->device->id) {
0654     case DMA0_ID:
0655     case DMA1_ID:
0656         iop_desc_init_memcpy(desc, 1);
0657         hw_desc.dma->byte_count = 0;
0658         hw_desc.dma->dest_addr = 0;
0659         hw_desc.dma->src_addr = 0;
0660         break;
0661     case AAU_ID:
0662         iop_desc_init_null_xor(desc, 2, 1);
0663         hw_desc.aau->byte_count = 0;
0664         hw_desc.aau->dest_addr = 0;
0665         hw_desc.aau->src[0] = 0;
0666         hw_desc.aau->src[1] = 0;
0667         break;
0668     default:
0669         BUG();
0670     }
0671 }
0672 
0673 static inline void
0674 iop_desc_set_zero_sum_byte_count(struct iop_adma_desc_slot *desc, u32 len)
0675 {
0676     int slots_per_op = desc->slots_per_op;
0677     struct iop3xx_desc_aau *hw_desc = desc->hw_desc, *iter;
0678     int i = 0;
0679 
0680     if (len <= IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT) {
0681         hw_desc->byte_count = len;
0682     } else {
0683         do {
0684             iter = iop_hw_desc_slot_idx(hw_desc, i);
0685             iter->byte_count = IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT;
0686             len -= IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT;
0687             i += slots_per_op;
0688         } while (len > IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT);
0689 
0690         iter = iop_hw_desc_slot_idx(hw_desc, i);
0691         iter->byte_count = len;
0692     }
0693 }
0694 
0695 static inline void iop_desc_set_dest_addr(struct iop_adma_desc_slot *desc,
0696                     struct iop_adma_chan *chan,
0697                     dma_addr_t addr)
0698 {
0699     union iop3xx_desc hw_desc = { .ptr = desc->hw_desc, };
0700 
0701     switch (chan->device->id) {
0702     case DMA0_ID:
0703     case DMA1_ID:
0704         hw_desc.dma->dest_addr = addr;
0705         break;
0706     case AAU_ID:
0707         hw_desc.aau->dest_addr = addr;
0708         break;
0709     default:
0710         BUG();
0711     }
0712 }
0713 
0714 static inline void iop_desc_set_memcpy_src_addr(struct iop_adma_desc_slot *desc,
0715                     dma_addr_t addr)
0716 {
0717     struct iop3xx_desc_dma *hw_desc = desc->hw_desc;
0718     hw_desc->src_addr = addr;
0719 }
0720 
0721 static inline void
0722 iop_desc_set_zero_sum_src_addr(struct iop_adma_desc_slot *desc, int src_idx,
0723                 dma_addr_t addr)
0724 {
0725 
0726     struct iop3xx_desc_aau *hw_desc = desc->hw_desc, *iter;
0727     int slot_cnt = desc->slot_cnt, slots_per_op = desc->slots_per_op;
0728     int i;
0729 
0730     for (i = 0; (slot_cnt -= slots_per_op) >= 0;
0731         i += slots_per_op, addr += IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT) {
0732         iter = iop_hw_desc_slot_idx(hw_desc, i);
0733         iop3xx_aau_desc_set_src_addr(iter, src_idx, addr);
0734     }
0735 }
0736 
0737 static inline void iop_desc_set_xor_src_addr(struct iop_adma_desc_slot *desc,
0738                     int src_idx, dma_addr_t addr)
0739 {
0740 
0741     struct iop3xx_desc_aau *hw_desc = desc->hw_desc, *iter;
0742     int slot_cnt = desc->slot_cnt, slots_per_op = desc->slots_per_op;
0743     int i;
0744 
0745     for (i = 0; (slot_cnt -= slots_per_op) >= 0;
0746         i += slots_per_op, addr += IOP_ADMA_XOR_MAX_BYTE_COUNT) {
0747         iter = iop_hw_desc_slot_idx(hw_desc, i);
0748         iop3xx_aau_desc_set_src_addr(iter, src_idx, addr);
0749     }
0750 }
0751 
0752 static inline void iop_desc_set_next_desc(struct iop_adma_desc_slot *desc,
0753                     u32 next_desc_addr)
0754 {
0755     /* hw_desc->next_desc is the same location for all channels */
0756     union iop3xx_desc hw_desc = { .ptr = desc->hw_desc, };
0757 
0758     iop_paranoia(hw_desc.dma->next_desc);
0759     hw_desc.dma->next_desc = next_desc_addr;
0760 }
0761 
0762 static inline u32 iop_desc_get_next_desc(struct iop_adma_desc_slot *desc)
0763 {
0764     /* hw_desc->next_desc is the same location for all channels */
0765     union iop3xx_desc hw_desc = { .ptr = desc->hw_desc, };
0766     return hw_desc.dma->next_desc;
0767 }
0768 
0769 static inline void iop_desc_clear_next_desc(struct iop_adma_desc_slot *desc)
0770 {
0771     /* hw_desc->next_desc is the same location for all channels */
0772     union iop3xx_desc hw_desc = { .ptr = desc->hw_desc, };
0773     hw_desc.dma->next_desc = 0;
0774 }
0775 
0776 static inline void iop_desc_set_block_fill_val(struct iop_adma_desc_slot *desc,
0777                         u32 val)
0778 {
0779     struct iop3xx_desc_aau *hw_desc = desc->hw_desc;
0780     hw_desc->src[0] = val;
0781 }
0782 
0783 static inline enum sum_check_flags
0784 iop_desc_get_zero_result(struct iop_adma_desc_slot *desc)
0785 {
0786     struct iop3xx_desc_aau *hw_desc = desc->hw_desc;
0787     struct iop3xx_aau_desc_ctrl desc_ctrl = hw_desc->desc_ctrl_field;
0788 
0789     iop_paranoia(!(desc_ctrl.tx_complete && desc_ctrl.zero_result_en));
0790     return desc_ctrl.zero_result_err << SUM_CHECK_P;
0791 }
0792 
0793 static inline void iop_chan_append(struct iop_adma_chan *chan)
0794 {
0795     u32 dma_chan_ctrl;
0796 
0797     dma_chan_ctrl = __raw_readl(DMA_CCR(chan));
0798     dma_chan_ctrl |= 0x2;
0799     __raw_writel(dma_chan_ctrl, DMA_CCR(chan));
0800 }
0801 
0802 static inline u32 iop_chan_get_status(struct iop_adma_chan *chan)
0803 {
0804     return __raw_readl(DMA_CSR(chan));
0805 }
0806 
0807 static inline void iop_chan_disable(struct iop_adma_chan *chan)
0808 {
0809     u32 dma_chan_ctrl = __raw_readl(DMA_CCR(chan));
0810     dma_chan_ctrl &= ~1;
0811     __raw_writel(dma_chan_ctrl, DMA_CCR(chan));
0812 }
0813 
0814 static inline void iop_chan_enable(struct iop_adma_chan *chan)
0815 {
0816     u32 dma_chan_ctrl = __raw_readl(DMA_CCR(chan));
0817 
0818     dma_chan_ctrl |= 1;
0819     __raw_writel(dma_chan_ctrl, DMA_CCR(chan));
0820 }
0821 
0822 static inline void iop_adma_device_clear_eot_status(struct iop_adma_chan *chan)
0823 {
0824     u32 status = __raw_readl(DMA_CSR(chan));
0825     status &= (1 << 9);
0826     __raw_writel(status, DMA_CSR(chan));
0827 }
0828 
0829 static inline void iop_adma_device_clear_eoc_status(struct iop_adma_chan *chan)
0830 {
0831     u32 status = __raw_readl(DMA_CSR(chan));
0832     status &= (1 << 8);
0833     __raw_writel(status, DMA_CSR(chan));
0834 }
0835 
0836 static inline void iop_adma_device_clear_err_status(struct iop_adma_chan *chan)
0837 {
0838     u32 status = __raw_readl(DMA_CSR(chan));
0839 
0840     switch (chan->device->id) {
0841     case DMA0_ID:
0842     case DMA1_ID:
0843         status &= (1 << 5) | (1 << 3) | (1 << 2) | (1 << 1);
0844         break;
0845     case AAU_ID:
0846         status &= (1 << 5);
0847         break;
0848     default:
0849         BUG();
0850     }
0851 
0852     __raw_writel(status, DMA_CSR(chan));
0853 }
0854 
0855 static inline int
0856 iop_is_err_int_parity(unsigned long status, struct iop_adma_chan *chan)
0857 {
0858     return 0;
0859 }
0860 
0861 static inline int
0862 iop_is_err_mcu_abort(unsigned long status, struct iop_adma_chan *chan)
0863 {
0864     return 0;
0865 }
0866 
0867 static inline int
0868 iop_is_err_int_tabort(unsigned long status, struct iop_adma_chan *chan)
0869 {
0870     return 0;
0871 }
0872 
0873 static inline int
0874 iop_is_err_int_mabort(unsigned long status, struct iop_adma_chan *chan)
0875 {
0876     return test_bit(5, &status);
0877 }
0878 
0879 static inline int
0880 iop_is_err_pci_tabort(unsigned long status, struct iop_adma_chan *chan)
0881 {
0882     switch (chan->device->id) {
0883     case DMA0_ID:
0884     case DMA1_ID:
0885         return test_bit(2, &status);
0886     default:
0887         return 0;
0888     }
0889 }
0890 
0891 static inline int
0892 iop_is_err_pci_mabort(unsigned long status, struct iop_adma_chan *chan)
0893 {
0894     switch (chan->device->id) {
0895     case DMA0_ID:
0896     case DMA1_ID:
0897         return test_bit(3, &status);
0898     default:
0899         return 0;
0900     }
0901 }
0902 
0903 static inline int
0904 iop_is_err_split_tx(unsigned long status, struct iop_adma_chan *chan)
0905 {
0906     switch (chan->device->id) {
0907     case DMA0_ID:
0908     case DMA1_ID:
0909         return test_bit(1, &status);
0910     default:
0911         return 0;
0912     }
0913 }
0914 #endif /* _ADMA_H */