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