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