xref: /linux/drivers/gpu/drm/imagination/pvr_device.h (revision 07fdad3a93756b872da7b53647715c48d0f4a2d0)
1 /* SPDX-License-Identifier: GPL-2.0-only OR MIT */
2 /* Copyright (c) 2023 Imagination Technologies Ltd. */
3 
4 #ifndef PVR_DEVICE_H
5 #define PVR_DEVICE_H
6 
7 #include "pvr_ccb.h"
8 #include "pvr_device_info.h"
9 #include "pvr_fw.h"
10 #include "pvr_params.h"
11 #include "pvr_rogue_fwif_stream.h"
12 #include "pvr_stream.h"
13 
14 #include <drm/drm_device.h>
15 #include <drm/drm_file.h>
16 #include <drm/drm_mm.h>
17 
18 #include <linux/bits.h>
19 #include <linux/compiler_attributes.h>
20 #include <linux/compiler_types.h>
21 #include <linux/device.h>
22 #include <linux/io.h>
23 #include <linux/iopoll.h>
24 #include <linux/kernel.h>
25 #include <linux/math.h>
26 #include <linux/mutex.h>
27 #include <linux/spinlock_types.h>
28 #include <linux/timer.h>
29 #include <linux/types.h>
30 #include <linux/wait.h>
31 #include <linux/workqueue.h>
32 #include <linux/xarray.h>
33 
34 /* Forward declaration from <linux/clk.h>. */
35 struct clk;
36 
37 /* Forward declaration from <linux/firmware.h>. */
38 struct firmware;
39 
40 /* Forward declaration from <linux/pwrseq/consumer.h> */
41 struct pwrseq_desc;
42 
43 /**
44  * struct pvr_gpu_id - Hardware GPU ID information for a PowerVR device
45  * @b: Branch ID.
46  * @v: Version ID.
47  * @n: Number of scalable units.
48  * @c: Config ID.
49  */
50 struct pvr_gpu_id {
51 	u16 b, v, n, c;
52 };
53 
54 /**
55  * struct pvr_fw_version - Firmware version information
56  * @major: Major version number.
57  * @minor: Minor version number.
58  */
59 struct pvr_fw_version {
60 	u16 major, minor;
61 };
62 
63 /**
64  * struct pvr_device_data - Platform specific data associated with a compatible string.
65  * @pwr_ops: Pointer to a structure with platform-specific power functions.
66  */
67 struct pvr_device_data {
68 	const struct pvr_power_sequence_ops *pwr_ops;
69 };
70 
71 /**
72  * struct pvr_device - powervr-specific wrapper for &struct drm_device
73  */
74 struct pvr_device {
75 	/**
76 	 * @base: The underlying &struct drm_device.
77 	 *
78 	 * Do not access this member directly, instead call
79 	 * from_pvr_device().
80 	 */
81 	struct drm_device base;
82 
83 	/** @gpu_id: GPU ID detected at runtime. */
84 	struct pvr_gpu_id gpu_id;
85 
86 	/**
87 	 * @features: Hardware feature information.
88 	 *
89 	 * Do not access this member directly, instead use PVR_HAS_FEATURE()
90 	 * or PVR_FEATURE_VALUE() macros.
91 	 */
92 	struct pvr_device_features features;
93 
94 	/**
95 	 * @quirks: Hardware quirk information.
96 	 *
97 	 * Do not access this member directly, instead use PVR_HAS_QUIRK().
98 	 */
99 	struct pvr_device_quirks quirks;
100 
101 	/**
102 	 * @enhancements: Hardware enhancement information.
103 	 *
104 	 * Do not access this member directly, instead use
105 	 * PVR_HAS_ENHANCEMENT().
106 	 */
107 	struct pvr_device_enhancements enhancements;
108 
109 	/** @fw_version: Firmware version detected at runtime. */
110 	struct pvr_fw_version fw_version;
111 
112 	/** @device_data: Pointer to platform-specific data. */
113 	const struct pvr_device_data *device_data;
114 
115 	/** @regs_resource: Resource representing device control registers. */
116 	struct resource *regs_resource;
117 
118 	/**
119 	 * @regs: Device control registers.
120 	 *
121 	 * These are mapped into memory when the device is initialized; that
122 	 * location is where this pointer points.
123 	 */
124 	void __iomem *regs;
125 
126 	/**
127 	 * @core_clk: General core clock.
128 	 *
129 	 * This is the primary clock used by the entire GPU core.
130 	 */
131 	struct clk *core_clk;
132 
133 	/**
134 	 * @sys_clk: Optional system bus clock.
135 	 *
136 	 * This may be used on some platforms to provide an independent clock to the SoC Interface
137 	 * (SOCIF). If present, this needs to be enabled/disabled together with @core_clk.
138 	 */
139 	struct clk *sys_clk;
140 
141 	/**
142 	 * @mem_clk: Optional memory clock.
143 	 *
144 	 * This may be used on some platforms to provide an independent clock to the Memory
145 	 * Interface (MEMIF). If present, this needs to be enabled/disabled together with @core_clk.
146 	 */
147 	struct clk *mem_clk;
148 
149 	struct pvr_device_power {
150 		struct device **domain_devs;
151 		struct device_link **domain_links;
152 
153 		u32 domain_count;
154 	} power;
155 
156 	/**
157 	 * @reset: Optional reset line.
158 	 *
159 	 * This may be used on some platforms to provide a reset line that needs to be de-asserted
160 	 * after power-up procedure. It would also need to be asserted after the power-down
161 	 * procedure.
162 	 */
163 	struct reset_control *reset;
164 
165 	/** @pwrseq: Pointer to a power sequencer, if one is used. */
166 	struct pwrseq_desc *pwrseq;
167 
168 	/** @irq: IRQ number. */
169 	int irq;
170 
171 	/** @fwccb: Firmware CCB. */
172 	struct pvr_ccb fwccb;
173 
174 	/**
175 	 * @kernel_vm_ctx: Virtual memory context used for kernel mappings.
176 	 *
177 	 * This is used for mappings in the firmware address region when a META firmware processor
178 	 * is in use.
179 	 *
180 	 * When a MIPS firmware processor is in use, this will be %NULL.
181 	 */
182 	struct pvr_vm_context *kernel_vm_ctx;
183 
184 	/** @fw_dev: Firmware related data. */
185 	struct pvr_fw_device fw_dev;
186 
187 	/**
188 	 * @params: Device-specific parameters.
189 	 *
190 	 *          The values of these parameters are initialized from the
191 	 *          defaults specified as module parameters. They may be
192 	 *          modified at runtime via debugfs (if enabled).
193 	 */
194 	struct pvr_device_params params;
195 
196 	/** @stream_musthave_quirks: Bit array of "must-have" quirks for stream commands. */
197 	u32 stream_musthave_quirks[PVR_STREAM_TYPE_MAX][PVR_STREAM_EXTHDR_TYPE_MAX];
198 
199 	/**
200 	 * @mmu_flush_cache_flags: Records which MMU caches require flushing
201 	 * before submitting the next job.
202 	 */
203 	atomic_t mmu_flush_cache_flags;
204 
205 	/**
206 	 * @ctx_ids: Array of contexts belonging to this device. Array members
207 	 *           are of type "struct pvr_context *".
208 	 *
209 	 * This array is used to allocate IDs used by the firmware.
210 	 */
211 	struct xarray ctx_ids;
212 
213 	/**
214 	 * @free_list_ids: Array of free lists belonging to this device. Array members
215 	 *                 are of type "struct pvr_free_list *".
216 	 *
217 	 * This array is used to allocate IDs used by the firmware.
218 	 */
219 	struct xarray free_list_ids;
220 
221 	/**
222 	 * @job_ids: Array of jobs belonging to this device. Array members
223 	 *           are of type "struct pvr_job *".
224 	 */
225 	struct xarray job_ids;
226 
227 	/**
228 	 * @queues: Queue-related fields.
229 	 */
230 	struct {
231 		/** @queues.active: Active queue list. */
232 		struct list_head active;
233 
234 		/** @queues.idle: Idle queue list. */
235 		struct list_head idle;
236 
237 		/** @queues.lock: Lock protecting access to the active/idle
238 		 *  lists. */
239 		struct mutex lock;
240 	} queues;
241 
242 	/**
243 	 * @watchdog: Watchdog for communications with firmware.
244 	 */
245 	struct {
246 		/** @watchdog.work: Work item for watchdog callback. */
247 		struct delayed_work work;
248 
249 		/**
250 		 * @watchdog.old_kccb_cmds_executed: KCCB command execution
251 		 * count at last watchdog poll.
252 		 */
253 		u32 old_kccb_cmds_executed;
254 
255 		/**
256 		 * @watchdog.kccb_stall_count: Number of watchdog polls
257 		 * KCCB has been stalled for.
258 		 */
259 		u32 kccb_stall_count;
260 	} watchdog;
261 
262 	/**
263 	 * @kccb: Circular buffer for communications with firmware.
264 	 */
265 	struct {
266 		/** @kccb.ccb: Kernel CCB. */
267 		struct pvr_ccb ccb;
268 
269 		/** @kccb.rtn_q: Waitqueue for KCCB command return waiters. */
270 		wait_queue_head_t rtn_q;
271 
272 		/** @kccb.rtn_obj: Object representing KCCB return slots. */
273 		struct pvr_fw_object *rtn_obj;
274 
275 		/**
276 		 * @kccb.rtn: Pointer to CPU mapping of KCCB return slots.
277 		 * Must be accessed by READ_ONCE()/WRITE_ONCE().
278 		 */
279 		u32 *rtn;
280 
281 		/** @kccb.slot_count: Total number of KCCB slots available. */
282 		u32 slot_count;
283 
284 		/** @kccb.reserved_count: Number of KCCB slots reserved for
285 		 *  future use. */
286 		u32 reserved_count;
287 
288 		/**
289 		 * @kccb.waiters: List of KCCB slot waiters.
290 		 */
291 		struct list_head waiters;
292 
293 		/** @kccb.fence_ctx: KCCB fence context. */
294 		struct {
295 			/** @kccb.fence_ctx.id: KCCB fence context ID
296 			 *  allocated with dma_fence_context_alloc(). */
297 			u64 id;
298 
299 			/** @kccb.fence_ctx.seqno: Sequence number incremented
300 			 *  each time a fence is created. */
301 			atomic_t seqno;
302 
303 			/**
304 			 * @kccb.fence_ctx.lock: Lock used to synchronize
305 			 * access to fences allocated by this context.
306 			 */
307 			spinlock_t lock;
308 		} fence_ctx;
309 	} kccb;
310 
311 	/**
312 	 * @lost: %true if the device has been lost.
313 	 *
314 	 * This variable is set if the device has become irretrievably unavailable, e.g. if the
315 	 * firmware processor has stopped responding and can not be revived via a hard reset.
316 	 */
317 	bool lost;
318 
319 	/**
320 	 * @reset_sem: Reset semaphore.
321 	 *
322 	 * GPU reset code will lock this for writing. Any code that submits commands to the firmware
323 	 * that isn't in an IRQ handler or on the scheduler workqueue must lock this for reading.
324 	 * Once this has been successfully locked, &pvr_dev->lost _must_ be checked, and -%EIO must
325 	 * be returned if it is set.
326 	 */
327 	struct rw_semaphore reset_sem;
328 
329 	/** @sched_wq: Workqueue for schedulers. */
330 	struct workqueue_struct *sched_wq;
331 
332 	/**
333 	 * @ctx_list_lock: Lock to be held when accessing the context list in
334 	 *  struct pvr_file.
335 	 */
336 	spinlock_t ctx_list_lock;
337 
338 	/** @has_safety_events: Whether this device can raise safety events. */
339 	bool has_safety_events;
340 };
341 
342 /**
343  * struct pvr_file - powervr-specific data to be assigned to &struct
344  * drm_file.driver_priv
345  */
346 struct pvr_file {
347 	/**
348 	 * @file: A reference to the parent &struct drm_file.
349 	 *
350 	 * Do not access this member directly, instead call from_pvr_file().
351 	 */
352 	struct drm_file *file;
353 
354 	/**
355 	 * @pvr_dev: A reference to the powervr-specific wrapper for the
356 	 * associated device. Saves on repeated calls to to_pvr_device().
357 	 */
358 	struct pvr_device *pvr_dev;
359 
360 	/**
361 	 * @ctx_handles: Array of contexts belonging to this file. Array members
362 	 * are of type "struct pvr_context *".
363 	 *
364 	 * This array is used to allocate handles returned to userspace.
365 	 */
366 	struct xarray ctx_handles;
367 
368 	/**
369 	 * @free_list_handles: Array of free lists belonging to this file. Array
370 	 * members are of type "struct pvr_free_list *".
371 	 *
372 	 * This array is used to allocate handles returned to userspace.
373 	 */
374 	struct xarray free_list_handles;
375 
376 	/**
377 	 * @hwrt_handles: Array of HWRT datasets belonging to this file. Array
378 	 * members are of type "struct pvr_hwrt_dataset *".
379 	 *
380 	 * This array is used to allocate handles returned to userspace.
381 	 */
382 	struct xarray hwrt_handles;
383 
384 	/**
385 	 * @vm_ctx_handles: Array of VM contexts belonging to this file. Array
386 	 * members are of type "struct pvr_vm_context *".
387 	 *
388 	 * This array is used to allocate handles returned to userspace.
389 	 */
390 	struct xarray vm_ctx_handles;
391 
392 	/** @contexts: PVR context list. */
393 	struct list_head contexts;
394 };
395 
396 /**
397  * PVR_HAS_FEATURE() - Tests whether a PowerVR device has a given feature
398  * @pvr_dev: [IN] Target PowerVR device.
399  * @feature: [IN] Hardware feature name.
400  *
401  * Feature names are derived from those found in &struct pvr_device_features by
402  * dropping the 'has_' prefix, which is applied by this macro.
403  *
404  * Return:
405  *  * true if the named feature is present in the hardware
406  *  * false if the named feature is not present in the hardware
407  */
408 #define PVR_HAS_FEATURE(pvr_dev, feature) ((pvr_dev)->features.has_##feature)
409 
410 /**
411  * PVR_FEATURE_VALUE() - Gets a PowerVR device feature value
412  * @pvr_dev: [IN] Target PowerVR device.
413  * @feature: [IN] Feature name.
414  * @value_out: [OUT] Feature value.
415  *
416  * This macro will get a feature value for those features that have values.
417  * If the feature is not present, nothing will be stored to @value_out.
418  *
419  * Feature names are derived from those found in &struct pvr_device_features by
420  * dropping the 'has_' prefix.
421  *
422  * Return:
423  *  * 0 on success, or
424  *  * -%EINVAL if the named feature is not present in the hardware
425  */
426 #define PVR_FEATURE_VALUE(pvr_dev, feature, value_out)             \
427 	({                                                         \
428 		struct pvr_device *_pvr_dev = pvr_dev;             \
429 		int _ret = -EINVAL;                                \
430 		if (_pvr_dev->features.has_##feature) {            \
431 			*(value_out) = _pvr_dev->features.feature; \
432 			_ret = 0;                                  \
433 		}                                                  \
434 		_ret;                                              \
435 	})
436 
437 /**
438  * PVR_HAS_QUIRK() - Tests whether a physical device has a given quirk
439  * @pvr_dev: [IN] Target PowerVR device.
440  * @quirk: [IN] Hardware quirk name.
441  *
442  * Quirk numbers are derived from those found in #pvr_device_quirks by
443  * dropping the 'has_brn' prefix, which is applied by this macro.
444  *
445  * Returns
446  *  * true if the quirk is present in the hardware, or
447  *  * false if the quirk is not present in the hardware.
448  */
449 #define PVR_HAS_QUIRK(pvr_dev, quirk) ((pvr_dev)->quirks.has_brn##quirk)
450 
451 /**
452  * PVR_HAS_ENHANCEMENT() - Tests whether a physical device has a given
453  *                         enhancement
454  * @pvr_dev: [IN] Target PowerVR device.
455  * @enhancement: [IN] Hardware enhancement name.
456  *
457  * Enhancement numbers are derived from those found in #pvr_device_enhancements
458  * by dropping the 'has_ern' prefix, which is applied by this macro.
459  *
460  * Returns
461  *  * true if the enhancement is present in the hardware, or
462  *  * false if the enhancement is not present in the hardware.
463  */
464 #define PVR_HAS_ENHANCEMENT(pvr_dev, enhancement) ((pvr_dev)->enhancements.has_ern##enhancement)
465 
466 #define from_pvr_device(pvr_dev) (&(pvr_dev)->base)
467 
468 #define to_pvr_device(drm_dev) container_of_const(drm_dev, struct pvr_device, base)
469 
470 #define from_pvr_file(pvr_file) ((pvr_file)->file)
471 
472 #define to_pvr_file(file) ((file)->driver_priv)
473 
474 /**
475  * PVR_PACKED_BVNC() - Packs B, V, N and C values into a 64-bit unsigned integer
476  * @b: Branch ID.
477  * @v: Version ID.
478  * @n: Number of scalable units.
479  * @c: Config ID.
480  *
481  * The packed layout is as follows:
482  *
483  *    +--------+--------+--------+-------+
484  *    | 63..48 | 47..32 | 31..16 | 15..0 |
485  *    +========+========+========+=======+
486  *    | B      | V      | N      | C     |
487  *    +--------+--------+--------+-------+
488  *
489  * pvr_gpu_id_to_packed_bvnc() should be used instead of this macro when a
490  * &struct pvr_gpu_id is available in order to ensure proper type checking.
491  *
492  * Return: Packed BVNC.
493  */
494 /* clang-format off */
495 #define PVR_PACKED_BVNC(b, v, n, c) \
496 	((((u64)(b) & GENMASK_ULL(15, 0)) << 48) | \
497 	 (((u64)(v) & GENMASK_ULL(15, 0)) << 32) | \
498 	 (((u64)(n) & GENMASK_ULL(15, 0)) << 16) | \
499 	 (((u64)(c) & GENMASK_ULL(15, 0)) <<  0))
500 /* clang-format on */
501 
502 /**
503  * pvr_gpu_id_to_packed_bvnc() - Packs B, V, N and C values into a 64-bit
504  * unsigned integer
505  * @gpu_id: GPU ID.
506  *
507  * The packed layout is as follows:
508  *
509  *    +--------+--------+--------+-------+
510  *    | 63..48 | 47..32 | 31..16 | 15..0 |
511  *    +========+========+========+=======+
512  *    | B      | V      | N      | C     |
513  *    +--------+--------+--------+-------+
514  *
515  * This should be used in preference to PVR_PACKED_BVNC() when a &struct
516  * pvr_gpu_id is available in order to ensure proper type checking.
517  *
518  * Return: Packed BVNC.
519  */
520 static __always_inline u64
521 pvr_gpu_id_to_packed_bvnc(struct pvr_gpu_id *gpu_id)
522 {
523 	return PVR_PACKED_BVNC(gpu_id->b, gpu_id->v, gpu_id->n, gpu_id->c);
524 }
525 
526 static __always_inline void
527 packed_bvnc_to_pvr_gpu_id(u64 bvnc, struct pvr_gpu_id *gpu_id)
528 {
529 	gpu_id->b = (bvnc & GENMASK_ULL(63, 48)) >> 48;
530 	gpu_id->v = (bvnc & GENMASK_ULL(47, 32)) >> 32;
531 	gpu_id->n = (bvnc & GENMASK_ULL(31, 16)) >> 16;
532 	gpu_id->c = bvnc & GENMASK_ULL(15, 0);
533 }
534 
535 int pvr_device_init(struct pvr_device *pvr_dev);
536 void pvr_device_fini(struct pvr_device *pvr_dev);
537 void pvr_device_reset(struct pvr_device *pvr_dev);
538 
539 bool
540 pvr_device_has_uapi_quirk(struct pvr_device *pvr_dev, u32 quirk);
541 bool
542 pvr_device_has_uapi_enhancement(struct pvr_device *pvr_dev, u32 enhancement);
543 bool
544 pvr_device_has_feature(struct pvr_device *pvr_dev, u32 feature);
545 
546 /**
547  * PVR_CR_FIELD_GET() - Extract a single field from a PowerVR control register
548  * @val: Value of the target register.
549  * @field: Field specifier, as defined in "pvr_rogue_cr_defs.h".
550  *
551  * Return: The extracted field.
552  */
553 #define PVR_CR_FIELD_GET(val, field) FIELD_GET(~ROGUE_CR_##field##_CLRMSK, val)
554 
555 /**
556  * pvr_cr_read32() - Read a 32-bit register from a PowerVR device
557  * @pvr_dev: Target PowerVR device.
558  * @reg: Target register.
559  *
560  * Return: The value of the requested register.
561  */
562 static __always_inline u32
563 pvr_cr_read32(struct pvr_device *pvr_dev, u32 reg)
564 {
565 	return ioread32(pvr_dev->regs + reg);
566 }
567 
568 /**
569  * pvr_cr_read64() - Read a 64-bit register from a PowerVR device
570  * @pvr_dev: Target PowerVR device.
571  * @reg: Target register.
572  *
573  * Return: The value of the requested register.
574  */
575 static __always_inline u64
576 pvr_cr_read64(struct pvr_device *pvr_dev, u32 reg)
577 {
578 	return ioread64(pvr_dev->regs + reg);
579 }
580 
581 /**
582  * pvr_cr_write32() - Write to a 32-bit register in a PowerVR device
583  * @pvr_dev: Target PowerVR device.
584  * @reg: Target register.
585  * @val: Value to write.
586  */
587 static __always_inline void
588 pvr_cr_write32(struct pvr_device *pvr_dev, u32 reg, u32 val)
589 {
590 	iowrite32(val, pvr_dev->regs + reg);
591 }
592 
593 /**
594  * pvr_cr_write64() - Write to a 64-bit register in a PowerVR device
595  * @pvr_dev: Target PowerVR device.
596  * @reg: Target register.
597  * @val: Value to write.
598  */
599 static __always_inline void
600 pvr_cr_write64(struct pvr_device *pvr_dev, u32 reg, u64 val)
601 {
602 	iowrite64(val, pvr_dev->regs + reg);
603 }
604 
605 /**
606  * pvr_cr_poll_reg32() - Wait for a 32-bit register to match a given value by
607  *                       polling
608  * @pvr_dev: Target PowerVR device.
609  * @reg_addr: Address of register.
610  * @reg_value: Expected register value (after masking).
611  * @reg_mask: Mask of bits valid for comparison with @reg_value.
612  * @timeout_usec: Timeout length, in us.
613  *
614  * Returns:
615  *  * 0 on success, or
616  *  * -%ETIMEDOUT on timeout.
617  */
618 static __always_inline int
619 pvr_cr_poll_reg32(struct pvr_device *pvr_dev, u32 reg_addr, u32 reg_value,
620 		  u32 reg_mask, u64 timeout_usec)
621 {
622 	u32 value;
623 
624 	return readl_poll_timeout(pvr_dev->regs + reg_addr, value,
625 		(value & reg_mask) == reg_value, 0, timeout_usec);
626 }
627 
628 /**
629  * pvr_cr_poll_reg64() - Wait for a 64-bit register to match a given value by
630  *                       polling
631  * @pvr_dev: Target PowerVR device.
632  * @reg_addr: Address of register.
633  * @reg_value: Expected register value (after masking).
634  * @reg_mask: Mask of bits valid for comparison with @reg_value.
635  * @timeout_usec: Timeout length, in us.
636  *
637  * Returns:
638  *  * 0 on success, or
639  *  * -%ETIMEDOUT on timeout.
640  */
641 static __always_inline int
642 pvr_cr_poll_reg64(struct pvr_device *pvr_dev, u32 reg_addr, u64 reg_value,
643 		  u64 reg_mask, u64 timeout_usec)
644 {
645 	u64 value;
646 
647 	return readq_poll_timeout(pvr_dev->regs + reg_addr, value,
648 		(value & reg_mask) == reg_value, 0, timeout_usec);
649 }
650 
651 /**
652  * pvr_round_up_to_cacheline_size() - Round up a provided size to be cacheline
653  *                                    aligned
654  * @pvr_dev: Target PowerVR device.
655  * @size: Initial size, in bytes.
656  *
657  * Returns:
658  *  * Size aligned to cacheline size.
659  */
660 static __always_inline size_t
661 pvr_round_up_to_cacheline_size(struct pvr_device *pvr_dev, size_t size)
662 {
663 	u16 slc_cacheline_size_bits = 0;
664 	u16 slc_cacheline_size_bytes;
665 
666 	WARN_ON(!PVR_HAS_FEATURE(pvr_dev, slc_cache_line_size_bits));
667 	PVR_FEATURE_VALUE(pvr_dev, slc_cache_line_size_bits,
668 			  &slc_cacheline_size_bits);
669 	slc_cacheline_size_bytes = slc_cacheline_size_bits / 8;
670 
671 	return round_up(size, slc_cacheline_size_bytes);
672 }
673 
674 /**
675  * DOC: IOCTL validation helpers
676  *
677  * To validate the constraints imposed on IOCTL argument structs, a collection
678  * of macros and helper functions exist in ``pvr_device.h``.
679  *
680  * Of the current helpers, it should only be necessary to call
681  * PVR_IOCTL_UNION_PADDING_CHECK() directly. This macro should be used once in
682  * every code path which extracts a union member from a struct passed from
683  * userspace.
684  */
685 
686 /**
687  * pvr_ioctl_union_padding_check() - Validate that the implicit padding between
688  * the end of a union member and the end of the union itself is zeroed.
689  * @instance: Pointer to the instance of the struct to validate.
690  * @union_offset: Offset into the type of @instance of the target union. Must
691  * be 64-bit aligned.
692  * @union_size: Size of the target union in the type of @instance. Must be
693  * 64-bit aligned.
694  * @member_size: Size of the target member in the target union specified by
695  * @union_offset and @union_size. It is assumed that the offset of the target
696  * member is zero relative to @union_offset. Must be 64-bit aligned.
697  *
698  * You probably want to use PVR_IOCTL_UNION_PADDING_CHECK() instead of calling
699  * this function directly, since that macro abstracts away much of the setup,
700  * and also provides some static validation. See its docs for details.
701  *
702  * Return:
703  *  * %true if every byte between the end of the used member of the union and
704  *    the end of that union is zeroed, or
705  *  * %false otherwise.
706  */
707 static __always_inline bool
708 pvr_ioctl_union_padding_check(void *instance, size_t union_offset,
709 			      size_t union_size, size_t member_size)
710 {
711 	/*
712 	 * void pointer arithmetic is technically illegal - cast to a byte
713 	 * pointer so this addition works safely.
714 	 */
715 	void *padding_start = ((u8 *)instance) + union_offset + member_size;
716 	size_t padding_size = union_size - member_size;
717 
718 	return mem_is_zero(padding_start, padding_size);
719 }
720 
721 /**
722  * PVR_STATIC_ASSERT_64BIT_ALIGNED() - Inline assertion for 64-bit alignment.
723  * @static_expr_: Target expression to evaluate.
724  *
725  * If @static_expr_ does not evaluate to a constant integer which would be a
726  * 64-bit aligned address (i.e. a multiple of 8), compilation will fail.
727  *
728  * Return:
729  * The value of @static_expr_.
730  */
731 #define PVR_STATIC_ASSERT_64BIT_ALIGNED(static_expr_)                     \
732 	({                                                                \
733 		static_assert(((static_expr_) & (sizeof(u64) - 1)) == 0); \
734 		(static_expr_);                                           \
735 	})
736 
737 /**
738  * PVR_IOCTL_UNION_PADDING_CHECK() - Validate that the implicit padding between
739  * the end of a union member and the end of the union itself is zeroed.
740  * @struct_instance_: An expression which evaluates to a pointer to a UAPI data
741  * struct.
742  * @union_: The name of the union member of @struct_instance_ to check. If the
743  * union member is nested within the type of @struct_instance_, this may
744  * contain the member access operator (".").
745  * @member_: The name of the member of @union_ to assess.
746  *
747  * This is a wrapper around pvr_ioctl_union_padding_check() which performs
748  * alignment checks and simplifies things for the caller.
749  *
750  * Return:
751  *  * %true if every byte in @struct_instance_ between the end of @member_ and
752  *    the end of @union_ is zeroed, or
753  *  * %false otherwise.
754  */
755 #define PVR_IOCTL_UNION_PADDING_CHECK(struct_instance_, union_, member_)     \
756 	({                                                                   \
757 		typeof(struct_instance_) __instance = (struct_instance_);    \
758 		size_t __union_offset = PVR_STATIC_ASSERT_64BIT_ALIGNED(     \
759 			offsetof(typeof(*__instance), union_));              \
760 		size_t __union_size = PVR_STATIC_ASSERT_64BIT_ALIGNED(       \
761 			sizeof(__instance->union_));                         \
762 		size_t __member_size = PVR_STATIC_ASSERT_64BIT_ALIGNED(      \
763 			sizeof(__instance->union_.member_));                 \
764 		pvr_ioctl_union_padding_check(__instance, __union_offset,    \
765 					      __union_size, __member_size);  \
766 	})
767 
768 /*
769  * These utility functions should more properly be placed in pvr_fw.h, but that
770  * would cause a dependency cycle between that header and this one. Since
771  * they're primarily used in pvr_device.c, let's put them in here for now.
772  */
773 
774 static __always_inline bool
775 pvr_fw_irq_pending(struct pvr_device *pvr_dev)
776 {
777 	return pvr_dev->fw_dev.defs->irq_pending(pvr_dev);
778 }
779 
780 static __always_inline void
781 pvr_fw_irq_clear(struct pvr_device *pvr_dev)
782 {
783 	pvr_dev->fw_dev.defs->irq_clear(pvr_dev);
784 }
785 
786 #endif /* PVR_DEVICE_H */
787