Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-or-later */
0002 /*
0003  * SiFive FU540 Platform DMA driver
0004  * Copyright (C) 2019 SiFive
0005  *
0006  * Based partially on:
0007  * - drivers/dma/fsl-edma.c
0008  * - drivers/dma/dw-edma/
0009  * - drivers/dma/pxa-dma.c
0010  *
0011  * See the following sources for further documentation:
0012  * - Chapter 12 "Platform DMA Engine (PDMA)" of
0013  *   SiFive FU540-C000 v1.0
0014  *   https://static.dev.sifive.com/FU540-C000-v1.0.pdf
0015  */
0016 #ifndef _SF_PDMA_H
0017 #define _SF_PDMA_H
0018 
0019 #include <linux/dmaengine.h>
0020 #include <linux/dma-direction.h>
0021 
0022 #include "../dmaengine.h"
0023 #include "../virt-dma.h"
0024 
0025 #define PDMA_MAX_NR_CH                  4
0026 
0027 #define PDMA_BASE_ADDR                  0x3000000
0028 #define PDMA_CHAN_OFFSET                0x1000
0029 
0030 /* Register Offset */
0031 #define PDMA_CTRL                   0x000
0032 #define PDMA_XFER_TYPE                  0x004
0033 #define PDMA_XFER_SIZE                  0x008
0034 #define PDMA_DST_ADDR                   0x010
0035 #define PDMA_SRC_ADDR                   0x018
0036 #define PDMA_ACT_TYPE                   0x104 /* Read-only */
0037 #define PDMA_REMAINING_BYTE             0x108 /* Read-only */
0038 #define PDMA_CUR_DST_ADDR               0x110 /* Read-only*/
0039 #define PDMA_CUR_SRC_ADDR               0x118 /* Read-only*/
0040 
0041 /* CTRL */
0042 #define PDMA_CLEAR_CTRL                 0x0
0043 #define PDMA_CLAIM_MASK                 GENMASK(0, 0)
0044 #define PDMA_RUN_MASK                   GENMASK(1, 1)
0045 #define PDMA_ENABLE_DONE_INT_MASK           GENMASK(14, 14)
0046 #define PDMA_ENABLE_ERR_INT_MASK            GENMASK(15, 15)
0047 #define PDMA_DONE_STATUS_MASK               GENMASK(30, 30)
0048 #define PDMA_ERR_STATUS_MASK                GENMASK(31, 31)
0049 
0050 /* Transfer Type */
0051 #define PDMA_FULL_SPEED                 0xFF000008
0052 
0053 /* Error Recovery */
0054 #define MAX_RETRY                   1
0055 
0056 #define SF_PDMA_REG_BASE(ch)    (pdma->membase + (PDMA_CHAN_OFFSET * (ch)))
0057 
0058 struct pdma_regs {
0059     /* read-write regs */
0060     void __iomem *ctrl;     /* 4 bytes */
0061 
0062     void __iomem *xfer_type;    /* 4 bytes */
0063     void __iomem *xfer_size;    /* 8 bytes */
0064     void __iomem *dst_addr;     /* 8 bytes */
0065     void __iomem *src_addr;     /* 8 bytes */
0066 
0067     /* read-only */
0068     void __iomem *act_type;     /* 4 bytes */
0069     void __iomem *residue;      /* 8 bytes */
0070     void __iomem *cur_dst_addr; /* 8 bytes */
0071     void __iomem *cur_src_addr; /* 8 bytes */
0072 };
0073 
0074 struct sf_pdma_desc {
0075     u32             xfer_type;
0076     u64             xfer_size;
0077     u64             dst_addr;
0078     u64             src_addr;
0079     struct virt_dma_desc        vdesc;
0080     struct sf_pdma_chan     *chan;
0081     bool                in_use;
0082     enum dma_transfer_direction dirn;
0083     struct dma_async_tx_descriptor *async_tx;
0084 };
0085 
0086 enum sf_pdma_pm_state {
0087     RUNNING = 0,
0088     SUSPENDED,
0089 };
0090 
0091 struct sf_pdma_chan {
0092     struct virt_dma_chan        vchan;
0093     enum dma_status         status;
0094     enum sf_pdma_pm_state       pm_state;
0095     u32             slave_id;
0096     struct sf_pdma          *pdma;
0097     struct sf_pdma_desc     *desc;
0098     struct dma_slave_config     cfg;
0099     u32             attr;
0100     dma_addr_t          dma_dev_addr;
0101     u32             dma_dev_size;
0102     struct tasklet_struct       done_tasklet;
0103     struct tasklet_struct       err_tasklet;
0104     struct pdma_regs        regs;
0105     spinlock_t          lock; /* protect chan data */
0106     bool                xfer_err;
0107     int             txirq;
0108     int             errirq;
0109     int             retries;
0110 };
0111 
0112 struct sf_pdma {
0113     struct dma_device       dma_dev;
0114     void __iomem            *membase;
0115     void __iomem            *mappedbase;
0116     u32         n_chans;
0117     struct sf_pdma_chan chans[];
0118 };
0119 
0120 #endif /* _SF_PDMA_H */