1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-or-later */ 2*4882a593Smuzhiyun /* 3*4882a593Smuzhiyun * DMA driver header for STMicroelectronics STi FDMA controller 4*4882a593Smuzhiyun * 5*4882a593Smuzhiyun * Copyright (C) 2014 STMicroelectronics 6*4882a593Smuzhiyun * 7*4882a593Smuzhiyun * Author: Ludovic Barre <Ludovic.barre@st.com> 8*4882a593Smuzhiyun */ 9*4882a593Smuzhiyun #ifndef __DMA_ST_FDMA_H 10*4882a593Smuzhiyun #define __DMA_ST_FDMA_H 11*4882a593Smuzhiyun 12*4882a593Smuzhiyun #include <linux/dmaengine.h> 13*4882a593Smuzhiyun #include <linux/dmapool.h> 14*4882a593Smuzhiyun #include <linux/io.h> 15*4882a593Smuzhiyun #include <linux/remoteproc/st_slim_rproc.h> 16*4882a593Smuzhiyun #include "virt-dma.h" 17*4882a593Smuzhiyun 18*4882a593Smuzhiyun #define ST_FDMA_NR_DREQS 32 19*4882a593Smuzhiyun #define FW_NAME_SIZE 30 20*4882a593Smuzhiyun #define DRIVER_NAME "st-fdma" 21*4882a593Smuzhiyun 22*4882a593Smuzhiyun /** 23*4882a593Smuzhiyun * struct st_fdma_generic_node - Free running/paced generic node 24*4882a593Smuzhiyun * 25*4882a593Smuzhiyun * @length: Length in bytes of a line in a 2D mem to mem 26*4882a593Smuzhiyun * @sstride: Stride, in bytes, between source lines in a 2D data move 27*4882a593Smuzhiyun * @dstride: Stride, in bytes, between destination lines in a 2D data move 28*4882a593Smuzhiyun */ 29*4882a593Smuzhiyun struct st_fdma_generic_node { 30*4882a593Smuzhiyun u32 length; 31*4882a593Smuzhiyun u32 sstride; 32*4882a593Smuzhiyun u32 dstride; 33*4882a593Smuzhiyun }; 34*4882a593Smuzhiyun 35*4882a593Smuzhiyun /** 36*4882a593Smuzhiyun * struct st_fdma_hw_node - Node structure used by fdma hw 37*4882a593Smuzhiyun * 38*4882a593Smuzhiyun * @next: Pointer to next node 39*4882a593Smuzhiyun * @control: Transfer Control Parameters 40*4882a593Smuzhiyun * @nbytes: Number of Bytes to read 41*4882a593Smuzhiyun * @saddr: Source address 42*4882a593Smuzhiyun * @daddr: Destination address 43*4882a593Smuzhiyun * 44*4882a593Smuzhiyun * @generic: generic node for free running/paced transfert type 45*4882a593Smuzhiyun * 2 others transfert type are possible, but not yet implemented 46*4882a593Smuzhiyun * 47*4882a593Smuzhiyun * The NODE structures must be aligned to a 32 byte boundary 48*4882a593Smuzhiyun */ 49*4882a593Smuzhiyun struct st_fdma_hw_node { 50*4882a593Smuzhiyun u32 next; 51*4882a593Smuzhiyun u32 control; 52*4882a593Smuzhiyun u32 nbytes; 53*4882a593Smuzhiyun u32 saddr; 54*4882a593Smuzhiyun u32 daddr; 55*4882a593Smuzhiyun union { 56*4882a593Smuzhiyun struct st_fdma_generic_node generic; 57*4882a593Smuzhiyun }; 58*4882a593Smuzhiyun } __aligned(32); 59*4882a593Smuzhiyun 60*4882a593Smuzhiyun /* 61*4882a593Smuzhiyun * node control parameters 62*4882a593Smuzhiyun */ 63*4882a593Smuzhiyun #define FDMA_NODE_CTRL_REQ_MAP_MASK GENMASK(4, 0) 64*4882a593Smuzhiyun #define FDMA_NODE_CTRL_REQ_MAP_FREE_RUN 0x0 65*4882a593Smuzhiyun #define FDMA_NODE_CTRL_REQ_MAP_DREQ(n) ((n)&FDMA_NODE_CTRL_REQ_MAP_MASK) 66*4882a593Smuzhiyun #define FDMA_NODE_CTRL_REQ_MAP_EXT FDMA_NODE_CTRL_REQ_MAP_MASK 67*4882a593Smuzhiyun #define FDMA_NODE_CTRL_SRC_MASK GENMASK(6, 5) 68*4882a593Smuzhiyun #define FDMA_NODE_CTRL_SRC_STATIC BIT(5) 69*4882a593Smuzhiyun #define FDMA_NODE_CTRL_SRC_INCR BIT(6) 70*4882a593Smuzhiyun #define FDMA_NODE_CTRL_DST_MASK GENMASK(8, 7) 71*4882a593Smuzhiyun #define FDMA_NODE_CTRL_DST_STATIC BIT(7) 72*4882a593Smuzhiyun #define FDMA_NODE_CTRL_DST_INCR BIT(8) 73*4882a593Smuzhiyun #define FDMA_NODE_CTRL_SECURE BIT(15) 74*4882a593Smuzhiyun #define FDMA_NODE_CTRL_PAUSE_EON BIT(30) 75*4882a593Smuzhiyun #define FDMA_NODE_CTRL_INT_EON BIT(31) 76*4882a593Smuzhiyun 77*4882a593Smuzhiyun /** 78*4882a593Smuzhiyun * struct st_fdma_sw_node - descriptor structure for link list 79*4882a593Smuzhiyun * 80*4882a593Smuzhiyun * @pdesc: Physical address of desc 81*4882a593Smuzhiyun * @node: link used for putting this into a channel queue 82*4882a593Smuzhiyun */ 83*4882a593Smuzhiyun struct st_fdma_sw_node { 84*4882a593Smuzhiyun dma_addr_t pdesc; 85*4882a593Smuzhiyun struct st_fdma_hw_node *desc; 86*4882a593Smuzhiyun }; 87*4882a593Smuzhiyun 88*4882a593Smuzhiyun #define NAME_SZ 10 89*4882a593Smuzhiyun 90*4882a593Smuzhiyun struct st_fdma_driverdata { 91*4882a593Smuzhiyun u32 id; 92*4882a593Smuzhiyun char name[NAME_SZ]; 93*4882a593Smuzhiyun }; 94*4882a593Smuzhiyun 95*4882a593Smuzhiyun struct st_fdma_desc { 96*4882a593Smuzhiyun struct virt_dma_desc vdesc; 97*4882a593Smuzhiyun struct st_fdma_chan *fchan; 98*4882a593Smuzhiyun bool iscyclic; 99*4882a593Smuzhiyun unsigned int n_nodes; 100*4882a593Smuzhiyun struct st_fdma_sw_node node[]; 101*4882a593Smuzhiyun }; 102*4882a593Smuzhiyun 103*4882a593Smuzhiyun enum st_fdma_type { 104*4882a593Smuzhiyun ST_FDMA_TYPE_FREE_RUN, 105*4882a593Smuzhiyun ST_FDMA_TYPE_PACED, 106*4882a593Smuzhiyun }; 107*4882a593Smuzhiyun 108*4882a593Smuzhiyun struct st_fdma_cfg { 109*4882a593Smuzhiyun struct device_node *of_node; 110*4882a593Smuzhiyun enum st_fdma_type type; 111*4882a593Smuzhiyun dma_addr_t dev_addr; 112*4882a593Smuzhiyun enum dma_transfer_direction dir; 113*4882a593Smuzhiyun int req_line; /* request line */ 114*4882a593Smuzhiyun long req_ctrl; /* Request control */ 115*4882a593Smuzhiyun }; 116*4882a593Smuzhiyun 117*4882a593Smuzhiyun struct st_fdma_chan { 118*4882a593Smuzhiyun struct st_fdma_dev *fdev; 119*4882a593Smuzhiyun struct dma_pool *node_pool; 120*4882a593Smuzhiyun struct dma_slave_config scfg; 121*4882a593Smuzhiyun struct st_fdma_cfg cfg; 122*4882a593Smuzhiyun 123*4882a593Smuzhiyun int dreq_line; 124*4882a593Smuzhiyun 125*4882a593Smuzhiyun struct virt_dma_chan vchan; 126*4882a593Smuzhiyun struct st_fdma_desc *fdesc; 127*4882a593Smuzhiyun enum dma_status status; 128*4882a593Smuzhiyun }; 129*4882a593Smuzhiyun 130*4882a593Smuzhiyun struct st_fdma_dev { 131*4882a593Smuzhiyun struct device *dev; 132*4882a593Smuzhiyun const struct st_fdma_driverdata *drvdata; 133*4882a593Smuzhiyun struct dma_device dma_device; 134*4882a593Smuzhiyun 135*4882a593Smuzhiyun struct st_slim_rproc *slim_rproc; 136*4882a593Smuzhiyun 137*4882a593Smuzhiyun int irq; 138*4882a593Smuzhiyun 139*4882a593Smuzhiyun struct st_fdma_chan *chans; 140*4882a593Smuzhiyun 141*4882a593Smuzhiyun spinlock_t dreq_lock; 142*4882a593Smuzhiyun unsigned long dreq_mask; 143*4882a593Smuzhiyun 144*4882a593Smuzhiyun u32 nr_channels; 145*4882a593Smuzhiyun char fw_name[FW_NAME_SIZE]; 146*4882a593Smuzhiyun }; 147*4882a593Smuzhiyun 148*4882a593Smuzhiyun /* Peripheral Registers*/ 149*4882a593Smuzhiyun 150*4882a593Smuzhiyun #define FDMA_CMD_STA_OFST 0xFC0 151*4882a593Smuzhiyun #define FDMA_CMD_SET_OFST 0xFC4 152*4882a593Smuzhiyun #define FDMA_CMD_CLR_OFST 0xFC8 153*4882a593Smuzhiyun #define FDMA_CMD_MASK_OFST 0xFCC 154*4882a593Smuzhiyun #define FDMA_CMD_START(ch) (0x1 << (ch << 1)) 155*4882a593Smuzhiyun #define FDMA_CMD_PAUSE(ch) (0x2 << (ch << 1)) 156*4882a593Smuzhiyun #define FDMA_CMD_FLUSH(ch) (0x3 << (ch << 1)) 157*4882a593Smuzhiyun 158*4882a593Smuzhiyun #define FDMA_INT_STA_OFST 0xFD0 159*4882a593Smuzhiyun #define FDMA_INT_STA_CH 0x1 160*4882a593Smuzhiyun #define FDMA_INT_STA_ERR 0x2 161*4882a593Smuzhiyun 162*4882a593Smuzhiyun #define FDMA_INT_SET_OFST 0xFD4 163*4882a593Smuzhiyun #define FDMA_INT_CLR_OFST 0xFD8 164*4882a593Smuzhiyun #define FDMA_INT_MASK_OFST 0xFDC 165*4882a593Smuzhiyun 166*4882a593Smuzhiyun #define fdma_read(fdev, name) \ 167*4882a593Smuzhiyun readl((fdev)->slim_rproc->peri + name) 168*4882a593Smuzhiyun 169*4882a593Smuzhiyun #define fdma_write(fdev, val, name) \ 170*4882a593Smuzhiyun writel((val), (fdev)->slim_rproc->peri + name) 171*4882a593Smuzhiyun 172*4882a593Smuzhiyun /* fchan interface (dmem) */ 173*4882a593Smuzhiyun #define FDMA_CH_CMD_OFST 0x200 174*4882a593Smuzhiyun #define FDMA_CH_CMD_STA_MASK GENMASK(1, 0) 175*4882a593Smuzhiyun #define FDMA_CH_CMD_STA_IDLE (0x0) 176*4882a593Smuzhiyun #define FDMA_CH_CMD_STA_START (0x1) 177*4882a593Smuzhiyun #define FDMA_CH_CMD_STA_RUNNING (0x2) 178*4882a593Smuzhiyun #define FDMA_CH_CMD_STA_PAUSED (0x3) 179*4882a593Smuzhiyun #define FDMA_CH_CMD_ERR_MASK GENMASK(4, 2) 180*4882a593Smuzhiyun #define FDMA_CH_CMD_ERR_INT (0x0 << 2) 181*4882a593Smuzhiyun #define FDMA_CH_CMD_ERR_NAND (0x1 << 2) 182*4882a593Smuzhiyun #define FDMA_CH_CMD_ERR_MCHI (0x2 << 2) 183*4882a593Smuzhiyun #define FDMA_CH_CMD_DATA_MASK GENMASK(31, 5) 184*4882a593Smuzhiyun #define fchan_read(fchan, name) \ 185*4882a593Smuzhiyun readl((fchan)->fdev->slim_rproc->mem[ST_SLIM_DMEM].cpu_addr \ 186*4882a593Smuzhiyun + (fchan)->vchan.chan.chan_id * 0x4 \ 187*4882a593Smuzhiyun + name) 188*4882a593Smuzhiyun 189*4882a593Smuzhiyun #define fchan_write(fchan, val, name) \ 190*4882a593Smuzhiyun writel((val), (fchan)->fdev->slim_rproc->mem[ST_SLIM_DMEM].cpu_addr \ 191*4882a593Smuzhiyun + (fchan)->vchan.chan.chan_id * 0x4 \ 192*4882a593Smuzhiyun + name) 193*4882a593Smuzhiyun 194*4882a593Smuzhiyun /* req interface */ 195*4882a593Smuzhiyun #define FDMA_REQ_CTRL_OFST 0x240 196*4882a593Smuzhiyun #define dreq_write(fchan, val, name) \ 197*4882a593Smuzhiyun writel((val), (fchan)->fdev->slim_rproc->mem[ST_SLIM_DMEM].cpu_addr \ 198*4882a593Smuzhiyun + fchan->dreq_line * 0x04 \ 199*4882a593Smuzhiyun + name) 200*4882a593Smuzhiyun /* node interface */ 201*4882a593Smuzhiyun #define FDMA_NODE_SZ 128 202*4882a593Smuzhiyun #define FDMA_PTRN_OFST 0x800 203*4882a593Smuzhiyun #define FDMA_CNTN_OFST 0x808 204*4882a593Smuzhiyun #define FDMA_SADDRN_OFST 0x80c 205*4882a593Smuzhiyun #define FDMA_DADDRN_OFST 0x810 206*4882a593Smuzhiyun #define fnode_read(fchan, name) \ 207*4882a593Smuzhiyun readl((fchan)->fdev->slim_rproc->mem[ST_SLIM_DMEM].cpu_addr \ 208*4882a593Smuzhiyun + (fchan)->vchan.chan.chan_id * FDMA_NODE_SZ \ 209*4882a593Smuzhiyun + name) 210*4882a593Smuzhiyun 211*4882a593Smuzhiyun #define fnode_write(fchan, val, name) \ 212*4882a593Smuzhiyun writel((val), (fchan)->fdev->slim_rproc->mem[ST_SLIM_DMEM].cpu_addr \ 213*4882a593Smuzhiyun + (fchan)->vchan.chan.chan_id * FDMA_NODE_SZ \ 214*4882a593Smuzhiyun + name) 215*4882a593Smuzhiyun 216*4882a593Smuzhiyun /* 217*4882a593Smuzhiyun * request control bits 218*4882a593Smuzhiyun */ 219*4882a593Smuzhiyun #define FDMA_REQ_CTRL_NUM_OPS_MASK GENMASK(31, 24) 220*4882a593Smuzhiyun #define FDMA_REQ_CTRL_NUM_OPS(n) (FDMA_REQ_CTRL_NUM_OPS_MASK & \ 221*4882a593Smuzhiyun ((n) << 24)) 222*4882a593Smuzhiyun #define FDMA_REQ_CTRL_INITIATOR_MASK BIT(22) 223*4882a593Smuzhiyun #define FDMA_REQ_CTRL_INIT0 (0x0 << 22) 224*4882a593Smuzhiyun #define FDMA_REQ_CTRL_INIT1 (0x1 << 22) 225*4882a593Smuzhiyun #define FDMA_REQ_CTRL_INC_ADDR_ON BIT(21) 226*4882a593Smuzhiyun #define FDMA_REQ_CTRL_DATA_SWAP_ON BIT(17) 227*4882a593Smuzhiyun #define FDMA_REQ_CTRL_WNR BIT(14) 228*4882a593Smuzhiyun #define FDMA_REQ_CTRL_OPCODE_MASK GENMASK(7, 4) 229*4882a593Smuzhiyun #define FDMA_REQ_CTRL_OPCODE_LD_ST1 (0x0 << 4) 230*4882a593Smuzhiyun #define FDMA_REQ_CTRL_OPCODE_LD_ST2 (0x1 << 4) 231*4882a593Smuzhiyun #define FDMA_REQ_CTRL_OPCODE_LD_ST4 (0x2 << 4) 232*4882a593Smuzhiyun #define FDMA_REQ_CTRL_OPCODE_LD_ST8 (0x3 << 4) 233*4882a593Smuzhiyun #define FDMA_REQ_CTRL_OPCODE_LD_ST16 (0x4 << 4) 234*4882a593Smuzhiyun #define FDMA_REQ_CTRL_OPCODE_LD_ST32 (0x5 << 4) 235*4882a593Smuzhiyun #define FDMA_REQ_CTRL_OPCODE_LD_ST64 (0x6 << 4) 236*4882a593Smuzhiyun #define FDMA_REQ_CTRL_HOLDOFF_MASK GENMASK(2, 0) 237*4882a593Smuzhiyun #define FDMA_REQ_CTRL_HOLDOFF(n) ((n) & FDMA_REQ_CTRL_HOLDOFF_MASK) 238*4882a593Smuzhiyun 239*4882a593Smuzhiyun /* bits used by client to configure request control */ 240*4882a593Smuzhiyun #define FDMA_REQ_CTRL_CFG_MASK (FDMA_REQ_CTRL_HOLDOFF_MASK | \ 241*4882a593Smuzhiyun FDMA_REQ_CTRL_DATA_SWAP_ON | \ 242*4882a593Smuzhiyun FDMA_REQ_CTRL_INC_ADDR_ON | \ 243*4882a593Smuzhiyun FDMA_REQ_CTRL_INITIATOR_MASK) 244*4882a593Smuzhiyun 245*4882a593Smuzhiyun #endif /* __DMA_ST_FDMA_H */ 246