Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
adma.h
Go to the documentation of this file.
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 
42  union {
44  struct {
45  unsigned int pq_upper_src_addr:24;
46  unsigned int pq_dmlt:8;
47  };
48  };
49 };
50 
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 
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 
83  union {
86  };
87  union {
91  };
92  union {
95  };
96  union {
99  };
100  union {
103  };
105 };
106 
124 };
125 
140  struct {
141  unsigned int q_upper_src_addr:24;
142  unsigned int q_dmlt:8;
143  };
146 };
147 
148 static 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 
155 static inline u32 iop_chan_get_current_descriptor(struct iop_adma_chan *chan)
156 {
157  return __raw_readl(ADMA_ADAR(chan));
158 }
159 
160 static inline void iop_chan_set_next_descriptor(struct iop_adma_chan *chan,
162 {
163  __raw_writel(next_desc_addr, ADMA_ANDAR(chan));
164 }
165 
166 #define ADMA_STATUS_BUSY (1 << 13)
167 
168 static inline char iop_chan_is_busy(struct iop_adma_chan *chan)
169 {
170  if (__raw_readl(ADMA_ACSR(chan)) &
172  return 1;
173  else
174  return 0;
175 }
176 
177 static inline int
178 iop_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 
184 static inline int
185 iop_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 
193 static inline int
194 iop_chan_memset_slot_count(size_t len, int *slots_per_op)
195 {
196  *slots_per_op = 1;
197  return 1;
198 }
199 
200 static inline int
201 iop_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 
221 static inline u32 iop_desc_get_dest_addr(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->dest_addr;
226 }
227 
228 static inline u32 iop_desc_get_qdest_addr(struct iop_adma_desc_slot *desc,
229  struct iop_adma_chan *chan)
230 {
231  struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc;
232  return hw_desc->q_dest_addr;
233 }
234 
235 static inline u32 iop_desc_get_byte_count(struct iop_adma_desc_slot *desc,
236  struct iop_adma_chan *chan)
237 {
238  struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc;
239  return hw_desc->byte_count_field.byte_count;
240 }
241 
242 static inline u32 iop_desc_get_src_addr(struct iop_adma_desc_slot *desc,
243  struct iop_adma_chan *chan,
244  int src_idx)
245 {
246  struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc;
247  return hw_desc->src[src_idx].src_addr;
248 }
249 
250 static inline u32 iop_desc_get_src_count(struct iop_adma_desc_slot *desc,
251  struct iop_adma_chan *chan)
252 {
253  struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc;
254  return hw_desc->desc_ctrl_field.src_select + 1;
255 }
256 
257 static inline void
258 iop_desc_init_memcpy(struct iop_adma_desc_slot *desc, unsigned long flags)
259 {
260  struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc;
261  union {
262  u32 value;
264  } u_desc_ctrl;
265 
266  u_desc_ctrl.value = 0;
267  u_desc_ctrl.field.xfer_dir = 3; /* local to internal bus */
268  u_desc_ctrl.field.int_en = flags & DMA_PREP_INTERRUPT;
269  hw_desc->desc_ctrl = u_desc_ctrl.value;
270  hw_desc->crc_addr = 0;
271 }
272 
273 static inline void
274 iop_desc_init_memset(struct iop_adma_desc_slot *desc, unsigned long flags)
275 {
276  struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc;
277  union {
278  u32 value;
280  } u_desc_ctrl;
281 
282  u_desc_ctrl.value = 0;
283  u_desc_ctrl.field.xfer_dir = 3; /* local to internal bus */
284  u_desc_ctrl.field.block_fill_en = 1;
285  u_desc_ctrl.field.int_en = flags & DMA_PREP_INTERRUPT;
286  hw_desc->desc_ctrl = u_desc_ctrl.value;
287  hw_desc->crc_addr = 0;
288 }
289 
290 /* to do: support buffers larger than ADMA_MAX_BYTE_COUNT */
291 static inline void
292 iop_desc_init_xor(struct iop_adma_desc_slot *desc, int src_cnt,
293  unsigned long flags)
294 {
295  struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc;
296  union {
297  u32 value;
299  } u_desc_ctrl;
300 
301  u_desc_ctrl.value = 0;
302  u_desc_ctrl.field.src_select = src_cnt - 1;
303  u_desc_ctrl.field.xfer_dir = 3; /* local to internal bus */
304  u_desc_ctrl.field.int_en = flags & DMA_PREP_INTERRUPT;
305  hw_desc->desc_ctrl = u_desc_ctrl.value;
306  hw_desc->crc_addr = 0;
307 
308 }
309 #define iop_desc_init_null_xor(d, s, i) iop_desc_init_xor(d, s, i)
310 
311 /* to do: support buffers larger than ADMA_MAX_BYTE_COUNT */
312 static inline int
313 iop_desc_init_zero_sum(struct iop_adma_desc_slot *desc, int src_cnt,
314  unsigned long flags)
315 {
316  struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc;
317  union {
318  u32 value;
319  struct iop13xx_adma_desc_ctrl field;
320  } u_desc_ctrl;
321 
322  u_desc_ctrl.value = 0;
323  u_desc_ctrl.field.src_select = src_cnt - 1;
324  u_desc_ctrl.field.xfer_dir = 3; /* local to internal bus */
325  u_desc_ctrl.field.zero_result = 1;
326  u_desc_ctrl.field.status_write_back_en = 1;
327  u_desc_ctrl.field.int_en = flags & DMA_PREP_INTERRUPT;
328  hw_desc->desc_ctrl = u_desc_ctrl.value;
329  hw_desc->crc_addr = 0;
330 
331  return 1;
332 }
333 
334 static inline void
335 iop_desc_init_pq(struct iop_adma_desc_slot *desc, int src_cnt,
336  unsigned long flags)
337 {
338  struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc;
339  union {
340  u32 value;
342  } u_desc_ctrl;
343 
344  u_desc_ctrl.value = 0;
345  u_desc_ctrl.field.src_select = src_cnt - 1;
346  u_desc_ctrl.field.xfer_dir = 3; /* local to internal bus */
347  u_desc_ctrl.field.pq_xfer_en = 1;
348  u_desc_ctrl.field.p_xfer_dis = !!(flags & DMA_PREP_PQ_DISABLE_P);
349  u_desc_ctrl.field.int_en = flags & DMA_PREP_INTERRUPT;
350  hw_desc->desc_ctrl = u_desc_ctrl.value;
351 }
352 
353 static inline int iop_desc_is_pq(struct iop_adma_desc_slot *desc)
354 {
355  struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc;
356  union {
357  u32 value;
359  } u_desc_ctrl;
360 
361  u_desc_ctrl.value = hw_desc->desc_ctrl;
362  return u_desc_ctrl.field.pq_xfer_en;
363 }
364 
365 static inline void
366 iop_desc_init_pq_zero_sum(struct iop_adma_desc_slot *desc, int src_cnt,
367  unsigned long flags)
368 {
369  struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc;
370  union {
371  u32 value;
373  } u_desc_ctrl;
374 
375  u_desc_ctrl.value = 0;
376  u_desc_ctrl.field.src_select = src_cnt - 1;
377  u_desc_ctrl.field.xfer_dir = 3; /* local to internal bus */
378  u_desc_ctrl.field.zero_result = 1;
379  u_desc_ctrl.field.status_write_back_en = 1;
380  u_desc_ctrl.field.pq_xfer_en = 1;
381  u_desc_ctrl.field.p_xfer_dis = !!(flags & DMA_PREP_PQ_DISABLE_P);
382  u_desc_ctrl.field.int_en = flags & DMA_PREP_INTERRUPT;
383  hw_desc->desc_ctrl = u_desc_ctrl.value;
384 }
385 
386 static inline void iop_desc_set_byte_count(struct iop_adma_desc_slot *desc,
387  struct iop_adma_chan *chan,
388  u32 byte_count)
389 {
390  struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc;
391  hw_desc->byte_count = byte_count;
392 }
393 
394 static inline void
395 iop_desc_set_zero_sum_byte_count(struct iop_adma_desc_slot *desc, u32 len)
396 {
397  int slots_per_op = desc->slots_per_op;
398  struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc, *iter;
399  int i = 0;
400 
402  hw_desc->byte_count = len;
403  } else {
404  do {
405  iter = iop_hw_desc_slot_idx(hw_desc, i);
406  iter->byte_count = IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT;
408  i += slots_per_op;
409  } while (len > IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT);
410 
411  if (len) {
412  iter = iop_hw_desc_slot_idx(hw_desc, i);
413  iter->byte_count = len;
414  }
415  }
416 }
417 
418 #define iop_desc_set_pq_zero_sum_byte_count iop_desc_set_zero_sum_byte_count
419 
420 static inline void iop_desc_set_dest_addr(struct iop_adma_desc_slot *desc,
421  struct iop_adma_chan *chan,
423 {
424  struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc;
425  hw_desc->dest_addr = addr;
426  hw_desc->upper_dest_addr = 0;
427 }
428 
429 static inline void
430 iop_desc_set_pq_addr(struct iop_adma_desc_slot *desc, dma_addr_t *addr)
431 {
432  struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc;
433 
434  hw_desc->dest_addr = addr[0];
435  hw_desc->q_dest_addr = addr[1];
436  hw_desc->upper_dest_addr = 0;
437 }
438 
439 static inline void iop_desc_set_memcpy_src_addr(struct iop_adma_desc_slot *desc,
441 {
442  struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc;
443  hw_desc->src[0].src_addr = addr;
444  hw_desc->src[0].upper_src_addr = 0;
445 }
446 
447 static inline void iop_desc_set_xor_src_addr(struct iop_adma_desc_slot *desc,
448  int src_idx, dma_addr_t addr)
449 {
450  int slot_cnt = desc->slot_cnt, slots_per_op = desc->slots_per_op;
451  struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc, *iter;
452  int i = 0;
453 
454  do {
455  iter = iop_hw_desc_slot_idx(hw_desc, i);
456  iter->src[src_idx].src_addr = addr;
457  iter->src[src_idx].upper_src_addr = 0;
458  slot_cnt -= slots_per_op;
459  if (slot_cnt) {
460  i += slots_per_op;
462  }
463  } while (slot_cnt);
464 }
465 
466 static inline void
467 iop_desc_set_pq_src_addr(struct iop_adma_desc_slot *desc, int src_idx,
468  dma_addr_t addr, unsigned char coef)
469 {
470  int slot_cnt = desc->slot_cnt, slots_per_op = desc->slots_per_op;
471  struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc, *iter;
472  struct iop13xx_adma_src *src;
473  int i = 0;
474 
475  do {
476  iter = iop_hw_desc_slot_idx(hw_desc, i);
477  src = &iter->src[src_idx];
478  src->src_addr = addr;
479  src->pq_upper_src_addr = 0;
480  src->pq_dmlt = coef;
481  slot_cnt -= slots_per_op;
482  if (slot_cnt) {
483  i += slots_per_op;
485  }
486  } while (slot_cnt);
487 }
488 
489 static inline void
490 iop_desc_init_interrupt(struct iop_adma_desc_slot *desc,
491  struct iop_adma_chan *chan)
492 {
493  iop_desc_init_memcpy(desc, 1);
494  iop_desc_set_byte_count(desc, chan, 0);
495  iop_desc_set_dest_addr(desc, chan, 0);
496  iop_desc_set_memcpy_src_addr(desc, 0);
497 }
498 
499 #define iop_desc_set_zero_sum_src_addr iop_desc_set_xor_src_addr
500 #define iop_desc_set_pq_zero_sum_src_addr iop_desc_set_pq_src_addr
501 
502 static inline void
503 iop_desc_set_pq_zero_sum_addr(struct iop_adma_desc_slot *desc, int pq_idx,
504  dma_addr_t *src)
505 {
506  iop_desc_set_xor_src_addr(desc, pq_idx, src[pq_idx]);
507  iop_desc_set_xor_src_addr(desc, pq_idx+1, src[pq_idx+1]);
508 }
509 
510 static inline void iop_desc_set_next_desc(struct iop_adma_desc_slot *desc,
511  u32 next_desc_addr)
512 {
513  struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc;
514 
515  iop_paranoia(hw_desc->next_desc);
516  hw_desc->next_desc = next_desc_addr;
517 }
518 
519 static inline u32 iop_desc_get_next_desc(struct iop_adma_desc_slot *desc)
520 {
521  struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc;
522  return hw_desc->next_desc;
523 }
524 
525 static inline void iop_desc_clear_next_desc(struct iop_adma_desc_slot *desc)
526 {
527  struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc;
528  hw_desc->next_desc = 0;
529 }
530 
531 static inline void iop_desc_set_block_fill_val(struct iop_adma_desc_slot *desc,
532  u32 val)
533 {
534  struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc;
535  hw_desc->block_fill_data = val;
536 }
537 
538 static inline enum sum_check_flags
539 iop_desc_get_zero_result(struct iop_adma_desc_slot *desc)
540 {
541  struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc;
542  struct iop13xx_adma_desc_ctrl desc_ctrl = hw_desc->desc_ctrl_field;
544  enum sum_check_flags flags;
545 
546  BUG_ON(!(byte_count.tx_complete && desc_ctrl.zero_result));
547 
548  flags = byte_count.zero_result_err_q << SUM_CHECK_Q;
549  flags |= byte_count.zero_result_err << SUM_CHECK_P;
550 
551  return flags;
552 }
553 
554 static inline void iop_chan_append(struct iop_adma_chan *chan)
555 {
556  u32 adma_accr;
557 
558  adma_accr = __raw_readl(ADMA_ACCR(chan));
559  adma_accr |= 0x2;
560  __raw_writel(adma_accr, ADMA_ACCR(chan));
561 }
562 
563 static inline u32 iop_chan_get_status(struct iop_adma_chan *chan)
564 {
565  return __raw_readl(ADMA_ACSR(chan));
566 }
567 
568 static inline void iop_chan_disable(struct iop_adma_chan *chan)
569 {
570  u32 adma_chan_ctrl = __raw_readl(ADMA_ACCR(chan));
571  adma_chan_ctrl &= ~0x1;
572  __raw_writel(adma_chan_ctrl, ADMA_ACCR(chan));
573 }
574 
575 static inline void iop_chan_enable(struct iop_adma_chan *chan)
576 {
577  u32 adma_chan_ctrl;
578 
579  adma_chan_ctrl = __raw_readl(ADMA_ACCR(chan));
580  adma_chan_ctrl |= 0x1;
581  __raw_writel(adma_chan_ctrl, ADMA_ACCR(chan));
582 }
583 
584 static inline void iop_adma_device_clear_eot_status(struct iop_adma_chan *chan)
585 {
586  u32 status = __raw_readl(ADMA_ACSR(chan));
587  status &= (1 << 12);
588  __raw_writel(status, ADMA_ACSR(chan));
589 }
590 
591 static inline void iop_adma_device_clear_eoc_status(struct iop_adma_chan *chan)
592 {
593  u32 status = __raw_readl(ADMA_ACSR(chan));
594  status &= (1 << 11);
595  __raw_writel(status, ADMA_ACSR(chan));
596 }
597 
598 static inline void iop_adma_device_clear_err_status(struct iop_adma_chan *chan)
599 {
600  u32 status = __raw_readl(ADMA_ACSR(chan));
601  status &= (1 << 9) | (1 << 5) | (1 << 4) | (1 << 3);
602  __raw_writel(status, ADMA_ACSR(chan));
603 }
604 
605 static inline int
606 iop_is_err_int_parity(unsigned long status, struct iop_adma_chan *chan)
607 {
608  return test_bit(9, &status);
609 }
610 
611 static inline int
612 iop_is_err_mcu_abort(unsigned long status, struct iop_adma_chan *chan)
613 {
614  return test_bit(5, &status);
615 }
616 
617 static inline int
618 iop_is_err_int_tabort(unsigned long status, struct iop_adma_chan *chan)
619 {
620  return test_bit(4, &status);
621 }
622 
623 static inline int
624 iop_is_err_int_mabort(unsigned long status, struct iop_adma_chan *chan)
625 {
626  return test_bit(3, &status);
627 }
628 
629 static inline int
630 iop_is_err_pci_tabort(unsigned long status, struct iop_adma_chan *chan)
631 {
632  return 0;
633 }
634 
635 static inline int
636 iop_is_err_pci_mabort(unsigned long status, struct iop_adma_chan *chan)
637 {
638  return 0;
639 }
640 
641 static inline int
642 iop_is_err_split_tx(unsigned long status, struct iop_adma_chan *chan)
643 {
644  return 0;
645 }
646 
647 #endif /* _ADMA_H */