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