hc
2023-12-11 6778948f9de86c3cfaf36725a7c87dcff9ba247f
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
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Copyright (C) Rockchip Electronics Co., Ltd.
 *
 * Author: Huang Lee <Putin.li@rock-chips.com>
 */
 
#ifndef __LINUX_RVE_DRV_H_
#define __LINUX_RVE_DRV_H_
 
#include <linux/clk.h>
#include <linux/completion.h>
#include <linux/debugfs.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/dma-buf-cache.h>
#include <linux/dma-mapping.h>
#include <linux/err.h>
#include <linux/fb.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/irq.h>
#include <linux/kernel.h>
#include <linux/kref.h>
#include <linux/miscdevice.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/poll.h>
#include <linux/regulator/consumer.h>
#include <linux/scatterlist.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/syscalls.h>
#include <linux/time.h>
#include <linux/timer.h>
#include <linux/uaccess.h>
#include <linux/version.h>
#include <linux/wait.h>
#include <linux/wakelock.h>
#include <linux/pm_runtime.h>
#include <linux/sched/mm.h>
 
#include <asm/cacheflush.h>
 
#include <linux/iommu.h>
#include <linux/iova.h>
#include <linux/dma-iommu.h>
#include <linux/dma-map-ops.h>
#include <linux/hrtimer.h>
 
#include "rve_debugger.h"
#include "rve.h"
 
/* sample interval: 1000ms */
#define RVE_LOAD_INTERVAL 1000000000
 
/* Driver information */
#define DRIVER_DESC        "RVE Device Driver"
#define DRIVER_NAME        "rve"
 
#define STR_HELPER(x) #x
#define STR(x) STR_HELPER(x)
 
#define RVE_MAJOR_VERSION_MASK        (0x0000FF00)
#define RVE_MINOR_VERSION_MASK        (0x000000FF)
#define RVE_PROD_NUM_MASK                (0xFFFF0000)
 
#define DRIVER_MAJOR_VERSION        1
#define DRIVER_MINOR_VERSION        0
#define DRIVER_REVISION_VERSION        4
 
#define DRIVER_VERSION (STR(DRIVER_MAJOR_VERSION) "." STR(DRIVER_MINOR_VERSION) \
           "." STR(DRIVER_REVISION_VERSION))
 
/* time limit */
#define RVE_ASYNC_TIMEOUT_DELAY        500
#define RVE_SYNC_TIMEOUT_DELAY        HZ
#define RVE_RESET_TIMEOUT            10000
 
#define RVE_BUFFER_POOL_MAX_SIZE    64
#define RVE_MAX_SCHEDULER 1
 
#define RVE_MAX_BUS_CLK 10
#define RVE_MAX_PID_INFO 10
 
extern struct rve_drvdata_t *rve_drvdata;
 
enum {
   RVE_SCHEDULER_CORE0        = 1,
   RVE_NONE_CORE             = 0,
};
 
enum {
   RVE_CMD_SLAVE        = 1,
   RVE_CMD_MASTER        = 2,
};
 
struct rve_fence_context {
   unsigned int context;
   unsigned int seqno;
   spinlock_t spinlock;
};
 
struct rve_fence_waiter {
   /* Base sync driver waiter structure */
   struct dma_fence_cb waiter;
 
   struct rve_job *job;
};
 
struct rve_scheduler_t;
struct rve_internal_ctx_t;
 
struct rve_session {
   int id;
 
   pid_t tgid;
};
 
struct rve_job {
   struct list_head head;
   struct rve_scheduler_t *scheduler;
   struct rve_session *session;
 
   struct rve_cmd_reg_array_t *regcmd_data;
 
   struct rve_internal_ctx_t *ctx;
 
   /* for rve virtual_address */
   struct mm_struct *mm;
 
   struct dma_fence *out_fence;
   struct dma_fence *in_fence;
   spinlock_t fence_lock;
   ktime_t timestamp;
   ktime_t hw_running_time;
   ktime_t hw_recoder_time;
   unsigned int flags;
 
   int priority;
   int core;
   int ret;
   pid_t pid;
};
 
struct rve_backend_ops {
   int (*get_version)(struct rve_scheduler_t *scheduler);
   int (*set_reg)(struct rve_job *job, struct rve_scheduler_t *scheduler);
   int (*init_reg)(struct rve_job *job);
   void (*soft_reset)(struct rve_scheduler_t *scheduler);
};
 
struct rve_timer {
   u32 busy_time;
   u32 busy_time_record;
};
 
struct rve_sche_pid_info_t {
   pid_t pid;
   /* hw total use time, per hrtimer */
   u32 hw_time_total;
 
   uint32_t last_job_rd_bandwidth;
   uint32_t last_job_wr_bandwidth;
   uint32_t last_job_cycle_cnt;
};
 
struct rve_sche_session_info_t {
   struct rve_sche_pid_info_t pid_info[RVE_MAX_PID_INFO];
 
   int pd_refcount;
 
   /* the bandwidth of total read bytes, per hrtimer */
   uint32_t rd_bandwidth;
   /* the bandwidth of total write bytes, per hrtimer */
   uint32_t wr_bandwidth;
   /* the total running cycle of current frame, per hrtimer */
   uint32_t cycle_cnt;
   /* total interrupt count */
   uint64_t total_int_cnt;
};
 
struct rve_scheduler_t {
   struct device *dev;
   void __iomem *rve_base;
 
   struct clk *clks[RVE_MAX_BUS_CLK];
   int num_clks;
 
   struct rve_job *running_job;
   struct list_head todo_list;
   spinlock_t irq_lock;
   wait_queue_head_t job_done_wq;
   const struct rve_backend_ops *ops;
   const struct rve_hw_data *data;
   int job_count;
   int irq;
   struct rve_version_t version;
   int core;
 
   struct rve_timer timer;
 
   struct rve_sche_session_info_t session;
};
 
struct rve_cmd_reg_array_t {
   uint32_t cmd_reg[58];
};
 
struct rve_ctx_debug_info_t {
   pid_t pid;
   u32 timestamp;
   /* hw total use time, per hrtimer */
   u32 hw_time_total;
   /* last job use time, per hrtimer*/
   u32 last_job_use_time;
   /* last job hardware use time, per hrtimer*/
   u32 last_job_hw_use_time;
   /* the most time-consuming job, per hrtimer */
   u32 max_cost_time_per_sec;
};
 
struct rve_internal_ctx_t {
   struct rve_scheduler_t *scheduler;
   struct rve_session *session;
 
   struct rve_cmd_reg_array_t *regcmd_data;
   uint32_t cmd_num;
 
   uint32_t sync_mode;
   int flags;
   int id;
 
   uint32_t running_job_count;
   uint32_t finished_job_count;
   bool is_running;
 
   uint32_t disable_auto_cancel;
 
   int priority;
   int32_t out_fence_fd;
   int32_t in_fence_fd;
 
   struct dma_fence *out_fence;
 
   spinlock_t lock;
   struct kref refcount;
 
   /* debug info */
   struct rve_ctx_debug_info_t debug_info;
 
   /* TODO: add some common work */
};
 
struct rve_pending_ctx_manager {
   spinlock_t lock;
 
   /*
    * @ctx_id_idr:
    *
    * Mapping of ctx id to object pointers. Used by the GEM
    * subsystem. Protected by @lock.
    */
   struct idr ctx_id_idr;
 
   int ctx_count;
};
 
struct rve_session_manager {
   struct mutex lock;
 
   struct idr ctx_id_idr;
 
   int session_cnt;
};
 
struct rve_drvdata_t {
   struct rve_fence_context *fence_ctx;
 
   /* used by rve2's mmu lock */
   struct mutex lock;
 
   struct rve_scheduler_t *scheduler[RVE_MAX_SCHEDULER];
   int num_of_scheduler;
 
   struct delayed_work power_off_work;
   struct wake_lock wake_lock;
 
   struct rve_mm *mm;
 
   /* rve_job pending manager, import by RVE_IOC_START_CONFIG */
   struct rve_pending_ctx_manager *pend_ctx_manager;
 
   struct rve_session_manager *session_manager;
 
#ifdef CONFIG_ROCKCHIP_RVE_DEBUGGER
   struct rve_debugger *debugger;
#endif
};
 
struct rve_irqs_data_t {
   const char *name;
   irqreturn_t (*irq_hdl)(int irq, void *ctx);
   irqreturn_t (*irq_thread)(int irq, void *ctx);
};
 
struct rve_match_data_t {
   const char * const *clks;
   int num_clks;
   const struct rve_irqs_data_t *irqs;
   int num_irqs;
};
 
static inline int rve_read(int offset, struct rve_scheduler_t *scheduler)
{
   return readl(scheduler->rve_base + offset);
}
 
static inline void rve_write(int value, int offset, struct rve_scheduler_t *scheduler)
{
   writel(value, scheduler->rve_base + offset);
}
 
int rve_power_enable(struct rve_scheduler_t *scheduler);
int rve_power_disable(struct rve_scheduler_t *scheduler);
 
#endif /* __LINUX_RVE_FENCE_H_ */