Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'drm-misc-next-2025-06-19' of https://gitlab.freedesktop.org/drm/misc/kernel into drm-next

drm-misc-next for 6.17:

UAPI Changes:
- Add Task Information for the wedge API

Cross-subsystem Changes:

Core Changes:
- Fix warnings related to export.h
- fbdev: Make CONFIG_FIRMWARE_EDID available on all architectures
- fence: Fix UAF issues
- format-helper: Improve tests

Driver Changes:
- ivpu: Add turbo flag, Add Wildcat Lake Support
- rz-du: Improve MIPI-DSI Support
- vmwgfx: fence improvement

Signed-off-by: Dave Airlie <airlied@redhat.com>

From: Maxime Ripard <mripard@redhat.com>
Link: https://lore.kernel.org/r/20250619-perfect-industrious-whippet-8ed3db@houat

+1487 -1432
+17
Documentation/gpu/drm-uapi.rst
··· 446 446 hang is usually the most critical one which can result in consequential hangs or 447 447 complete wedging. 448 448 449 + Task information 450 + --------------- 451 + 452 + The information about which application (if any) was involved in the device 453 + wedging is useful for userspace if they want to notify the user about what 454 + happened (e.g. the compositor display a message to the user "The <task name> 455 + caused a graphical error and the system recovered") or to implement policies 456 + (e.g. the daemon may "ban" an task that keeps resetting the device). If the task 457 + information is available, the uevent will display as ``PID=<pid>`` and 458 + ``TASK=<task name>``. Otherwise, ``PID`` and ``TASK`` will not appear in the 459 + event string. 460 + 461 + The reliability of this information is driver and hardware specific, and should 462 + be taken with a caution regarding it's precision. To have a big picture of what 463 + really happened, the devcoredump file provides should have much more detailed 464 + information about the device state and about the event. 465 + 449 466 Consumer prerequisites 450 467 ---------------------- 451 468
+4
arch/x86/kernel/setup.c
··· 213 213 */ 214 214 struct screen_info screen_info; 215 215 EXPORT_SYMBOL(screen_info); 216 + #if defined(CONFIG_FIRMWARE_EDID) 216 217 struct edid_info edid_info; 217 218 EXPORT_SYMBOL_GPL(edid_info); 219 + #endif 218 220 219 221 extern int root_mountflags; 220 222 ··· 527 525 { 528 526 ROOT_DEV = old_decode_dev(boot_params.hdr.root_dev); 529 527 screen_info = boot_params.screen_info; 528 + #if defined(CONFIG_FIRMWARE_EDID) 530 529 edid_info = boot_params.edid_info; 530 + #endif 531 531 #ifdef CONFIG_X86_32 532 532 apm_info.bios = boot_params.apm_bios_info; 533 533 ist_info = boot_params.ist_info;
+1 -1
drivers/accel/amdxdna/aie2_ctx.c
··· 566 566 .size = MAX_CHAIN_CMDBUF_SIZE, 567 567 }; 568 568 569 - abo = amdxdna_drm_alloc_dev_bo(&xdna->ddev, &args, client->filp, true); 569 + abo = amdxdna_drm_alloc_dev_bo(&xdna->ddev, &args, client->filp); 570 570 if (IS_ERR(abo)) { 571 571 ret = PTR_ERR(abo); 572 572 goto free_cmd_bufs;
+103 -88
drivers/accel/amdxdna/amdxdna_gem.c
··· 24 24 MODULE_IMPORT_NS("DMA_BUF"); 25 25 26 26 static int 27 - amdxdna_gem_insert_node_locked(struct amdxdna_gem_obj *abo, bool use_vmap) 27 + amdxdna_gem_heap_alloc(struct amdxdna_gem_obj *abo) 28 28 { 29 29 struct amdxdna_client *client = abo->client; 30 30 struct amdxdna_dev *xdna = client->xdna; 31 31 struct amdxdna_mem *mem = &abo->mem; 32 + struct amdxdna_gem_obj *heap; 32 33 u64 offset; 33 34 u32 align; 34 35 int ret; 35 36 37 + mutex_lock(&client->mm_lock); 38 + 39 + heap = client->dev_heap; 40 + if (!heap) { 41 + ret = -EINVAL; 42 + goto unlock_out; 43 + } 44 + 45 + if (heap->mem.userptr == AMDXDNA_INVALID_ADDR) { 46 + XDNA_ERR(xdna, "Invalid dev heap userptr"); 47 + ret = -EINVAL; 48 + goto unlock_out; 49 + } 50 + 51 + if (mem->size == 0 || mem->size > heap->mem.size) { 52 + XDNA_ERR(xdna, "Invalid dev bo size 0x%lx, limit 0x%lx", 53 + mem->size, heap->mem.size); 54 + ret = -EINVAL; 55 + goto unlock_out; 56 + } 57 + 36 58 align = 1 << max(PAGE_SHIFT, xdna->dev_info->dev_mem_buf_shift); 37 - ret = drm_mm_insert_node_generic(&abo->dev_heap->mm, &abo->mm_node, 59 + ret = drm_mm_insert_node_generic(&heap->mm, &abo->mm_node, 38 60 mem->size, align, 39 61 0, DRM_MM_INSERT_BEST); 40 62 if (ret) { 41 63 XDNA_ERR(xdna, "Failed to alloc dev bo memory, ret %d", ret); 42 - return ret; 64 + goto unlock_out; 43 65 } 44 66 45 67 mem->dev_addr = abo->mm_node.start; 46 - offset = mem->dev_addr - abo->dev_heap->mem.dev_addr; 47 - mem->userptr = abo->dev_heap->mem.userptr + offset; 48 - mem->pages = &abo->dev_heap->base.pages[offset >> PAGE_SHIFT]; 49 - mem->nr_pages = mem->size >> PAGE_SHIFT; 68 + offset = mem->dev_addr - heap->mem.dev_addr; 69 + mem->userptr = heap->mem.userptr + offset; 70 + mem->kva = heap->mem.kva + offset; 50 71 51 - if (use_vmap) { 52 - mem->kva = vmap(mem->pages, mem->nr_pages, VM_MAP, PAGE_KERNEL); 53 - if (!mem->kva) { 54 - XDNA_ERR(xdna, "Failed to vmap"); 55 - drm_mm_remove_node(&abo->mm_node); 56 - return -EFAULT; 57 - } 58 - } 72 + drm_gem_object_get(to_gobj(heap)); 59 73 60 - return 0; 74 + unlock_out: 75 + mutex_unlock(&client->mm_lock); 76 + 77 + return ret; 78 + } 79 + 80 + static void 81 + amdxdna_gem_destroy_obj(struct amdxdna_gem_obj *abo) 82 + { 83 + mutex_destroy(&abo->lock); 84 + kfree(abo); 85 + } 86 + 87 + static void 88 + amdxdna_gem_heap_free(struct amdxdna_gem_obj *abo) 89 + { 90 + struct amdxdna_gem_obj *heap; 91 + 92 + mutex_lock(&abo->client->mm_lock); 93 + 94 + drm_mm_remove_node(&abo->mm_node); 95 + 96 + heap = abo->client->dev_heap; 97 + drm_gem_object_put(to_gobj(heap)); 98 + 99 + mutex_unlock(&abo->client->mm_lock); 61 100 } 62 101 63 102 static bool amdxdna_hmm_invalidate(struct mmu_interval_notifier *mni, ··· 250 211 free_map: 251 212 kfree(mapp); 252 213 return ret; 214 + } 215 + 216 + static void amdxdna_gem_dev_obj_free(struct drm_gem_object *gobj) 217 + { 218 + struct amdxdna_dev *xdna = to_xdna_dev(gobj->dev); 219 + struct amdxdna_gem_obj *abo = to_xdna_obj(gobj); 220 + 221 + XDNA_DBG(xdna, "BO type %d xdna_addr 0x%llx", abo->type, abo->mem.dev_addr); 222 + if (abo->pinned) 223 + amdxdna_gem_unpin(abo); 224 + 225 + amdxdna_gem_heap_free(abo); 226 + drm_gem_object_release(gobj); 227 + amdxdna_gem_destroy_obj(abo); 253 228 } 254 229 255 230 static int amdxdna_insert_pages(struct amdxdna_gem_obj *abo, ··· 427 374 if (abo->pinned) 428 375 amdxdna_gem_unpin(abo); 429 376 430 - if (abo->type == AMDXDNA_BO_DEV) { 431 - mutex_lock(&abo->client->mm_lock); 432 - drm_mm_remove_node(&abo->mm_node); 433 - mutex_unlock(&abo->client->mm_lock); 434 - 435 - vunmap(abo->mem.kva); 436 - drm_gem_object_put(to_gobj(abo->dev_heap)); 437 - drm_gem_object_release(gobj); 438 - mutex_destroy(&abo->lock); 439 - kfree(abo); 440 - return; 441 - } 442 - 443 377 if (abo->type == AMDXDNA_BO_DEV_HEAP) 444 378 drm_mm_takedown(&abo->mm); 445 379 ··· 442 402 } 443 403 444 404 static const struct drm_gem_object_funcs amdxdna_gem_dev_obj_funcs = { 445 - .free = amdxdna_gem_obj_free, 405 + .free = amdxdna_gem_dev_obj_free, 446 406 }; 447 407 448 408 static const struct drm_gem_object_funcs amdxdna_gem_shmem_funcs = { ··· 567 527 struct drm_file *filp) 568 528 { 569 529 struct amdxdna_client *client = filp->driver_priv; 530 + struct iosys_map map = IOSYS_MAP_INIT_VADDR(NULL); 570 531 struct amdxdna_dev *xdna = to_xdna_dev(dev); 571 532 struct drm_gem_shmem_object *shmem; 572 533 struct amdxdna_gem_obj *abo; ··· 594 553 595 554 shmem->map_wc = false; 596 555 abo = to_xdna_obj(&shmem->base); 597 - 598 556 abo->type = AMDXDNA_BO_DEV_HEAP; 599 557 abo->client = client; 600 558 abo->mem.dev_addr = client->xdna->dev_info->dev_mem_base; 601 559 drm_mm_init(&abo->mm, abo->mem.dev_addr, abo->mem.size); 560 + 561 + ret = drm_gem_vmap(to_gobj(abo), &map); 562 + if (ret) { 563 + XDNA_ERR(xdna, "Vmap heap bo failed, ret %d", ret); 564 + goto release_obj; 565 + } 566 + abo->mem.kva = map.vaddr; 602 567 603 568 client->dev_heap = abo; 604 569 drm_gem_object_get(to_gobj(abo)); ··· 612 565 613 566 return abo; 614 567 568 + release_obj: 569 + drm_gem_object_put(to_gobj(abo)); 615 570 mm_unlock: 616 571 mutex_unlock(&client->mm_lock); 617 572 return ERR_PTR(ret); ··· 622 573 struct amdxdna_gem_obj * 623 574 amdxdna_drm_alloc_dev_bo(struct drm_device *dev, 624 575 struct amdxdna_drm_create_bo *args, 625 - struct drm_file *filp, bool use_vmap) 576 + struct drm_file *filp) 626 577 { 627 578 struct amdxdna_client *client = filp->driver_priv; 628 579 struct amdxdna_dev *xdna = to_xdna_dev(dev); 629 580 size_t aligned_sz = PAGE_ALIGN(args->size); 630 - struct amdxdna_gem_obj *abo, *heap; 581 + struct amdxdna_gem_obj *abo; 631 582 int ret; 632 583 633 - mutex_lock(&client->mm_lock); 634 - heap = client->dev_heap; 635 - if (!heap) { 636 - ret = -EINVAL; 637 - goto mm_unlock; 638 - } 639 - 640 - if (heap->mem.userptr == AMDXDNA_INVALID_ADDR) { 641 - XDNA_ERR(xdna, "Invalid dev heap userptr"); 642 - ret = -EINVAL; 643 - goto mm_unlock; 644 - } 645 - 646 - if (args->size > heap->mem.size) { 647 - XDNA_ERR(xdna, "Invalid dev bo size 0x%llx, limit 0x%lx", 648 - args->size, heap->mem.size); 649 - ret = -EINVAL; 650 - goto mm_unlock; 651 - } 652 - 653 584 abo = amdxdna_gem_create_obj(&xdna->ddev, aligned_sz); 654 - if (IS_ERR(abo)) { 655 - ret = PTR_ERR(abo); 656 - goto mm_unlock; 657 - } 585 + if (IS_ERR(abo)) 586 + return abo; 587 + 658 588 to_gobj(abo)->funcs = &amdxdna_gem_dev_obj_funcs; 659 589 abo->type = AMDXDNA_BO_DEV; 660 590 abo->client = client; 661 - abo->dev_heap = heap; 662 - ret = amdxdna_gem_insert_node_locked(abo, use_vmap); 591 + 592 + ret = amdxdna_gem_heap_alloc(abo); 663 593 if (ret) { 664 594 XDNA_ERR(xdna, "Failed to alloc dev bo memory, ret %d", ret); 665 - goto mm_unlock; 595 + amdxdna_gem_destroy_obj(abo); 596 + return ERR_PTR(ret); 666 597 } 667 598 668 - drm_gem_object_get(to_gobj(heap)); 669 599 drm_gem_private_object_init(&xdna->ddev, to_gobj(abo), aligned_sz); 670 600 671 - mutex_unlock(&client->mm_lock); 672 601 return abo; 673 - 674 - mm_unlock: 675 - mutex_unlock(&client->mm_lock); 676 - return ERR_PTR(ret); 677 602 } 678 603 679 604 static struct amdxdna_gem_obj * ··· 655 632 struct amdxdna_drm_create_bo *args, 656 633 struct drm_file *filp) 657 634 { 635 + struct iosys_map map = IOSYS_MAP_INIT_VADDR(NULL); 658 636 struct amdxdna_dev *xdna = to_xdna_dev(dev); 659 637 struct drm_gem_shmem_object *shmem; 660 638 struct amdxdna_gem_obj *abo; 661 - struct iosys_map map; 662 639 int ret; 663 640 664 641 if (args->size > XDNA_MAX_CMD_BO_SIZE) { ··· 715 692 abo = amdxdna_drm_create_dev_heap(dev, args, filp); 716 693 break; 717 694 case AMDXDNA_BO_DEV: 718 - abo = amdxdna_drm_alloc_dev_bo(dev, args, filp, false); 695 + abo = amdxdna_drm_alloc_dev_bo(dev, args, filp); 719 696 break; 720 697 case AMDXDNA_BO_CMD: 721 698 abo = amdxdna_drm_create_cmd_bo(dev, args, filp); ··· 747 724 struct amdxdna_dev *xdna = to_xdna_dev(to_gobj(abo)->dev); 748 725 int ret; 749 726 727 + if (abo->type == AMDXDNA_BO_DEV) 728 + abo = abo->client->dev_heap; 729 + 750 730 if (is_import_bo(abo)) 751 731 return 0; 752 732 753 - switch (abo->type) { 754 - case AMDXDNA_BO_SHMEM: 755 - case AMDXDNA_BO_DEV_HEAP: 756 - ret = drm_gem_shmem_pin(&abo->base); 757 - break; 758 - case AMDXDNA_BO_DEV: 759 - ret = drm_gem_shmem_pin(&abo->dev_heap->base); 760 - break; 761 - default: 762 - ret = -EOPNOTSUPP; 763 - } 733 + ret = drm_gem_shmem_pin(&abo->base); 764 734 765 735 XDNA_DBG(xdna, "BO type %d ret %d", abo->type, ret); 766 736 return ret; ··· 762 746 int amdxdna_gem_pin(struct amdxdna_gem_obj *abo) 763 747 { 764 748 int ret; 765 - 766 - if (abo->type == AMDXDNA_BO_DEV) 767 - abo = abo->dev_heap; 768 749 769 750 mutex_lock(&abo->lock); 770 751 ret = amdxdna_gem_pin_nolock(abo); ··· 772 759 773 760 void amdxdna_gem_unpin(struct amdxdna_gem_obj *abo) 774 761 { 762 + if (abo->type == AMDXDNA_BO_DEV) 763 + abo = abo->client->dev_heap; 764 + 775 765 if (is_import_bo(abo)) 776 766 return; 777 - 778 - if (abo->type == AMDXDNA_BO_DEV) 779 - abo = abo->dev_heap; 780 767 781 768 mutex_lock(&abo->lock); 782 769 drm_gem_shmem_unpin(&abo->base); ··· 868 855 869 856 if (is_import_bo(abo)) 870 857 drm_clflush_sg(abo->base.sgt); 871 - else if (abo->type == AMDXDNA_BO_DEV) 872 - drm_clflush_pages(abo->mem.pages, abo->mem.nr_pages); 873 - else 858 + else if (abo->mem.kva) 859 + drm_clflush_virt_range(abo->mem.kva + args->offset, args->size); 860 + else if (abo->base.pages) 874 861 drm_clflush_pages(abo->base.pages, gobj->size >> PAGE_SHIFT); 862 + else 863 + drm_WARN(&xdna->ddev, 1, "Can not get flush memory"); 875 864 876 865 amdxdna_gem_unpin(abo); 877 866
+1 -2
drivers/accel/amdxdna/amdxdna_gem.h
··· 41 41 42 42 /* Below members is uninitialized when needed */ 43 43 struct drm_mm mm; /* For AMDXDNA_BO_DEV_HEAP */ 44 - struct amdxdna_gem_obj *dev_heap; /* For AMDXDNA_BO_DEV */ 45 44 struct drm_mm_node mm_node; /* For AMDXDNA_BO_DEV */ 46 45 u32 assigned_hwctx; 47 46 struct dma_buf *dma_buf; ··· 71 72 struct amdxdna_gem_obj * 72 73 amdxdna_drm_alloc_dev_bo(struct drm_device *dev, 73 74 struct amdxdna_drm_create_bo *args, 74 - struct drm_file *filp, bool use_vmap); 75 + struct drm_file *filp); 75 76 76 77 int amdxdna_gem_pin_nolock(struct amdxdna_gem_obj *abo); 77 78 int amdxdna_gem_pin(struct amdxdna_gem_obj *abo);
+1
drivers/accel/ivpu/ivpu_drv.c
··· 704 704 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_ARL) }, 705 705 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_LNL) }, 706 706 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PTL_P) }, 707 + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_WCL) }, 707 708 { } 708 709 }; 709 710 MODULE_DEVICE_TABLE(pci, ivpu_pci_ids);
+9 -5
drivers/accel/ivpu/ivpu_drv.h
··· 1 1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 2 /* 3 - * Copyright (C) 2020-2024 Intel Corporation 3 + * Copyright (C) 2020-2025 Intel Corporation 4 4 */ 5 5 6 6 #ifndef __IVPU_DRV_H__ ··· 26 26 #define PCI_DEVICE_ID_ARL 0xad1d 27 27 #define PCI_DEVICE_ID_LNL 0x643e 28 28 #define PCI_DEVICE_ID_PTL_P 0xb03e 29 + #define PCI_DEVICE_ID_WCL 0xfd3e 29 30 30 31 #define IVPU_HW_IP_37XX 37 31 32 #define IVPU_HW_IP_40XX 40 ··· 209 208 #define IVPU_TEST_MODE_D0I3_MSG_ENABLE BIT(5) 210 209 #define IVPU_TEST_MODE_MIP_DISABLE BIT(6) 211 210 #define IVPU_TEST_MODE_DISABLE_TIMEOUTS BIT(8) 212 - #define IVPU_TEST_MODE_TURBO BIT(9) 213 - #define IVPU_TEST_MODE_CLK_RELINQ_DISABLE BIT(10) 214 - #define IVPU_TEST_MODE_CLK_RELINQ_ENABLE BIT(11) 215 - #define IVPU_TEST_MODE_D0I2_DISABLE BIT(12) 211 + #define IVPU_TEST_MODE_TURBO_ENABLE BIT(9) 212 + #define IVPU_TEST_MODE_TURBO_DISABLE BIT(10) 213 + #define IVPU_TEST_MODE_CLK_RELINQ_DISABLE BIT(11) 214 + #define IVPU_TEST_MODE_CLK_RELINQ_ENABLE BIT(12) 215 + #define IVPU_TEST_MODE_D0I2_DISABLE BIT(13) 216 216 extern int ivpu_test_mode; 217 217 218 218 struct ivpu_file_priv *ivpu_file_priv_get(struct ivpu_file_priv *file_priv); ··· 243 241 case PCI_DEVICE_ID_LNL: 244 242 return IVPU_HW_IP_40XX; 245 243 case PCI_DEVICE_ID_PTL_P: 244 + case PCI_DEVICE_ID_WCL: 246 245 return IVPU_HW_IP_50XX; 247 246 default: 248 247 dump_stack(); ··· 260 257 return IVPU_HW_BTRS_MTL; 261 258 case PCI_DEVICE_ID_LNL: 262 259 case PCI_DEVICE_ID_PTL_P: 260 + case PCI_DEVICE_ID_WCL: 263 261 return IVPU_HW_BTRS_LNL; 264 262 default: 265 263 dump_stack();
+1
drivers/accel/ivpu/ivpu_hw_ip.c
··· 683 683 return; 684 684 685 685 switch (ivpu_device_id(vdev)) { 686 + case PCI_DEVICE_ID_WCL: 686 687 case PCI_DEVICE_ID_PTL_P: 687 688 post = high ? 18 : 0; 688 689 post1 = 0;
+53 -28
drivers/accel/ivpu/ivpu_job.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 2 /* 3 - * Copyright (C) 2020-2024 Intel Corporation 3 + * Copyright (C) 2020-2025 Intel Corporation 4 4 */ 5 5 6 6 #include <drm/drm_file.h> ··· 100 100 return NULL; 101 101 } 102 102 103 + /** 104 + * ivpu_cmdq_get_entry_count - Calculate the number of entries in the command queue. 105 + * @cmdq: Pointer to the command queue structure. 106 + * 107 + * Returns the number of entries that can fit in the command queue memory. 108 + */ 109 + static inline u32 ivpu_cmdq_get_entry_count(struct ivpu_cmdq *cmdq) 110 + { 111 + size_t size = ivpu_bo_size(cmdq->mem) - sizeof(struct vpu_job_queue_header); 112 + 113 + return size / sizeof(struct vpu_job_queue_entry); 114 + } 115 + 116 + /** 117 + * ivpu_cmdq_get_flags - Get command queue flags based on input flags and test mode. 118 + * @vdev: Pointer to the ivpu device structure. 119 + * @flags: Input flags to determine the command queue flags. 120 + * 121 + * Returns the calculated command queue flags, considering both the input flags 122 + * and the current test mode settings. 123 + */ 124 + static u32 ivpu_cmdq_get_flags(struct ivpu_device *vdev, u32 flags) 125 + { 126 + u32 cmdq_flags = 0; 127 + 128 + if ((flags & DRM_IVPU_CMDQ_FLAG_TURBO) && (ivpu_hw_ip_gen(vdev) >= IVPU_HW_IP_40XX)) 129 + cmdq_flags |= VPU_JOB_QUEUE_FLAGS_TURBO_MODE; 130 + 131 + /* Test mode can override the TURBO flag coming from the application */ 132 + if (ivpu_test_mode & IVPU_TEST_MODE_TURBO_ENABLE) 133 + cmdq_flags |= VPU_JOB_QUEUE_FLAGS_TURBO_MODE; 134 + if (ivpu_test_mode & IVPU_TEST_MODE_TURBO_DISABLE) 135 + cmdq_flags &= ~VPU_JOB_QUEUE_FLAGS_TURBO_MODE; 136 + 137 + return cmdq_flags; 138 + } 139 + 103 140 static void ivpu_cmdq_free(struct ivpu_file_priv *file_priv, struct ivpu_cmdq *cmdq) 104 141 { 105 142 ivpu_preemption_buffers_free(file_priv->vdev, file_priv, cmdq); ··· 144 107 kfree(cmdq); 145 108 } 146 109 147 - static struct ivpu_cmdq *ivpu_cmdq_create(struct ivpu_file_priv *file_priv, u8 priority, 148 - bool is_legacy) 110 + static struct ivpu_cmdq *ivpu_cmdq_create(struct ivpu_file_priv *file_priv, u8 priority, u32 flags) 149 111 { 150 112 struct ivpu_device *vdev = file_priv->vdev; 151 113 struct ivpu_cmdq *cmdq = NULL; ··· 157 121 ivpu_err(vdev, "Failed to allocate command queue\n"); 158 122 return NULL; 159 123 } 160 - 161 - cmdq->priority = priority; 162 - cmdq->is_legacy = is_legacy; 163 - 164 124 ret = xa_alloc_cyclic(&file_priv->cmdq_xa, &cmdq->id, cmdq, file_priv->cmdq_limit, 165 125 &file_priv->cmdq_id_next, GFP_KERNEL); 166 126 if (ret < 0) { ··· 164 132 goto err_free_cmdq; 165 133 } 166 134 167 - ivpu_dbg(vdev, JOB, "Command queue %d created, ctx %d\n", cmdq->id, file_priv->ctx.id); 135 + cmdq->entry_count = ivpu_cmdq_get_entry_count(cmdq); 136 + cmdq->priority = priority; 137 + 138 + cmdq->jobq = (struct vpu_job_queue *)ivpu_bo_vaddr(cmdq->mem); 139 + cmdq->jobq->header.engine_idx = VPU_ENGINE_COMPUTE; 140 + cmdq->jobq->header.flags = ivpu_cmdq_get_flags(vdev, flags); 141 + 142 + ivpu_dbg(vdev, JOB, "Command queue %d created, ctx %d, flags 0x%08x\n", 143 + cmdq->id, file_priv->ctx.id, cmdq->jobq->header.flags); 168 144 return cmdq; 169 145 170 146 err_free_cmdq: ··· 228 188 return ret; 229 189 } 230 190 231 - static void ivpu_cmdq_jobq_init(struct ivpu_device *vdev, struct vpu_job_queue *jobq) 191 + static void ivpu_cmdq_jobq_reset(struct ivpu_device *vdev, struct vpu_job_queue *jobq) 232 192 { 233 - jobq->header.engine_idx = VPU_ENGINE_COMPUTE; 234 193 jobq->header.head = 0; 235 194 jobq->header.tail = 0; 236 195 237 - if (ivpu_test_mode & IVPU_TEST_MODE_TURBO) { 238 - ivpu_dbg(vdev, JOB, "Turbo mode enabled"); 239 - jobq->header.flags = VPU_JOB_QUEUE_FLAGS_TURBO_MODE; 240 - } 241 - 242 196 wmb(); /* Flush WC buffer for jobq->header */ 243 - } 244 - 245 - static inline u32 ivpu_cmdq_get_entry_count(struct ivpu_cmdq *cmdq) 246 - { 247 - size_t size = ivpu_bo_size(cmdq->mem) - sizeof(struct vpu_job_queue_header); 248 - 249 - return size / sizeof(struct vpu_job_queue_entry); 250 197 } 251 198 252 199 static int ivpu_cmdq_register(struct ivpu_file_priv *file_priv, struct ivpu_cmdq *cmdq) ··· 246 219 if (cmdq->db_id) 247 220 return 0; 248 221 249 - cmdq->entry_count = ivpu_cmdq_get_entry_count(cmdq); 250 - cmdq->jobq = (struct vpu_job_queue *)ivpu_bo_vaddr(cmdq->mem); 251 - 252 - ivpu_cmdq_jobq_init(vdev, cmdq->jobq); 222 + ivpu_cmdq_jobq_reset(vdev, cmdq->jobq); 253 223 254 224 if (vdev->fw->sched_mode == VPU_SCHEDULING_MODE_HW) { 255 225 ret = ivpu_hws_cmdq_init(file_priv, cmdq, VPU_ENGINE_COMPUTE, cmdq->priority); ··· 315 291 break; 316 292 317 293 if (!cmdq) { 318 - cmdq = ivpu_cmdq_create(file_priv, priority, true); 294 + cmdq = ivpu_cmdq_create(file_priv, priority, 0); 319 295 if (!cmdq) 320 296 return NULL; 297 + cmdq->is_legacy = true; 321 298 } 322 299 323 300 return cmdq; ··· 916 891 917 892 mutex_lock(&file_priv->lock); 918 893 919 - cmdq = ivpu_cmdq_create(file_priv, ivpu_job_to_jsm_priority(args->priority), false); 894 + cmdq = ivpu_cmdq_create(file_priv, ivpu_job_to_jsm_priority(args->priority), args->flags); 920 895 if (cmdq) 921 896 args->cmdq_id = cmdq->id; 922 897
+101 -10
drivers/dma-buf/dma-fence.c
··· 511 511 512 512 dma_fence_enable_sw_signaling(fence); 513 513 514 - trace_dma_fence_wait_start(fence); 514 + if (trace_dma_fence_wait_start_enabled()) { 515 + rcu_read_lock(); 516 + trace_dma_fence_wait_start(fence); 517 + rcu_read_unlock(); 518 + } 515 519 if (fence->ops->wait) 516 520 ret = fence->ops->wait(fence, intr, timeout); 517 521 else 518 522 ret = dma_fence_default_wait(fence, intr, timeout); 519 - trace_dma_fence_wait_end(fence); 523 + if (trace_dma_fence_wait_end_enabled()) { 524 + rcu_read_lock(); 525 + trace_dma_fence_wait_end(fence); 526 + rcu_read_unlock(); 527 + } 520 528 return ret; 521 529 } 522 530 EXPORT_SYMBOL(dma_fence_wait_timeout); ··· 541 533 struct dma_fence *fence = 542 534 container_of(kref, struct dma_fence, refcount); 543 535 536 + rcu_read_lock(); 544 537 trace_dma_fence_destroy(fence); 545 538 546 - if (WARN(!list_empty(&fence->cb_list) && 547 - !test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags), 548 - "Fence %s:%s:%llx:%llx released with pending signals!\n", 549 - dma_fence_driver_name(fence), 550 - dma_fence_timeline_name(fence), 551 - fence->context, fence->seqno)) { 539 + if (!list_empty(&fence->cb_list) && 540 + !test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags)) { 541 + const char __rcu *timeline; 542 + const char __rcu *driver; 552 543 unsigned long flags; 544 + 545 + driver = dma_fence_driver_name(fence); 546 + timeline = dma_fence_timeline_name(fence); 547 + 548 + WARN(1, 549 + "Fence %s:%s:%llx:%llx released with pending signals!\n", 550 + rcu_dereference(driver), rcu_dereference(timeline), 551 + fence->context, fence->seqno); 553 552 554 553 /* 555 554 * Failed to signal before release, likely a refcounting issue. ··· 570 555 dma_fence_signal_locked(fence); 571 556 spin_unlock_irqrestore(fence->lock, flags); 572 557 } 558 + 559 + rcu_read_unlock(); 573 560 574 561 if (fence->ops->release) 575 562 fence->ops->release(fence); ··· 999 982 */ 1000 983 void dma_fence_describe(struct dma_fence *fence, struct seq_file *seq) 1001 984 { 985 + const char __rcu *timeline; 986 + const char __rcu *driver; 987 + 988 + rcu_read_lock(); 989 + 990 + timeline = dma_fence_timeline_name(fence); 991 + driver = dma_fence_driver_name(fence); 992 + 1002 993 seq_printf(seq, "%s %s seq %llu %ssignalled\n", 1003 - dma_fence_driver_name(fence), 1004 - dma_fence_timeline_name(fence), 994 + rcu_dereference(driver), 995 + rcu_dereference(timeline), 1005 996 fence->seqno, 1006 997 dma_fence_is_signaled(fence) ? "" : "un"); 998 + 999 + rcu_read_unlock(); 1007 1000 } 1008 1001 EXPORT_SYMBOL(dma_fence_describe); 1009 1002 ··· 1082 1055 BIT(DMA_FENCE_FLAG_SEQNO64_BIT)); 1083 1056 } 1084 1057 EXPORT_SYMBOL(dma_fence_init64); 1058 + 1059 + /** 1060 + * dma_fence_driver_name - Access the driver name 1061 + * @fence: the fence to query 1062 + * 1063 + * Returns a driver name backing the dma-fence implementation. 1064 + * 1065 + * IMPORTANT CONSIDERATION: 1066 + * Dma-fence contract stipulates that access to driver provided data (data not 1067 + * directly embedded into the object itself), such as the &dma_fence.lock and 1068 + * memory potentially accessed by the &dma_fence.ops functions, is forbidden 1069 + * after the fence has been signalled. Drivers are allowed to free that data, 1070 + * and some do. 1071 + * 1072 + * To allow safe access drivers are mandated to guarantee a RCU grace period 1073 + * between signalling the fence and freeing said data. 1074 + * 1075 + * As such access to the driver name is only valid inside a RCU locked section. 1076 + * The pointer MUST be both queried and USED ONLY WITHIN a SINGLE block guarded 1077 + * by the &rcu_read_lock and &rcu_read_unlock pair. 1078 + */ 1079 + const char __rcu *dma_fence_driver_name(struct dma_fence *fence) 1080 + { 1081 + RCU_LOCKDEP_WARN(!rcu_read_lock_held(), 1082 + "RCU protection is required for safe access to returned string"); 1083 + 1084 + if (!test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags)) 1085 + return fence->ops->get_driver_name(fence); 1086 + else 1087 + return "detached-driver"; 1088 + } 1089 + EXPORT_SYMBOL(dma_fence_driver_name); 1090 + 1091 + /** 1092 + * dma_fence_timeline_name - Access the timeline name 1093 + * @fence: the fence to query 1094 + * 1095 + * Returns a timeline name provided by the dma-fence implementation. 1096 + * 1097 + * IMPORTANT CONSIDERATION: 1098 + * Dma-fence contract stipulates that access to driver provided data (data not 1099 + * directly embedded into the object itself), such as the &dma_fence.lock and 1100 + * memory potentially accessed by the &dma_fence.ops functions, is forbidden 1101 + * after the fence has been signalled. Drivers are allowed to free that data, 1102 + * and some do. 1103 + * 1104 + * To allow safe access drivers are mandated to guarantee a RCU grace period 1105 + * between signalling the fence and freeing said data. 1106 + * 1107 + * As such access to the driver name is only valid inside a RCU locked section. 1108 + * The pointer MUST be both queried and USED ONLY WITHIN a SINGLE block guarded 1109 + * by the &rcu_read_lock and &rcu_read_unlock pair. 1110 + */ 1111 + const char __rcu *dma_fence_timeline_name(struct dma_fence *fence) 1112 + { 1113 + RCU_LOCKDEP_WARN(!rcu_read_lock_held(), 1114 + "RCU protection is required for safe access to returned string"); 1115 + 1116 + if (!test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags)) 1117 + return fence->ops->get_driver_name(fence); 1118 + else 1119 + return "signaled-timeline"; 1120 + } 1121 + EXPORT_SYMBOL(dma_fence_timeline_name);
+20 -4
drivers/dma-buf/sync_file.c
··· 135 135 strscpy(buf, sync_file->user_name, len); 136 136 } else { 137 137 struct dma_fence *fence = sync_file->fence; 138 + const char __rcu *timeline; 139 + const char __rcu *driver; 138 140 141 + rcu_read_lock(); 142 + driver = dma_fence_driver_name(fence); 143 + timeline = dma_fence_timeline_name(fence); 139 144 snprintf(buf, len, "%s-%s%llu-%lld", 140 - dma_fence_driver_name(fence), 141 - dma_fence_timeline_name(fence), 145 + rcu_dereference(driver), 146 + rcu_dereference(timeline), 142 147 fence->context, 143 148 fence->seqno); 149 + rcu_read_unlock(); 144 150 } 145 151 146 152 return buf; ··· 268 262 static int sync_fill_fence_info(struct dma_fence *fence, 269 263 struct sync_fence_info *info) 270 264 { 271 - strscpy(info->obj_name, dma_fence_timeline_name(fence), 265 + const char __rcu *timeline; 266 + const char __rcu *driver; 267 + 268 + rcu_read_lock(); 269 + 270 + driver = dma_fence_driver_name(fence); 271 + timeline = dma_fence_timeline_name(fence); 272 + 273 + strscpy(info->obj_name, rcu_dereference(timeline), 272 274 sizeof(info->obj_name)); 273 - strscpy(info->driver_name, dma_fence_driver_name(fence), 275 + strscpy(info->driver_name, rcu_dereference(driver), 274 276 sizeof(info->driver_name)); 275 277 276 278 info->status = dma_fence_get_status(fence); ··· 286 272 dma_fence_is_signaled(fence) ? 287 273 ktime_to_ns(dma_fence_timestamp(fence)) : 288 274 ktime_set(0, 0); 275 + 276 + rcu_read_unlock(); 289 277 290 278 return info->status; 291 279 }
+1
drivers/gpu/drm/Kconfig.debug
··· 70 70 select DRM_GEM_SHMEM_HELPER 71 71 select DRM_KUNIT_TEST_HELPERS 72 72 select DRM_LIB_RANDOM 73 + select DRM_SYSFB_HELPER 73 74 select PRIME_NUMBERS 74 75 default KUNIT_ALL_TESTS 75 76 help
+1 -1
drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c
··· 1786 1786 1787 1787 ti = amdgpu_vm_get_task_info_vm(vm); 1788 1788 if (ti) { 1789 - seq_printf(m, "pid:%d\tProcess:%s ----------\n", ti->pid, ti->process_name); 1789 + seq_printf(m, "pid:%d\tProcess:%s ----------\n", ti->task.pid, ti->process_name); 1790 1790 amdgpu_vm_put_task_info(ti); 1791 1791 } 1792 1792
+2 -2
drivers/gpu/drm/amd/amdgpu/amdgpu_dev_coredump.c
··· 220 220 drm_printf(&p, "time: %lld.%09ld\n", coredump->reset_time.tv_sec, 221 221 coredump->reset_time.tv_nsec); 222 222 223 - if (coredump->reset_task_info.pid) 223 + if (coredump->reset_task_info.task.pid) 224 224 drm_printf(&p, "process_name: %s PID: %d\n", 225 225 coredump->reset_task_info.process_name, 226 - coredump->reset_task_info.pid); 226 + coredump->reset_task_info.task.pid); 227 227 228 228 /* SOC Information */ 229 229 drm_printf(&p, "\nSOC Information\n");
+11 -2
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
··· 6363 6363 6364 6364 atomic_set(&adev->reset_domain->reset_res, r); 6365 6365 6366 - if (!r) 6367 - drm_dev_wedged_event(adev_to_drm(adev), DRM_WEDGE_RECOVERY_NONE); 6366 + if (!r) { 6367 + struct amdgpu_task_info *ti = NULL; 6368 + 6369 + if (job) 6370 + ti = amdgpu_vm_get_task_info_pasid(adev, job->pasid); 6371 + 6372 + drm_dev_wedged_event(adev_to_drm(adev), DRM_WEDGE_RECOVERY_NONE, 6373 + ti ? &ti->task : NULL); 6374 + 6375 + amdgpu_vm_put_task_info(ti); 6376 + } 6368 6377 6369 6378 return r; 6370 6379 }
+1 -1
drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
··· 329 329 330 330 dev_warn(adev->dev, "validate_and_fence failed: %d\n", r); 331 331 if (ti) { 332 - dev_warn(adev->dev, "pid %d\n", ti->pid); 332 + dev_warn(adev->dev, "pid %d\n", ti->task.pid); 333 333 amdgpu_vm_put_task_info(ti); 334 334 } 335 335 }
+6 -5
drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
··· 89 89 { 90 90 struct amdgpu_ring *ring = to_amdgpu_ring(s_job->sched); 91 91 struct amdgpu_job *job = to_amdgpu_job(s_job); 92 + struct drm_wedge_task_info *info = NULL; 92 93 struct amdgpu_task_info *ti; 93 94 struct amdgpu_device *adev = ring->adev; 94 95 int idx; ··· 125 124 126 125 ti = amdgpu_vm_get_task_info_pasid(ring->adev, job->pasid); 127 126 if (ti) { 128 - dev_err(adev->dev, 129 - "Process information: process %s pid %d thread %s pid %d\n", 130 - ti->process_name, ti->tgid, ti->task_name, ti->pid); 131 - amdgpu_vm_put_task_info(ti); 127 + amdgpu_vm_print_task_info(adev, ti); 128 + info = &ti->task; 132 129 } 133 130 134 131 /* attempt a per ring reset */ ··· 165 166 if (amdgpu_ring_sched_ready(ring)) 166 167 drm_sched_start(&ring->sched, 0); 167 168 dev_err(adev->dev, "Ring %s reset succeeded\n", ring->sched.name); 168 - drm_dev_wedged_event(adev_to_drm(adev), DRM_WEDGE_RECOVERY_NONE); 169 + drm_dev_wedged_event(adev_to_drm(adev), DRM_WEDGE_RECOVERY_NONE, info); 169 170 goto exit; 170 171 } 171 172 dev_err(adev->dev, "Ring %s reset failure\n", ring->sched.name); 172 173 } 173 174 dma_fence_set_error(&s_job->s_fence->finished, -ETIME); 175 + 176 + amdgpu_vm_put_task_info(ti); 174 177 175 178 if (amdgpu_device_should_recover_gpu(ring->adev)) { 176 179 struct amdgpu_reset_context reset_context;
+16 -6
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
··· 622 622 623 623 pr_warn_ratelimited("Evicted user BO is not reserved\n"); 624 624 if (ti) { 625 - pr_warn_ratelimited("pid %d\n", ti->pid); 625 + pr_warn_ratelimited("pid %d\n", ti->task.pid); 626 626 amdgpu_vm_put_task_info(ti); 627 627 } 628 628 ··· 2447 2447 */ 2448 2448 void amdgpu_vm_put_task_info(struct amdgpu_task_info *task_info) 2449 2449 { 2450 - kref_put(&task_info->refcount, amdgpu_vm_destroy_task_info); 2450 + if (task_info) 2451 + kref_put(&task_info->refcount, amdgpu_vm_destroy_task_info); 2451 2452 } 2452 2453 2453 2454 /** ··· 2508 2507 if (!vm->task_info) 2509 2508 return; 2510 2509 2511 - if (vm->task_info->pid == current->pid) 2510 + if (vm->task_info->task.pid == current->pid) 2512 2511 return; 2513 2512 2514 - vm->task_info->pid = current->pid; 2515 - get_task_comm(vm->task_info->task_name, current); 2513 + vm->task_info->task.pid = current->pid; 2514 + get_task_comm(vm->task_info->task.comm, current); 2516 2515 2517 2516 if (current->group_leader->mm != current->mm) 2518 2517 return; ··· 2775 2774 2776 2775 dev_warn(adev->dev, 2777 2776 "VM memory stats for proc %s(%d) task %s(%d) is non-zero when fini\n", 2778 - ti->process_name, ti->pid, ti->task_name, ti->tgid); 2777 + ti->process_name, ti->task.pid, ti->task.comm, ti->tgid); 2779 2778 } 2780 2779 2781 2780 amdgpu_vm_put_task_info(vm->task_info); ··· 3156 3155 bool amdgpu_vm_is_bo_always_valid(struct amdgpu_vm *vm, struct amdgpu_bo *bo) 3157 3156 { 3158 3157 return bo && bo->tbo.base.resv == vm->root.bo->tbo.base.resv; 3158 + } 3159 + 3160 + void amdgpu_vm_print_task_info(struct amdgpu_device *adev, 3161 + struct amdgpu_task_info *task_info) 3162 + { 3163 + dev_err(adev->dev, 3164 + " Process %s pid %d thread %s pid %d\n", 3165 + task_info->process_name, task_info->tgid, 3166 + task_info->task.comm, task_info->task.pid); 3159 3167 }
+4 -2
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
··· 236 236 }; 237 237 238 238 struct amdgpu_task_info { 239 + struct drm_wedge_task_info task; 239 240 char process_name[TASK_COMM_LEN]; 240 - char task_name[TASK_COMM_LEN]; 241 - pid_t pid; 242 241 pid_t tgid; 243 242 struct kref refcount; 244 243 }; ··· 666 667 void amdgpu_vm_tlb_fence_create(struct amdgpu_device *adev, 667 668 struct amdgpu_vm *vm, 668 669 struct dma_fence **fence); 670 + 671 + void amdgpu_vm_print_task_info(struct amdgpu_device *adev, 672 + struct amdgpu_task_info *task_info); 669 673 670 674 #endif
+1 -4
drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
··· 164 164 entry->src_id, entry->ring_id, entry->vmid, entry->pasid); 165 165 task_info = amdgpu_vm_get_task_info_pasid(adev, entry->pasid); 166 166 if (task_info) { 167 - dev_err(adev->dev, 168 - " in process %s pid %d thread %s pid %d\n", 169 - task_info->process_name, task_info->tgid, 170 - task_info->task_name, task_info->pid); 167 + amdgpu_vm_print_task_info(adev, task_info); 171 168 amdgpu_vm_put_task_info(task_info); 172 169 } 173 170
+1 -4
drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c
··· 134 134 entry->src_id, entry->ring_id, entry->vmid, entry->pasid); 135 135 task_info = amdgpu_vm_get_task_info_pasid(adev, entry->pasid); 136 136 if (task_info) { 137 - dev_err(adev->dev, 138 - " in process %s pid %d thread %s pid %d)\n", 139 - task_info->process_name, task_info->tgid, 140 - task_info->task_name, task_info->pid); 137 + amdgpu_vm_print_task_info(adev, task_info); 141 138 amdgpu_vm_put_task_info(task_info); 142 139 } 143 140
+1 -4
drivers/gpu/drm/amd/amdgpu/gmc_v12_0.c
··· 127 127 entry->src_id, entry->ring_id, entry->vmid, entry->pasid); 128 128 task_info = amdgpu_vm_get_task_info_pasid(adev, entry->pasid); 129 129 if (task_info) { 130 - dev_err(adev->dev, 131 - " in process %s pid %d thread %s pid %d)\n", 132 - task_info->process_name, task_info->tgid, 133 - task_info->task_name, task_info->pid); 130 + amdgpu_vm_print_task_info(adev, task_info); 134 131 amdgpu_vm_put_task_info(task_info); 135 132 } 136 133
+1 -3
drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
··· 1458 1458 1459 1459 task_info = amdgpu_vm_get_task_info_pasid(adev, entry->pasid); 1460 1460 if (task_info) { 1461 - dev_err(adev->dev, " for process %s pid %d thread %s pid %d\n", 1462 - task_info->process_name, task_info->tgid, 1463 - task_info->task_name, task_info->pid); 1461 + amdgpu_vm_print_task_info(adev, task_info); 1464 1462 amdgpu_vm_put_task_info(task_info); 1465 1463 } 1466 1464
+1 -4
drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
··· 641 641 642 642 task_info = amdgpu_vm_get_task_info_pasid(adev, entry->pasid); 643 643 if (task_info) { 644 - dev_err(adev->dev, 645 - " for process %s pid %d thread %s pid %d)\n", 646 - task_info->process_name, task_info->tgid, 647 - task_info->task_name, task_info->pid); 644 + amdgpu_vm_print_task_info(adev, task_info); 648 645 amdgpu_vm_put_task_info(task_info); 649 646 } 650 647
+1 -1
drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
··· 2187 2187 dev_dbg_ratelimited(adev->dev, 2188 2188 " for process %s pid %d thread %s pid %d\n", 2189 2189 task_info->process_name, task_info->tgid, 2190 - task_info->task_name, task_info->pid); 2190 + task_info->task.comm, task_info->task.pid); 2191 2191 amdgpu_vm_put_task_info(task_info); 2192 2192 } 2193 2193
+1 -1
drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c
··· 1884 1884 if (task_info) { 1885 1885 dev_dbg_ratelimited(adev->dev, " for process %s pid %d thread %s pid %d\n", 1886 1886 task_info->process_name, task_info->tgid, 1887 - task_info->task_name, task_info->pid); 1887 + task_info->task.comm, task_info->task.pid); 1888 1888 amdgpu_vm_put_task_info(task_info); 1889 1889 } 1890 1890
+1 -1
drivers/gpu/drm/amd/amdkfd/kfd_events.c
··· 1302 1302 if (ti) { 1303 1303 dev_err(dev->adev->dev, 1304 1304 "Queues reset on process %s tid %d thread %s pid %d\n", 1305 - ti->process_name, ti->tgid, ti->task_name, ti->pid); 1305 + ti->process_name, ti->tgid, ti->task.comm, ti->task.pid); 1306 1306 amdgpu_vm_put_task_info(ti); 1307 1307 } 1308 1308 }
+4 -4
drivers/gpu/drm/amd/amdkfd/kfd_smi_events.c
··· 253 253 task_info = amdgpu_vm_get_task_info_pasid(dev->adev, pasid); 254 254 if (task_info) { 255 255 /* Report VM faults from user applications, not retry from kernel */ 256 - if (task_info->pid) 256 + if (task_info->task.pid) 257 257 kfd_smi_event_add(0, dev, KFD_SMI_EVENT_VMFAULT, KFD_EVENT_FMT_VMFAULT( 258 - task_info->pid, task_info->task_name)); 258 + task_info->task.pid, task_info->task.comm)); 259 259 amdgpu_vm_put_task_info(task_info); 260 260 } 261 261 } ··· 359 359 kfd_smi_event_add(0, pdd->dev, 360 360 start ? KFD_SMI_EVENT_PROCESS_START : 361 361 KFD_SMI_EVENT_PROCESS_END, 362 - KFD_EVENT_FMT_PROCESS(task_info->pid, 363 - task_info->task_name)); 362 + KFD_EVENT_FMT_PROCESS(task_info->task.pid, 363 + task_info->task.comm)); 364 364 amdgpu_vm_put_task_info(task_info); 365 365 } 366 366 }
+2
drivers/gpu/drm/bridge/analogix/analogix-i2c-dptx.c
··· 5 5 * Based on anx7808 driver obtained from chromeos with copyright: 6 6 * Copyright(c) 2013, Google Inc. 7 7 */ 8 + 9 + #include <linux/export.h> 8 10 #include <linux/regmap.h> 9 11 10 12 #include <drm/display/drm_dp_helper.h>
+1
drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
··· 9 9 #include <linux/clk.h> 10 10 #include <linux/component.h> 11 11 #include <linux/err.h> 12 + #include <linux/export.h> 12 13 #include <linux/gpio/consumer.h> 13 14 #include <linux/interrupt.h> 14 15 #include <linux/io.h>
+1
drivers/gpu/drm/bridge/aux-bridge.c
··· 5 5 * Author: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> 6 6 */ 7 7 #include <linux/auxiliary_bus.h> 8 + #include <linux/export.h> 8 9 #include <linux/module.h> 9 10 #include <linux/of.h> 10 11
+1
drivers/gpu/drm/bridge/aux-hpd-bridge.c
··· 5 5 * Author: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> 6 6 */ 7 7 #include <linux/auxiliary_bus.h> 8 + #include <linux/export.h> 8 9 #include <linux/module.h> 9 10 #include <linux/of.h> 10 11
+2
drivers/gpu/drm/bridge/imx/imx-legacy-bridge.c
··· 5 5 * bridge driver for legacy DT bindings, utilizing display-timings node 6 6 */ 7 7 8 + #include <linux/export.h> 9 + 8 10 #include <drm/drm_bridge.h> 9 11 #include <drm/drm_modes.h> 10 12 #include <drm/drm_probe_helper.h>
+1
drivers/gpu/drm/bridge/panel.c
··· 5 5 */ 6 6 7 7 #include <linux/debugfs.h> 8 + #include <linux/export.h> 8 9 9 10 #include <drm/drm_atomic_helper.h> 10 11 #include <drm/drm_bridge.h>
+1
drivers/gpu/drm/bridge/samsung-dsim.c
··· 14 14 15 15 #include <linux/clk.h> 16 16 #include <linux/delay.h> 17 + #include <linux/export.h> 17 18 #include <linux/irq.h> 18 19 #include <linux/media-bus-format.h> 19 20 #include <linux/of.h>
+1
drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
··· 8 8 */ 9 9 #include <linux/completion.h> 10 10 #include <linux/hdmi.h> 11 + #include <linux/export.h> 11 12 #include <linux/i2c.h> 12 13 #include <linux/irq.h> 13 14 #include <linux/module.h>
+1
drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
··· 9 9 #include <linux/clk.h> 10 10 #include <linux/delay.h> 11 11 #include <linux/err.h> 12 + #include <linux/export.h> 12 13 #include <linux/hdmi.h> 13 14 #include <linux/i2c.h> 14 15 #include <linux/irq.h>
+1
drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
··· 11 11 #include <linux/clk.h> 12 12 #include <linux/component.h> 13 13 #include <linux/debugfs.h> 14 + #include <linux/export.h> 14 15 #include <linux/iopoll.h> 15 16 #include <linux/math64.h> 16 17 #include <linux/media-bus-format.h>
+1
drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi2.c
··· 9 9 10 10 #include <linux/bitfield.h> 11 11 #include <linux/clk.h> 12 + #include <linux/export.h> 12 13 #include <linux/iopoll.h> 13 14 #include <linux/media-bus-format.h> 14 15 #include <linux/module.h>
+14 -53
drivers/gpu/drm/bridge/ti-sn65dsi86.c
··· 447 447 * Auxiliary Devices (*not* AUX) 448 448 */ 449 449 450 - static void ti_sn65dsi86_uninit_aux(void *data) 451 - { 452 - auxiliary_device_uninit(data); 453 - } 454 - 455 - static void ti_sn65dsi86_delete_aux(void *data) 456 - { 457 - auxiliary_device_delete(data); 458 - } 459 - 460 - static void ti_sn65dsi86_aux_device_release(struct device *dev) 461 - { 462 - struct auxiliary_device *aux = container_of(dev, struct auxiliary_device, dev); 463 - 464 - kfree(aux); 465 - } 466 - 467 450 static int ti_sn65dsi86_add_aux_device(struct ti_sn65dsi86 *pdata, 468 451 struct auxiliary_device **aux_out, 469 452 const char *name) ··· 454 471 struct device *dev = pdata->dev; 455 472 const struct i2c_client *client = to_i2c_client(dev); 456 473 struct auxiliary_device *aux; 457 - int ret; 474 + int id; 458 475 459 - aux = kzalloc(sizeof(*aux), GFP_KERNEL); 476 + id = (client->adapter->nr << 10) | client->addr; 477 + aux = __devm_auxiliary_device_create(dev, KBUILD_MODNAME, name, 478 + NULL, id); 460 479 if (!aux) 461 - return -ENOMEM; 480 + return -ENODEV; 462 481 463 - aux->name = name; 464 - aux->id = (client->adapter->nr << 10) | client->addr; 465 - aux->dev.parent = dev; 466 - aux->dev.release = ti_sn65dsi86_aux_device_release; 467 - device_set_of_node_from_dev(&aux->dev, dev); 468 - ret = auxiliary_device_init(aux); 469 - if (ret) { 470 - kfree(aux); 471 - return ret; 472 - } 473 - ret = devm_add_action_or_reset(dev, ti_sn65dsi86_uninit_aux, aux); 474 - if (ret) 475 - return ret; 476 - 477 - ret = auxiliary_device_add(aux); 478 - if (ret) 479 - return ret; 480 - ret = devm_add_action_or_reset(dev, ti_sn65dsi86_delete_aux, aux); 481 - if (!ret) 482 - *aux_out = aux; 483 - 484 - return ret; 482 + *aux_out = aux; 483 + return 0; 485 484 } 486 485 487 486 /* ----------------------------------------------------------------------------- ··· 1672 1707 return !!(val & BIT(SN_GPIO_INPUT_SHIFT + offset)); 1673 1708 } 1674 1709 1675 - static void ti_sn_bridge_gpio_set(struct gpio_chip *chip, unsigned int offset, 1676 - int val) 1710 + static int ti_sn_bridge_gpio_set(struct gpio_chip *chip, unsigned int offset, 1711 + int val) 1677 1712 { 1678 1713 struct ti_sn65dsi86 *pdata = gpiochip_get_data(chip); 1679 - int ret; 1680 1714 1681 1715 if (!test_bit(offset, pdata->gchip_output)) { 1682 1716 dev_err(pdata->dev, "Ignoring GPIO set while input\n"); 1683 - return; 1717 + return -EPERM; 1684 1718 } 1685 1719 1686 1720 val &= 1; 1687 - ret = regmap_update_bits(pdata->regmap, SN_GPIO_IO_REG, 1688 - BIT(SN_GPIO_OUTPUT_SHIFT + offset), 1689 - val << (SN_GPIO_OUTPUT_SHIFT + offset)); 1690 - if (ret) 1691 - dev_warn(pdata->dev, 1692 - "Failed to set bridge GPIO %u: %d\n", offset, ret); 1721 + return regmap_update_bits(pdata->regmap, SN_GPIO_IO_REG, 1722 + BIT(SN_GPIO_OUTPUT_SHIFT + offset), 1723 + val << (SN_GPIO_OUTPUT_SHIFT + offset)); 1693 1724 } 1694 1725 1695 1726 static int ti_sn_bridge_gpio_direction_input(struct gpio_chip *chip, ··· 1789 1828 pdata->gchip.direction_input = ti_sn_bridge_gpio_direction_input; 1790 1829 pdata->gchip.direction_output = ti_sn_bridge_gpio_direction_output; 1791 1830 pdata->gchip.get = ti_sn_bridge_gpio_get; 1792 - pdata->gchip.set = ti_sn_bridge_gpio_set; 1831 + pdata->gchip.set_rv = ti_sn_bridge_gpio_set; 1793 1832 pdata->gchip.can_sleep = true; 1794 1833 pdata->gchip.names = ti_sn_bridge_gpio_names; 1795 1834 pdata->gchip.ngpio = SN_NUM_GPIOS;
+2
drivers/gpu/drm/clients/drm_client_setup.c
··· 1 1 // SPDX-License-Identifier: MIT 2 2 3 + #include <linux/export.h> 4 + 3 5 #include <drm/clients/drm_client_setup.h> 4 6 #include <drm/drm_device.h> 5 7 #include <drm/drm_fourcc.h>
+1
drivers/gpu/drm/display/drm_bridge_connector.c
··· 3 3 * Copyright (C) 2019 Laurent Pinchart <laurent.pinchart@ideasonboard.com> 4 4 */ 5 5 6 + #include <linux/export.h> 6 7 #include <linux/kernel.h> 7 8 #include <linux/module.h> 8 9 #include <linux/of.h>
+1
drivers/gpu/drm/display/drm_dp_aux_bus.c
··· 12 12 * to perform transactions on that bus. 13 13 */ 14 14 15 + #include <linux/export.h> 15 16 #include <linux/init.h> 16 17 #include <linux/kernel.h> 17 18 #include <linux/module.h>
+1
drivers/gpu/drm/display/drm_dp_cec.c
··· 5 5 * Copyright 2018 Cisco Systems, Inc. and/or its affiliates. All rights reserved. 6 6 */ 7 7 8 + #include <linux/export.h> 8 9 #include <linux/kernel.h> 9 10 #include <linux/module.h> 10 11 #include <linux/slab.h>
+1
drivers/gpu/drm/display/drm_dp_helper.c
··· 24 24 #include <linux/delay.h> 25 25 #include <linux/dynamic_debug.h> 26 26 #include <linux/errno.h> 27 + #include <linux/export.h> 27 28 #include <linux/i2c.h> 28 29 #include <linux/init.h> 29 30 #include <linux/iopoll.h>
+1
drivers/gpu/drm/display/drm_dp_mst_topology.c
··· 23 23 #include <linux/bitfield.h> 24 24 #include <linux/delay.h> 25 25 #include <linux/errno.h> 26 + #include <linux/export.h> 26 27 #include <linux/i2c.h> 27 28 #include <linux/init.h> 28 29 #include <linux/kernel.h>
+1
drivers/gpu/drm/display/drm_dp_tunnel.c
··· 3 3 * Copyright © 2023 Intel Corporation 4 4 */ 5 5 6 + #include <linux/export.h> 6 7 #include <linux/ref_tracker.h> 7 8 #include <linux/types.h> 8 9
+1
drivers/gpu/drm/display/drm_dsc_helper.c
··· 6 6 * Manasi Navare <manasi.d.navare@intel.com> 7 7 */ 8 8 9 + #include <linux/export.h> 9 10 #include <linux/kernel.h> 10 11 #include <linux/module.h> 11 12 #include <linux/init.h>
+1
drivers/gpu/drm/display/drm_hdmi_audio_helper.c
··· 3 3 * Copyright (c) 2024 Linaro Ltd 4 4 */ 5 5 6 + #include <linux/export.h> 6 7 #include <linux/mutex.h> 7 8 #include <linux/of_graph.h> 8 9 #include <linux/platform_device.h>
+1
drivers/gpu/drm/display/drm_hdmi_cec_helper.c
··· 8 8 #include <drm/drm_managed.h> 9 9 #include <drm/display/drm_hdmi_cec_helper.h> 10 10 11 + #include <linux/export.h> 11 12 #include <linux/mutex.h> 12 13 13 14 #include <media/cec.h>
+1
drivers/gpu/drm/display/drm_hdmi_cec_notifier_helper.c
··· 8 8 #include <drm/drm_managed.h> 9 9 #include <drm/display/drm_hdmi_cec_helper.h> 10 10 11 + #include <linux/export.h> 11 12 #include <linux/mutex.h> 12 13 13 14 #include <media/cec.h>
+1
drivers/gpu/drm/display/drm_hdmi_helper.c
··· 1 1 // SPDX-License-Identifier: MIT 2 2 3 + #include <linux/export.h> 3 4 #include <linux/module.h> 4 5 5 6 #include <drm/display/drm_hdmi_helper.h>
+2
drivers/gpu/drm/display/drm_hdmi_state_helper.c
··· 1 1 // SPDX-License-Identifier: MIT 2 2 3 + #include <linux/export.h> 4 + 3 5 #include <drm/drm_atomic.h> 4 6 #include <drm/drm_connector.h> 5 7 #include <drm/drm_edid.h>
+1
drivers/gpu/drm/display/drm_scdc_helper.c
··· 21 21 * DEALINGS IN THE SOFTWARE. 22 22 */ 23 23 24 + #include <linux/export.h> 24 25 #include <linux/i2c.h> 25 26 #include <linux/slab.h> 26 27 #include <linux/delay.h>
+1 -1
drivers/gpu/drm/drm_atomic.c
··· 26 26 * Daniel Vetter <daniel.vetter@ffwll.ch> 27 27 */ 28 28 29 - 29 + #include <linux/export.h> 30 30 #include <linux/sync_file.h> 31 31 32 32 #include <drm/drm_atomic.h>
+1
drivers/gpu/drm/drm_atomic_helper.c
··· 25 25 * Daniel Vetter <daniel.vetter@ffwll.ch> 26 26 */ 27 27 28 + #include <linux/export.h> 28 29 #include <linux/dma-fence.h> 29 30 #include <linux/ktime.h> 30 31
+1
drivers/gpu/drm/drm_atomic_state_helper.c
··· 37 37 #include <drm/drm_vblank.h> 38 38 #include <drm/drm_writeback.h> 39 39 40 + #include <linux/export.h> 40 41 #include <linux/slab.h> 41 42 #include <linux/dma-fence.h> 42 43
+1
drivers/gpu/drm/drm_atomic_uapi.c
··· 36 36 #include <drm/drm_writeback.h> 37 37 #include <drm/drm_vblank.h> 38 38 39 + #include <linux/export.h> 39 40 #include <linux/dma-fence.h> 40 41 #include <linux/uaccess.h> 41 42 #include <linux/sync_file.h>
+1
drivers/gpu/drm/drm_auth.c
··· 28 28 * OTHER DEALINGS IN THE SOFTWARE. 29 29 */ 30 30 31 + #include <linux/export.h> 31 32 #include <linux/slab.h> 32 33 33 34 #include <drm/drm_auth.h>
+1
drivers/gpu/drm/drm_bridge.c
··· 23 23 24 24 #include <linux/debugfs.h> 25 25 #include <linux/err.h> 26 + #include <linux/export.h> 26 27 #include <linux/media-bus-format.h> 27 28 #include <linux/module.h> 28 29 #include <linux/mutex.h>
+2
drivers/gpu/drm/drm_bridge_helper.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-or-later 2 2 3 + #include <linux/export.h> 4 + 3 5 #include <drm/drm_atomic.h> 4 6 #include <drm/drm_atomic_helper.h> 5 7 #include <drm/drm_bridge.h>
+1
drivers/gpu/drm/drm_buddy.c
··· 5 5 6 6 #include <kunit/test-bug.h> 7 7 8 + #include <linux/export.h> 8 9 #include <linux/kmemleak.h> 9 10 #include <linux/module.h> 10 11 #include <linux/sizes.h>
+1
drivers/gpu/drm/drm_client.c
··· 3 3 * Copyright 2018 Noralf Trønnes 4 4 */ 5 5 6 + #include <linux/export.h> 6 7 #include <linux/iosys-map.h> 7 8 #include <linux/list.h> 8 9 #include <linux/mutex.h>
+1
drivers/gpu/drm/drm_client_event.c
··· 3 3 * Copyright 2018 Noralf Trønnes 4 4 */ 5 5 6 + #include <linux/export.h> 6 7 #include <linux/list.h> 7 8 #include <linux/mutex.h> 8 9 #include <linux/seq_file.h>
+2
drivers/gpu/drm/drm_client_modeset.c
··· 8 8 */ 9 9 10 10 #include "drm/drm_modeset_lock.h" 11 + 12 + #include <linux/export.h> 11 13 #include <linux/module.h> 12 14 #include <linux/mutex.h> 13 15 #include <linux/slab.h>
+1
drivers/gpu/drm/drm_color_mgmt.c
··· 20 20 * OF THIS SOFTWARE. 21 21 */ 22 22 23 + #include <linux/export.h> 23 24 #include <linux/uaccess.h> 24 25 25 26 #include <drm/drm_atomic.h>
+1
drivers/gpu/drm/drm_connector.c
··· 33 33 #include <drm/drm_sysfs.h> 34 34 #include <drm/drm_utils.h> 35 35 36 + #include <linux/export.h> 36 37 #include <linux/platform_device.h> 37 38 #include <linux/property.h> 38 39 #include <linux/uaccess.h>
+2
drivers/gpu/drm/drm_damage_helper.c
··· 30 30 * 31 31 **************************************************************************/ 32 32 33 + #include <linux/export.h> 34 + 33 35 #include <drm/drm_atomic.h> 34 36 #include <drm/drm_damage_helper.h> 35 37 #include <drm/drm_device.h>
+1
drivers/gpu/drm/drm_debugfs_crc.c
··· 29 29 #include <linux/circ_buf.h> 30 30 #include <linux/ctype.h> 31 31 #include <linux/debugfs.h> 32 + #include <linux/export.h> 32 33 #include <linux/poll.h> 33 34 #include <linux/uaccess.h> 34 35
+18 -4
drivers/gpu/drm/drm_drv.c
··· 29 29 #include <linux/bitops.h> 30 30 #include <linux/cgroup_dmem.h> 31 31 #include <linux/debugfs.h> 32 + #include <linux/export.h> 32 33 #include <linux/fs.h> 33 34 #include <linux/module.h> 34 35 #include <linux/moduleparam.h> 35 36 #include <linux/mount.h> 36 37 #include <linux/pseudo_fs.h> 38 + #include <linux/sched.h> 37 39 #include <linux/slab.h> 38 40 #include <linux/sprintf.h> 39 41 #include <linux/srcu.h> ··· 540 538 } 541 539 } 542 540 541 + #define WEDGE_STR_LEN 32 542 + #define PID_STR_LEN 15 543 + #define COMM_STR_LEN (TASK_COMM_LEN + 5) 544 + 543 545 /** 544 546 * drm_dev_wedged_event - generate a device wedged uevent 545 547 * @dev: DRM device 546 548 * @method: method(s) to be used for recovery 549 + * @info: optional information about the guilty task 547 550 * 548 551 * This generates a device wedged uevent for the DRM device specified by @dev. 549 552 * Recovery @method\(s) of choice will be sent in the uevent environment as ··· 561 554 * 562 555 * Returns: 0 on success, negative error code otherwise. 563 556 */ 564 - int drm_dev_wedged_event(struct drm_device *dev, unsigned long method) 557 + int drm_dev_wedged_event(struct drm_device *dev, unsigned long method, 558 + struct drm_wedge_task_info *info) 565 559 { 560 + char event_string[WEDGE_STR_LEN], pid_string[PID_STR_LEN], comm_string[COMM_STR_LEN]; 561 + char *envp[] = { event_string, NULL, NULL, NULL }; 566 562 const char *recovery = NULL; 567 563 unsigned int len, opt; 568 - /* Event string length up to 28+ characters with available methods */ 569 - char event_string[32]; 570 - char *envp[] = { event_string, NULL }; 571 564 572 565 len = scnprintf(event_string, sizeof(event_string), "%s", "WEDGED="); 573 566 ··· 588 581 589 582 drm_info(dev, "device wedged, %s\n", method == DRM_WEDGE_RECOVERY_NONE ? 590 583 "but recovered through reset" : "needs recovery"); 584 + 585 + if (info && (info->comm[0] != '\0') && (info->pid >= 0)) { 586 + snprintf(pid_string, sizeof(pid_string), "PID=%u", info->pid); 587 + snprintf(comm_string, sizeof(comm_string), "TASK=%s", info->comm); 588 + envp[1] = pid_string; 589 + envp[2] = comm_string; 590 + } 591 591 592 592 return kobject_uevent_env(&dev->primary->kdev->kobj, KOBJ_CHANGE, envp); 593 593 }
+1
drivers/gpu/drm/drm_edid.c
··· 31 31 #include <linux/bitfield.h> 32 32 #include <linux/byteorder/generic.h> 33 33 #include <linux/cec.h> 34 + #include <linux/export.h> 34 35 #include <linux/hdmi.h> 35 36 #include <linux/i2c.h> 36 37 #include <linux/kernel.h>
+2
drivers/gpu/drm/drm_exec.c
··· 2 2 3 3 #include <drm/drm_exec.h> 4 4 #include <drm/drm_gem.h> 5 + 5 6 #include <linux/dma-resv.h> 7 + #include <linux/export.h> 6 8 7 9 /** 8 10 * DOC: Overview
+2
drivers/gpu/drm/drm_fb_dma_helper.c
··· 17 17 #include <drm/drm_gem_framebuffer_helper.h> 18 18 #include <drm/drm_panic.h> 19 19 #include <drm/drm_plane.h> 20 + 20 21 #include <linux/dma-mapping.h> 22 + #include <linux/export.h> 21 23 #include <linux/module.h> 22 24 23 25 /**
+1
drivers/gpu/drm/drm_fb_helper.c
··· 30 30 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 31 31 32 32 #include <linux/console.h> 33 + #include <linux/export.h> 33 34 #include <linux/pci.h> 34 35 #include <linux/sysrq.h> 35 36 #include <linux/vga_switcheroo.h>
+1
drivers/gpu/drm/drm_fbdev_dma.c
··· 1 1 // SPDX-License-Identifier: MIT 2 2 3 + #include <linux/export.h> 3 4 #include <linux/fb.h> 4 5 #include <linux/vmalloc.h> 5 6
+1
drivers/gpu/drm/drm_fbdev_shmem.c
··· 1 1 // SPDX-License-Identifier: MIT 2 2 3 + #include <linux/export.h> 3 4 #include <linux/fb.h> 4 5 5 6 #include <drm/drm_drv.h>
+1
drivers/gpu/drm/drm_fbdev_ttm.c
··· 1 1 // SPDX-License-Identifier: MIT 2 2 3 + #include <linux/export.h> 3 4 #include <linux/moduleparam.h> 4 5 #include <linux/vmalloc.h> 5 6
+1
drivers/gpu/drm/drm_file.c
··· 33 33 34 34 #include <linux/anon_inodes.h> 35 35 #include <linux/dma-fence.h> 36 + #include <linux/export.h> 36 37 #include <linux/file.h> 37 38 #include <linux/module.h> 38 39 #include <linux/pci.h>
+1
drivers/gpu/drm/drm_flip_work.c
··· 21 21 * SOFTWARE. 22 22 */ 23 23 24 + #include <linux/export.h> 24 25 #include <linux/slab.h> 25 26 26 27 #include <drm/drm_flip_work.h>
+99 -148
drivers/gpu/drm/drm_format_helper.c
··· 8 8 * (at your option) any later version. 9 9 */ 10 10 11 + #include <linux/export.h> 11 12 #include <linux/io.h> 12 13 #include <linux/iosys-map.h> 13 14 #include <linux/module.h> ··· 858 857 drm_fb_xfrm_line_32to32(dbuf, sbuf, pixels, drm_pixel_xrgb8888_to_abgr8888); 859 858 } 860 859 861 - static void drm_fb_xrgb8888_to_abgr8888(struct iosys_map *dst, const unsigned int *dst_pitch, 862 - const struct iosys_map *src, 863 - const struct drm_framebuffer *fb, 864 - const struct drm_rect *clip, 865 - struct drm_format_conv_state *state) 860 + /** 861 + * drm_fb_xrgb8888_to_abgr8888 - Convert XRGB8888 to ABGR8888 clip buffer 862 + * @dst: Array of ABGR8888 destination buffers 863 + * @dst_pitch: Array of numbers of bytes between the start of two consecutive scanlines 864 + * within @dst; can be NULL if scanlines are stored next to each other. 865 + * @src: Array of XRGB8888 source buffer 866 + * @fb: DRM framebuffer 867 + * @clip: Clip rectangle area to copy 868 + * @state: Transform and conversion state 869 + * 870 + * This function copies parts of a framebuffer to display memory and converts the 871 + * color format during the process. The parameters @dst, @dst_pitch and @src refer 872 + * to arrays. Each array must have at least as many entries as there are planes in 873 + * @fb's format. Each entry stores the value for the format's respective color plane 874 + * at the same index. 875 + * 876 + * This function does not apply clipping on @dst (i.e. the destination is at the 877 + * top-left corner). 878 + * 879 + * Drivers can use this function for ABGR8888 devices that don't support XRGB8888 880 + * natively. It sets an opaque alpha channel as part of the conversion. 881 + */ 882 + void drm_fb_xrgb8888_to_abgr8888(struct iosys_map *dst, const unsigned int *dst_pitch, 883 + const struct iosys_map *src, 884 + const struct drm_framebuffer *fb, 885 + const struct drm_rect *clip, 886 + struct drm_format_conv_state *state) 866 887 { 867 888 static const u8 dst_pixsize[DRM_FORMAT_MAX_PLANES] = { 868 889 4, ··· 893 870 drm_fb_xfrm(dst, dst_pitch, dst_pixsize, src, fb, clip, false, state, 894 871 drm_fb_xrgb8888_to_abgr8888_line); 895 872 } 873 + EXPORT_SYMBOL(drm_fb_xrgb8888_to_abgr8888); 896 874 897 875 static void drm_fb_xrgb8888_to_xbgr8888_line(void *dbuf, const void *sbuf, unsigned int pixels) 898 876 { 899 877 drm_fb_xfrm_line_32to32(dbuf, sbuf, pixels, drm_pixel_xrgb8888_to_xbgr8888); 900 878 } 901 879 902 - static void drm_fb_xrgb8888_to_xbgr8888(struct iosys_map *dst, const unsigned int *dst_pitch, 903 - const struct iosys_map *src, 904 - const struct drm_framebuffer *fb, 905 - const struct drm_rect *clip, 906 - struct drm_format_conv_state *state) 880 + /** 881 + * drm_fb_xrgb8888_to_xbgr8888 - Convert XRGB8888 to XBGR8888 clip buffer 882 + * @dst: Array of XBGR8888 destination buffers 883 + * @dst_pitch: Array of numbers of bytes between the start of two consecutive scanlines 884 + * within @dst; can be NULL if scanlines are stored next to each other. 885 + * @src: Array of XRGB8888 source buffer 886 + * @fb: DRM framebuffer 887 + * @clip: Clip rectangle area to copy 888 + * @state: Transform and conversion state 889 + * 890 + * This function copies parts of a framebuffer to display memory and converts the 891 + * color format during the process. The parameters @dst, @dst_pitch and @src refer 892 + * to arrays. Each array must have at least as many entries as there are planes in 893 + * @fb's format. Each entry stores the value for the format's respective color plane 894 + * at the same index. 895 + * 896 + * This function does not apply clipping on @dst (i.e. the destination is at the 897 + * top-left corner). 898 + * 899 + * Drivers can use this function for XBGR8888 devices that don't support XRGB8888 900 + * natively. 901 + */ 902 + void drm_fb_xrgb8888_to_xbgr8888(struct iosys_map *dst, const unsigned int *dst_pitch, 903 + const struct iosys_map *src, 904 + const struct drm_framebuffer *fb, 905 + const struct drm_rect *clip, 906 + struct drm_format_conv_state *state) 907 907 { 908 908 static const u8 dst_pixsize[DRM_FORMAT_MAX_PLANES] = { 909 909 4, ··· 935 889 drm_fb_xfrm(dst, dst_pitch, dst_pixsize, src, fb, clip, false, state, 936 890 drm_fb_xrgb8888_to_xbgr8888_line); 937 891 } 892 + EXPORT_SYMBOL(drm_fb_xrgb8888_to_xbgr8888); 893 + 894 + static void drm_fb_xrgb8888_to_bgrx8888_line(void *dbuf, const void *sbuf, unsigned int pixels) 895 + { 896 + drm_fb_xfrm_line_32to32(dbuf, sbuf, pixels, drm_pixel_xrgb8888_to_bgrx8888); 897 + } 898 + 899 + /** 900 + * drm_fb_xrgb8888_to_bgrx8888 - Convert XRGB8888 to BGRX8888 clip buffer 901 + * @dst: Array of BGRX8888 destination buffers 902 + * @dst_pitch: Array of numbers of bytes between the start of two consecutive scanlines 903 + * within @dst; can be NULL if scanlines are stored next to each other. 904 + * @src: Array of XRGB8888 source buffer 905 + * @fb: DRM framebuffer 906 + * @clip: Clip rectangle area to copy 907 + * @state: Transform and conversion state 908 + * 909 + * This function copies parts of a framebuffer to display memory and converts the 910 + * color format during the process. The parameters @dst, @dst_pitch and @src refer 911 + * to arrays. Each array must have at least as many entries as there are planes in 912 + * @fb's format. Each entry stores the value for the format's respective color plane 913 + * at the same index. 914 + * 915 + * This function does not apply clipping on @dst (i.e. the destination is at the 916 + * top-left corner). 917 + * 918 + * Drivers can use this function for BGRX8888 devices that don't support XRGB8888 919 + * natively. 920 + */ 921 + void drm_fb_xrgb8888_to_bgrx8888(struct iosys_map *dst, const unsigned int *dst_pitch, 922 + const struct iosys_map *src, 923 + const struct drm_framebuffer *fb, 924 + const struct drm_rect *clip, 925 + struct drm_format_conv_state *state) 926 + { 927 + static const u8 dst_pixsize[DRM_FORMAT_MAX_PLANES] = { 928 + 4, 929 + }; 930 + 931 + drm_fb_xfrm(dst, dst_pitch, dst_pixsize, src, fb, clip, false, state, 932 + drm_fb_xrgb8888_to_bgrx8888_line); 933 + } 934 + EXPORT_SYMBOL(drm_fb_xrgb8888_to_bgrx8888); 938 935 939 936 static void drm_fb_xrgb8888_to_xrgb2101010_line(void *dbuf, const void *sbuf, unsigned int pixels) 940 937 { ··· 1339 1250 } 1340 1251 } 1341 1252 EXPORT_SYMBOL(drm_fb_xrgb8888_to_mono); 1342 - 1343 - static uint32_t drm_fb_nonalpha_fourcc(uint32_t fourcc) 1344 - { 1345 - /* only handle formats with depth != 0 and alpha channel */ 1346 - switch (fourcc) { 1347 - case DRM_FORMAT_ARGB1555: 1348 - return DRM_FORMAT_XRGB1555; 1349 - case DRM_FORMAT_ABGR1555: 1350 - return DRM_FORMAT_XBGR1555; 1351 - case DRM_FORMAT_RGBA5551: 1352 - return DRM_FORMAT_RGBX5551; 1353 - case DRM_FORMAT_BGRA5551: 1354 - return DRM_FORMAT_BGRX5551; 1355 - case DRM_FORMAT_ARGB8888: 1356 - return DRM_FORMAT_XRGB8888; 1357 - case DRM_FORMAT_ABGR8888: 1358 - return DRM_FORMAT_XBGR8888; 1359 - case DRM_FORMAT_RGBA8888: 1360 - return DRM_FORMAT_RGBX8888; 1361 - case DRM_FORMAT_BGRA8888: 1362 - return DRM_FORMAT_BGRX8888; 1363 - case DRM_FORMAT_ARGB2101010: 1364 - return DRM_FORMAT_XRGB2101010; 1365 - case DRM_FORMAT_ABGR2101010: 1366 - return DRM_FORMAT_XBGR2101010; 1367 - case DRM_FORMAT_RGBA1010102: 1368 - return DRM_FORMAT_RGBX1010102; 1369 - case DRM_FORMAT_BGRA1010102: 1370 - return DRM_FORMAT_BGRX1010102; 1371 - } 1372 - 1373 - return fourcc; 1374 - } 1375 - 1376 - static bool is_listed_fourcc(const uint32_t *fourccs, size_t nfourccs, uint32_t fourcc) 1377 - { 1378 - const uint32_t *fourccs_end = fourccs + nfourccs; 1379 - 1380 - while (fourccs < fourccs_end) { 1381 - if (*fourccs == fourcc) 1382 - return true; 1383 - ++fourccs; 1384 - } 1385 - return false; 1386 - } 1387 - 1388 - /** 1389 - * drm_fb_build_fourcc_list - Filters a list of supported color formats against 1390 - * the device's native formats 1391 - * @dev: DRM device 1392 - * @native_fourccs: 4CC codes of natively supported color formats 1393 - * @native_nfourccs: The number of entries in @native_fourccs 1394 - * @fourccs_out: Returns 4CC codes of supported color formats 1395 - * @nfourccs_out: The number of available entries in @fourccs_out 1396 - * 1397 - * This function create a list of supported color format from natively 1398 - * supported formats and additional emulated formats. 1399 - * At a minimum, most userspace programs expect at least support for 1400 - * XRGB8888 on the primary plane. Devices that have to emulate the 1401 - * format, and possibly others, can use drm_fb_build_fourcc_list() to 1402 - * create a list of supported color formats. The returned list can 1403 - * be handed over to drm_universal_plane_init() et al. Native formats 1404 - * will go before emulated formats. Native formats with alpha channel 1405 - * will be replaced by such without, as primary planes usually don't 1406 - * support alpha. Other heuristics might be applied 1407 - * to optimize the order. Formats near the beginning of the list are 1408 - * usually preferred over formats near the end of the list. 1409 - * 1410 - * Returns: 1411 - * The number of color-formats 4CC codes returned in @fourccs_out. 1412 - */ 1413 - size_t drm_fb_build_fourcc_list(struct drm_device *dev, 1414 - const u32 *native_fourccs, size_t native_nfourccs, 1415 - u32 *fourccs_out, size_t nfourccs_out) 1416 - { 1417 - /* 1418 - * XRGB8888 is the default fallback format for most of userspace 1419 - * and it's currently the only format that should be emulated for 1420 - * the primary plane. Only if there's ever another default fallback, 1421 - * it should be added here. 1422 - */ 1423 - static const uint32_t extra_fourccs[] = { 1424 - DRM_FORMAT_XRGB8888, 1425 - }; 1426 - static const size_t extra_nfourccs = ARRAY_SIZE(extra_fourccs); 1427 - 1428 - u32 *fourccs = fourccs_out; 1429 - const u32 *fourccs_end = fourccs_out + nfourccs_out; 1430 - size_t i; 1431 - 1432 - /* 1433 - * The device's native formats go first. 1434 - */ 1435 - 1436 - for (i = 0; i < native_nfourccs; ++i) { 1437 - /* 1438 - * Several DTs, boot loaders and firmware report native 1439 - * alpha formats that are non-alpha formats instead. So 1440 - * replace alpha formats by non-alpha formats. 1441 - */ 1442 - u32 fourcc = drm_fb_nonalpha_fourcc(native_fourccs[i]); 1443 - 1444 - if (is_listed_fourcc(fourccs_out, fourccs - fourccs_out, fourcc)) { 1445 - continue; /* skip duplicate entries */ 1446 - } else if (fourccs == fourccs_end) { 1447 - drm_warn(dev, "Ignoring native format %p4cc\n", &fourcc); 1448 - continue; /* end of available output buffer */ 1449 - } 1450 - 1451 - drm_dbg_kms(dev, "adding native format %p4cc\n", &fourcc); 1452 - 1453 - *fourccs = fourcc; 1454 - ++fourccs; 1455 - } 1456 - 1457 - /* 1458 - * The extra formats, emulated by the driver, go second. 1459 - */ 1460 - 1461 - for (i = 0; (i < extra_nfourccs) && (fourccs < fourccs_end); ++i) { 1462 - u32 fourcc = extra_fourccs[i]; 1463 - 1464 - if (is_listed_fourcc(fourccs_out, fourccs - fourccs_out, fourcc)) { 1465 - continue; /* skip duplicate and native entries */ 1466 - } else if (fourccs == fourccs_end) { 1467 - drm_warn(dev, "Ignoring emulated format %p4cc\n", &fourcc); 1468 - continue; /* end of available output buffer */ 1469 - } 1470 - 1471 - drm_dbg_kms(dev, "adding emulated format %p4cc\n", &fourcc); 1472 - 1473 - *fourccs = fourcc; 1474 - ++fourccs; 1475 - } 1476 - 1477 - return fourccs - fourccs_out; 1478 - } 1479 - EXPORT_SYMBOL(drm_fb_build_fourcc_list);
+9 -1
drivers/gpu/drm/drm_format_internal.h
··· 42 42 u32 b = pix & 0x000000ff; 43 43 44 44 /* ITU-R BT.601: Y = 0.299 R + 0.587 G + 0.114 B */ 45 - return (3 * r + 6 * g + b) / 10; 45 + return (77 * r + 150 * g + 29 * b) / 256; 46 46 } 47 47 48 48 static inline u32 drm_pixel_xrgb8888_to_rgb332(u32 pix) ··· 109 109 ((pix & 0x00ff0000) >> 16) | 110 110 ((pix & 0x0000ff00)) | 111 111 ((pix & 0x000000ff) << 16); 112 + } 113 + 114 + static inline u32 drm_pixel_xrgb8888_to_bgrx8888(u32 pix) 115 + { 116 + return ((pix & 0xff000000) >> 24) | /* also copy filler bits */ 117 + ((pix & 0x00ff0000) >> 8) | 118 + ((pix & 0x0000ff00) << 8) | 119 + ((pix & 0x000000ff) << 24); 112 120 } 113 121 114 122 static inline u32 drm_pixel_xrgb8888_to_abgr8888(u32 pix)
+1
drivers/gpu/drm/drm_gem.c
··· 26 26 */ 27 27 28 28 #include <linux/dma-buf.h> 29 + #include <linux/export.h> 29 30 #include <linux/file.h> 30 31 #include <linux/fs.h> 31 32 #include <linux/iosys-map.h>
+1
drivers/gpu/drm/drm_gem_atomic_helper.c
··· 2 2 3 3 #include <linux/dma-resv.h> 4 4 #include <linux/dma-fence-chain.h> 5 + #include <linux/export.h> 5 6 6 7 #include <drm/drm_atomic_state_helper.h> 7 8 #include <drm/drm_atomic_uapi.h>
+1
drivers/gpu/drm/drm_gem_framebuffer_helper.c
··· 5 5 * Copyright (C) 2017 Noralf Trønnes 6 6 */ 7 7 8 + #include <linux/export.h> 8 9 #include <linux/slab.h> 9 10 #include <linux/module.h> 10 11
+1
drivers/gpu/drm/drm_gem_ttm_helper.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-or-later 2 2 3 + #include <linux/export.h> 3 4 #include <linux/module.h> 4 5 5 6 #include <drm/drm_gem_ttm_helper.h>
+1
drivers/gpu/drm/drm_gem_vram_helper.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-or-later 2 2 3 + #include <linux/export.h> 3 4 #include <linux/iosys-map.h> 4 5 #include <linux/module.h> 5 6
+1
drivers/gpu/drm/drm_gpusvm.c
··· 7 7 */ 8 8 9 9 #include <linux/dma-mapping.h> 10 + #include <linux/export.h> 10 11 #include <linux/hmm.h> 11 12 #include <linux/memremap.h> 12 13 #include <linux/migrate.h>
+1
drivers/gpu/drm/drm_gpuvm.c
··· 27 27 28 28 #include <drm/drm_gpuvm.h> 29 29 30 + #include <linux/export.h> 30 31 #include <linux/interval_tree_generic.h> 31 32 #include <linux/mm.h> 32 33
+1
drivers/gpu/drm/drm_managed.c
··· 7 7 8 8 #include <drm/drm_managed.h> 9 9 10 + #include <linux/export.h> 10 11 #include <linux/list.h> 11 12 #include <linux/mutex.h> 12 13 #include <linux/slab.h>
+1
drivers/gpu/drm/drm_mipi_dbi.c
··· 8 8 #include <linux/backlight.h> 9 9 #include <linux/debugfs.h> 10 10 #include <linux/delay.h> 11 + #include <linux/export.h> 11 12 #include <linux/gpio/consumer.h> 12 13 #include <linux/module.h> 13 14 #include <linux/regulator/consumer.h>
+1
drivers/gpu/drm/drm_mipi_dsi.c
··· 26 26 */ 27 27 28 28 #include <linux/device.h> 29 + #include <linux/export.h> 29 30 #include <linux/module.h> 30 31 #include <linux/of.h> 31 32 #include <linux/of_device.h>
+1
drivers/gpu/drm/drm_mode_config.c
··· 20 20 * OF THIS SOFTWARE. 21 21 */ 22 22 23 + #include <linux/export.h> 23 24 #include <linux/uaccess.h> 24 25 25 26 #include <drm/drm_drv.h>
+2
drivers/gpu/drm/drm_modeset_helper.c
··· 20 20 * OF THIS SOFTWARE. 21 21 */ 22 22 23 + #include <linux/export.h> 24 + 23 25 #include <drm/drm_atomic_helper.h> 24 26 #include <drm/drm_client_event.h> 25 27 #include <drm/drm_fourcc.h>
+2
drivers/gpu/drm/drm_modeset_lock.c
··· 21 21 * OTHER DEALINGS IN THE SOFTWARE. 22 22 */ 23 23 24 + #include <linux/export.h> 25 + 24 26 #include <drm/drm_atomic.h> 25 27 #include <drm/drm_crtc.h> 26 28 #include <drm/drm_device.h>
+1
drivers/gpu/drm/drm_panel.c
··· 23 23 24 24 #include <linux/backlight.h> 25 25 #include <linux/err.h> 26 + #include <linux/export.h> 26 27 #include <linux/module.h> 27 28 #include <linux/of.h> 28 29
+1
drivers/gpu/drm/drm_panel_backlight_quirks.c
··· 2 2 3 3 #include <linux/array_size.h> 4 4 #include <linux/dmi.h> 5 + #include <linux/export.h> 5 6 #include <linux/mod_devicetable.h> 6 7 #include <linux/module.h> 7 8 #include <drm/drm_edid.h>
+1
drivers/gpu/drm/drm_panel_orientation_quirks.c
··· 9 9 */ 10 10 11 11 #include <linux/dmi.h> 12 + #include <linux/export.h> 12 13 #include <linux/module.h> 13 14 #include <drm/drm_connector.h> 14 15 #include <drm/drm_utils.h>
+1
drivers/gpu/drm/drm_panic.c
··· 6 6 * Tux Ascii art taken from cowsay written by Tony Monroe 7 7 */ 8 8 9 + #include <linux/export.h> 9 10 #include <linux/font.h> 10 11 #include <linux/highmem.h> 11 12 #include <linux/init.h>
-1
drivers/gpu/drm/drm_pci.c
··· 23 23 */ 24 24 25 25 #include <linux/dma-mapping.h> 26 - #include <linux/export.h> 27 26 #include <linux/list.h> 28 27 #include <linux/mutex.h> 29 28 #include <linux/pci.h>
+1
drivers/gpu/drm/drm_plane.c
··· 20 20 * OF THIS SOFTWARE. 21 21 */ 22 22 23 + #include <linux/export.h> 23 24 #include <linux/slab.h> 24 25 #include <linux/uaccess.h> 25 26
+1
drivers/gpu/drm/drm_plane_helper.c
··· 23 23 * SOFTWARE. 24 24 */ 25 25 26 + #include <linux/export.h> 26 27 #include <linux/list.h> 27 28 28 29 #include <drm/drm_atomic.h>
+1
drivers/gpu/drm/drm_print.c
··· 25 25 26 26 #include <linux/debugfs.h> 27 27 #include <linux/dynamic_debug.h> 28 + #include <linux/export.h> 28 29 #include <linux/io.h> 29 30 #include <linux/moduleparam.h> 30 31 #include <linux/seq_file.h>
+1
drivers/gpu/drm/drm_privacy_screen.c
··· 7 7 */ 8 8 9 9 #include <linux/device.h> 10 + #include <linux/export.h> 10 11 #include <linux/kernel.h> 11 12 #include <linux/list.h> 12 13 #include <linux/module.h>
+1
drivers/gpu/drm/drm_self_refresh_helper.c
··· 7 7 */ 8 8 #include <linux/average.h> 9 9 #include <linux/bitops.h> 10 + #include <linux/export.h> 10 11 #include <linux/slab.h> 11 12 #include <linux/workqueue.h> 12 13
+1
drivers/gpu/drm/drm_simple_kms_helper.c
··· 3 3 * Copyright (C) 2016 Noralf Trønnes 4 4 */ 5 5 6 + #include <linux/export.h> 6 7 #include <linux/module.h> 7 8 #include <linux/slab.h> 8 9
+2
drivers/gpu/drm/drm_suballoc.c
··· 42 42 43 43 #include <drm/drm_suballoc.h> 44 44 #include <drm/drm_print.h> 45 + 46 + #include <linux/export.h> 45 47 #include <linux/slab.h> 46 48 #include <linux/sched.h> 47 49 #include <linux/wait.h>
+1
drivers/gpu/drm/drm_syncobj.c
··· 195 195 #include <linux/anon_inodes.h> 196 196 #include <linux/dma-fence-unwrap.h> 197 197 #include <linux/eventfd.h> 198 + #include <linux/export.h> 198 199 #include <linux/file.h> 199 200 #include <linux/fs.h> 200 201 #include <linux/sched/signal.h>
+2
drivers/gpu/drm/drm_vblank_work.c
··· 2 2 3 3 #include <uapi/linux/sched/types.h> 4 4 5 + #include <linux/export.h> 6 + 5 7 #include <drm/drm_print.h> 6 8 #include <drm/drm_vblank.h> 7 9 #include <drm/drm_vblank_work.h>
+1
drivers/gpu/drm/drm_vma_manager.c
··· 23 23 * OTHER DEALINGS IN THE SOFTWARE. 24 24 */ 25 25 26 + #include <linux/export.h> 26 27 #include <linux/mm.h> 27 28 #include <linux/module.h> 28 29 #include <linux/rbtree.h>
+1
drivers/gpu/drm/drm_writeback.c
··· 10 10 */ 11 11 12 12 #include <linux/dma-fence.h> 13 + #include <linux/export.h> 13 14 14 15 #include <drm/drm_crtc.h> 15 16 #include <drm/drm_device.h>
+8 -2
drivers/gpu/drm/i915/gt/intel_gt_requests.c
··· 250 250 llist_for_each_entry_safe(rq, rn, first, watchdog.link) { 251 251 if (!i915_request_completed(rq)) { 252 252 struct dma_fence *f = &rq->fence; 253 + const char __rcu *timeline; 254 + const char __rcu *driver; 253 255 256 + rcu_read_lock(); 257 + driver = dma_fence_driver_name(f); 258 + timeline = dma_fence_timeline_name(f); 254 259 pr_notice("Fence expiration time out i915-%s:%s:%llx!\n", 255 - dma_fence_driver_name(f), 256 - dma_fence_timeline_name(f), 260 + rcu_dereference(driver), 261 + rcu_dereference(timeline), 257 262 f->seqno); 263 + rcu_read_unlock(); 258 264 i915_request_cancel(rq, -EINTR); 259 265 } 260 266 i915_request_put(rq);
+2 -1
drivers/gpu/drm/i915/gt/intel_reset.c
··· 1448 1448 kobject_uevent_env(kobj, KOBJ_CHANGE, reset_done_event); 1449 1449 else 1450 1450 drm_dev_wedged_event(&gt->i915->drm, 1451 - DRM_WEDGE_RECOVERY_REBIND | DRM_WEDGE_RECOVERY_BUS_RESET); 1451 + DRM_WEDGE_RECOVERY_REBIND | DRM_WEDGE_RECOVERY_BUS_RESET, 1452 + NULL); 1452 1453 } 1453 1454 1454 1455 /**
+5 -2
drivers/gpu/drm/i915/i915_request.c
··· 2184 2184 const char *prefix, 2185 2185 int indent) 2186 2186 { 2187 - const char *name = dma_fence_timeline_name((struct dma_fence *)&rq->fence); 2187 + const char __rcu *timeline; 2188 2188 char buf[80] = ""; 2189 2189 int x = 0; 2190 2190 ··· 2220 2220 2221 2221 x = print_sched_attr(&rq->sched.attr, buf, x, sizeof(buf)); 2222 2222 2223 + rcu_read_lock(); 2224 + timeline = dma_fence_timeline_name((struct dma_fence *)&rq->fence); 2223 2225 drm_printf(m, "%s%.*s%c %llx:%lld%s%s %s @ %dms: %s\n", 2224 2226 prefix, indent, " ", 2225 2227 queue_status(rq), ··· 2230 2228 fence_status(rq), 2231 2229 buf, 2232 2230 jiffies_to_msecs(jiffies - rq->emitted_jiffies), 2233 - name); 2231 + rcu_dereference(timeline)); 2232 + rcu_read_unlock(); 2234 2233 } 2235 2234 2236 2235 static bool engine_match_ring(struct intel_engine_cs *engine, struct i915_request *rq)
+8 -2
drivers/gpu/drm/i915/i915_sw_fence.c
··· 430 430 struct i915_sw_dma_fence_cb_timer *cb = timer_container_of(cb, t, 431 431 timer); 432 432 struct i915_sw_fence *fence; 433 + const char __rcu *timeline; 434 + const char __rcu *driver; 433 435 434 436 fence = xchg(&cb->base.fence, NULL); 435 437 if (!fence) 436 438 return; 437 439 440 + rcu_read_lock(); 441 + driver = dma_fence_driver_name(cb->dma); 442 + timeline = dma_fence_timeline_name(cb->dma); 438 443 pr_notice("Asynchronous wait on fence %s:%s:%llx timed out (hint:%ps)\n", 439 - dma_fence_driver_name(cb->dma), 440 - dma_fence_timeline_name(cb->dma), 444 + rcu_dereference(driver), 445 + rcu_dereference(timeline), 441 446 cb->dma->seqno, 442 447 i915_sw_fence_debug_hint(fence)); 448 + rcu_read_unlock(); 443 449 444 450 i915_sw_fence_set_error_once(fence, -ETIMEDOUT); 445 451 i915_sw_fence_complete(fence);
+1
drivers/gpu/drm/lib/drm_random.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 2 2 #include <linux/bitops.h> 3 + #include <linux/export.h> 3 4 #include <linux/kernel.h> 4 5 #include <linux/random.h> 5 6 #include <linux/slab.h>
+1 -1
drivers/gpu/drm/omapdrm/dss/dispc.c
··· 524 524 DSSDBG("context saved\n"); 525 525 } 526 526 527 - static void dispc_restore_context(struct dispc_device *dispc) 527 + static noinline_for_stack void dispc_restore_context(struct dispc_device *dispc) 528 528 { 529 529 int i, j; 530 530
+1
drivers/gpu/drm/panel/panel-samsung-s6e63m0.c
··· 13 13 14 14 #include <linux/backlight.h> 15 15 #include <linux/delay.h> 16 + #include <linux/export.h> 16 17 #include <linux/gpio/consumer.h> 17 18 #include <linux/module.h> 18 19 #include <linux/property.h>
+114 -37
drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c
··· 11 11 #include <linux/dma-mapping.h> 12 12 #include <linux/io.h> 13 13 #include <linux/iopoll.h> 14 + #include <linux/math.h> 14 15 #include <linux/module.h> 15 16 #include <linux/of.h> 16 17 #include <linux/of_graph.h> ··· 19 18 #include <linux/pm_runtime.h> 20 19 #include <linux/reset.h> 21 20 #include <linux/slab.h> 21 + #include <linux/units.h> 22 22 23 23 #include <drm/drm_atomic.h> 24 24 #include <drm/drm_atomic_helper.h> ··· 34 32 35 33 #define RZG2L_DCS_BUF_SIZE 128 /* Maximum DCS buffer size in external memory. */ 36 34 35 + #define RZ_MIPI_DSI_FEATURE_16BPP BIT(0) 36 + 37 + struct rzg2l_mipi_dsi; 38 + 39 + struct rzg2l_mipi_dsi_hw_info { 40 + int (*dphy_init)(struct rzg2l_mipi_dsi *dsi, u64 hsfreq_millihz); 41 + void (*dphy_startup_late_init)(struct rzg2l_mipi_dsi *dsi); 42 + void (*dphy_exit)(struct rzg2l_mipi_dsi *dsi); 43 + int (*dphy_conf_clks)(struct rzg2l_mipi_dsi *dsi, unsigned long mode_freq, 44 + u64 *hsfreq_millihz); 45 + unsigned int (*dphy_mode_clk_check)(struct rzg2l_mipi_dsi *dsi, 46 + unsigned long mode_freq); 47 + u32 phy_reg_offset; 48 + u32 link_reg_offset; 49 + unsigned long min_dclk; 50 + unsigned long max_dclk; 51 + u8 features; 52 + }; 53 + 37 54 struct rzg2l_mipi_dsi { 38 55 struct device *dev; 39 56 void __iomem *mmio; 57 + 58 + const struct rzg2l_mipi_dsi_hw_info *info; 40 59 41 60 struct reset_control *rstc; 42 61 struct reset_control *arstc; ··· 108 85 109 86 static const struct rzg2l_mipi_dsi_timings rzg2l_mipi_dsi_global_timings[] = { 110 87 { 111 - .hsfreq_max = 80000, 88 + .hsfreq_max = 80000000, 112 89 .t_init = 79801, 113 90 .tclk_prepare = 8, 114 91 .ths_prepare = 13, ··· 122 99 .tlpx = 6, 123 100 }, 124 101 { 125 - .hsfreq_max = 125000, 102 + .hsfreq_max = 125000000, 126 103 .t_init = 79801, 127 104 .tclk_prepare = 8, 128 105 .ths_prepare = 12, ··· 136 113 .tlpx = 6, 137 114 }, 138 115 { 139 - .hsfreq_max = 250000, 116 + .hsfreq_max = 250000000, 140 117 .t_init = 79801, 141 118 .tclk_prepare = 8, 142 119 .ths_prepare = 12, ··· 150 127 .tlpx = 6, 151 128 }, 152 129 { 153 - .hsfreq_max = 360000, 130 + .hsfreq_max = 360000000, 154 131 .t_init = 79801, 155 132 .tclk_prepare = 8, 156 133 .ths_prepare = 10, ··· 164 141 .tlpx = 6, 165 142 }, 166 143 { 167 - .hsfreq_max = 720000, 144 + .hsfreq_max = 720000000, 168 145 .t_init = 79801, 169 146 .tclk_prepare = 8, 170 147 .ths_prepare = 9, ··· 178 155 .tlpx = 6, 179 156 }, 180 157 { 181 - .hsfreq_max = 1500000, 158 + .hsfreq_max = 1500000000, 182 159 .t_init = 79801, 183 160 .tclk_prepare = 8, 184 161 .ths_prepare = 9, ··· 195 172 196 173 static void rzg2l_mipi_dsi_phy_write(struct rzg2l_mipi_dsi *dsi, u32 reg, u32 data) 197 174 { 198 - iowrite32(data, dsi->mmio + reg); 175 + iowrite32(data, dsi->mmio + dsi->info->phy_reg_offset + reg); 199 176 } 200 177 201 178 static void rzg2l_mipi_dsi_link_write(struct rzg2l_mipi_dsi *dsi, u32 reg, u32 data) 202 179 { 203 - iowrite32(data, dsi->mmio + LINK_REG_OFFSET + reg); 180 + iowrite32(data, dsi->mmio + dsi->info->link_reg_offset + reg); 204 181 } 205 182 206 183 static u32 rzg2l_mipi_dsi_phy_read(struct rzg2l_mipi_dsi *dsi, u32 reg) 207 184 { 208 - return ioread32(dsi->mmio + reg); 185 + return ioread32(dsi->mmio + dsi->info->phy_reg_offset + reg); 209 186 } 210 187 211 188 static u32 rzg2l_mipi_dsi_link_read(struct rzg2l_mipi_dsi *dsi, u32 reg) 212 189 { 213 - return ioread32(dsi->mmio + LINK_REG_OFFSET + reg); 190 + return ioread32(dsi->mmio + dsi->info->link_reg_offset + reg); 214 191 } 215 192 216 193 /* ----------------------------------------------------------------------------- ··· 218 195 */ 219 196 220 197 static int rzg2l_mipi_dsi_dphy_init(struct rzg2l_mipi_dsi *dsi, 221 - unsigned long hsfreq) 198 + u64 hsfreq_millihz) 222 199 { 200 + unsigned long hsfreq = DIV_ROUND_CLOSEST_ULL(hsfreq_millihz, MILLI); 223 201 const struct rzg2l_mipi_dsi_timings *dphy_timings; 224 202 unsigned int i; 225 203 u32 dphyctrl0; ··· 289 265 reset_control_assert(dsi->rstc); 290 266 } 291 267 268 + static int rzg2l_dphy_conf_clks(struct rzg2l_mipi_dsi *dsi, unsigned long mode_freq, 269 + u64 *hsfreq_millihz) 270 + { 271 + unsigned long vclk_rate; 272 + unsigned int bpp; 273 + 274 + clk_set_rate(dsi->vclk, mode_freq * KILO); 275 + vclk_rate = clk_get_rate(dsi->vclk); 276 + if (vclk_rate != mode_freq * KILO) 277 + dev_dbg(dsi->dev, "Requested vclk rate %lu, actual %lu mismatch\n", 278 + mode_freq * KILO, vclk_rate); 279 + /* 280 + * Relationship between hsclk and vclk must follow 281 + * vclk * bpp = hsclk * 8 * lanes 282 + * where vclk: video clock (Hz) 283 + * bpp: video pixel bit depth 284 + * hsclk: DSI HS Byte clock frequency (Hz) 285 + * lanes: number of data lanes 286 + * 287 + * hsclk(bit) = hsclk(byte) * 8 = hsfreq 288 + */ 289 + bpp = mipi_dsi_pixel_format_to_bpp(dsi->format); 290 + *hsfreq_millihz = DIV_ROUND_CLOSEST_ULL(mul_u32_u32(vclk_rate, bpp * MILLI), 291 + dsi->lanes); 292 + 293 + return 0; 294 + } 295 + 292 296 static int rzg2l_mipi_dsi_startup(struct rzg2l_mipi_dsi *dsi, 293 297 const struct drm_display_mode *mode) 294 298 { 295 299 unsigned long hsfreq; 296 - unsigned int bpp; 300 + u64 hsfreq_millihz; 297 301 u32 txsetr; 298 302 u32 clstptsetr; 299 303 u32 lptrnstsetr; ··· 332 280 u32 dsisetr; 333 281 int ret; 334 282 335 - /* 336 - * Relationship between hsclk and vclk must follow 337 - * vclk * bpp = hsclk * 8 * lanes 338 - * where vclk: video clock (Hz) 339 - * bpp: video pixel bit depth 340 - * hsclk: DSI HS Byte clock frequency (Hz) 341 - * lanes: number of data lanes 342 - * 343 - * hsclk(bit) = hsclk(byte) * 8 344 - */ 345 - bpp = mipi_dsi_pixel_format_to_bpp(dsi->format); 346 - hsfreq = (mode->clock * bpp * 8) / (8 * dsi->lanes); 347 - 348 283 ret = pm_runtime_resume_and_get(dsi->dev); 349 284 if (ret < 0) 350 285 return ret; 351 286 352 - clk_set_rate(dsi->vclk, mode->clock * 1000); 287 + ret = dsi->info->dphy_conf_clks(dsi, mode->clock, &hsfreq_millihz); 288 + if (ret < 0) 289 + goto err_phy; 353 290 354 - ret = rzg2l_mipi_dsi_dphy_init(dsi, hsfreq); 291 + ret = dsi->info->dphy_init(dsi, hsfreq_millihz); 355 292 if (ret < 0) 356 293 goto err_phy; 357 294 ··· 348 307 txsetr = TXSETR_DLEN | TXSETR_NUMLANEUSE(dsi->lanes - 1) | TXSETR_CLEN; 349 308 rzg2l_mipi_dsi_link_write(dsi, TXSETR, txsetr); 350 309 310 + if (dsi->info->dphy_startup_late_init) 311 + dsi->info->dphy_startup_late_init(dsi); 312 + 313 + hsfreq = DIV_ROUND_CLOSEST_ULL(hsfreq_millihz, MILLI); 351 314 /* 352 315 * Global timings characteristic depends on high speed Clock Frequency 353 316 * Currently MIPI DSI-IF just supports maximum FHD@60 with: ··· 360 315 * - data lanes: maximum 4 lanes 361 316 * Therefore maximum hsclk will be 891 Mbps. 362 317 */ 363 - if (hsfreq > 445500) { 318 + if (hsfreq > 445500000) { 364 319 clkkpt = 12; 365 320 clkbfht = 15; 366 321 clkstpt = 48; 367 322 golpbkt = 75; 368 - } else if (hsfreq > 250000) { 323 + } else if (hsfreq > 250000000) { 369 324 clkkpt = 7; 370 325 clkbfht = 8; 371 326 clkstpt = 27; ··· 396 351 return 0; 397 352 398 353 err_phy: 399 - rzg2l_mipi_dsi_dphy_exit(dsi); 354 + dsi->info->dphy_exit(dsi); 400 355 pm_runtime_put(dsi->dev); 401 356 402 357 return ret; ··· 404 359 405 360 static void rzg2l_mipi_dsi_stop(struct rzg2l_mipi_dsi *dsi) 406 361 { 407 - rzg2l_mipi_dsi_dphy_exit(dsi); 362 + dsi->info->dphy_exit(dsi); 408 363 pm_runtime_put(dsi->dev); 409 364 } 410 365 ··· 654 609 const struct drm_display_info *info, 655 610 const struct drm_display_mode *mode) 656 611 { 657 - if (mode->clock > 148500) 612 + struct rzg2l_mipi_dsi *dsi = bridge_to_rzg2l_mipi_dsi(bridge); 613 + 614 + if (mode->clock > dsi->info->max_dclk) 658 615 return MODE_CLOCK_HIGH; 616 + 617 + if (mode->clock < dsi->info->min_dclk) 618 + return MODE_CLOCK_LOW; 619 + 620 + if (dsi->info->dphy_mode_clk_check) { 621 + enum drm_mode_status status; 622 + 623 + status = dsi->info->dphy_mode_clk_check(dsi, mode->clock); 624 + if (status != MODE_OK) 625 + return status; 626 + } 659 627 660 628 return MODE_OK; 661 629 } ··· 703 645 704 646 switch (mipi_dsi_pixel_format_to_bpp(device->format)) { 705 647 case 24: 648 + break; 706 649 case 18: 650 + break; 651 + case 16: 652 + if (!(dsi->info->features & RZ_MIPI_DSI_FEATURE_16BPP)) { 653 + dev_err(dsi->dev, "Unsupported format 0x%04x\n", 654 + device->format); 655 + return -EINVAL; 656 + } 707 657 break; 708 658 default: 709 659 dev_err(dsi->dev, "Unsupported format 0x%04x\n", device->format); ··· 962 896 platform_set_drvdata(pdev, dsi); 963 897 dsi->dev = &pdev->dev; 964 898 899 + dsi->info = of_device_get_match_data(&pdev->dev); 900 + 965 901 ret = drm_of_get_data_lanes_count_ep(dsi->dev->of_node, 1, 0, 1, 4); 966 902 if (ret < 0) 967 903 return dev_err_probe(dsi->dev, ret, ··· 979 911 if (IS_ERR(dsi->vclk)) 980 912 return PTR_ERR(dsi->vclk); 981 913 982 - dsi->rstc = devm_reset_control_get_exclusive(dsi->dev, "rst"); 914 + dsi->rstc = devm_reset_control_get_optional_exclusive(dsi->dev, "rst"); 983 915 if (IS_ERR(dsi->rstc)) 984 916 return dev_err_probe(dsi->dev, PTR_ERR(dsi->rstc), 985 917 "failed to get rst\n"); ··· 1007 939 * mode->clock and format are not available. So initialize DPHY with 1008 940 * timing parameters for 80Mbps. 1009 941 */ 1010 - ret = rzg2l_mipi_dsi_dphy_init(dsi, 80000); 942 + ret = dsi->info->dphy_init(dsi, 80000000ULL * MILLI); 1011 943 if (ret < 0) 1012 944 goto err_phy; 1013 945 1014 946 txsetr = rzg2l_mipi_dsi_link_read(dsi, TXSETR); 1015 947 dsi->num_data_lanes = min(((txsetr >> 16) & 3) + 1, num_data_lanes); 1016 - rzg2l_mipi_dsi_dphy_exit(dsi); 948 + dsi->info->dphy_exit(dsi); 1017 949 pm_runtime_put(dsi->dev); 1018 950 1019 951 /* Initialize the DRM bridge. */ ··· 1034 966 return 0; 1035 967 1036 968 err_phy: 1037 - rzg2l_mipi_dsi_dphy_exit(dsi); 969 + dsi->info->dphy_exit(dsi); 1038 970 pm_runtime_put(dsi->dev); 1039 971 err_pm_disable: 1040 972 pm_runtime_disable(dsi->dev); ··· 1051 983 pm_runtime_disable(&pdev->dev); 1052 984 } 1053 985 986 + static const struct rzg2l_mipi_dsi_hw_info rzg2l_mipi_dsi_info = { 987 + .dphy_init = rzg2l_mipi_dsi_dphy_init, 988 + .dphy_exit = rzg2l_mipi_dsi_dphy_exit, 989 + .dphy_conf_clks = rzg2l_dphy_conf_clks, 990 + .link_reg_offset = 0x10000, 991 + .min_dclk = 5803, 992 + .max_dclk = 148500, 993 + }; 994 + 1054 995 static const struct of_device_id rzg2l_mipi_dsi_of_table[] = { 1055 - { .compatible = "renesas,rzg2l-mipi-dsi" }, 996 + { .compatible = "renesas,rzg2l-mipi-dsi", .data = &rzg2l_mipi_dsi_info, }, 1056 997 { /* sentinel */ } 1057 998 }; 1058 999
-2
drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi_regs.h
··· 41 41 #define DSIDPHYTIM3_THS_ZERO(x) ((x) << 0) 42 42 43 43 /* --------------------------------------------------------*/ 44 - /* Link Registers */ 45 - #define LINK_REG_OFFSET 0x10000 46 44 47 45 /* Link Status Register */ 48 46 #define LINKSR 0x10
+1
drivers/gpu/drm/scheduler/sched_entity.c
··· 21 21 * 22 22 */ 23 23 24 + #include <linux/export.h> 24 25 #include <linux/slab.h> 25 26 #include <linux/completion.h> 26 27
+1
drivers/gpu/drm/scheduler/sched_fence.c
··· 21 21 * 22 22 */ 23 23 24 + #include <linux/export.h> 24 25 #include <linux/module.h> 25 26 #include <linux/sched.h> 26 27 #include <linux/slab.h>
+1
drivers/gpu/drm/scheduler/sched_main.c
··· 66 66 * This implies waiting for previously executed jobs. 67 67 */ 68 68 69 + #include <linux/export.h> 69 70 #include <linux/wait.h> 70 71 #include <linux/sched.h> 71 72 #include <linux/completion.h>
+4
drivers/gpu/drm/sysfb/drm_sysfb_helper.h
··· 93 93 * Plane 94 94 */ 95 95 96 + size_t drm_sysfb_build_fourcc_list(struct drm_device *dev, 97 + const u32 *native_fourccs, size_t native_nfourccs, 98 + u32 *fourccs_out, size_t nfourccs_out); 99 + 96 100 int drm_sysfb_plane_helper_atomic_check(struct drm_plane *plane, 97 101 struct drm_atomic_state *new_state); 98 102 void drm_sysfb_plane_helper_atomic_update(struct drm_plane *plane,
+138
drivers/gpu/drm/sysfb/drm_sysfb_modeset.c
··· 47 47 * Plane 48 48 */ 49 49 50 + static u32 to_nonalpha_fourcc(u32 fourcc) 51 + { 52 + /* only handle formats with depth != 0 and alpha channel */ 53 + switch (fourcc) { 54 + case DRM_FORMAT_ARGB1555: 55 + return DRM_FORMAT_XRGB1555; 56 + case DRM_FORMAT_ABGR1555: 57 + return DRM_FORMAT_XBGR1555; 58 + case DRM_FORMAT_RGBA5551: 59 + return DRM_FORMAT_RGBX5551; 60 + case DRM_FORMAT_BGRA5551: 61 + return DRM_FORMAT_BGRX5551; 62 + case DRM_FORMAT_ARGB8888: 63 + return DRM_FORMAT_XRGB8888; 64 + case DRM_FORMAT_ABGR8888: 65 + return DRM_FORMAT_XBGR8888; 66 + case DRM_FORMAT_RGBA8888: 67 + return DRM_FORMAT_RGBX8888; 68 + case DRM_FORMAT_BGRA8888: 69 + return DRM_FORMAT_BGRX8888; 70 + case DRM_FORMAT_ARGB2101010: 71 + return DRM_FORMAT_XRGB2101010; 72 + case DRM_FORMAT_ABGR2101010: 73 + return DRM_FORMAT_XBGR2101010; 74 + case DRM_FORMAT_RGBA1010102: 75 + return DRM_FORMAT_RGBX1010102; 76 + case DRM_FORMAT_BGRA1010102: 77 + return DRM_FORMAT_BGRX1010102; 78 + } 79 + 80 + return fourcc; 81 + } 82 + 83 + static bool is_listed_fourcc(const u32 *fourccs, size_t nfourccs, u32 fourcc) 84 + { 85 + const u32 *fourccs_end = fourccs + nfourccs; 86 + 87 + while (fourccs < fourccs_end) { 88 + if (*fourccs == fourcc) 89 + return true; 90 + ++fourccs; 91 + } 92 + return false; 93 + } 94 + 95 + /** 96 + * drm_sysfb_build_fourcc_list - Filters a list of supported color formats against 97 + * the device's native formats 98 + * @dev: DRM device 99 + * @native_fourccs: 4CC codes of natively supported color formats 100 + * @native_nfourccs: The number of entries in @native_fourccs 101 + * @fourccs_out: Returns 4CC codes of supported color formats 102 + * @nfourccs_out: The number of available entries in @fourccs_out 103 + * 104 + * This function create a list of supported color format from natively 105 + * supported formats and additional emulated formats. 106 + * At a minimum, most userspace programs expect at least support for 107 + * XRGB8888 on the primary plane. Sysfb devices that have to emulate 108 + * the format should use drm_sysfb_build_fourcc_list() to create a list 109 + * of supported color formats. The returned list can be handed over to 110 + * drm_universal_plane_init() et al. Native formats will go before 111 + * emulated formats. Native formats with alpha channel will be replaced 112 + * by equal formats without alpha channel, as primary planes usually 113 + * don't support alpha. Other heuristics might be applied to optimize 114 + * the sorting order. Formats near the beginning of the list are usually 115 + * preferred over formats near the end of the list. 116 + * 117 + * Returns: 118 + * The number of color-formats 4CC codes returned in @fourccs_out. 119 + */ 120 + size_t drm_sysfb_build_fourcc_list(struct drm_device *dev, 121 + const u32 *native_fourccs, size_t native_nfourccs, 122 + u32 *fourccs_out, size_t nfourccs_out) 123 + { 124 + /* 125 + * XRGB8888 is the default fallback format for most of userspace 126 + * and it's currently the only format that should be emulated for 127 + * the primary plane. Only if there's ever another default fallback, 128 + * it should be added here. 129 + */ 130 + static const u32 extra_fourccs[] = { 131 + DRM_FORMAT_XRGB8888, 132 + }; 133 + static const size_t extra_nfourccs = ARRAY_SIZE(extra_fourccs); 134 + 135 + u32 *fourccs = fourccs_out; 136 + const u32 *fourccs_end = fourccs_out + nfourccs_out; 137 + size_t i; 138 + 139 + /* 140 + * The device's native formats go first. 141 + */ 142 + 143 + for (i = 0; i < native_nfourccs; ++i) { 144 + /* 145 + * Several DTs, boot loaders and firmware report native 146 + * alpha formats that are non-alpha formats instead. So 147 + * replace alpha formats by non-alpha formats. 148 + */ 149 + u32 fourcc = to_nonalpha_fourcc(native_fourccs[i]); 150 + 151 + if (is_listed_fourcc(fourccs_out, fourccs - fourccs_out, fourcc)) { 152 + continue; /* skip duplicate entries */ 153 + } else if (fourccs == fourccs_end) { 154 + drm_warn(dev, "Ignoring native format %p4cc\n", &fourcc); 155 + continue; /* end of available output buffer */ 156 + } 157 + 158 + drm_dbg_kms(dev, "adding native format %p4cc\n", &fourcc); 159 + 160 + *fourccs = fourcc; 161 + ++fourccs; 162 + } 163 + 164 + /* 165 + * The extra formats, emulated by the driver, go second. 166 + */ 167 + 168 + for (i = 0; (i < extra_nfourccs) && (fourccs < fourccs_end); ++i) { 169 + u32 fourcc = extra_fourccs[i]; 170 + 171 + if (is_listed_fourcc(fourccs_out, fourccs - fourccs_out, fourcc)) { 172 + continue; /* skip duplicate and native entries */ 173 + } else if (fourccs == fourccs_end) { 174 + drm_warn(dev, "Ignoring emulated format %p4cc\n", &fourcc); 175 + continue; /* end of available output buffer */ 176 + } 177 + 178 + drm_dbg_kms(dev, "adding emulated format %p4cc\n", &fourcc); 179 + 180 + *fourccs = fourcc; 181 + ++fourccs; 182 + } 183 + 184 + return fourccs - fourccs_out; 185 + } 186 + EXPORT_SYMBOL(drm_sysfb_build_fourcc_list); 187 + 50 188 int drm_sysfb_plane_helper_atomic_check(struct drm_plane *plane, 51 189 struct drm_atomic_state *new_state) 52 190 {
+3 -3
drivers/gpu/drm/sysfb/efidrm.c
··· 202 202 drm_dbg(dev, "framebuffer format=%p4cc, size=%dx%d, stride=%d bytes\n", 203 203 &format->format, width, height, stride); 204 204 205 - #ifdef CONFIG_X86 205 + #if defined(CONFIG_FIRMWARE_EDID) 206 206 if (drm_edid_header_is_valid(edid_info.dummy) == 8) 207 207 sysfb->edid = edid_info.dummy; 208 208 #endif ··· 271 271 272 272 /* Primary plane */ 273 273 274 - nformats = drm_fb_build_fourcc_list(dev, &format->format, 1, 275 - efi->formats, ARRAY_SIZE(efi->formats)); 274 + nformats = drm_sysfb_build_fourcc_list(dev, &format->format, 1, 275 + efi->formats, ARRAY_SIZE(efi->formats)); 276 276 277 277 primary_plane = &efi->primary_plane; 278 278 ret = drm_universal_plane_init(dev, primary_plane, 0, &efidrm_primary_plane_funcs,
+2 -3
drivers/gpu/drm/sysfb/ofdrm.c
··· 15 15 #include <drm/drm_drv.h> 16 16 #include <drm/drm_edid.h> 17 17 #include <drm/drm_fbdev_shmem.h> 18 - #include <drm/drm_format_helper.h> 19 18 #include <drm/drm_framebuffer.h> 20 19 #include <drm/drm_gem_atomic_helper.h> 21 20 #include <drm/drm_gem_framebuffer_helper.h> ··· 1014 1015 1015 1016 /* Primary plane */ 1016 1017 1017 - nformats = drm_fb_build_fourcc_list(dev, &format->format, 1, 1018 - odev->formats, ARRAY_SIZE(odev->formats)); 1018 + nformats = drm_sysfb_build_fourcc_list(dev, &format->format, 1, 1019 + odev->formats, ARRAY_SIZE(odev->formats)); 1019 1020 1020 1021 primary_plane = &odev->primary_plane; 1021 1022 ret = drm_universal_plane_init(dev, primary_plane, 0, &ofdrm_primary_plane_funcs,
+2 -3
drivers/gpu/drm/sysfb/simpledrm.c
··· 18 18 #include <drm/drm_device.h> 19 19 #include <drm/drm_drv.h> 20 20 #include <drm/drm_fbdev_shmem.h> 21 - #include <drm/drm_format_helper.h> 22 21 #include <drm/drm_framebuffer.h> 23 22 #include <drm/drm_gem_atomic_helper.h> 24 23 #include <drm/drm_gem_framebuffer_helper.h> ··· 764 765 765 766 /* Primary plane */ 766 767 767 - nformats = drm_fb_build_fourcc_list(dev, &format->format, 1, 768 - sdev->formats, ARRAY_SIZE(sdev->formats)); 768 + nformats = drm_sysfb_build_fourcc_list(dev, &format->format, 1, 769 + sdev->formats, ARRAY_SIZE(sdev->formats)); 769 770 770 771 primary_plane = &sdev->primary_plane; 771 772 ret = drm_universal_plane_init(dev, primary_plane, 0, &simpledrm_primary_plane_funcs,
+3 -3
drivers/gpu/drm/sysfb/vesadrm.c
··· 344 344 #endif 345 345 } 346 346 347 - #ifdef CONFIG_X86 347 + #if defined(CONFIG_FIRMWARE_EDID) 348 348 if (drm_edid_header_is_valid(edid_info.dummy) == 8) 349 349 sysfb->edid = edid_info.dummy; 350 350 #endif ··· 402 402 403 403 /* Primary plane */ 404 404 405 - nformats = drm_fb_build_fourcc_list(dev, &format->format, 1, 406 - vesa->formats, ARRAY_SIZE(vesa->formats)); 405 + nformats = drm_sysfb_build_fourcc_list(dev, &format->format, 1, 406 + vesa->formats, ARRAY_SIZE(vesa->formats)); 407 407 408 408 primary_plane = &vesa->primary_plane; 409 409 ret = drm_universal_plane_init(dev, primary_plane, 0, &vesadrm_primary_plane_funcs,
+2 -1
drivers/gpu/drm/tests/Makefile
··· 23 23 drm_modes_test.o \ 24 24 drm_plane_helper_test.o \ 25 25 drm_probe_helper_test.o \ 26 - drm_rect_test.o 26 + drm_rect_test.o \ 27 + drm_sysfb_modeset_test.o 27 28 28 29 CFLAGS_drm_mm_test.o := $(DISABLE_STRUCTLEAK_PLUGIN)
+22 -240
drivers/gpu/drm/tests/drm_format_helper_test.c
··· 279 279 .dst_pitch = TEST_USE_DEFAULT_PITCH, 280 280 .expected = { 281 281 0xFF, 0x00, 282 - 0x4C, 0x99, 283 - 0x19, 0x66, 284 - 0xE5, 0xB2, 282 + 0x4C, 0x95, 283 + 0x1C, 0x69, 284 + 0xE2, 0xB2, 285 285 }, 286 286 }, 287 287 .rgb332_result = { ··· 430 430 .gray8_result = { 431 431 .dst_pitch = 5, 432 432 .expected = { 433 - 0x3C, 0x33, 0xC4, 0x00, 0x00, 434 - 0xBB, 0x3C, 0x33, 0x00, 0x00, 435 - 0x34, 0xBB, 0x3C, 0x00, 0x00, 433 + 0x3D, 0x32, 0xC1, 0x00, 0x00, 434 + 0xBA, 0x3D, 0x32, 0x00, 0x00, 435 + 0x34, 0xBA, 0x3D, 0x00, 0x00, 436 436 }, 437 437 }, 438 438 .rgb332_result = { ··· 748 748 buf = dst.vaddr; 749 749 memset(buf, 0, dst_size); 750 750 751 - int blit_result = 0; 752 - 753 - blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_RGB565, &src, &fb, &params->clip, 754 - &fmtcnv_state); 755 - 751 + drm_fb_xrgb8888_to_rgb565(&dst, dst_pitch, &src, &fb, &params->clip, 752 + &fmtcnv_state, false); 756 753 buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16)); 757 - 758 - KUNIT_EXPECT_FALSE(test, blit_result); 759 754 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size); 760 755 } 761 756 ··· 790 795 buf = dst.vaddr; /* restore original value of buf */ 791 796 memset(buf, 0, dst_size); 792 797 793 - int blit_result = 0; 794 - 795 - blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_XRGB1555, &src, &fb, &params->clip, 796 - &fmtcnv_state); 797 - 798 + drm_fb_xrgb8888_to_xrgb1555(&dst, dst_pitch, &src, &fb, &params->clip, &fmtcnv_state); 798 799 buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16)); 799 - 800 - KUNIT_EXPECT_FALSE(test, blit_result); 801 800 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size); 802 801 } 803 802 ··· 831 842 buf = dst.vaddr; /* restore original value of buf */ 832 843 memset(buf, 0, dst_size); 833 844 834 - int blit_result = 0; 835 - 836 - blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_ARGB1555, &src, &fb, &params->clip, 837 - &fmtcnv_state); 838 - 845 + drm_fb_xrgb8888_to_argb1555(&dst, dst_pitch, &src, &fb, &params->clip, &fmtcnv_state); 839 846 buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16)); 840 - 841 - KUNIT_EXPECT_FALSE(test, blit_result); 842 847 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size); 843 848 } 844 849 ··· 872 889 buf = dst.vaddr; /* restore original value of buf */ 873 890 memset(buf, 0, dst_size); 874 891 875 - int blit_result = 0; 876 - 877 - blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_RGBA5551, &src, &fb, &params->clip, 878 - &fmtcnv_state); 879 - 892 + drm_fb_xrgb8888_to_rgba5551(&dst, dst_pitch, &src, &fb, &params->clip, &fmtcnv_state); 880 893 buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16)); 881 - 882 - KUNIT_EXPECT_FALSE(test, blit_result); 883 894 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size); 884 895 } 885 896 ··· 916 939 buf = dst.vaddr; /* restore original value of buf */ 917 940 memset(buf, 0, dst_size); 918 941 919 - int blit_result = 0; 920 - 921 - blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_RGB888, &src, &fb, &params->clip, 922 - &fmtcnv_state); 923 - 924 - KUNIT_EXPECT_FALSE(test, blit_result); 942 + drm_fb_xrgb8888_to_rgb888(&dst, dst_pitch, &src, &fb, &params->clip, &fmtcnv_state); 925 943 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size); 926 944 } 927 945 ··· 957 985 buf = dst.vaddr; /* restore original value of buf */ 958 986 memset(buf, 0, dst_size); 959 987 960 - int blit_result = 0; 961 - 962 - blit_result = drm_fb_blit(&dst, &result->dst_pitch, DRM_FORMAT_BGR888, &src, &fb, &params->clip, 988 + drm_fb_xrgb8888_to_bgr888(&dst, &result->dst_pitch, &src, &fb, &params->clip, 963 989 &fmtcnv_state); 964 - 965 - KUNIT_EXPECT_FALSE(test, blit_result); 966 990 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size); 967 991 } 968 992 ··· 998 1030 buf = dst.vaddr; /* restore original value of buf */ 999 1031 memset(buf, 0, dst_size); 1000 1032 1001 - int blit_result = 0; 1002 - 1003 - blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_ARGB8888, &src, &fb, &params->clip, 1004 - &fmtcnv_state); 1005 - 1033 + drm_fb_xrgb8888_to_argb8888(&dst, dst_pitch, &src, &fb, &params->clip, &fmtcnv_state); 1006 1034 buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32)); 1007 - 1008 - KUNIT_EXPECT_FALSE(test, blit_result); 1009 1035 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size); 1010 1036 } 1011 1037 ··· 1039 1077 buf = dst.vaddr; /* restore original value of buf */ 1040 1078 memset(buf, 0, dst_size); 1041 1079 1042 - int blit_result = 0; 1043 - 1044 - blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_XRGB2101010, &src, &fb, 1045 - &params->clip, &fmtcnv_state); 1046 - 1047 - KUNIT_EXPECT_FALSE(test, blit_result); 1080 + drm_fb_xrgb8888_to_xrgb2101010(&dst, dst_pitch, &src, &fb, &params->clip, &fmtcnv_state); 1048 1081 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size); 1049 1082 } 1050 1083 ··· 1079 1122 buf = dst.vaddr; /* restore original value of buf */ 1080 1123 memset(buf, 0, dst_size); 1081 1124 1082 - int blit_result = 0; 1083 - 1084 - blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_ARGB2101010, &src, &fb, 1085 - &params->clip, &fmtcnv_state); 1086 - 1125 + drm_fb_xrgb8888_to_argb2101010(&dst, dst_pitch, &src, &fb, &params->clip, &fmtcnv_state); 1087 1126 buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32)); 1088 - 1089 - KUNIT_EXPECT_FALSE(test, blit_result); 1090 1127 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size); 1091 1128 } 1092 1129 ··· 1153 1202 buf = dst.vaddr; /* restore original value of buf */ 1154 1203 memset(buf, 0, dst_size); 1155 1204 1156 - int blit_result; 1157 - 1158 - blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_XRGB8888 | DRM_FORMAT_BIG_ENDIAN, 1159 - &src, &fb, &params->clip, &fmtcnv_state); 1205 + drm_fb_swab(&dst, dst_pitch, &src, &fb, &params->clip, false, &fmtcnv_state); 1160 1206 buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32)); 1161 - 1162 - KUNIT_EXPECT_FALSE(test, blit_result); 1163 1207 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size); 1164 1208 1165 1209 buf = dst.vaddr; 1166 1210 memset(buf, 0, dst_size); 1167 1211 1168 - blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_BGRX8888, &src, &fb, &params->clip, 1169 - &fmtcnv_state); 1212 + drm_fb_xrgb8888_to_bgrx8888(&dst, dst_pitch, &src, &fb, &params->clip, &fmtcnv_state); 1170 1213 buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32)); 1171 - 1172 - KUNIT_EXPECT_FALSE(test, blit_result); 1173 1214 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size); 1174 1215 1175 1216 buf = dst.vaddr; ··· 1172 1229 mock_format.format |= DRM_FORMAT_BIG_ENDIAN; 1173 1230 fb.format = &mock_format; 1174 1231 1175 - blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_XRGB8888, &src, &fb, &params->clip, 1176 - &fmtcnv_state); 1232 + drm_fb_swab(&dst, dst_pitch, &src, &fb, &params->clip, false, &fmtcnv_state); 1177 1233 buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32)); 1178 - 1179 - KUNIT_EXPECT_FALSE(test, blit_result); 1180 1234 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size); 1181 1235 } 1182 1236 ··· 1206 1266 const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ? 1207 1267 NULL : &result->dst_pitch; 1208 1268 1209 - int blit_result = 0; 1210 - 1211 - blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_ABGR8888, &src, &fb, &params->clip, 1212 - &fmtcnv_state); 1213 - 1269 + drm_fb_xrgb8888_to_abgr8888(&dst, dst_pitch, &src, &fb, &params->clip, &fmtcnv_state); 1214 1270 buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32)); 1215 - 1216 - KUNIT_EXPECT_FALSE(test, blit_result); 1217 1271 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size); 1218 1272 } 1219 1273 ··· 1240 1306 const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ? 1241 1307 NULL : &result->dst_pitch; 1242 1308 1243 - int blit_result = 0; 1244 - 1245 - blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_XBGR8888, &src, &fb, &params->clip, 1246 - &fmtcnv_state); 1247 - 1309 + drm_fb_xrgb8888_to_xbgr8888(&dst, dst_pitch, &src, &fb, &params->clip, &fmtcnv_state); 1248 1310 buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32)); 1249 - 1250 - KUNIT_EXPECT_FALSE(test, blit_result); 1251 1311 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size); 1252 1312 } 1253 1313 ··· 1333 1405 offset = drm_fb_clip_offset(pitch, format_info, &params->clip); 1334 1406 1335 1407 KUNIT_EXPECT_EQ(test, offset, params->expected_offset); 1336 - } 1337 - 1338 - struct fb_build_fourcc_list_case { 1339 - const char *name; 1340 - u32 native_fourccs[TEST_BUF_SIZE]; 1341 - size_t native_fourccs_size; 1342 - u32 expected[TEST_BUF_SIZE]; 1343 - size_t expected_fourccs_size; 1344 - }; 1345 - 1346 - static struct fb_build_fourcc_list_case fb_build_fourcc_list_cases[] = { 1347 - { 1348 - .name = "no native formats", 1349 - .native_fourccs = { }, 1350 - .native_fourccs_size = 0, 1351 - .expected = { DRM_FORMAT_XRGB8888 }, 1352 - .expected_fourccs_size = 1, 1353 - }, 1354 - { 1355 - .name = "XRGB8888 as native format", 1356 - .native_fourccs = { DRM_FORMAT_XRGB8888 }, 1357 - .native_fourccs_size = 1, 1358 - .expected = { DRM_FORMAT_XRGB8888 }, 1359 - .expected_fourccs_size = 1, 1360 - }, 1361 - { 1362 - .name = "remove duplicates", 1363 - .native_fourccs = { 1364 - DRM_FORMAT_XRGB8888, 1365 - DRM_FORMAT_XRGB8888, 1366 - DRM_FORMAT_RGB888, 1367 - DRM_FORMAT_RGB888, 1368 - DRM_FORMAT_RGB888, 1369 - DRM_FORMAT_XRGB8888, 1370 - DRM_FORMAT_RGB888, 1371 - DRM_FORMAT_RGB565, 1372 - DRM_FORMAT_RGB888, 1373 - DRM_FORMAT_XRGB8888, 1374 - DRM_FORMAT_RGB565, 1375 - DRM_FORMAT_RGB565, 1376 - DRM_FORMAT_XRGB8888, 1377 - }, 1378 - .native_fourccs_size = 11, 1379 - .expected = { 1380 - DRM_FORMAT_XRGB8888, 1381 - DRM_FORMAT_RGB888, 1382 - DRM_FORMAT_RGB565, 1383 - }, 1384 - .expected_fourccs_size = 3, 1385 - }, 1386 - { 1387 - .name = "convert alpha formats", 1388 - .native_fourccs = { 1389 - DRM_FORMAT_ARGB1555, 1390 - DRM_FORMAT_ABGR1555, 1391 - DRM_FORMAT_RGBA5551, 1392 - DRM_FORMAT_BGRA5551, 1393 - DRM_FORMAT_ARGB8888, 1394 - DRM_FORMAT_ABGR8888, 1395 - DRM_FORMAT_RGBA8888, 1396 - DRM_FORMAT_BGRA8888, 1397 - DRM_FORMAT_ARGB2101010, 1398 - DRM_FORMAT_ABGR2101010, 1399 - DRM_FORMAT_RGBA1010102, 1400 - DRM_FORMAT_BGRA1010102, 1401 - }, 1402 - .native_fourccs_size = 12, 1403 - .expected = { 1404 - DRM_FORMAT_XRGB1555, 1405 - DRM_FORMAT_XBGR1555, 1406 - DRM_FORMAT_RGBX5551, 1407 - DRM_FORMAT_BGRX5551, 1408 - DRM_FORMAT_XRGB8888, 1409 - DRM_FORMAT_XBGR8888, 1410 - DRM_FORMAT_RGBX8888, 1411 - DRM_FORMAT_BGRX8888, 1412 - DRM_FORMAT_XRGB2101010, 1413 - DRM_FORMAT_XBGR2101010, 1414 - DRM_FORMAT_RGBX1010102, 1415 - DRM_FORMAT_BGRX1010102, 1416 - }, 1417 - .expected_fourccs_size = 12, 1418 - }, 1419 - { 1420 - .name = "random formats", 1421 - .native_fourccs = { 1422 - DRM_FORMAT_Y212, 1423 - DRM_FORMAT_ARGB1555, 1424 - DRM_FORMAT_ABGR16161616F, 1425 - DRM_FORMAT_C8, 1426 - DRM_FORMAT_BGR888, 1427 - DRM_FORMAT_XRGB1555, 1428 - DRM_FORMAT_RGBA5551, 1429 - DRM_FORMAT_BGR565_A8, 1430 - DRM_FORMAT_R10, 1431 - DRM_FORMAT_XYUV8888, 1432 - }, 1433 - .native_fourccs_size = 10, 1434 - .expected = { 1435 - DRM_FORMAT_Y212, 1436 - DRM_FORMAT_XRGB1555, 1437 - DRM_FORMAT_ABGR16161616F, 1438 - DRM_FORMAT_C8, 1439 - DRM_FORMAT_BGR888, 1440 - DRM_FORMAT_RGBX5551, 1441 - DRM_FORMAT_BGR565_A8, 1442 - DRM_FORMAT_R10, 1443 - DRM_FORMAT_XYUV8888, 1444 - DRM_FORMAT_XRGB8888, 1445 - }, 1446 - .expected_fourccs_size = 10, 1447 - }, 1448 - }; 1449 - 1450 - static void fb_build_fourcc_list_case_desc(struct fb_build_fourcc_list_case *t, char *desc) 1451 - { 1452 - strscpy(desc, t->name, KUNIT_PARAM_DESC_SIZE); 1453 - } 1454 - 1455 - KUNIT_ARRAY_PARAM(fb_build_fourcc_list, fb_build_fourcc_list_cases, fb_build_fourcc_list_case_desc); 1456 - 1457 - static void drm_test_fb_build_fourcc_list(struct kunit *test) 1458 - { 1459 - const struct fb_build_fourcc_list_case *params = test->param_value; 1460 - u32 fourccs_out[TEST_BUF_SIZE] = {0}; 1461 - size_t nfourccs_out; 1462 - struct drm_device *drm; 1463 - struct device *dev; 1464 - 1465 - dev = drm_kunit_helper_alloc_device(test); 1466 - KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev); 1467 - 1468 - drm = __drm_kunit_helper_alloc_drm_device(test, dev, sizeof(*drm), 0, DRIVER_MODESET); 1469 - KUNIT_ASSERT_NOT_ERR_OR_NULL(test, drm); 1470 - 1471 - nfourccs_out = drm_fb_build_fourcc_list(drm, params->native_fourccs, 1472 - params->native_fourccs_size, 1473 - fourccs_out, TEST_BUF_SIZE); 1474 - 1475 - KUNIT_EXPECT_EQ(test, nfourccs_out, params->expected_fourccs_size); 1476 - KUNIT_EXPECT_MEMEQ(test, fourccs_out, params->expected, TEST_BUF_SIZE); 1477 1408 } 1478 1409 1479 1410 struct fb_memcpy_case { ··· 1697 1910 memset(buf[i], 0, dst_size[i]); 1698 1911 } 1699 1912 1700 - int blit_result; 1913 + drm_fb_memcpy(dst, dst_pitches, src, &fb, &params->clip); 1701 1914 1702 - blit_result = drm_fb_blit(dst, dst_pitches, params->format, src, &fb, &params->clip, 1703 - &fmtcnv_state); 1704 - 1705 - KUNIT_EXPECT_FALSE(test, blit_result); 1706 1915 for (size_t i = 0; i < fb.format->num_planes; i++) { 1707 1916 expected[i] = cpubuf_to_le32(test, params->expected[i], TEST_BUF_SIZE); 1708 1917 KUNIT_EXPECT_MEMEQ_MSG(test, buf[i], expected[i], dst_size[i], ··· 1723 1940 KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_xbgr8888, convert_xrgb8888_gen_params), 1724 1941 KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_abgr8888, convert_xrgb8888_gen_params), 1725 1942 KUNIT_CASE_PARAM(drm_test_fb_clip_offset, clip_offset_gen_params), 1726 - KUNIT_CASE_PARAM(drm_test_fb_build_fourcc_list, fb_build_fourcc_list_gen_params), 1727 1943 KUNIT_CASE_PARAM(drm_test_fb_memcpy, fb_memcpy_gen_params), 1728 1944 {} 1729 1945 };
+1
drivers/gpu/drm/tests/drm_kunit_helpers.c
··· 13 13 #include <kunit/resource.h> 14 14 15 15 #include <linux/device.h> 16 + #include <linux/export.h> 16 17 #include <linux/platform_device.h> 17 18 18 19 #define KUNIT_DEVICE_NAME "drm-kunit-mock-device"
+168
drivers/gpu/drm/tests/drm_sysfb_modeset_test.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 2 + 3 + #include <kunit/test.h> 4 + 5 + #include <drm/drm_fourcc.h> 6 + #include <drm/drm_kunit_helpers.h> 7 + 8 + #include "../sysfb/drm_sysfb_helper.h" 9 + 10 + #define TEST_BUF_SIZE 50 11 + 12 + struct sysfb_build_fourcc_list_case { 13 + const char *name; 14 + u32 native_fourccs[TEST_BUF_SIZE]; 15 + size_t native_fourccs_size; 16 + u32 expected[TEST_BUF_SIZE]; 17 + size_t expected_fourccs_size; 18 + }; 19 + 20 + static struct sysfb_build_fourcc_list_case sysfb_build_fourcc_list_cases[] = { 21 + { 22 + .name = "no native formats", 23 + .native_fourccs = { }, 24 + .native_fourccs_size = 0, 25 + .expected = { DRM_FORMAT_XRGB8888 }, 26 + .expected_fourccs_size = 1, 27 + }, 28 + { 29 + .name = "XRGB8888 as native format", 30 + .native_fourccs = { DRM_FORMAT_XRGB8888 }, 31 + .native_fourccs_size = 1, 32 + .expected = { DRM_FORMAT_XRGB8888 }, 33 + .expected_fourccs_size = 1, 34 + }, 35 + { 36 + .name = "remove duplicates", 37 + .native_fourccs = { 38 + DRM_FORMAT_XRGB8888, 39 + DRM_FORMAT_XRGB8888, 40 + DRM_FORMAT_RGB888, 41 + DRM_FORMAT_RGB888, 42 + DRM_FORMAT_RGB888, 43 + DRM_FORMAT_XRGB8888, 44 + DRM_FORMAT_RGB888, 45 + DRM_FORMAT_RGB565, 46 + DRM_FORMAT_RGB888, 47 + DRM_FORMAT_XRGB8888, 48 + DRM_FORMAT_RGB565, 49 + DRM_FORMAT_RGB565, 50 + DRM_FORMAT_XRGB8888, 51 + }, 52 + .native_fourccs_size = 11, 53 + .expected = { 54 + DRM_FORMAT_XRGB8888, 55 + DRM_FORMAT_RGB888, 56 + DRM_FORMAT_RGB565, 57 + }, 58 + .expected_fourccs_size = 3, 59 + }, 60 + { 61 + .name = "convert alpha formats", 62 + .native_fourccs = { 63 + DRM_FORMAT_ARGB1555, 64 + DRM_FORMAT_ABGR1555, 65 + DRM_FORMAT_RGBA5551, 66 + DRM_FORMAT_BGRA5551, 67 + DRM_FORMAT_ARGB8888, 68 + DRM_FORMAT_ABGR8888, 69 + DRM_FORMAT_RGBA8888, 70 + DRM_FORMAT_BGRA8888, 71 + DRM_FORMAT_ARGB2101010, 72 + DRM_FORMAT_ABGR2101010, 73 + DRM_FORMAT_RGBA1010102, 74 + DRM_FORMAT_BGRA1010102, 75 + }, 76 + .native_fourccs_size = 12, 77 + .expected = { 78 + DRM_FORMAT_XRGB1555, 79 + DRM_FORMAT_XBGR1555, 80 + DRM_FORMAT_RGBX5551, 81 + DRM_FORMAT_BGRX5551, 82 + DRM_FORMAT_XRGB8888, 83 + DRM_FORMAT_XBGR8888, 84 + DRM_FORMAT_RGBX8888, 85 + DRM_FORMAT_BGRX8888, 86 + DRM_FORMAT_XRGB2101010, 87 + DRM_FORMAT_XBGR2101010, 88 + DRM_FORMAT_RGBX1010102, 89 + DRM_FORMAT_BGRX1010102, 90 + }, 91 + .expected_fourccs_size = 12, 92 + }, 93 + { 94 + .name = "random formats", 95 + .native_fourccs = { 96 + DRM_FORMAT_Y212, 97 + DRM_FORMAT_ARGB1555, 98 + DRM_FORMAT_ABGR16161616F, 99 + DRM_FORMAT_C8, 100 + DRM_FORMAT_BGR888, 101 + DRM_FORMAT_XRGB1555, 102 + DRM_FORMAT_RGBA5551, 103 + DRM_FORMAT_BGR565_A8, 104 + DRM_FORMAT_R10, 105 + DRM_FORMAT_XYUV8888, 106 + }, 107 + .native_fourccs_size = 10, 108 + .expected = { 109 + DRM_FORMAT_Y212, 110 + DRM_FORMAT_XRGB1555, 111 + DRM_FORMAT_ABGR16161616F, 112 + DRM_FORMAT_C8, 113 + DRM_FORMAT_BGR888, 114 + DRM_FORMAT_RGBX5551, 115 + DRM_FORMAT_BGR565_A8, 116 + DRM_FORMAT_R10, 117 + DRM_FORMAT_XYUV8888, 118 + DRM_FORMAT_XRGB8888, 119 + }, 120 + .expected_fourccs_size = 10, 121 + }, 122 + }; 123 + 124 + static void sysfb_build_fourcc_list_case_desc(struct sysfb_build_fourcc_list_case *t, char *desc) 125 + { 126 + strscpy(desc, t->name, KUNIT_PARAM_DESC_SIZE); 127 + } 128 + 129 + KUNIT_ARRAY_PARAM(sysfb_build_fourcc_list, sysfb_build_fourcc_list_cases, 130 + sysfb_build_fourcc_list_case_desc); 131 + 132 + static void drm_test_sysfb_build_fourcc_list(struct kunit *test) 133 + { 134 + const struct sysfb_build_fourcc_list_case *params = test->param_value; 135 + u32 fourccs_out[TEST_BUF_SIZE] = {0}; 136 + size_t nfourccs_out; 137 + struct drm_device *drm; 138 + struct device *dev; 139 + 140 + dev = drm_kunit_helper_alloc_device(test); 141 + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev); 142 + 143 + drm = __drm_kunit_helper_alloc_drm_device(test, dev, sizeof(*drm), 0, DRIVER_MODESET); 144 + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, drm); 145 + 146 + nfourccs_out = drm_sysfb_build_fourcc_list(drm, params->native_fourccs, 147 + params->native_fourccs_size, 148 + fourccs_out, TEST_BUF_SIZE); 149 + 150 + KUNIT_EXPECT_EQ(test, nfourccs_out, params->expected_fourccs_size); 151 + KUNIT_EXPECT_MEMEQ(test, fourccs_out, params->expected, TEST_BUF_SIZE); 152 + } 153 + 154 + static struct kunit_case drm_sysfb_modeset_test_cases[] = { 155 + KUNIT_CASE_PARAM(drm_test_sysfb_build_fourcc_list, sysfb_build_fourcc_list_gen_params), 156 + {} 157 + }; 158 + 159 + static struct kunit_suite drm_sysfb_modeset_test_suite = { 160 + .name = "drm_sysfb_modeset_test", 161 + .test_cases = drm_sysfb_modeset_test_cases, 162 + }; 163 + 164 + kunit_test_suite(drm_sysfb_modeset_test_suite); 165 + 166 + MODULE_DESCRIPTION("KUnit tests for the drm_sysfb_modeset APIs"); 167 + MODULE_LICENSE("GPL"); 168 + MODULE_AUTHOR("José Expósito <jose.exposito89@gmail.com>");
+3
drivers/gpu/drm/ttm/tests/ttm_kunit_helpers.c
··· 2 2 /* 3 3 * Copyright © 2023 Intel Corporation 4 4 */ 5 + 6 + #include <linux/export.h> 7 + 5 8 #include <drm/ttm/ttm_tt.h> 6 9 7 10 #include "ttm_kunit_helpers.h"
+3
drivers/gpu/drm/ttm/tests/ttm_mock_manager.c
··· 2 2 /* 3 3 * Copyright © 2023 Intel Corporation 4 4 */ 5 + 6 + #include <linux/export.h> 7 + 5 8 #include <drm/ttm/ttm_resource.h> 6 9 #include <drm/ttm/ttm_device.h> 7 10 #include <drm/ttm/ttm_placement.h>
+1
drivers/gpu/drm/ttm/ttm_agp_backend.c
··· 36 36 #include <drm/ttm/ttm_tt.h> 37 37 #include <drm/ttm/ttm_resource.h> 38 38 #include <linux/agp_backend.h> 39 + #include <linux/export.h> 39 40 #include <linux/module.h> 40 41 #include <linux/slab.h> 41 42 #include <linux/io.h>
+2
drivers/gpu/drm/ttm/ttm_backup.c
··· 4 4 */ 5 5 6 6 #include <drm/ttm/ttm_backup.h> 7 + 8 + #include <linux/export.h> 7 9 #include <linux/page-flags.h> 8 10 #include <linux/swap.h> 9 11
+1
drivers/gpu/drm/ttm/ttm_bo.c
··· 35 35 #include <drm/ttm/ttm_placement.h> 36 36 #include <drm/ttm/ttm_tt.h> 37 37 38 + #include <linux/export.h> 38 39 #include <linux/jiffies.h> 39 40 #include <linux/slab.h> 40 41 #include <linux/sched.h>
+2
drivers/gpu/drm/ttm/ttm_bo_util.c
··· 28 28 /* 29 29 * Authors: Thomas Hellstrom <thellstrom-at-vmware-dot-com> 30 30 */ 31 + 32 + #include <linux/export.h> 31 33 #include <linux/swap.h> 32 34 #include <linux/vmalloc.h> 33 35
+2
drivers/gpu/drm/ttm/ttm_bo_vm.c
··· 31 31 32 32 #define pr_fmt(fmt) "[TTM] " fmt 33 33 34 + #include <linux/export.h> 35 + 34 36 #include <drm/ttm/ttm_bo.h> 35 37 #include <drm/ttm/ttm_placement.h> 36 38 #include <drm/ttm/ttm_tt.h>
+1
drivers/gpu/drm/ttm/ttm_device.c
··· 28 28 #define pr_fmt(fmt) "[TTM DEVICE] " fmt 29 29 30 30 #include <linux/debugfs.h> 31 + #include <linux/export.h> 31 32 #include <linux/mm.h> 32 33 33 34 #include <drm/ttm/ttm_bo.h>
+2
drivers/gpu/drm/ttm/ttm_execbuf_util.c
··· 26 26 * 27 27 **************************************************************************/ 28 28 29 + #include <linux/export.h> 30 + 29 31 #include <drm/ttm/ttm_execbuf_util.h> 30 32 #include <drm/ttm/ttm_bo.h> 31 33
+1
drivers/gpu/drm/ttm/ttm_pool.c
··· 31 31 * cause they are rather slow compared to alloc_pages+map. 32 32 */ 33 33 34 + #include <linux/export.h> 34 35 #include <linux/module.h> 35 36 #include <linux/dma-mapping.h> 36 37 #include <linux/debugfs.h>
+2
drivers/gpu/drm/ttm/ttm_range_manager.c
··· 34 34 #include <drm/ttm/ttm_range_manager.h> 35 35 #include <drm/ttm/ttm_bo.h> 36 36 #include <drm/drm_mm.h> 37 + 38 + #include <linux/export.h> 37 39 #include <linux/slab.h> 38 40 #include <linux/spinlock.h> 39 41
+1
drivers/gpu/drm/ttm/ttm_resource.c
··· 23 23 */ 24 24 25 25 #include <linux/debugfs.h> 26 + #include <linux/export.h> 26 27 #include <linux/io-mapping.h> 27 28 #include <linux/iosys-map.h> 28 29 #include <linux/scatterlist.h>
+1
drivers/gpu/drm/ttm/ttm_tt.c
··· 33 33 34 34 #include <linux/cc_platform.h> 35 35 #include <linux/debugfs.h> 36 + #include <linux/export.h> 36 37 #include <linux/file.h> 37 38 #include <linux/module.h> 38 39 #include <linux/sched.h>
+5 -2
drivers/gpu/drm/vkms/tests/Makefile
··· 1 1 # SPDX-License-Identifier: GPL-2.0-only 2 2 3 - obj-$(CONFIG_DRM_VKMS_KUNIT_TEST) += vkms_config_test.o 4 - obj-$(CONFIG_DRM_VKMS_KUNIT_TESTS) += vkms_format_test.o 3 + vkms-kunit-tests-y := \ 4 + vkms_config_test.o \ 5 + vkms_format_test.o 6 + 7 + obj-$(CONFIG_DRM_VKMS_KUNIT_TEST) += vkms-kunit-tests.o
+1 -1
drivers/gpu/drm/vmwgfx/vmwgfx_cmd.c
··· 544 544 cmd_fence = (struct svga_fifo_cmd_fence *) fm; 545 545 cmd_fence->fence = *seqno; 546 546 vmw_cmd_commit_flush(dev_priv, bytes); 547 - vmw_update_seqno(dev_priv); 547 + vmw_fences_update(dev_priv->fman); 548 548 549 549 out_err: 550 550 return ret;
+5 -3
drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
··· 440 440 vmw_write(dev_priv, SVGA_REG_CONFIG_DONE, 1); 441 441 } 442 442 443 - dev_priv->last_read_seqno = vmw_fence_read(dev_priv); 444 - atomic_set(&dev_priv->marker_seq, dev_priv->last_read_seqno); 443 + u32 seqno = vmw_fence_read(dev_priv); 444 + 445 + atomic_set(&dev_priv->last_read_seqno, seqno); 446 + atomic_set(&dev_priv->marker_seq, seqno); 445 447 return 0; 446 448 } 447 449 ··· 456 454 while (vmw_read(vmw, SVGA_REG_BUSY) != 0) 457 455 ; 458 456 459 - vmw->last_read_seqno = vmw_fence_read(vmw); 457 + atomic_set(&vmw->last_read_seqno, vmw_fence_read(vmw)); 460 458 461 459 vmw_write(vmw, SVGA_REG_CONFIG_DONE, 462 460 vmw->config_done_state);
+9 -10
drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
··· 522 522 int cmdbuf_waiters; /* Protected by waiter_lock */ 523 523 int error_waiters; /* Protected by waiter_lock */ 524 524 int fifo_queue_waiters; /* Protected by waiter_lock */ 525 - uint32_t last_read_seqno; 525 + atomic_t last_read_seqno; 526 526 struct vmw_fence_manager *fman; 527 527 uint32_t irq_mask; /* Updates protected by waiter_lock */ 528 528 ··· 1006 1006 uint32_t seqno, 1007 1007 bool interruptible, 1008 1008 unsigned long timeout); 1009 - extern void vmw_update_seqno(struct vmw_private *dev_priv); 1010 - extern void vmw_seqno_waiter_add(struct vmw_private *dev_priv); 1011 - extern void vmw_seqno_waiter_remove(struct vmw_private *dev_priv); 1012 - extern void vmw_goal_waiter_add(struct vmw_private *dev_priv); 1013 - extern void vmw_goal_waiter_remove(struct vmw_private *dev_priv); 1014 - extern void vmw_generic_waiter_add(struct vmw_private *dev_priv, u32 flag, 1015 - int *waiter_count); 1016 - extern void vmw_generic_waiter_remove(struct vmw_private *dev_priv, 1017 - u32 flag, int *waiter_count); 1009 + bool vmw_seqno_waiter_add(struct vmw_private *dev_priv); 1010 + bool vmw_seqno_waiter_remove(struct vmw_private *dev_priv); 1011 + bool vmw_goal_waiter_add(struct vmw_private *dev_priv); 1012 + bool vmw_goal_waiter_remove(struct vmw_private *dev_priv); 1013 + bool vmw_generic_waiter_add(struct vmw_private *dev_priv, u32 flag, 1014 + int *waiter_count); 1015 + bool vmw_generic_waiter_remove(struct vmw_private *dev_priv, 1016 + u32 flag, int *waiter_count); 1018 1017 1019 1018 /** 1020 1019 * Kernel modesetting - vmwgfx_kms.c
+1 -28
drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
··· 3878 3878 3879 3879 fence_rep.handle = fence_handle; 3880 3880 fence_rep.seqno = fence->base.seqno; 3881 - vmw_update_seqno(dev_priv); 3882 - fence_rep.passed_seqno = dev_priv->last_read_seqno; 3881 + fence_rep.passed_seqno = vmw_fences_update(dev_priv->fman); 3883 3882 } 3884 3883 3885 3884 /* ··· 4067 4068 return 0; 4068 4069 } 4069 4070 4070 - /* 4071 - * DMA fence callback to remove a seqno_waiter 4072 - */ 4073 - struct seqno_waiter_rm_context { 4074 - struct dma_fence_cb base; 4075 - struct vmw_private *dev_priv; 4076 - }; 4077 - 4078 - static void seqno_waiter_rm_cb(struct dma_fence *f, struct dma_fence_cb *cb) 4079 - { 4080 - struct seqno_waiter_rm_context *ctx = 4081 - container_of(cb, struct seqno_waiter_rm_context, base); 4082 - 4083 - vmw_seqno_waiter_remove(ctx->dev_priv); 4084 - kfree(ctx); 4085 - } 4086 - 4087 4071 int vmw_execbuf_process(struct drm_file *file_priv, 4088 4072 struct vmw_private *dev_priv, 4089 4073 void __user *user_commands, void *kernel_commands, ··· 4247 4265 } else { 4248 4266 /* Link the fence with the FD created earlier */ 4249 4267 fd_install(out_fence_fd, sync_file->file); 4250 - struct seqno_waiter_rm_context *ctx = 4251 - kmalloc(sizeof(*ctx), GFP_KERNEL); 4252 - ctx->dev_priv = dev_priv; 4253 - vmw_seqno_waiter_add(dev_priv); 4254 - if (dma_fence_add_callback(&fence->base, &ctx->base, 4255 - seqno_waiter_rm_cb) < 0) { 4256 - vmw_seqno_waiter_remove(dev_priv); 4257 - kfree(ctx); 4258 - } 4259 4268 } 4260 4269 } 4261 4270
+71 -439
drivers/gpu/drm/vmwgfx/vmwgfx_fence.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 OR MIT 2 2 /************************************************************************** 3 3 * 4 - * Copyright 2011-2023 VMware, Inc., Palo Alto, CA., USA 5 - * 6 - * Permission is hereby granted, free of charge, to any person obtaining a 7 - * copy of this software and associated documentation files (the 8 - * "Software"), to deal in the Software without restriction, including 9 - * without limitation the rights to use, copy, modify, merge, publish, 10 - * distribute, sub license, and/or sell copies of the Software, and to 11 - * permit persons to whom the Software is furnished to do so, subject to 12 - * the following conditions: 13 - * 14 - * The above copyright notice and this permission notice (including the 15 - * next paragraph) shall be included in all copies or substantial portions 16 - * of the Software. 17 - * 18 - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 21 - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, 22 - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 23 - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 24 - * USE OR OTHER DEALINGS IN THE SOFTWARE. 4 + * Copyright (c) 2009-2025 Broadcom. All Rights Reserved. The term 5 + * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. 25 6 * 26 7 **************************************************************************/ 27 - 28 - #include <linux/sched/signal.h> 29 8 30 9 #include "vmwgfx_drv.h" 31 10 ··· 14 35 struct vmw_private *dev_priv; 15 36 spinlock_t lock; 16 37 struct list_head fence_list; 17 - struct work_struct work; 18 38 bool fifo_down; 19 - struct list_head cleanup_list; 20 - uint32_t pending_actions[VMW_ACTION_MAX]; 21 - struct mutex goal_irq_mutex; 22 - bool goal_irq_on; /* Protected by @goal_irq_mutex */ 23 - bool seqno_valid; /* Protected by @lock, and may not be set to true 24 - without the @goal_irq_mutex held. */ 25 39 u64 ctx; 26 40 }; 27 41 ··· 24 52 }; 25 53 26 54 /** 27 - * struct vmw_event_fence_action - fence action that delivers a drm event. 55 + * struct vmw_event_fence_action - fence callback that delivers a DRM event. 28 56 * 29 - * @action: A struct vmw_fence_action to hook up to a fence. 57 + * @base: For use with dma_fence_add_callback(...) 30 58 * @event: A pointer to the pending event. 31 - * @fence: A referenced pointer to the fence to keep it alive while @action 32 - * hangs on it. 33 59 * @dev: Pointer to a struct drm_device so we can access the event stuff. 34 60 * @tv_sec: If non-null, the variable pointed to will be assigned 35 61 * current time tv_sec val when the fence signals. ··· 35 65 * be assigned the current time tv_usec val when the fence signals. 36 66 */ 37 67 struct vmw_event_fence_action { 38 - struct vmw_fence_action action; 68 + struct dma_fence_cb base; 39 69 40 70 struct drm_pending_event *event; 41 - struct vmw_fence_obj *fence; 42 71 struct drm_device *dev; 43 72 44 73 uint32_t *tv_sec; ··· 50 81 return container_of(fence->base.lock, struct vmw_fence_manager, lock); 51 82 } 52 83 53 - static u32 vmw_fence_goal_read(struct vmw_private *vmw) 54 - { 55 - if ((vmw->capabilities2 & SVGA_CAP2_EXTRA_REGS) != 0) 56 - return vmw_read(vmw, SVGA_REG_FENCE_GOAL); 57 - else 58 - return vmw_fifo_mem_read(vmw, SVGA_FIFO_FENCE_GOAL); 59 - } 60 - 61 - static void vmw_fence_goal_write(struct vmw_private *vmw, u32 value) 62 - { 63 - if ((vmw->capabilities2 & SVGA_CAP2_EXTRA_REGS) != 0) 64 - vmw_write(vmw, SVGA_REG_FENCE_GOAL, value); 65 - else 66 - vmw_fifo_mem_write(vmw, SVGA_FIFO_FENCE_GOAL, value); 67 - } 68 - 69 - /* 70 - * Note on fencing subsystem usage of irqs: 71 - * Typically the vmw_fences_update function is called 72 - * 73 - * a) When a new fence seqno has been submitted by the fifo code. 74 - * b) On-demand when we have waiters. Sleeping waiters will switch on the 75 - * ANY_FENCE irq and call vmw_fences_update function each time an ANY_FENCE 76 - * irq is received. When the last fence waiter is gone, that IRQ is masked 77 - * away. 78 - * 79 - * In situations where there are no waiters and we don't submit any new fences, 80 - * fence objects may not be signaled. This is perfectly OK, since there are 81 - * no consumers of the signaled data, but that is NOT ok when there are fence 82 - * actions attached to a fence. The fencing subsystem then makes use of the 83 - * FENCE_GOAL irq and sets the fence goal seqno to that of the next fence 84 - * which has an action attached, and each time vmw_fences_update is called, 85 - * the subsystem makes sure the fence goal seqno is updated. 86 - * 87 - * The fence goal seqno irq is on as long as there are unsignaled fence 88 - * objects with actions attached to them. 89 - */ 90 - 91 84 static void vmw_fence_obj_destroy(struct dma_fence *f) 92 85 { 93 86 struct vmw_fence_obj *fence = ··· 57 126 struct vmw_fence_manager *fman = fman_from_fence(fence); 58 127 59 128 if (!list_empty(&fence->head)) { 129 + /* The fence manager still has an implicit reference to this 130 + * fence via the fence list if head is set. Because the lock is 131 + * required to be held when the fence manager updates the fence 132 + * list either the fence will have been removed after we get 133 + * the lock below or we can safely remove it and the fence 134 + * manager will never see it. This implies the fence is being 135 + * deleted without being signaled which is dubious but valid 136 + * if there are no callbacks. The dma_fence code that calls 137 + * this hook will warn about deleted unsignaled with callbacks 138 + * so no need to warn again here. 139 + */ 60 140 spin_lock(&fman->lock); 61 141 list_del_init(&fence->head); 142 + if (fence->waiter_added) 143 + vmw_seqno_waiter_remove(fman->dev_priv); 62 144 spin_unlock(&fman->lock); 63 145 } 64 146 fence->destroy(fence); ··· 87 143 return "svga"; 88 144 } 89 145 146 + /* When we toggle signaling for the SVGA device there is a race period from 147 + * the time we first read the fence seqno to the time we enable interrupts. 148 + * If we miss the interrupt for a fence during this period its likely the driver 149 + * will stall. As a result we need to re-read the seqno after interrupts are 150 + * enabled. If interrupts were already enabled we just increment the number of 151 + * seqno waiters. 152 + */ 90 153 static bool vmw_fence_enable_signaling(struct dma_fence *f) 91 154 { 155 + u32 seqno; 92 156 struct vmw_fence_obj *fence = 93 157 container_of(f, struct vmw_fence_obj, base); 94 158 95 159 struct vmw_fence_manager *fman = fman_from_fence(fence); 96 160 struct vmw_private *dev_priv = fman->dev_priv; 97 - 98 - u32 seqno = vmw_fence_read(dev_priv); 99 - if (seqno - fence->base.seqno < VMW_FENCE_WRAP) 161 + check_for_race: 162 + seqno = vmw_fence_read(dev_priv); 163 + if (seqno - fence->base.seqno < VMW_FENCE_WRAP) { 164 + if (fence->waiter_added) { 165 + vmw_seqno_waiter_remove(dev_priv); 166 + fence->waiter_added = false; 167 + } 100 168 return false; 101 - 169 + } else if (!fence->waiter_added) { 170 + fence->waiter_added = true; 171 + if (vmw_seqno_waiter_add(dev_priv)) 172 + goto check_for_race; 173 + } 102 174 return true; 103 175 } 104 176 105 - struct vmwgfx_wait_cb { 106 - struct dma_fence_cb base; 107 - struct task_struct *task; 108 - }; 109 - 110 - static void 111 - vmwgfx_wait_cb(struct dma_fence *fence, struct dma_fence_cb *cb) 112 - { 113 - struct vmwgfx_wait_cb *wait = 114 - container_of(cb, struct vmwgfx_wait_cb, base); 115 - 116 - wake_up_process(wait->task); 117 - } 118 - 119 - static void __vmw_fences_update(struct vmw_fence_manager *fman); 120 - 121 - static long vmw_fence_wait(struct dma_fence *f, bool intr, signed long timeout) 122 - { 123 - struct vmw_fence_obj *fence = 124 - container_of(f, struct vmw_fence_obj, base); 125 - 126 - struct vmw_fence_manager *fman = fman_from_fence(fence); 127 - struct vmw_private *dev_priv = fman->dev_priv; 128 - struct vmwgfx_wait_cb cb; 129 - long ret = timeout; 130 - 131 - if (likely(vmw_fence_obj_signaled(fence))) 132 - return timeout; 133 - 134 - vmw_seqno_waiter_add(dev_priv); 135 - 136 - spin_lock(f->lock); 137 - 138 - if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &f->flags)) 139 - goto out; 140 - 141 - if (intr && signal_pending(current)) { 142 - ret = -ERESTARTSYS; 143 - goto out; 144 - } 145 - 146 - cb.base.func = vmwgfx_wait_cb; 147 - cb.task = current; 148 - list_add(&cb.base.node, &f->cb_list); 149 - 150 - for (;;) { 151 - __vmw_fences_update(fman); 152 - 153 - /* 154 - * We can use the barrier free __set_current_state() since 155 - * DMA_FENCE_FLAG_SIGNALED_BIT + wakeup is protected by the 156 - * fence spinlock. 157 - */ 158 - if (intr) 159 - __set_current_state(TASK_INTERRUPTIBLE); 160 - else 161 - __set_current_state(TASK_UNINTERRUPTIBLE); 162 - 163 - if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &f->flags)) { 164 - if (ret == 0 && timeout > 0) 165 - ret = 1; 166 - break; 167 - } 168 - 169 - if (intr && signal_pending(current)) { 170 - ret = -ERESTARTSYS; 171 - break; 172 - } 173 - 174 - if (ret == 0) 175 - break; 176 - 177 - spin_unlock(f->lock); 178 - 179 - ret = schedule_timeout(ret); 180 - 181 - spin_lock(f->lock); 182 - } 183 - __set_current_state(TASK_RUNNING); 184 - if (!list_empty(&cb.base.node)) 185 - list_del(&cb.base.node); 186 - 187 - out: 188 - spin_unlock(f->lock); 189 - 190 - vmw_seqno_waiter_remove(dev_priv); 191 - 192 - return ret; 193 - } 177 + static u32 __vmw_fences_update(struct vmw_fence_manager *fman); 194 178 195 179 static const struct dma_fence_ops vmw_fence_ops = { 196 180 .get_driver_name = vmw_fence_get_driver_name, 197 181 .get_timeline_name = vmw_fence_get_timeline_name, 198 182 .enable_signaling = vmw_fence_enable_signaling, 199 - .wait = vmw_fence_wait, 200 183 .release = vmw_fence_obj_destroy, 201 184 }; 202 - 203 - /* 204 - * Execute signal actions on fences recently signaled. 205 - * This is done from a workqueue so we don't have to execute 206 - * signal actions from atomic context. 207 - */ 208 - 209 - static void vmw_fence_work_func(struct work_struct *work) 210 - { 211 - struct vmw_fence_manager *fman = 212 - container_of(work, struct vmw_fence_manager, work); 213 - struct list_head list; 214 - struct vmw_fence_action *action, *next_action; 215 - bool seqno_valid; 216 - 217 - do { 218 - INIT_LIST_HEAD(&list); 219 - mutex_lock(&fman->goal_irq_mutex); 220 - 221 - spin_lock(&fman->lock); 222 - list_splice_init(&fman->cleanup_list, &list); 223 - seqno_valid = fman->seqno_valid; 224 - spin_unlock(&fman->lock); 225 - 226 - if (!seqno_valid && fman->goal_irq_on) { 227 - fman->goal_irq_on = false; 228 - vmw_goal_waiter_remove(fman->dev_priv); 229 - } 230 - mutex_unlock(&fman->goal_irq_mutex); 231 - 232 - if (list_empty(&list)) 233 - return; 234 - 235 - /* 236 - * At this point, only we should be able to manipulate the 237 - * list heads of the actions we have on the private list. 238 - * hence fman::lock not held. 239 - */ 240 - 241 - list_for_each_entry_safe(action, next_action, &list, head) { 242 - list_del_init(&action->head); 243 - if (action->cleanup) 244 - action->cleanup(action); 245 - } 246 - } while (1); 247 - } 248 185 249 186 struct vmw_fence_manager *vmw_fence_manager_init(struct vmw_private *dev_priv) 250 187 { ··· 137 312 fman->dev_priv = dev_priv; 138 313 spin_lock_init(&fman->lock); 139 314 INIT_LIST_HEAD(&fman->fence_list); 140 - INIT_LIST_HEAD(&fman->cleanup_list); 141 - INIT_WORK(&fman->work, &vmw_fence_work_func); 142 315 fman->fifo_down = true; 143 - mutex_init(&fman->goal_irq_mutex); 144 316 fman->ctx = dma_fence_context_alloc(1); 145 317 146 318 return fman; ··· 147 325 { 148 326 bool lists_empty; 149 327 150 - (void) cancel_work_sync(&fman->work); 151 - 152 328 spin_lock(&fman->lock); 153 - lists_empty = list_empty(&fman->fence_list) && 154 - list_empty(&fman->cleanup_list); 329 + lists_empty = list_empty(&fman->fence_list); 155 330 spin_unlock(&fman->lock); 156 331 157 332 BUG_ON(!lists_empty); ··· 163 344 164 345 dma_fence_init(&fence->base, &vmw_fence_ops, &fman->lock, 165 346 fman->ctx, seqno); 166 - INIT_LIST_HEAD(&fence->seq_passed_actions); 167 347 fence->destroy = destroy; 168 348 169 349 spin_lock(&fman->lock); ··· 170 352 ret = -EBUSY; 171 353 goto out_unlock; 172 354 } 355 + /* This creates an implicit reference to the fence from the fence 356 + * manager. It will be dropped when the fence is signaled which is 357 + * expected to happen before deletion. The dtor has code to catch 358 + * the rare deletion before signaling case. 359 + */ 173 360 list_add_tail(&fence->head, &fman->fence_list); 174 361 175 362 out_unlock: ··· 183 360 184 361 } 185 362 186 - static void vmw_fences_perform_actions(struct vmw_fence_manager *fman, 187 - struct list_head *list) 188 - { 189 - struct vmw_fence_action *action, *next_action; 190 - 191 - list_for_each_entry_safe(action, next_action, list, head) { 192 - list_del_init(&action->head); 193 - fman->pending_actions[action->type]--; 194 - if (action->seq_passed != NULL) 195 - action->seq_passed(action); 196 - 197 - /* 198 - * Add the cleanup action to the cleanup list so that 199 - * it will be performed by a worker task. 200 - */ 201 - 202 - list_add_tail(&action->head, &fman->cleanup_list); 203 - } 204 - } 205 - 206 - /** 207 - * vmw_fence_goal_new_locked - Figure out a new device fence goal 208 - * seqno if needed. 209 - * 210 - * @fman: Pointer to a fence manager. 211 - * @passed_seqno: The seqno the device currently signals as passed. 212 - * 213 - * This function should be called with the fence manager lock held. 214 - * It is typically called when we have a new passed_seqno, and 215 - * we might need to update the fence goal. It checks to see whether 216 - * the current fence goal has already passed, and, in that case, 217 - * scans through all unsignaled fences to get the next fence object with an 218 - * action attached, and sets the seqno of that fence as a new fence goal. 219 - * 220 - * returns true if the device goal seqno was updated. False otherwise. 221 - */ 222 - static bool vmw_fence_goal_new_locked(struct vmw_fence_manager *fman, 223 - u32 passed_seqno) 224 - { 225 - u32 goal_seqno; 226 - struct vmw_fence_obj *fence, *next_fence; 227 - 228 - if (likely(!fman->seqno_valid)) 229 - return false; 230 - 231 - goal_seqno = vmw_fence_goal_read(fman->dev_priv); 232 - if (likely(passed_seqno - goal_seqno >= VMW_FENCE_WRAP)) 233 - return false; 234 - 235 - fman->seqno_valid = false; 236 - list_for_each_entry_safe(fence, next_fence, &fman->fence_list, head) { 237 - if (!list_empty(&fence->seq_passed_actions)) { 238 - fman->seqno_valid = true; 239 - vmw_fence_goal_write(fman->dev_priv, 240 - fence->base.seqno); 241 - break; 242 - } 243 - } 244 - 245 - return true; 246 - } 247 - 248 - 249 - /** 250 - * vmw_fence_goal_check_locked - Replace the device fence goal seqno if 251 - * needed. 252 - * 253 - * @fence: Pointer to a struct vmw_fence_obj the seqno of which should be 254 - * considered as a device fence goal. 255 - * 256 - * This function should be called with the fence manager lock held. 257 - * It is typically called when an action has been attached to a fence to 258 - * check whether the seqno of that fence should be used for a fence 259 - * goal interrupt. This is typically needed if the current fence goal is 260 - * invalid, or has a higher seqno than that of the current fence object. 261 - * 262 - * returns true if the device goal seqno was updated. False otherwise. 263 - */ 264 - static bool vmw_fence_goal_check_locked(struct vmw_fence_obj *fence) 265 - { 266 - struct vmw_fence_manager *fman = fman_from_fence(fence); 267 - u32 goal_seqno; 268 - 269 - if (dma_fence_is_signaled_locked(&fence->base)) 270 - return false; 271 - 272 - goal_seqno = vmw_fence_goal_read(fman->dev_priv); 273 - if (likely(fman->seqno_valid && 274 - goal_seqno - fence->base.seqno < VMW_FENCE_WRAP)) 275 - return false; 276 - 277 - vmw_fence_goal_write(fman->dev_priv, fence->base.seqno); 278 - fman->seqno_valid = true; 279 - 280 - return true; 281 - } 282 - 283 - static void __vmw_fences_update(struct vmw_fence_manager *fman) 363 + static u32 __vmw_fences_update(struct vmw_fence_manager *fman) 284 364 { 285 365 struct vmw_fence_obj *fence, *next_fence; 286 - struct list_head action_list; 287 - bool needs_rerun; 288 - uint32_t seqno, new_seqno; 366 + const bool cookie = dma_fence_begin_signalling(); 367 + const u32 seqno = vmw_fence_read(fman->dev_priv); 289 368 290 - seqno = vmw_fence_read(fman->dev_priv); 291 - rerun: 292 369 list_for_each_entry_safe(fence, next_fence, &fman->fence_list, head) { 293 370 if (seqno - fence->base.seqno < VMW_FENCE_WRAP) { 294 371 list_del_init(&fence->head); 372 + if (fence->waiter_added) { 373 + vmw_seqno_waiter_remove(fman->dev_priv); 374 + fence->waiter_added = false; 375 + } 295 376 dma_fence_signal_locked(&fence->base); 296 - INIT_LIST_HEAD(&action_list); 297 - list_splice_init(&fence->seq_passed_actions, 298 - &action_list); 299 - vmw_fences_perform_actions(fman, &action_list); 300 377 } else 301 378 break; 302 379 } 303 - 304 - /* 305 - * Rerun if the fence goal seqno was updated, and the 306 - * hardware might have raced with that update, so that 307 - * we missed a fence_goal irq. 308 - */ 309 - 310 - needs_rerun = vmw_fence_goal_new_locked(fman, seqno); 311 - if (unlikely(needs_rerun)) { 312 - new_seqno = vmw_fence_read(fman->dev_priv); 313 - if (new_seqno != seqno) { 314 - seqno = new_seqno; 315 - goto rerun; 316 - } 317 - } 318 - 319 - if (!list_empty(&fman->cleanup_list)) 320 - (void) schedule_work(&fman->work); 380 + dma_fence_end_signalling(cookie); 381 + atomic_set_release(&fman->dev_priv->last_read_seqno, seqno); 382 + return seqno; 321 383 } 322 384 323 - void vmw_fences_update(struct vmw_fence_manager *fman) 385 + u32 vmw_fences_update(struct vmw_fence_manager *fman) 324 386 { 387 + u32 seqno; 325 388 spin_lock(&fman->lock); 326 - __vmw_fences_update(fman); 389 + seqno = __vmw_fences_update(fman); 327 390 spin_unlock(&fman->lock); 391 + return seqno; 328 392 } 329 393 330 394 bool vmw_fence_obj_signaled(struct vmw_fence_obj *fence) ··· 249 539 struct vmw_fence_obj **p_fence) 250 540 { 251 541 struct vmw_fence_obj *fence; 252 - int ret; 542 + int ret; 253 543 254 544 fence = kzalloc(sizeof(*fence), GFP_KERNEL); 255 545 if (unlikely(!fence)) 256 546 return -ENOMEM; 257 547 258 - ret = vmw_fence_obj_init(fman, fence, seqno, 259 - vmw_fence_destroy); 548 + ret = vmw_fence_obj_init(fman, fence, seqno, vmw_fence_destroy); 260 549 if (unlikely(ret != 0)) 261 550 goto out_err_init; 262 551 ··· 347 638 348 639 void vmw_fence_fifo_down(struct vmw_fence_manager *fman) 349 640 { 350 - struct list_head action_list; 351 641 int ret; 352 642 353 643 /* ··· 369 661 if (unlikely(ret != 0)) { 370 662 list_del_init(&fence->head); 371 663 dma_fence_signal(&fence->base); 372 - INIT_LIST_HEAD(&action_list); 373 - list_splice_init(&fence->seq_passed_actions, 374 - &action_list); 375 - vmw_fences_perform_actions(fman, &action_list); 376 664 } 377 665 378 666 BUG_ON(!list_empty(&fence->head)); ··· 482 778 (struct drm_vmw_fence_signaled_arg *) data; 483 779 struct ttm_base_object *base; 484 780 struct vmw_fence_obj *fence; 485 - struct vmw_fence_manager *fman; 486 781 struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile; 487 782 struct vmw_private *dev_priv = vmw_priv(dev); 488 783 ··· 490 787 return PTR_ERR(base); 491 788 492 789 fence = &(container_of(base, struct vmw_user_fence, base)->fence); 493 - fman = fman_from_fence(fence); 494 790 495 791 arg->signaled = vmw_fence_obj_signaled(fence); 496 792 497 793 arg->signaled_flags = arg->flags; 498 - spin_lock(&fman->lock); 499 - arg->passed_seqno = dev_priv->last_read_seqno; 500 - spin_unlock(&fman->lock); 794 + arg->passed_seqno = atomic_read_acquire(&dev_priv->last_read_seqno); 501 795 502 796 ttm_base_object_unref(&base); 503 797 ··· 522 822 * attached has passed. It queues the event on the submitter's event list. 523 823 * This function is always called from atomic context. 524 824 */ 525 - static void vmw_event_fence_action_seq_passed(struct vmw_fence_action *action) 825 + static void vmw_event_fence_action_seq_passed(struct dma_fence *f, 826 + struct dma_fence_cb *cb) 526 827 { 527 828 struct vmw_event_fence_action *eaction = 528 - container_of(action, struct vmw_event_fence_action, action); 829 + container_of(cb, struct vmw_event_fence_action, base); 529 830 struct drm_device *dev = eaction->dev; 530 831 struct drm_pending_event *event = eaction->event; 531 832 ··· 538 837 if (likely(eaction->tv_sec != NULL)) { 539 838 struct timespec64 ts; 540 839 541 - ktime_get_ts64(&ts); 840 + ktime_to_timespec64(f->timestamp); 542 841 /* monotonic time, so no y2038 overflow */ 543 842 *eaction->tv_sec = ts.tv_sec; 544 843 *eaction->tv_usec = ts.tv_nsec / NSEC_PER_USEC; ··· 547 846 drm_send_event_locked(dev, eaction->event); 548 847 eaction->event = NULL; 549 848 spin_unlock_irq(&dev->event_lock); 550 - } 551 - 552 - /** 553 - * vmw_event_fence_action_cleanup 554 - * 555 - * @action: The struct vmw_fence_action embedded in a struct 556 - * vmw_event_fence_action. 557 - * 558 - * This function is the struct vmw_fence_action destructor. It's typically 559 - * called from a workqueue. 560 - */ 561 - static void vmw_event_fence_action_cleanup(struct vmw_fence_action *action) 562 - { 563 - struct vmw_event_fence_action *eaction = 564 - container_of(action, struct vmw_event_fence_action, action); 565 - 566 - vmw_fence_obj_unreference(&eaction->fence); 849 + dma_fence_put(f); 567 850 kfree(eaction); 568 - } 569 - 570 - 571 - /** 572 - * vmw_fence_obj_add_action - Add an action to a fence object. 573 - * 574 - * @fence: The fence object. 575 - * @action: The action to add. 576 - * 577 - * Note that the action callbacks may be executed before this function 578 - * returns. 579 - */ 580 - static void vmw_fence_obj_add_action(struct vmw_fence_obj *fence, 581 - struct vmw_fence_action *action) 582 - { 583 - struct vmw_fence_manager *fman = fman_from_fence(fence); 584 - bool run_update = false; 585 - 586 - mutex_lock(&fman->goal_irq_mutex); 587 - spin_lock(&fman->lock); 588 - 589 - fman->pending_actions[action->type]++; 590 - if (dma_fence_is_signaled_locked(&fence->base)) { 591 - struct list_head action_list; 592 - 593 - INIT_LIST_HEAD(&action_list); 594 - list_add_tail(&action->head, &action_list); 595 - vmw_fences_perform_actions(fman, &action_list); 596 - } else { 597 - list_add_tail(&action->head, &fence->seq_passed_actions); 598 - 599 - /* 600 - * This function may set fman::seqno_valid, so it must 601 - * be run with the goal_irq_mutex held. 602 - */ 603 - run_update = vmw_fence_goal_check_locked(fence); 604 - } 605 - 606 - spin_unlock(&fman->lock); 607 - 608 - if (run_update) { 609 - if (!fman->goal_irq_on) { 610 - fman->goal_irq_on = true; 611 - vmw_goal_waiter_add(fman->dev_priv); 612 - } 613 - vmw_fences_update(fman); 614 - } 615 - mutex_unlock(&fman->goal_irq_mutex); 616 - 617 851 } 618 852 619 853 /** ··· 585 949 return -ENOMEM; 586 950 587 951 eaction->event = event; 588 - 589 - eaction->action.seq_passed = vmw_event_fence_action_seq_passed; 590 - eaction->action.cleanup = vmw_event_fence_action_cleanup; 591 - eaction->action.type = VMW_ACTION_EVENT; 592 - 593 - eaction->fence = vmw_fence_obj_reference(fence); 594 952 eaction->dev = &fman->dev_priv->drm; 595 953 eaction->tv_sec = tv_sec; 596 954 eaction->tv_usec = tv_usec; 597 955 598 - vmw_fence_obj_add_action(fence, &eaction->action); 599 - 956 + vmw_fence_obj_reference(fence); // Dropped in CB 957 + if (dma_fence_add_callback(&fence->base, &eaction->base, 958 + vmw_event_fence_action_seq_passed) < 0) 959 + vmw_event_fence_action_seq_passed(&fence->base, &eaction->base); 600 960 return 0; 601 961 } 602 962
+2 -19
drivers/gpu/drm/vmwgfx/vmwgfx_fence.h
··· 39 39 struct vmw_private; 40 40 struct vmw_fence_manager; 41 41 42 - /** 43 - * 44 - * 45 - */ 46 - enum vmw_action_type { 47 - VMW_ACTION_EVENT = 0, 48 - VMW_ACTION_MAX 49 - }; 50 - 51 - struct vmw_fence_action { 52 - struct list_head head; 53 - enum vmw_action_type type; 54 - void (*seq_passed) (struct vmw_fence_action *action); 55 - void (*cleanup) (struct vmw_fence_action *action); 56 - }; 57 - 58 42 struct vmw_fence_obj { 59 43 struct dma_fence base; 60 - 44 + bool waiter_added; 61 45 struct list_head head; 62 - struct list_head seq_passed_actions; 63 46 void (*destroy)(struct vmw_fence_obj *fence); 64 47 }; 65 48 ··· 69 86 return fence; 70 87 } 71 88 72 - extern void vmw_fences_update(struct vmw_fence_manager *fman); 89 + u32 vmw_fences_update(struct vmw_fence_manager *fman); 73 90 74 91 extern bool vmw_fence_obj_signaled(struct vmw_fence_obj *fence); 75 92
+30 -31
drivers/gpu/drm/vmwgfx/vmwgfx_irq.c
··· 123 123 return (vmw_read(dev_priv, SVGA_REG_BUSY) == 0); 124 124 } 125 125 126 - void vmw_update_seqno(struct vmw_private *dev_priv) 127 - { 128 - uint32_t seqno = vmw_fence_read(dev_priv); 129 - 130 - if (dev_priv->last_read_seqno != seqno) { 131 - dev_priv->last_read_seqno = seqno; 132 - vmw_fences_update(dev_priv->fman); 133 - } 134 - } 135 - 136 126 bool vmw_seqno_passed(struct vmw_private *dev_priv, 137 127 uint32_t seqno) 138 128 { 139 129 bool ret; 130 + u32 last_read_seqno = atomic_read_acquire(&dev_priv->last_read_seqno); 140 131 141 - if (likely(dev_priv->last_read_seqno - seqno < VMW_FENCE_WRAP)) 132 + if (last_read_seqno - seqno < VMW_FENCE_WRAP) 142 133 return true; 143 134 144 - vmw_update_seqno(dev_priv); 145 - if (likely(dev_priv->last_read_seqno - seqno < VMW_FENCE_WRAP)) 135 + last_read_seqno = vmw_fences_update(dev_priv->fman); 136 + if (last_read_seqno - seqno < VMW_FENCE_WRAP) 146 137 return true; 147 138 148 139 if (!vmw_has_fences(dev_priv) && vmw_fifo_idle(dev_priv, seqno)) ··· 230 239 return ret; 231 240 } 232 241 233 - void vmw_generic_waiter_add(struct vmw_private *dev_priv, 242 + bool vmw_generic_waiter_add(struct vmw_private *dev_priv, 234 243 u32 flag, int *waiter_count) 235 244 { 236 - spin_lock_bh(&dev_priv->waiter_lock); 245 + bool hw_programmed = false; 246 + 247 + spin_lock(&dev_priv->waiter_lock); 237 248 if ((*waiter_count)++ == 0) { 238 249 vmw_irq_status_write(dev_priv, flag); 239 250 dev_priv->irq_mask |= flag; 240 251 vmw_write(dev_priv, SVGA_REG_IRQMASK, dev_priv->irq_mask); 252 + hw_programmed = true; 241 253 } 242 - spin_unlock_bh(&dev_priv->waiter_lock); 254 + spin_unlock(&dev_priv->waiter_lock); 255 + return hw_programmed; 243 256 } 244 257 245 - void vmw_generic_waiter_remove(struct vmw_private *dev_priv, 258 + bool vmw_generic_waiter_remove(struct vmw_private *dev_priv, 246 259 u32 flag, int *waiter_count) 247 260 { 248 - spin_lock_bh(&dev_priv->waiter_lock); 261 + bool hw_programmed = false; 262 + 263 + spin_lock(&dev_priv->waiter_lock); 249 264 if (--(*waiter_count) == 0) { 250 265 dev_priv->irq_mask &= ~flag; 251 266 vmw_write(dev_priv, SVGA_REG_IRQMASK, dev_priv->irq_mask); 267 + hw_programmed = true; 252 268 } 253 - spin_unlock_bh(&dev_priv->waiter_lock); 269 + spin_unlock(&dev_priv->waiter_lock); 270 + return hw_programmed; 254 271 } 255 272 256 - void vmw_seqno_waiter_add(struct vmw_private *dev_priv) 273 + bool vmw_seqno_waiter_add(struct vmw_private *dev_priv) 257 274 { 258 - vmw_generic_waiter_add(dev_priv, SVGA_IRQFLAG_ANY_FENCE, 259 - &dev_priv->fence_queue_waiters); 275 + return vmw_generic_waiter_add(dev_priv, SVGA_IRQFLAG_ANY_FENCE, 276 + &dev_priv->fence_queue_waiters); 260 277 } 261 278 262 - void vmw_seqno_waiter_remove(struct vmw_private *dev_priv) 279 + bool vmw_seqno_waiter_remove(struct vmw_private *dev_priv) 263 280 { 264 - vmw_generic_waiter_remove(dev_priv, SVGA_IRQFLAG_ANY_FENCE, 265 - &dev_priv->fence_queue_waiters); 281 + return vmw_generic_waiter_remove(dev_priv, SVGA_IRQFLAG_ANY_FENCE, 282 + &dev_priv->fence_queue_waiters); 266 283 } 267 284 268 - void vmw_goal_waiter_add(struct vmw_private *dev_priv) 285 + bool vmw_goal_waiter_add(struct vmw_private *dev_priv) 269 286 { 270 - vmw_generic_waiter_add(dev_priv, vmw_irqflag_fence_goal(dev_priv), 271 - &dev_priv->goal_queue_waiters); 287 + return vmw_generic_waiter_add(dev_priv, vmw_irqflag_fence_goal(dev_priv), 288 + &dev_priv->goal_queue_waiters); 272 289 } 273 290 274 - void vmw_goal_waiter_remove(struct vmw_private *dev_priv) 291 + bool vmw_goal_waiter_remove(struct vmw_private *dev_priv) 275 292 { 276 - vmw_generic_waiter_remove(dev_priv, vmw_irqflag_fence_goal(dev_priv), 277 - &dev_priv->goal_queue_waiters); 293 + return vmw_generic_waiter_remove(dev_priv, vmw_irqflag_fence_goal(dev_priv), 294 + &dev_priv->goal_queue_waiters); 278 295 } 279 296 280 297 static void vmw_irq_preinstall(struct drm_device *dev)
+1 -1
drivers/gpu/drm/vmwgfx/vmwgfx_shader.c
··· 896 896 .busy_domain = VMW_BO_DOMAIN_SYS, 897 897 .bo_type = ttm_bo_type_device, 898 898 .size = size, 899 - .pin = true, 899 + .pin = false, 900 900 .keep_resv = true, 901 901 }; 902 902
+2 -1
drivers/gpu/drm/xe/xe_device.c
··· 1167 1167 1168 1168 /* Notify userspace of wedged device */ 1169 1169 drm_dev_wedged_event(&xe->drm, 1170 - DRM_WEDGE_RECOVERY_REBIND | DRM_WEDGE_RECOVERY_BUS_RESET); 1170 + DRM_WEDGE_RECOVERY_REBIND | DRM_WEDGE_RECOVERY_BUS_RESET, 1171 + NULL); 1171 1172 } 1172 1173 1173 1174 for_each_gt(gt, xe, id)
+2
drivers/gpu/drm/xe/xe_guc_exec_queue_types.h
··· 20 20 struct xe_guc_exec_queue { 21 21 /** @q: Backpointer to parent xe_exec_queue */ 22 22 struct xe_exec_queue *q; 23 + /** @rcu: For safe freeing of exported dma fences */ 24 + struct rcu_head rcu; 23 25 /** @sched: GPU scheduler for this xe_exec_queue */ 24 26 struct xe_gpu_scheduler sched; 25 27 /** @entity: Scheduler entity for this xe_exec_queue */
+6 -1
drivers/gpu/drm/xe/xe_guc_submit.c
··· 1299 1299 xe_sched_entity_fini(&ge->entity); 1300 1300 xe_sched_fini(&ge->sched); 1301 1301 1302 - kfree(ge); 1302 + /* 1303 + * RCU free due sched being exported via DRM scheduler fences 1304 + * (timeline name). 1305 + */ 1306 + kfree_rcu(ge, rcu); 1303 1307 xe_exec_queue_fini(q); 1304 1308 xe_pm_runtime_put(guc_to_xe(guc)); 1305 1309 } ··· 1486 1482 1487 1483 q->guc = ge; 1488 1484 ge->q = q; 1485 + init_rcu_head(&ge->rcu); 1489 1486 init_waitqueue_head(&ge->suspend_wait); 1490 1487 1491 1488 for (i = 0; i < MAX_STATIC_MSG_TYPE; ++i)
+3
drivers/gpu/drm/xe/xe_hw_fence.c
··· 100 100 spin_unlock_irqrestore(&irq->lock, flags); 101 101 dma_fence_end_signalling(tmp); 102 102 } 103 + 104 + /* Safe release of the irq->lock used in dma_fence_init. */ 105 + synchronize_rcu(); 103 106 } 104 107 105 108 void xe_hw_fence_irq_run(struct xe_hw_fence_irq *irq)
+17 -1
drivers/video/Kconfig
··· 61 61 62 62 endif # HAS_IOMEM 63 63 64 + config FIRMWARE_EDID 65 + bool "Enable firmware EDID" 66 + depends on X86 67 + help 68 + This enables access to the EDID transferred from the firmware. 69 + On x86, this is from the VESA BIOS. DRM display drivers will 70 + be able to export the information to userspace. 71 + 72 + Also enable this if DDC/I2C transfers do not work for your driver 73 + and if you are using nvidiafb, i810fb or savagefb. 74 + 75 + In general, choosing Y for this option is safe. If you 76 + experience extremely long delays while booting before you get 77 + something on your display, try setting this to N. Matrox cards in 78 + combination with certain motherboards and monitors are known to 79 + suffer from this problem. 80 + 64 81 if VT 65 82 source "drivers/video/console/Kconfig" 66 83 endif ··· 86 69 source "drivers/video/logo/Kconfig" 87 70 88 71 endif 89 - 90 72 91 73 endmenu
+1
drivers/video/fbdev/c2p_iplan2.c
··· 8 8 * for more details. 9 9 */ 10 10 11 + #include <linux/export.h> 11 12 #include <linux/module.h> 12 13 #include <linux/string.h> 13 14
+1
drivers/video/fbdev/c2p_planar.c
··· 8 8 * for more details. 9 9 */ 10 10 11 + #include <linux/export.h> 11 12 #include <linux/module.h> 12 13 #include <linux/string.h> 13 14
-15
drivers/video/fbdev/core/Kconfig
··· 10 10 config FB_NOTIFY 11 11 bool 12 12 13 - config FIRMWARE_EDID 14 - bool "Enable firmware EDID" 15 - depends on FB 16 - help 17 - This enables access to the EDID transferred from the firmware. 18 - On the i386, this is from the Video BIOS. Enable this if DDC/I2C 19 - transfers do not work for your driver and if you are using 20 - nvidiafb, i810fb or savagefb. 21 - 22 - In general, choosing Y for this option is safe. If you 23 - experience extremely long delays while booting before you get 24 - something on your display, try setting this to N. Matrox cards in 25 - combination with certain motherboards and monitors are known to 26 - suffer from this problem. 27 - 28 13 config FB_DEVICE 29 14 bool "Provide legacy /dev/fb* device" 30 15 depends on FB_CORE
+2
drivers/video/fbdev/core/cfbcopyarea.c
··· 2 2 /* 3 3 * Copyright (C) 2025 Zsolt Kajtar (soci@c64.rulez.org) 4 4 */ 5 + 6 + #include <linux/export.h> 5 7 #include <linux/module.h> 6 8 #include <linux/fb.h> 7 9 #include <linux/bitrev.h>
+2
drivers/video/fbdev/core/cfbfillrect.c
··· 2 2 /* 3 3 * Copyright (C) 2025 Zsolt Kajtar (soci@c64.rulez.org) 4 4 */ 5 + 6 + #include <linux/export.h> 5 7 #include <linux/module.h> 6 8 #include <linux/fb.h> 7 9 #include <linux/bitrev.h>
+2
drivers/video/fbdev/core/cfbimgblt.c
··· 2 2 /* 3 3 * Copyright (C) 2025 Zsolt Kajtar (soci@c64.rulez.org) 4 4 */ 5 + 6 + #include <linux/export.h> 5 7 #include <linux/module.h> 6 8 #include <linux/fb.h> 7 9 #include <linux/bitrev.h>
+1
drivers/video/fbdev/core/fb_ddc.c
··· 10 10 11 11 #include <linux/delay.h> 12 12 #include <linux/device.h> 13 + #include <linux/export.h> 13 14 #include <linux/module.h> 14 15 #include <linux/fb.h> 15 16 #include <linux/i2c-algo-bit.h>
+1
drivers/video/fbdev/core/fb_defio.c
··· 11 11 #include <linux/module.h> 12 12 #include <linux/kernel.h> 13 13 #include <linux/errno.h> 14 + #include <linux/export.h> 14 15 #include <linux/string.h> 15 16 #include <linux/mm.h> 16 17 #include <linux/vmalloc.h>
+1
drivers/video/fbdev/core/fb_io_fops.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 2 2 3 + #include <linux/export.h> 3 4 #include <linux/fb.h> 4 5 #include <linux/module.h> 5 6 #include <linux/uaccess.h>
+2
drivers/video/fbdev/core/fb_sys_fops.c
··· 9 9 * for more details. 10 10 * 11 11 */ 12 + 13 + #include <linux/export.h> 12 14 #include <linux/fb.h> 13 15 #include <linux/module.h> 14 16 #include <linux/uaccess.h>
+1
drivers/video/fbdev/core/fbcmap.c
··· 11 11 * more details. 12 12 */ 13 13 14 + #include <linux/export.h> 14 15 #include <linux/string.h> 15 16 #include <linux/module.h> 16 17 #include <linux/fb.h>
+1
drivers/video/fbdev/core/fbcon.c
··· 56 56 * more details. 57 57 */ 58 58 59 + #include <linux/export.h> 59 60 #include <linux/module.h> 60 61 #include <linux/types.h> 61 62 #include <linux/fs.h>
+3 -2
drivers/video/fbdev/core/fbmon.c
··· 26 26 * for more details. 27 27 * 28 28 */ 29 + 30 + #include <linux/export.h> 29 31 #include <linux/fb.h> 30 32 #include <linux/module.h> 31 33 #include <linux/pci.h> ··· 1484 1482 -EINVAL : 0; 1485 1483 } 1486 1484 1487 - #if defined(CONFIG_FIRMWARE_EDID) && defined(CONFIG_X86) 1488 - 1489 1485 /* 1490 1486 * We need to ensure that the EDID block is only returned for 1491 1487 * the primary graphics adapter. 1492 1488 */ 1493 1489 1490 + #if defined(CONFIG_FIRMWARE_EDID) 1494 1491 const unsigned char *fb_firmware_edid(struct device *device) 1495 1492 { 1496 1493 struct pci_dev *dev = NULL;
+1
drivers/video/fbdev/core/modedb.c
··· 11 11 * more details. 12 12 */ 13 13 14 + #include <linux/export.h> 14 15 #include <linux/module.h> 15 16 #include <linux/slab.h> 16 17 #include <linux/fb.h>
+1
drivers/video/fbdev/core/svgalib.c
··· 10 10 * Some parts are based on David Boucher's viafb (http://davesdomain.org.uk/viafb/) 11 11 */ 12 12 13 + #include <linux/export.h> 13 14 #include <linux/module.h> 14 15 #include <linux/kernel.h> 15 16 #include <linux/string.h>
+2
drivers/video/fbdev/core/syscopyarea.c
··· 2 2 /* 3 3 * Copyright (C) 2025 Zsolt Kajtar (soci@c64.rulez.org) 4 4 */ 5 + 6 + #include <linux/export.h> 5 7 #include <linux/module.h> 6 8 #include <linux/fb.h> 7 9 #include <linux/bitrev.h>
+2
drivers/video/fbdev/core/sysfillrect.c
··· 2 2 /* 3 3 * Copyright (C) 2025 Zsolt Kajtar (soci@c64.rulez.org) 4 4 */ 5 + 6 + #include <linux/export.h> 5 7 #include <linux/module.h> 6 8 #include <linux/fb.h> 7 9 #include <linux/bitrev.h>
+2
drivers/video/fbdev/core/sysimgblt.c
··· 2 2 /* 3 3 * Copyright (C) 2025 Zsolt Kajtar (soci@c64.rulez.org) 4 4 */ 5 + 6 + #include <linux/export.h> 5 7 #include <linux/module.h> 6 8 #include <linux/fb.h> 7 9 #include <linux/bitrev.h>
-36
drivers/video/fbdev/cyber2000fb.c
··· 1089 1089 cyber2000_grphw(EXT_FUNC_CTL, old, cfb); 1090 1090 } 1091 1091 } 1092 - EXPORT_SYMBOL(cyber2000fb_enable_extregs); 1093 1092 1094 1093 /* 1095 1094 * Disable access to the extended registers ··· 1108 1109 else 1109 1110 cfb->func_use_count -= 1; 1110 1111 } 1111 - EXPORT_SYMBOL(cyber2000fb_disable_extregs); 1112 - 1113 - /* 1114 - * Attach a capture/tv driver to the core CyberX0X0 driver. 1115 - */ 1116 - int cyber2000fb_attach(struct cyberpro_info *info, int idx) 1117 - { 1118 - if (int_cfb_info != NULL) { 1119 - info->dev = int_cfb_info->fb.device; 1120 - #ifdef CONFIG_FB_CYBER2000_I2C 1121 - info->i2c = &int_cfb_info->i2c_adapter; 1122 - #else 1123 - info->i2c = NULL; 1124 - #endif 1125 - info->regs = int_cfb_info->regs; 1126 - info->irq = int_cfb_info->irq; 1127 - info->fb = int_cfb_info->fb.screen_base; 1128 - info->fb_size = int_cfb_info->fb.fix.smem_len; 1129 - info->info = int_cfb_info; 1130 - 1131 - strscpy(info->dev_name, int_cfb_info->fb.fix.id, 1132 - sizeof(info->dev_name)); 1133 - } 1134 - 1135 - return int_cfb_info != NULL; 1136 - } 1137 - EXPORT_SYMBOL(cyber2000fb_attach); 1138 - 1139 - /* 1140 - * Detach a capture/tv driver from the core CyberX0X0 driver. 1141 - */ 1142 - void cyber2000fb_detach(int idx) 1143 - { 1144 - } 1145 - EXPORT_SYMBOL(cyber2000fb_detach); 1146 1112 1147 1113 #ifdef CONFIG_FB_CYBER2000_DDC 1148 1114
-2
drivers/video/fbdev/cyber2000fb.h
··· 488 488 * Note! Writing to the Cyber20x0 registers from an interrupt 489 489 * routine is definitely a bad idea atm. 490 490 */ 491 - int cyber2000fb_attach(struct cyberpro_info *info, int idx); 492 - void cyber2000fb_detach(int idx); 493 491 void cyber2000fb_enable_extregs(struct cfb_info *cfb); 494 492 void cyber2000fb_disable_extregs(struct cfb_info *cfb);
+2 -1
drivers/video/fbdev/macmodes.c
··· 16 16 */ 17 17 18 18 #include <linux/errno.h> 19 + #include <linux/export.h> 19 20 #include <linux/fb.h> 20 21 #include <linux/string.h> 21 22 #include <linux/module.h> ··· 237 236 case CMODE_8: 238 237 var->bits_per_pixel = 8; 239 238 var->red.offset = 0; 240 - var->red.length = 8; 239 + var->red.length = 8; 241 240 var->green.offset = 0; 242 241 var->green.length = 8; 243 242 var->blue.offset = 0;
+14 -12
drivers/video/fbdev/matrox/g450_pll.c
··· 14 14 * 15 15 */ 16 16 17 + #include <linux/export.h> 18 + 17 19 #include "g450_pll.h" 18 20 #include "matroxfb_DAC1064.h" 19 21 ··· 260 258 unsigned int found = 0; 261 259 unsigned int idx; 262 260 unsigned int mnpfound = mnparray[0]; 263 - 261 + 264 262 for (idx = 0; idx < mnpcount; idx++) { 265 263 unsigned int sarray[3]; 266 264 unsigned int *sptr; 267 265 { 268 266 unsigned int mnp; 269 - 267 + 270 268 sptr = sarray; 271 269 mnp = mnparray[idx]; 272 270 if (mnp & 0x38) { ··· 279 277 } 280 278 while (sptr >= sarray) { 281 279 unsigned int mnp = *sptr--; 282 - 280 + 283 281 if (g450_testpll(minfo, mnp - 0x0300, pll) && 284 282 g450_testpll(minfo, mnp + 0x0300, pll) && 285 283 g450_testpll(minfo, mnp - 0x0200, pll) && ··· 312 310 struct matrox_pll_cache *ci, unsigned int mnp_key) 313 311 { 314 312 unsigned int i; 315 - 313 + 316 314 mnp_key &= G450_MNP_FREQBITS; 317 315 for (i = 0; i < ci->valid; i++) { 318 316 if (ci->data[i].mnp_key == mnp_key) { 319 317 unsigned int mnp; 320 - 318 + 321 319 mnp = ci->data[i].mnp_value; 322 320 if (i) { 323 321 memmove(ci->data + 1, ci->data, i * sizeof(*ci->data)); ··· 345 343 { 346 344 u_int8_t tmp, xpwrctrl; 347 345 unsigned long flags; 348 - 346 + 349 347 matroxfb_DAC_lock_irqsave(flags); 350 348 351 349 xpwrctrl = matroxfb_DAC_in(minfo, M1064_XPWRCTRL); ··· 377 375 } 378 376 { 379 377 u_int8_t misc; 380 - 378 + 381 379 misc = mga_inb(M_MISC_REG_READ) & ~0x0C; 382 380 switch (pll) { 383 381 case M_PIXEL_PLL_A: ··· 411 409 u_int8_t tmp; 412 410 unsigned int mnp; 413 411 unsigned long flags; 414 - 412 + 415 413 matroxfb_DAC_lock_irqsave(flags); 416 414 tmp = matroxfb_DAC_in(minfo, M1064_XPWRCTRL); 417 415 if (!(tmp & 2)) { 418 416 matroxfb_DAC_out(minfo, M1064_XPWRCTRL, tmp | 2); 419 417 } 420 - 418 + 421 419 mnp = matroxfb_DAC_in(minfo, M1064_XPIXPLLCM) << 16; 422 420 mnp |= matroxfb_DAC_in(minfo, M1064_XPIXPLLCN) << 8; 423 421 matroxfb_DAC_unlock_irqrestore(flags); ··· 443 441 delta = pll_freq_delta(fout, g450_vco2f(mnp, vco)); 444 442 for (idx = mnpcount; idx > 0; idx--) { 445 443 /* == is important; due to nextpll algorithm we get 446 - sorted equally good frequencies from lower VCO 444 + sorted equally good frequencies from lower VCO 447 445 frequency to higher - with <= lowest wins, while 448 446 with < highest one wins */ 449 447 if (delta <= deltaarray[idx-1]) { ··· 474 472 { 475 473 unsigned long flags; 476 474 unsigned int mnp; 477 - 475 + 478 476 matroxfb_DAC_lock_irqsave(flags); 479 477 mnp = g450_checkcache(minfo, ci, mnparray[0]); 480 478 if (mnp != NO_MORE_MNP) { ··· 497 495 unsigned int pll) 498 496 { 499 497 unsigned int* arr; 500 - 498 + 501 499 arr = kmalloc(sizeof(*arr) * MNP_TABLE_SIZE * 2, GFP_KERNEL); 502 500 if (arr) { 503 501 int r;
+24 -23
drivers/video/fbdev/matrox/matroxfb_DAC1064.c
··· 13 13 * 14 14 */ 15 15 16 + #include <linux/export.h> 16 17 17 18 #include "matroxfb_DAC1064.h" 18 19 #include "matroxfb_misc.h" ··· 44 43 unsigned int p; 45 44 46 45 DBG(__func__) 47 - 46 + 48 47 /* only for devices older than G450 */ 49 48 50 49 fvco = PLL_calcclock(minfo, freq, fmax, in, feed, &p); 51 - 50 + 52 51 p = (1 << p) - 1; 53 52 if (fvco <= 100000) 54 53 ; ··· 170 169 struct matrox_hw_state *hw = &minfo->hw; 171 170 int pixelmnp; 172 171 int videomnp; 173 - 172 + 174 173 c2_ctl = hw->crtc2.ctl & ~0x4007; /* Clear PLL + enable for CRTC2 */ 175 174 c2_ctl |= 0x0001; /* Enable CRTC2 */ 176 175 hw->DACreg[POS1064_XPWRCTRL] &= ~0x02; /* Stop VIDEO PLL */ ··· 193 192 } 194 193 c2_ctl |= 0x0006; /* Use video PLL */ 195 194 hw->DACreg[POS1064_XPWRCTRL] |= 0x02; 196 - 195 + 197 196 outDAC1064(minfo, M1064_XPWRCTRL, hw->DACreg[POS1064_XPWRCTRL]); 198 197 matroxfb_g450_setpll_cond(minfo, videomnp, M_VIDEO_PLL); 199 198 } ··· 201 200 hw->DACreg[POS1064_XPIXCLKCTRL] &= ~M1064_XPIXCLKCTRL_PLL_UP; 202 201 if (pixelmnp >= 0) { 203 202 hw->DACreg[POS1064_XPIXCLKCTRL] |= M1064_XPIXCLKCTRL_PLL_UP; 204 - 203 + 205 204 outDAC1064(minfo, M1064_XPIXCLKCTRL, hw->DACreg[POS1064_XPIXCLKCTRL]); 206 205 matroxfb_g450_setpll_cond(minfo, pixelmnp, M_PIXEL_PLL_C); 207 206 } ··· 304 303 poweroff TMDS. But if we boot with DFP connected, 305 304 TMDS generated clocks are used instead of ALL pixclocks 306 305 available... If someone knows which register 307 - handles it, please reveal this secret to me... */ 306 + handles it, please reveal this secret to me... */ 308 307 hw->DACreg[POS1064_XPWRCTRL] &= ~0x04; /* Poweroff TMDS */ 309 - #endif 308 + #endif 310 309 break; 311 310 } 312 311 /* Now set timming related variables... */ ··· 729 728 } else { 730 729 unsigned long flags; 731 730 unsigned int pwr; 732 - 731 + 733 732 matroxfb_DAC_lock_irqsave(flags); 734 733 pwr = inDAC1064(minfo, M1064_XPWRCTRL) & ~0x02; 735 734 outDAC1064(minfo, M1064_XPWRCTRL, pwr); 736 735 matroxfb_DAC_unlock_irqrestore(flags); 737 736 } 738 737 matroxfb_g450_setclk(minfo, minfo->values.pll.system, M_SYSTEM_PLL); 739 - 738 + 740 739 /* switch clocks to their real PLL source(s) */ 741 740 pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, minfo->hw.MXoptionReg | 4); 742 741 pci_write_config_dword(minfo->pcidev, PCI_OPTION3_REG, minfo->values.reg.opt3); ··· 749 748 /* disable memory refresh */ 750 749 minfo->hw.MXoptionReg &= ~0x001F8000; 751 750 pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, minfo->hw.MXoptionReg); 752 - 751 + 753 752 /* set memory interface parameters */ 754 753 minfo->hw.MXoptionReg &= ~0x00207E00; 755 754 minfo->hw.MXoptionReg |= 0x00207E00 & minfo->values.reg.opt; 756 755 pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, minfo->hw.MXoptionReg); 757 756 pci_write_config_dword(minfo->pcidev, PCI_OPTION2_REG, minfo->values.reg.opt2); 758 - 757 + 759 758 mga_outl(M_CTLWTST, minfo->values.reg.mctlwtst); 760 - 759 + 761 760 /* first set up memory interface with disabled memory interface clocks */ 762 761 pci_write_config_dword(minfo->pcidev, PCI_MEMMISC_REG, minfo->values.reg.memmisc & ~0x80000000U); 763 762 mga_outl(M_MEMRDBK, minfo->values.reg.memrdbk); ··· 766 765 pci_write_config_dword(minfo->pcidev, PCI_MEMMISC_REG, minfo->values.reg.memmisc | 0x80000000U); 767 766 768 767 udelay(200); 769 - 768 + 770 769 if (minfo->values.memory.ddr && (!minfo->values.memory.emrswen || !minfo->values.memory.dll)) { 771 770 mga_outl(M_MEMRDBK, minfo->values.reg.memrdbk & ~0x1000); 772 771 } 773 772 mga_outl(M_MACCESS, minfo->values.reg.maccess | 0x8000); 774 - 773 + 775 774 udelay(200); 776 - 775 + 777 776 minfo->hw.MXoptionReg |= 0x001F8000 & minfo->values.reg.opt; 778 777 pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, minfo->hw.MXoptionReg); 779 - 778 + 780 779 /* value is written to memory chips only if old != new */ 781 780 mga_outl(M_PLNWT, 0); 782 781 mga_outl(M_PLNWT, ~0); 783 - 782 + 784 783 if (minfo->values.reg.mctlwtst != minfo->values.reg.mctlwtst_core) { 785 784 mga_outl(M_CTLWTST, minfo->values.reg.mctlwtst_core); 786 785 } 787 - 786 + 788 787 } 789 788 790 789 static void g450_preinit(struct matrox_fb_info *minfo) ··· 792 791 u_int32_t c2ctl; 793 792 u_int8_t curctl; 794 793 u_int8_t c1ctl; 795 - 794 + 796 795 /* minfo->hw.MXoptionReg = minfo->values.reg.opt; */ 797 796 minfo->hw.MXoptionReg &= 0xC0000100; 798 797 minfo->hw.MXoptionReg |= 0x00000020; ··· 806 805 pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, minfo->hw.MXoptionReg); 807 806 808 807 /* Init system clocks */ 809 - 808 + 810 809 /* stop crtc2 */ 811 810 c2ctl = mga_inl(M_C2CTL); 812 811 mga_outl(M_C2CTL, c2ctl & ~1); ··· 819 818 820 819 g450_mclk_init(minfo); 821 820 g450_memory_init(minfo); 822 - 821 + 823 822 /* set legacy VGA clock sources for DOSEmu or VMware... */ 824 823 matroxfb_g450_setclk(minfo, 25175, M_PIXEL_PLL_A); 825 824 matroxfb_g450_setclk(minfo, 28322, M_PIXEL_PLL_B); 826 825 827 826 /* restore crtc1 */ 828 827 mga_setr(M_SEQ_INDEX, 1, c1ctl); 829 - 828 + 830 829 /* restore cursor */ 831 830 outDAC1064(minfo, M1064_XCURCTRL, curctl); 832 831 833 832 /* restore crtc2 */ 834 833 mga_outl(M_C2CTL, c2ctl); 835 - 834 + 836 835 return; 837 836 } 838 837
+1
drivers/video/fbdev/matrox/matroxfb_Ti3026.c
··· 79 79 * 80 80 */ 81 81 82 + #include <linux/export.h> 82 83 83 84 #include "matroxfb_Ti3026.h" 84 85 #include "matroxfb_misc.h"
+2
drivers/video/fbdev/matrox/matroxfb_accel.c
··· 77 77 * 78 78 */ 79 79 80 + #include <linux/export.h> 81 + 80 82 #include "matroxfb_accel.h" 81 83 #include "matroxfb_DAC1064.h" 82 84 #include "matroxfb_Ti3026.h"
+1
drivers/video/fbdev/matrox/matroxfb_base.c
··· 101 101 */ 102 102 103 103 #include <linux/aperture.h> 104 + #include <linux/export.h> 104 105 #include <linux/version.h> 105 106 106 107 #include "matroxfb_base.h"
+32 -30
drivers/video/fbdev/matrox/matroxfb_g450.c
··· 13 13 * 14 14 */ 15 15 16 + #include <linux/export.h> 17 + 16 18 #include "matroxfb_base.h" 17 19 #include "matroxfb_misc.h" 18 20 #include "matroxfb_DAC1064.h" ··· 34 32 #define WLMAX 0x3FF 35 33 36 34 static const struct mctl g450_controls[] = 37 - { { { V4L2_CID_BRIGHTNESS, V4L2_CTRL_TYPE_INTEGER, 35 + { { { V4L2_CID_BRIGHTNESS, V4L2_CTRL_TYPE_INTEGER, 38 36 "brightness", 39 - 0, WLMAX-BLMIN, 1, 370-BLMIN, 37 + 0, WLMAX-BLMIN, 1, 370-BLMIN, 40 38 0, 41 39 }, offsetof(struct matrox_fb_info, altout.tvo_params.brightness) }, 42 - { { V4L2_CID_CONTRAST, V4L2_CTRL_TYPE_INTEGER, 40 + { { V4L2_CID_CONTRAST, V4L2_CTRL_TYPE_INTEGER, 43 41 "contrast", 44 - 0, 1023, 1, 127, 42 + 0, 1023, 1, 127, 45 43 0, 46 44 }, offsetof(struct matrox_fb_info, altout.tvo_params.contrast) }, 47 45 { { V4L2_CID_SATURATION, V4L2_CTRL_TYPE_INTEGER, 48 46 "saturation", 49 - 0, 255, 1, 165, 47 + 0, 255, 1, 165, 50 48 0, 51 49 }, offsetof(struct matrox_fb_info, altout.tvo_params.saturation) }, 52 50 { { V4L2_CID_HUE, V4L2_CTRL_TYPE_INTEGER, 53 51 "hue", 54 - 0, 255, 1, 0, 52 + 0, 255, 1, 0, 55 53 0, 56 54 }, offsetof(struct matrox_fb_info, altout.tvo_params.hue) }, 57 55 { { MATROXFB_CID_TESTOUT, V4L2_CTRL_TYPE_BOOLEAN, 58 56 "test output", 59 - 0, 1, 1, 0, 57 + 0, 1, 1, 0, 60 58 0, 61 59 }, offsetof(struct matrox_fb_info, altout.tvo_params.testout) }, 62 60 }; ··· 91 89 static void tvo_fill_defaults(struct matrox_fb_info *minfo) 92 90 { 93 91 unsigned int i; 94 - 92 + 95 93 for (i = 0; i < G450CTRLS; i++) { 96 94 *get_ctrl_ptr(minfo, i) = g450_controls[i].desc.default_value; 97 95 } ··· 101 99 { 102 100 unsigned long flags; 103 101 int val; 104 - 102 + 105 103 matroxfb_DAC_lock_irqsave(flags); 106 104 matroxfb_DAC_out(minfo, 0x87, reg); 107 105 val = matroxfb_DAC_in(minfo, 0x88); ··· 143 141 144 142 static int g450_query_ctrl(void* md, struct v4l2_queryctrl *p) { 145 143 int i; 146 - 144 + 147 145 i = get_ctrl_id(p->id); 148 146 if (i >= 0) { 149 147 *p = g450_controls[i].desc; 150 148 return 0; 151 149 } 152 150 if (i == -ENOENT) { 153 - static const struct v4l2_queryctrl disctrl = 151 + static const struct v4l2_queryctrl disctrl = 154 152 { .flags = V4L2_CTRL_FLAG_DISABLED }; 155 - 153 + 156 154 i = p->id; 157 155 *p = disctrl; 158 156 p->id = i; ··· 165 163 static int g450_set_ctrl(void* md, struct v4l2_control *p) { 166 164 int i; 167 165 struct matrox_fb_info *minfo = md; 168 - 166 + 169 167 i = get_ctrl_id(p->id); 170 168 if (i < 0) return -EINVAL; 171 169 ··· 211 209 } 212 210 break; 213 211 } 214 - 212 + 215 213 216 214 return 0; 217 215 } ··· 219 217 static int g450_get_ctrl(void* md, struct v4l2_control *p) { 220 218 int i; 221 219 struct matrox_fb_info *minfo = md; 222 - 220 + 223 221 i = get_ctrl_id(p->id); 224 222 if (i < 0) return -EINVAL; 225 223 p->value = *get_ctrl_ptr(minfo, i); ··· 249 247 unsigned long long piic; 250 248 int mnp; 251 249 int over; 252 - 250 + 253 251 r->regs[0x80] = 0x03; /* | 0x40 for SCART */ 254 252 255 253 hvis = ((mt->HDisplay << 1) + 3) & ~3; 256 - 254 + 257 255 if (hvis >= 2048) { 258 256 hvis = 2044; 259 257 } 260 - 258 + 261 259 piic = 1000000000ULL * hvis; 262 260 do_div(piic, outd->h_vis); 263 261 264 262 dprintk(KERN_DEBUG "Want %u kHz pixclock\n", (unsigned int)piic); 265 - 263 + 266 264 mnp = matroxfb_g450_setclk(minfo, piic, M_VIDEO_PLL); 267 - 265 + 268 266 mt->mnp = mnp; 269 267 mt->pixclock = g450_mnp2f(minfo, mnp); 270 268 ··· 277 275 piic = outd->chromasc; 278 276 do_div(piic, mt->pixclock); 279 277 chromasc = piic; 280 - 278 + 281 279 dprintk(KERN_DEBUG "Chroma is %08X\n", chromasc); 282 280 283 281 r->regs[0] = piic >> 24; ··· 289 287 hsl = (((outd->h_sync + pixclock) / pixclock)) & ~1; 290 288 hlen = hvis + hfp + hsl + hbp; 291 289 over = hlen & 0x0F; 292 - 290 + 293 291 dprintk(KERN_DEBUG "WL: vis=%u, hf=%u, hs=%u, hb=%u, total=%u\n", hvis, hfp, hsl, hbp, hlen); 294 292 295 293 if (over) { ··· 312 310 r->regs[0x2C] = hfp; 313 311 r->regs[0x31] = hvis / 8; 314 312 r->regs[0x32] = hvis & 7; 315 - 313 + 316 314 dprintk(KERN_DEBUG "PG: vis=%04X, hf=%02X, hs=%02X, hb=%02X, total=%04X\n", hvis, hfp, hsl, hbp, hlen); 317 315 318 316 r->regs[0x84] = 1; /* x sync point */ 319 317 r->regs[0x85] = 0; 320 318 hvis = hvis >> 1; 321 319 hlen = hlen >> 1; 322 - 320 + 323 321 dprintk(KERN_DEBUG "hlen=%u hvis=%u\n", hlen, hvis); 324 322 325 323 mt->interlaced = 1; ··· 334 332 unsigned int vtotal; 335 333 unsigned int vsyncend; 336 334 unsigned int vdisplay; 337 - 335 + 338 336 vtotal = mt->VTotal; 339 337 vsyncend = mt->VSyncEnd; 340 338 vdisplay = mt->VDisplay; 341 339 if (vtotal < outd->v_total) { 342 340 unsigned int yovr = outd->v_total - vtotal; 343 - 341 + 344 342 vsyncend += yovr >> 1; 345 343 } else if (vtotal > outd->v_total) { 346 344 vdisplay = outd->v_total - 4; ··· 352 350 r->regs[0x33] = upper - 1; /* upper blanking */ 353 351 r->regs[0x82] = upper; /* y sync point */ 354 352 r->regs[0x83] = upper >> 8; 355 - 353 + 356 354 mt->VDisplay = vdisplay; 357 355 mt->VSyncStart = outd->v_total - 2; 358 356 mt->VSyncEnd = outd->v_total; ··· 511 509 LR(0x80); 512 510 LR(0x82); LR(0x83); 513 511 LR(0x84); LR(0x85); 514 - 512 + 515 513 cve2_set_reg(minfo, 0x3E, 0x01); 516 - 514 + 517 515 for (i = 0; i < 0x3E; i++) { 518 516 LR(i); 519 517 } ··· 560 558 561 559 static int matroxfb_g450_program(void* md) { 562 560 struct matrox_fb_info *minfo = md; 563 - 561 + 564 562 if (minfo->outputs[1].mode != MATROXFB_OUTPUT_MODE_MONITOR) { 565 563 cve2_init_TV(minfo, &minfo->hw.maven); 566 564 }
+11 -10
drivers/video/fbdev/matrox/matroxfb_misc.c
··· 85 85 * 86 86 */ 87 87 88 + #include <linux/export.h> 88 89 89 90 #include "matroxfb_misc.h" 90 91 #include <linux/interrupt.h> ··· 391 390 392 391 static void get_pins(unsigned char __iomem* pins, struct matrox_bios* bd) { 393 392 unsigned int b0 = readb(pins); 394 - 393 + 395 394 if (b0 == 0x2E && readb(pins+1) == 0x41) { 396 395 unsigned int pins_len = readb(pins+2); 397 396 unsigned int i; ··· 427 426 428 427 static void get_bios_version(unsigned char __iomem * vbios, struct matrox_bios* bd) { 429 428 unsigned int pcir_offset; 430 - 429 + 431 430 pcir_offset = readb(vbios + 24) | (readb(vbios + 25) << 8); 432 431 if (pcir_offset >= 26 && pcir_offset < 0xFFE0 && 433 432 readb(vbios + pcir_offset ) == 'P' && ··· 452 451 453 452 static void get_bios_output(unsigned char __iomem* vbios, struct matrox_bios* bd) { 454 453 unsigned char b; 455 - 454 + 456 455 b = readb(vbios + 0x7FF1); 457 456 if (b == 0xFF) { 458 457 b = 0; ··· 462 461 463 462 static void get_bios_tvout(unsigned char __iomem* vbios, struct matrox_bios* bd) { 464 463 unsigned int i; 465 - 464 + 466 465 /* Check for 'IBM .*(V....TVO' string - it means TVO BIOS */ 467 466 bd->output.tvout = 0; 468 467 if (readb(vbios + 0x1D) != 'I' || ··· 473 472 } 474 473 for (i = 0x2D; i < 0x2D + 128; i++) { 475 474 unsigned char b = readb(vbios + i); 476 - 475 + 477 476 if (b == '(' && readb(vbios + i + 1) == 'V') { 478 477 if (readb(vbios + i + 6) == 'T' && 479 478 readb(vbios + i + 7) == 'V' && ··· 489 488 490 489 static void parse_bios(unsigned char __iomem* vbios, struct matrox_bios* bd) { 491 490 unsigned int pins_offset; 492 - 491 + 493 492 if (readb(vbios) != 0x55 || readb(vbios + 1) != 0xAA) { 494 493 return; 495 494 } ··· 649 648 const struct matrox_bios *bd) 650 649 { 651 650 unsigned int mult; 652 - 651 + 653 652 mult = bd->pins[4]?8000:6000; 654 - 653 + 655 654 minfo->limits.pixel.vcomax = (bd->pins[ 38] == 0xFF) ? 600000 : bd->pins[ 38] * mult; 656 655 minfo->limits.system.vcomax = (bd->pins[ 36] == 0xFF) ? minfo->limits.pixel.vcomax : bd->pins[ 36] * mult; 657 656 minfo->limits.video.vcomax = (bd->pins[ 37] == 0xFF) ? minfo->limits.system.vcomax : bd->pins[ 37] * mult; ··· 771 770 u32 biosbase; 772 771 u32 fbbase; 773 772 struct pci_dev *pdev = minfo->pcidev; 774 - 773 + 775 774 memset(&minfo->bios, 0, sizeof(minfo->bios)); 776 775 pci_read_config_dword(pdev, PCI_OPTION_REG, &opt); 777 776 pci_write_config_dword(pdev, PCI_OPTION_REG, opt | PCI_OPTION_ENABLE_ROM); ··· 791 790 } else { 792 791 unsigned int ven = readb(b+0x64+0) | (readb(b+0x64+1) << 8); 793 792 unsigned int dev = readb(b+0x64+2) | (readb(b+0x64+3) << 8); 794 - 793 + 795 794 if (ven != pdev->vendor || dev != pdev->device) { 796 795 printk(KERN_INFO "matroxfb: Legacy BIOS is for %04X:%04X, while this device is %04X:%04X\n", 797 796 ven, dev, pdev->vendor, pdev->device);
-1
drivers/video/fbdev/mb862xx/mb862xx-i2c.c
··· 9 9 #include <linux/i2c.h> 10 10 #include <linux/io.h> 11 11 #include <linux/delay.h> 12 - #include <linux/export.h> 13 12 14 13 #include "mb862xxfb.h" 15 14 #include "mb862xx_reg.h"
+1
drivers/video/fbdev/omap/lcd_dma.c
··· 18 18 * Support functions for the OMAP internal DMA channels. 19 19 */ 20 20 21 + #include <linux/export.h> 21 22 #include <linux/module.h> 22 23 #include <linux/spinlock.h> 23 24 #include <linux/interrupt.h>
+2
drivers/video/fbdev/omap/lcdc.c
··· 5 5 * Copyright (C) 2004 Nokia Corporation 6 6 * Author: Imre Deak <imre.deak@nokia.com> 7 7 */ 8 + 8 9 #include <linux/module.h> 9 10 #include <linux/device.h> 11 + #include <linux/export.h> 10 12 #include <linux/interrupt.h> 11 13 #include <linux/spinlock.h> 12 14 #include <linux/err.h>
+2
drivers/video/fbdev/omap/omapfb_main.c
··· 11 11 * Dirk Behme <dirk.behme@de.bosch.com> - changes for 2.6 kernel API 12 12 * Texas Instruments - H3 support 13 13 */ 14 + 15 + #include <linux/export.h> 14 16 #include <linux/platform_device.h> 15 17 #include <linux/mm.h> 16 18 #include <linux/slab.h>
+1
drivers/video/fbdev/omap2/omapfb/dss/apply.c
··· 6 6 7 7 #define DSS_SUBSYS_NAME "APPLY" 8 8 9 + #include <linux/export.h> 9 10 #include <linux/kernel.h> 10 11 #include <linux/module.h> 11 12 #include <linux/slab.h>
+1
drivers/video/fbdev/omap2/omapfb/dss/core.c
··· 15 15 #include <linux/module.h> 16 16 #include <linux/clk.h> 17 17 #include <linux/err.h> 18 + #include <linux/export.h> 18 19 #include <linux/platform_device.h> 19 20 #include <linux/seq_file.h> 20 21 #include <linux/debugfs.h>
+1
drivers/video/fbdev/omap2/omapfb/dss/dispc-compat.c
··· 6 6 7 7 #define DSS_SUBSYS_NAME "APPLY" 8 8 9 + #include <linux/export.h> 9 10 #include <linux/kernel.h> 10 11 #include <linux/module.h> 11 12 #include <linux/slab.h>
+1
drivers/video/fbdev/omap2/omapfb/dss/display.c
··· 11 11 12 12 #define DSS_SUBSYS_NAME "DISPLAY" 13 13 14 + #include <linux/export.h> 14 15 #include <linux/kernel.h> 15 16 #include <linux/module.h> 16 17 #include <linux/jiffies.h>
-1
drivers/video/fbdev/omap2/omapfb/dss/dpi.c
··· 13 13 14 14 #include <linux/kernel.h> 15 15 #include <linux/delay.h> 16 - #include <linux/export.h> 17 16 #include <linux/err.h> 18 17 #include <linux/errno.h> 19 18 #include <linux/platform_device.h>
+1
drivers/video/fbdev/omap2/omapfb/dss/dss-of.c
··· 6 6 7 7 #include <linux/device.h> 8 8 #include <linux/err.h> 9 + #include <linux/export.h> 9 10 #include <linux/module.h> 10 11 #include <linux/of.h> 11 12 #include <linux/of_graph.h>
+1
drivers/video/fbdev/omap2/omapfb/dss/dss_features.c
··· 6 6 * Author: Archit Taneja <archit@ti.com> 7 7 */ 8 8 9 + #include <linux/export.h> 9 10 #include <linux/kernel.h> 10 11 #include <linux/module.h> 11 12 #include <linux/types.h>
+1
drivers/video/fbdev/omap2/omapfb/dss/manager.c
··· 11 11 12 12 #define DSS_SUBSYS_NAME "MANAGER" 13 13 14 + #include <linux/export.h> 14 15 #include <linux/kernel.h> 15 16 #include <linux/slab.h> 16 17 #include <linux/module.h>
+1
drivers/video/fbdev/omap2/omapfb/dss/output.c
··· 4 4 * Author: Archit Taneja <archit@ti.com> 5 5 */ 6 6 7 + #include <linux/export.h> 7 8 #include <linux/kernel.h> 8 9 #include <linux/module.h> 9 10 #include <linux/platform_device.h>
+1
drivers/video/fbdev/omap2/omapfb/dss/overlay.c
··· 14 14 #include <linux/kernel.h> 15 15 #include <linux/module.h> 16 16 #include <linux/err.h> 17 + #include <linux/export.h> 17 18 #include <linux/sysfs.h> 18 19 #include <linux/platform_device.h> 19 20 #include <linux/delay.h>
-1
drivers/video/fbdev/omap2/omapfb/dss/sdi.c
··· 12 12 #include <linux/delay.h> 13 13 #include <linux/err.h> 14 14 #include <linux/regulator/consumer.h> 15 - #include <linux/export.h> 16 15 #include <linux/platform_device.h> 17 16 #include <linux/string.h> 18 17 #include <linux/of.h>
+1
drivers/video/fbdev/omap2/omapfb/dss/venc.c
··· 14 14 #include <linux/module.h> 15 15 #include <linux/clk.h> 16 16 #include <linux/err.h> 17 + #include <linux/export.h> 17 18 #include <linux/io.h> 18 19 #include <linux/mutex.h> 19 20 #include <linux/completion.h>
-1
drivers/video/fbdev/omap2/omapfb/omapfb-ioctl.c
··· 16 16 #include <linux/mm.h> 17 17 #include <linux/omapfb.h> 18 18 #include <linux/vmalloc.h> 19 - #include <linux/export.h> 20 19 #include <linux/sizes.h> 21 20 22 21 #include <video/omapfb_dss.h>
+1
drivers/video/fbdev/omap2/omapfb/vrfb.c
··· 9 9 /*#define DEBUG*/ 10 10 11 11 #include <linux/err.h> 12 + #include <linux/export.h> 12 13 #include <linux/kernel.h> 13 14 #include <linux/module.h> 14 15 #include <linux/ioport.h>
+2 -15
drivers/video/fbdev/pxafb.c
··· 1030 1030 1031 1031 /* 1032 1032 * Some touchscreens need hsync information from the video driver to 1033 - * function correctly. We export it here. Note that 'hsync_time' and 1034 - * the value returned from pxafb_get_hsync_time() is the *reciprocal* 1035 - * of the hsync period in seconds. 1033 + * function correctly. We export it here. Note that 'hsync_time' is 1034 + * the *reciprocal* of the hsync period in seconds. 1036 1035 */ 1037 1036 static inline void set_hsync_time(struct pxafb_info *fbi, unsigned int pcd) 1038 1037 { ··· 1046 1047 1047 1048 fbi->hsync_time = htime; 1048 1049 } 1049 - 1050 - unsigned long pxafb_get_hsync_time(struct device *dev) 1051 - { 1052 - struct pxafb_info *fbi = dev_get_drvdata(dev); 1053 - 1054 - /* If display is blanked/suspended, hsync isn't active */ 1055 - if (!fbi || (fbi->state != C_ENABLE)) 1056 - return 0; 1057 - 1058 - return fbi->hsync_time; 1059 - } 1060 - EXPORT_SYMBOL(pxafb_get_hsync_time); 1061 1050 1062 1051 static int setup_frame_dma(struct pxafb_info *fbi, int dma, int pal, 1063 1052 unsigned long start, size_t size)
+1
drivers/video/fbdev/sbuslib.c
··· 5 5 */ 6 6 7 7 #include <linux/compat.h> 8 + #include <linux/export.h> 8 9 #include <linux/kernel.h> 9 10 #include <linux/module.h> 10 11 #include <linux/string.h>
-2
drivers/video/fbdev/sis/sis.h
··· 673 673 674 674 /* SiS-specific exported functions */ 675 675 void sis_malloc(struct sis_memreq *req); 676 - void sis_malloc_new(struct pci_dev *pdev, struct sis_memreq *req); 677 676 void sis_free(u32 base); 678 - void sis_free_new(struct pci_dev *pdev, u32 base); 679 677 680 678 /* Routines from init.c/init301.c */ 681 679 extern unsigned short SiS_GetModeID_LCD(int VGAEngine, unsigned int VBFlags, int HDisplay,
-25
drivers/video/fbdev/sis/sis_main.c
··· 3421 3421 req->offset = req->size = 0; 3422 3422 } 3423 3423 3424 - void 3425 - sis_malloc_new(struct pci_dev *pdev, struct sis_memreq *req) 3426 - { 3427 - struct sis_video_info *ivideo = pci_get_drvdata(pdev); 3428 - 3429 - sis_int_malloc(ivideo, req); 3430 - } 3431 - 3432 3424 /* sis_free: u32 because "base" is offset inside video ram, can never be >4GB */ 3433 3425 3434 3426 static void ··· 3443 3451 sis_free(u32 base) 3444 3452 { 3445 3453 struct sis_video_info *ivideo = sisfb_heap->vinfo; 3446 - 3447 - sis_int_free(ivideo, base); 3448 - } 3449 - 3450 - void 3451 - sis_free_new(struct pci_dev *pdev, u32 base) 3452 - { 3453 - struct sis_video_info *ivideo = pci_get_drvdata(pdev); 3454 3454 3455 3455 sis_int_free(ivideo, base); 3456 3456 } ··· 6816 6832 #endif 6817 6833 6818 6834 #endif /* /MODULE */ 6819 - 6820 - /* _GPL only for new symbols. */ 6821 - EXPORT_SYMBOL(sis_malloc); 6822 - EXPORT_SYMBOL(sis_free); 6823 - EXPORT_SYMBOL_GPL(sis_malloc_new); 6824 - EXPORT_SYMBOL_GPL(sis_free_new); 6825 - 6826 - 6827 -
+1
drivers/video/fbdev/via/via-core.c
··· 9 9 * Core code for the Via multifunction framebuffer device. 10 10 */ 11 11 #include <linux/aperture.h> 12 + #include <linux/export.h> 12 13 #include <linux/via-core.h> 13 14 #include <linux/via_i2c.h> 14 15 #include "via-gpio.h"
-1
drivers/video/fbdev/via/via-gpio.c
··· 10 10 #include <linux/gpio/machine.h> 11 11 #include <linux/platform_device.h> 12 12 #include <linux/via-core.h> 13 - #include <linux/export.h> 14 13 #include "via-gpio.h" 15 14 16 15 /*
+1
drivers/video/fbdev/via/via_i2c.c
··· 7 7 8 8 #include <linux/platform_device.h> 9 9 #include <linux/delay.h> 10 + #include <linux/export.h> 10 11 #include <linux/spinlock.h> 11 12 #include <linux/module.h> 12 13 #include <linux/via-core.h>
+1
drivers/video/fbdev/wmt_ge_rops.c
··· 7 7 * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com> 8 8 */ 9 9 10 + #include <linux/export.h> 10 11 #include <linux/module.h> 11 12 #include <linux/fb.h> 12 13 #include <linux/io.h>
+9
include/drm/drm_device.h
··· 5 5 #include <linux/kref.h> 6 6 #include <linux/mutex.h> 7 7 #include <linux/idr.h> 8 + #include <linux/sched.h> 8 9 9 10 #include <drm/drm_mode_config.h> 10 11 ··· 30 29 #define DRM_WEDGE_RECOVERY_NONE BIT(0) /* optional telemetry collection */ 31 30 #define DRM_WEDGE_RECOVERY_REBIND BIT(1) /* unbind + bind driver */ 32 31 #define DRM_WEDGE_RECOVERY_BUS_RESET BIT(2) /* unbind + reset bus device + bind */ 32 + 33 + /** 34 + * struct drm_wedge_task_info - information about the guilty task of a wedge dev 35 + */ 36 + struct drm_wedge_task_info { 37 + pid_t pid; 38 + char comm[TASK_COMM_LEN]; 39 + }; 33 40 34 41 /** 35 42 * enum switch_power_state - power state of drm device
+2 -1
include/drm/drm_drv.h
··· 487 487 bool drm_dev_enter(struct drm_device *dev, int *idx); 488 488 void drm_dev_exit(int idx); 489 489 void drm_dev_unplug(struct drm_device *dev); 490 - int drm_dev_wedged_event(struct drm_device *dev, unsigned long method); 490 + int drm_dev_wedged_event(struct drm_device *dev, unsigned long method, 491 + struct drm_wedge_task_info *info); 491 492 492 493 /** 493 494 * drm_dev_is_unplugged - is a DRM device unplugged
+9 -4
include/drm/drm_format_helper.h
··· 102 102 void drm_fb_xrgb8888_to_argb8888(struct iosys_map *dst, const unsigned int *dst_pitch, 103 103 const struct iosys_map *src, const struct drm_framebuffer *fb, 104 104 const struct drm_rect *clip, struct drm_format_conv_state *state); 105 + void drm_fb_xrgb8888_to_abgr8888(struct iosys_map *dst, const unsigned int *dst_pitch, 106 + const struct iosys_map *src, const struct drm_framebuffer *fb, 107 + const struct drm_rect *clip, struct drm_format_conv_state *state); 108 + void drm_fb_xrgb8888_to_xbgr8888(struct iosys_map *dst, const unsigned int *dst_pitch, 109 + const struct iosys_map *src, const struct drm_framebuffer *fb, 110 + const struct drm_rect *clip, struct drm_format_conv_state *state); 111 + void drm_fb_xrgb8888_to_bgrx8888(struct iosys_map *dst, const unsigned int *dst_pitch, 112 + const struct iosys_map *src, const struct drm_framebuffer *fb, 113 + const struct drm_rect *clip, struct drm_format_conv_state *state); 105 114 void drm_fb_xrgb8888_to_xrgb2101010(struct iosys_map *dst, const unsigned int *dst_pitch, 106 115 const struct iosys_map *src, const struct drm_framebuffer *fb, 107 116 const struct drm_rect *clip, ··· 133 124 void drm_fb_xrgb8888_to_mono(struct iosys_map *dst, const unsigned int *dst_pitch, 134 125 const struct iosys_map *src, const struct drm_framebuffer *fb, 135 126 const struct drm_rect *clip, struct drm_format_conv_state *state); 136 - 137 - size_t drm_fb_build_fourcc_list(struct drm_device *dev, 138 - const u32 *native_fourccs, size_t native_nfourccs, 139 - u32 *fourccs_out, size_t nfourccs_out); 140 127 141 128 #endif /* __LINUX_DRM_FORMAT_HELPER_H */
+22 -9
include/linux/dma-fence.h
··· 378 378 struct dma_fence_cb *cb); 379 379 void dma_fence_enable_sw_signaling(struct dma_fence *fence); 380 380 381 - static inline const char *dma_fence_driver_name(struct dma_fence *fence) 382 - { 383 - return fence->ops->get_driver_name(fence); 384 - } 385 - 386 - static inline const char *dma_fence_timeline_name(struct dma_fence *fence) 387 - { 388 - return fence->ops->get_timeline_name(fence); 389 - } 381 + /** 382 + * DOC: Safe external access to driver provided object members 383 + * 384 + * All data not stored directly in the dma-fence object, such as the 385 + * &dma_fence.lock and memory potentially accessed by functions in the 386 + * &dma_fence.ops table, MUST NOT be accessed after the fence has been signalled 387 + * because after that point drivers are allowed to free it. 388 + * 389 + * All code accessing that data via the dma-fence API (or directly, which is 390 + * discouraged), MUST make sure to contain the complete access within a 391 + * &rcu_read_lock and &rcu_read_unlock pair. 392 + * 393 + * Some dma-fence API handles this automatically, while other, as for example 394 + * &dma_fence_driver_name and &dma_fence_timeline_name, leave that 395 + * responsibility to the caller. 396 + * 397 + * To enable this scheme to work drivers MUST ensure a RCU grace period elapses 398 + * between signalling the fence and freeing the said data. 399 + * 400 + */ 401 + const char __rcu *dma_fence_driver_name(struct dma_fence *fence); 402 + const char __rcu *dma_fence_timeline_name(struct dma_fence *fence); 390 403 391 404 /** 392 405 * dma_fence_is_signaled_locked - Return an indication if the fence
-1
include/linux/platform_data/video-pxafb.h
··· 150 150 }; 151 151 152 152 void pxa_set_fb_info(struct device *, struct pxafb_mach_info *); 153 - unsigned long pxafb_get_hsync_time(struct device *dev); 154 153 155 154 /* smartpanel related */ 156 155 #define SMART_CMD_A0 (0x1 << 8)
+34 -4
include/trace/events/dma_fence.h
··· 34 34 __entry->seqno) 35 35 ); 36 36 37 - DEFINE_EVENT(dma_fence, dma_fence_emit, 37 + /* 38 + * Safe only for call sites which are guaranteed to not race with fence 39 + * signaling,holding the fence->lock and having checked for not signaled, or the 40 + * signaling path itself. 41 + */ 42 + DECLARE_EVENT_CLASS(dma_fence_unsignaled, 43 + 44 + TP_PROTO(struct dma_fence *fence), 45 + 46 + TP_ARGS(fence), 47 + 48 + TP_STRUCT__entry( 49 + __string(driver, fence->ops->get_driver_name(fence)) 50 + __string(timeline, fence->ops->get_timeline_name(fence)) 51 + __field(unsigned int, context) 52 + __field(unsigned int, seqno) 53 + ), 54 + 55 + TP_fast_assign( 56 + __assign_str(driver); 57 + __assign_str(timeline); 58 + __entry->context = fence->context; 59 + __entry->seqno = fence->seqno; 60 + ), 61 + 62 + TP_printk("driver=%s timeline=%s context=%u seqno=%u", 63 + __get_str(driver), __get_str(timeline), __entry->context, 64 + __entry->seqno) 65 + ); 66 + 67 + DEFINE_EVENT(dma_fence_unsignaled, dma_fence_emit, 38 68 39 69 TP_PROTO(struct dma_fence *fence), 40 70 41 71 TP_ARGS(fence) 42 72 ); 43 73 44 - DEFINE_EVENT(dma_fence, dma_fence_init, 74 + DEFINE_EVENT(dma_fence_unsignaled, dma_fence_init, 45 75 46 76 TP_PROTO(struct dma_fence *fence), 47 77 ··· 85 55 TP_ARGS(fence) 86 56 ); 87 57 88 - DEFINE_EVENT(dma_fence, dma_fence_enable_signal, 58 + DEFINE_EVENT(dma_fence_unsignaled, dma_fence_enable_signal, 89 59 90 60 TP_PROTO(struct dma_fence *fence), 91 61 92 62 TP_ARGS(fence) 93 63 ); 94 64 95 - DEFINE_EVENT(dma_fence, dma_fence_signaled, 65 + DEFINE_EVENT(dma_fence_unsignaled, dma_fence_signaled, 96 66 97 67 TP_PROTO(struct dma_fence *fence), 98 68
+14
include/uapi/drm/ivpu_accel.h
··· 445 445 __u64 data_size; 446 446 }; 447 447 448 + /* Command queue flags */ 449 + #define DRM_IVPU_CMDQ_FLAG_TURBO 0x00000001 450 + 448 451 /** 449 452 * struct drm_ivpu_cmdq_create - Create command queue for job submission 450 453 */ ··· 465 462 * %DRM_IVPU_JOB_PRIORITY_REALTIME 466 463 */ 467 464 __u32 priority; 465 + /** 466 + * @flags: 467 + * 468 + * Supported flags: 469 + * 470 + * %DRM_IVPU_CMDQ_FLAG_TURBO 471 + * 472 + * Enable low-latency mode for the command queue. The NPU will maximize performance 473 + * when executing jobs from such queue at the cost of increased power usage. 474 + */ 475 + __u32 flags; 468 476 }; 469 477 470 478 /**
+2 -1
include/video/edid.h
··· 4 4 5 5 #include <uapi/video/edid.h> 6 6 7 - #ifdef CONFIG_X86 7 + #if defined(CONFIG_FIRMWARE_EDID) 8 8 extern struct edid_info edid_info; 9 9 #endif 10 + 10 11 #endif /* __linux_video_edid_h__ */
-6
include/video/sisfb.h
··· 15 15 #define SIS_300_VGA 1 16 16 #define SIS_315_VGA 2 17 17 18 - #define SISFB_HAVE_MALLOC_NEW 19 - extern void sis_malloc(struct sis_memreq *req); 20 - extern void sis_malloc_new(struct pci_dev *pdev, struct sis_memreq *req); 21 - 22 - extern void sis_free(u32 base); 23 - extern void sis_free_new(struct pci_dev *pdev, u32 base); 24 18 #endif