1 #ifndef __NVKM_RUNL_H__
2 #define __NVKM_RUNL_H__
3 #include <core/intr.h>
4 struct nvkm_cctx;
5 struct nvkm_cgrp;
6 struct nvkm_chan;
7 struct nvkm_memory;
8 struct nvkm_object;
9 struct nvkm_vctx;
10 enum nvkm_subdev_type;
11 
12 struct nvkm_engn {
13 	const struct nvkm_engn_func {
14 		int (*nonstall)(struct nvkm_engn *);
15 		bool (*chsw)(struct nvkm_engn *);
16 		int (*cxid)(struct nvkm_engn *, bool *cgid);
17 		void (*mmu_fault_trigger)(struct nvkm_engn *);
18 		bool (*mmu_fault_triggered)(struct nvkm_engn *);
19 		int (*ctor)(struct nvkm_engn *, struct nvkm_vctx *);
20 		void (*bind)(struct nvkm_engn *, struct nvkm_cctx *, struct nvkm_chan *);
21 		int (*ramht_add)(struct nvkm_engn *, struct nvkm_object *, struct nvkm_chan *);
22 		void (*ramht_del)(struct nvkm_chan *, int hash);
23 	} *func;
24 	struct nvkm_runl *runl;
25 	int id;
26 
27 	struct nvkm_engine *engine;
28 
29 	int fault;
30 
31 	struct list_head head;
32 };
33 
34 #define ENGN_PRINT(e,l,p,f,a...)                                                           \
35 	RUNL_PRINT((e)->runl, l, p, "%02d[%8s]:"f, (e)->id, (e)->engine->subdev.name, ##a)
36 #define ENGN_DEBUG(e,f,a...) ENGN_PRINT((e), DEBUG,   info, " "f"\n", ##a)
37 
38 struct nvkm_runl {
39 	const struct nvkm_runl_func {
40 		void (*init)(struct nvkm_runl *);
41 		void (*fini)(struct nvkm_runl *);
42 		int runqs;
43 		u8 size;
44 		int (*update)(struct nvkm_runl *);
45 		void (*insert_cgrp)(struct nvkm_cgrp *, struct nvkm_memory *, u64 offset);
46 		void (*insert_chan)(struct nvkm_chan *, struct nvkm_memory *, u64 offset);
47 		void (*commit)(struct nvkm_runl *, struct nvkm_memory *, u32 start, int count);
48 		int (*wait)(struct nvkm_runl *);
49 		bool (*pending)(struct nvkm_runl *);
50 		void (*block)(struct nvkm_runl *, u32 engm);
51 		void (*allow)(struct nvkm_runl *, u32 engm);
52 		void (*fault_clear)(struct nvkm_runl *);
53 		void (*preempt)(struct nvkm_runl *);
54 		bool (*preempt_pending)(struct nvkm_runl *);
55 	} *func;
56 	struct nvkm_fifo *fifo;
57 	int id;
58 	u32 addr;
59 	u32 chan;
60 	u16 doorbell;
61 
62 	struct nvkm_chid *cgid;
63 #define NVKM_CHAN_EVENT_ERRORED BIT(0)
64 	struct nvkm_chid *chid;
65 
66 	struct list_head engns;
67 
68 	struct nvkm_runq *runq[2];
69 	int runq_nr;
70 
71 	struct nvkm_inth inth;
72 
73 	struct {
74 		int vector;
75 		struct nvkm_inth inth;
76 	} nonstall;
77 
78 	struct list_head cgrps;
79 	int cgrp_nr;
80 	int chan_nr;
81 	atomic_t changed;
82 	struct nvkm_memory *mem;
83 	u32 offset;
84 	struct mutex mutex;
85 
86 	int blocked;
87 
88 	struct work_struct work;
89 	atomic_t rc_triggered;
90 	atomic_t rc_pending;
91 
92 	struct list_head head;
93 };
94 
95 struct nvkm_runl *nvkm_runl_new(struct nvkm_fifo *, int runi, u32 addr, int id_nr);
96 struct nvkm_runl *nvkm_runl_get(struct nvkm_fifo *, int runi, u32 addr);
97 struct nvkm_engn *nvkm_runl_add(struct nvkm_runl *, int engi, const struct nvkm_engn_func *,
98 				enum nvkm_subdev_type, int inst);
99 void nvkm_runl_del(struct nvkm_runl *);
100 void nvkm_runl_fini(struct nvkm_runl *);
101 void nvkm_runl_block(struct nvkm_runl *);
102 void nvkm_runl_allow(struct nvkm_runl *);
103 void nvkm_runl_update_locked(struct nvkm_runl *, bool wait);
104 bool nvkm_runl_update_pending(struct nvkm_runl *);
105 int nvkm_runl_preempt_wait(struct nvkm_runl *);
106 
107 void nvkm_runl_rc_engn(struct nvkm_runl *, struct nvkm_engn *);
108 void nvkm_runl_rc_cgrp(struct nvkm_cgrp *);
109 
110 struct nvkm_cgrp *nvkm_runl_cgrp_get_cgid(struct nvkm_runl *, int cgid, unsigned long *irqflags);
111 struct nvkm_chan *nvkm_runl_chan_get_chid(struct nvkm_runl *, int chid, unsigned long *irqflags);
112 struct nvkm_chan *nvkm_runl_chan_get_inst(struct nvkm_runl *, u64 inst, unsigned long *irqflags);
113 
114 #define nvkm_runl_find_engn(engn,runl,cond) nvkm_list_find(engn, &(runl)->engns, head, (cond))
115 
116 #define nvkm_runl_first(fifo) list_first_entry(&(fifo)->runls, struct nvkm_runl, head)
117 #define nvkm_runl_foreach(runl,fifo) list_for_each_entry((runl), &(fifo)->runls, head)
118 #define nvkm_runl_foreach_cond(runl,fifo,cond) nvkm_list_foreach(runl, &(fifo)->runls, head, (cond))
119 #define nvkm_runl_foreach_engn(engn,runl) list_for_each_entry((engn), &(runl)->engns, head)
120 #define nvkm_runl_foreach_engn_cond(engn,runl,cond) \
121 	nvkm_list_foreach(engn, &(runl)->engns, head, (cond))
122 #define nvkm_runl_foreach_cgrp(cgrp,runl) list_for_each_entry((cgrp), &(runl)->cgrps, head)
123 #define nvkm_runl_foreach_cgrp_safe(cgrp,gtmp,runl) \
124 	list_for_each_entry_safe((cgrp), (gtmp), &(runl)->cgrps, head)
125 
126 #define RUNL_PRINT(r,l,p,f,a...)                                                          \
127 	nvkm_printk__(&(r)->fifo->engine.subdev, NV_DBG_##l, p, "%06x:"f, (r)->addr, ##a)
128 #define RUNL_ERROR(r,f,a...) RUNL_PRINT((r), ERROR,    err, " "f"\n", ##a)
129 #define RUNL_DEBUG(r,f,a...) RUNL_PRINT((r), DEBUG,   info, " "f"\n", ##a)
130 #define RUNL_TRACE(r,f,a...) RUNL_PRINT((r), TRACE,   info, " "f"\n", ##a)
131 #endif
132