1/* 2 * Copyright(c) 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#define ADMA_ACCR(chan) (chan->mmr_base + 0x0) 26#define ADMA_ACSR(chan) (chan->mmr_base + 0x4) 27#define ADMA_ADAR(chan) (chan->mmr_base + 0x8) 28#define ADMA_IIPCR(chan) (chan->mmr_base + 0x18) 29#define ADMA_IIPAR(chan) (chan->mmr_base + 0x1c) 30#define ADMA_IIPUAR(chan) (chan->mmr_base + 0x20) 31#define ADMA_ANDAR(chan) (chan->mmr_base + 0x24) 32#define ADMA_ADCR(chan) (chan->mmr_base + 0x28) 33#define ADMA_CARMD(chan) (chan->mmr_base + 0x2c) 34#define ADMA_ABCR(chan) (chan->mmr_base + 0x30) 35#define ADMA_DLADR(chan) (chan->mmr_base + 0x34) 36#define ADMA_DUADR(chan) (chan->mmr_base + 0x38) 37#define ADMA_SLAR(src, chan) (chan->mmr_base + (0x3c + (src << 3))) 38#define ADMA_SUAR(src, chan) (chan->mmr_base + (0x40 + (src << 3))) 39 40struct iop13xx_adma_src { 41 u32 src_addr; 42 union { 43 u32 upper_src_addr; 44 struct { 45 unsigned int pq_upper_src_addr:24; 46 unsigned int pq_dmlt:8; 47 }; 48 }; 49}; 50 51struct iop13xx_adma_desc_ctrl { 52 unsigned int int_en:1; 53 unsigned int xfer_dir:2; 54 unsigned int src_select:4; 55 unsigned int zero_result:1; 56 unsigned int block_fill_en:1; 57 unsigned int crc_gen_en:1; 58 unsigned int crc_xfer_dis:1; 59 unsigned int crc_seed_fetch_dis:1; 60 unsigned int status_write_back_en:1; 61 unsigned int endian_swap_en:1; 62 unsigned int reserved0:2; 63 unsigned int pq_update_xfer_en:1; 64 unsigned int dual_xor_en:1; 65 unsigned int pq_xfer_en:1; 66 unsigned int p_xfer_dis:1; 67 unsigned int reserved1:10; 68 unsigned int relax_order_en:1; 69 unsigned int no_snoop_en:1; 70}; 71 72struct iop13xx_adma_byte_count { 73 unsigned int byte_count:24; 74 unsigned int host_if:3; 75 unsigned int reserved:2; 76 unsigned int zero_result_err_q:1; 77 unsigned int zero_result_err:1; 78 unsigned int tx_complete:1; 79}; 80 81struct iop13xx_adma_desc_hw { 82 u32 next_desc; 83 union { 84 u32 desc_ctrl; 85 struct iop13xx_adma_desc_ctrl desc_ctrl_field; 86 }; 87 union { 88 u32 crc_addr; 89 u32 block_fill_data; 90 u32 q_dest_addr; 91 }; 92 union { 93 u32 byte_count; 94 struct iop13xx_adma_byte_count byte_count_field; 95 }; 96 union { 97 u32 dest_addr; 98 u32 p_dest_addr; 99 }; 100 union { 101 u32 upper_dest_addr; 102 u32 pq_upper_dest_addr; 103 }; 104 struct iop13xx_adma_src src[1]; 105}; 106 107struct iop13xx_adma_desc_dual_xor { 108 u32 next_desc; 109 u32 desc_ctrl; 110 u32 reserved; 111 u32 byte_count; 112 u32 h_dest_addr; 113 u32 h_upper_dest_addr; 114 u32 src0_addr; 115 u32 upper_src0_addr; 116 u32 src1_addr; 117 u32 upper_src1_addr; 118 u32 h_src_addr; 119 u32 h_upper_src_addr; 120 u32 d_src_addr; 121 u32 d_upper_src_addr; 122 u32 d_dest_addr; 123 u32 d_upper_dest_addr; 124}; 125 126struct iop13xx_adma_desc_pq_update { 127 u32 next_desc; 128 u32 desc_ctrl; 129 u32 reserved; 130 u32 byte_count; 131 u32 p_dest_addr; 132 u32 p_upper_dest_addr; 133 u32 src0_addr; 134 u32 upper_src0_addr; 135 u32 src1_addr; 136 u32 upper_src1_addr; 137 u32 p_src_addr; 138 u32 p_upper_src_addr; 139 u32 q_src_addr; 140 struct { 141 unsigned int q_upper_src_addr:24; 142 unsigned int q_dmlt:8; 143 }; 144 u32 q_dest_addr; 145 u32 q_upper_dest_addr; 146}; 147 148static inline int iop_adma_get_max_xor(void) 149{ 150 return 16; 151} 152 153#define iop_adma_get_max_pq iop_adma_get_max_xor 154 155static inline u32 iop_chan_get_current_descriptor(struct iop_adma_chan *chan) 156{ 157 return __raw_readl(ADMA_ADAR(chan)); 158} 159 160static inline void iop_chan_set_next_descriptor(struct iop_adma_chan *chan, 161 u32 next_desc_addr) 162{ 163 __raw_writel(next_desc_addr, ADMA_ANDAR(chan)); 164} 165 166#define ADMA_STATUS_BUSY (1 << 13) 167 168static inline char iop_chan_is_busy(struct iop_adma_chan *chan) 169{ 170 if (__raw_readl(ADMA_ACSR(chan)) & 171 ADMA_STATUS_BUSY) 172 return 1; 173 else 174 return 0; 175} 176 177static inline int 178iop_chan_get_desc_align(struct iop_adma_chan *chan, int num_slots) 179{ 180 return 1; 181} 182#define iop_desc_is_aligned(x, y) 1 183 184static inline int 185iop_chan_memcpy_slot_count(size_t len, int *slots_per_op) 186{ 187 *slots_per_op = 1; 188 return 1; 189} 190 191#define iop_chan_interrupt_slot_count(s, c) iop_chan_memcpy_slot_count(0, s) 192 193static inline int 194iop_chan_memset_slot_count(size_t len, int *slots_per_op) 195{ 196 *slots_per_op = 1; 197 return 1; 198} 199 200static inline int 201iop_chan_xor_slot_count(size_t len, int src_cnt, int *slots_per_op) 202{ 203 static const char slot_count_table[] = { 1, 2, 2, 2, 204 2, 3, 3, 3, 205 3, 4, 4, 4, 206 4, 5, 5, 5, 207 }; 208 *slots_per_op = slot_count_table[src_cnt - 1]; 209 return *slots_per_op; 210} 211 212#define ADMA_MAX_BYTE_COUNT (16 * 1024 * 1024) 213#define IOP_ADMA_MAX_BYTE_COUNT ADMA_MAX_BYTE_COUNT 214#define IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT ADMA_MAX_BYTE_COUNT 215#define IOP_ADMA_XOR_MAX_BYTE_COUNT ADMA_MAX_BYTE_COUNT 216#define IOP_ADMA_PQ_MAX_BYTE_COUNT ADMA_MAX_BYTE_COUNT 217#define iop_chan_zero_sum_slot_count(l, s, o) iop_chan_xor_slot_count(l, s, o) 218#define iop_chan_pq_slot_count iop_chan_xor_slot_count 219#define iop_chan_pq_zero_sum_slot_count iop_chan_xor_slot_count 220 221static inline u32 iop_desc_get_byte_count(struct iop_adma_desc_slot *desc, 222 struct iop_adma_chan *chan) 223{ 224 struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc; 225 return hw_desc->byte_count_field.byte_count; 226} 227 228static inline u32 iop_desc_get_src_addr(struct iop_adma_desc_slot *desc, 229 struct iop_adma_chan *chan, 230 int src_idx) 231{ 232 struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc; 233 return hw_desc->src[src_idx].src_addr; 234} 235 236static inline u32 iop_desc_get_src_count(struct iop_adma_desc_slot *desc, 237 struct iop_adma_chan *chan) 238{ 239 struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc; 240 return hw_desc->desc_ctrl_field.src_select + 1; 241} 242 243static inline void 244iop_desc_init_memcpy(struct iop_adma_desc_slot *desc, unsigned long flags) 245{ 246 struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc; 247 union { 248 u32 value; 249 struct iop13xx_adma_desc_ctrl field; 250 } u_desc_ctrl; 251 252 u_desc_ctrl.value = 0; 253 u_desc_ctrl.field.xfer_dir = 3; /* local to internal bus */ 254 u_desc_ctrl.field.int_en = flags & DMA_PREP_INTERRUPT; 255 hw_desc->desc_ctrl = u_desc_ctrl.value; 256 hw_desc->crc_addr = 0; 257} 258 259static inline void 260iop_desc_init_memset(struct iop_adma_desc_slot *desc, unsigned long flags) 261{ 262 struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc; 263 union { 264 u32 value; 265 struct iop13xx_adma_desc_ctrl field; 266 } u_desc_ctrl; 267 268 u_desc_ctrl.value = 0; 269 u_desc_ctrl.field.xfer_dir = 3; /* local to internal bus */ 270 u_desc_ctrl.field.block_fill_en = 1; 271 u_desc_ctrl.field.int_en = flags & DMA_PREP_INTERRUPT; 272 hw_desc->desc_ctrl = u_desc_ctrl.value; 273 hw_desc->crc_addr = 0; 274} 275 276/* to do: support buffers larger than ADMA_MAX_BYTE_COUNT */ 277static inline void 278iop_desc_init_xor(struct iop_adma_desc_slot *desc, int src_cnt, 279 unsigned long flags) 280{ 281 struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc; 282 union { 283 u32 value; 284 struct iop13xx_adma_desc_ctrl field; 285 } u_desc_ctrl; 286 287 u_desc_ctrl.value = 0; 288 u_desc_ctrl.field.src_select = src_cnt - 1; 289 u_desc_ctrl.field.xfer_dir = 3; /* local to internal bus */ 290 u_desc_ctrl.field.int_en = flags & DMA_PREP_INTERRUPT; 291 hw_desc->desc_ctrl = u_desc_ctrl.value; 292 hw_desc->crc_addr = 0; 293 294} 295#define iop_desc_init_null_xor(d, s, i) iop_desc_init_xor(d, s, i) 296 297/* to do: support buffers larger than ADMA_MAX_BYTE_COUNT */ 298static inline int 299iop_desc_init_zero_sum(struct iop_adma_desc_slot *desc, int src_cnt, 300 unsigned long flags) 301{ 302 struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc; 303 union { 304 u32 value; 305 struct iop13xx_adma_desc_ctrl field; 306 } u_desc_ctrl; 307 308 u_desc_ctrl.value = 0; 309 u_desc_ctrl.field.src_select = src_cnt - 1; 310 u_desc_ctrl.field.xfer_dir = 3; /* local to internal bus */ 311 u_desc_ctrl.field.zero_result = 1; 312 u_desc_ctrl.field.status_write_back_en = 1; 313 u_desc_ctrl.field.int_en = flags & DMA_PREP_INTERRUPT; 314 hw_desc->desc_ctrl = u_desc_ctrl.value; 315 hw_desc->crc_addr = 0; 316 317 return 1; 318} 319 320static inline void 321iop_desc_init_pq(struct iop_adma_desc_slot *desc, int src_cnt, 322 unsigned long flags) 323{ 324 struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc; 325 union { 326 u32 value; 327 struct iop13xx_adma_desc_ctrl field; 328 } u_desc_ctrl; 329 330 u_desc_ctrl.value = 0; 331 u_desc_ctrl.field.src_select = src_cnt - 1; 332 u_desc_ctrl.field.xfer_dir = 3; /* local to internal bus */ 333 u_desc_ctrl.field.pq_xfer_en = 1; 334 u_desc_ctrl.field.p_xfer_dis = !!(flags & DMA_PREP_PQ_DISABLE_P); 335 u_desc_ctrl.field.int_en = flags & DMA_PREP_INTERRUPT; 336 hw_desc->desc_ctrl = u_desc_ctrl.value; 337} 338 339static inline void 340iop_desc_init_pq_zero_sum(struct iop_adma_desc_slot *desc, int src_cnt, 341 unsigned long flags) 342{ 343 struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc; 344 union { 345 u32 value; 346 struct iop13xx_adma_desc_ctrl field; 347 } u_desc_ctrl; 348 349 u_desc_ctrl.value = 0; 350 u_desc_ctrl.field.src_select = src_cnt - 1; 351 u_desc_ctrl.field.xfer_dir = 3; /* local to internal bus */ 352 u_desc_ctrl.field.zero_result = 1; 353 u_desc_ctrl.field.status_write_back_en = 1; 354 u_desc_ctrl.field.pq_xfer_en = 1; 355 u_desc_ctrl.field.p_xfer_dis = !!(flags & DMA_PREP_PQ_DISABLE_P); 356 u_desc_ctrl.field.int_en = flags & DMA_PREP_INTERRUPT; 357 hw_desc->desc_ctrl = u_desc_ctrl.value; 358} 359 360static inline void iop_desc_set_byte_count(struct iop_adma_desc_slot *desc, 361 struct iop_adma_chan *chan, 362 u32 byte_count) 363{ 364 struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc; 365 hw_desc->byte_count = byte_count; 366} 367 368static inline void 369iop_desc_set_zero_sum_byte_count(struct iop_adma_desc_slot *desc, u32 len) 370{ 371 int slots_per_op = desc->slots_per_op; 372 struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc, *iter; 373 int i = 0; 374 375 if (len <= IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT) { 376 hw_desc->byte_count = len; 377 } else { 378 do { 379 iter = iop_hw_desc_slot_idx(hw_desc, i); 380 iter->byte_count = IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT; 381 len -= IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT; 382 i += slots_per_op; 383 } while (len > IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT); 384 385 if (len) { 386 iter = iop_hw_desc_slot_idx(hw_desc, i); 387 iter->byte_count = len; 388 } 389 } 390} 391 392#define iop_desc_set_pq_zero_sum_byte_count iop_desc_set_zero_sum_byte_count 393 394static inline void iop_desc_set_dest_addr(struct iop_adma_desc_slot *desc, 395 struct iop_adma_chan *chan, 396 dma_addr_t addr) 397{ 398 struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc; 399 hw_desc->dest_addr = addr; 400 hw_desc->upper_dest_addr = 0; 401} 402 403static inline void 404iop_desc_set_pq_addr(struct iop_adma_desc_slot *desc, dma_addr_t *addr) 405{ 406 struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc; 407 408 hw_desc->dest_addr = addr[0]; 409 hw_desc->q_dest_addr = addr[1]; 410 hw_desc->upper_dest_addr = 0; 411} 412 413static inline void iop_desc_set_memcpy_src_addr(struct iop_adma_desc_slot *desc, 414 dma_addr_t addr) 415{ 416 struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc; 417 hw_desc->src[0].src_addr = addr; 418 hw_desc->src[0].upper_src_addr = 0; 419} 420 421static inline void iop_desc_set_xor_src_addr(struct iop_adma_desc_slot *desc, 422 int src_idx, dma_addr_t addr) 423{ 424 int slot_cnt = desc->slot_cnt, slots_per_op = desc->slots_per_op; 425 struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc, *iter; 426 int i = 0; 427 428 do { 429 iter = iop_hw_desc_slot_idx(hw_desc, i); 430 iter->src[src_idx].src_addr = addr; 431 iter->src[src_idx].upper_src_addr = 0; 432 slot_cnt -= slots_per_op; 433 if (slot_cnt) { 434 i += slots_per_op; 435 addr += IOP_ADMA_XOR_MAX_BYTE_COUNT; 436 } 437 } while (slot_cnt); 438} 439 440static inline void 441iop_desc_set_pq_src_addr(struct iop_adma_desc_slot *desc, int src_idx, 442 dma_addr_t addr, unsigned char coef) 443{ 444 int slot_cnt = desc->slot_cnt, slots_per_op = desc->slots_per_op; 445 struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc, *iter; 446 struct iop13xx_adma_src *src; 447 int i = 0; 448 449 do { 450 iter = iop_hw_desc_slot_idx(hw_desc, i); 451 src = &iter->src[src_idx]; 452 src->src_addr = addr; 453 src->pq_upper_src_addr = 0; 454 src->pq_dmlt = coef; 455 slot_cnt -= slots_per_op; 456 if (slot_cnt) { 457 i += slots_per_op; 458 addr += IOP_ADMA_PQ_MAX_BYTE_COUNT; 459 } 460 } while (slot_cnt); 461} 462 463static inline void 464iop_desc_init_interrupt(struct iop_adma_desc_slot *desc, 465 struct iop_adma_chan *chan) 466{ 467 iop_desc_init_memcpy(desc, 1); 468 iop_desc_set_byte_count(desc, chan, 0); 469 iop_desc_set_dest_addr(desc, chan, 0); 470 iop_desc_set_memcpy_src_addr(desc, 0); 471} 472 473#define iop_desc_set_zero_sum_src_addr iop_desc_set_xor_src_addr 474#define iop_desc_set_pq_zero_sum_src_addr iop_desc_set_pq_src_addr 475 476static inline void 477iop_desc_set_pq_zero_sum_addr(struct iop_adma_desc_slot *desc, int pq_idx, 478 dma_addr_t *src) 479{ 480 iop_desc_set_xor_src_addr(desc, pq_idx, src[pq_idx]); 481 iop_desc_set_xor_src_addr(desc, pq_idx+1, src[pq_idx+1]); 482} 483 484static inline void iop_desc_set_next_desc(struct iop_adma_desc_slot *desc, 485 u32 next_desc_addr) 486{ 487 struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc; 488 489 iop_paranoia(hw_desc->next_desc); 490 hw_desc->next_desc = next_desc_addr; 491} 492 493static inline u32 iop_desc_get_next_desc(struct iop_adma_desc_slot *desc) 494{ 495 struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc; 496 return hw_desc->next_desc; 497} 498 499static inline void iop_desc_clear_next_desc(struct iop_adma_desc_slot *desc) 500{ 501 struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc; 502 hw_desc->next_desc = 0; 503} 504 505static inline void iop_desc_set_block_fill_val(struct iop_adma_desc_slot *desc, 506 u32 val) 507{ 508 struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc; 509 hw_desc->block_fill_data = val; 510} 511 512static inline enum sum_check_flags 513iop_desc_get_zero_result(struct iop_adma_desc_slot *desc) 514{ 515 struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc; 516 struct iop13xx_adma_desc_ctrl desc_ctrl = hw_desc->desc_ctrl_field; 517 struct iop13xx_adma_byte_count byte_count = hw_desc->byte_count_field; 518 enum sum_check_flags flags; 519 520 BUG_ON(!(byte_count.tx_complete && desc_ctrl.zero_result)); 521 522 flags = byte_count.zero_result_err_q << SUM_CHECK_Q; 523 flags |= byte_count.zero_result_err << SUM_CHECK_P; 524 525 return flags; 526} 527 528static inline void iop_chan_append(struct iop_adma_chan *chan) 529{ 530 u32 adma_accr; 531 532 adma_accr = __raw_readl(ADMA_ACCR(chan)); 533 adma_accr |= 0x2; 534 __raw_writel(adma_accr, ADMA_ACCR(chan)); 535} 536 537static inline u32 iop_chan_get_status(struct iop_adma_chan *chan) 538{ 539 return __raw_readl(ADMA_ACSR(chan)); 540} 541 542static inline void iop_chan_disable(struct iop_adma_chan *chan) 543{ 544 u32 adma_chan_ctrl = __raw_readl(ADMA_ACCR(chan)); 545 adma_chan_ctrl &= ~0x1; 546 __raw_writel(adma_chan_ctrl, ADMA_ACCR(chan)); 547} 548 549static inline void iop_chan_enable(struct iop_adma_chan *chan) 550{ 551 u32 adma_chan_ctrl; 552 553 adma_chan_ctrl = __raw_readl(ADMA_ACCR(chan)); 554 adma_chan_ctrl |= 0x1; 555 __raw_writel(adma_chan_ctrl, ADMA_ACCR(chan)); 556} 557 558static inline void iop_adma_device_clear_eot_status(struct iop_adma_chan *chan) 559{ 560 u32 status = __raw_readl(ADMA_ACSR(chan)); 561 status &= (1 << 12); 562 __raw_writel(status, ADMA_ACSR(chan)); 563} 564 565static inline void iop_adma_device_clear_eoc_status(struct iop_adma_chan *chan) 566{ 567 u32 status = __raw_readl(ADMA_ACSR(chan)); 568 status &= (1 << 11); 569 __raw_writel(status, ADMA_ACSR(chan)); 570} 571 572static inline void iop_adma_device_clear_err_status(struct iop_adma_chan *chan) 573{ 574 u32 status = __raw_readl(ADMA_ACSR(chan)); 575 status &= (1 << 9) | (1 << 5) | (1 << 4) | (1 << 3); 576 __raw_writel(status, ADMA_ACSR(chan)); 577} 578 579static inline int 580iop_is_err_int_parity(unsigned long status, struct iop_adma_chan *chan) 581{ 582 return test_bit(9, &status); 583} 584 585static inline int 586iop_is_err_mcu_abort(unsigned long status, struct iop_adma_chan *chan) 587{ 588 return test_bit(5, &status); 589} 590 591static inline int 592iop_is_err_int_tabort(unsigned long status, struct iop_adma_chan *chan) 593{ 594 return test_bit(4, &status); 595} 596 597static inline int 598iop_is_err_int_mabort(unsigned long status, struct iop_adma_chan *chan) 599{ 600 return test_bit(3, &status); 601} 602 603static inline int 604iop_is_err_pci_tabort(unsigned long status, struct iop_adma_chan *chan) 605{ 606 return 0; 607} 608 609static inline int 610iop_is_err_pci_mabort(unsigned long status, struct iop_adma_chan *chan) 611{ 612 return 0; 613} 614 615static inline int 616iop_is_err_split_tx(unsigned long status, struct iop_adma_chan *chan) 617{ 618 return 0; 619} 620 621#endif /* _ADMA_H */ 622