1/* SPDX-License-Identifier: MIT */
2#ifndef __NVKM_FLCNEN_H__
3#define __NVKM_FLCNEN_H__
4#define nvkm_falcon(p) container_of((p), struct nvkm_falcon, engine)
5#include <core/engine.h>
6struct nvkm_chan;
7
8enum nvkm_falcon_dmaidx {
9	FALCON_DMAIDX_UCODE		= 0,
10	FALCON_DMAIDX_VIRT		= 1,
11	FALCON_DMAIDX_PHYS_VID		= 2,
12	FALCON_DMAIDX_PHYS_SYS_COH	= 3,
13	FALCON_DMAIDX_PHYS_SYS_NCOH	= 4,
14	FALCON_SEC2_DMAIDX_UCODE	= 6,
15};
16
17struct nvkm_falcon {
18	const struct nvkm_falcon_func *func;
19	struct nvkm_subdev *owner;
20	const char *name;
21	u32 addr;
22	u32 addr2;
23
24	struct mutex mutex;
25	struct mutex dmem_mutex;
26	bool oneinit;
27
28	struct nvkm_subdev *user;
29
30	u8 version;
31	u8 secret;
32	bool debug;
33
34	struct nvkm_memory *core;
35	bool external;
36
37	struct {
38		u32 limit;
39		u32 *data;
40		u32  size;
41		u8 ports;
42	} code;
43
44	struct {
45		u32 limit;
46		u32 *data;
47		u32  size;
48		u8 ports;
49	} data;
50
51	struct nvkm_engine engine;
52};
53
54int nvkm_falcon_get(struct nvkm_falcon *, struct nvkm_subdev *);
55void nvkm_falcon_put(struct nvkm_falcon *, struct nvkm_subdev *);
56
57int nvkm_falcon_new_(const struct nvkm_falcon_func *, struct nvkm_device *,
58		     enum nvkm_subdev_type, int inst, bool enable, u32 addr, struct nvkm_engine **);
59
60struct nvkm_falcon_func {
61	int (*disable)(struct nvkm_falcon *);
62	int (*enable)(struct nvkm_falcon *);
63	int (*select)(struct nvkm_falcon *);
64	u32 addr2;
65	u32 riscv_irqmask;
66	bool reset_pmc;
67	int (*reset_eng)(struct nvkm_falcon *);
68	int (*reset_prep)(struct nvkm_falcon *);
69	int (*reset_wait_mem_scrubbing)(struct nvkm_falcon *);
70
71	u32 debug;
72	void (*bind_inst)(struct nvkm_falcon *, int target, u64 addr);
73	int (*bind_stat)(struct nvkm_falcon *, bool intr);
74	bool bind_intr;
75
76	const struct nvkm_falcon_func_pio *imem_pio;
77	const struct nvkm_falcon_func_dma *imem_dma;
78
79	const struct nvkm_falcon_func_pio *dmem_pio;
80	const struct nvkm_falcon_func_dma *dmem_dma;
81
82	u32 emem_addr;
83	const struct nvkm_falcon_func_pio *emem_pio;
84
85	struct {
86		u32 head;
87		u32 tail;
88		u32 stride;
89	} cmdq, msgq;
90
91	bool (*riscv_active)(struct nvkm_falcon *);
92	void (*intr_retrigger)(struct nvkm_falcon *);
93
94	struct {
95		u32 *data;
96		u32  size;
97	} code;
98	struct {
99		u32 *data;
100		u32  size;
101	} data;
102	void (*init)(struct nvkm_falcon *);
103	void (*intr)(struct nvkm_falcon *, struct nvkm_chan *);
104
105	void (*load_imem)(struct nvkm_falcon *, void *, u32, u32, u16, u8, bool);
106	void (*load_dmem)(struct nvkm_falcon *, void *, u32, u32, u8);
107	void (*start)(struct nvkm_falcon *);
108
109	struct nvkm_sclass sclass[];
110};
111
112static inline u32
113nvkm_falcon_rd32(struct nvkm_falcon *falcon, u32 addr)
114{
115	return nvkm_rd32(falcon->owner->device, falcon->addr + addr);
116}
117
118static inline void
119nvkm_falcon_wr32(struct nvkm_falcon *falcon, u32 addr, u32 data)
120{
121	nvkm_wr32(falcon->owner->device, falcon->addr + addr, data);
122}
123
124static inline u32
125nvkm_falcon_mask(struct nvkm_falcon *falcon, u32 addr, u32 mask, u32 val)
126{
127	struct nvkm_device *device = falcon->owner->device;
128
129	return nvkm_mask(device, falcon->addr + addr, mask, val);
130}
131
132void nvkm_falcon_load_imem(struct nvkm_falcon *, void *, u32, u32, u16, u8,
133			   bool);
134void nvkm_falcon_load_dmem(struct nvkm_falcon *, void *, u32, u32, u8);
135void nvkm_falcon_start(struct nvkm_falcon *);
136#endif
137