2019-05-27 09:55:01 +03:00
/* SPDX-License-Identifier: GPL-2.0-or-later */
2016-10-18 12:39:10 +03:00
/*
* DMA driver header for STMicroelectronics STi FDMA controller
*
* Copyright ( C ) 2014 STMicroelectronics
*
* Author : Ludovic Barre < Ludovic . barre @ st . com >
*/
# ifndef __DMA_ST_FDMA_H
# define __DMA_ST_FDMA_H
# include <linux/dmaengine.h>
# include <linux/dmapool.h>
# include <linux/io.h>
# include <linux/remoteproc/st_slim_rproc.h>
# include "virt-dma.h"
# define ST_FDMA_NR_DREQS 32
# define FW_NAME_SIZE 30
# define DRIVER_NAME "st-fdma"
/**
* struct st_fdma_generic_node - Free running / paced generic node
*
* @ length : Length in bytes of a line in a 2 D mem to mem
* @ sstride : Stride , in bytes , between source lines in a 2 D data move
* @ dstride : Stride , in bytes , between destination lines in a 2 D data move
*/
struct st_fdma_generic_node {
u32 length ;
u32 sstride ;
u32 dstride ;
} ;
/**
* struct st_fdma_hw_node - Node structure used by fdma hw
*
* @ next : Pointer to next node
* @ control : Transfer Control Parameters
* @ nbytes : Number of Bytes to read
* @ saddr : Source address
* @ daddr : Destination address
*
* @ generic : generic node for free running / paced transfert type
* 2 others transfert type are possible , but not yet implemented
*
* The NODE structures must be aligned to a 32 byte boundary
*/
struct st_fdma_hw_node {
u32 next ;
u32 control ;
u32 nbytes ;
u32 saddr ;
u32 daddr ;
union {
struct st_fdma_generic_node generic ;
} ;
} __aligned ( 32 ) ;
/*
* node control parameters
*/
# define FDMA_NODE_CTRL_REQ_MAP_MASK GENMASK(4, 0)
# define FDMA_NODE_CTRL_REQ_MAP_FREE_RUN 0x0
# define FDMA_NODE_CTRL_REQ_MAP_DREQ(n) ((n)&FDMA_NODE_CTRL_REQ_MAP_MASK)
# define FDMA_NODE_CTRL_REQ_MAP_EXT FDMA_NODE_CTRL_REQ_MAP_MASK
# define FDMA_NODE_CTRL_SRC_MASK GENMASK(6, 5)
# define FDMA_NODE_CTRL_SRC_STATIC BIT(5)
# define FDMA_NODE_CTRL_SRC_INCR BIT(6)
# define FDMA_NODE_CTRL_DST_MASK GENMASK(8, 7)
# define FDMA_NODE_CTRL_DST_STATIC BIT(7)
# define FDMA_NODE_CTRL_DST_INCR BIT(8)
# define FDMA_NODE_CTRL_SECURE BIT(15)
# define FDMA_NODE_CTRL_PAUSE_EON BIT(30)
# define FDMA_NODE_CTRL_INT_EON BIT(31)
/**
* struct st_fdma_sw_node - descriptor structure for link list
*
* @ pdesc : Physical address of desc
* @ node : link used for putting this into a channel queue
*/
struct st_fdma_sw_node {
dma_addr_t pdesc ;
struct st_fdma_hw_node * desc ;
} ;
# define NAME_SZ 10
struct st_fdma_driverdata {
u32 id ;
char name [ NAME_SZ ] ;
} ;
struct st_fdma_desc {
struct virt_dma_desc vdesc ;
struct st_fdma_chan * fchan ;
bool iscyclic ;
unsigned int n_nodes ;
struct st_fdma_sw_node node [ ] ;
} ;
enum st_fdma_type {
ST_FDMA_TYPE_FREE_RUN ,
ST_FDMA_TYPE_PACED ,
} ;
struct st_fdma_cfg {
struct device_node * of_node ;
enum st_fdma_type type ;
dma_addr_t dev_addr ;
enum dma_transfer_direction dir ;
int req_line ; /* request line */
long req_ctrl ; /* Request control */
} ;
struct st_fdma_chan {
struct st_fdma_dev * fdev ;
struct dma_pool * node_pool ;
struct dma_slave_config scfg ;
struct st_fdma_cfg cfg ;
int dreq_line ;
struct virt_dma_chan vchan ;
struct st_fdma_desc * fdesc ;
enum dma_status status ;
} ;
struct st_fdma_dev {
struct device * dev ;
const struct st_fdma_driverdata * drvdata ;
struct dma_device dma_device ;
struct st_slim_rproc * slim_rproc ;
int irq ;
struct st_fdma_chan * chans ;
spinlock_t dreq_lock ;
unsigned long dreq_mask ;
u32 nr_channels ;
char fw_name [ FW_NAME_SIZE ] ;
} ;
/* Peripheral Registers*/
# define FDMA_CMD_STA_OFST 0xFC0
# define FDMA_CMD_SET_OFST 0xFC4
# define FDMA_CMD_CLR_OFST 0xFC8
# define FDMA_CMD_MASK_OFST 0xFCC
# define FDMA_CMD_START(ch) (0x1 << (ch << 1))
# define FDMA_CMD_PAUSE(ch) (0x2 << (ch << 1))
# define FDMA_CMD_FLUSH(ch) (0x3 << (ch << 1))
# define FDMA_INT_STA_OFST 0xFD0
# define FDMA_INT_STA_CH 0x1
# define FDMA_INT_STA_ERR 0x2
# define FDMA_INT_SET_OFST 0xFD4
# define FDMA_INT_CLR_OFST 0xFD8
# define FDMA_INT_MASK_OFST 0xFDC
# define fdma_read(fdev, name) \
readl ( ( fdev ) - > slim_rproc - > peri + name )
# define fdma_write(fdev, val, name) \
writel ( ( val ) , ( fdev ) - > slim_rproc - > peri + name )
/* fchan interface (dmem) */
# define FDMA_CH_CMD_OFST 0x200
# define FDMA_CH_CMD_STA_MASK GENMASK(1, 0)
# define FDMA_CH_CMD_STA_IDLE (0x0)
# define FDMA_CH_CMD_STA_START (0x1)
# define FDMA_CH_CMD_STA_RUNNING (0x2)
# define FDMA_CH_CMD_STA_PAUSED (0x3)
# define FDMA_CH_CMD_ERR_MASK GENMASK(4, 2)
# define FDMA_CH_CMD_ERR_INT (0x0 << 2)
# define FDMA_CH_CMD_ERR_NAND (0x1 << 2)
# define FDMA_CH_CMD_ERR_MCHI (0x2 << 2)
# define FDMA_CH_CMD_DATA_MASK GENMASK(31, 5)
# define fchan_read(fchan, name) \
readl ( ( fchan ) - > fdev - > slim_rproc - > mem [ ST_SLIM_DMEM ] . cpu_addr \
+ ( fchan ) - > vchan . chan . chan_id * 0x4 \
+ name )
# define fchan_write(fchan, val, name) \
writel ( ( val ) , ( fchan ) - > fdev - > slim_rproc - > mem [ ST_SLIM_DMEM ] . cpu_addr \
+ ( fchan ) - > vchan . chan . chan_id * 0x4 \
+ name )
/* req interface */
# define FDMA_REQ_CTRL_OFST 0x240
# define dreq_write(fchan, val, name) \
writel ( ( val ) , ( fchan ) - > fdev - > slim_rproc - > mem [ ST_SLIM_DMEM ] . cpu_addr \
+ fchan - > dreq_line * 0x04 \
+ name )
/* node interface */
# define FDMA_NODE_SZ 128
# define FDMA_PTRN_OFST 0x800
# define FDMA_CNTN_OFST 0x808
# define FDMA_SADDRN_OFST 0x80c
# define FDMA_DADDRN_OFST 0x810
# define fnode_read(fchan, name) \
readl ( ( fchan ) - > fdev - > slim_rproc - > mem [ ST_SLIM_DMEM ] . cpu_addr \
+ ( fchan ) - > vchan . chan . chan_id * FDMA_NODE_SZ \
+ name )
# define fnode_write(fchan, val, name) \
writel ( ( val ) , ( fchan ) - > fdev - > slim_rproc - > mem [ ST_SLIM_DMEM ] . cpu_addr \
+ ( fchan ) - > vchan . chan . chan_id * FDMA_NODE_SZ \
+ name )
/*
* request control bits
*/
# define FDMA_REQ_CTRL_NUM_OPS_MASK GENMASK(31, 24)
# define FDMA_REQ_CTRL_NUM_OPS(n) (FDMA_REQ_CTRL_NUM_OPS_MASK & \
( ( n ) < < 24 ) )
# define FDMA_REQ_CTRL_INITIATOR_MASK BIT(22)
# define FDMA_REQ_CTRL_INIT0 (0x0 << 22)
# define FDMA_REQ_CTRL_INIT1 (0x1 << 22)
# define FDMA_REQ_CTRL_INC_ADDR_ON BIT(21)
# define FDMA_REQ_CTRL_DATA_SWAP_ON BIT(17)
# define FDMA_REQ_CTRL_WNR BIT(14)
# define FDMA_REQ_CTRL_OPCODE_MASK GENMASK(7, 4)
# define FDMA_REQ_CTRL_OPCODE_LD_ST1 (0x0 << 4)
# define FDMA_REQ_CTRL_OPCODE_LD_ST2 (0x1 << 4)
# define FDMA_REQ_CTRL_OPCODE_LD_ST4 (0x2 << 4)
# define FDMA_REQ_CTRL_OPCODE_LD_ST8 (0x3 << 4)
# define FDMA_REQ_CTRL_OPCODE_LD_ST16 (0x4 << 4)
# define FDMA_REQ_CTRL_OPCODE_LD_ST32 (0x5 << 4)
# define FDMA_REQ_CTRL_OPCODE_LD_ST64 (0x6 << 4)
# define FDMA_REQ_CTRL_HOLDOFF_MASK GENMASK(2, 0)
# define FDMA_REQ_CTRL_HOLDOFF(n) ((n) & FDMA_REQ_CTRL_HOLDOFF_MASK)
/* bits used by client to configure request control */
# define FDMA_REQ_CTRL_CFG_MASK (FDMA_REQ_CTRL_HOLDOFF_MASK | \
FDMA_REQ_CTRL_DATA_SWAP_ON | \
FDMA_REQ_CTRL_INC_ADDR_ON | \
FDMA_REQ_CTRL_INITIATOR_MASK )
# endif /* __DMA_ST_FDMA_H */