linux/arch/arm/include/asm/hardware/iop3xx-adma.h
<<
>>
Prefs
   1/*
   2 * Copyright © 2006, Intel Corporation.
   3 *
   4 * This program is free software; you can redistribute it and/or modify it
   5 * under the terms and conditions of the GNU General Public License,
   6 * version 2, as published by the Free Software Foundation.
   7 *
   8 * This program is distributed in the hope it will be useful, but WITHOUT
   9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  10 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  11 * more details.
  12 *
  13 * You should have received a copy of the GNU General Public License along with
  14 * this program; if not, write to the Free Software Foundation, Inc.,
  15 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
  16 *
  17 */
  18#ifndef _ADMA_H
  19#define _ADMA_H
  20#include <linux/types.h>
  21#include <linux/io.h>
  22#include <mach/hardware.h>
  23#include <asm/hardware/iop_adma.h>
  24
  25/* Memory copy units */
  26#define DMA_CCR(chan)           (chan->mmr_base + 0x0)
  27#define DMA_CSR(chan)           (chan->mmr_base + 0x4)
  28#define DMA_DAR(chan)           (chan->mmr_base + 0xc)
  29#define DMA_NDAR(chan)          (chan->mmr_base + 0x10)
  30#define DMA_PADR(chan)          (chan->mmr_base + 0x14)
  31#define DMA_PUADR(chan) (chan->mmr_base + 0x18)
  32#define DMA_LADR(chan)          (chan->mmr_base + 0x1c)
  33#define DMA_BCR(chan)           (chan->mmr_base + 0x20)
  34#define DMA_DCR(chan)           (chan->mmr_base + 0x24)
  35
  36/* Application accelerator unit  */
  37#define AAU_ACR(chan)           (chan->mmr_base + 0x0)
  38#define AAU_ASR(chan)           (chan->mmr_base + 0x4)
  39#define AAU_ADAR(chan)          (chan->mmr_base + 0x8)
  40#define AAU_ANDAR(chan) (chan->mmr_base + 0xc)
  41#define AAU_SAR(src, chan)      (chan->mmr_base + (0x10 + ((src) << 2)))
  42#define AAU_DAR(chan)           (chan->mmr_base + 0x20)
  43#define AAU_ABCR(chan)          (chan->mmr_base + 0x24)
  44#define AAU_ADCR(chan)          (chan->mmr_base + 0x28)
  45#define AAU_SAR_EDCR(src_edc)   (chan->mmr_base + (0x02c + ((src_edc-4) << 2)))
  46#define AAU_EDCR0_IDX   8
  47#define AAU_EDCR1_IDX   17
  48#define AAU_EDCR2_IDX   26
  49
  50#define DMA0_ID 0
  51#define DMA1_ID 1
  52#define AAU_ID 2
  53
  54struct iop3xx_aau_desc_ctrl {
  55        unsigned int int_en:1;
  56        unsigned int blk1_cmd_ctrl:3;
  57        unsigned int blk2_cmd_ctrl:3;
  58        unsigned int blk3_cmd_ctrl:3;
  59        unsigned int blk4_cmd_ctrl:3;
  60        unsigned int blk5_cmd_ctrl:3;
  61        unsigned int blk6_cmd_ctrl:3;
  62        unsigned int blk7_cmd_ctrl:3;
  63        unsigned int blk8_cmd_ctrl:3;
  64        unsigned int blk_ctrl:2;
  65        unsigned int dual_xor_en:1;
  66        unsigned int tx_complete:1;
  67        unsigned int zero_result_err:1;
  68        unsigned int zero_result_en:1;
  69        unsigned int dest_write_en:1;
  70};
  71
  72struct iop3xx_aau_e_desc_ctrl {
  73        unsigned int reserved:1;
  74        unsigned int blk1_cmd_ctrl:3;
  75        unsigned int blk2_cmd_ctrl:3;
  76        unsigned int blk3_cmd_ctrl:3;
  77        unsigned int blk4_cmd_ctrl:3;
  78        unsigned int blk5_cmd_ctrl:3;
  79        unsigned int blk6_cmd_ctrl:3;
  80        unsigned int blk7_cmd_ctrl:3;
  81        unsigned int blk8_cmd_ctrl:3;
  82        unsigned int reserved2:7;
  83};
  84
  85struct iop3xx_dma_desc_ctrl {
  86        unsigned int pci_transaction:4;
  87        unsigned int int_en:1;
  88        unsigned int dac_cycle_en:1;
  89        unsigned int mem_to_mem_en:1;
  90        unsigned int crc_data_tx_en:1;
  91        unsigned int crc_gen_en:1;
  92        unsigned int crc_seed_dis:1;
  93        unsigned int reserved:21;
  94        unsigned int crc_tx_complete:1;
  95};
  96
  97struct iop3xx_desc_dma {
  98        u32 next_desc;
  99        union {
 100                u32 pci_src_addr;
 101                u32 pci_dest_addr;
 102                u32 src_addr;
 103        };
 104        union {
 105                u32 upper_pci_src_addr;
 106                u32 upper_pci_dest_addr;
 107        };
 108        union {
 109                u32 local_pci_src_addr;
 110                u32 local_pci_dest_addr;
 111                u32 dest_addr;
 112        };
 113        u32 byte_count;
 114        union {
 115                u32 desc_ctrl;
 116                struct iop3xx_dma_desc_ctrl desc_ctrl_field;
 117        };
 118        u32 crc_addr;
 119};
 120
 121struct iop3xx_desc_aau {
 122        u32 next_desc;
 123        u32 src[4];
 124        u32 dest_addr;
 125        u32 byte_count;
 126        union {
 127                u32 desc_ctrl;
 128                struct iop3xx_aau_desc_ctrl desc_ctrl_field;
 129        };
 130        union {
 131                u32 src_addr;
 132                u32 e_desc_ctrl;
 133                struct iop3xx_aau_e_desc_ctrl e_desc_ctrl_field;
 134        } src_edc[31];
 135};
 136
 137struct iop3xx_aau_gfmr {
 138        unsigned int gfmr1:8;
 139        unsigned int gfmr2:8;
 140        unsigned int gfmr3:8;
 141        unsigned int gfmr4:8;
 142};
 143
 144struct iop3xx_desc_pq_xor {
 145        u32 next_desc;
 146        u32 src[3];
 147        union {
 148                u32 data_mult1;
 149                struct iop3xx_aau_gfmr data_mult1_field;
 150        };
 151        u32 dest_addr;
 152        u32 byte_count;
 153        union {
 154                u32 desc_ctrl;
 155                struct iop3xx_aau_desc_ctrl desc_ctrl_field;
 156        };
 157        union {
 158                u32 src_addr;
 159                u32 e_desc_ctrl;
 160                struct iop3xx_aau_e_desc_ctrl e_desc_ctrl_field;
 161                u32 data_multiplier;
 162                struct iop3xx_aau_gfmr data_mult_field;
 163                u32 reserved;
 164        } src_edc_gfmr[19];
 165};
 166
 167struct iop3xx_desc_dual_xor {
 168        u32 next_desc;
 169        u32 src0_addr;
 170        u32 src1_addr;
 171        u32 h_src_addr;
 172        u32 d_src_addr;
 173        u32 h_dest_addr;
 174        u32 byte_count;
 175        union {
 176                u32 desc_ctrl;
 177                struct iop3xx_aau_desc_ctrl desc_ctrl_field;
 178        };
 179        u32 d_dest_addr;
 180};
 181
 182union iop3xx_desc {
 183        struct iop3xx_desc_aau *aau;
 184        struct iop3xx_desc_dma *dma;
 185        struct iop3xx_desc_pq_xor *pq_xor;
 186        struct iop3xx_desc_dual_xor *dual_xor;
 187        void *ptr;
 188};
 189
 190/* No support for p+q operations */
 191static inline int
 192iop_chan_pq_slot_count(size_t len, int src_cnt, int *slots_per_op)
 193{
 194        BUG();
 195        return 0;
 196}
 197
 198static inline void
 199iop_desc_init_pq(struct iop_adma_desc_slot *desc, int src_cnt,
 200                  unsigned long flags)
 201{
 202        BUG();
 203}
 204
 205static inline void
 206iop_desc_set_pq_addr(struct iop_adma_desc_slot *desc, dma_addr_t *addr)
 207{
 208        BUG();
 209}
 210
 211static inline void
 212iop_desc_set_pq_src_addr(struct iop_adma_desc_slot *desc, int src_idx,
 213                         dma_addr_t addr, unsigned char coef)
 214{
 215        BUG();
 216}
 217
 218static inline int
 219iop_chan_pq_zero_sum_slot_count(size_t len, int src_cnt, int *slots_per_op)
 220{
 221        BUG();
 222        return 0;
 223}
 224
 225static inline void
 226iop_desc_init_pq_zero_sum(struct iop_adma_desc_slot *desc, int src_cnt,
 227                          unsigned long flags)
 228{
 229        BUG();
 230}
 231
 232static inline void
 233iop_desc_set_pq_zero_sum_byte_count(struct iop_adma_desc_slot *desc, u32 len)
 234{
 235        BUG();
 236}
 237
 238#define iop_desc_set_pq_zero_sum_src_addr iop_desc_set_pq_src_addr
 239
 240static inline void
 241iop_desc_set_pq_zero_sum_addr(struct iop_adma_desc_slot *desc, int pq_idx,
 242                              dma_addr_t *src)
 243{
 244        BUG();
 245}
 246
 247static inline int iop_adma_get_max_xor(void)
 248{
 249        return 32;
 250}
 251
 252static inline int iop_adma_get_max_pq(void)
 253{
 254        BUG();
 255        return 0;
 256}
 257
 258static inline u32 iop_chan_get_current_descriptor(struct iop_adma_chan *chan)
 259{
 260        int id = chan->device->id;
 261
 262        switch (id) {
 263        case DMA0_ID:
 264        case DMA1_ID:
 265                return __raw_readl(DMA_DAR(chan));
 266        case AAU_ID:
 267                return __raw_readl(AAU_ADAR(chan));
 268        default:
 269                BUG();
 270        }
 271        return 0;
 272}
 273
 274static inline void iop_chan_set_next_descriptor(struct iop_adma_chan *chan,
 275                                                u32 next_desc_addr)
 276{
 277        int id = chan->device->id;
 278
 279        switch (id) {
 280        case DMA0_ID:
 281        case DMA1_ID:
 282                __raw_writel(next_desc_addr, DMA_NDAR(chan));
 283                break;
 284        case AAU_ID:
 285                __raw_writel(next_desc_addr, AAU_ANDAR(chan));
 286                break;
 287        }
 288
 289}
 290
 291#define IOP_ADMA_STATUS_BUSY (1 << 10)
 292#define IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT (1024)
 293#define IOP_ADMA_XOR_MAX_BYTE_COUNT (16 * 1024 * 1024)
 294#define IOP_ADMA_MAX_BYTE_COUNT (16 * 1024 * 1024)
 295
 296static inline int iop_chan_is_busy(struct iop_adma_chan *chan)
 297{
 298        u32 status = __raw_readl(DMA_CSR(chan));
 299        return (status & IOP_ADMA_STATUS_BUSY) ? 1 : 0;
 300}
 301
 302static inline int iop_desc_is_aligned(struct iop_adma_desc_slot *desc,
 303                                        int num_slots)
 304{
 305        /* num_slots will only ever be 1, 2, 4, or 8 */
 306        return (desc->idx & (num_slots - 1)) ? 0 : 1;
 307}
 308
 309/* to do: support large (i.e. > hw max) buffer sizes */
 310static inline int iop_chan_memcpy_slot_count(size_t len, int *slots_per_op)
 311{
 312        *slots_per_op = 1;
 313        return 1;
 314}
 315
 316/* to do: support large (i.e. > hw max) buffer sizes */
 317static inline int iop_chan_memset_slot_count(size_t len, int *slots_per_op)
 318{
 319        *slots_per_op = 1;
 320        return 1;
 321}
 322
 323static inline int iop3xx_aau_xor_slot_count(size_t len, int src_cnt,
 324                                        int *slots_per_op)
 325{
 326        static const char slot_count_table[] = {
 327                                                1, 1, 1, 1, /* 01 - 04 */
 328                                                2, 2, 2, 2, /* 05 - 08 */
 329                                                4, 4, 4, 4, /* 09 - 12 */
 330                                                4, 4, 4, 4, /* 13 - 16 */
 331                                                8, 8, 8, 8, /* 17 - 20 */
 332                                                8, 8, 8, 8, /* 21 - 24 */
 333                                                8, 8, 8, 8, /* 25 - 28 */
 334                                                8, 8, 8, 8, /* 29 - 32 */
 335                                              };
 336        *slots_per_op = slot_count_table[src_cnt - 1];
 337        return *slots_per_op;
 338}
 339
 340static inline int
 341iop_chan_interrupt_slot_count(int *slots_per_op, struct iop_adma_chan *chan)
 342{
 343        switch (chan->device->id) {
 344        case DMA0_ID:
 345        case DMA1_ID:
 346                return iop_chan_memcpy_slot_count(0, slots_per_op);
 347        case AAU_ID:
 348                return iop3xx_aau_xor_slot_count(0, 2, slots_per_op);
 349        default:
 350                BUG();
 351        }
 352        return 0;
 353}
 354
 355static inline int iop_chan_xor_slot_count(size_t len, int src_cnt,
 356                                                int *slots_per_op)
 357{
 358        int slot_cnt = iop3xx_aau_xor_slot_count(len, src_cnt, slots_per_op);
 359
 360        if (len <= IOP_ADMA_XOR_MAX_BYTE_COUNT)
 361                return slot_cnt;
 362
 363        len -= IOP_ADMA_XOR_MAX_BYTE_COUNT;
 364        while (len > IOP_ADMA_XOR_MAX_BYTE_COUNT) {
 365                len -= IOP_ADMA_XOR_MAX_BYTE_COUNT;
 366                slot_cnt += *slots_per_op;
 367        }
 368
 369        slot_cnt += *slots_per_op;
 370
 371        return slot_cnt;
 372}
 373
 374/* zero sum on iop3xx is limited to 1k at a time so it requires multiple
 375 * descriptors
 376 */
 377static inline int iop_chan_zero_sum_slot_count(size_t len, int src_cnt,
 378                                                int *slots_per_op)
 379{
 380        int slot_cnt = iop3xx_aau_xor_slot_count(len, src_cnt, slots_per_op);
 381
 382        if (len <= IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT)
 383                return slot_cnt;
 384
 385        len -= IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT;
 386        while (len > IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT) {
 387                len -= IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT;
 388                slot_cnt += *slots_per_op;
 389        }
 390
 391        slot_cnt += *slots_per_op;
 392
 393        return slot_cnt;
 394}
 395
 396static inline int iop_desc_is_pq(struct iop_adma_desc_slot *desc)
 397{
 398        return 0;
 399}
 400
 401static inline u32 iop_desc_get_dest_addr(struct iop_adma_desc_slot *desc,
 402                                        struct iop_adma_chan *chan)
 403{
 404        union iop3xx_desc hw_desc = { .ptr = desc->hw_desc, };
 405
 406        switch (chan->device->id) {
 407        case DMA0_ID:
 408        case DMA1_ID:
 409                return hw_desc.dma->dest_addr;
 410        case AAU_ID:
 411                return hw_desc.aau->dest_addr;
 412        default:
 413                BUG();
 414        }
 415        return 0;
 416}
 417
 418
 419static inline u32 iop_desc_get_qdest_addr(struct iop_adma_desc_slot *desc,
 420                                          struct iop_adma_chan *chan)
 421{
 422        BUG();
 423        return 0;
 424}
 425
 426static inline u32 iop_desc_get_byte_count(struct iop_adma_desc_slot *desc,
 427                                        struct iop_adma_chan *chan)
 428{
 429        union iop3xx_desc hw_desc = { .ptr = desc->hw_desc, };
 430
 431        switch (chan->device->id) {
 432        case DMA0_ID:
 433        case DMA1_ID:
 434                return hw_desc.dma->byte_count;
 435        case AAU_ID:
 436                return hw_desc.aau->byte_count;
 437        default:
 438                BUG();
 439        }
 440        return 0;
 441}
 442
 443/* translate the src_idx to a descriptor word index */
 444static inline int __desc_idx(int src_idx)
 445{
 446        static const int desc_idx_table[] = { 0, 0, 0, 0,
 447                                              0, 1, 2, 3,
 448                                              5, 6, 7, 8,
 449                                              9, 10, 11, 12,
 450                                              14, 15, 16, 17,
 451                                              18, 19, 20, 21,
 452                                              23, 24, 25, 26,
 453                                              27, 28, 29, 30,
 454                                            };
 455
 456        return desc_idx_table[src_idx];
 457}
 458
 459static inline u32 iop_desc_get_src_addr(struct iop_adma_desc_slot *desc,
 460                                        struct iop_adma_chan *chan,
 461                                        int src_idx)
 462{
 463        union iop3xx_desc hw_desc = { .ptr = desc->hw_desc, };
 464
 465        switch (chan->device->id) {
 466        case DMA0_ID:
 467        case DMA1_ID:
 468                return hw_desc.dma->src_addr;
 469        case AAU_ID:
 470                break;
 471        default:
 472                BUG();
 473        }
 474
 475        if (src_idx < 4)
 476                return hw_desc.aau->src[src_idx];
 477        else
 478                return hw_desc.aau->src_edc[__desc_idx(src_idx)].src_addr;
 479}
 480
 481static inline void iop3xx_aau_desc_set_src_addr(struct iop3xx_desc_aau *hw_desc,
 482                                        int src_idx, dma_addr_t addr)
 483{
 484        if (src_idx < 4)
 485                hw_desc->src[src_idx] = addr;
 486        else
 487                hw_desc->src_edc[__desc_idx(src_idx)].src_addr = addr;
 488}
 489
 490static inline void
 491iop_desc_init_memcpy(struct iop_adma_desc_slot *desc, unsigned long flags)
 492{
 493        struct iop3xx_desc_dma *hw_desc = desc->hw_desc;
 494        union {
 495                u32 value;
 496                struct iop3xx_dma_desc_ctrl field;
 497        } u_desc_ctrl;
 498
 499        u_desc_ctrl.value = 0;
 500        u_desc_ctrl.field.mem_to_mem_en = 1;
 501        u_desc_ctrl.field.pci_transaction = 0xe; /* memory read block */
 502        u_desc_ctrl.field.int_en = flags & DMA_PREP_INTERRUPT;
 503        hw_desc->desc_ctrl = u_desc_ctrl.value;
 504        hw_desc->upper_pci_src_addr = 0;
 505        hw_desc->crc_addr = 0;
 506}
 507
 508static inline void
 509iop_desc_init_memset(struct iop_adma_desc_slot *desc, unsigned long flags)
 510{
 511        struct iop3xx_desc_aau *hw_desc = desc->hw_desc;
 512        union {
 513                u32 value;
 514                struct iop3xx_aau_desc_ctrl field;
 515        } u_desc_ctrl;
 516
 517        u_desc_ctrl.value = 0;
 518        u_desc_ctrl.field.blk1_cmd_ctrl = 0x2; /* memory block fill */
 519        u_desc_ctrl.field.dest_write_en = 1;
 520        u_desc_ctrl.field.int_en = flags & DMA_PREP_INTERRUPT;
 521        hw_desc->desc_ctrl = u_desc_ctrl.value;
 522}
 523
 524static inline u32
 525iop3xx_desc_init_xor(struct iop3xx_desc_aau *hw_desc, int src_cnt,
 526                     unsigned long flags)
 527{
 528        int i, shift;
 529        u32 edcr;
 530        union {
 531                u32 value;
 532                struct iop3xx_aau_desc_ctrl field;
 533        } u_desc_ctrl;
 534
 535        u_desc_ctrl.value = 0;
 536        switch (src_cnt) {
 537        case 25 ... 32:
 538                u_desc_ctrl.field.blk_ctrl = 0x3; /* use EDCR[2:0] */
 539                edcr = 0;
 540                shift = 1;
 541                for (i = 24; i < src_cnt; i++) {
 542                        edcr |= (1 << shift);
 543                        shift += 3;
 544                }
 545                hw_desc->src_edc[AAU_EDCR2_IDX].e_desc_ctrl = edcr;
 546                src_cnt = 24;
 547                /* fall through */
 548        case 17 ... 24:
 549                if (!u_desc_ctrl.field.blk_ctrl) {
 550                        hw_desc->src_edc[AAU_EDCR2_IDX].e_desc_ctrl = 0;
 551                        u_desc_ctrl.field.blk_ctrl = 0x3; /* use EDCR[2:0] */
 552                }
 553                edcr = 0;
 554                shift = 1;
 555                for (i = 16; i < src_cnt; i++) {
 556                        edcr |= (1 << shift);
 557                        shift += 3;
 558                }
 559                hw_desc->src_edc[AAU_EDCR1_IDX].e_desc_ctrl = edcr;
 560                src_cnt = 16;
 561                /* fall through */
 562        case 9 ... 16:
 563                if (!u_desc_ctrl.field.blk_ctrl)
 564                        u_desc_ctrl.field.blk_ctrl = 0x2; /* use EDCR0 */
 565                edcr = 0;
 566                shift = 1;
 567                for (i = 8; i < src_cnt; i++) {
 568                        edcr |= (1 << shift);
 569                        shift += 3;
 570                }
 571                hw_desc->src_edc[AAU_EDCR0_IDX].e_desc_ctrl = edcr;
 572                src_cnt = 8;
 573                /* fall through */
 574        case 2 ... 8:
 575                shift = 1;
 576                for (i = 0; i < src_cnt; i++) {
 577                        u_desc_ctrl.value |= (1 << shift);
 578                        shift += 3;
 579                }
 580
 581                if (!u_desc_ctrl.field.blk_ctrl && src_cnt > 4)
 582                        u_desc_ctrl.field.blk_ctrl = 0x1; /* use mini-desc */
 583        }
 584
 585        u_desc_ctrl.field.dest_write_en = 1;
 586        u_desc_ctrl.field.blk1_cmd_ctrl = 0x7; /* direct fill */
 587        u_desc_ctrl.field.int_en = flags & DMA_PREP_INTERRUPT;
 588        hw_desc->desc_ctrl = u_desc_ctrl.value;
 589
 590        return u_desc_ctrl.value;
 591}
 592
 593static inline void
 594iop_desc_init_xor(struct iop_adma_desc_slot *desc, int src_cnt,
 595                  unsigned long flags)
 596{
 597        iop3xx_desc_init_xor(desc->hw_desc, src_cnt, flags);
 598}
 599
 600/* return the number of operations */
 601static inline int
 602iop_desc_init_zero_sum(struct iop_adma_desc_slot *desc, int src_cnt,
 603                       unsigned long flags)
 604{
 605        int slot_cnt = desc->slot_cnt, slots_per_op = desc->slots_per_op;
 606        struct iop3xx_desc_aau *hw_desc, *prev_hw_desc, *iter;
 607        union {
 608                u32 value;
 609                struct iop3xx_aau_desc_ctrl field;
 610        } u_desc_ctrl;
 611        int i, j;
 612
 613        hw_desc = desc->hw_desc;
 614
 615        for (i = 0, j = 0; (slot_cnt -= slots_per_op) >= 0;
 616                i += slots_per_op, j++) {
 617                iter = iop_hw_desc_slot_idx(hw_desc, i);
 618                u_desc_ctrl.value = iop3xx_desc_init_xor(iter, src_cnt, flags);
 619                u_desc_ctrl.field.dest_write_en = 0;
 620                u_desc_ctrl.field.zero_result_en = 1;
 621                u_desc_ctrl.field.int_en = flags & DMA_PREP_INTERRUPT;
 622                iter->desc_ctrl = u_desc_ctrl.value;
 623
 624                /* for the subsequent descriptors preserve the store queue
 625                 * and chain them together
 626                 */
 627                if (i) {
 628                        prev_hw_desc =
 629                                iop_hw_desc_slot_idx(hw_desc, i - slots_per_op);
 630                        prev_hw_desc->next_desc =
 631                                (u32) (desc->async_tx.phys + (i << 5));
 632                }
 633        }
 634
 635        return j;
 636}
 637
 638static inline void
 639iop_desc_init_null_xor(struct iop_adma_desc_slot *desc, int src_cnt,
 640                       unsigned long flags)
 641{
 642        struct iop3xx_desc_aau *hw_desc = desc->hw_desc;
 643        union {
 644                u32 value;
 645                struct iop3xx_aau_desc_ctrl field;
 646        } u_desc_ctrl;
 647
 648        u_desc_ctrl.value = 0;
 649        switch (src_cnt) {
 650        case 25 ... 32:
 651                u_desc_ctrl.field.blk_ctrl = 0x3; /* use EDCR[2:0] */
 652                hw_desc->src_edc[AAU_EDCR2_IDX].e_desc_ctrl = 0;
 653                /* fall through */
 654        case 17 ... 24:
 655                if (!u_desc_ctrl.field.blk_ctrl) {
 656                        hw_desc->src_edc[AAU_EDCR2_IDX].e_desc_ctrl = 0;
 657                        u_desc_ctrl.field.blk_ctrl = 0x3; /* use EDCR[2:0] */
 658                }
 659                hw_desc->src_edc[AAU_EDCR1_IDX].e_desc_ctrl = 0;
 660                /* fall through */
 661        case 9 ... 16:
 662                if (!u_desc_ctrl.field.blk_ctrl)
 663                        u_desc_ctrl.field.blk_ctrl = 0x2; /* use EDCR0 */
 664                hw_desc->src_edc[AAU_EDCR0_IDX].e_desc_ctrl = 0;
 665                /* fall through */
 666        case 1 ... 8:
 667                if (!u_desc_ctrl.field.blk_ctrl && src_cnt > 4)
 668                        u_desc_ctrl.field.blk_ctrl = 0x1; /* use mini-desc */
 669        }
 670
 671        u_desc_ctrl.field.dest_write_en = 0;
 672        u_desc_ctrl.field.int_en = flags & DMA_PREP_INTERRUPT;
 673        hw_desc->desc_ctrl = u_desc_ctrl.value;
 674}
 675
 676static inline void iop_desc_set_byte_count(struct iop_adma_desc_slot *desc,
 677                                        struct iop_adma_chan *chan,
 678                                        u32 byte_count)
 679{
 680        union iop3xx_desc hw_desc = { .ptr = desc->hw_desc, };
 681
 682        switch (chan->device->id) {
 683        case DMA0_ID:
 684        case DMA1_ID:
 685                hw_desc.dma->byte_count = byte_count;
 686                break;
 687        case AAU_ID:
 688                hw_desc.aau->byte_count = byte_count;
 689                break;
 690        default:
 691                BUG();
 692        }
 693}
 694
 695static inline void
 696iop_desc_init_interrupt(struct iop_adma_desc_slot *desc,
 697                        struct iop_adma_chan *chan)
 698{
 699        union iop3xx_desc hw_desc = { .ptr = desc->hw_desc, };
 700
 701        switch (chan->device->id) {
 702        case DMA0_ID:
 703        case DMA1_ID:
 704                iop_desc_init_memcpy(desc, 1);
 705                hw_desc.dma->byte_count = 0;
 706                hw_desc.dma->dest_addr = 0;
 707                hw_desc.dma->src_addr = 0;
 708                break;
 709        case AAU_ID:
 710                iop_desc_init_null_xor(desc, 2, 1);
 711                hw_desc.aau->byte_count = 0;
 712                hw_desc.aau->dest_addr = 0;
 713                hw_desc.aau->src[0] = 0;
 714                hw_desc.aau->src[1] = 0;
 715                break;
 716        default:
 717                BUG();
 718        }
 719}
 720
 721static inline void
 722iop_desc_set_zero_sum_byte_count(struct iop_adma_desc_slot *desc, u32 len)
 723{
 724        int slots_per_op = desc->slots_per_op;
 725        struct iop3xx_desc_aau *hw_desc = desc->hw_desc, *iter;
 726        int i = 0;
 727
 728        if (len <= IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT) {
 729                hw_desc->byte_count = len;
 730        } else {
 731                do {
 732                        iter = iop_hw_desc_slot_idx(hw_desc, i);
 733                        iter->byte_count = IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT;
 734                        len -= IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT;
 735                        i += slots_per_op;
 736                } while (len > IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT);
 737
 738                iter = iop_hw_desc_slot_idx(hw_desc, i);
 739                iter->byte_count = len;
 740        }
 741}
 742
 743static inline void iop_desc_set_dest_addr(struct iop_adma_desc_slot *desc,
 744                                        struct iop_adma_chan *chan,
 745                                        dma_addr_t addr)
 746{
 747        union iop3xx_desc hw_desc = { .ptr = desc->hw_desc, };
 748
 749        switch (chan->device->id) {
 750        case DMA0_ID:
 751        case DMA1_ID:
 752                hw_desc.dma->dest_addr = addr;
 753                break;
 754        case AAU_ID:
 755                hw_desc.aau->dest_addr = addr;
 756                break;
 757        default:
 758                BUG();
 759        }
 760}
 761
 762static inline void iop_desc_set_memcpy_src_addr(struct iop_adma_desc_slot *desc,
 763                                        dma_addr_t addr)
 764{
 765        struct iop3xx_desc_dma *hw_desc = desc->hw_desc;
 766        hw_desc->src_addr = addr;
 767}
 768
 769static inline void
 770iop_desc_set_zero_sum_src_addr(struct iop_adma_desc_slot *desc, int src_idx,
 771                                dma_addr_t addr)
 772{
 773
 774        struct iop3xx_desc_aau *hw_desc = desc->hw_desc, *iter;
 775        int slot_cnt = desc->slot_cnt, slots_per_op = desc->slots_per_op;
 776        int i;
 777
 778        for (i = 0; (slot_cnt -= slots_per_op) >= 0;
 779                i += slots_per_op, addr += IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT) {
 780                iter = iop_hw_desc_slot_idx(hw_desc, i);
 781                iop3xx_aau_desc_set_src_addr(iter, src_idx, addr);
 782        }
 783}
 784
 785static inline void iop_desc_set_xor_src_addr(struct iop_adma_desc_slot *desc,
 786                                        int src_idx, dma_addr_t addr)
 787{
 788
 789        struct iop3xx_desc_aau *hw_desc = desc->hw_desc, *iter;
 790        int slot_cnt = desc->slot_cnt, slots_per_op = desc->slots_per_op;
 791        int i;
 792
 793        for (i = 0; (slot_cnt -= slots_per_op) >= 0;
 794                i += slots_per_op, addr += IOP_ADMA_XOR_MAX_BYTE_COUNT) {
 795                iter = iop_hw_desc_slot_idx(hw_desc, i);
 796                iop3xx_aau_desc_set_src_addr(iter, src_idx, addr);
 797        }
 798}
 799
 800static inline void iop_desc_set_next_desc(struct iop_adma_desc_slot *desc,
 801                                        u32 next_desc_addr)
 802{
 803        /* hw_desc->next_desc is the same location for all channels */
 804        union iop3xx_desc hw_desc = { .ptr = desc->hw_desc, };
 805
 806        iop_paranoia(hw_desc.dma->next_desc);
 807        hw_desc.dma->next_desc = next_desc_addr;
 808}
 809
 810static inline u32 iop_desc_get_next_desc(struct iop_adma_desc_slot *desc)
 811{
 812        /* hw_desc->next_desc is the same location for all channels */
 813        union iop3xx_desc hw_desc = { .ptr = desc->hw_desc, };
 814        return hw_desc.dma->next_desc;
 815}
 816
 817static inline void iop_desc_clear_next_desc(struct iop_adma_desc_slot *desc)
 818{
 819        /* hw_desc->next_desc is the same location for all channels */
 820        union iop3xx_desc hw_desc = { .ptr = desc->hw_desc, };
 821        hw_desc.dma->next_desc = 0;
 822}
 823
 824static inline void iop_desc_set_block_fill_val(struct iop_adma_desc_slot *desc,
 825                                                u32 val)
 826{
 827        struct iop3xx_desc_aau *hw_desc = desc->hw_desc;
 828        hw_desc->src[0] = val;
 829}
 830
 831static inline enum sum_check_flags
 832iop_desc_get_zero_result(struct iop_adma_desc_slot *desc)
 833{
 834        struct iop3xx_desc_aau *hw_desc = desc->hw_desc;
 835        struct iop3xx_aau_desc_ctrl desc_ctrl = hw_desc->desc_ctrl_field;
 836
 837        iop_paranoia(!(desc_ctrl.tx_complete && desc_ctrl.zero_result_en));
 838        return desc_ctrl.zero_result_err << SUM_CHECK_P;
 839}
 840
 841static inline void iop_chan_append(struct iop_adma_chan *chan)
 842{
 843        u32 dma_chan_ctrl;
 844
 845        dma_chan_ctrl = __raw_readl(DMA_CCR(chan));
 846        dma_chan_ctrl |= 0x2;
 847        __raw_writel(dma_chan_ctrl, DMA_CCR(chan));
 848}
 849
 850static inline u32 iop_chan_get_status(struct iop_adma_chan *chan)
 851{
 852        return __raw_readl(DMA_CSR(chan));
 853}
 854
 855static inline void iop_chan_disable(struct iop_adma_chan *chan)
 856{
 857        u32 dma_chan_ctrl = __raw_readl(DMA_CCR(chan));
 858        dma_chan_ctrl &= ~1;
 859        __raw_writel(dma_chan_ctrl, DMA_CCR(chan));
 860}
 861
 862static inline void iop_chan_enable(struct iop_adma_chan *chan)
 863{
 864        u32 dma_chan_ctrl = __raw_readl(DMA_CCR(chan));
 865
 866        dma_chan_ctrl |= 1;
 867        __raw_writel(dma_chan_ctrl, DMA_CCR(chan));
 868}
 869
 870static inline void iop_adma_device_clear_eot_status(struct iop_adma_chan *chan)
 871{
 872        u32 status = __raw_readl(DMA_CSR(chan));
 873        status &= (1 << 9);
 874        __raw_writel(status, DMA_CSR(chan));
 875}
 876
 877static inline void iop_adma_device_clear_eoc_status(struct iop_adma_chan *chan)
 878{
 879        u32 status = __raw_readl(DMA_CSR(chan));
 880        status &= (1 << 8);
 881        __raw_writel(status, DMA_CSR(chan));
 882}
 883
 884static inline void iop_adma_device_clear_err_status(struct iop_adma_chan *chan)
 885{
 886        u32 status = __raw_readl(DMA_CSR(chan));
 887
 888        switch (chan->device->id) {
 889        case DMA0_ID:
 890        case DMA1_ID:
 891                status &= (1 << 5) | (1 << 3) | (1 << 2) | (1 << 1);
 892                break;
 893        case AAU_ID:
 894                status &= (1 << 5);
 895                break;
 896        default:
 897                BUG();
 898        }
 899
 900        __raw_writel(status, DMA_CSR(chan));
 901}
 902
 903static inline int
 904iop_is_err_int_parity(unsigned long status, struct iop_adma_chan *chan)
 905{
 906        return 0;
 907}
 908
 909static inline int
 910iop_is_err_mcu_abort(unsigned long status, struct iop_adma_chan *chan)
 911{
 912        return 0;
 913}
 914
 915static inline int
 916iop_is_err_int_tabort(unsigned long status, struct iop_adma_chan *chan)
 917{
 918        return 0;
 919}
 920
 921static inline int
 922iop_is_err_int_mabort(unsigned long status, struct iop_adma_chan *chan)
 923{
 924        return test_bit(5, &status);
 925}
 926
 927static inline int
 928iop_is_err_pci_tabort(unsigned long status, struct iop_adma_chan *chan)
 929{
 930        switch (chan->device->id) {
 931        case DMA0_ID:
 932        case DMA1_ID:
 933                return test_bit(2, &status);
 934        default:
 935                return 0;
 936        }
 937}
 938
 939static inline int
 940iop_is_err_pci_mabort(unsigned long status, struct iop_adma_chan *chan)
 941{
 942        switch (chan->device->id) {
 943        case DMA0_ID:
 944        case DMA1_ID:
 945                return test_bit(3, &status);
 946        default:
 947                return 0;
 948        }
 949}
 950
 951static inline int
 952iop_is_err_split_tx(unsigned long status, struct iop_adma_chan *chan)
 953{
 954        switch (chan->device->id) {
 955        case DMA0_ID:
 956        case DMA1_ID:
 957                return test_bit(1, &status);
 958        default:
 959                return 0;
 960        }
 961}
 962#endif /* _ADMA_H */
 963