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