12874c5fdSThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-or-later */ 2812ab065SPeter Griffin /* 3812ab065SPeter Griffin * DMA driver header for STMicroelectronics STi FDMA controller 4812ab065SPeter Griffin * 5812ab065SPeter Griffin * Copyright (C) 2014 STMicroelectronics 6812ab065SPeter Griffin * 7812ab065SPeter Griffin * Author: Ludovic Barre <Ludovic.barre@st.com> 8812ab065SPeter Griffin */ 9812ab065SPeter Griffin #ifndef __DMA_ST_FDMA_H 10812ab065SPeter Griffin #define __DMA_ST_FDMA_H 11812ab065SPeter Griffin 12812ab065SPeter Griffin #include <linux/dmaengine.h> 13812ab065SPeter Griffin #include <linux/dmapool.h> 14812ab065SPeter Griffin #include <linux/io.h> 15812ab065SPeter Griffin #include <linux/remoteproc/st_slim_rproc.h> 16812ab065SPeter Griffin #include "virt-dma.h" 17812ab065SPeter Griffin 18812ab065SPeter Griffin #define ST_FDMA_NR_DREQS 32 19812ab065SPeter Griffin #define FW_NAME_SIZE 30 20812ab065SPeter Griffin #define DRIVER_NAME "st-fdma" 21812ab065SPeter Griffin 22812ab065SPeter Griffin /** 23812ab065SPeter Griffin * struct st_fdma_generic_node - Free running/paced generic node 24812ab065SPeter Griffin * 25812ab065SPeter Griffin * @length: Length in bytes of a line in a 2D mem to mem 26812ab065SPeter Griffin * @sstride: Stride, in bytes, between source lines in a 2D data move 27812ab065SPeter Griffin * @dstride: Stride, in bytes, between destination lines in a 2D data move 28812ab065SPeter Griffin */ 29812ab065SPeter Griffin struct st_fdma_generic_node { 30812ab065SPeter Griffin u32 length; 31812ab065SPeter Griffin u32 sstride; 32812ab065SPeter Griffin u32 dstride; 33812ab065SPeter Griffin }; 34812ab065SPeter Griffin 35812ab065SPeter Griffin /** 36812ab065SPeter Griffin * struct st_fdma_hw_node - Node structure used by fdma hw 37812ab065SPeter Griffin * 38812ab065SPeter Griffin * @next: Pointer to next node 39812ab065SPeter Griffin * @control: Transfer Control Parameters 40812ab065SPeter Griffin * @nbytes: Number of Bytes to read 41812ab065SPeter Griffin * @saddr: Source address 42812ab065SPeter Griffin * @daddr: Destination address 43812ab065SPeter Griffin * 44812ab065SPeter Griffin * @generic: generic node for free running/paced transfert type 45812ab065SPeter Griffin * 2 others transfert type are possible, but not yet implemented 46812ab065SPeter Griffin * 47812ab065SPeter Griffin * The NODE structures must be aligned to a 32 byte boundary 48812ab065SPeter Griffin */ 49812ab065SPeter Griffin struct st_fdma_hw_node { 50812ab065SPeter Griffin u32 next; 51812ab065SPeter Griffin u32 control; 52812ab065SPeter Griffin u32 nbytes; 53812ab065SPeter Griffin u32 saddr; 54812ab065SPeter Griffin u32 daddr; 55812ab065SPeter Griffin union { 56812ab065SPeter Griffin struct st_fdma_generic_node generic; 57812ab065SPeter Griffin }; 58812ab065SPeter Griffin } __aligned(32); 59812ab065SPeter Griffin 60812ab065SPeter Griffin /* 61812ab065SPeter Griffin * node control parameters 62812ab065SPeter Griffin */ 63812ab065SPeter Griffin #define FDMA_NODE_CTRL_REQ_MAP_MASK GENMASK(4, 0) 64812ab065SPeter Griffin #define FDMA_NODE_CTRL_REQ_MAP_FREE_RUN 0x0 65812ab065SPeter Griffin #define FDMA_NODE_CTRL_REQ_MAP_DREQ(n) ((n)&FDMA_NODE_CTRL_REQ_MAP_MASK) 66812ab065SPeter Griffin #define FDMA_NODE_CTRL_REQ_MAP_EXT FDMA_NODE_CTRL_REQ_MAP_MASK 67812ab065SPeter Griffin #define FDMA_NODE_CTRL_SRC_MASK GENMASK(6, 5) 68812ab065SPeter Griffin #define FDMA_NODE_CTRL_SRC_STATIC BIT(5) 69812ab065SPeter Griffin #define FDMA_NODE_CTRL_SRC_INCR BIT(6) 70812ab065SPeter Griffin #define FDMA_NODE_CTRL_DST_MASK GENMASK(8, 7) 71812ab065SPeter Griffin #define FDMA_NODE_CTRL_DST_STATIC BIT(7) 72812ab065SPeter Griffin #define FDMA_NODE_CTRL_DST_INCR BIT(8) 73812ab065SPeter Griffin #define FDMA_NODE_CTRL_SECURE BIT(15) 74812ab065SPeter Griffin #define FDMA_NODE_CTRL_PAUSE_EON BIT(30) 75812ab065SPeter Griffin #define FDMA_NODE_CTRL_INT_EON BIT(31) 76812ab065SPeter Griffin 77812ab065SPeter Griffin /** 78812ab065SPeter Griffin * struct st_fdma_sw_node - descriptor structure for link list 79812ab065SPeter Griffin * 80812ab065SPeter Griffin * @pdesc: Physical address of desc 81812ab065SPeter Griffin * @node: link used for putting this into a channel queue 82812ab065SPeter Griffin */ 83812ab065SPeter Griffin struct st_fdma_sw_node { 84812ab065SPeter Griffin dma_addr_t pdesc; 85812ab065SPeter Griffin struct st_fdma_hw_node *desc; 86812ab065SPeter Griffin }; 87812ab065SPeter Griffin 88812ab065SPeter Griffin #define NAME_SZ 10 89812ab065SPeter Griffin 90812ab065SPeter Griffin struct st_fdma_driverdata { 91812ab065SPeter Griffin u32 id; 92812ab065SPeter Griffin char name[NAME_SZ]; 93812ab065SPeter Griffin }; 94812ab065SPeter Griffin 95812ab065SPeter Griffin struct st_fdma_desc { 96812ab065SPeter Griffin struct virt_dma_desc vdesc; 97812ab065SPeter Griffin struct st_fdma_chan *fchan; 98812ab065SPeter Griffin bool iscyclic; 99812ab065SPeter Griffin unsigned int n_nodes; 100812ab065SPeter Griffin struct st_fdma_sw_node node[]; 101812ab065SPeter Griffin }; 102812ab065SPeter Griffin 103812ab065SPeter Griffin enum st_fdma_type { 104812ab065SPeter Griffin ST_FDMA_TYPE_FREE_RUN, 105812ab065SPeter Griffin ST_FDMA_TYPE_PACED, 106812ab065SPeter Griffin }; 107812ab065SPeter Griffin 108812ab065SPeter Griffin struct st_fdma_cfg { 109812ab065SPeter Griffin struct device_node *of_node; 110812ab065SPeter Griffin enum st_fdma_type type; 111812ab065SPeter Griffin dma_addr_t dev_addr; 112812ab065SPeter Griffin enum dma_transfer_direction dir; 113812ab065SPeter Griffin int req_line; /* request line */ 114812ab065SPeter Griffin long req_ctrl; /* Request control */ 115812ab065SPeter Griffin }; 116812ab065SPeter Griffin 117812ab065SPeter Griffin struct st_fdma_chan { 118812ab065SPeter Griffin struct st_fdma_dev *fdev; 119812ab065SPeter Griffin struct dma_pool *node_pool; 120812ab065SPeter Griffin struct dma_slave_config scfg; 121812ab065SPeter Griffin struct st_fdma_cfg cfg; 122812ab065SPeter Griffin 123812ab065SPeter Griffin int dreq_line; 124812ab065SPeter Griffin 125812ab065SPeter Griffin struct virt_dma_chan vchan; 126812ab065SPeter Griffin struct st_fdma_desc *fdesc; 127812ab065SPeter Griffin enum dma_status status; 128812ab065SPeter Griffin }; 129812ab065SPeter Griffin 130812ab065SPeter Griffin struct st_fdma_dev { 131812ab065SPeter Griffin struct device *dev; 132812ab065SPeter Griffin const struct st_fdma_driverdata *drvdata; 133812ab065SPeter Griffin struct dma_device dma_device; 134812ab065SPeter Griffin 135812ab065SPeter Griffin struct st_slim_rproc *slim_rproc; 136812ab065SPeter Griffin 137812ab065SPeter Griffin int irq; 138812ab065SPeter Griffin 139812ab065SPeter Griffin struct st_fdma_chan *chans; 140812ab065SPeter Griffin 141812ab065SPeter Griffin spinlock_t dreq_lock; 142812ab065SPeter Griffin unsigned long dreq_mask; 143812ab065SPeter Griffin 144812ab065SPeter Griffin u32 nr_channels; 145812ab065SPeter Griffin char fw_name[FW_NAME_SIZE]; 146812ab065SPeter Griffin }; 147812ab065SPeter Griffin 148812ab065SPeter Griffin /* Peripheral Registers*/ 149812ab065SPeter Griffin 150812ab065SPeter Griffin #define FDMA_CMD_STA_OFST 0xFC0 151812ab065SPeter Griffin #define FDMA_CMD_SET_OFST 0xFC4 152812ab065SPeter Griffin #define FDMA_CMD_CLR_OFST 0xFC8 153812ab065SPeter Griffin #define FDMA_CMD_MASK_OFST 0xFCC 154812ab065SPeter Griffin #define FDMA_CMD_START(ch) (0x1 << (ch << 1)) 155812ab065SPeter Griffin #define FDMA_CMD_PAUSE(ch) (0x2 << (ch << 1)) 156812ab065SPeter Griffin #define FDMA_CMD_FLUSH(ch) (0x3 << (ch << 1)) 157812ab065SPeter Griffin 158812ab065SPeter Griffin #define FDMA_INT_STA_OFST 0xFD0 159812ab065SPeter Griffin #define FDMA_INT_STA_CH 0x1 160812ab065SPeter Griffin #define FDMA_INT_STA_ERR 0x2 161812ab065SPeter Griffin 162812ab065SPeter Griffin #define FDMA_INT_SET_OFST 0xFD4 163812ab065SPeter Griffin #define FDMA_INT_CLR_OFST 0xFD8 164812ab065SPeter Griffin #define FDMA_INT_MASK_OFST 0xFDC 165812ab065SPeter Griffin 166812ab065SPeter Griffin #define fdma_read(fdev, name) \ 167812ab065SPeter Griffin readl((fdev)->slim_rproc->peri + name) 168812ab065SPeter Griffin 169812ab065SPeter Griffin #define fdma_write(fdev, val, name) \ 170812ab065SPeter Griffin writel((val), (fdev)->slim_rproc->peri + name) 171812ab065SPeter Griffin 172812ab065SPeter Griffin /* fchan interface (dmem) */ 173812ab065SPeter Griffin #define FDMA_CH_CMD_OFST 0x200 174812ab065SPeter Griffin #define FDMA_CH_CMD_STA_MASK GENMASK(1, 0) 175812ab065SPeter Griffin #define FDMA_CH_CMD_STA_IDLE (0x0) 176812ab065SPeter Griffin #define FDMA_CH_CMD_STA_START (0x1) 177812ab065SPeter Griffin #define FDMA_CH_CMD_STA_RUNNING (0x2) 178812ab065SPeter Griffin #define FDMA_CH_CMD_STA_PAUSED (0x3) 179812ab065SPeter Griffin #define FDMA_CH_CMD_ERR_MASK GENMASK(4, 2) 180812ab065SPeter Griffin #define FDMA_CH_CMD_ERR_INT (0x0 << 2) 181812ab065SPeter Griffin #define FDMA_CH_CMD_ERR_NAND (0x1 << 2) 182812ab065SPeter Griffin #define FDMA_CH_CMD_ERR_MCHI (0x2 << 2) 183812ab065SPeter Griffin #define FDMA_CH_CMD_DATA_MASK GENMASK(31, 5) 184812ab065SPeter Griffin #define fchan_read(fchan, name) \ 185812ab065SPeter Griffin readl((fchan)->fdev->slim_rproc->mem[ST_SLIM_DMEM].cpu_addr \ 186812ab065SPeter Griffin + (fchan)->vchan.chan.chan_id * 0x4 \ 187812ab065SPeter Griffin + name) 188812ab065SPeter Griffin 189812ab065SPeter Griffin #define fchan_write(fchan, val, name) \ 190812ab065SPeter Griffin writel((val), (fchan)->fdev->slim_rproc->mem[ST_SLIM_DMEM].cpu_addr \ 191812ab065SPeter Griffin + (fchan)->vchan.chan.chan_id * 0x4 \ 192812ab065SPeter Griffin + name) 193812ab065SPeter Griffin 194812ab065SPeter Griffin /* req interface */ 195812ab065SPeter Griffin #define FDMA_REQ_CTRL_OFST 0x240 196812ab065SPeter Griffin #define dreq_write(fchan, val, name) \ 197812ab065SPeter Griffin writel((val), (fchan)->fdev->slim_rproc->mem[ST_SLIM_DMEM].cpu_addr \ 198812ab065SPeter Griffin + fchan->dreq_line * 0x04 \ 199812ab065SPeter Griffin + name) 200812ab065SPeter Griffin /* node interface */ 201812ab065SPeter Griffin #define FDMA_NODE_SZ 128 202812ab065SPeter Griffin #define FDMA_PTRN_OFST 0x800 203812ab065SPeter Griffin #define FDMA_CNTN_OFST 0x808 204812ab065SPeter Griffin #define FDMA_SADDRN_OFST 0x80c 205812ab065SPeter Griffin #define FDMA_DADDRN_OFST 0x810 206812ab065SPeter Griffin #define fnode_read(fchan, name) \ 207812ab065SPeter Griffin readl((fchan)->fdev->slim_rproc->mem[ST_SLIM_DMEM].cpu_addr \ 208812ab065SPeter Griffin + (fchan)->vchan.chan.chan_id * FDMA_NODE_SZ \ 209812ab065SPeter Griffin + name) 210812ab065SPeter Griffin 211812ab065SPeter Griffin #define fnode_write(fchan, val, name) \ 212812ab065SPeter Griffin writel((val), (fchan)->fdev->slim_rproc->mem[ST_SLIM_DMEM].cpu_addr \ 213812ab065SPeter Griffin + (fchan)->vchan.chan.chan_id * FDMA_NODE_SZ \ 214812ab065SPeter Griffin + name) 215812ab065SPeter Griffin 216812ab065SPeter Griffin /* 217812ab065SPeter Griffin * request control bits 218812ab065SPeter Griffin */ 219812ab065SPeter Griffin #define FDMA_REQ_CTRL_NUM_OPS_MASK GENMASK(31, 24) 220812ab065SPeter Griffin #define FDMA_REQ_CTRL_NUM_OPS(n) (FDMA_REQ_CTRL_NUM_OPS_MASK & \ 221812ab065SPeter Griffin ((n) << 24)) 222812ab065SPeter Griffin #define FDMA_REQ_CTRL_INITIATOR_MASK BIT(22) 223812ab065SPeter Griffin #define FDMA_REQ_CTRL_INIT0 (0x0 << 22) 224812ab065SPeter Griffin #define FDMA_REQ_CTRL_INIT1 (0x1 << 22) 225812ab065SPeter Griffin #define FDMA_REQ_CTRL_INC_ADDR_ON BIT(21) 226812ab065SPeter Griffin #define FDMA_REQ_CTRL_DATA_SWAP_ON BIT(17) 227812ab065SPeter Griffin #define FDMA_REQ_CTRL_WNR BIT(14) 228812ab065SPeter Griffin #define FDMA_REQ_CTRL_OPCODE_MASK GENMASK(7, 4) 229812ab065SPeter Griffin #define FDMA_REQ_CTRL_OPCODE_LD_ST1 (0x0 << 4) 230812ab065SPeter Griffin #define FDMA_REQ_CTRL_OPCODE_LD_ST2 (0x1 << 4) 231812ab065SPeter Griffin #define FDMA_REQ_CTRL_OPCODE_LD_ST4 (0x2 << 4) 232812ab065SPeter Griffin #define FDMA_REQ_CTRL_OPCODE_LD_ST8 (0x3 << 4) 233812ab065SPeter Griffin #define FDMA_REQ_CTRL_OPCODE_LD_ST16 (0x4 << 4) 234812ab065SPeter Griffin #define FDMA_REQ_CTRL_OPCODE_LD_ST32 (0x5 << 4) 235812ab065SPeter Griffin #define FDMA_REQ_CTRL_OPCODE_LD_ST64 (0x6 << 4) 236812ab065SPeter Griffin #define FDMA_REQ_CTRL_HOLDOFF_MASK GENMASK(2, 0) 237812ab065SPeter Griffin #define FDMA_REQ_CTRL_HOLDOFF(n) ((n) & FDMA_REQ_CTRL_HOLDOFF_MASK) 238812ab065SPeter Griffin 239812ab065SPeter Griffin /* bits used by client to configure request control */ 240812ab065SPeter Griffin #define FDMA_REQ_CTRL_CFG_MASK (FDMA_REQ_CTRL_HOLDOFF_MASK | \ 241812ab065SPeter Griffin FDMA_REQ_CTRL_DATA_SWAP_ON | \ 242812ab065SPeter Griffin FDMA_REQ_CTRL_INC_ADDR_ON | \ 243812ab065SPeter Griffin FDMA_REQ_CTRL_INITIATOR_MASK) 244812ab065SPeter Griffin 245812ab065SPeter Griffin #endif /* __DMA_ST_FDMA_H */ 246