1/*	$NetBSD: falcon.h,v 1.3 2021/12/18 23:45:33 riastradh Exp $	*/
2
3/* SPDX-License-Identifier: MIT */
4#ifndef __NVKM_FLCNEN_H__
5#define __NVKM_FLCNEN_H__
6#define nvkm_falcon(p) container_of((p), struct nvkm_falcon, engine)
7#include <core/engine.h>
8struct nvkm_fifo_chan;
9struct nvkm_gpuobj;
10
11enum nvkm_falcon_dmaidx {
12	FALCON_DMAIDX_UCODE		= 0,
13	FALCON_DMAIDX_VIRT		= 1,
14	FALCON_DMAIDX_PHYS_VID		= 2,
15	FALCON_DMAIDX_PHYS_SYS_COH	= 3,
16	FALCON_DMAIDX_PHYS_SYS_NCOH	= 4,
17	FALCON_SEC2_DMAIDX_UCODE	= 6,
18};
19
20struct nvkm_falcon {
21	const struct nvkm_falcon_func *func;
22	const struct nvkm_subdev *owner;
23	const char *name;
24	u32 addr;
25
26	struct mutex mutex;
27	struct mutex dmem_mutex;
28	bool oneinit;
29
30	const struct nvkm_subdev *user;
31
32	u8 version;
33	u8 secret;
34	bool debug;
35
36	struct nvkm_memory *core;
37	bool external;
38
39	struct {
40		u32 limit;
41		u32 *data;
42		u32  size;
43		u8 ports;
44	} code;
45
46	struct {
47		u32 limit;
48		u32 *data;
49		u32  size;
50		u8 ports;
51	} data;
52
53	struct nvkm_engine engine;
54};
55
56/* This constructor must be called from the owner's oneinit() hook and
57 * *not* its constructor.  This is to ensure that DEVINIT has been
58 * completed, and that the device is correctly enabled before we touch
59 * falcon registers.
60 */
61int nvkm_falcon_v1_new(struct nvkm_subdev *owner, const char *name, u32 addr,
62		       struct nvkm_falcon **);
63
64void nvkm_falcon_del(struct nvkm_falcon **);
65int nvkm_falcon_get(struct nvkm_falcon *, const struct nvkm_subdev *);
66void nvkm_falcon_put(struct nvkm_falcon *, const struct nvkm_subdev *);
67
68int nvkm_falcon_new_(const struct nvkm_falcon_func *, struct nvkm_device *,
69		     int index, bool enable, u32 addr, struct nvkm_engine **);
70
71struct nvkm_falcon_func {
72	struct {
73		u32 *data;
74		u32  size;
75	} code;
76	struct {
77		u32 *data;
78		u32  size;
79	} data;
80	void (*init)(struct nvkm_falcon *);
81	void (*intr)(struct nvkm_falcon *, struct nvkm_fifo_chan *);
82
83	u32 debug;
84	u32 fbif;
85
86	void (*load_imem)(struct nvkm_falcon *, void *, u32, u32, u16, u8, bool);
87	void (*load_dmem)(struct nvkm_falcon *, void *, u32, u32, u8);
88	void (*read_dmem)(struct nvkm_falcon *, u32, u32, u8, void *);
89	u32 emem_addr;
90	void (*bind_context)(struct nvkm_falcon *, struct nvkm_memory *);
91	int (*wait_for_halt)(struct nvkm_falcon *, u32);
92	int (*clear_interrupt)(struct nvkm_falcon *, u32);
93	void (*set_start_addr)(struct nvkm_falcon *, u32 start_addr);
94	void (*start)(struct nvkm_falcon *);
95	int (*enable)(struct nvkm_falcon *falcon);
96	void (*disable)(struct nvkm_falcon *falcon);
97	int (*reset)(struct nvkm_falcon *);
98
99	struct {
100		u32 head;
101		u32 tail;
102		u32 stride;
103	} cmdq, msgq;
104
105	struct nvkm_sclass sclass[];
106};
107
108static inline u32
109nvkm_falcon_rd32(struct nvkm_falcon *falcon, u32 addr)
110{
111	return nvkm_rd32(falcon->owner->device, falcon->addr + addr);
112}
113
114static inline void
115nvkm_falcon_wr32(struct nvkm_falcon *falcon, u32 addr, u32 data)
116{
117	nvkm_wr32(falcon->owner->device, falcon->addr + addr, data);
118}
119
120static inline u32
121nvkm_falcon_mask(struct nvkm_falcon *falcon, u32 addr, u32 mask, u32 val)
122{
123	struct nvkm_device *device = falcon->owner->device;
124
125	return nvkm_mask(device, falcon->addr + addr, mask, val);
126}
127
128void nvkm_falcon_load_imem(struct nvkm_falcon *, void *, u32, u32, u16, u8,
129			   bool);
130void nvkm_falcon_load_dmem(struct nvkm_falcon *, void *, u32, u32, u8);
131void nvkm_falcon_read_dmem(struct nvkm_falcon *, u32, u32, u8, void *);
132void nvkm_falcon_bind_context(struct nvkm_falcon *, struct nvkm_memory *);
133void nvkm_falcon_set_start_addr(struct nvkm_falcon *, u32);
134void nvkm_falcon_start(struct nvkm_falcon *);
135int nvkm_falcon_wait_for_halt(struct nvkm_falcon *, u32);
136int nvkm_falcon_clear_interrupt(struct nvkm_falcon *, u32);
137int nvkm_falcon_enable(struct nvkm_falcon *);
138void nvkm_falcon_disable(struct nvkm_falcon *);
139int nvkm_falcon_reset(struct nvkm_falcon *);
140#endif
141