aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/remoteproc.h
blob: 685a042db8f8912e951299d9b52bdd6ac879aaf3 (plain)
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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
/*
 * Remote Processor Framework
 *
 * Copyright(c) 2011 Texas Instruments. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * * Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 * * Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in
 *   the documentation and/or other materials provided with the
 *   distribution.
 * * Neither the name Texas Instruments nor the names of its
 *   contributors may be used to endorse or promote products derived
 *   from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef REMOTEPROC_H
#define REMOTEPROC_H

#include <linux/mutex.h>
#include <linux/completion.h>
#include <linux/workqueue.h>
#include <linux/notifier.h>
#include <linux/pm_qos_params.h>

/* Must match the BIOS version embeded in the BIOS firmware image */
#define RPROC_BIOS_VERSION	2

/* Maximum number of entries that can be added for lookup */
#define RPROC_MAX_MEM_ENTRIES	20

/**
 * The following enums and structures define the binary format of the images
 * we load and run the remote processors with.
 *
 * The binary format is as follows:
 *
 * struct {
 *     char magic[4] = { 'R', 'P', 'R', 'C' };
 *     u32 version;
 *     u32 header_len;
 *     char header[...] = { header_len bytes of unformatted, textual header };
 *     struct section {
 *         u32 type;
 *         u64 da;
 *         u32 len;
 *         u8 content[...] = { len bytes of binary data };
 *     } [ no limit on number of sections ];
 * } __packed;
 */
struct fw_header {
	char magic[4];
	u32 version;
	u32 header_len;
	char header[0];
} __packed;

struct fw_section {
	u32 type;
	u64 da;
	u32 len;
	char content[0];
} __packed;

enum fw_section_type {
	FW_RESOURCE	= 0,
	FW_TEXT		= 1,
	FW_DATA		= 2,
	FW_MMU		= 3,
	FW_SIGNATURE	= 4,
};

struct fw_resource {
	u32 type;
	u64 da;
	u64 pa;
	u32 len;
	u32 reserved;
	u8 name[48];
} __packed;

enum fw_resource_type {
	RSC_CARVEOUT	= 0,
	RSC_DEVMEM	= 1,
	RSC_DEVICE	= 2,
	RSC_IRQ		= 3,
	RSC_TRACE	= 4,
	RSC_BOOTADDR	= 5,
	RSC_CRASHDUMP	= 6,
	RSC_END		= 7,
};

/**
 * struct rproc_mem_pool - descriptor for the rproc's contiguous memory pool data
 *
 * @mem_base: starting physical address of the dynamic pool
 * @mem_size: size of the initial dynamic pool
 * @cur_base: current available physical address in the pool
 * @cur_size: remaining available memory in the pool
 * @st_base:  starting physical address of the static pool
 * @st_size:  size of the static pool
 */
struct rproc_mem_pool {
	phys_addr_t mem_base;
	u32 mem_size;
	phys_addr_t cur_base;
	u32 cur_size;
	phys_addr_t st_base;
	u32 st_size;
};

/**
 * struct rproc_mem_entry - descriptor of a remote memory region
 *
 * @da:		virtual address as seen by the device (aka device address)
 * @pa:		physical address
 * @size:	size of this memory region
 */
struct rproc_mem_entry {
	u64 da;
	phys_addr_t pa;
	u32 size;
	bool core;
};

enum rproc_constraint {
	RPROC_CONSTRAINT_SCALE,
	RPROC_CONSTRAINT_LATENCY,
	RPROC_CONSTRAINT_BANDWIDTH,
};

struct rproc;

struct rproc_ops {
	int (*start)(struct rproc *rproc, u64 bootaddr);
	int (*stop)(struct rproc *rproc);
	int (*suspend)(struct rproc *rproc, bool force);
	int (*resume)(struct rproc *rproc);
	int (*iommu_init)(struct rproc *, int (*)(struct rproc *, u64, u32));
	int (*iommu_exit)(struct rproc *);
	int (*set_lat)(struct rproc *rproc, long v);
	int (*set_bw)(struct rproc *rproc, long v);
	int (*scale)(struct rproc *rproc, long v);
	int (*watchdog_init)(struct rproc *, int (*)(struct rproc *));
	int (*watchdog_exit)(struct rproc *);
	void (*dump_registers)(struct rproc *);
};

/*
 * enum rproc_state - remote processor states
 *
 * @RPROC_OFFLINE: needs firmware load and init to exit this state.
 *
 * @RPROC_SUSPENDED: needs to be woken up to receive a message.
 *
 * @RPROC_RUNNING: up and running.
 *
 * @RPROC_LOADING: asynchronous firmware loading has started
 *
 * @RPROC_CRASHED: needs to be logged, connections torn down, resources
 * released, and returned to OFFLINE.
 */
enum rproc_state {
	RPROC_OFFLINE,
	RPROC_SUSPENDED,
	RPROC_RUNNING,
	RPROC_LOADING,
	RPROC_CRASHED,
};

/*
 * enum rproc_event - remote processor events
 *
 * @RPROC_ERROR: Fatal error has happened on the remote processor.
 *
 * @RPROC_PRE_SUSPEND: users can register for that event in order to cancel
 *		       autosuspend, they just need to return an error in the
 *		       callback function.
 *
 * @RPROC_POS_SUSPEND: users can register for that event in order to release
 *		       resources not needed when the remote processor is
 *		       sleeping or if they need to save some context.
 *
 * @RPROC_RESUME: users should use this event to revert what was done in the
 *		  POS_SUSPEND event.
 *
 * @RPROC_SECURE: remote processor secure mode has changed.
 *
 * @RPROC_LOAD_ERROR: an error has occurred during loading the remote processor
 *                    binary. users can use this event to release any resources
 *                    acquired after a request to start the processor.
 */
enum rproc_event {
	RPROC_ERROR,
	RPROC_PRE_SUSPEND,
	RPROC_POS_SUSPEND,
	RPROC_RESUME,
	RPROC_SECURE,
	RPROC_LOAD_ERROR,
};

#define RPROC_MAX_NAME	100

/*
 * struct rproc - a physical remote processor device
 *
 * @next: next rproc entry in the list
 * @name: human readable name of the rproc, cannot exceed RPROC_MAX_NAME bytes
 * @memory_maps: table of da-to-pa memory maps (relevant if device is behind
 *               an iommu)
 * @memory_pool: platform-specific contiguous memory pool data (relevant for
 *               allocating memory needed for the remote processor image)
 * @firmware: name of firmware file to be loaded
 * @owner: reference to the platform-specific rproc module
 * @priv: private data which belongs to the platform-specific rproc module
 * @ops: platform-specific start/stop rproc handlers
 * @dev: reference to the platform-specific rproc dev
 * @count: usage refcount
 * @state: rproc_state enum value representing the state of the device
 * @lock: lock which protects concurrent manipulations of the rproc
 * @dbg_dir: debugfs directory of this rproc device
 * @trace_buf0: main trace buffer of the remote processor
 * @trace_buf1: second, optional, trace buffer of the remote processor
 * @trace_len0: length of main trace buffer of the remote processor
 * @trace_len1: length of the second (and optional) trace buffer
 * @cdump_buf0: main exception/crash dump buffer of the remote processor
 * @cdump_buf1: second exception/crash dump buffer of the remote processor
 * @cdump_len0: length of main crash dump buffer of the remote processor
 * @cdump_len1: length of the second (and optional) crash dump buffer
 * @firmware_loading_complete: flags e/o asynchronous firmware loading
 * @mmufault_work: work in charge of notifing mmufault
 * @nb_error: notify block for fatal errors
 * @error_comp: completion used when an error happens
 * @secure_ttb: private data for configuring iommu in secure mode
 * @secure_restart: completion event notifier for the secure restart process
 * @secure_mode: flag to dictate whether to enable secure loading
 * @secure_ok: restart status flag to be looked up upon the event's completion
 * @secure_reset: flag to uninstall the firewalls
 */
struct rproc {
	struct list_head next;
	const char *name;
	struct rproc_mem_entry memory_maps[RPROC_MAX_MEM_ENTRIES];
	struct rproc_mem_pool *memory_pool;
	const char *firmware;
	struct module *owner;
	void *priv;
	const struct rproc_ops *ops;
	struct device *dev;
	int count;
	int state;
	struct mutex lock;
	struct dentry *dbg_dir;
	char *trace_buf0, *trace_buf1;
	char *last_trace_buf0, *last_trace_buf1;
	int trace_len0, trace_len1;
	int last_trace_len0, last_trace_len1;
	void *cdump_buf0, *cdump_buf1;
	int cdump_len0, cdump_len1;
	struct mutex tlock;
	struct completion firmware_loading_complete;
	struct work_struct error_work, unload_work;
	struct blocking_notifier_head nbh;
	struct completion error_comp;
#ifdef CONFIG_REMOTE_PROC_AUTOSUSPEND
	unsigned sus_timeout;
	bool force_suspend;
	bool need_resume;
	bool need_restart;
	struct mutex pm_lock;
#endif
	struct pm_qos_request_list *qos_request;
	void *secure_ttb;
	struct completion secure_restart;
	struct mutex secure_lock;
	bool secure_mode;
	bool secure_ok;
	bool secure_reset;
	bool halt_on_crash;
	char *header;
	int header_len;
};

int rproc_set_secure(const char *, bool);
struct rproc *rproc_get(const char *);
void rproc_put(struct rproc *);
int rproc_event_register(struct rproc *, struct notifier_block *);
int rproc_event_unregister(struct rproc *, struct notifier_block *);
int rproc_register(struct device *, const char *, const struct rproc_ops *,
		const char *, struct rproc_mem_pool *, struct module *,
		unsigned int timeout);
int rproc_unregister(const char *);
void rproc_last_busy(struct rproc *);
#ifdef CONFIG_REMOTE_PROC_AUTOSUSPEND
extern const struct dev_pm_ops rproc_gen_pm_ops;
#define GENERIC_RPROC_PM_OPS	(&rproc_gen_pm_ops)
#else
#define GENERIC_RPROC_PM_OPS	NULL
#endif
int rproc_set_constraints(struct rproc *, enum rproc_constraint type, long v);
int rproc_error_notify(struct rproc *rproc);

#endif /* REMOTEPROC_H */