162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright(c) 2004 - 2009 Intel Corporation. All rights reserved. 462306a36Sopenharmony_ci */ 562306a36Sopenharmony_ci#ifndef IOATDMA_H 662306a36Sopenharmony_ci#define IOATDMA_H 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#include <linux/dmaengine.h> 962306a36Sopenharmony_ci#include <linux/init.h> 1062306a36Sopenharmony_ci#include <linux/dmapool.h> 1162306a36Sopenharmony_ci#include <linux/cache.h> 1262306a36Sopenharmony_ci#include <linux/pci_ids.h> 1362306a36Sopenharmony_ci#include <linux/circ_buf.h> 1462306a36Sopenharmony_ci#include <linux/interrupt.h> 1562306a36Sopenharmony_ci#include "registers.h" 1662306a36Sopenharmony_ci#include "hw.h" 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ci#define IOAT_DMA_VERSION "5.00" 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_ci#define IOAT_DMA_DCA_ANY_CPU ~0 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci#define to_ioatdma_device(dev) container_of(dev, struct ioatdma_device, dma_dev) 2362306a36Sopenharmony_ci#define to_dev(ioat_chan) (&(ioat_chan)->ioat_dma->pdev->dev) 2462306a36Sopenharmony_ci#define to_pdev(ioat_chan) ((ioat_chan)->ioat_dma->pdev) 2562306a36Sopenharmony_ci 2662306a36Sopenharmony_ci#define chan_num(ch) ((int)((ch)->reg_base - (ch)->ioat_dma->reg_base) / 0x80) 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_ci/* ioat hardware assumes at least two sources for raid operations */ 2962306a36Sopenharmony_ci#define src_cnt_to_sw(x) ((x) + 2) 3062306a36Sopenharmony_ci#define src_cnt_to_hw(x) ((x) - 2) 3162306a36Sopenharmony_ci#define ndest_to_sw(x) ((x) + 1) 3262306a36Sopenharmony_ci#define ndest_to_hw(x) ((x) - 1) 3362306a36Sopenharmony_ci#define src16_cnt_to_sw(x) ((x) + 9) 3462306a36Sopenharmony_ci#define src16_cnt_to_hw(x) ((x) - 9) 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_ci/* 3762306a36Sopenharmony_ci * workaround for IOAT ver.3.0 null descriptor issue 3862306a36Sopenharmony_ci * (channel returns error when size is 0) 3962306a36Sopenharmony_ci */ 4062306a36Sopenharmony_ci#define NULL_DESC_BUFFER_SIZE 1 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_cienum ioat_irq_mode { 4362306a36Sopenharmony_ci IOAT_NOIRQ = 0, 4462306a36Sopenharmony_ci IOAT_MSIX, 4562306a36Sopenharmony_ci IOAT_MSI, 4662306a36Sopenharmony_ci IOAT_INTX 4762306a36Sopenharmony_ci}; 4862306a36Sopenharmony_ci 4962306a36Sopenharmony_ci/** 5062306a36Sopenharmony_ci * struct ioatdma_device - internal representation of a IOAT device 5162306a36Sopenharmony_ci * @pdev: PCI-Express device 5262306a36Sopenharmony_ci * @reg_base: MMIO register space base address 5362306a36Sopenharmony_ci * @completion_pool: DMA buffers for completion ops 5462306a36Sopenharmony_ci * @sed_hw_pool: DMA super descriptor pools 5562306a36Sopenharmony_ci * @dma_dev: embedded struct dma_device 5662306a36Sopenharmony_ci * @version: version of ioatdma device 5762306a36Sopenharmony_ci * @msix_entries: irq handlers 5862306a36Sopenharmony_ci * @idx: per channel data 5962306a36Sopenharmony_ci * @dca: direct cache access context 6062306a36Sopenharmony_ci * @irq_mode: interrupt mode (INTX, MSI, MSIX) 6162306a36Sopenharmony_ci * @cap: read DMA capabilities register 6262306a36Sopenharmony_ci */ 6362306a36Sopenharmony_cistruct ioatdma_device { 6462306a36Sopenharmony_ci struct pci_dev *pdev; 6562306a36Sopenharmony_ci void __iomem *reg_base; 6662306a36Sopenharmony_ci struct dma_pool *completion_pool; 6762306a36Sopenharmony_ci#define MAX_SED_POOLS 5 6862306a36Sopenharmony_ci struct dma_pool *sed_hw_pool[MAX_SED_POOLS]; 6962306a36Sopenharmony_ci struct dma_device dma_dev; 7062306a36Sopenharmony_ci u8 version; 7162306a36Sopenharmony_ci#define IOAT_MAX_CHANS 4 7262306a36Sopenharmony_ci struct msix_entry msix_entries[IOAT_MAX_CHANS]; 7362306a36Sopenharmony_ci struct ioatdma_chan *idx[IOAT_MAX_CHANS]; 7462306a36Sopenharmony_ci struct dca_provider *dca; 7562306a36Sopenharmony_ci enum ioat_irq_mode irq_mode; 7662306a36Sopenharmony_ci u32 cap; 7762306a36Sopenharmony_ci int chancnt; 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_ci /* shadow version for CB3.3 chan reset errata workaround */ 8062306a36Sopenharmony_ci u64 msixtba0; 8162306a36Sopenharmony_ci u64 msixdata0; 8262306a36Sopenharmony_ci u32 msixpba; 8362306a36Sopenharmony_ci}; 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_ci#define IOAT_MAX_ORDER 16 8662306a36Sopenharmony_ci#define IOAT_MAX_DESCS (1 << IOAT_MAX_ORDER) 8762306a36Sopenharmony_ci#define IOAT_CHUNK_SIZE (SZ_512K) 8862306a36Sopenharmony_ci#define IOAT_DESCS_PER_CHUNK (IOAT_CHUNK_SIZE / IOAT_DESC_SZ) 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_cistruct ioat_descs { 9162306a36Sopenharmony_ci void *virt; 9262306a36Sopenharmony_ci dma_addr_t hw; 9362306a36Sopenharmony_ci}; 9462306a36Sopenharmony_ci 9562306a36Sopenharmony_cistruct ioatdma_chan { 9662306a36Sopenharmony_ci struct dma_chan dma_chan; 9762306a36Sopenharmony_ci void __iomem *reg_base; 9862306a36Sopenharmony_ci dma_addr_t last_completion; 9962306a36Sopenharmony_ci spinlock_t cleanup_lock; 10062306a36Sopenharmony_ci unsigned long state; 10162306a36Sopenharmony_ci #define IOAT_CHAN_DOWN 0 10262306a36Sopenharmony_ci #define IOAT_COMPLETION_ACK 1 10362306a36Sopenharmony_ci #define IOAT_RESET_PENDING 2 10462306a36Sopenharmony_ci #define IOAT_KOBJ_INIT_FAIL 3 10562306a36Sopenharmony_ci #define IOAT_RUN 5 10662306a36Sopenharmony_ci #define IOAT_CHAN_ACTIVE 6 10762306a36Sopenharmony_ci struct timer_list timer; 10862306a36Sopenharmony_ci #define RESET_DELAY msecs_to_jiffies(100) 10962306a36Sopenharmony_ci struct ioatdma_device *ioat_dma; 11062306a36Sopenharmony_ci dma_addr_t completion_dma; 11162306a36Sopenharmony_ci u64 *completion; 11262306a36Sopenharmony_ci struct tasklet_struct cleanup_task; 11362306a36Sopenharmony_ci struct kobject kobj; 11462306a36Sopenharmony_ci 11562306a36Sopenharmony_ci/* ioat v2 / v3 channel attributes 11662306a36Sopenharmony_ci * @xfercap_log; log2 of channel max transfer length (for fast division) 11762306a36Sopenharmony_ci * @head: allocated index 11862306a36Sopenharmony_ci * @issued: hardware notification point 11962306a36Sopenharmony_ci * @tail: cleanup index 12062306a36Sopenharmony_ci * @dmacount: identical to 'head' except for occasionally resetting to zero 12162306a36Sopenharmony_ci * @alloc_order: log2 of the number of allocated descriptors 12262306a36Sopenharmony_ci * @produce: number of descriptors to produce at submit time 12362306a36Sopenharmony_ci * @ring: software ring buffer implementation of hardware ring 12462306a36Sopenharmony_ci * @prep_lock: serializes descriptor preparation (producers) 12562306a36Sopenharmony_ci */ 12662306a36Sopenharmony_ci size_t xfercap_log; 12762306a36Sopenharmony_ci u16 head; 12862306a36Sopenharmony_ci u16 issued; 12962306a36Sopenharmony_ci u16 tail; 13062306a36Sopenharmony_ci u16 dmacount; 13162306a36Sopenharmony_ci u16 alloc_order; 13262306a36Sopenharmony_ci u16 produce; 13362306a36Sopenharmony_ci struct ioat_ring_ent **ring; 13462306a36Sopenharmony_ci spinlock_t prep_lock; 13562306a36Sopenharmony_ci struct ioat_descs descs[IOAT_MAX_DESCS / IOAT_DESCS_PER_CHUNK]; 13662306a36Sopenharmony_ci int desc_chunks; 13762306a36Sopenharmony_ci int intr_coalesce; 13862306a36Sopenharmony_ci int prev_intr_coalesce; 13962306a36Sopenharmony_ci}; 14062306a36Sopenharmony_ci 14162306a36Sopenharmony_cistruct ioat_sysfs_entry { 14262306a36Sopenharmony_ci struct attribute attr; 14362306a36Sopenharmony_ci ssize_t (*show)(struct dma_chan *, char *); 14462306a36Sopenharmony_ci ssize_t (*store)(struct dma_chan *, const char *, size_t); 14562306a36Sopenharmony_ci}; 14662306a36Sopenharmony_ci 14762306a36Sopenharmony_ci/** 14862306a36Sopenharmony_ci * struct ioat_sed_ent - wrapper around super extended hardware descriptor 14962306a36Sopenharmony_ci * @hw: hardware SED 15062306a36Sopenharmony_ci * @dma: dma address for the SED 15162306a36Sopenharmony_ci * @parent: point to the dma descriptor that's the parent 15262306a36Sopenharmony_ci * @hw_pool: descriptor pool index 15362306a36Sopenharmony_ci */ 15462306a36Sopenharmony_cistruct ioat_sed_ent { 15562306a36Sopenharmony_ci struct ioat_sed_raw_descriptor *hw; 15662306a36Sopenharmony_ci dma_addr_t dma; 15762306a36Sopenharmony_ci struct ioat_ring_ent *parent; 15862306a36Sopenharmony_ci unsigned int hw_pool; 15962306a36Sopenharmony_ci}; 16062306a36Sopenharmony_ci 16162306a36Sopenharmony_ci/** 16262306a36Sopenharmony_ci * struct ioat_ring_ent - wrapper around hardware descriptor 16362306a36Sopenharmony_ci * @hw: hardware DMA descriptor (for memcpy) 16462306a36Sopenharmony_ci * @xor: hardware xor descriptor 16562306a36Sopenharmony_ci * @xor_ex: hardware xor extension descriptor 16662306a36Sopenharmony_ci * @pq: hardware pq descriptor 16762306a36Sopenharmony_ci * @pq_ex: hardware pq extension descriptor 16862306a36Sopenharmony_ci * @pqu: hardware pq update descriptor 16962306a36Sopenharmony_ci * @raw: hardware raw (un-typed) descriptor 17062306a36Sopenharmony_ci * @txd: the generic software descriptor for all engines 17162306a36Sopenharmony_ci * @len: total transaction length for unmap 17262306a36Sopenharmony_ci * @result: asynchronous result of validate operations 17362306a36Sopenharmony_ci * @id: identifier for debug 17462306a36Sopenharmony_ci * @sed: pointer to super extended descriptor sw desc 17562306a36Sopenharmony_ci */ 17662306a36Sopenharmony_ci 17762306a36Sopenharmony_cistruct ioat_ring_ent { 17862306a36Sopenharmony_ci union { 17962306a36Sopenharmony_ci struct ioat_dma_descriptor *hw; 18062306a36Sopenharmony_ci struct ioat_xor_descriptor *xor; 18162306a36Sopenharmony_ci struct ioat_xor_ext_descriptor *xor_ex; 18262306a36Sopenharmony_ci struct ioat_pq_descriptor *pq; 18362306a36Sopenharmony_ci struct ioat_pq_ext_descriptor *pq_ex; 18462306a36Sopenharmony_ci struct ioat_pq_update_descriptor *pqu; 18562306a36Sopenharmony_ci struct ioat_raw_descriptor *raw; 18662306a36Sopenharmony_ci }; 18762306a36Sopenharmony_ci size_t len; 18862306a36Sopenharmony_ci struct dma_async_tx_descriptor txd; 18962306a36Sopenharmony_ci enum sum_check_flags *result; 19062306a36Sopenharmony_ci #ifdef DEBUG 19162306a36Sopenharmony_ci int id; 19262306a36Sopenharmony_ci #endif 19362306a36Sopenharmony_ci struct ioat_sed_ent *sed; 19462306a36Sopenharmony_ci}; 19562306a36Sopenharmony_ci 19662306a36Sopenharmony_ciextern const struct sysfs_ops ioat_sysfs_ops; 19762306a36Sopenharmony_ciextern struct ioat_sysfs_entry ioat_version_attr; 19862306a36Sopenharmony_ciextern struct ioat_sysfs_entry ioat_cap_attr; 19962306a36Sopenharmony_ciextern int ioat_pending_level; 20062306a36Sopenharmony_ciextern struct kobj_type ioat_ktype; 20162306a36Sopenharmony_ciextern struct kmem_cache *ioat_cache; 20262306a36Sopenharmony_ciextern struct kmem_cache *ioat_sed_cache; 20362306a36Sopenharmony_ci 20462306a36Sopenharmony_cistatic inline struct ioatdma_chan *to_ioat_chan(struct dma_chan *c) 20562306a36Sopenharmony_ci{ 20662306a36Sopenharmony_ci return container_of(c, struct ioatdma_chan, dma_chan); 20762306a36Sopenharmony_ci} 20862306a36Sopenharmony_ci 20962306a36Sopenharmony_ci/* wrapper around hardware descriptor format + additional software fields */ 21062306a36Sopenharmony_ci#ifdef DEBUG 21162306a36Sopenharmony_ci#define set_desc_id(desc, i) ((desc)->id = (i)) 21262306a36Sopenharmony_ci#define desc_id(desc) ((desc)->id) 21362306a36Sopenharmony_ci#else 21462306a36Sopenharmony_ci#define set_desc_id(desc, i) 21562306a36Sopenharmony_ci#define desc_id(desc) (0) 21662306a36Sopenharmony_ci#endif 21762306a36Sopenharmony_ci 21862306a36Sopenharmony_cistatic inline void 21962306a36Sopenharmony_ci__dump_desc_dbg(struct ioatdma_chan *ioat_chan, struct ioat_dma_descriptor *hw, 22062306a36Sopenharmony_ci struct dma_async_tx_descriptor *tx, int id) 22162306a36Sopenharmony_ci{ 22262306a36Sopenharmony_ci struct device *dev = to_dev(ioat_chan); 22362306a36Sopenharmony_ci 22462306a36Sopenharmony_ci dev_dbg(dev, "desc[%d]: (%#llx->%#llx) cookie: %d flags: %#x" 22562306a36Sopenharmony_ci " ctl: %#10.8x (op: %#x int_en: %d compl: %d)\n", id, 22662306a36Sopenharmony_ci (unsigned long long) tx->phys, 22762306a36Sopenharmony_ci (unsigned long long) hw->next, tx->cookie, tx->flags, 22862306a36Sopenharmony_ci hw->ctl, hw->ctl_f.op, hw->ctl_f.int_en, hw->ctl_f.compl_write); 22962306a36Sopenharmony_ci} 23062306a36Sopenharmony_ci 23162306a36Sopenharmony_ci#define dump_desc_dbg(c, d) \ 23262306a36Sopenharmony_ci ({ if (d) __dump_desc_dbg(c, d->hw, &d->txd, desc_id(d)); 0; }) 23362306a36Sopenharmony_ci 23462306a36Sopenharmony_cistatic inline struct ioatdma_chan * 23562306a36Sopenharmony_ciioat_chan_by_index(struct ioatdma_device *ioat_dma, int index) 23662306a36Sopenharmony_ci{ 23762306a36Sopenharmony_ci return ioat_dma->idx[index]; 23862306a36Sopenharmony_ci} 23962306a36Sopenharmony_ci 24062306a36Sopenharmony_cistatic inline u64 ioat_chansts(struct ioatdma_chan *ioat_chan) 24162306a36Sopenharmony_ci{ 24262306a36Sopenharmony_ci return readq(ioat_chan->reg_base + IOAT_CHANSTS_OFFSET); 24362306a36Sopenharmony_ci} 24462306a36Sopenharmony_ci 24562306a36Sopenharmony_cistatic inline u64 ioat_chansts_to_addr(u64 status) 24662306a36Sopenharmony_ci{ 24762306a36Sopenharmony_ci return status & IOAT_CHANSTS_COMPLETED_DESCRIPTOR_ADDR; 24862306a36Sopenharmony_ci} 24962306a36Sopenharmony_ci 25062306a36Sopenharmony_cistatic inline u32 ioat_chanerr(struct ioatdma_chan *ioat_chan) 25162306a36Sopenharmony_ci{ 25262306a36Sopenharmony_ci return readl(ioat_chan->reg_base + IOAT_CHANERR_OFFSET); 25362306a36Sopenharmony_ci} 25462306a36Sopenharmony_ci 25562306a36Sopenharmony_cistatic inline void ioat_suspend(struct ioatdma_chan *ioat_chan) 25662306a36Sopenharmony_ci{ 25762306a36Sopenharmony_ci u8 ver = ioat_chan->ioat_dma->version; 25862306a36Sopenharmony_ci 25962306a36Sopenharmony_ci writeb(IOAT_CHANCMD_SUSPEND, 26062306a36Sopenharmony_ci ioat_chan->reg_base + IOAT_CHANCMD_OFFSET(ver)); 26162306a36Sopenharmony_ci} 26262306a36Sopenharmony_ci 26362306a36Sopenharmony_cistatic inline void ioat_reset(struct ioatdma_chan *ioat_chan) 26462306a36Sopenharmony_ci{ 26562306a36Sopenharmony_ci u8 ver = ioat_chan->ioat_dma->version; 26662306a36Sopenharmony_ci 26762306a36Sopenharmony_ci writeb(IOAT_CHANCMD_RESET, 26862306a36Sopenharmony_ci ioat_chan->reg_base + IOAT_CHANCMD_OFFSET(ver)); 26962306a36Sopenharmony_ci} 27062306a36Sopenharmony_ci 27162306a36Sopenharmony_cistatic inline bool ioat_reset_pending(struct ioatdma_chan *ioat_chan) 27262306a36Sopenharmony_ci{ 27362306a36Sopenharmony_ci u8 ver = ioat_chan->ioat_dma->version; 27462306a36Sopenharmony_ci u8 cmd; 27562306a36Sopenharmony_ci 27662306a36Sopenharmony_ci cmd = readb(ioat_chan->reg_base + IOAT_CHANCMD_OFFSET(ver)); 27762306a36Sopenharmony_ci return (cmd & IOAT_CHANCMD_RESET) == IOAT_CHANCMD_RESET; 27862306a36Sopenharmony_ci} 27962306a36Sopenharmony_ci 28062306a36Sopenharmony_cistatic inline bool is_ioat_active(unsigned long status) 28162306a36Sopenharmony_ci{ 28262306a36Sopenharmony_ci return ((status & IOAT_CHANSTS_STATUS) == IOAT_CHANSTS_ACTIVE); 28362306a36Sopenharmony_ci} 28462306a36Sopenharmony_ci 28562306a36Sopenharmony_cistatic inline bool is_ioat_idle(unsigned long status) 28662306a36Sopenharmony_ci{ 28762306a36Sopenharmony_ci return ((status & IOAT_CHANSTS_STATUS) == IOAT_CHANSTS_DONE); 28862306a36Sopenharmony_ci} 28962306a36Sopenharmony_ci 29062306a36Sopenharmony_cistatic inline bool is_ioat_halted(unsigned long status) 29162306a36Sopenharmony_ci{ 29262306a36Sopenharmony_ci return ((status & IOAT_CHANSTS_STATUS) == IOAT_CHANSTS_HALTED); 29362306a36Sopenharmony_ci} 29462306a36Sopenharmony_ci 29562306a36Sopenharmony_cistatic inline bool is_ioat_suspended(unsigned long status) 29662306a36Sopenharmony_ci{ 29762306a36Sopenharmony_ci return ((status & IOAT_CHANSTS_STATUS) == IOAT_CHANSTS_SUSPENDED); 29862306a36Sopenharmony_ci} 29962306a36Sopenharmony_ci 30062306a36Sopenharmony_ci/* channel was fatally programmed */ 30162306a36Sopenharmony_cistatic inline bool is_ioat_bug(unsigned long err) 30262306a36Sopenharmony_ci{ 30362306a36Sopenharmony_ci return !!err; 30462306a36Sopenharmony_ci} 30562306a36Sopenharmony_ci 30662306a36Sopenharmony_ci 30762306a36Sopenharmony_cistatic inline u32 ioat_ring_size(struct ioatdma_chan *ioat_chan) 30862306a36Sopenharmony_ci{ 30962306a36Sopenharmony_ci return 1 << ioat_chan->alloc_order; 31062306a36Sopenharmony_ci} 31162306a36Sopenharmony_ci 31262306a36Sopenharmony_ci/* count of descriptors in flight with the engine */ 31362306a36Sopenharmony_cistatic inline u16 ioat_ring_active(struct ioatdma_chan *ioat_chan) 31462306a36Sopenharmony_ci{ 31562306a36Sopenharmony_ci return CIRC_CNT(ioat_chan->head, ioat_chan->tail, 31662306a36Sopenharmony_ci ioat_ring_size(ioat_chan)); 31762306a36Sopenharmony_ci} 31862306a36Sopenharmony_ci 31962306a36Sopenharmony_ci/* count of descriptors pending submission to hardware */ 32062306a36Sopenharmony_cistatic inline u16 ioat_ring_pending(struct ioatdma_chan *ioat_chan) 32162306a36Sopenharmony_ci{ 32262306a36Sopenharmony_ci return CIRC_CNT(ioat_chan->head, ioat_chan->issued, 32362306a36Sopenharmony_ci ioat_ring_size(ioat_chan)); 32462306a36Sopenharmony_ci} 32562306a36Sopenharmony_ci 32662306a36Sopenharmony_cistatic inline u32 ioat_ring_space(struct ioatdma_chan *ioat_chan) 32762306a36Sopenharmony_ci{ 32862306a36Sopenharmony_ci return ioat_ring_size(ioat_chan) - ioat_ring_active(ioat_chan); 32962306a36Sopenharmony_ci} 33062306a36Sopenharmony_ci 33162306a36Sopenharmony_cistatic inline u16 33262306a36Sopenharmony_ciioat_xferlen_to_descs(struct ioatdma_chan *ioat_chan, size_t len) 33362306a36Sopenharmony_ci{ 33462306a36Sopenharmony_ci u16 num_descs = len >> ioat_chan->xfercap_log; 33562306a36Sopenharmony_ci 33662306a36Sopenharmony_ci num_descs += !!(len & ((1 << ioat_chan->xfercap_log) - 1)); 33762306a36Sopenharmony_ci return num_descs; 33862306a36Sopenharmony_ci} 33962306a36Sopenharmony_ci 34062306a36Sopenharmony_cistatic inline struct ioat_ring_ent * 34162306a36Sopenharmony_ciioat_get_ring_ent(struct ioatdma_chan *ioat_chan, u16 idx) 34262306a36Sopenharmony_ci{ 34362306a36Sopenharmony_ci return ioat_chan->ring[idx & (ioat_ring_size(ioat_chan) - 1)]; 34462306a36Sopenharmony_ci} 34562306a36Sopenharmony_ci 34662306a36Sopenharmony_cistatic inline void 34762306a36Sopenharmony_ciioat_set_chainaddr(struct ioatdma_chan *ioat_chan, u64 addr) 34862306a36Sopenharmony_ci{ 34962306a36Sopenharmony_ci writel(addr & 0x00000000FFFFFFFF, 35062306a36Sopenharmony_ci ioat_chan->reg_base + IOAT2_CHAINADDR_OFFSET_LOW); 35162306a36Sopenharmony_ci writel(addr >> 32, 35262306a36Sopenharmony_ci ioat_chan->reg_base + IOAT2_CHAINADDR_OFFSET_HIGH); 35362306a36Sopenharmony_ci} 35462306a36Sopenharmony_ci 35562306a36Sopenharmony_ci/* IOAT Prep functions */ 35662306a36Sopenharmony_cistruct dma_async_tx_descriptor * 35762306a36Sopenharmony_ciioat_dma_prep_memcpy_lock(struct dma_chan *c, dma_addr_t dma_dest, 35862306a36Sopenharmony_ci dma_addr_t dma_src, size_t len, unsigned long flags); 35962306a36Sopenharmony_cistruct dma_async_tx_descriptor * 36062306a36Sopenharmony_ciioat_prep_interrupt_lock(struct dma_chan *c, unsigned long flags); 36162306a36Sopenharmony_cistruct dma_async_tx_descriptor * 36262306a36Sopenharmony_ciioat_prep_xor(struct dma_chan *chan, dma_addr_t dest, dma_addr_t *src, 36362306a36Sopenharmony_ci unsigned int src_cnt, size_t len, unsigned long flags); 36462306a36Sopenharmony_cistruct dma_async_tx_descriptor * 36562306a36Sopenharmony_ciioat_prep_xor_val(struct dma_chan *chan, dma_addr_t *src, 36662306a36Sopenharmony_ci unsigned int src_cnt, size_t len, 36762306a36Sopenharmony_ci enum sum_check_flags *result, unsigned long flags); 36862306a36Sopenharmony_cistruct dma_async_tx_descriptor * 36962306a36Sopenharmony_ciioat_prep_pq(struct dma_chan *chan, dma_addr_t *dst, dma_addr_t *src, 37062306a36Sopenharmony_ci unsigned int src_cnt, const unsigned char *scf, size_t len, 37162306a36Sopenharmony_ci unsigned long flags); 37262306a36Sopenharmony_cistruct dma_async_tx_descriptor * 37362306a36Sopenharmony_ciioat_prep_pq_val(struct dma_chan *chan, dma_addr_t *pq, dma_addr_t *src, 37462306a36Sopenharmony_ci unsigned int src_cnt, const unsigned char *scf, size_t len, 37562306a36Sopenharmony_ci enum sum_check_flags *pqres, unsigned long flags); 37662306a36Sopenharmony_cistruct dma_async_tx_descriptor * 37762306a36Sopenharmony_ciioat_prep_pqxor(struct dma_chan *chan, dma_addr_t dst, dma_addr_t *src, 37862306a36Sopenharmony_ci unsigned int src_cnt, size_t len, unsigned long flags); 37962306a36Sopenharmony_cistruct dma_async_tx_descriptor * 38062306a36Sopenharmony_ciioat_prep_pqxor_val(struct dma_chan *chan, dma_addr_t *src, 38162306a36Sopenharmony_ci unsigned int src_cnt, size_t len, 38262306a36Sopenharmony_ci enum sum_check_flags *result, unsigned long flags); 38362306a36Sopenharmony_ci 38462306a36Sopenharmony_ci/* IOAT Operation functions */ 38562306a36Sopenharmony_ciirqreturn_t ioat_dma_do_interrupt(int irq, void *data); 38662306a36Sopenharmony_ciirqreturn_t ioat_dma_do_interrupt_msix(int irq, void *data); 38762306a36Sopenharmony_cistruct ioat_ring_ent ** 38862306a36Sopenharmony_ciioat_alloc_ring(struct dma_chan *c, int order, gfp_t flags); 38962306a36Sopenharmony_civoid ioat_start_null_desc(struct ioatdma_chan *ioat_chan); 39062306a36Sopenharmony_civoid ioat_free_ring_ent(struct ioat_ring_ent *desc, struct dma_chan *chan); 39162306a36Sopenharmony_ciint ioat_reset_hw(struct ioatdma_chan *ioat_chan); 39262306a36Sopenharmony_cienum dma_status 39362306a36Sopenharmony_ciioat_tx_status(struct dma_chan *c, dma_cookie_t cookie, 39462306a36Sopenharmony_ci struct dma_tx_state *txstate); 39562306a36Sopenharmony_civoid ioat_cleanup_event(struct tasklet_struct *t); 39662306a36Sopenharmony_civoid ioat_timer_event(struct timer_list *t); 39762306a36Sopenharmony_ciint ioat_check_space_lock(struct ioatdma_chan *ioat_chan, int num_descs); 39862306a36Sopenharmony_civoid ioat_issue_pending(struct dma_chan *chan); 39962306a36Sopenharmony_ci 40062306a36Sopenharmony_ci/* IOAT Init functions */ 40162306a36Sopenharmony_cibool is_bwd_ioat(struct pci_dev *pdev); 40262306a36Sopenharmony_cistruct dca_provider *ioat_dca_init(struct pci_dev *pdev, void __iomem *iobase); 40362306a36Sopenharmony_civoid ioat_kobject_add(struct ioatdma_device *ioat_dma, struct kobj_type *type); 40462306a36Sopenharmony_civoid ioat_kobject_del(struct ioatdma_device *ioat_dma); 40562306a36Sopenharmony_ciint ioat_dma_setup_interrupts(struct ioatdma_device *ioat_dma); 40662306a36Sopenharmony_civoid ioat_stop(struct ioatdma_chan *ioat_chan); 40762306a36Sopenharmony_ci#endif /* IOATDMA_H */ 408