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