File Index
Files and directories
Sign in
FILE

pvr_fw.h

File preview with syntax highlighting.

linux-6.19.14/drivers/gpu/drm/imagination/pvr_fw.h C
  1/* SPDX-License-Identifier: GPL-2.0-only OR MIT */
  2/* Copyright (c) 2023 Imagination Technologies Ltd. */
  3
  4#ifndef PVR_FW_H
  5#define PVR_FW_H
  6
  7#include "pvr_fw_info.h"
  8#include "pvr_fw_trace.h"
  9#include "pvr_gem.h"
 10
 11#include <drm/drm_mm.h>
 12
 13#include <linux/types.h>
 14
 15/* Forward declarations from "pvr_device.h". */
 16struct pvr_device;
 17struct pvr_file;
 18
 19/* Forward declaration from "pvr_vm.h". */
 20struct pvr_vm_context;
 21
 22#define ROGUE_FWIF_FWCCB_NUMCMDS_LOG2 5
 23
 24#define ROGUE_FWIF_KCCB_NUMCMDS_LOG2_DEFAULT 7
 25
 26/**
 27 * struct pvr_fw_object - container for firmware memory allocations
 28 */
 29struct pvr_fw_object {
 30	/** @ref_count: FW object reference counter. */
 31	struct kref ref_count;
 32
 33	/** @gem: GEM object backing the FW object. */
 34	struct pvr_gem_object *gem;
 35
 36	/**
 37	 * @fw_mm_node: Node representing mapping in FW address space. @pvr_obj->lock must
 38	 *              be held when writing.
 39	 */
 40	struct drm_mm_node fw_mm_node;
 41
 42	/**
 43	 * @fw_addr_offset: Virtual address offset of firmware mapping. Only
 44	 *                  valid if @flags has %PVR_GEM_OBJECT_FLAGS_FW_MAPPED
 45	 *                  set.
 46	 */
 47	u32 fw_addr_offset;
 48
 49	/**
 50	 * @init: Initialisation callback. Will be called on object creation and FW hard reset.
 51	 *        Object will have been zeroed before this is called.
 52	 */
 53	void (*init)(void *cpu_ptr, void *priv);
 54
 55	/** @init_priv: Private data for initialisation callback. */
 56	void *init_priv;
 57
 58	/** @node: Node for firmware object list. */
 59	struct list_head node;
 60};
 61
 62/**
 63 * struct pvr_fw_defs - FW processor function table and static definitions
 64 */
 65struct pvr_fw_defs {
 66	/**
 67	 * @init:
 68	 *
 69	 * FW processor specific initialisation.
 70	 * @pvr_dev: Target PowerVR device.
 71	 *
 72	 * This function must call pvr_fw_heap_calculate() to initialise the firmware heap for this
 73	 * FW processor.
 74	 *
 75	 * This function is mandatory.
 76	 *
 77	 * Returns:
 78	 *  * 0 on success, or
 79	 *  * Any appropriate error on failure.
 80	 */
 81	int (*init)(struct pvr_device *pvr_dev);
 82
 83	/**
 84	 * @fini:
 85	 *
 86	 * FW processor specific finalisation.
 87	 * @pvr_dev: Target PowerVR device.
 88	 *
 89	 * This function is optional.
 90	 */
 91	void (*fini)(struct pvr_device *pvr_dev);
 92
 93	/**
 94	 * @fw_process:
 95	 *
 96	 * Load and process firmware image.
 97	 * @pvr_dev: Target PowerVR device.
 98	 * @fw: Pointer to firmware image.
 99	 * @fw_code_ptr: Pointer to firmware code section.
100	 * @fw_data_ptr: Pointer to firmware data section.
101	 * @fw_core_code_ptr: Pointer to firmware core code section. May be %NULL.
102	 * @fw_core_data_ptr: Pointer to firmware core data section. May be %NULL.
103	 * @core_code_alloc_size: Total allocation size of core code section.
104	 *
105	 * This function is mandatory.
106	 *
107	 * Returns:
108	 *  * 0 on success, or
109	 *  * Any appropriate error on failure.
110	 */
111	int (*fw_process)(struct pvr_device *pvr_dev, const u8 *fw,
112			  u8 *fw_code_ptr, u8 *fw_data_ptr, u8 *fw_core_code_ptr,
113			  u8 *fw_core_data_ptr, u32 core_code_alloc_size);
114
115	/**
116	 * @vm_map:
117	 *
118	 * Map FW object into FW processor address space.
119	 * @pvr_dev: Target PowerVR device.
120	 * @fw_obj: FW object to map.
121	 *
122	 * This function is mandatory.
123	 *
124	 * Returns:
125	 *  * 0 on success, or
126	 *  * Any appropriate error on failure.
127	 */
128	int (*vm_map)(struct pvr_device *pvr_dev, struct pvr_fw_object *fw_obj);
129
130	/**
131	 * @vm_unmap:
132	 *
133	 * Unmap FW object from FW processor address space.
134	 * @pvr_dev: Target PowerVR device.
135	 * @fw_obj: FW object to map.
136	 *
137	 * This function is mandatory.
138	 */
139	void (*vm_unmap)(struct pvr_device *pvr_dev, struct pvr_fw_object *fw_obj);
140
141	/**
142	 * @get_fw_addr_with_offset:
143	 *
144	 * Called to get address of object in firmware address space, with offset.
145	 * @fw_obj: Pointer to object.
146	 * @offset: Desired offset from start of object.
147	 *
148	 * This function is mandatory.
149	 *
150	 * Returns:
151	 *  * Address in firmware address space.
152	 */
153	u32 (*get_fw_addr_with_offset)(struct pvr_fw_object *fw_obj, u32 offset);
154
155	/**
156	 * @wrapper_init:
157	 *
158	 * Called to initialise FW wrapper.
159	 * @pvr_dev: Target PowerVR device.
160	 *
161	 * This function is mandatory.
162	 *
163	 * Returns:
164	 *  * 0 on success.
165	 *  * Any appropriate error on failure.
166	 */
167	int (*wrapper_init)(struct pvr_device *pvr_dev);
168
169	/**
170	 * @irq_pending: Check interrupt status register for pending interrupts.
171	 *
172	 * @pvr_dev: Target PowerVR device.
173	 *
174	 * This function is mandatory.
175	 */
176	bool (*irq_pending)(struct pvr_device *pvr_dev);
177
178	/**
179	 * @irq_clear: Clear pending interrupts.
180	 *
181	 * @pvr_dev: Target PowerVR device.
182	 *
183	 * This function is mandatory.
184	 */
185	void (*irq_clear)(struct pvr_device *pvr_dev);
186
187	/**
188	 * @has_fixed_data_addr: Specify whether the firmware fixed data must be loaded at the
189	 *                       address given by the firmware layout table.
190	 *
191	 * This value is mandatory.
192	 */
193	bool has_fixed_data_addr;
194};
195
196/**
197 * struct pvr_fw_mem - FW memory allocations
198 */
199struct pvr_fw_mem {
200	/** @code_obj: Object representing firmware code. */
201	struct pvr_fw_object *code_obj;
202
203	/** @data_obj: Object representing firmware data. */
204	struct pvr_fw_object *data_obj;
205
206	/**
207	 * @core_code_obj: Object representing firmware core code. May be
208	 *                 %NULL if firmware does not contain this section.
209	 */
210	struct pvr_fw_object *core_code_obj;
211
212	/**
213	 * @core_data_obj: Object representing firmware core data. May be
214	 *                 %NULL if firmware does not contain this section.
215	 */
216	struct pvr_fw_object *core_data_obj;
217
218	/** @code: Driver-side copy of firmware code. */
219	u8 *code;
220
221	/** @data: Driver-side copy of firmware data. */
222	u8 *data;
223
224	/**
225	 * @core_code: Driver-side copy of firmware core code. May be %NULL if firmware does not
226	 *             contain this section.
227	 */
228	u8 *core_code;
229
230	/**
231	 * @core_data: Driver-side copy of firmware core data. May be %NULL if firmware does not
232	 *             contain this section.
233	 */
234	u8 *core_data;
235
236	/** @code_alloc_size: Allocation size of firmware code section. */
237	u32 code_alloc_size;
238
239	/** @data_alloc_size: Allocation size of firmware data section. */
240	u32 data_alloc_size;
241
242	/** @core_code_alloc_size: Allocation size of firmware core code section. */
243	u32 core_code_alloc_size;
244
245	/** @core_data_alloc_size: Allocation size of firmware core data section. */
246	u32 core_data_alloc_size;
247
248	/**
249	 * @fwif_connection_ctl_obj: Object representing FWIF connection control
250	 *                           structure.
251	 */
252	struct pvr_fw_object *fwif_connection_ctl_obj;
253
254	/** @osinit_obj: Object representing FW OSINIT structure. */
255	struct pvr_fw_object *osinit_obj;
256
257	/** @sysinit_obj: Object representing FW SYSINIT structure. */
258	struct pvr_fw_object *sysinit_obj;
259
260	/** @osdata_obj: Object representing FW OSDATA structure. */
261	struct pvr_fw_object *osdata_obj;
262
263	/** @hwrinfobuf_obj: Object representing FW hwrinfobuf structure. */
264	struct pvr_fw_object *hwrinfobuf_obj;
265
266	/** @sysdata_obj: Object representing FW SYSDATA structure. */
267	struct pvr_fw_object *sysdata_obj;
268
269	/** @power_sync_obj: Object representing power sync state. */
270	struct pvr_fw_object *power_sync_obj;
271
272	/** @fault_page_obj: Object representing FW fault page. */
273	struct pvr_fw_object *fault_page_obj;
274
275	/** @gpu_util_fwcb_obj: Object representing FW GPU utilisation control structure. */
276	struct pvr_fw_object *gpu_util_fwcb_obj;
277
278	/** @runtime_cfg_obj: Object representing FW runtime config structure. */
279	struct pvr_fw_object *runtime_cfg_obj;
280
281	/** @mmucache_sync_obj: Object used as the sync parameter in an MMU cache operation. */
282	struct pvr_fw_object *mmucache_sync_obj;
283};
284
285struct pvr_fw_device {
286	/** @firmware: Handle to the firmware loaded into the device. */
287	const struct firmware *firmware;
288
289	/** @header: Pointer to firmware header. */
290	const struct pvr_fw_info_header *header;
291
292	/** @layout_entries: Pointer to firmware layout. */
293	const struct pvr_fw_layout_entry *layout_entries;
294
295	/** @mem: Structure containing objects representing firmware memory allocations. */
296	struct pvr_fw_mem mem;
297
298	/** @booted: %true if the firmware has been booted, %false otherwise. */
299	bool booted;
300
301	/**
302	 * @processor_type: FW processor type for this device. Must be one of
303	 *                  %PVR_FW_PROCESSOR_TYPE_*.
304	 */
305	u16 processor_type;
306
307	/** @funcs: Function table for the FW processor used by this device. */
308	const struct pvr_fw_defs *defs;
309
310	/** @processor_data: Pointer to data specific to FW processor. */
311	union {
312		/** @mips_data: Pointer to MIPS-specific data. */
313		struct pvr_fw_mips_data *mips_data;
314	} processor_data;
315
316	/** @fw_heap_info: Firmware heap information. */
317	struct {
318		/** @gpu_addr: Base address of firmware heap in GPU address space. */
319		u64 gpu_addr;
320
321		/** @size: Size of main area of heap. */
322		u32 size;
323
324		/** @offset_mask: Mask for offsets within FW heap. */
325		u32 offset_mask;
326
327		/** @raw_size: Raw size of heap, including reserved areas. */
328		u32 raw_size;
329
330		/** @log2_size: Log2 of raw size of heap. */
331		u32 log2_size;
332
333		/** @config_offset: Offset of config area within heap. */
334		u32 config_offset;
335
336		/** @reserved_size: Size of reserved area in heap. */
337		u32 reserved_size;
338	} fw_heap_info;
339
340	/** @fw_mm: Firmware address space allocator. */
341	struct drm_mm fw_mm;
342
343	/** @fw_mm_lock: Lock protecting access to &fw_mm. */
344	spinlock_t fw_mm_lock;
345
346	/** @fw_mm_base: Base address of address space managed by @fw_mm. */
347	u64 fw_mm_base;
348
349	/**
350	 * @fwif_connection_ctl: Pointer to CPU mapping of FWIF connection
351	 *                       control structure.
352	 */
353	struct rogue_fwif_connection_ctl *fwif_connection_ctl;
354
355	/** @fwif_sysinit: Pointer to CPU mapping of FW SYSINIT structure. */
356	struct rogue_fwif_sysinit *fwif_sysinit;
357
358	/** @fwif_sysdata: Pointer to CPU mapping of FW SYSDATA structure. */
359	struct rogue_fwif_sysdata *fwif_sysdata;
360
361	/** @fwif_osinit: Pointer to CPU mapping of FW OSINIT structure. */
362	struct rogue_fwif_osinit *fwif_osinit;
363
364	/** @fwif_osdata: Pointer to CPU mapping of FW OSDATA structure. */
365	struct rogue_fwif_osdata *fwif_osdata;
366
367	/** @power_sync: Pointer to CPU mapping of power sync state. */
368	u32 *power_sync;
369
370	/** @hwrinfobuf: Pointer to CPU mapping of FW HWR info buffer. */
371	struct rogue_fwif_hwrinfobuf *hwrinfobuf;
372
373	/** @fw_trace: Device firmware trace buffer state. */
374	struct pvr_fw_trace fw_trace;
375
376	/** @fw_objs: Structure tracking FW objects. */
377	struct {
378		/** @list: Head of FW object list. */
379		struct list_head list;
380
381		/** @lock: Lock protecting access to FW object list. */
382		struct mutex lock;
383	} fw_objs;
384};
385
386enum pvr_fw_processor_type {
387	PVR_FW_PROCESSOR_TYPE_META = 0,
388	PVR_FW_PROCESSOR_TYPE_MIPS,
389	PVR_FW_PROCESSOR_TYPE_RISCV,
390	PVR_FW_PROCESSOR_TYPE_COUNT,
391};
392
393extern const struct pvr_fw_defs pvr_fw_defs_meta;
394extern const struct pvr_fw_defs pvr_fw_defs_mips;
395extern const struct pvr_fw_defs pvr_fw_defs_riscv;
396
397int pvr_fw_validate_init_device_info(struct pvr_device *pvr_dev);
398int pvr_fw_init(struct pvr_device *pvr_dev);
399void pvr_fw_fini(struct pvr_device *pvr_dev);
400
401int pvr_wait_for_fw_boot(struct pvr_device *pvr_dev);
402
403int
404pvr_fw_hard_reset(struct pvr_device *pvr_dev);
405
406void pvr_fw_mts_schedule(struct pvr_device *pvr_dev, u32 val);
407
408void
409pvr_fw_heap_info_init(struct pvr_device *pvr_dev, u32 log2_size, u32 reserved_size);
410
411const struct pvr_fw_layout_entry *
412pvr_fw_find_layout_entry(struct pvr_device *pvr_dev, enum pvr_fw_section_id id);
413int
414pvr_fw_find_mmu_segment(struct pvr_device *pvr_dev, u32 addr, u32 size, void *fw_code_ptr,
415			void *fw_data_ptr, void *fw_core_code_ptr, void *fw_core_data_ptr,
416			void **host_addr_out);
417
418int
419pvr_fw_structure_cleanup(struct pvr_device *pvr_dev, u32 type, struct pvr_fw_object *fw_obj,
420			 u32 offset);
421
422int pvr_fw_object_create(struct pvr_device *pvr_dev, size_t size, u64 flags,
423			 void (*init)(void *cpu_ptr, void *priv), void *init_priv,
424			 struct pvr_fw_object **pvr_obj_out);
425
426void *pvr_fw_object_create_and_map(struct pvr_device *pvr_dev, size_t size, u64 flags,
427				   void (*init)(void *cpu_ptr, void *priv),
428				   void *init_priv, struct pvr_fw_object **pvr_obj_out);
429
430void *
431pvr_fw_object_create_and_map_offset(struct pvr_device *pvr_dev, u32 dev_offset, size_t size,
432				    u64 flags, void (*init)(void *cpu_ptr, void *priv),
433				    void *init_priv, struct pvr_fw_object **pvr_obj_out);
434
435static __always_inline void *
436pvr_fw_object_vmap(struct pvr_fw_object *fw_obj)
437{
438	return pvr_gem_object_vmap(fw_obj->gem);
439}
440
441static __always_inline void
442pvr_fw_object_vunmap(struct pvr_fw_object *fw_obj)
443{
444	pvr_gem_object_vunmap(fw_obj->gem);
445}
446
447void pvr_fw_object_destroy(struct pvr_fw_object *fw_obj);
448
449static __always_inline void
450pvr_fw_object_unmap_and_destroy(struct pvr_fw_object *fw_obj)
451{
452	pvr_fw_object_vunmap(fw_obj);
453	pvr_fw_object_destroy(fw_obj);
454}
455
456/**
457 * pvr_fw_object_get_dma_addr() - Get DMA address for given offset in firmware
458 * object.
459 * @fw_obj: Pointer to object to lookup address in.
460 * @offset: Offset within object to lookup address at.
461 * @dma_addr_out: Pointer to location to store DMA address.
462 *
463 * Returns:
464 *  * 0 on success, or
465 *  * -%EINVAL if object is not currently backed, or if @offset is out of valid
466 *    range for this object.
467 */
468static __always_inline int
469pvr_fw_object_get_dma_addr(struct pvr_fw_object *fw_obj, u32 offset, dma_addr_t *dma_addr_out)
470{
471	return pvr_gem_get_dma_addr(fw_obj->gem, offset, dma_addr_out);
472}
473
474void pvr_fw_object_get_fw_addr_offset(struct pvr_fw_object *fw_obj, u32 offset, u32 *fw_addr_out);
475
476static __always_inline void
477pvr_fw_object_get_fw_addr(struct pvr_fw_object *fw_obj, u32 *fw_addr_out)
478{
479	pvr_fw_object_get_fw_addr_offset(fw_obj, 0, fw_addr_out);
480}
481
482u64
483pvr_fw_obj_get_gpu_addr(struct pvr_fw_object *fw_obj);
484
485static __always_inline size_t
486pvr_fw_obj_get_object_size(struct pvr_fw_object *fw_obj)
487{
488	return pvr_gem_object_size(fw_obj->gem);
489}
490
491/* Util functions defined in pvr_fw_util.c. These are intended for use in pvr_fw_<arch>.c files. */
492int
493pvr_fw_process_elf_command_stream(struct pvr_device *pvr_dev, const u8 *fw, u8 *fw_code_ptr,
494				  u8 *fw_data_ptr, u8 *fw_core_code_ptr, u8 *fw_core_data_ptr);
495
496#endif /* PVR_FW_H */
~/ Read-only file preview.