FILE
pvr_device.c
File preview with syntax highlighting.
linux-6.19.14/drivers/gpu/drm/imagination/pvr_device.c
1// SPDX-License-Identifier: GPL-2.0-only OR MIT 2/* Copyright (c) 2023 Imagination Technologies Ltd. */ 3 4#include "pvr_device.h" 5#include "pvr_device_info.h" 6 7#include "pvr_fw.h" 8#include "pvr_params.h" 9#include "pvr_power.h" 10#include "pvr_queue.h" 11#include "pvr_rogue_cr_defs.h" 12#include "pvr_stream.h" 13#include "pvr_vm.h" 14 15#include <drm/drm_print.h> 16 17#include <linux/bitfield.h> 18#include <linux/clk.h> 19#include <linux/compiler_attributes.h> 20#include <linux/compiler_types.h> 21#include <linux/dma-mapping.h> 22#include <linux/err.h> 23#include <linux/firmware.h> 24#include <linux/gfp.h> 25#include <linux/interrupt.h> 26#include <linux/of.h> 27#include <linux/platform_device.h> 28#include <linux/pm_runtime.h> 29#include <linux/reset.h> 30#include <linux/slab.h> 31#include <linux/stddef.h> 32#include <linux/types.h> 33#include <linux/workqueue.h> 34 35/* Major number for the supported version of the firmware. */ 36#define PVR_FW_VERSION_MAJOR 1 37 38/** 39 * pvr_device_reg_init() - Initialize kernel access to a PowerVR device's 40 * control registers. 41 * @pvr_dev: Target PowerVR device. 42 * 43 * Sets struct pvr_device->regs. 44 * 45 * This method of mapping the device control registers into memory ensures that 46 * they are unmapped when the driver is detached (i.e. no explicit cleanup is 47 * required). 48 * 49 * Return: 50 * * 0 on success, or 51 * * Any error returned by devm_platform_get_and_ioremap_resource(). 52 */ 53static int 54pvr_device_reg_init(struct pvr_device *pvr_dev) 55{ 56 struct drm_device *drm_dev = from_pvr_device(pvr_dev); 57 struct platform_device *plat_dev = to_platform_device(drm_dev->dev); 58 struct resource *regs_resource; 59 void __iomem *regs; 60 61 pvr_dev->regs_resource = NULL; 62 pvr_dev->regs = NULL; 63 64 regs = devm_platform_get_and_ioremap_resource(plat_dev, 0, ®s_resource); 65 if (IS_ERR(regs)) 66 return dev_err_probe(drm_dev->dev, PTR_ERR(regs), 67 "failed to ioremap gpu registers\n"); 68 69 pvr_dev->regs = regs; 70 pvr_dev->regs_resource = regs_resource; 71 72 return 0; 73} 74 75/** 76 * pvr_device_clk_init() - Initialize clocks required by a PowerVR device 77 * @pvr_dev: Target PowerVR device. 78 * 79 * Sets struct pvr_device->core_clk, struct pvr_device->sys_clk and 80 * struct pvr_device->mem_clk. 81 * 82 * Three clocks are required by the PowerVR device: core, sys and mem. On 83 * return, this function guarantees that the clocks are in one of the following 84 * states: 85 * 86 * * All successfully initialized, 87 * * Core errored, sys and mem uninitialized, 88 * * Core deinitialized, sys errored, mem uninitialized, or 89 * * Core and sys deinitialized, mem errored. 90 * 91 * Return: 92 * * 0 on success, 93 * * Any error returned by devm_clk_get(), or 94 * * Any error returned by devm_clk_get_optional(). 95 */ 96static int pvr_device_clk_init(struct pvr_device *pvr_dev) 97{ 98 struct drm_device *drm_dev = from_pvr_device(pvr_dev); 99 struct clk *core_clk; 100 struct clk *sys_clk; 101 struct clk *mem_clk; 102 103 core_clk = devm_clk_get(drm_dev->dev, "core"); 104 if (IS_ERR(core_clk)) 105 return dev_err_probe(drm_dev->dev, PTR_ERR(core_clk), 106 "failed to get core clock\n"); 107 108 sys_clk = devm_clk_get_optional(drm_dev->dev, "sys"); 109 if (IS_ERR(sys_clk)) 110 return dev_err_probe(drm_dev->dev, PTR_ERR(sys_clk), 111 "failed to get sys clock\n"); 112 113 mem_clk = devm_clk_get_optional(drm_dev->dev, "mem"); 114 if (IS_ERR(mem_clk)) 115 return dev_err_probe(drm_dev->dev, PTR_ERR(mem_clk), 116 "failed to get mem clock\n"); 117 118 pvr_dev->core_clk = core_clk; 119 pvr_dev->sys_clk = sys_clk; 120 pvr_dev->mem_clk = mem_clk; 121 122 return 0; 123} 124 125/** 126 * pvr_device_process_active_queues() - Process all queue related events. 127 * @pvr_dev: PowerVR device to check 128 * 129 * This is called any time we receive a FW event. It iterates over all 130 * active queues and calls pvr_queue_process() on them. 131 */ 132static void pvr_device_process_active_queues(struct pvr_device *pvr_dev) 133{ 134 struct pvr_queue *queue, *tmp_queue; 135 LIST_HEAD(active_queues); 136 137 mutex_lock(&pvr_dev->queues.lock); 138 139 /* Move all active queues to a temporary list. Queues that remain 140 * active after we're done processing them are re-inserted to 141 * the queues.active list by pvr_queue_process(). 142 */ 143 list_splice_init(&pvr_dev->queues.active, &active_queues); 144 145 list_for_each_entry_safe(queue, tmp_queue, &active_queues, node) 146 pvr_queue_process(queue); 147 148 mutex_unlock(&pvr_dev->queues.lock); 149} 150 151static bool pvr_device_safety_irq_pending(struct pvr_device *pvr_dev) 152{ 153 u32 events; 154 155 WARN_ON_ONCE(!pvr_dev->has_safety_events); 156 157 events = pvr_cr_read32(pvr_dev, ROGUE_CR_EVENT_STATUS); 158 159 return (events & ROGUE_CR_EVENT_STATUS_SAFETY_EN) != 0; 160} 161 162static void pvr_device_safety_irq_clear(struct pvr_device *pvr_dev) 163{ 164 WARN_ON_ONCE(!pvr_dev->has_safety_events); 165 166 pvr_cr_write32(pvr_dev, ROGUE_CR_EVENT_CLEAR, 167 ROGUE_CR_EVENT_CLEAR_SAFETY_EN); 168} 169 170static void pvr_device_handle_safety_events(struct pvr_device *pvr_dev) 171{ 172 struct drm_device *drm_dev = from_pvr_device(pvr_dev); 173 u32 events; 174 175 WARN_ON_ONCE(!pvr_dev->has_safety_events); 176 177 events = pvr_cr_read32(pvr_dev, ROGUE_CR_SAFETY_EVENT_STATUS__ROGUEXE); 178 179 /* Handle only these events on the host and leave the rest to the FW. */ 180 events &= ROGUE_CR_SAFETY_EVENT_STATUS__ROGUEXE__FAULT_FW_EN | 181 ROGUE_CR_SAFETY_EVENT_STATUS__ROGUEXE__WATCHDOG_TIMEOUT_EN; 182 183 pvr_cr_write32(pvr_dev, ROGUE_CR_SAFETY_EVENT_CLEAR__ROGUEXE, events); 184 185 if (events & ROGUE_CR_SAFETY_EVENT_STATUS__ROGUEXE__FAULT_FW_EN) { 186 u32 fault_fw = pvr_cr_read32(pvr_dev, ROGUE_CR_FAULT_FW_STATUS); 187 188 pvr_cr_write32(pvr_dev, ROGUE_CR_FAULT_FW_CLEAR, fault_fw); 189 190 drm_info(drm_dev, "Safety event: FW fault (mask=0x%08x)\n", fault_fw); 191 } 192 193 if (events & ROGUE_CR_SAFETY_EVENT_STATUS__ROGUEXE__WATCHDOG_TIMEOUT_EN) { 194 /* 195 * The watchdog timer is disabled by the driver so this event 196 * should never be fired. 197 */ 198 drm_info(drm_dev, "Safety event: Watchdog timeout\n"); 199 } 200} 201 202static irqreturn_t pvr_device_irq_thread_handler(int irq, void *data) 203{ 204 struct pvr_device *pvr_dev = data; 205 struct drm_device *drm_dev = from_pvr_device(pvr_dev); 206 irqreturn_t ret = IRQ_NONE; 207 208 /* We are in the threaded handler, we can keep dequeuing events until we 209 * don't see any. This should allow us to reduce the number of interrupts 210 * when the GPU is receiving a massive amount of short jobs. 211 */ 212 while (pvr_fw_irq_pending(pvr_dev)) { 213 pvr_fw_irq_clear(pvr_dev); 214 215 if (pvr_dev->fw_dev.booted) { 216 pvr_fwccb_process(pvr_dev); 217 pvr_kccb_wake_up_waiters(pvr_dev); 218 pvr_device_process_active_queues(pvr_dev); 219 } 220 221 pm_runtime_mark_last_busy(drm_dev->dev); 222 223 ret = IRQ_HANDLED; 224 } 225 226 if (pvr_dev->has_safety_events) { 227 while (pvr_device_safety_irq_pending(pvr_dev)) { 228 pvr_device_safety_irq_clear(pvr_dev); 229 pvr_device_handle_safety_events(pvr_dev); 230 231 ret = IRQ_HANDLED; 232 } 233 } 234 235 return ret; 236} 237 238static irqreturn_t pvr_device_irq_handler(int irq, void *data) 239{ 240 struct pvr_device *pvr_dev = data; 241 bool safety_irq_pending = false; 242 243 if (pvr_dev->has_safety_events) 244 safety_irq_pending = pvr_device_safety_irq_pending(pvr_dev); 245 246 if (!pvr_fw_irq_pending(pvr_dev) && !safety_irq_pending) 247 return IRQ_NONE; /* Spurious IRQ - ignore. */ 248 249 return IRQ_WAKE_THREAD; 250} 251 252static void pvr_device_safety_irq_init(struct pvr_device *pvr_dev) 253{ 254 u32 num_ecc_rams = 0; 255 256 /* 257 * Safety events are an optional feature of the RogueXE platform. They 258 * are only enabled if at least one of ECC memory or the watchdog timer 259 * are present in HW. While safety events can be generated by other 260 * systems, that will never happen if the above mentioned hardware is 261 * not present. 262 */ 263 if (!PVR_HAS_FEATURE(pvr_dev, roguexe)) { 264 pvr_dev->has_safety_events = false; 265 return; 266 } 267 268 PVR_FEATURE_VALUE(pvr_dev, ecc_rams, &num_ecc_rams); 269 270 pvr_dev->has_safety_events = 271 num_ecc_rams > 0 || PVR_HAS_FEATURE(pvr_dev, watchdog_timer); 272} 273 274/** 275 * pvr_device_irq_init() - Initialise IRQ required by a PowerVR device 276 * @pvr_dev: Target PowerVR device. 277 * 278 * Returns: 279 * * 0 on success, 280 * * Any error returned by platform_get_irq_byname(), or 281 * * Any error returned by request_irq(). 282 */ 283static int 284pvr_device_irq_init(struct pvr_device *pvr_dev) 285{ 286 struct drm_device *drm_dev = from_pvr_device(pvr_dev); 287 struct platform_device *plat_dev = to_platform_device(drm_dev->dev); 288 289 init_waitqueue_head(&pvr_dev->kccb.rtn_q); 290 291 pvr_device_safety_irq_init(pvr_dev); 292 293 pvr_dev->irq = platform_get_irq(plat_dev, 0); 294 if (pvr_dev->irq < 0) 295 return pvr_dev->irq; 296 297 /* Clear any pending events before requesting the IRQ line. */ 298 pvr_fw_irq_clear(pvr_dev); 299 300 if (pvr_dev->has_safety_events) 301 pvr_device_safety_irq_clear(pvr_dev); 302 303 /* 304 * The ONESHOT flag ensures IRQs are masked while the thread handler is 305 * running. 306 */ 307 return request_threaded_irq(pvr_dev->irq, pvr_device_irq_handler, 308 pvr_device_irq_thread_handler, 309 IRQF_SHARED | IRQF_ONESHOT, "gpu", pvr_dev); 310} 311 312/** 313 * pvr_device_irq_fini() - Deinitialise IRQ required by a PowerVR device 314 * @pvr_dev: Target PowerVR device. 315 */ 316static void 317pvr_device_irq_fini(struct pvr_device *pvr_dev) 318{ 319 free_irq(pvr_dev->irq, pvr_dev); 320} 321 322/** 323 * pvr_build_firmware_filename() - Construct a PowerVR firmware filename 324 * @pvr_dev: Target PowerVR device. 325 * @base: First part of the filename. 326 * @major: Major version number. 327 * 328 * A PowerVR firmware filename consists of three parts separated by underscores 329 * (``'_'``) along with a '.fw' file suffix. The first part is the exact value 330 * of @base, the second part is the hardware version string derived from @pvr_fw 331 * and the final part is the firmware version number constructed from @major with 332 * a 'v' prefix, e.g. powervr/rogue_4.40.2.51_v1.fw. 333 * 334 * The returned string will have been slab allocated and must be freed with 335 * kfree(). 336 * 337 * Return: 338 * * The constructed filename on success, or 339 * * Any error returned by kasprintf(). 340 */ 341static char * 342pvr_build_firmware_filename(struct pvr_device *pvr_dev, const char *base, 343 u8 major) 344{ 345 struct pvr_gpu_id *gpu_id = &pvr_dev->gpu_id; 346 347 return kasprintf(GFP_KERNEL, "%s_%d.%d.%d.%d_v%d.fw", base, gpu_id->b, 348 gpu_id->v, gpu_id->n, gpu_id->c, major); 349} 350 351static void 352pvr_release_firmware(void *data) 353{ 354 struct pvr_device *pvr_dev = data; 355 356 release_firmware(pvr_dev->fw_dev.firmware); 357} 358 359/** 360 * pvr_request_firmware() - Load firmware for a PowerVR device 361 * @pvr_dev: Target PowerVR device. 362 * 363 * See pvr_build_firmware_filename() for details on firmware file naming. 364 * 365 * Return: 366 * * 0 on success, 367 * * Any error returned by pvr_build_firmware_filename(), or 368 * * Any error returned by request_firmware(). 369 */ 370static int 371pvr_request_firmware(struct pvr_device *pvr_dev) 372{ 373 struct drm_device *drm_dev = &pvr_dev->base; 374 char *filename; 375 const struct firmware *fw; 376 int err; 377 378 filename = pvr_build_firmware_filename(pvr_dev, "powervr/rogue", 379 PVR_FW_VERSION_MAJOR); 380 if (!filename) 381 return -ENOMEM; 382 383 /* 384 * This function takes a copy of &filename, meaning we can free our 385 * instance before returning. 386 */ 387 err = request_firmware(&fw, filename, pvr_dev->base.dev); 388 if (err) { 389 drm_err(drm_dev, "failed to load firmware %s (err=%d)\n", 390 filename, err); 391 goto err_free_filename; 392 } 393 394 drm_info(drm_dev, "loaded firmware %s\n", filename); 395 kfree(filename); 396 397 pvr_dev->fw_dev.firmware = fw; 398 399 return devm_add_action_or_reset(drm_dev->dev, pvr_release_firmware, pvr_dev); 400 401err_free_filename: 402 kfree(filename); 403 404 return err; 405} 406 407/** 408 * pvr_load_gpu_id() - Load a PowerVR device's GPU ID (BVNC) from control registers. 409 * 410 * Sets struct pvr_dev.gpu_id. 411 * 412 * @pvr_dev: Target PowerVR device. 413 */ 414static void 415pvr_load_gpu_id(struct pvr_device *pvr_dev) 416{ 417 struct pvr_gpu_id *gpu_id = &pvr_dev->gpu_id; 418 u64 bvnc; 419 420 /* 421 * Try reading the BVNC using the newer (cleaner) method first. If the 422 * B value is zero, fall back to the older method. 423 */ 424 bvnc = pvr_cr_read64(pvr_dev, ROGUE_CR_CORE_ID__PBVNC); 425 426 gpu_id->b = PVR_CR_FIELD_GET(bvnc, CORE_ID__PBVNC__BRANCH_ID); 427 if (gpu_id->b != 0) { 428 gpu_id->v = PVR_CR_FIELD_GET(bvnc, CORE_ID__PBVNC__VERSION_ID); 429 gpu_id->n = PVR_CR_FIELD_GET(bvnc, CORE_ID__PBVNC__NUMBER_OF_SCALABLE_UNITS); 430 gpu_id->c = PVR_CR_FIELD_GET(bvnc, CORE_ID__PBVNC__CONFIG_ID); 431 } else { 432 u32 core_rev = pvr_cr_read32(pvr_dev, ROGUE_CR_CORE_REVISION); 433 u32 core_id = pvr_cr_read32(pvr_dev, ROGUE_CR_CORE_ID); 434 u16 core_id_config = PVR_CR_FIELD_GET(core_id, CORE_ID_CONFIG); 435 436 gpu_id->b = PVR_CR_FIELD_GET(core_rev, CORE_REVISION_MAJOR); 437 gpu_id->v = PVR_CR_FIELD_GET(core_rev, CORE_REVISION_MINOR); 438 gpu_id->n = FIELD_GET(0xFF00, core_id_config); 439 gpu_id->c = FIELD_GET(0x00FF, core_id_config); 440 } 441} 442 443/** 444 * pvr_set_dma_info() - Set PowerVR device DMA information 445 * @pvr_dev: Target PowerVR device. 446 * 447 * Sets the DMA mask and max segment size for the PowerVR device. 448 * 449 * Return: 450 * * 0 on success, 451 * * Any error returned by PVR_FEATURE_VALUE(), or 452 * * Any error returned by dma_set_mask(). 453 */ 454 455static int 456pvr_set_dma_info(struct pvr_device *pvr_dev) 457{ 458 struct drm_device *drm_dev = from_pvr_device(pvr_dev); 459 u16 phys_bus_width; 460 int err; 461 462 err = PVR_FEATURE_VALUE(pvr_dev, phys_bus_width, &phys_bus_width); 463 if (err) { 464 drm_err(drm_dev, "Failed to get device physical bus width\n"); 465 return err; 466 } 467 468 err = dma_set_mask(drm_dev->dev, DMA_BIT_MASK(phys_bus_width)); 469 if (err) { 470 drm_err(drm_dev, "Failed to set DMA mask (err=%d)\n", err); 471 return err; 472 } 473 474 dma_set_max_seg_size(drm_dev->dev, UINT_MAX); 475 476 return 0; 477} 478 479/** 480 * pvr_device_gpu_init() - GPU-specific initialization for a PowerVR device 481 * @pvr_dev: Target PowerVR device. 482 * 483 * The following steps are taken to ensure the device is ready: 484 * 485 * 1. Read the hardware version information from control registers, 486 * 2. Initialise the hardware feature information, 487 * 3. Setup the device DMA information, 488 * 4. Setup the device-scoped memory context, and 489 * 5. Load firmware into the device. 490 * 491 * Return: 492 * * 0 on success, 493 * * -%ENODEV if the GPU is not supported, 494 * * Any error returned by pvr_set_dma_info(), 495 * * Any error returned by pvr_memory_context_init(), or 496 * * Any error returned by pvr_request_firmware(). 497 */ 498static int 499pvr_device_gpu_init(struct pvr_device *pvr_dev) 500{ 501 int err; 502 503 pvr_load_gpu_id(pvr_dev); 504 505 err = pvr_request_firmware(pvr_dev); 506 if (err) 507 return err; 508 509 err = pvr_fw_validate_init_device_info(pvr_dev); 510 if (err) 511 return err; 512 513 if (PVR_HAS_FEATURE(pvr_dev, meta)) 514 pvr_dev->fw_dev.processor_type = PVR_FW_PROCESSOR_TYPE_META; 515 else if (PVR_HAS_FEATURE(pvr_dev, mips)) 516 pvr_dev->fw_dev.processor_type = PVR_FW_PROCESSOR_TYPE_MIPS; 517 else if (PVR_HAS_FEATURE(pvr_dev, riscv_fw_processor)) 518 pvr_dev->fw_dev.processor_type = PVR_FW_PROCESSOR_TYPE_RISCV; 519 else 520 return -EINVAL; 521 522 pvr_stream_create_musthave_masks(pvr_dev); 523 524 err = pvr_set_dma_info(pvr_dev); 525 if (err) 526 return err; 527 528 if (pvr_dev->fw_dev.processor_type != PVR_FW_PROCESSOR_TYPE_MIPS) { 529 pvr_dev->kernel_vm_ctx = pvr_vm_create_context(pvr_dev, false); 530 if (IS_ERR(pvr_dev->kernel_vm_ctx)) 531 return PTR_ERR(pvr_dev->kernel_vm_ctx); 532 } 533 534 err = pvr_fw_init(pvr_dev); 535 if (err) 536 goto err_vm_ctx_put; 537 538 return 0; 539 540err_vm_ctx_put: 541 if (pvr_dev->fw_dev.processor_type != PVR_FW_PROCESSOR_TYPE_MIPS) { 542 pvr_vm_context_put(pvr_dev->kernel_vm_ctx); 543 pvr_dev->kernel_vm_ctx = NULL; 544 } 545 546 return err; 547} 548 549/** 550 * pvr_device_gpu_fini() - GPU-specific deinitialization for a PowerVR device 551 * @pvr_dev: Target PowerVR device. 552 */ 553static void 554pvr_device_gpu_fini(struct pvr_device *pvr_dev) 555{ 556 pvr_fw_fini(pvr_dev); 557 558 if (pvr_dev->fw_dev.processor_type != PVR_FW_PROCESSOR_TYPE_MIPS) { 559 WARN_ON(!pvr_vm_context_put(pvr_dev->kernel_vm_ctx)); 560 pvr_dev->kernel_vm_ctx = NULL; 561 } 562} 563 564/** 565 * pvr_device_init() - Initialize a PowerVR device 566 * @pvr_dev: Target PowerVR device. 567 * 568 * If this function returns successfully, the device will have been fully 569 * initialized. Otherwise, any parts of the device initialized before an error 570 * occurs will be de-initialized before returning. 571 * 572 * NOTE: The initialization steps currently taken are the bare minimum required 573 * to read from the control registers. The device is unlikely to function 574 * until further initialization steps are added. [This note should be 575 * removed when that happens.] 576 * 577 * Return: 578 * * 0 on success, 579 * * Any error returned by pvr_device_reg_init(), 580 * * Any error returned by pvr_device_clk_init(), or 581 * * Any error returned by pvr_device_gpu_init(). 582 */ 583int 584pvr_device_init(struct pvr_device *pvr_dev) 585{ 586 struct drm_device *drm_dev = from_pvr_device(pvr_dev); 587 struct device *dev = drm_dev->dev; 588 int err; 589 590 /* Get the platform-specific data based on the compatible string. */ 591 pvr_dev->device_data = of_device_get_match_data(dev); 592 593 /* 594 * Setup device parameters. We do this first in case other steps 595 * depend on them. 596 */ 597 err = pvr_device_params_init(&pvr_dev->params); 598 if (err) 599 return err; 600 601 /* Enable and initialize clocks required for the device to operate. */ 602 err = pvr_device_clk_init(pvr_dev); 603 if (err) 604 return err; 605 606 err = pvr_dev->device_data->pwr_ops->init(pvr_dev); 607 if (err) 608 return err; 609 610 /* Explicitly power the GPU so we can access control registers before the FW is booted. */ 611 err = pm_runtime_resume_and_get(dev); 612 if (err) 613 return err; 614 615 /* Map the control registers into memory. */ 616 err = pvr_device_reg_init(pvr_dev); 617 if (err) 618 goto err_pm_runtime_put; 619 620 /* Perform GPU-specific initialization steps. */ 621 err = pvr_device_gpu_init(pvr_dev); 622 if (err) 623 goto err_pm_runtime_put; 624 625 err = pvr_device_irq_init(pvr_dev); 626 if (err) 627 goto err_device_gpu_fini; 628 629 pm_runtime_put(dev); 630 631 return 0; 632 633err_device_gpu_fini: 634 pvr_device_gpu_fini(pvr_dev); 635 636err_pm_runtime_put: 637 pm_runtime_put_sync_suspend(dev); 638 639 return err; 640} 641 642/** 643 * pvr_device_fini() - Deinitialize a PowerVR device 644 * @pvr_dev: Target PowerVR device. 645 */ 646void 647pvr_device_fini(struct pvr_device *pvr_dev) 648{ 649 /* 650 * Deinitialization stages are performed in reverse order compared to 651 * the initialization stages in pvr_device_init(). 652 */ 653 pvr_device_irq_fini(pvr_dev); 654 pvr_device_gpu_fini(pvr_dev); 655} 656 657bool 658pvr_device_has_uapi_quirk(struct pvr_device *pvr_dev, u32 quirk) 659{ 660 switch (quirk) { 661 case 47217: 662 return PVR_HAS_QUIRK(pvr_dev, 47217); 663 case 48545: 664 return PVR_HAS_QUIRK(pvr_dev, 48545); 665 case 49927: 666 return PVR_HAS_QUIRK(pvr_dev, 49927); 667 case 51764: 668 return PVR_HAS_QUIRK(pvr_dev, 51764); 669 case 62269: 670 return PVR_HAS_QUIRK(pvr_dev, 62269); 671 default: 672 return false; 673 }; 674} 675 676bool 677pvr_device_has_uapi_enhancement(struct pvr_device *pvr_dev, u32 enhancement) 678{ 679 switch (enhancement) { 680 case 35421: 681 return PVR_HAS_ENHANCEMENT(pvr_dev, 35421); 682 case 42064: 683 return PVR_HAS_ENHANCEMENT(pvr_dev, 42064); 684 default: 685 return false; 686 }; 687} 688 689/** 690 * pvr_device_has_feature() - Look up device feature based on feature definition 691 * @pvr_dev: Device pointer. 692 * @feature: Feature to look up. Should be one of %PVR_FEATURE_*. 693 * 694 * Returns: 695 * * %true if feature is present on device, or 696 * * %false if feature is not present on device. 697 */ 698bool 699pvr_device_has_feature(struct pvr_device *pvr_dev, u32 feature) 700{ 701 switch (feature) { 702 case PVR_FEATURE_CLUSTER_GROUPING: 703 return PVR_HAS_FEATURE(pvr_dev, cluster_grouping); 704 705 case PVR_FEATURE_COMPUTE_MORTON_CAPABLE: 706 return PVR_HAS_FEATURE(pvr_dev, compute_morton_capable); 707 708 case PVR_FEATURE_FB_CDC_V4: 709 return PVR_HAS_FEATURE(pvr_dev, fb_cdc_v4); 710 711 case PVR_FEATURE_GPU_MULTICORE_SUPPORT: 712 return PVR_HAS_FEATURE(pvr_dev, gpu_multicore_support); 713 714 case PVR_FEATURE_ISP_ZLS_D24_S8_PACKING_OGL_MODE: 715 return PVR_HAS_FEATURE(pvr_dev, isp_zls_d24_s8_packing_ogl_mode); 716 717 case PVR_FEATURE_S7_TOP_INFRASTRUCTURE: 718 return PVR_HAS_FEATURE(pvr_dev, s7_top_infrastructure); 719 720 case PVR_FEATURE_TESSELLATION: 721 return PVR_HAS_FEATURE(pvr_dev, tessellation); 722 723 case PVR_FEATURE_TPU_DM_GLOBAL_REGISTERS: 724 return PVR_HAS_FEATURE(pvr_dev, tpu_dm_global_registers); 725 726 case PVR_FEATURE_VDM_DRAWINDIRECT: 727 return PVR_HAS_FEATURE(pvr_dev, vdm_drawindirect); 728 729 case PVR_FEATURE_VDM_OBJECT_LEVEL_LLS: 730 return PVR_HAS_FEATURE(pvr_dev, vdm_object_level_lls); 731 732 case PVR_FEATURE_ZLS_SUBTILE: 733 return PVR_HAS_FEATURE(pvr_dev, zls_subtile); 734 735 /* Derived features. */ 736 case PVR_FEATURE_CDM_USER_MODE_QUEUE: { 737 u8 cdm_control_stream_format = 0; 738 739 PVR_FEATURE_VALUE(pvr_dev, cdm_control_stream_format, &cdm_control_stream_format); 740 return (cdm_control_stream_format >= 2 && cdm_control_stream_format <= 4); 741 } 742 743 case PVR_FEATURE_REQUIRES_FB_CDC_ZLS_SETUP: 744 if (PVR_HAS_FEATURE(pvr_dev, fbcdc_algorithm)) { 745 u8 fbcdc_algorithm = 0; 746 747 PVR_FEATURE_VALUE(pvr_dev, fbcdc_algorithm, &fbcdc_algorithm); 748 return (fbcdc_algorithm < 3 || PVR_HAS_FEATURE(pvr_dev, fb_cdc_v4)); 749 } 750 return false; 751 752 default: 753 WARN(true, "Looking up undefined feature %u\n", feature); 754 return false; 755 } 756}
~/
Read-only file preview.