File Index
Files and directories
Sign in
FILE

pvr_device.h

File preview with syntax highlighting.

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