1*4882a593Smuzhiyun /* 2*4882a593Smuzhiyun * 2006-2009 (C) DENX Software Engineering. 3*4882a593Smuzhiyun * 4*4882a593Smuzhiyun * Author: Yuri Tikhonov <yur@emcraft.com> 5*4882a593Smuzhiyun * 6*4882a593Smuzhiyun * This file is licensed under the terms of the GNU General Public License 7*4882a593Smuzhiyun * version 2. This program is licensed "as is" without any warranty of 8*4882a593Smuzhiyun * any kind, whether express or implied. 9*4882a593Smuzhiyun */ 10*4882a593Smuzhiyun 11*4882a593Smuzhiyun #ifndef _PPC440SPE_ADMA_H 12*4882a593Smuzhiyun #define _PPC440SPE_ADMA_H 13*4882a593Smuzhiyun 14*4882a593Smuzhiyun #include <linux/types.h> 15*4882a593Smuzhiyun #include "dma.h" 16*4882a593Smuzhiyun #include "xor.h" 17*4882a593Smuzhiyun 18*4882a593Smuzhiyun #define to_ppc440spe_adma_chan(chan) \ 19*4882a593Smuzhiyun container_of(chan, struct ppc440spe_adma_chan, common) 20*4882a593Smuzhiyun #define to_ppc440spe_adma_device(dev) \ 21*4882a593Smuzhiyun container_of(dev, struct ppc440spe_adma_device, common) 22*4882a593Smuzhiyun #define tx_to_ppc440spe_adma_slot(tx) \ 23*4882a593Smuzhiyun container_of(tx, struct ppc440spe_adma_desc_slot, async_tx) 24*4882a593Smuzhiyun 25*4882a593Smuzhiyun /* Default polynomial (for 440SP is only available) */ 26*4882a593Smuzhiyun #define PPC440SPE_DEFAULT_POLY 0x4d 27*4882a593Smuzhiyun 28*4882a593Smuzhiyun #define PPC440SPE_ADMA_ENGINES_NUM (XOR_ENGINES_NUM + DMA_ENGINES_NUM) 29*4882a593Smuzhiyun 30*4882a593Smuzhiyun #define PPC440SPE_ADMA_WATCHDOG_MSEC 3 31*4882a593Smuzhiyun #define PPC440SPE_ADMA_THRESHOLD 1 32*4882a593Smuzhiyun 33*4882a593Smuzhiyun #define PPC440SPE_DMA0_ID 0 34*4882a593Smuzhiyun #define PPC440SPE_DMA1_ID 1 35*4882a593Smuzhiyun #define PPC440SPE_XOR_ID 2 36*4882a593Smuzhiyun 37*4882a593Smuzhiyun #define PPC440SPE_ADMA_DMA_MAX_BYTE_COUNT 0xFFFFFFUL 38*4882a593Smuzhiyun /* this is the XOR_CBBCR width */ 39*4882a593Smuzhiyun #define PPC440SPE_ADMA_XOR_MAX_BYTE_COUNT (1 << 31) 40*4882a593Smuzhiyun #define PPC440SPE_ADMA_ZERO_SUM_MAX_BYTE_COUNT PPC440SPE_ADMA_XOR_MAX_BYTE_COUNT 41*4882a593Smuzhiyun 42*4882a593Smuzhiyun #define PPC440SPE_RXOR_RUN 0 43*4882a593Smuzhiyun 44*4882a593Smuzhiyun #define MQ0_CF2H_RXOR_BS_MASK 0x1FF 45*4882a593Smuzhiyun 46*4882a593Smuzhiyun #undef ADMA_LL_DEBUG 47*4882a593Smuzhiyun 48*4882a593Smuzhiyun /** 49*4882a593Smuzhiyun * struct ppc440spe_adma_device - internal representation of an ADMA device 50*4882a593Smuzhiyun * @dev: device 51*4882a593Smuzhiyun * @dma_reg: base for DMAx register access 52*4882a593Smuzhiyun * @xor_reg: base for XOR register access 53*4882a593Smuzhiyun * @i2o_reg: base for I2O register access 54*4882a593Smuzhiyun * @id: HW ADMA Device selector 55*4882a593Smuzhiyun * @dma_desc_pool_virt: base of DMA descriptor region (CPU address) 56*4882a593Smuzhiyun * @dma_desc_pool: base of DMA descriptor region (DMA address) 57*4882a593Smuzhiyun * @pool_size: size of the pool 58*4882a593Smuzhiyun * @irq: DMAx or XOR irq number 59*4882a593Smuzhiyun * @err_irq: DMAx error irq number 60*4882a593Smuzhiyun * @common: embedded struct dma_device 61*4882a593Smuzhiyun */ 62*4882a593Smuzhiyun struct ppc440spe_adma_device { 63*4882a593Smuzhiyun struct device *dev; 64*4882a593Smuzhiyun struct dma_regs __iomem *dma_reg; 65*4882a593Smuzhiyun struct xor_regs __iomem *xor_reg; 66*4882a593Smuzhiyun struct i2o_regs __iomem *i2o_reg; 67*4882a593Smuzhiyun int id; 68*4882a593Smuzhiyun void *dma_desc_pool_virt; 69*4882a593Smuzhiyun dma_addr_t dma_desc_pool; 70*4882a593Smuzhiyun size_t pool_size; 71*4882a593Smuzhiyun int irq; 72*4882a593Smuzhiyun int err_irq; 73*4882a593Smuzhiyun struct dma_device common; 74*4882a593Smuzhiyun }; 75*4882a593Smuzhiyun 76*4882a593Smuzhiyun /** 77*4882a593Smuzhiyun * struct ppc440spe_adma_chan - internal representation of an ADMA channel 78*4882a593Smuzhiyun * @lock: serializes enqueue/dequeue operations to the slot pool 79*4882a593Smuzhiyun * @device: parent device 80*4882a593Smuzhiyun * @chain: device chain view of the descriptors 81*4882a593Smuzhiyun * @common: common dmaengine channel object members 82*4882a593Smuzhiyun * @all_slots: complete domain of slots usable by the channel 83*4882a593Smuzhiyun * @pending: allows batching of hardware operations 84*4882a593Smuzhiyun * @slots_allocated: records the actual size of the descriptor slot pool 85*4882a593Smuzhiyun * @hw_chain_inited: h/w descriptor chain initialization flag 86*4882a593Smuzhiyun * @irq_tasklet: bottom half where ppc440spe_adma_slot_cleanup runs 87*4882a593Smuzhiyun * @needs_unmap: if buffers should not be unmapped upon final processing 88*4882a593Smuzhiyun * @pdest_page: P destination page for async validate operation 89*4882a593Smuzhiyun * @qdest_page: Q destination page for async validate operation 90*4882a593Smuzhiyun * @pdest: P dma addr for async validate operation 91*4882a593Smuzhiyun * @qdest: Q dma addr for async validate operation 92*4882a593Smuzhiyun */ 93*4882a593Smuzhiyun struct ppc440spe_adma_chan { 94*4882a593Smuzhiyun spinlock_t lock; 95*4882a593Smuzhiyun struct ppc440spe_adma_device *device; 96*4882a593Smuzhiyun struct list_head chain; 97*4882a593Smuzhiyun struct dma_chan common; 98*4882a593Smuzhiyun struct list_head all_slots; 99*4882a593Smuzhiyun struct ppc440spe_adma_desc_slot *last_used; 100*4882a593Smuzhiyun int pending; 101*4882a593Smuzhiyun int slots_allocated; 102*4882a593Smuzhiyun int hw_chain_inited; 103*4882a593Smuzhiyun struct tasklet_struct irq_tasklet; 104*4882a593Smuzhiyun u8 needs_unmap; 105*4882a593Smuzhiyun struct page *pdest_page; 106*4882a593Smuzhiyun struct page *qdest_page; 107*4882a593Smuzhiyun dma_addr_t pdest; 108*4882a593Smuzhiyun dma_addr_t qdest; 109*4882a593Smuzhiyun }; 110*4882a593Smuzhiyun 111*4882a593Smuzhiyun struct ppc440spe_rxor { 112*4882a593Smuzhiyun u32 addrl; 113*4882a593Smuzhiyun u32 addrh; 114*4882a593Smuzhiyun int len; 115*4882a593Smuzhiyun int xor_count; 116*4882a593Smuzhiyun int addr_count; 117*4882a593Smuzhiyun int desc_count; 118*4882a593Smuzhiyun int state; 119*4882a593Smuzhiyun }; 120*4882a593Smuzhiyun 121*4882a593Smuzhiyun /** 122*4882a593Smuzhiyun * struct ppc440spe_adma_desc_slot - PPC440SPE-ADMA software descriptor 123*4882a593Smuzhiyun * @phys: hardware address of the hardware descriptor chain 124*4882a593Smuzhiyun * @group_head: first operation in a transaction 125*4882a593Smuzhiyun * @hw_next: pointer to the next descriptor in chain 126*4882a593Smuzhiyun * @async_tx: support for the async_tx api 127*4882a593Smuzhiyun * @slot_node: node on the iop_adma_chan.all_slots list 128*4882a593Smuzhiyun * @chain_node: node on the op_adma_chan.chain list 129*4882a593Smuzhiyun * @group_list: list of slots that make up a multi-descriptor transaction 130*4882a593Smuzhiyun * for example transfer lengths larger than the supported hw max 131*4882a593Smuzhiyun * @unmap_len: transaction bytecount 132*4882a593Smuzhiyun * @hw_desc: virtual address of the hardware descriptor chain 133*4882a593Smuzhiyun * @stride: currently chained or not 134*4882a593Smuzhiyun * @idx: pool index 135*4882a593Smuzhiyun * @slot_cnt: total slots used in an transaction (group of operations) 136*4882a593Smuzhiyun * @src_cnt: number of sources set in this descriptor 137*4882a593Smuzhiyun * @dst_cnt: number of destinations set in the descriptor 138*4882a593Smuzhiyun * @slots_per_op: number of slots per operation 139*4882a593Smuzhiyun * @descs_per_op: number of slot per P/Q operation see comment 140*4882a593Smuzhiyun * for ppc440spe_prep_dma_pqxor function 141*4882a593Smuzhiyun * @flags: desc state/type 142*4882a593Smuzhiyun * @reverse_flags: 1 if a corresponding rxor address uses reversed address order 143*4882a593Smuzhiyun * @xor_check_result: result of zero sum 144*4882a593Smuzhiyun * @crc32_result: result crc calculation 145*4882a593Smuzhiyun */ 146*4882a593Smuzhiyun struct ppc440spe_adma_desc_slot { 147*4882a593Smuzhiyun dma_addr_t phys; 148*4882a593Smuzhiyun struct ppc440spe_adma_desc_slot *group_head; 149*4882a593Smuzhiyun struct ppc440spe_adma_desc_slot *hw_next; 150*4882a593Smuzhiyun struct dma_async_tx_descriptor async_tx; 151*4882a593Smuzhiyun struct list_head slot_node; 152*4882a593Smuzhiyun struct list_head chain_node; /* node in channel ops list */ 153*4882a593Smuzhiyun struct list_head group_list; /* list */ 154*4882a593Smuzhiyun unsigned int unmap_len; 155*4882a593Smuzhiyun void *hw_desc; 156*4882a593Smuzhiyun u16 stride; 157*4882a593Smuzhiyun u16 idx; 158*4882a593Smuzhiyun u16 slot_cnt; 159*4882a593Smuzhiyun u8 src_cnt; 160*4882a593Smuzhiyun u8 dst_cnt; 161*4882a593Smuzhiyun u8 slots_per_op; 162*4882a593Smuzhiyun u8 descs_per_op; 163*4882a593Smuzhiyun unsigned long flags; 164*4882a593Smuzhiyun unsigned long reverse_flags[8]; 165*4882a593Smuzhiyun 166*4882a593Smuzhiyun #define PPC440SPE_DESC_INT 0 /* generate interrupt on complete */ 167*4882a593Smuzhiyun #define PPC440SPE_ZERO_P 1 /* clear P destionaion */ 168*4882a593Smuzhiyun #define PPC440SPE_ZERO_Q 2 /* clear Q destination */ 169*4882a593Smuzhiyun #define PPC440SPE_COHERENT 3 /* src/dst are coherent */ 170*4882a593Smuzhiyun 171*4882a593Smuzhiyun #define PPC440SPE_DESC_WXOR 4 /* WXORs are in chain */ 172*4882a593Smuzhiyun #define PPC440SPE_DESC_RXOR 5 /* RXOR is in chain */ 173*4882a593Smuzhiyun 174*4882a593Smuzhiyun #define PPC440SPE_DESC_RXOR123 8 /* CDB for RXOR123 operation */ 175*4882a593Smuzhiyun #define PPC440SPE_DESC_RXOR124 9 /* CDB for RXOR124 operation */ 176*4882a593Smuzhiyun #define PPC440SPE_DESC_RXOR125 10 /* CDB for RXOR125 operation */ 177*4882a593Smuzhiyun #define PPC440SPE_DESC_RXOR12 11 /* CDB for RXOR12 operation */ 178*4882a593Smuzhiyun #define PPC440SPE_DESC_RXOR_REV 12 /* CDB has srcs in reversed order */ 179*4882a593Smuzhiyun 180*4882a593Smuzhiyun #define PPC440SPE_DESC_PCHECK 13 181*4882a593Smuzhiyun #define PPC440SPE_DESC_QCHECK 14 182*4882a593Smuzhiyun 183*4882a593Smuzhiyun #define PPC440SPE_DESC_RXOR_MSK 0x3 184*4882a593Smuzhiyun 185*4882a593Smuzhiyun struct ppc440spe_rxor rxor_cursor; 186*4882a593Smuzhiyun 187*4882a593Smuzhiyun union { 188*4882a593Smuzhiyun u32 *xor_check_result; 189*4882a593Smuzhiyun u32 *crc32_result; 190*4882a593Smuzhiyun }; 191*4882a593Smuzhiyun }; 192*4882a593Smuzhiyun 193*4882a593Smuzhiyun #endif /* _PPC440SPE_ADMA_H */ 194