2019-11-07 11:49:21 +03:00
/* SPDX-License-Identifier: GPL-2.0-or-later */
2019-11-18 17:35:52 +03:00
/*
2019-11-07 11:49:21 +03:00
* SiFive FU540 Platform DMA driver
* Copyright ( C ) 2019 SiFive
*
* Based partially on :
* - drivers / dma / fsl - edma . c
* - drivers / dma / dw - edma /
* - drivers / dma / pxa - dma . c
*
* See the following sources for further documentation :
* - Chapter 12 " Platform DMA Engine (PDMA) " of
* SiFive FU540 - C000 v1 .0
* https : //static.dev.sifive.com/FU540-C000-v1.0.pdf
*/
# ifndef _SF_PDMA_H
# define _SF_PDMA_H
# include <linux/dmaengine.h>
# include <linux/dma-direction.h>
# include "../dmaengine.h"
# include "../virt-dma.h"
2022-03-28 12:52:25 +03:00
# define PDMA_MAX_NR_CH 4
2019-11-07 11:49:21 +03:00
# define PDMA_BASE_ADDR 0x3000000
# define PDMA_CHAN_OFFSET 0x1000
/* Register Offset */
# define PDMA_CTRL 0x000
# define PDMA_XFER_TYPE 0x004
# define PDMA_XFER_SIZE 0x008
# define PDMA_DST_ADDR 0x010
# define PDMA_SRC_ADDR 0x018
# define PDMA_ACT_TYPE 0x104 /* Read-only */
# define PDMA_REMAINING_BYTE 0x108 /* Read-only */
# define PDMA_CUR_DST_ADDR 0x110 /* Read-only*/
# define PDMA_CUR_SRC_ADDR 0x118 /* Read-only*/
/* CTRL */
# define PDMA_CLEAR_CTRL 0x0
# define PDMA_CLAIM_MASK GENMASK(0, 0)
# define PDMA_RUN_MASK GENMASK(1, 1)
# define PDMA_ENABLE_DONE_INT_MASK GENMASK(14, 14)
# define PDMA_ENABLE_ERR_INT_MASK GENMASK(15, 15)
# define PDMA_DONE_STATUS_MASK GENMASK(30, 30)
# define PDMA_ERR_STATUS_MASK GENMASK(31, 31)
/* Transfer Type */
# define PDMA_FULL_SPEED 0xFF000008
/* Error Recovery */
# define MAX_RETRY 1
2019-11-18 17:35:53 +03:00
# define SF_PDMA_REG_BASE(ch) (pdma->membase + (PDMA_CHAN_OFFSET * (ch)))
2019-11-07 11:49:21 +03:00
struct pdma_regs {
/* read-write regs */
void __iomem * ctrl ; /* 4 bytes */
void __iomem * xfer_type ; /* 4 bytes */
void __iomem * xfer_size ; /* 8 bytes */
void __iomem * dst_addr ; /* 8 bytes */
void __iomem * src_addr ; /* 8 bytes */
/* read-only */
void __iomem * act_type ; /* 4 bytes */
void __iomem * residue ; /* 8 bytes */
void __iomem * cur_dst_addr ; /* 8 bytes */
void __iomem * cur_src_addr ; /* 8 bytes */
} ;
struct sf_pdma_desc {
u32 xfer_type ;
u64 xfer_size ;
u64 dst_addr ;
u64 src_addr ;
struct virt_dma_desc vdesc ;
struct sf_pdma_chan * chan ;
bool in_use ;
enum dma_transfer_direction dirn ;
struct dma_async_tx_descriptor * async_tx ;
} ;
enum sf_pdma_pm_state {
RUNNING = 0 ,
SUSPENDED ,
} ;
struct sf_pdma_chan {
struct virt_dma_chan vchan ;
enum dma_status status ;
enum sf_pdma_pm_state pm_state ;
u32 slave_id ;
struct sf_pdma * pdma ;
struct sf_pdma_desc * desc ;
struct dma_slave_config cfg ;
u32 attr ;
dma_addr_t dma_dev_addr ;
u32 dma_dev_size ;
struct tasklet_struct done_tasklet ;
struct tasklet_struct err_tasklet ;
struct pdma_regs regs ;
spinlock_t lock ; /* protect chan data */
bool xfer_err ;
int txirq ;
int errirq ;
int retries ;
} ;
struct sf_pdma {
struct dma_device dma_dev ;
void __iomem * membase ;
void __iomem * mappedbase ;
u32 n_chans ;
2022-03-28 12:52:25 +03:00
struct sf_pdma_chan chans [ ] ;
2019-11-07 11:49:21 +03:00
} ;
# endif /* _SF_PDMA_H */