1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0 */ 2*4882a593Smuzhiyun /* 3*4882a593Smuzhiyun * Copyright (C) 2018 Rockchip Electronics Co., Ltd. 4*4882a593Smuzhiyun */ 5*4882a593Smuzhiyun #ifndef __SOC_ROCKCHIP_PCIE_DMA_TRX_H 6*4882a593Smuzhiyun #define __SOC_ROCKCHIP_PCIE_DMA_TRX_H 7*4882a593Smuzhiyun 8*4882a593Smuzhiyun #include <linux/debugfs.h> 9*4882a593Smuzhiyun 10*4882a593Smuzhiyun #define PCIE_DMA_TABLE_NUM 32 11*4882a593Smuzhiyun 12*4882a593Smuzhiyun #define PCIE_DMA_TRX_TYPE_NUM 3 13*4882a593Smuzhiyun 14*4882a593Smuzhiyun #define PCIE_DMA_CHN0 0x0 15*4882a593Smuzhiyun #define PCIE_DMA_CHN1 0x1 16*4882a593Smuzhiyun #define PCIE_DMA_DEFAULT_CHN PCIE_DMA_CHN0 17*4882a593Smuzhiyun 18*4882a593Smuzhiyun #define PCIE_DMA_DATA_SND_TABLE_OFFSET 0x0 19*4882a593Smuzhiyun #define PCIE_DMA_DATA_RCV_ACK_TABLE_OFFSET 0x8 20*4882a593Smuzhiyun #define PCIE_DMA_DATA_FREE_ACK_TABLE_OFFSET 0x10 21*4882a593Smuzhiyun #define PCIE_DMA_DATA_READ_REMOTE_TABLE_OFFSET 0x18 22*4882a593Smuzhiyun 23*4882a593Smuzhiyun enum dma_dir { 24*4882a593Smuzhiyun DMA_FROM_BUS, 25*4882a593Smuzhiyun DMA_TO_BUS, 26*4882a593Smuzhiyun }; 27*4882a593Smuzhiyun 28*4882a593Smuzhiyun /** 29*4882a593Smuzhiyun * The Channel Control Register for read and write. 30*4882a593Smuzhiyun */ 31*4882a593Smuzhiyun union chan_ctrl_lo { 32*4882a593Smuzhiyun struct { 33*4882a593Smuzhiyun u32 cb :1; // 0 34*4882a593Smuzhiyun u32 tcb :1; // 1 35*4882a593Smuzhiyun u32 llp :1; // 2 36*4882a593Smuzhiyun u32 lie :1; // 3 37*4882a593Smuzhiyun u32 rie :1; // 4 38*4882a593Smuzhiyun u32 cs :2; // 5:6 39*4882a593Smuzhiyun u32 rsvd1 :1; // 7 40*4882a593Smuzhiyun u32 ccs :1; // 8 41*4882a593Smuzhiyun u32 llen :1; // 9 42*4882a593Smuzhiyun u32 b_64s :1; // 10 43*4882a593Smuzhiyun u32 b_64d :1; // 11 44*4882a593Smuzhiyun u32 pf :5; // 12:16 45*4882a593Smuzhiyun u32 rsvd2 :7; // 17:23 46*4882a593Smuzhiyun u32 sn :1; // 24 47*4882a593Smuzhiyun u32 ro :1; // 25 48*4882a593Smuzhiyun u32 td :1; // 26 49*4882a593Smuzhiyun u32 tc :3; // 27:29 50*4882a593Smuzhiyun u32 at :2; // 30:31 51*4882a593Smuzhiyun }; 52*4882a593Smuzhiyun u32 asdword; 53*4882a593Smuzhiyun }; 54*4882a593Smuzhiyun 55*4882a593Smuzhiyun /** 56*4882a593Smuzhiyun * The Channel Control Register high part for read and write. 57*4882a593Smuzhiyun */ 58*4882a593Smuzhiyun union chan_ctrl_hi { 59*4882a593Smuzhiyun struct { 60*4882a593Smuzhiyun u32 vfenb :1; // 0 61*4882a593Smuzhiyun u32 vfunc :8; // 1-8 62*4882a593Smuzhiyun u32 rsvd0 :23; // 9-31 63*4882a593Smuzhiyun }; 64*4882a593Smuzhiyun u32 asdword; 65*4882a593Smuzhiyun }; 66*4882a593Smuzhiyun 67*4882a593Smuzhiyun /** 68*4882a593Smuzhiyun * The Channel Weight Register. 69*4882a593Smuzhiyun */ 70*4882a593Smuzhiyun union weight { 71*4882a593Smuzhiyun struct { 72*4882a593Smuzhiyun u32 weight0 :5; // 0:4 73*4882a593Smuzhiyun u32 weight1 :5; // 5:9 74*4882a593Smuzhiyun u32 weight2 :5; // 10:14 75*4882a593Smuzhiyun u32 weight3 :5; // 15:19 76*4882a593Smuzhiyun u32 rsvd :12; // 20:31 77*4882a593Smuzhiyun }; 78*4882a593Smuzhiyun u32 asdword; 79*4882a593Smuzhiyun }; 80*4882a593Smuzhiyun 81*4882a593Smuzhiyun /** 82*4882a593Smuzhiyun * The Doorbell Register for read and write. 83*4882a593Smuzhiyun */ 84*4882a593Smuzhiyun union db { 85*4882a593Smuzhiyun struct { 86*4882a593Smuzhiyun u32 chnl :3; // 0 87*4882a593Smuzhiyun u32 reserved0 :28; // 3:30 88*4882a593Smuzhiyun u32 stop :1; // 31 89*4882a593Smuzhiyun }; 90*4882a593Smuzhiyun u32 asdword; 91*4882a593Smuzhiyun }; 92*4882a593Smuzhiyun 93*4882a593Smuzhiyun /** 94*4882a593Smuzhiyun * The Context Registers for read and write. 95*4882a593Smuzhiyun */ 96*4882a593Smuzhiyun struct ctx_regs { 97*4882a593Smuzhiyun union chan_ctrl_lo ctrllo; 98*4882a593Smuzhiyun union chan_ctrl_hi ctrlhi; 99*4882a593Smuzhiyun u32 xfersize; 100*4882a593Smuzhiyun u32 sarptrlo; 101*4882a593Smuzhiyun u32 sarptrhi; 102*4882a593Smuzhiyun u32 darptrlo; 103*4882a593Smuzhiyun u32 darptrhi; 104*4882a593Smuzhiyun }; 105*4882a593Smuzhiyun 106*4882a593Smuzhiyun /** 107*4882a593Smuzhiyun * The Enable Register for read and write. 108*4882a593Smuzhiyun */ 109*4882a593Smuzhiyun union enb { 110*4882a593Smuzhiyun struct { 111*4882a593Smuzhiyun u32 enb :1; // 0 112*4882a593Smuzhiyun u32 reserved0 :31; // 1:31 113*4882a593Smuzhiyun }; 114*4882a593Smuzhiyun u32 asdword; 115*4882a593Smuzhiyun }; 116*4882a593Smuzhiyun 117*4882a593Smuzhiyun /** 118*4882a593Smuzhiyun * The Interrupt Status Register for read and write. 119*4882a593Smuzhiyun */ 120*4882a593Smuzhiyun union int_status { 121*4882a593Smuzhiyun struct { 122*4882a593Smuzhiyun u32 donesta :8; 123*4882a593Smuzhiyun u32 rsvd0 :8; 124*4882a593Smuzhiyun u32 abortsta :8; 125*4882a593Smuzhiyun u32 rsvd1 :8; 126*4882a593Smuzhiyun }; 127*4882a593Smuzhiyun u32 asdword; 128*4882a593Smuzhiyun }; 129*4882a593Smuzhiyun 130*4882a593Smuzhiyun /** 131*4882a593Smuzhiyun * The Interrupt Clear Register for read and write. 132*4882a593Smuzhiyun */ 133*4882a593Smuzhiyun union int_clear { 134*4882a593Smuzhiyun struct { 135*4882a593Smuzhiyun u32 doneclr :8; 136*4882a593Smuzhiyun u32 rsvd0 :8; 137*4882a593Smuzhiyun u32 abortclr :8; 138*4882a593Smuzhiyun u32 rsvd1 :8; 139*4882a593Smuzhiyun }; 140*4882a593Smuzhiyun u32 asdword; 141*4882a593Smuzhiyun }; 142*4882a593Smuzhiyun 143*4882a593Smuzhiyun struct dma_table { 144*4882a593Smuzhiyun u32 *descs; 145*4882a593Smuzhiyun int chn; 146*4882a593Smuzhiyun phys_addr_t phys_descs; 147*4882a593Smuzhiyun u32 dir; 148*4882a593Smuzhiyun u32 type; 149*4882a593Smuzhiyun struct list_head tbl_node; 150*4882a593Smuzhiyun union enb enb; 151*4882a593Smuzhiyun struct ctx_regs ctx_reg; 152*4882a593Smuzhiyun union weight weilo; 153*4882a593Smuzhiyun union weight weihi; 154*4882a593Smuzhiyun union db start; 155*4882a593Smuzhiyun phys_addr_t local; 156*4882a593Smuzhiyun phys_addr_t bus; 157*4882a593Smuzhiyun size_t buf_size; 158*4882a593Smuzhiyun }; 159*4882a593Smuzhiyun 160*4882a593Smuzhiyun struct dma_trx_obj { 161*4882a593Smuzhiyun struct device *dev; 162*4882a593Smuzhiyun int loop_count; 163*4882a593Smuzhiyun int loop_count_threshold; 164*4882a593Smuzhiyun void *local_mem_base; 165*4882a593Smuzhiyun phys_addr_t local_mem_start; 166*4882a593Smuzhiyun size_t local_mem_size; 167*4882a593Smuzhiyun phys_addr_t remote_mem_start; 168*4882a593Smuzhiyun void *region_base; 169*4882a593Smuzhiyun phys_addr_t region_start; 170*4882a593Smuzhiyun size_t region_size; 171*4882a593Smuzhiyun int dma_free; 172*4882a593Smuzhiyun unsigned long local_write_available; 173*4882a593Smuzhiyun unsigned long local_read_available; 174*4882a593Smuzhiyun unsigned long remote_write_available; 175*4882a593Smuzhiyun spinlock_t tbl_list_lock; /* lock dma table */ 176*4882a593Smuzhiyun struct list_head tbl_list; 177*4882a593Smuzhiyun struct work_struct dma_trx_work; 178*4882a593Smuzhiyun wait_queue_head_t event_queue; 179*4882a593Smuzhiyun struct workqueue_struct *dma_trx_wq; 180*4882a593Smuzhiyun struct dma_table *table[PCIE_DMA_TABLE_NUM]; 181*4882a593Smuzhiyun struct dma_table *cur; 182*4882a593Smuzhiyun struct hrtimer scan_timer; 183*4882a593Smuzhiyun int busno; 184*4882a593Smuzhiyun void *priv; 185*4882a593Smuzhiyun struct completion done; 186*4882a593Smuzhiyun int ref_count; 187*4882a593Smuzhiyun struct mutex count_mutex; 188*4882a593Smuzhiyun unsigned long irq_num; 189*4882a593Smuzhiyun struct dentry *pcie_root; 190*4882a593Smuzhiyun struct pcie_misc_dev *pcie_dev; 191*4882a593Smuzhiyun void (*start_dma_func)(struct dma_trx_obj *obj, struct dma_table *table); 192*4882a593Smuzhiyun void (*config_dma_func)(struct dma_table *table); 193*4882a593Smuzhiyun int (*get_dma_status)(struct dma_trx_obj *obj, u8 chn, enum dma_dir dir); 194*4882a593Smuzhiyun int (*cb)(struct dma_trx_obj *obj, u32 chn, enum dma_dir dir); 195*4882a593Smuzhiyun ktime_t begin; 196*4882a593Smuzhiyun ktime_t end; 197*4882a593Smuzhiyun u64 cache_time_total; 198*4882a593Smuzhiyun u64 cache_time_avarage; 199*4882a593Smuzhiyun u32 buffer_size; 200*4882a593Smuzhiyun u32 rd_buf_size; 201*4882a593Smuzhiyun u32 wr_buf_size; 202*4882a593Smuzhiyun u32 ack_base; 203*4882a593Smuzhiyun u32 set_data_check_pos; 204*4882a593Smuzhiyun u32 set_local_idx_pos; 205*4882a593Smuzhiyun u32 set_buf_size_pos; 206*4882a593Smuzhiyun u32 set_chk_sum_pos; 207*4882a593Smuzhiyun u32 version; 208*4882a593Smuzhiyun int addr_reverse; 209*4882a593Smuzhiyun }; 210*4882a593Smuzhiyun 211*4882a593Smuzhiyun #if IS_ENABLED(CONFIG_ROCKCHIP_PCIE_DMA_OBJ) 212*4882a593Smuzhiyun struct dma_trx_obj *rk_pcie_dma_obj_probe(struct device *dev); 213*4882a593Smuzhiyun void rk_pcie_dma_obj_remove(struct dma_trx_obj *obj); 214*4882a593Smuzhiyun #else rk_pcie_dma_obj_probe(struct device * dev)215*4882a593Smuzhiyunstatic inline struct dma_trx_obj *rk_pcie_dma_obj_probe(struct device *dev) 216*4882a593Smuzhiyun { 217*4882a593Smuzhiyun return NULL; 218*4882a593Smuzhiyun } 219*4882a593Smuzhiyun rk_pcie_dma_obj_remove(struct dma_trx_obj * obj)220*4882a593Smuzhiyunstatic inline void rk_pcie_dma_obj_remove(struct dma_trx_obj *obj) 221*4882a593Smuzhiyun { 222*4882a593Smuzhiyun } 223*4882a593Smuzhiyun #endif 224*4882a593Smuzhiyun 225*4882a593Smuzhiyun #endif 226