210 lines · c
1/* SPDX-License-Identifier: GPL-2.0 */2/*3 * Copyright (c) 2018-2019 Synopsys, Inc. and/or its affiliates.4 * Synopsys DesignWare eDMA core driver5 *6 * Author: Gustavo Pimentel <gustavo.pimentel@synopsys.com>7 */8 9#ifndef _DW_EDMA_CORE_H10#define _DW_EDMA_CORE_H11 12#include <linux/msi.h>13#include <linux/dma/edma.h>14 15#include "../virt-dma.h"16 17#define EDMA_LL_SZ 2418 19enum dw_edma_dir {20 EDMA_DIR_WRITE = 0,21 EDMA_DIR_READ22};23 24enum dw_edma_request {25 EDMA_REQ_NONE = 0,26 EDMA_REQ_STOP,27 EDMA_REQ_PAUSE28};29 30enum dw_edma_status {31 EDMA_ST_IDLE = 0,32 EDMA_ST_PAUSE,33 EDMA_ST_BUSY34};35 36enum dw_edma_xfer_type {37 EDMA_XFER_SCATTER_GATHER = 0,38 EDMA_XFER_CYCLIC,39 EDMA_XFER_INTERLEAVED40};41 42struct dw_edma_chan;43struct dw_edma_chunk;44 45struct dw_edma_burst {46 struct list_head list;47 u64 sar;48 u64 dar;49 u32 sz;50};51 52struct dw_edma_chunk {53 struct list_head list;54 struct dw_edma_chan *chan;55 struct dw_edma_burst *burst;56 57 u32 bursts_alloc;58 59 u8 cb;60 struct dw_edma_region ll_region; /* Linked list */61};62 63struct dw_edma_desc {64 struct virt_dma_desc vd;65 struct dw_edma_chan *chan;66 struct dw_edma_chunk *chunk;67 68 u32 chunks_alloc;69 70 u32 alloc_sz;71 u32 xfer_sz;72};73 74struct dw_edma_chan {75 struct virt_dma_chan vc;76 struct dw_edma *dw;77 int id;78 enum dw_edma_dir dir;79 80 u32 ll_max;81 82 struct msi_msg msi;83 84 enum dw_edma_request request;85 enum dw_edma_status status;86 u8 configured;87 88 struct dma_slave_config config;89};90 91struct dw_edma_irq {92 struct msi_msg msi;93 u32 wr_mask;94 u32 rd_mask;95 struct dw_edma *dw;96};97 98struct dw_edma {99 char name[32];100 101 struct dma_device dma;102 103 u16 wr_ch_cnt;104 u16 rd_ch_cnt;105 106 struct dw_edma_irq *irq;107 int nr_irqs;108 109 struct dw_edma_chan *chan;110 111 raw_spinlock_t lock; /* Only for legacy */112 113 struct dw_edma_chip *chip;114 115 const struct dw_edma_core_ops *core;116};117 118typedef void (*dw_edma_handler_t)(struct dw_edma_chan *);119 120struct dw_edma_core_ops {121 void (*off)(struct dw_edma *dw);122 u16 (*ch_count)(struct dw_edma *dw, enum dw_edma_dir dir);123 enum dma_status (*ch_status)(struct dw_edma_chan *chan);124 irqreturn_t (*handle_int)(struct dw_edma_irq *dw_irq, enum dw_edma_dir dir,125 dw_edma_handler_t done, dw_edma_handler_t abort);126 void (*start)(struct dw_edma_chunk *chunk, bool first);127 void (*ch_config)(struct dw_edma_chan *chan);128 void (*debugfs_on)(struct dw_edma *dw);129};130 131struct dw_edma_sg {132 struct scatterlist *sgl;133 unsigned int len;134};135 136struct dw_edma_cyclic {137 dma_addr_t paddr;138 size_t len;139 size_t cnt;140};141 142struct dw_edma_transfer {143 struct dma_chan *dchan;144 union dw_edma_xfer {145 struct dw_edma_sg sg;146 struct dw_edma_cyclic cyclic;147 struct dma_interleaved_template *il;148 } xfer;149 enum dma_transfer_direction direction;150 unsigned long flags;151 enum dw_edma_xfer_type type;152};153 154static inline155struct dw_edma_chan *vc2dw_edma_chan(struct virt_dma_chan *vc)156{157 return container_of(vc, struct dw_edma_chan, vc);158}159 160static inline161struct dw_edma_chan *dchan2dw_edma_chan(struct dma_chan *dchan)162{163 return vc2dw_edma_chan(to_virt_chan(dchan));164}165 166static inline167void dw_edma_core_off(struct dw_edma *dw)168{169 dw->core->off(dw);170}171 172static inline173u16 dw_edma_core_ch_count(struct dw_edma *dw, enum dw_edma_dir dir)174{175 return dw->core->ch_count(dw, dir);176}177 178static inline179enum dma_status dw_edma_core_ch_status(struct dw_edma_chan *chan)180{181 return chan->dw->core->ch_status(chan);182}183 184static inline irqreturn_t185dw_edma_core_handle_int(struct dw_edma_irq *dw_irq, enum dw_edma_dir dir,186 dw_edma_handler_t done, dw_edma_handler_t abort)187{188 return dw_irq->dw->core->handle_int(dw_irq, dir, done, abort);189}190 191static inline192void dw_edma_core_start(struct dw_edma *dw, struct dw_edma_chunk *chunk, bool first)193{194 dw->core->start(chunk, first);195}196 197static inline198void dw_edma_core_ch_config(struct dw_edma_chan *chan)199{200 chan->dw->core->ch_config(chan);201}202 203static inline204void dw_edma_core_debugfs_on(struct dw_edma *dw)205{206 dw->core->debugfs_on(dw);207}208 209#endif /* _DW_EDMA_CORE_H */210