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