aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau/include/nvkm/engine/falcon.h
blob: 27c1f868552cdb4380d0904cfda06eab792c725c (plain) (blame)
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
/* SPDX-License-Identifier: MIT */
#ifndef __NVKM_FLCNEN_H__
#define __NVKM_FLCNEN_H__
#define nvkm_falcon(p) container_of((p), struct nvkm_falcon, engine)
#include <core/engine.h>
struct nvkm_fifo_chan;
struct nvkm_gpuobj;

enum nvkm_falcon_dmaidx {
	FALCON_DMAIDX_UCODE		= 0,
	FALCON_DMAIDX_VIRT		= 1,
	FALCON_DMAIDX_PHYS_VID		= 2,
	FALCON_DMAIDX_PHYS_SYS_COH	= 3,
	FALCON_DMAIDX_PHYS_SYS_NCOH	= 4,
	FALCON_SEC2_DMAIDX_UCODE	= 6,
};

struct nvkm_falcon {
	const struct nvkm_falcon_func *func;
	const struct nvkm_subdev *owner;
	const char *name;
	u32 addr;

	struct mutex mutex;
	struct mutex dmem_mutex;
	bool oneinit;

	const struct nvkm_subdev *user;

	u8 version;
	u8 secret;
	bool debug;

	struct nvkm_memory *core;
	bool external;

	struct {
		u32 limit;
		u32 *data;
		u32  size;
		u8 ports;
	} code;

	struct {
		u32 limit;
		u32 *data;
		u32  size;
		u8 ports;
	} data;

	struct nvkm_engine engine;
};

/* This constructor must be called from the owner's oneinit() hook and
 * *not* its constructor.  This is to ensure that DEVINIT has been
 * completed, and that the device is correctly enabled before we touch
 * falcon registers.
 */
int nvkm_falcon_v1_new(struct nvkm_subdev *owner, const char *name, u32 addr,
		       struct nvkm_falcon **);

void nvkm_falcon_del(struct nvkm_falcon **);
int nvkm_falcon_get(struct nvkm_falcon *, const struct nvkm_subdev *);
void nvkm_falcon_put(struct nvkm_falcon *, const struct nvkm_subdev *);

int nvkm_falcon_new_(const struct nvkm_falcon_func *, struct nvkm_device *,
		     int index, bool enable, u32 addr, struct nvkm_engine **);

struct nvkm_falcon_func {
	struct {
		u32 *data;
		u32  size;
	} code;
	struct {
		u32 *data;
		u32  size;
	} data;
	void (*init)(struct nvkm_falcon *);
	void (*intr)(struct nvkm_falcon *, struct nvkm_fifo_chan *);

	u32 debug;
	u32 fbif;

	void (*load_imem)(struct nvkm_falcon *, void *, u32, u32, u16, u8, bool);
	void (*load_dmem)(struct nvkm_falcon *, void *, u32, u32, u8);
	void (*read_dmem)(struct nvkm_falcon *, u32, u32, u8, void *);
	u32 emem_addr;
	void (*bind_context)(struct nvkm_falcon *, struct nvkm_memory *);
	int (*wait_for_halt)(struct nvkm_falcon *, u32);
	int (*clear_interrupt)(struct nvkm_falcon *, u32);
	void (*set_start_addr)(struct nvkm_falcon *, u32 start_addr);
	void (*start)(struct nvkm_falcon *);
	int (*enable)(struct nvkm_falcon *falcon);
	void (*disable)(struct nvkm_falcon *falcon);
	int (*reset)(struct nvkm_falcon *);

	struct {
		u32 head;
		u32 tail;
		u32 stride;
	} cmdq, msgq;

	struct nvkm_sclass sclass[];
};

static inline u32
nvkm_falcon_rd32(struct nvkm_falcon *falcon, u32 addr)
{
	return nvkm_rd32(falcon->owner->device, falcon->addr + addr);
}

static inline void
nvkm_falcon_wr32(struct nvkm_falcon *falcon, u32 addr, u32 data)
{
	nvkm_wr32(falcon->owner->device, falcon->addr + addr, data);
}

static inline u32
nvkm_falcon_mask(struct nvkm_falcon *falcon, u32 addr, u32 mask, u32 val)
{
	struct nvkm_device *device = falcon->owner->device;

	return nvkm_mask(device, falcon->addr + addr, mask, val);
}

void nvkm_falcon_load_imem(struct nvkm_falcon *, void *, u32, u32, u16, u8,
			   bool);
void nvkm_falcon_load_dmem(struct nvkm_falcon *, void *, u32, u32, u8);
void nvkm_falcon_read_dmem(struct nvkm_falcon *, u32, u32, u8, void *);
void nvkm_falcon_bind_context(struct nvkm_falcon *, struct nvkm_memory *);
void nvkm_falcon_set_start_addr(struct nvkm_falcon *, u32);
void nvkm_falcon_start(struct nvkm_falcon *);
int nvkm_falcon_wait_for_halt(struct nvkm_falcon *, u32);
int nvkm_falcon_clear_interrupt(struct nvkm_falcon *, u32);
int nvkm_falcon_enable(struct nvkm_falcon *);
void nvkm_falcon_disable(struct nvkm_falcon *);
int nvkm_falcon_reset(struct nvkm_falcon *);
#endif