xref: /linux/drivers/gpu/drm/imagination/pvr_device.h (revision 952a33dc08cefde50540cc82abaa2e09f37ef540)
14babef07SSarah Walker /* SPDX-License-Identifier: GPL-2.0-only OR MIT */
24babef07SSarah Walker /* Copyright (c) 2023 Imagination Technologies Ltd. */
34babef07SSarah Walker 
44babef07SSarah Walker #ifndef PVR_DEVICE_H
54babef07SSarah Walker #define PVR_DEVICE_H
64babef07SSarah Walker 
7cc1aeedbSSarah Walker #include "pvr_ccb.h"
8f99f5f3eSSarah Walker #include "pvr_device_info.h"
9f99f5f3eSSarah Walker #include "pvr_fw.h"
10cb56cd61SSarah Walker #include "pvr_params.h"
11d2d79d29SSarah Walker #include "pvr_rogue_fwif_stream.h"
12d2d79d29SSarah Walker #include "pvr_stream.h"
13f99f5f3eSSarah Walker 
144babef07SSarah Walker #include <drm/drm_device.h>
154babef07SSarah Walker #include <drm/drm_file.h>
164babef07SSarah Walker #include <drm/drm_mm.h>
174babef07SSarah Walker 
184babef07SSarah Walker #include <linux/bits.h>
194babef07SSarah Walker #include <linux/compiler_attributes.h>
204babef07SSarah Walker #include <linux/compiler_types.h>
211f88f017SSarah Walker #include <linux/io.h>
221f88f017SSarah Walker #include <linux/iopoll.h>
234babef07SSarah Walker #include <linux/kernel.h>
241f88f017SSarah Walker #include <linux/math.h>
251f88f017SSarah Walker #include <linux/mutex.h>
26*b0ef514bSBrendan King #include <linux/spinlock_types.h>
271f88f017SSarah Walker #include <linux/timer.h>
284babef07SSarah Walker #include <linux/types.h>
294babef07SSarah Walker #include <linux/wait.h>
301f88f017SSarah Walker #include <linux/workqueue.h>
311f88f017SSarah Walker #include <linux/xarray.h>
321f88f017SSarah Walker 
331f88f017SSarah Walker /* Forward declaration from <linux/clk.h>. */
341f88f017SSarah Walker struct clk;
351f88f017SSarah Walker 
361f88f017SSarah Walker /* Forward declaration from <linux/firmware.h>. */
371f88f017SSarah Walker struct firmware;
384babef07SSarah Walker 
394babef07SSarah Walker /**
40f99f5f3eSSarah Walker  * struct pvr_gpu_id - Hardware GPU ID information for a PowerVR device
41f99f5f3eSSarah Walker  * @b: Branch ID.
42f99f5f3eSSarah Walker  * @v: Version ID.
43f99f5f3eSSarah Walker  * @n: Number of scalable units.
44f99f5f3eSSarah Walker  * @c: Config ID.
45f99f5f3eSSarah Walker  */
46f99f5f3eSSarah Walker struct pvr_gpu_id {
47f99f5f3eSSarah Walker 	u16 b, v, n, c;
48f99f5f3eSSarah Walker };
49f99f5f3eSSarah Walker 
50f99f5f3eSSarah Walker /**
51f99f5f3eSSarah Walker  * struct pvr_fw_version - Firmware version information
52f99f5f3eSSarah Walker  * @major: Major version number.
53f99f5f3eSSarah Walker  * @minor: Minor version number.
54f99f5f3eSSarah Walker  */
55f99f5f3eSSarah Walker struct pvr_fw_version {
56f99f5f3eSSarah Walker 	u16 major, minor;
57f99f5f3eSSarah Walker };
58f99f5f3eSSarah Walker 
59f99f5f3eSSarah Walker /**
604babef07SSarah Walker  * struct pvr_device - powervr-specific wrapper for &struct drm_device
614babef07SSarah Walker  */
624babef07SSarah Walker struct pvr_device {
634babef07SSarah Walker 	/**
644babef07SSarah Walker 	 * @base: The underlying &struct drm_device.
654babef07SSarah Walker 	 *
664babef07SSarah Walker 	 * Do not access this member directly, instead call
674babef07SSarah Walker 	 * from_pvr_device().
684babef07SSarah Walker 	 */
694babef07SSarah Walker 	struct drm_device base;
701f88f017SSarah Walker 
71f99f5f3eSSarah Walker 	/** @gpu_id: GPU ID detected at runtime. */
72f99f5f3eSSarah Walker 	struct pvr_gpu_id gpu_id;
73f99f5f3eSSarah Walker 
74f99f5f3eSSarah Walker 	/**
75f99f5f3eSSarah Walker 	 * @features: Hardware feature information.
76f99f5f3eSSarah Walker 	 *
77f99f5f3eSSarah Walker 	 * Do not access this member directly, instead use PVR_HAS_FEATURE()
78f99f5f3eSSarah Walker 	 * or PVR_FEATURE_VALUE() macros.
79f99f5f3eSSarah Walker 	 */
80f99f5f3eSSarah Walker 	struct pvr_device_features features;
81f99f5f3eSSarah Walker 
82f99f5f3eSSarah Walker 	/**
83f99f5f3eSSarah Walker 	 * @quirks: Hardware quirk information.
84f99f5f3eSSarah Walker 	 *
85f99f5f3eSSarah Walker 	 * Do not access this member directly, instead use PVR_HAS_QUIRK().
86f99f5f3eSSarah Walker 	 */
87f99f5f3eSSarah Walker 	struct pvr_device_quirks quirks;
88f99f5f3eSSarah Walker 
89f99f5f3eSSarah Walker 	/**
90f99f5f3eSSarah Walker 	 * @enhancements: Hardware enhancement information.
91f99f5f3eSSarah Walker 	 *
92f99f5f3eSSarah Walker 	 * Do not access this member directly, instead use
93f99f5f3eSSarah Walker 	 * PVR_HAS_ENHANCEMENT().
94f99f5f3eSSarah Walker 	 */
95f99f5f3eSSarah Walker 	struct pvr_device_enhancements enhancements;
96f99f5f3eSSarah Walker 
97f99f5f3eSSarah Walker 	/** @fw_version: Firmware version detected at runtime. */
98f99f5f3eSSarah Walker 	struct pvr_fw_version fw_version;
99f99f5f3eSSarah Walker 
100927f3e02SSarah Walker 	/** @regs_resource: Resource representing device control registers. */
101927f3e02SSarah Walker 	struct resource *regs_resource;
102927f3e02SSarah Walker 
1031f88f017SSarah Walker 	/**
1041f88f017SSarah Walker 	 * @regs: Device control registers.
1051f88f017SSarah Walker 	 *
1061f88f017SSarah Walker 	 * These are mapped into memory when the device is initialized; that
1071f88f017SSarah Walker 	 * location is where this pointer points.
1081f88f017SSarah Walker 	 */
1091f88f017SSarah Walker 	void __iomem *regs;
1101f88f017SSarah Walker 
1111f88f017SSarah Walker 	/**
1121f88f017SSarah Walker 	 * @core_clk: General core clock.
1131f88f017SSarah Walker 	 *
1141f88f017SSarah Walker 	 * This is the primary clock used by the entire GPU core.
1151f88f017SSarah Walker 	 */
1161f88f017SSarah Walker 	struct clk *core_clk;
1171f88f017SSarah Walker 
1181f88f017SSarah Walker 	/**
1191f88f017SSarah Walker 	 * @sys_clk: Optional system bus clock.
1201f88f017SSarah Walker 	 *
1211f88f017SSarah Walker 	 * This may be used on some platforms to provide an independent clock to the SoC Interface
1221f88f017SSarah Walker 	 * (SOCIF). If present, this needs to be enabled/disabled together with @core_clk.
1231f88f017SSarah Walker 	 */
1241f88f017SSarah Walker 	struct clk *sys_clk;
1251f88f017SSarah Walker 
1261f88f017SSarah Walker 	/**
1271f88f017SSarah Walker 	 * @mem_clk: Optional memory clock.
1281f88f017SSarah Walker 	 *
1291f88f017SSarah Walker 	 * This may be used on some platforms to provide an independent clock to the Memory
1301f88f017SSarah Walker 	 * Interface (MEMIF). If present, this needs to be enabled/disabled together with @core_clk.
1311f88f017SSarah Walker 	 */
1321f88f017SSarah Walker 	struct clk *mem_clk;
133f99f5f3eSSarah Walker 
134cc1aeedbSSarah Walker 	/** @irq: IRQ number. */
135cc1aeedbSSarah Walker 	int irq;
136cc1aeedbSSarah Walker 
137cc1aeedbSSarah Walker 	/** @fwccb: Firmware CCB. */
138cc1aeedbSSarah Walker 	struct pvr_ccb fwccb;
139cc1aeedbSSarah Walker 
140ff5f643dSDonald Robson 	/**
141ff5f643dSDonald Robson 	 * @kernel_vm_ctx: Virtual memory context used for kernel mappings.
142ff5f643dSDonald Robson 	 *
143ff5f643dSDonald Robson 	 * This is used for mappings in the firmware address region when a META firmware processor
144ff5f643dSDonald Robson 	 * is in use.
145ff5f643dSDonald Robson 	 *
146ff5f643dSDonald Robson 	 * When a MIPS firmware processor is in use, this will be %NULL.
147ff5f643dSDonald Robson 	 */
148ff5f643dSDonald Robson 	struct pvr_vm_context *kernel_vm_ctx;
149ff5f643dSDonald Robson 
150f99f5f3eSSarah Walker 	/** @fw_dev: Firmware related data. */
151f99f5f3eSSarah Walker 	struct pvr_fw_device fw_dev;
152ff5f643dSDonald Robson 
153cb56cd61SSarah Walker 	/**
154cb56cd61SSarah Walker 	 * @params: Device-specific parameters.
155cb56cd61SSarah Walker 	 *
156cb56cd61SSarah Walker 	 *          The values of these parameters are initialized from the
157cb56cd61SSarah Walker 	 *          defaults specified as module parameters. They may be
158cb56cd61SSarah Walker 	 *          modified at runtime via debugfs (if enabled).
159cb56cd61SSarah Walker 	 */
160cb56cd61SSarah Walker 	struct pvr_device_params params;
161cb56cd61SSarah Walker 
162d2d79d29SSarah Walker 	/** @stream_musthave_quirks: Bit array of "must-have" quirks for stream commands. */
163d2d79d29SSarah Walker 	u32 stream_musthave_quirks[PVR_STREAM_TYPE_MAX][PVR_STREAM_EXTHDR_TYPE_MAX];
164d2d79d29SSarah Walker 
165ff5f643dSDonald Robson 	/**
166ff5f643dSDonald Robson 	 * @mmu_flush_cache_flags: Records which MMU caches require flushing
167ff5f643dSDonald Robson 	 * before submitting the next job.
168ff5f643dSDonald Robson 	 */
169ff5f643dSDonald Robson 	atomic_t mmu_flush_cache_flags;
170727538a4SSarah Walker 
1716eedddabSSarah Walker 	/**
172d2d79d29SSarah Walker 	 * @ctx_ids: Array of contexts belonging to this device. Array members
173d2d79d29SSarah Walker 	 *           are of type "struct pvr_context *".
174d2d79d29SSarah Walker 	 *
175d2d79d29SSarah Walker 	 * This array is used to allocate IDs used by the firmware.
176d2d79d29SSarah Walker 	 */
177d2d79d29SSarah Walker 	struct xarray ctx_ids;
178d2d79d29SSarah Walker 
179d2d79d29SSarah Walker 	/**
1806eedddabSSarah Walker 	 * @free_list_ids: Array of free lists belonging to this device. Array members
1816eedddabSSarah Walker 	 *                 are of type "struct pvr_free_list *".
1826eedddabSSarah Walker 	 *
1836eedddabSSarah Walker 	 * This array is used to allocate IDs used by the firmware.
1846eedddabSSarah Walker 	 */
1856eedddabSSarah Walker 	struct xarray free_list_ids;
1866eedddabSSarah Walker 
187eaf01ee5SSarah Walker 	/**
188eaf01ee5SSarah Walker 	 * @job_ids: Array of jobs belonging to this device. Array members
189eaf01ee5SSarah Walker 	 *           are of type "struct pvr_job *".
190eaf01ee5SSarah Walker 	 */
191eaf01ee5SSarah Walker 	struct xarray job_ids;
192eaf01ee5SSarah Walker 
193eaf01ee5SSarah Walker 	/**
194eaf01ee5SSarah Walker 	 * @queues: Queue-related fields.
195eaf01ee5SSarah Walker 	 */
196eaf01ee5SSarah Walker 	struct {
197eee70683SRandy Dunlap 		/** @queues.active: Active queue list. */
198eaf01ee5SSarah Walker 		struct list_head active;
199eaf01ee5SSarah Walker 
200eee70683SRandy Dunlap 		/** @queues.idle: Idle queue list. */
201eaf01ee5SSarah Walker 		struct list_head idle;
202eaf01ee5SSarah Walker 
203eee70683SRandy Dunlap 		/** @queues.lock: Lock protecting access to the active/idle
204eee70683SRandy Dunlap 		 *  lists. */
205eaf01ee5SSarah Walker 		struct mutex lock;
206eaf01ee5SSarah Walker 	} queues;
207eaf01ee5SSarah Walker 
2083cc808e3SDonald Robson 	/**
2093cc808e3SDonald Robson 	 * @watchdog: Watchdog for communications with firmware.
2103cc808e3SDonald Robson 	 */
211727538a4SSarah Walker 	struct {
212eee70683SRandy Dunlap 		/** @watchdog.work: Work item for watchdog callback. */
213727538a4SSarah Walker 		struct delayed_work work;
214727538a4SSarah Walker 
2153cc808e3SDonald Robson 		/**
216eee70683SRandy Dunlap 		 * @watchdog.old_kccb_cmds_executed: KCCB command execution
217eee70683SRandy Dunlap 		 * count at last watchdog poll.
2183cc808e3SDonald Robson 		 */
219727538a4SSarah Walker 		u32 old_kccb_cmds_executed;
220727538a4SSarah Walker 
2213cc808e3SDonald Robson 		/**
222eee70683SRandy Dunlap 		 * @watchdog.kccb_stall_count: Number of watchdog polls
223eee70683SRandy Dunlap 		 * KCCB has been stalled for.
2243cc808e3SDonald Robson 		 */
225727538a4SSarah Walker 		u32 kccb_stall_count;
226727538a4SSarah Walker 	} watchdog;
227727538a4SSarah Walker 
2283cc808e3SDonald Robson 	/**
2293cc808e3SDonald Robson 	 * @kccb: Circular buffer for communications with firmware.
2303cc808e3SDonald Robson 	 */
231cc1aeedbSSarah Walker 	struct {
232eee70683SRandy Dunlap 		/** @kccb.ccb: Kernel CCB. */
233cc1aeedbSSarah Walker 		struct pvr_ccb ccb;
234cc1aeedbSSarah Walker 
235eee70683SRandy Dunlap 		/** @kccb.rtn_q: Waitqueue for KCCB command return waiters. */
236cc1aeedbSSarah Walker 		wait_queue_head_t rtn_q;
237cc1aeedbSSarah Walker 
238eee70683SRandy Dunlap 		/** @kccb.rtn_obj: Object representing KCCB return slots. */
239cc1aeedbSSarah Walker 		struct pvr_fw_object *rtn_obj;
240cc1aeedbSSarah Walker 
241cc1aeedbSSarah Walker 		/**
242eee70683SRandy Dunlap 		 * @kccb.rtn: Pointer to CPU mapping of KCCB return slots.
243eee70683SRandy Dunlap 		 * Must be accessed by READ_ONCE()/WRITE_ONCE().
244cc1aeedbSSarah Walker 		 */
245cc1aeedbSSarah Walker 		u32 *rtn;
246cc1aeedbSSarah Walker 
247eee70683SRandy Dunlap 		/** @kccb.slot_count: Total number of KCCB slots available. */
248cc1aeedbSSarah Walker 		u32 slot_count;
249cc1aeedbSSarah Walker 
250eee70683SRandy Dunlap 		/** @kccb.reserved_count: Number of KCCB slots reserved for
251eee70683SRandy Dunlap 		 *  future use. */
252cc1aeedbSSarah Walker 		u32 reserved_count;
253cc1aeedbSSarah Walker 
254cc1aeedbSSarah Walker 		/**
255eee70683SRandy Dunlap 		 * @kccb.waiters: List of KCCB slot waiters.
256cc1aeedbSSarah Walker 		 */
257cc1aeedbSSarah Walker 		struct list_head waiters;
258cc1aeedbSSarah Walker 
259eee70683SRandy Dunlap 		/** @kccb.fence_ctx: KCCB fence context. */
260cc1aeedbSSarah Walker 		struct {
261eee70683SRandy Dunlap 			/** @kccb.fence_ctx.id: KCCB fence context ID
262eee70683SRandy Dunlap 			 *  allocated with dma_fence_context_alloc(). */
263cc1aeedbSSarah Walker 			u64 id;
264cc1aeedbSSarah Walker 
265eee70683SRandy Dunlap 			/** @kccb.fence_ctx.seqno: Sequence number incremented
266eee70683SRandy Dunlap 			 *  each time a fence is created. */
267cc1aeedbSSarah Walker 			atomic_t seqno;
268cc1aeedbSSarah Walker 
269cc1aeedbSSarah Walker 			/**
270eee70683SRandy Dunlap 			 * @kccb.fence_ctx.lock: Lock used to synchronize
271eee70683SRandy Dunlap 			 * access to fences allocated by this context.
272cc1aeedbSSarah Walker 			 */
273cc1aeedbSSarah Walker 			spinlock_t lock;
274cc1aeedbSSarah Walker 		} fence_ctx;
275cc1aeedbSSarah Walker 	} kccb;
276cc1aeedbSSarah Walker 
277727538a4SSarah Walker 	/**
278727538a4SSarah Walker 	 * @lost: %true if the device has been lost.
279727538a4SSarah Walker 	 *
280727538a4SSarah Walker 	 * This variable is set if the device has become irretrievably unavailable, e.g. if the
281727538a4SSarah Walker 	 * firmware processor has stopped responding and can not be revived via a hard reset.
282727538a4SSarah Walker 	 */
283727538a4SSarah Walker 	bool lost;
284727538a4SSarah Walker 
285cc1aeedbSSarah Walker 	/**
286cc1aeedbSSarah Walker 	 * @reset_sem: Reset semaphore.
287cc1aeedbSSarah Walker 	 *
288cc1aeedbSSarah Walker 	 * GPU reset code will lock this for writing. Any code that submits commands to the firmware
289cc1aeedbSSarah Walker 	 * that isn't in an IRQ handler or on the scheduler workqueue must lock this for reading.
290cc1aeedbSSarah Walker 	 * Once this has been successfully locked, &pvr_dev->lost _must_ be checked, and -%EIO must
291cc1aeedbSSarah Walker 	 * be returned if it is set.
292cc1aeedbSSarah Walker 	 */
293cc1aeedbSSarah Walker 	struct rw_semaphore reset_sem;
294cc1aeedbSSarah Walker 
295727538a4SSarah Walker 	/** @sched_wq: Workqueue for schedulers. */
296727538a4SSarah Walker 	struct workqueue_struct *sched_wq;
297*b0ef514bSBrendan King 
298*b0ef514bSBrendan King 	/**
299*b0ef514bSBrendan King 	 * @ctx_list_lock: Lock to be held when accessing the context list in
300*b0ef514bSBrendan King 	 *  struct pvr_file.
301*b0ef514bSBrendan King 	 */
302*b0ef514bSBrendan King 	spinlock_t ctx_list_lock;
3034babef07SSarah Walker };
3044babef07SSarah Walker 
3054babef07SSarah Walker /**
3064babef07SSarah Walker  * struct pvr_file - powervr-specific data to be assigned to &struct
3074babef07SSarah Walker  * drm_file.driver_priv
3084babef07SSarah Walker  */
3094babef07SSarah Walker struct pvr_file {
3104babef07SSarah Walker 	/**
3114babef07SSarah Walker 	 * @file: A reference to the parent &struct drm_file.
3124babef07SSarah Walker 	 *
3134babef07SSarah Walker 	 * Do not access this member directly, instead call from_pvr_file().
3144babef07SSarah Walker 	 */
3154babef07SSarah Walker 	struct drm_file *file;
3164babef07SSarah Walker 
3174babef07SSarah Walker 	/**
3184babef07SSarah Walker 	 * @pvr_dev: A reference to the powervr-specific wrapper for the
3193cc808e3SDonald Robson 	 * associated device. Saves on repeated calls to to_pvr_device().
3204babef07SSarah Walker 	 */
3214babef07SSarah Walker 	struct pvr_device *pvr_dev;
322ff5f643dSDonald Robson 
323ff5f643dSDonald Robson 	/**
324d2d79d29SSarah Walker 	 * @ctx_handles: Array of contexts belonging to this file. Array members
325d2d79d29SSarah Walker 	 * are of type "struct pvr_context *".
326d2d79d29SSarah Walker 	 *
327d2d79d29SSarah Walker 	 * This array is used to allocate handles returned to userspace.
328d2d79d29SSarah Walker 	 */
329d2d79d29SSarah Walker 	struct xarray ctx_handles;
330d2d79d29SSarah Walker 
331d2d79d29SSarah Walker 	/**
3326eedddabSSarah Walker 	 * @free_list_handles: Array of free lists belonging to this file. Array
3336eedddabSSarah Walker 	 * members are of type "struct pvr_free_list *".
3346eedddabSSarah Walker 	 *
3356eedddabSSarah Walker 	 * This array is used to allocate handles returned to userspace.
3366eedddabSSarah Walker 	 */
3376eedddabSSarah Walker 	struct xarray free_list_handles;
3386eedddabSSarah Walker 
3396eedddabSSarah Walker 	/**
3406eedddabSSarah Walker 	 * @hwrt_handles: Array of HWRT datasets belonging to this file. Array
3416eedddabSSarah Walker 	 * members are of type "struct pvr_hwrt_dataset *".
3426eedddabSSarah Walker 	 *
3436eedddabSSarah Walker 	 * This array is used to allocate handles returned to userspace.
3446eedddabSSarah Walker 	 */
3456eedddabSSarah Walker 	struct xarray hwrt_handles;
3466eedddabSSarah Walker 
3476eedddabSSarah Walker 	/**
348ff5f643dSDonald Robson 	 * @vm_ctx_handles: Array of VM contexts belonging to this file. Array
349ff5f643dSDonald Robson 	 * members are of type "struct pvr_vm_context *".
350ff5f643dSDonald Robson 	 *
351ff5f643dSDonald Robson 	 * This array is used to allocate handles returned to userspace.
352ff5f643dSDonald Robson 	 */
353ff5f643dSDonald Robson 	struct xarray vm_ctx_handles;
354*b0ef514bSBrendan King 
355*b0ef514bSBrendan King 	/** @contexts: PVR context list. */
356*b0ef514bSBrendan King 	struct list_head contexts;
3574babef07SSarah Walker };
3584babef07SSarah Walker 
359f99f5f3eSSarah Walker /**
360f99f5f3eSSarah Walker  * PVR_HAS_FEATURE() - Tests whether a PowerVR device has a given feature
361f99f5f3eSSarah Walker  * @pvr_dev: [IN] Target PowerVR device.
362f99f5f3eSSarah Walker  * @feature: [IN] Hardware feature name.
363f99f5f3eSSarah Walker  *
364f99f5f3eSSarah Walker  * Feature names are derived from those found in &struct pvr_device_features by
365f99f5f3eSSarah Walker  * dropping the 'has_' prefix, which is applied by this macro.
366f99f5f3eSSarah Walker  *
367f99f5f3eSSarah Walker  * Return:
368f99f5f3eSSarah Walker  *  * true if the named feature is present in the hardware
369f99f5f3eSSarah Walker  *  * false if the named feature is not present in the hardware
370f99f5f3eSSarah Walker  */
371f99f5f3eSSarah Walker #define PVR_HAS_FEATURE(pvr_dev, feature) ((pvr_dev)->features.has_##feature)
372f99f5f3eSSarah Walker 
373f99f5f3eSSarah Walker /**
374f99f5f3eSSarah Walker  * PVR_FEATURE_VALUE() - Gets a PowerVR device feature value
375f99f5f3eSSarah Walker  * @pvr_dev: [IN] Target PowerVR device.
376f99f5f3eSSarah Walker  * @feature: [IN] Feature name.
377f99f5f3eSSarah Walker  * @value_out: [OUT] Feature value.
378f99f5f3eSSarah Walker  *
379f99f5f3eSSarah Walker  * This macro will get a feature value for those features that have values.
380f99f5f3eSSarah Walker  * If the feature is not present, nothing will be stored to @value_out.
381f99f5f3eSSarah Walker  *
382f99f5f3eSSarah Walker  * Feature names are derived from those found in &struct pvr_device_features by
383f99f5f3eSSarah Walker  * dropping the 'has_' prefix.
384f99f5f3eSSarah Walker  *
385f99f5f3eSSarah Walker  * Return:
386f99f5f3eSSarah Walker  *  * 0 on success, or
387f99f5f3eSSarah Walker  *  * -%EINVAL if the named feature is not present in the hardware
388f99f5f3eSSarah Walker  */
389f99f5f3eSSarah Walker #define PVR_FEATURE_VALUE(pvr_dev, feature, value_out)             \
390f99f5f3eSSarah Walker 	({                                                         \
391f99f5f3eSSarah Walker 		struct pvr_device *_pvr_dev = pvr_dev;             \
392f99f5f3eSSarah Walker 		int _ret = -EINVAL;                                \
393f99f5f3eSSarah Walker 		if (_pvr_dev->features.has_##feature) {            \
394f99f5f3eSSarah Walker 			*(value_out) = _pvr_dev->features.feature; \
395f99f5f3eSSarah Walker 			_ret = 0;                                  \
396f99f5f3eSSarah Walker 		}                                                  \
397f99f5f3eSSarah Walker 		_ret;                                              \
398f99f5f3eSSarah Walker 	})
399f99f5f3eSSarah Walker 
400f99f5f3eSSarah Walker /**
401f99f5f3eSSarah Walker  * PVR_HAS_QUIRK() - Tests whether a physical device has a given quirk
402f99f5f3eSSarah Walker  * @pvr_dev: [IN] Target PowerVR device.
403f99f5f3eSSarah Walker  * @quirk: [IN] Hardware quirk name.
404f99f5f3eSSarah Walker  *
405f99f5f3eSSarah Walker  * Quirk numbers are derived from those found in #pvr_device_quirks by
406f99f5f3eSSarah Walker  * dropping the 'has_brn' prefix, which is applied by this macro.
407f99f5f3eSSarah Walker  *
408f99f5f3eSSarah Walker  * Returns
409f99f5f3eSSarah Walker  *  * true if the quirk is present in the hardware, or
410f99f5f3eSSarah Walker  *  * false if the quirk is not present in the hardware.
411f99f5f3eSSarah Walker  */
412f99f5f3eSSarah Walker #define PVR_HAS_QUIRK(pvr_dev, quirk) ((pvr_dev)->quirks.has_brn##quirk)
413f99f5f3eSSarah Walker 
414f99f5f3eSSarah Walker /**
415f99f5f3eSSarah Walker  * PVR_HAS_ENHANCEMENT() - Tests whether a physical device has a given
416f99f5f3eSSarah Walker  *                         enhancement
417f99f5f3eSSarah Walker  * @pvr_dev: [IN] Target PowerVR device.
418f99f5f3eSSarah Walker  * @enhancement: [IN] Hardware enhancement name.
419f99f5f3eSSarah Walker  *
420f99f5f3eSSarah Walker  * Enhancement numbers are derived from those found in #pvr_device_enhancements
421f99f5f3eSSarah Walker  * by dropping the 'has_ern' prefix, which is applied by this macro.
422f99f5f3eSSarah Walker  *
423f99f5f3eSSarah Walker  * Returns
424f99f5f3eSSarah Walker  *  * true if the enhancement is present in the hardware, or
425f99f5f3eSSarah Walker  *  * false if the enhancement is not present in the hardware.
426f99f5f3eSSarah Walker  */
427f99f5f3eSSarah Walker #define PVR_HAS_ENHANCEMENT(pvr_dev, enhancement) ((pvr_dev)->enhancements.has_ern##enhancement)
428f99f5f3eSSarah Walker 
4294babef07SSarah Walker #define from_pvr_device(pvr_dev) (&(pvr_dev)->base)
4304babef07SSarah Walker 
4314babef07SSarah Walker #define to_pvr_device(drm_dev) container_of_const(drm_dev, struct pvr_device, base)
4324babef07SSarah Walker 
4334babef07SSarah Walker #define from_pvr_file(pvr_file) ((pvr_file)->file)
4344babef07SSarah Walker 
4354babef07SSarah Walker #define to_pvr_file(file) ((file)->driver_priv)
4364babef07SSarah Walker 
437f99f5f3eSSarah Walker /**
438f99f5f3eSSarah Walker  * PVR_PACKED_BVNC() - Packs B, V, N and C values into a 64-bit unsigned integer
439f99f5f3eSSarah Walker  * @b: Branch ID.
440f99f5f3eSSarah Walker  * @v: Version ID.
441f99f5f3eSSarah Walker  * @n: Number of scalable units.
442f99f5f3eSSarah Walker  * @c: Config ID.
443f99f5f3eSSarah Walker  *
444f99f5f3eSSarah Walker  * The packed layout is as follows:
445f99f5f3eSSarah Walker  *
446f99f5f3eSSarah Walker  *    +--------+--------+--------+-------+
447f99f5f3eSSarah Walker  *    | 63..48 | 47..32 | 31..16 | 15..0 |
448f99f5f3eSSarah Walker  *    +========+========+========+=======+
449f99f5f3eSSarah Walker  *    | B      | V      | N      | C     |
450f99f5f3eSSarah Walker  *    +--------+--------+--------+-------+
451f99f5f3eSSarah Walker  *
452f99f5f3eSSarah Walker  * pvr_gpu_id_to_packed_bvnc() should be used instead of this macro when a
453f99f5f3eSSarah Walker  * &struct pvr_gpu_id is available in order to ensure proper type checking.
454f99f5f3eSSarah Walker  *
455f99f5f3eSSarah Walker  * Return: Packed BVNC.
456f99f5f3eSSarah Walker  */
457f99f5f3eSSarah Walker /* clang-format off */
458f99f5f3eSSarah Walker #define PVR_PACKED_BVNC(b, v, n, c) \
459f99f5f3eSSarah Walker 	((((u64)(b) & GENMASK_ULL(15, 0)) << 48) | \
460f99f5f3eSSarah Walker 	 (((u64)(v) & GENMASK_ULL(15, 0)) << 32) | \
461f99f5f3eSSarah Walker 	 (((u64)(n) & GENMASK_ULL(15, 0)) << 16) | \
462f99f5f3eSSarah Walker 	 (((u64)(c) & GENMASK_ULL(15, 0)) <<  0))
463f99f5f3eSSarah Walker /* clang-format on */
464f99f5f3eSSarah Walker 
465f99f5f3eSSarah Walker /**
466f99f5f3eSSarah Walker  * pvr_gpu_id_to_packed_bvnc() - Packs B, V, N and C values into a 64-bit
467f99f5f3eSSarah Walker  * unsigned integer
468f99f5f3eSSarah Walker  * @gpu_id: GPU ID.
469f99f5f3eSSarah Walker  *
470f99f5f3eSSarah Walker  * The packed layout is as follows:
471f99f5f3eSSarah Walker  *
472f99f5f3eSSarah Walker  *    +--------+--------+--------+-------+
473f99f5f3eSSarah Walker  *    | 63..48 | 47..32 | 31..16 | 15..0 |
474f99f5f3eSSarah Walker  *    +========+========+========+=======+
475f99f5f3eSSarah Walker  *    | B      | V      | N      | C     |
476f99f5f3eSSarah Walker  *    +--------+--------+--------+-------+
477f99f5f3eSSarah Walker  *
478f99f5f3eSSarah Walker  * This should be used in preference to PVR_PACKED_BVNC() when a &struct
479f99f5f3eSSarah Walker  * pvr_gpu_id is available in order to ensure proper type checking.
480f99f5f3eSSarah Walker  *
481f99f5f3eSSarah Walker  * Return: Packed BVNC.
482f99f5f3eSSarah Walker  */
483f99f5f3eSSarah Walker static __always_inline u64
484f99f5f3eSSarah Walker pvr_gpu_id_to_packed_bvnc(struct pvr_gpu_id *gpu_id)
485f99f5f3eSSarah Walker {
486f99f5f3eSSarah Walker 	return PVR_PACKED_BVNC(gpu_id->b, gpu_id->v, gpu_id->n, gpu_id->c);
487f99f5f3eSSarah Walker }
488f99f5f3eSSarah Walker 
489f99f5f3eSSarah Walker static __always_inline void
490f99f5f3eSSarah Walker packed_bvnc_to_pvr_gpu_id(u64 bvnc, struct pvr_gpu_id *gpu_id)
491f99f5f3eSSarah Walker {
492f99f5f3eSSarah Walker 	gpu_id->b = (bvnc & GENMASK_ULL(63, 48)) >> 48;
493f99f5f3eSSarah Walker 	gpu_id->v = (bvnc & GENMASK_ULL(47, 32)) >> 32;
494f99f5f3eSSarah Walker 	gpu_id->n = (bvnc & GENMASK_ULL(31, 16)) >> 16;
495f99f5f3eSSarah Walker 	gpu_id->c = bvnc & GENMASK_ULL(15, 0);
496f99f5f3eSSarah Walker }
497f99f5f3eSSarah Walker 
4981f88f017SSarah Walker int pvr_device_init(struct pvr_device *pvr_dev);
4991f88f017SSarah Walker void pvr_device_fini(struct pvr_device *pvr_dev);
500eaf01ee5SSarah Walker void pvr_device_reset(struct pvr_device *pvr_dev);
5011f88f017SSarah Walker 
502f99f5f3eSSarah Walker bool
503f99f5f3eSSarah Walker pvr_device_has_uapi_quirk(struct pvr_device *pvr_dev, u32 quirk);
504f99f5f3eSSarah Walker bool
505f99f5f3eSSarah Walker pvr_device_has_uapi_enhancement(struct pvr_device *pvr_dev, u32 enhancement);
506f99f5f3eSSarah Walker bool
507f99f5f3eSSarah Walker pvr_device_has_feature(struct pvr_device *pvr_dev, u32 feature);
508f99f5f3eSSarah Walker 
5091f88f017SSarah Walker /**
5101f88f017SSarah Walker  * PVR_CR_FIELD_GET() - Extract a single field from a PowerVR control register
5111f88f017SSarah Walker  * @val: Value of the target register.
5121f88f017SSarah Walker  * @field: Field specifier, as defined in "pvr_rogue_cr_defs.h".
5131f88f017SSarah Walker  *
5141f88f017SSarah Walker  * Return: The extracted field.
5151f88f017SSarah Walker  */
5161f88f017SSarah Walker #define PVR_CR_FIELD_GET(val, field) FIELD_GET(~ROGUE_CR_##field##_CLRMSK, val)
5171f88f017SSarah Walker 
5181f88f017SSarah Walker /**
5191f88f017SSarah Walker  * pvr_cr_read32() - Read a 32-bit register from a PowerVR device
5201f88f017SSarah Walker  * @pvr_dev: Target PowerVR device.
5211f88f017SSarah Walker  * @reg: Target register.
5221f88f017SSarah Walker  *
5231f88f017SSarah Walker  * Return: The value of the requested register.
5241f88f017SSarah Walker  */
5251f88f017SSarah Walker static __always_inline u32
5261f88f017SSarah Walker pvr_cr_read32(struct pvr_device *pvr_dev, u32 reg)
5271f88f017SSarah Walker {
5281f88f017SSarah Walker 	return ioread32(pvr_dev->regs + reg);
5291f88f017SSarah Walker }
5301f88f017SSarah Walker 
5311f88f017SSarah Walker /**
5321f88f017SSarah Walker  * pvr_cr_read64() - Read a 64-bit register from a PowerVR device
5331f88f017SSarah Walker  * @pvr_dev: Target PowerVR device.
5341f88f017SSarah Walker  * @reg: Target register.
5351f88f017SSarah Walker  *
5361f88f017SSarah Walker  * Return: The value of the requested register.
5371f88f017SSarah Walker  */
5381f88f017SSarah Walker static __always_inline u64
5391f88f017SSarah Walker pvr_cr_read64(struct pvr_device *pvr_dev, u32 reg)
5401f88f017SSarah Walker {
5411f88f017SSarah Walker 	return ioread64(pvr_dev->regs + reg);
5421f88f017SSarah Walker }
5431f88f017SSarah Walker 
5441f88f017SSarah Walker /**
5451f88f017SSarah Walker  * pvr_cr_write32() - Write to a 32-bit register in a PowerVR device
5461f88f017SSarah Walker  * @pvr_dev: Target PowerVR device.
5471f88f017SSarah Walker  * @reg: Target register.
5481f88f017SSarah Walker  * @val: Value to write.
5491f88f017SSarah Walker  */
5501f88f017SSarah Walker static __always_inline void
5511f88f017SSarah Walker pvr_cr_write32(struct pvr_device *pvr_dev, u32 reg, u32 val)
5521f88f017SSarah Walker {
5531f88f017SSarah Walker 	iowrite32(val, pvr_dev->regs + reg);
5541f88f017SSarah Walker }
5551f88f017SSarah Walker 
5561f88f017SSarah Walker /**
5571f88f017SSarah Walker  * pvr_cr_write64() - Write to a 64-bit register in a PowerVR device
5581f88f017SSarah Walker  * @pvr_dev: Target PowerVR device.
5591f88f017SSarah Walker  * @reg: Target register.
5601f88f017SSarah Walker  * @val: Value to write.
5611f88f017SSarah Walker  */
5621f88f017SSarah Walker static __always_inline void
5631f88f017SSarah Walker pvr_cr_write64(struct pvr_device *pvr_dev, u32 reg, u64 val)
5641f88f017SSarah Walker {
5651f88f017SSarah Walker 	iowrite64(val, pvr_dev->regs + reg);
5661f88f017SSarah Walker }
5671f88f017SSarah Walker 
5681f88f017SSarah Walker /**
5691f88f017SSarah Walker  * pvr_cr_poll_reg32() - Wait for a 32-bit register to match a given value by
5701f88f017SSarah Walker  *                       polling
5711f88f017SSarah Walker  * @pvr_dev: Target PowerVR device.
5721f88f017SSarah Walker  * @reg_addr: Address of register.
5731f88f017SSarah Walker  * @reg_value: Expected register value (after masking).
5741f88f017SSarah Walker  * @reg_mask: Mask of bits valid for comparison with @reg_value.
5751f88f017SSarah Walker  * @timeout_usec: Timeout length, in us.
5761f88f017SSarah Walker  *
5771f88f017SSarah Walker  * Returns:
5781f88f017SSarah Walker  *  * 0 on success, or
5791f88f017SSarah Walker  *  * -%ETIMEDOUT on timeout.
5801f88f017SSarah Walker  */
5811f88f017SSarah Walker static __always_inline int
5821f88f017SSarah Walker pvr_cr_poll_reg32(struct pvr_device *pvr_dev, u32 reg_addr, u32 reg_value,
5831f88f017SSarah Walker 		  u32 reg_mask, u64 timeout_usec)
5841f88f017SSarah Walker {
5851f88f017SSarah Walker 	u32 value;
5861f88f017SSarah Walker 
5871f88f017SSarah Walker 	return readl_poll_timeout(pvr_dev->regs + reg_addr, value,
5881f88f017SSarah Walker 		(value & reg_mask) == reg_value, 0, timeout_usec);
5891f88f017SSarah Walker }
5901f88f017SSarah Walker 
5911f88f017SSarah Walker /**
5921f88f017SSarah Walker  * pvr_cr_poll_reg64() - Wait for a 64-bit register to match a given value by
5931f88f017SSarah Walker  *                       polling
5941f88f017SSarah Walker  * @pvr_dev: Target PowerVR device.
5951f88f017SSarah Walker  * @reg_addr: Address of register.
5961f88f017SSarah Walker  * @reg_value: Expected register value (after masking).
5971f88f017SSarah Walker  * @reg_mask: Mask of bits valid for comparison with @reg_value.
5981f88f017SSarah Walker  * @timeout_usec: Timeout length, in us.
5991f88f017SSarah Walker  *
6001f88f017SSarah Walker  * Returns:
6011f88f017SSarah Walker  *  * 0 on success, or
6021f88f017SSarah Walker  *  * -%ETIMEDOUT on timeout.
6031f88f017SSarah Walker  */
6041f88f017SSarah Walker static __always_inline int
6051f88f017SSarah Walker pvr_cr_poll_reg64(struct pvr_device *pvr_dev, u32 reg_addr, u64 reg_value,
6061f88f017SSarah Walker 		  u64 reg_mask, u64 timeout_usec)
6071f88f017SSarah Walker {
6081f88f017SSarah Walker 	u64 value;
6091f88f017SSarah Walker 
6101f88f017SSarah Walker 	return readq_poll_timeout(pvr_dev->regs + reg_addr, value,
6111f88f017SSarah Walker 		(value & reg_mask) == reg_value, 0, timeout_usec);
6121f88f017SSarah Walker }
6131f88f017SSarah Walker 
6144babef07SSarah Walker /**
615f99f5f3eSSarah Walker  * pvr_round_up_to_cacheline_size() - Round up a provided size to be cacheline
616f99f5f3eSSarah Walker  *                                    aligned
617f99f5f3eSSarah Walker  * @pvr_dev: Target PowerVR device.
618f99f5f3eSSarah Walker  * @size: Initial size, in bytes.
619f99f5f3eSSarah Walker  *
620f99f5f3eSSarah Walker  * Returns:
621f99f5f3eSSarah Walker  *  * Size aligned to cacheline size.
622f99f5f3eSSarah Walker  */
623f99f5f3eSSarah Walker static __always_inline size_t
624f99f5f3eSSarah Walker pvr_round_up_to_cacheline_size(struct pvr_device *pvr_dev, size_t size)
625f99f5f3eSSarah Walker {
626f99f5f3eSSarah Walker 	u16 slc_cacheline_size_bits = 0;
627f99f5f3eSSarah Walker 	u16 slc_cacheline_size_bytes;
628f99f5f3eSSarah Walker 
629f99f5f3eSSarah Walker 	WARN_ON(!PVR_HAS_FEATURE(pvr_dev, slc_cache_line_size_bits));
630f99f5f3eSSarah Walker 	PVR_FEATURE_VALUE(pvr_dev, slc_cache_line_size_bits,
631f99f5f3eSSarah Walker 			  &slc_cacheline_size_bits);
632f99f5f3eSSarah Walker 	slc_cacheline_size_bytes = slc_cacheline_size_bits / 8;
633f99f5f3eSSarah Walker 
634f99f5f3eSSarah Walker 	return round_up(size, slc_cacheline_size_bytes);
635f99f5f3eSSarah Walker }
636f99f5f3eSSarah Walker 
637f99f5f3eSSarah Walker /**
6384babef07SSarah Walker  * DOC: IOCTL validation helpers
6394babef07SSarah Walker  *
6404babef07SSarah Walker  * To validate the constraints imposed on IOCTL argument structs, a collection
6414babef07SSarah Walker  * of macros and helper functions exist in ``pvr_device.h``.
6424babef07SSarah Walker  *
6434babef07SSarah Walker  * Of the current helpers, it should only be necessary to call
6444babef07SSarah Walker  * PVR_IOCTL_UNION_PADDING_CHECK() directly. This macro should be used once in
6454babef07SSarah Walker  * every code path which extracts a union member from a struct passed from
6464babef07SSarah Walker  * userspace.
6474babef07SSarah Walker  */
6484babef07SSarah Walker 
6494babef07SSarah Walker /**
6504babef07SSarah Walker  * pvr_ioctl_union_padding_check() - Validate that the implicit padding between
6514babef07SSarah Walker  * the end of a union member and the end of the union itself is zeroed.
6524babef07SSarah Walker  * @instance: Pointer to the instance of the struct to validate.
6534babef07SSarah Walker  * @union_offset: Offset into the type of @instance of the target union. Must
6544babef07SSarah Walker  * be 64-bit aligned.
6554babef07SSarah Walker  * @union_size: Size of the target union in the type of @instance. Must be
6564babef07SSarah Walker  * 64-bit aligned.
6574babef07SSarah Walker  * @member_size: Size of the target member in the target union specified by
6584babef07SSarah Walker  * @union_offset and @union_size. It is assumed that the offset of the target
6594babef07SSarah Walker  * member is zero relative to @union_offset. Must be 64-bit aligned.
6604babef07SSarah Walker  *
6614babef07SSarah Walker  * You probably want to use PVR_IOCTL_UNION_PADDING_CHECK() instead of calling
6624babef07SSarah Walker  * this function directly, since that macro abstracts away much of the setup,
6634babef07SSarah Walker  * and also provides some static validation. See its docs for details.
6644babef07SSarah Walker  *
6654babef07SSarah Walker  * Return:
6664babef07SSarah Walker  *  * %true if every byte between the end of the used member of the union and
6674babef07SSarah Walker  *    the end of that union is zeroed, or
6684babef07SSarah Walker  *  * %false otherwise.
6694babef07SSarah Walker  */
6704babef07SSarah Walker static __always_inline bool
6714babef07SSarah Walker pvr_ioctl_union_padding_check(void *instance, size_t union_offset,
6724babef07SSarah Walker 			      size_t union_size, size_t member_size)
6734babef07SSarah Walker {
6744babef07SSarah Walker 	/*
6754babef07SSarah Walker 	 * void pointer arithmetic is technically illegal - cast to a byte
6764babef07SSarah Walker 	 * pointer so this addition works safely.
6774babef07SSarah Walker 	 */
6784babef07SSarah Walker 	void *padding_start = ((u8 *)instance) + union_offset + member_size;
6794babef07SSarah Walker 	size_t padding_size = union_size - member_size;
6804babef07SSarah Walker 
681f7650635SJani Nikula 	return mem_is_zero(padding_start, padding_size);
6824babef07SSarah Walker }
6834babef07SSarah Walker 
6844babef07SSarah Walker /**
6854babef07SSarah Walker  * PVR_STATIC_ASSERT_64BIT_ALIGNED() - Inline assertion for 64-bit alignment.
6864babef07SSarah Walker  * @static_expr_: Target expression to evaluate.
6874babef07SSarah Walker  *
6884babef07SSarah Walker  * If @static_expr_ does not evaluate to a constant integer which would be a
6894babef07SSarah Walker  * 64-bit aligned address (i.e. a multiple of 8), compilation will fail.
6904babef07SSarah Walker  *
6914babef07SSarah Walker  * Return:
6924babef07SSarah Walker  * The value of @static_expr_.
6934babef07SSarah Walker  */
6944babef07SSarah Walker #define PVR_STATIC_ASSERT_64BIT_ALIGNED(static_expr_)                     \
6954babef07SSarah Walker 	({                                                                \
6964babef07SSarah Walker 		static_assert(((static_expr_) & (sizeof(u64) - 1)) == 0); \
6974babef07SSarah Walker 		(static_expr_);                                           \
6984babef07SSarah Walker 	})
6994babef07SSarah Walker 
7004babef07SSarah Walker /**
7014babef07SSarah Walker  * PVR_IOCTL_UNION_PADDING_CHECK() - Validate that the implicit padding between
7024babef07SSarah Walker  * the end of a union member and the end of the union itself is zeroed.
7034babef07SSarah Walker  * @struct_instance_: An expression which evaluates to a pointer to a UAPI data
7044babef07SSarah Walker  * struct.
7054babef07SSarah Walker  * @union_: The name of the union member of @struct_instance_ to check. If the
7064babef07SSarah Walker  * union member is nested within the type of @struct_instance_, this may
7074babef07SSarah Walker  * contain the member access operator (".").
7084babef07SSarah Walker  * @member_: The name of the member of @union_ to assess.
7094babef07SSarah Walker  *
7104babef07SSarah Walker  * This is a wrapper around pvr_ioctl_union_padding_check() which performs
7114babef07SSarah Walker  * alignment checks and simplifies things for the caller.
7124babef07SSarah Walker  *
7134babef07SSarah Walker  * Return:
7144babef07SSarah Walker  *  * %true if every byte in @struct_instance_ between the end of @member_ and
7154babef07SSarah Walker  *    the end of @union_ is zeroed, or
7164babef07SSarah Walker  *  * %false otherwise.
7174babef07SSarah Walker  */
7184babef07SSarah Walker #define PVR_IOCTL_UNION_PADDING_CHECK(struct_instance_, union_, member_)     \
7194babef07SSarah Walker 	({                                                                   \
7204babef07SSarah Walker 		typeof(struct_instance_) __instance = (struct_instance_);    \
7214babef07SSarah Walker 		size_t __union_offset = PVR_STATIC_ASSERT_64BIT_ALIGNED(     \
7224babef07SSarah Walker 			offsetof(typeof(*__instance), union_));              \
7234babef07SSarah Walker 		size_t __union_size = PVR_STATIC_ASSERT_64BIT_ALIGNED(       \
7244babef07SSarah Walker 			sizeof(__instance->union_));                         \
7254babef07SSarah Walker 		size_t __member_size = PVR_STATIC_ASSERT_64BIT_ALIGNED(      \
7264babef07SSarah Walker 			sizeof(__instance->union_.member_));                 \
7274babef07SSarah Walker 		pvr_ioctl_union_padding_check(__instance, __union_offset,    \
7284babef07SSarah Walker 					      __union_size, __member_size);  \
7294babef07SSarah Walker 	})
7304babef07SSarah Walker 
731f99f5f3eSSarah Walker #define PVR_FW_PROCESSOR_TYPE_META  0
732f99f5f3eSSarah Walker #define PVR_FW_PROCESSOR_TYPE_MIPS  1
733f99f5f3eSSarah Walker #define PVR_FW_PROCESSOR_TYPE_RISCV 2
734f99f5f3eSSarah Walker 
7354babef07SSarah Walker #endif /* PVR_DEVICE_H */
736