^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* SPDX-License-Identifier: GPL-2.0-or-later */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * SiFive FU540 Platform DMA driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (C) 2019 SiFive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Based partially on:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * - drivers/dma/fsl-edma.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * - drivers/dma/dw-edma/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * - drivers/dma/pxa-dma.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * See the following sources for further documentation:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * - Chapter 12 "Platform DMA Engine (PDMA)" of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * SiFive FU540-C000 v1.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * https://static.dev.sifive.com/FU540-C000-v1.0.pdf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #ifndef _SF_PDMA_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #define _SF_PDMA_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/dmaengine.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/dma-direction.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include "../dmaengine.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include "../virt-dma.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define PDMA_NR_CH 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #if (PDMA_NR_CH != 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #error "Please define PDMA_NR_CH to 4"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define PDMA_BASE_ADDR 0x3000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define PDMA_CHAN_OFFSET 0x1000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) /* Register Offset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define PDMA_CTRL 0x000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define PDMA_XFER_TYPE 0x004
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define PDMA_XFER_SIZE 0x008
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define PDMA_DST_ADDR 0x010
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define PDMA_SRC_ADDR 0x018
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define PDMA_ACT_TYPE 0x104 /* Read-only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define PDMA_REMAINING_BYTE 0x108 /* Read-only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define PDMA_CUR_DST_ADDR 0x110 /* Read-only*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define PDMA_CUR_SRC_ADDR 0x118 /* Read-only*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) /* CTRL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define PDMA_CLEAR_CTRL 0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define PDMA_CLAIM_MASK GENMASK(0, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define PDMA_RUN_MASK GENMASK(1, 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define PDMA_ENABLE_DONE_INT_MASK GENMASK(14, 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define PDMA_ENABLE_ERR_INT_MASK GENMASK(15, 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define PDMA_DONE_STATUS_MASK GENMASK(30, 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define PDMA_ERR_STATUS_MASK GENMASK(31, 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) /* Transfer Type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define PDMA_FULL_SPEED 0xFF000008
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) /* Error Recovery */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define MAX_RETRY 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define SF_PDMA_REG_BASE(ch) (pdma->membase + (PDMA_CHAN_OFFSET * (ch)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) struct pdma_regs {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) /* read-write regs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) void __iomem *ctrl; /* 4 bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) void __iomem *xfer_type; /* 4 bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) void __iomem *xfer_size; /* 8 bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) void __iomem *dst_addr; /* 8 bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) void __iomem *src_addr; /* 8 bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) /* read-only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) void __iomem *act_type; /* 4 bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) void __iomem *residue; /* 8 bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) void __iomem *cur_dst_addr; /* 8 bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) void __iomem *cur_src_addr; /* 8 bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) struct sf_pdma_desc {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) u32 xfer_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) u64 xfer_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) u64 dst_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) u64 src_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) struct virt_dma_desc vdesc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) struct sf_pdma_chan *chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) bool in_use;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) enum dma_transfer_direction dirn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) struct dma_async_tx_descriptor *async_tx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) enum sf_pdma_pm_state {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) RUNNING = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) SUSPENDED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) struct sf_pdma_chan {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) struct virt_dma_chan vchan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) enum dma_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) enum sf_pdma_pm_state pm_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) u32 slave_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) struct sf_pdma *pdma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) struct sf_pdma_desc *desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) struct dma_slave_config cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) u32 attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) dma_addr_t dma_dev_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) u32 dma_dev_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) struct tasklet_struct done_tasklet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) struct tasklet_struct err_tasklet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) struct pdma_regs regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) spinlock_t lock; /* protect chan data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) bool xfer_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) int txirq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) int errirq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) int retries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) struct sf_pdma {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) struct dma_device dma_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) void __iomem *membase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) void __iomem *mappedbase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) u32 n_chans;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) struct sf_pdma_chan chans[PDMA_NR_CH];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) #endif /* _SF_PDMA_H */