1b7019ac5SIlia Mirkin /* SPDX-License-Identifier: MIT */
25025407bSBen Skeggs #ifndef __NVKM_SUBDEV_H__
35025407bSBen Skeggs #define __NVKM_SUBDEV_H__
468f3f702SBen Skeggs #include <core/device.h>
5c39f472eSBen Skeggs 
665a279c1SBen Skeggs enum nvkm_subdev_type {
75ef25f06SBen Skeggs #define NVKM_LAYOUT_ONCE(t,s,p,...) t,
85ef25f06SBen Skeggs #define NVKM_LAYOUT_INST NVKM_LAYOUT_ONCE
9be0ed63fSBen Skeggs #include <core/layout.h>
10be0ed63fSBen Skeggs #undef NVKM_LAYOUT_INST
11be0ed63fSBen Skeggs #undef NVKM_LAYOUT_ONCE
1265a279c1SBen Skeggs 	NVKM_SUBDEV_NR
1365a279c1SBen Skeggs };
1465a279c1SBen Skeggs 
155025407bSBen Skeggs struct nvkm_subdev {
16f0290215SBen Skeggs 	const struct nvkm_subdev_func *func;
17d351b856SBen Skeggs 	struct nvkm_device *device;
1865a279c1SBen Skeggs 	enum nvkm_subdev_type type;
1965a279c1SBen Skeggs 	int inst;
208478cd5aSBen Skeggs 
219c28abb7SBen Skeggs 	char name[16];
22c39f472eSBen Skeggs 	u32 debug;
238478cd5aSBen Skeggs 
248478cd5aSBen Skeggs 	struct {
258478cd5aSBen Skeggs 		refcount_t refcount;
268478cd5aSBen Skeggs 		struct mutex mutex;
278478cd5aSBen Skeggs 		bool enabled;
288478cd5aSBen Skeggs 	} use;
29c39f472eSBen Skeggs 
30a7ab200aSBen Skeggs 	struct nvkm_inth inth;
31a7ab200aSBen Skeggs 
328478cd5aSBen Skeggs 	struct list_head head;
33f483253fSBen Skeggs 	void **pself;
3468f3f702SBen Skeggs 	bool oneinit;
35c39f472eSBen Skeggs };
36c39f472eSBen Skeggs 
37f0290215SBen Skeggs struct nvkm_subdev_func {
38f0290215SBen Skeggs 	void *(*dtor)(struct nvkm_subdev *);
39f0290215SBen Skeggs 	int (*preinit)(struct nvkm_subdev *);
40f0290215SBen Skeggs 	int (*oneinit)(struct nvkm_subdev *);
41c5c9127bSBen Skeggs 	int (*info)(struct nvkm_subdev *, u64 mthd, u64 *data);
42f0290215SBen Skeggs 	int (*init)(struct nvkm_subdev *);
43f0290215SBen Skeggs 	int (*fini)(struct nvkm_subdev *, bool suspend);
44f0290215SBen Skeggs 	void (*intr)(struct nvkm_subdev *);
45f0290215SBen Skeggs };
46f0290215SBen Skeggs 
479c28abb7SBen Skeggs extern const char *nvkm_subdev_type[NVKM_SUBDEV_NR];
48c5f38d67SBen Skeggs int nvkm_subdev_new_(const struct nvkm_subdev_func *, struct nvkm_device *, enum nvkm_subdev_type,
49c5f38d67SBen Skeggs 		     int inst, struct nvkm_subdev **);
508478cd5aSBen Skeggs void __nvkm_subdev_ctor(const struct nvkm_subdev_func *, struct nvkm_device *,
5165a279c1SBen Skeggs 			enum nvkm_subdev_type, int inst, struct nvkm_subdev *);
528478cd5aSBen Skeggs 
538478cd5aSBen Skeggs static inline void
nvkm_subdev_ctor(const struct nvkm_subdev_func * func,struct nvkm_device * device,enum nvkm_subdev_type type,int inst,struct nvkm_subdev * subdev)548478cd5aSBen Skeggs nvkm_subdev_ctor(const struct nvkm_subdev_func *func, struct nvkm_device *device,
558478cd5aSBen Skeggs 		 enum nvkm_subdev_type type, int inst, struct nvkm_subdev *subdev)
568478cd5aSBen Skeggs {
578478cd5aSBen Skeggs 	__nvkm_subdev_ctor(func, device, type, inst, subdev);
588478cd5aSBen Skeggs 	mutex_init(&subdev->use.mutex);
598478cd5aSBen Skeggs }
608478cd5aSBen Skeggs 
61f483253fSBen Skeggs void nvkm_subdev_disable(struct nvkm_device *, enum nvkm_subdev_type, int inst);
62f0290215SBen Skeggs void nvkm_subdev_del(struct nvkm_subdev **);
638478cd5aSBen Skeggs int  nvkm_subdev_ref(struct nvkm_subdev *);
648478cd5aSBen Skeggs void nvkm_subdev_unref(struct nvkm_subdev *);
65f0290215SBen Skeggs int  nvkm_subdev_preinit(struct nvkm_subdev *);
668478cd5aSBen Skeggs int  nvkm_subdev_oneinit(struct nvkm_subdev *);
67f0290215SBen Skeggs int  nvkm_subdev_init(struct nvkm_subdev *);
68f0290215SBen Skeggs int  nvkm_subdev_fini(struct nvkm_subdev *, bool suspend);
69c5c9127bSBen Skeggs int  nvkm_subdev_info(struct nvkm_subdev *, u64, u64 *);
70f0290215SBen Skeggs void nvkm_subdev_intr(struct nvkm_subdev *);
71f0290215SBen Skeggs 
726594363bSBen Skeggs /* subdev logging */
73*e442f1e4SBen Skeggs #define nvkm_printk_ok(s,u,l)                                                                \
74*e442f1e4SBen Skeggs 	((CONFIG_NOUVEAU_DEBUG >= (l)) && ((s)->debug >= (l) || ((u) && (u)->debug >= (l))))
75*e442f1e4SBen Skeggs #define nvkm_printk___(s,u,l,p,f,a...) do {                                                  \
76*e442f1e4SBen Skeggs 	if (nvkm_printk_ok((s), (u), (l))) {                                                 \
77*e442f1e4SBen Skeggs 		if ((u) && (u) != (s))                                                       \
78*e442f1e4SBen Skeggs 			dev_##p((s)->device->dev, "%s(%s):"f, (s)->name, (u)->name, ##a);    \
79*e442f1e4SBen Skeggs 		else                                                                         \
80*e442f1e4SBen Skeggs 			dev_##p((s)->device->dev, "%s:"f, (s)->name, ##a);                   \
81*e442f1e4SBen Skeggs 	}                                                                                    \
82c39f472eSBen Skeggs } while(0)
83*e442f1e4SBen Skeggs #define nvkm_printk__(s,l,p,f,a...) nvkm_printk___((s), (s), (l), p, f, ##a)
84*e442f1e4SBen Skeggs #define nvkm_printk_(s,l,p,f,a...) nvkm_printk__((s), (l), p, " "f, ##a)
856594363bSBen Skeggs #define nvkm_printk(s,l,p,f,a...) nvkm_printk_((s), NV_DBG_##l, p, f, ##a)
866594363bSBen Skeggs #define nvkm_fatal(s,f,a...) nvkm_printk((s), FATAL,   crit, f, ##a)
876594363bSBen Skeggs #define nvkm_error(s,f,a...) nvkm_printk((s), ERROR,    err, f, ##a)
886594363bSBen Skeggs #define nvkm_warn(s,f,a...)  nvkm_printk((s),  WARN, notice, f, ##a)
896594363bSBen Skeggs #define nvkm_info(s,f,a...)  nvkm_printk((s),  INFO,   info, f, ##a)
906594363bSBen Skeggs #define nvkm_debug(s,f,a...) nvkm_printk((s), DEBUG,   info, f, ##a)
916594363bSBen Skeggs #define nvkm_trace(s,f,a...) nvkm_printk((s), TRACE,   info, f, ##a)
926594363bSBen Skeggs #define nvkm_spam(s,f,a...)  nvkm_printk((s),  SPAM,    dbg, f, ##a)
939887bda0SLyude Paul 
949887bda0SLyude Paul #define nvkm_error_ratelimited(s,f,a...) nvkm_printk((s), ERROR, err_ratelimited, f, ##a)
95c39f472eSBen Skeggs #endif
96