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