]> Git Repo - linux.git/blob - drivers/gpu/drm/imagination/pvr_fw.h
Merge tag 'cxl-for-6.10' of git://git.kernel.org/pub/scm/linux/kernel/git/cxl/cxl
[linux.git] / drivers / gpu / drm / imagination / pvr_fw.h
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". */
16 struct pvr_device;
17 struct pvr_file;
18
19 /* Forward declaration from "pvr_vm.h". */
20 struct 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  */
29 struct 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  */
65 struct 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          * @has_fixed_data_addr:
171          *
172          * Called to check if firmware fixed data must be loaded at the address given by the
173          * firmware layout table.
174          *
175          * This function is mandatory.
176          *
177          * Returns:
178          *  * %true if firmware fixed data must be loaded at the address given by the firmware
179          *    layout table.
180          *  * %false otherwise.
181          */
182         bool (*has_fixed_data_addr)(void);
183
184         /**
185          * @irq: FW Interrupt information.
186          *
187          * Those are processor dependent, and should be initialized by the
188          * processor backend in pvr_fw_funcs::init().
189          */
190         struct {
191                 /** @enable_reg: FW interrupt enable register. */
192                 u32 enable_reg;
193
194                 /** @status_reg: FW interrupt status register. */
195                 u32 status_reg;
196
197                 /**
198                  * @clear_reg: FW interrupt clear register.
199                  *
200                  * If @status_reg == @clear_reg, we clear by write a bit to zero,
201                  * otherwise we clear by writing a bit to one.
202                  */
203                 u32 clear_reg;
204
205                 /** @event_mask: Bitmask of events to listen for. */
206                 u32 event_mask;
207
208                 /** @clear_mask: Value to write to the clear_reg in order to clear FW IRQs. */
209                 u32 clear_mask;
210         } irq;
211 };
212
213 /**
214  * struct pvr_fw_mem - FW memory allocations
215  */
216 struct pvr_fw_mem {
217         /** @code_obj: Object representing firmware code. */
218         struct pvr_fw_object *code_obj;
219
220         /** @data_obj: Object representing firmware data. */
221         struct pvr_fw_object *data_obj;
222
223         /**
224          * @core_code_obj: Object representing firmware core code. May be
225          *                 %NULL if firmware does not contain this section.
226          */
227         struct pvr_fw_object *core_code_obj;
228
229         /**
230          * @core_data_obj: Object representing firmware core data. May be
231          *                 %NULL if firmware does not contain this section.
232          */
233         struct pvr_fw_object *core_data_obj;
234
235         /** @code: Driver-side copy of firmware code. */
236         u8 *code;
237
238         /** @data: Driver-side copy of firmware data. */
239         u8 *data;
240
241         /**
242          * @core_code: Driver-side copy of firmware core code. May be %NULL if firmware does not
243          *             contain this section.
244          */
245         u8 *core_code;
246
247         /**
248          * @core_data: Driver-side copy of firmware core data. May be %NULL if firmware does not
249          *             contain this section.
250          */
251         u8 *core_data;
252
253         /** @code_alloc_size: Allocation size of firmware code section. */
254         u32 code_alloc_size;
255
256         /** @data_alloc_size: Allocation size of firmware data section. */
257         u32 data_alloc_size;
258
259         /** @core_code_alloc_size: Allocation size of firmware core code section. */
260         u32 core_code_alloc_size;
261
262         /** @core_data_alloc_size: Allocation size of firmware core data section. */
263         u32 core_data_alloc_size;
264
265         /**
266          * @fwif_connection_ctl_obj: Object representing FWIF connection control
267          *                           structure.
268          */
269         struct pvr_fw_object *fwif_connection_ctl_obj;
270
271         /** @osinit_obj: Object representing FW OSINIT structure. */
272         struct pvr_fw_object *osinit_obj;
273
274         /** @sysinit_obj: Object representing FW SYSINIT structure. */
275         struct pvr_fw_object *sysinit_obj;
276
277         /** @osdata_obj: Object representing FW OSDATA structure. */
278         struct pvr_fw_object *osdata_obj;
279
280         /** @hwrinfobuf_obj: Object representing FW hwrinfobuf structure. */
281         struct pvr_fw_object *hwrinfobuf_obj;
282
283         /** @sysdata_obj: Object representing FW SYSDATA structure. */
284         struct pvr_fw_object *sysdata_obj;
285
286         /** @power_sync_obj: Object representing power sync state. */
287         struct pvr_fw_object *power_sync_obj;
288
289         /** @fault_page_obj: Object representing FW fault page. */
290         struct pvr_fw_object *fault_page_obj;
291
292         /** @gpu_util_fwcb_obj: Object representing FW GPU utilisation control structure. */
293         struct pvr_fw_object *gpu_util_fwcb_obj;
294
295         /** @runtime_cfg_obj: Object representing FW runtime config structure. */
296         struct pvr_fw_object *runtime_cfg_obj;
297
298         /** @mmucache_sync_obj: Object used as the sync parameter in an MMU cache operation. */
299         struct pvr_fw_object *mmucache_sync_obj;
300 };
301
302 struct pvr_fw_device {
303         /** @firmware: Handle to the firmware loaded into the device. */
304         const struct firmware *firmware;
305
306         /** @header: Pointer to firmware header. */
307         const struct pvr_fw_info_header *header;
308
309         /** @layout_entries: Pointer to firmware layout. */
310         const struct pvr_fw_layout_entry *layout_entries;
311
312         /** @mem: Structure containing objects representing firmware memory allocations. */
313         struct pvr_fw_mem mem;
314
315         /** @booted: %true if the firmware has been booted, %false otherwise. */
316         bool booted;
317
318         /**
319          * @processor_type: FW processor type for this device. Must be one of
320          *                  %PVR_FW_PROCESSOR_TYPE_*.
321          */
322         u16 processor_type;
323
324         /** @funcs: Function table for the FW processor used by this device. */
325         const struct pvr_fw_defs *defs;
326
327         /** @processor_data: Pointer to data specific to FW processor. */
328         union {
329                 /** @mips_data: Pointer to MIPS-specific data. */
330                 struct pvr_fw_mips_data *mips_data;
331         } processor_data;
332
333         /** @fw_heap_info: Firmware heap information. */
334         struct {
335                 /** @gpu_addr: Base address of firmware heap in GPU address space. */
336                 u64 gpu_addr;
337
338                 /** @size: Size of main area of heap. */
339                 u32 size;
340
341                 /** @offset_mask: Mask for offsets within FW heap. */
342                 u32 offset_mask;
343
344                 /** @raw_size: Raw size of heap, including reserved areas. */
345                 u32 raw_size;
346
347                 /** @log2_size: Log2 of raw size of heap. */
348                 u32 log2_size;
349
350                 /** @config_offset: Offset of config area within heap. */
351                 u32 config_offset;
352
353                 /** @reserved_size: Size of reserved area in heap. */
354                 u32 reserved_size;
355         } fw_heap_info;
356
357         /** @fw_mm: Firmware address space allocator. */
358         struct drm_mm fw_mm;
359
360         /** @fw_mm_lock: Lock protecting access to &fw_mm. */
361         spinlock_t fw_mm_lock;
362
363         /** @fw_mm_base: Base address of address space managed by @fw_mm. */
364         u64 fw_mm_base;
365
366         /**
367          * @fwif_connection_ctl: Pointer to CPU mapping of FWIF connection
368          *                       control structure.
369          */
370         struct rogue_fwif_connection_ctl *fwif_connection_ctl;
371
372         /** @fwif_sysinit: Pointer to CPU mapping of FW SYSINIT structure. */
373         struct rogue_fwif_sysinit *fwif_sysinit;
374
375         /** @fwif_sysdata: Pointer to CPU mapping of FW SYSDATA structure. */
376         struct rogue_fwif_sysdata *fwif_sysdata;
377
378         /** @fwif_osinit: Pointer to CPU mapping of FW OSINIT structure. */
379         struct rogue_fwif_osinit *fwif_osinit;
380
381         /** @fwif_osdata: Pointer to CPU mapping of FW OSDATA structure. */
382         struct rogue_fwif_osdata *fwif_osdata;
383
384         /** @power_sync: Pointer to CPU mapping of power sync state. */
385         u32 *power_sync;
386
387         /** @hwrinfobuf: Pointer to CPU mapping of FW HWR info buffer. */
388         struct rogue_fwif_hwrinfobuf *hwrinfobuf;
389
390         /** @fw_trace: Device firmware trace buffer state. */
391         struct pvr_fw_trace fw_trace;
392
393         /** @fw_objs: Structure tracking FW objects. */
394         struct {
395                 /** @list: Head of FW object list. */
396                 struct list_head list;
397
398                 /** @lock: Lock protecting access to FW object list. */
399                 struct mutex lock;
400         } fw_objs;
401 };
402
403 #define pvr_fw_irq_read_reg(pvr_dev, name) \
404         pvr_cr_read32((pvr_dev), (pvr_dev)->fw_dev.defs->irq.name ## _reg)
405
406 #define pvr_fw_irq_write_reg(pvr_dev, name, value) \
407         pvr_cr_write32((pvr_dev), (pvr_dev)->fw_dev.defs->irq.name ## _reg, value)
408
409 #define pvr_fw_irq_pending(pvr_dev) \
410         (pvr_fw_irq_read_reg(pvr_dev, status) & (pvr_dev)->fw_dev.defs->irq.event_mask)
411
412 #define pvr_fw_irq_clear(pvr_dev) \
413         pvr_fw_irq_write_reg(pvr_dev, clear, (pvr_dev)->fw_dev.defs->irq.clear_mask)
414
415 #define pvr_fw_irq_enable(pvr_dev) \
416         pvr_fw_irq_write_reg(pvr_dev, enable, (pvr_dev)->fw_dev.defs->irq.event_mask)
417
418 #define pvr_fw_irq_disable(pvr_dev) \
419         pvr_fw_irq_write_reg(pvr_dev, enable, 0)
420
421 extern const struct pvr_fw_defs pvr_fw_defs_meta;
422 extern const struct pvr_fw_defs pvr_fw_defs_mips;
423
424 int pvr_fw_validate_init_device_info(struct pvr_device *pvr_dev);
425 int pvr_fw_init(struct pvr_device *pvr_dev);
426 void pvr_fw_fini(struct pvr_device *pvr_dev);
427
428 int pvr_wait_for_fw_boot(struct pvr_device *pvr_dev);
429
430 int
431 pvr_fw_hard_reset(struct pvr_device *pvr_dev);
432
433 void pvr_fw_mts_schedule(struct pvr_device *pvr_dev, u32 val);
434
435 void
436 pvr_fw_heap_info_init(struct pvr_device *pvr_dev, u32 log2_size, u32 reserved_size);
437
438 const struct pvr_fw_layout_entry *
439 pvr_fw_find_layout_entry(struct pvr_device *pvr_dev, enum pvr_fw_section_id id);
440 int
441 pvr_fw_find_mmu_segment(struct pvr_device *pvr_dev, u32 addr, u32 size, void *fw_code_ptr,
442                         void *fw_data_ptr, void *fw_core_code_ptr, void *fw_core_data_ptr,
443                         void **host_addr_out);
444
445 int
446 pvr_fw_structure_cleanup(struct pvr_device *pvr_dev, u32 type, struct pvr_fw_object *fw_obj,
447                          u32 offset);
448
449 int pvr_fw_object_create(struct pvr_device *pvr_dev, size_t size, u64 flags,
450                          void (*init)(void *cpu_ptr, void *priv), void *init_priv,
451                          struct pvr_fw_object **pvr_obj_out);
452
453 void *pvr_fw_object_create_and_map(struct pvr_device *pvr_dev, size_t size, u64 flags,
454                                    void (*init)(void *cpu_ptr, void *priv),
455                                    void *init_priv, struct pvr_fw_object **pvr_obj_out);
456
457 void *
458 pvr_fw_object_create_and_map_offset(struct pvr_device *pvr_dev, u32 dev_offset, size_t size,
459                                     u64 flags, void (*init)(void *cpu_ptr, void *priv),
460                                     void *init_priv, struct pvr_fw_object **pvr_obj_out);
461
462 static __always_inline void *
463 pvr_fw_object_vmap(struct pvr_fw_object *fw_obj)
464 {
465         return pvr_gem_object_vmap(fw_obj->gem);
466 }
467
468 static __always_inline void
469 pvr_fw_object_vunmap(struct pvr_fw_object *fw_obj)
470 {
471         pvr_gem_object_vunmap(fw_obj->gem);
472 }
473
474 void pvr_fw_object_destroy(struct pvr_fw_object *fw_obj);
475
476 static __always_inline void
477 pvr_fw_object_unmap_and_destroy(struct pvr_fw_object *fw_obj)
478 {
479         pvr_fw_object_vunmap(fw_obj);
480         pvr_fw_object_destroy(fw_obj);
481 }
482
483 /**
484  * pvr_fw_object_get_dma_addr() - Get DMA address for given offset in firmware
485  * object.
486  * @fw_obj: Pointer to object to lookup address in.
487  * @offset: Offset within object to lookup address at.
488  * @dma_addr_out: Pointer to location to store DMA address.
489  *
490  * Returns:
491  *  * 0 on success, or
492  *  * -%EINVAL if object is not currently backed, or if @offset is out of valid
493  *    range for this object.
494  */
495 static __always_inline int
496 pvr_fw_object_get_dma_addr(struct pvr_fw_object *fw_obj, u32 offset, dma_addr_t *dma_addr_out)
497 {
498         return pvr_gem_get_dma_addr(fw_obj->gem, offset, dma_addr_out);
499 }
500
501 void pvr_fw_object_get_fw_addr_offset(struct pvr_fw_object *fw_obj, u32 offset, u32 *fw_addr_out);
502
503 static __always_inline void
504 pvr_fw_object_get_fw_addr(struct pvr_fw_object *fw_obj, u32 *fw_addr_out)
505 {
506         pvr_fw_object_get_fw_addr_offset(fw_obj, 0, fw_addr_out);
507 }
508
509 #endif /* PVR_FW_H */
This page took 0.061708 seconds and 4 git commands to generate.