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

Merge tag 'drm-misc-fixes-2026-01-16' of https://gitlab.freedesktop.org/drm/misc/kernel into drm-fixes

drm-misc-fixes for v6.19-rc6:

vmwgfx:
- Fix hw regression from refactoring cursor handling on v10 'hardware'
- Fix warnings in destructor by merging the 2 release functions
- kernel doc fix
- error handling in vmw_compat_shader_add()

rockchip:
- fix vop2 polling
- fix regression waiting for cfgdone without config change
- fix warning when enabling encoder

core:
- take gem lock when preallocating in gpuvm.
- add single byte read fallback to dp for broken usb-c adapters
- remove duplicate drm_sysfb declarations

gud:
- Fix oops on usb disconnect

Simple panel:
- Re-add fallback when connector is not set to fix regressions
- Set correct type in DataImage SCF0700C48GGU18

nouveau:
- locking fixes for cursor handling.

Signed-off-by: Simona Vetter <simona.vetter@ffwll.ch>
From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Link: https://patch.msgid.link/ce0acfe2-9c1a-42b7-8782-f1e7f34b8544@linux.intel.com

+216 -162
+9
drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
··· 163 163 164 164 unsigned long ref_clk_rate; 165 165 struct regmap *regm; 166 + int main_irq; 166 167 167 168 unsigned long tmds_char_rate; 168 169 }; ··· 1272 1271 1273 1272 dw_hdmi_qp_init_hw(hdmi); 1274 1273 1274 + hdmi->main_irq = plat_data->main_irq; 1275 1275 ret = devm_request_threaded_irq(dev, plat_data->main_irq, 1276 1276 dw_hdmi_qp_main_hardirq, NULL, 1277 1277 IRQF_SHARED, dev_name(dev), hdmi); ··· 1333 1331 } 1334 1332 EXPORT_SYMBOL_GPL(dw_hdmi_qp_bind); 1335 1333 1334 + void dw_hdmi_qp_suspend(struct device *dev, struct dw_hdmi_qp *hdmi) 1335 + { 1336 + disable_irq(hdmi->main_irq); 1337 + } 1338 + EXPORT_SYMBOL_GPL(dw_hdmi_qp_suspend); 1339 + 1336 1340 void dw_hdmi_qp_resume(struct device *dev, struct dw_hdmi_qp *hdmi) 1337 1341 { 1338 1342 dw_hdmi_qp_init_hw(hdmi); 1343 + enable_irq(hdmi->main_irq); 1339 1344 } 1340 1345 EXPORT_SYMBOL_GPL(dw_hdmi_qp_resume); 1341 1346
+51 -24
drivers/gpu/drm/drm_gpuvm.c
··· 1602 1602 } 1603 1603 EXPORT_SYMBOL_GPL(drm_gpuvm_bo_create); 1604 1604 1605 + /* 1606 + * drm_gpuvm_bo_destroy_not_in_lists() - final part of drm_gpuvm_bo cleanup 1607 + * @vm_bo: the &drm_gpuvm_bo to destroy 1608 + * 1609 + * It is illegal to call this method if the @vm_bo is present in the GEMs gpuva 1610 + * list, the extobj list, or the evicted list. 1611 + * 1612 + * Note that this puts a refcount on the GEM object, which may destroy the GEM 1613 + * object if the refcount reaches zero. It's illegal for this to happen if the 1614 + * caller holds the GEMs gpuva mutex because it would free the mutex. 1615 + */ 1605 1616 static void 1606 - drm_gpuvm_bo_destroy(struct kref *kref) 1617 + drm_gpuvm_bo_destroy_not_in_lists(struct drm_gpuvm_bo *vm_bo) 1607 1618 { 1608 - struct drm_gpuvm_bo *vm_bo = container_of(kref, struct drm_gpuvm_bo, 1609 - kref); 1610 1619 struct drm_gpuvm *gpuvm = vm_bo->vm; 1611 1620 const struct drm_gpuvm_ops *ops = gpuvm->ops; 1612 1621 struct drm_gem_object *obj = vm_bo->obj; 1613 - bool lock = !drm_gpuvm_resv_protected(gpuvm); 1614 - 1615 - if (!lock) 1616 - drm_gpuvm_resv_assert_held(gpuvm); 1617 - 1618 - drm_gpuvm_bo_list_del(vm_bo, extobj, lock); 1619 - drm_gpuvm_bo_list_del(vm_bo, evict, lock); 1620 - 1621 - drm_gem_gpuva_assert_lock_held(gpuvm, obj); 1622 - list_del(&vm_bo->list.entry.gem); 1623 1622 1624 1623 if (ops && ops->vm_bo_free) 1625 1624 ops->vm_bo_free(vm_bo); ··· 1627 1628 1628 1629 drm_gpuvm_put(gpuvm); 1629 1630 drm_gem_object_put(obj); 1631 + } 1632 + 1633 + static void 1634 + drm_gpuvm_bo_destroy_not_in_lists_kref(struct kref *kref) 1635 + { 1636 + struct drm_gpuvm_bo *vm_bo = container_of(kref, struct drm_gpuvm_bo, 1637 + kref); 1638 + 1639 + drm_gpuvm_bo_destroy_not_in_lists(vm_bo); 1640 + } 1641 + 1642 + static void 1643 + drm_gpuvm_bo_destroy(struct kref *kref) 1644 + { 1645 + struct drm_gpuvm_bo *vm_bo = container_of(kref, struct drm_gpuvm_bo, 1646 + kref); 1647 + struct drm_gpuvm *gpuvm = vm_bo->vm; 1648 + bool lock = !drm_gpuvm_resv_protected(gpuvm); 1649 + 1650 + if (!lock) 1651 + drm_gpuvm_resv_assert_held(gpuvm); 1652 + 1653 + drm_gpuvm_bo_list_del(vm_bo, extobj, lock); 1654 + drm_gpuvm_bo_list_del(vm_bo, evict, lock); 1655 + 1656 + drm_gem_gpuva_assert_lock_held(gpuvm, vm_bo->obj); 1657 + list_del(&vm_bo->list.entry.gem); 1658 + 1659 + drm_gpuvm_bo_destroy_not_in_lists(vm_bo); 1630 1660 } 1631 1661 1632 1662 /** ··· 1773 1745 void 1774 1746 drm_gpuvm_bo_deferred_cleanup(struct drm_gpuvm *gpuvm) 1775 1747 { 1776 - const struct drm_gpuvm_ops *ops = gpuvm->ops; 1777 1748 struct drm_gpuvm_bo *vm_bo; 1778 - struct drm_gem_object *obj; 1779 1749 struct llist_node *bo_defer; 1780 1750 1781 1751 bo_defer = llist_del_all(&gpuvm->bo_defer); ··· 1792 1766 while (bo_defer) { 1793 1767 vm_bo = llist_entry(bo_defer, struct drm_gpuvm_bo, list.entry.bo_defer); 1794 1768 bo_defer = bo_defer->next; 1795 - obj = vm_bo->obj; 1796 - if (ops && ops->vm_bo_free) 1797 - ops->vm_bo_free(vm_bo); 1798 - else 1799 - kfree(vm_bo); 1800 - 1801 - drm_gpuvm_put(gpuvm); 1802 - drm_gem_object_put(obj); 1769 + drm_gpuvm_bo_destroy_not_in_lists(vm_bo); 1803 1770 } 1804 1771 } 1805 1772 EXPORT_SYMBOL_GPL(drm_gpuvm_bo_deferred_cleanup); ··· 1880 1861 * count is decreased. If not found @__vm_bo is returned without further 1881 1862 * increase of the reference count. 1882 1863 * 1864 + * The provided @__vm_bo must not already be in the gpuva, evict, or extobj 1865 + * lists prior to calling this method. 1866 + * 1883 1867 * A new &drm_gpuvm_bo is added to the GEMs gpuva list. 1884 1868 * 1885 1869 * Returns: a pointer to the found &drm_gpuvm_bo or @__vm_bo if no existing ··· 1895 1873 struct drm_gem_object *obj = __vm_bo->obj; 1896 1874 struct drm_gpuvm_bo *vm_bo; 1897 1875 1876 + drm_WARN_ON(gpuvm->drm, !drm_gpuvm_immediate_mode(gpuvm)); 1877 + 1878 + mutex_lock(&obj->gpuva.lock); 1898 1879 vm_bo = drm_gpuvm_bo_find(gpuvm, obj); 1899 1880 if (vm_bo) { 1900 - drm_gpuvm_bo_put(__vm_bo); 1881 + mutex_unlock(&obj->gpuva.lock); 1882 + kref_put(&__vm_bo->kref, drm_gpuvm_bo_destroy_not_in_lists_kref); 1901 1883 return vm_bo; 1902 1884 } 1903 1885 1904 1886 drm_gem_gpuva_assert_lock_held(gpuvm, obj); 1905 1887 list_add_tail(&__vm_bo->list.entry.gem, &obj->gpuva.list); 1888 + mutex_unlock(&obj->gpuva.lock); 1906 1889 1907 1890 return __vm_bo; 1908 1891 }
+8 -12
drivers/gpu/drm/gud/gud_pipe.c
··· 457 457 struct drm_plane_state *old_plane_state = drm_atomic_get_old_plane_state(state, plane); 458 458 struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state, plane); 459 459 struct drm_crtc *crtc = new_plane_state->crtc; 460 - struct drm_crtc_state *crtc_state; 460 + struct drm_crtc_state *crtc_state = NULL; 461 461 const struct drm_display_mode *mode; 462 462 struct drm_framebuffer *old_fb = old_plane_state->fb; 463 463 struct drm_connector_state *connector_state = NULL; 464 464 struct drm_framebuffer *fb = new_plane_state->fb; 465 - const struct drm_format_info *format = fb->format; 465 + const struct drm_format_info *format; 466 466 struct drm_connector *connector; 467 467 unsigned int i, num_properties; 468 468 struct gud_state_req *req; 469 469 int idx, ret; 470 470 size_t len; 471 471 472 - if (drm_WARN_ON_ONCE(plane->dev, !fb)) 473 - return -EINVAL; 474 - 475 - if (drm_WARN_ON_ONCE(plane->dev, !crtc)) 476 - return -EINVAL; 477 - 478 - crtc_state = drm_atomic_get_new_crtc_state(state, crtc); 479 - 480 - mode = &crtc_state->mode; 472 + if (crtc) 473 + crtc_state = drm_atomic_get_new_crtc_state(state, crtc); 481 474 482 475 ret = drm_atomic_helper_check_plane_state(new_plane_state, crtc_state, 483 476 DRM_PLANE_NO_SCALING, ··· 484 491 485 492 if (old_plane_state->rotation != new_plane_state->rotation) 486 493 crtc_state->mode_changed = true; 494 + 495 + mode = &crtc_state->mode; 496 + format = fb->format; 487 497 488 498 if (old_fb && old_fb->format != format) 489 499 crtc_state->mode_changed = true; ··· 594 598 struct drm_atomic_helper_damage_iter iter; 595 599 int ret, idx; 596 600 597 - if (crtc->state->mode_changed || !crtc->state->enable) { 601 + if (!crtc || crtc->state->mode_changed || !crtc->state->enable) { 598 602 cancel_work_sync(&gdrm->work); 599 603 mutex_lock(&gdrm->damage_lock); 600 604 if (gdrm->fb) {
+1
drivers/gpu/drm/nouveau/dispnv50/curs507a.c
··· 84 84 asyh->curs.handle = handle; 85 85 asyh->curs.offset = offset; 86 86 asyh->set.curs = asyh->curs.visible; 87 + nv50_atom(asyh->state.state)->lock_core = true; 87 88 } 88 89 } 89 90
+5
drivers/gpu/drm/nouveau/dispnv50/head.c
··· 43 43 union nv50_head_atom_mask clr = { 44 44 .mask = asyh->clr.mask & ~(flush ? 0 : asyh->set.mask), 45 45 }; 46 + 47 + lockdep_assert_held(&head->disp->mutex); 48 + 46 49 if (clr.crc) nv50_crc_atomic_clr(head); 47 50 if (clr.olut) head->func->olut_clr(head); 48 51 if (clr.core) head->func->core_clr(head); ··· 68 65 void 69 66 nv50_head_flush_set(struct nv50_head *head, struct nv50_head_atom *asyh) 70 67 { 68 + lockdep_assert_held(&head->disp->mutex); 69 + 71 70 if (asyh->set.view ) head->func->view (head, asyh); 72 71 if (asyh->set.mode ) head->func->mode (head, asyh); 73 72 if (asyh->set.core ) head->func->core_set(head, asyh);
+55 -55
drivers/gpu/drm/panel/panel-simple.c
··· 623 623 if (IS_ERR(desc)) 624 624 return ERR_CAST(desc); 625 625 626 + connector_type = desc->connector_type; 627 + /* Catch common mistakes for panels. */ 628 + switch (connector_type) { 629 + case 0: 630 + dev_warn(dev, "Specify missing connector_type\n"); 631 + connector_type = DRM_MODE_CONNECTOR_DPI; 632 + break; 633 + case DRM_MODE_CONNECTOR_LVDS: 634 + WARN_ON(desc->bus_flags & 635 + ~(DRM_BUS_FLAG_DE_LOW | 636 + DRM_BUS_FLAG_DE_HIGH | 637 + DRM_BUS_FLAG_DATA_MSB_TO_LSB | 638 + DRM_BUS_FLAG_DATA_LSB_TO_MSB)); 639 + WARN_ON(desc->bus_format != MEDIA_BUS_FMT_RGB666_1X7X3_SPWG && 640 + desc->bus_format != MEDIA_BUS_FMT_RGB888_1X7X4_SPWG && 641 + desc->bus_format != MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA); 642 + WARN_ON(desc->bus_format == MEDIA_BUS_FMT_RGB666_1X7X3_SPWG && 643 + desc->bpc != 6); 644 + WARN_ON((desc->bus_format == MEDIA_BUS_FMT_RGB888_1X7X4_SPWG || 645 + desc->bus_format == MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA) && 646 + desc->bpc != 8); 647 + break; 648 + case DRM_MODE_CONNECTOR_eDP: 649 + dev_warn(dev, "eDP panels moved to panel-edp\n"); 650 + return ERR_PTR(-EINVAL); 651 + case DRM_MODE_CONNECTOR_DSI: 652 + if (desc->bpc != 6 && desc->bpc != 8) 653 + dev_warn(dev, "Expected bpc in {6,8} but got: %u\n", desc->bpc); 654 + break; 655 + case DRM_MODE_CONNECTOR_DPI: 656 + bus_flags = DRM_BUS_FLAG_DE_LOW | 657 + DRM_BUS_FLAG_DE_HIGH | 658 + DRM_BUS_FLAG_PIXDATA_SAMPLE_POSEDGE | 659 + DRM_BUS_FLAG_PIXDATA_SAMPLE_NEGEDGE | 660 + DRM_BUS_FLAG_DATA_MSB_TO_LSB | 661 + DRM_BUS_FLAG_DATA_LSB_TO_MSB | 662 + DRM_BUS_FLAG_SYNC_SAMPLE_POSEDGE | 663 + DRM_BUS_FLAG_SYNC_SAMPLE_NEGEDGE; 664 + if (desc->bus_flags & ~bus_flags) 665 + dev_warn(dev, "Unexpected bus_flags(%d)\n", desc->bus_flags & ~bus_flags); 666 + if (!(desc->bus_flags & bus_flags)) 667 + dev_warn(dev, "Specify missing bus_flags\n"); 668 + if (desc->bus_format == 0) 669 + dev_warn(dev, "Specify missing bus_format\n"); 670 + if (desc->bpc != 6 && desc->bpc != 8) 671 + dev_warn(dev, "Expected bpc in {6,8} but got: %u\n", desc->bpc); 672 + break; 673 + default: 674 + dev_warn(dev, "Specify a valid connector_type: %d\n", desc->connector_type); 675 + connector_type = DRM_MODE_CONNECTOR_DPI; 676 + break; 677 + } 678 + 626 679 panel = devm_drm_panel_alloc(dev, struct panel_simple, base, 627 - &panel_simple_funcs, desc->connector_type); 680 + &panel_simple_funcs, connector_type); 628 681 if (IS_ERR(panel)) 629 682 return ERR_CAST(panel); 630 683 ··· 717 664 err = panel_simple_override_nondefault_lvds_datamapping(dev, panel); 718 665 if (err) 719 666 goto free_ddc; 720 - } 721 - 722 - connector_type = desc->connector_type; 723 - /* Catch common mistakes for panels. */ 724 - switch (connector_type) { 725 - case 0: 726 - dev_warn(dev, "Specify missing connector_type\n"); 727 - connector_type = DRM_MODE_CONNECTOR_DPI; 728 - break; 729 - case DRM_MODE_CONNECTOR_LVDS: 730 - WARN_ON(desc->bus_flags & 731 - ~(DRM_BUS_FLAG_DE_LOW | 732 - DRM_BUS_FLAG_DE_HIGH | 733 - DRM_BUS_FLAG_DATA_MSB_TO_LSB | 734 - DRM_BUS_FLAG_DATA_LSB_TO_MSB)); 735 - WARN_ON(desc->bus_format != MEDIA_BUS_FMT_RGB666_1X7X3_SPWG && 736 - desc->bus_format != MEDIA_BUS_FMT_RGB888_1X7X4_SPWG && 737 - desc->bus_format != MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA); 738 - WARN_ON(desc->bus_format == MEDIA_BUS_FMT_RGB666_1X7X3_SPWG && 739 - desc->bpc != 6); 740 - WARN_ON((desc->bus_format == MEDIA_BUS_FMT_RGB888_1X7X4_SPWG || 741 - desc->bus_format == MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA) && 742 - desc->bpc != 8); 743 - break; 744 - case DRM_MODE_CONNECTOR_eDP: 745 - dev_warn(dev, "eDP panels moved to panel-edp\n"); 746 - err = -EINVAL; 747 - goto free_ddc; 748 - case DRM_MODE_CONNECTOR_DSI: 749 - if (desc->bpc != 6 && desc->bpc != 8) 750 - dev_warn(dev, "Expected bpc in {6,8} but got: %u\n", desc->bpc); 751 - break; 752 - case DRM_MODE_CONNECTOR_DPI: 753 - bus_flags = DRM_BUS_FLAG_DE_LOW | 754 - DRM_BUS_FLAG_DE_HIGH | 755 - DRM_BUS_FLAG_PIXDATA_SAMPLE_POSEDGE | 756 - DRM_BUS_FLAG_PIXDATA_SAMPLE_NEGEDGE | 757 - DRM_BUS_FLAG_DATA_MSB_TO_LSB | 758 - DRM_BUS_FLAG_DATA_LSB_TO_MSB | 759 - DRM_BUS_FLAG_SYNC_SAMPLE_POSEDGE | 760 - DRM_BUS_FLAG_SYNC_SAMPLE_NEGEDGE; 761 - if (desc->bus_flags & ~bus_flags) 762 - dev_warn(dev, "Unexpected bus_flags(%d)\n", desc->bus_flags & ~bus_flags); 763 - if (!(desc->bus_flags & bus_flags)) 764 - dev_warn(dev, "Specify missing bus_flags\n"); 765 - if (desc->bus_format == 0) 766 - dev_warn(dev, "Specify missing bus_format\n"); 767 - if (desc->bpc != 6 && desc->bpc != 8) 768 - dev_warn(dev, "Expected bpc in {6,8} but got: %u\n", desc->bpc); 769 - break; 770 - default: 771 - dev_warn(dev, "Specify a valid connector_type: %d\n", desc->connector_type); 772 - connector_type = DRM_MODE_CONNECTOR_DPI; 773 - break; 774 667 } 775 668 776 669 dev_set_drvdata(dev, panel); ··· 1899 1900 }, 1900 1901 .bus_format = MEDIA_BUS_FMT_RGB888_1X24, 1901 1902 .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE, 1903 + .connector_type = DRM_MODE_CONNECTOR_DPI, 1902 1904 }; 1903 1905 1904 1906 static const struct display_timing dlc_dlc0700yzg_1_timing = {
-10
drivers/gpu/drm/panthor/panthor_mmu.c
··· 1252 1252 goto err_cleanup; 1253 1253 } 1254 1254 1255 - /* drm_gpuvm_bo_obtain_prealloc() will call drm_gpuvm_bo_put() on our 1256 - * pre-allocated BO if the <BO,VM> association exists. Given we 1257 - * only have one ref on preallocated_vm_bo, drm_gpuvm_bo_destroy() will 1258 - * be called immediately, and we have to hold the VM resv lock when 1259 - * calling this function. 1260 - */ 1261 - dma_resv_lock(panthor_vm_resv(vm), NULL); 1262 - mutex_lock(&bo->base.base.gpuva.lock); 1263 1255 op_ctx->map.vm_bo = drm_gpuvm_bo_obtain_prealloc(preallocated_vm_bo); 1264 - mutex_unlock(&bo->base.base.gpuva.lock); 1265 - dma_resv_unlock(panthor_vm_resv(vm)); 1266 1256 1267 1257 op_ctx->map.bo_offset = offset; 1268 1258
+12 -2
drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
··· 121 121 struct drm_crtc *crtc = encoder->crtc; 122 122 123 123 /* Unconditionally switch to TMDS as FRL is not yet supported */ 124 - gpiod_set_value(hdmi->frl_enable_gpio, 0); 124 + gpiod_set_value_cansleep(hdmi->frl_enable_gpio, 0); 125 125 126 126 if (!crtc || !crtc->state) 127 127 return; ··· 640 640 component_del(&pdev->dev, &dw_hdmi_qp_rockchip_ops); 641 641 } 642 642 643 + static int __maybe_unused dw_hdmi_qp_rockchip_suspend(struct device *dev) 644 + { 645 + struct rockchip_hdmi_qp *hdmi = dev_get_drvdata(dev); 646 + 647 + dw_hdmi_qp_suspend(dev, hdmi->hdmi); 648 + 649 + return 0; 650 + } 651 + 643 652 static int __maybe_unused dw_hdmi_qp_rockchip_resume(struct device *dev) 644 653 { 645 654 struct rockchip_hdmi_qp *hdmi = dev_get_drvdata(dev); ··· 664 655 } 665 656 666 657 static const struct dev_pm_ops dw_hdmi_qp_rockchip_pm = { 667 - SET_SYSTEM_SLEEP_PM_OPS(NULL, dw_hdmi_qp_rockchip_resume) 658 + SET_SYSTEM_SLEEP_PM_OPS(dw_hdmi_qp_rockchip_suspend, 659 + dw_hdmi_qp_rockchip_resume) 668 660 }; 669 661 670 662 struct platform_driver dw_hdmi_qp_rockchip_pltfm_driver = {
+13 -4
drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
··· 2104 2104 * Spin until the previous port_mux figuration is done. 2105 2105 */ 2106 2106 ret = readx_poll_timeout_atomic(rk3568_vop2_read_port_mux, vop2, port_mux_sel, 2107 - port_mux_sel == vop2->old_port_sel, 0, 50 * 1000); 2107 + port_mux_sel == vop2->old_port_sel, 10, 50 * 1000); 2108 2108 if (ret) 2109 2109 DRM_DEV_ERROR(vop2->dev, "wait port_mux done timeout: 0x%x--0x%x\n", 2110 2110 port_mux_sel, vop2->old_port_sel); ··· 2124 2124 * Spin until the previous layer configuration is done. 2125 2125 */ 2126 2126 ret = readx_poll_timeout_atomic(rk3568_vop2_read_layer_cfg, vop2, atv_layer_cfg, 2127 - atv_layer_cfg == cfg, 0, 50 * 1000); 2127 + atv_layer_cfg == cfg, 10, 50 * 1000); 2128 2128 if (ret) 2129 2129 DRM_DEV_ERROR(vop2->dev, "wait layer cfg done timeout: 0x%x--0x%x\n", 2130 2130 atv_layer_cfg, cfg); ··· 2144 2144 u8 layer_sel_id; 2145 2145 unsigned int ofs; 2146 2146 u32 ovl_ctrl; 2147 + u32 cfg_done; 2147 2148 int i; 2148 2149 struct vop2_video_port *vp0 = &vop2->vps[0]; 2149 2150 struct vop2_video_port *vp1 = &vop2->vps[1]; ··· 2299 2298 rk3568_vop2_wait_for_port_mux_done(vop2); 2300 2299 } 2301 2300 2302 - if (layer_sel != old_layer_sel && atv_layer_sel != old_layer_sel) 2303 - rk3568_vop2_wait_for_layer_cfg_done(vop2, vop2->old_layer_sel); 2301 + if (layer_sel != old_layer_sel && atv_layer_sel != old_layer_sel) { 2302 + cfg_done = vop2_readl(vop2, RK3568_REG_CFG_DONE); 2303 + cfg_done &= (BIT(vop2->data->nr_vps) - 1); 2304 + cfg_done &= ~BIT(vp->id); 2305 + /* 2306 + * Changes of other VPs' overlays have not taken effect 2307 + */ 2308 + if (cfg_done) 2309 + rk3568_vop2_wait_for_layer_cfg_done(vop2, vop2->old_layer_sel); 2310 + } 2304 2311 2305 2312 vop2_writel(vop2, RK3568_OVL_LAYER_SEL, layer_sel); 2306 2313 mutex_unlock(&vop2->ovl_lock);
-9
drivers/gpu/drm/sysfb/drm_sysfb_helper.h
··· 55 55 #endif 56 56 57 57 /* 58 - * Input parsing 59 - */ 60 - 61 - int drm_sysfb_get_validated_int(struct drm_device *dev, const char *name, 62 - u64 value, u32 max); 63 - int drm_sysfb_get_validated_int0(struct drm_device *dev, const char *name, 64 - u64 value, u32 max); 65 - 66 - /* 67 58 * Display modes 68 59 */ 69 60
+8 -14
drivers/gpu/drm/vmwgfx/vmwgfx_bo.c
··· 32 32 33 33 #include <drm/ttm/ttm_placement.h> 34 34 35 - static void vmw_bo_release(struct vmw_bo *vbo) 35 + /** 36 + * vmw_bo_free - vmw_bo destructor 37 + * 38 + * @bo: Pointer to the embedded struct ttm_buffer_object 39 + */ 40 + static void vmw_bo_free(struct ttm_buffer_object *bo) 36 41 { 37 42 struct vmw_resource *res; 43 + struct vmw_bo *vbo = to_vmw_bo(&bo->base); 38 44 39 45 WARN_ON(kref_read(&vbo->tbo.base.refcount) != 0); 40 46 vmw_bo_unmap(vbo); ··· 68 62 } 69 63 vmw_surface_unreference(&vbo->dumb_surface); 70 64 } 71 - drm_gem_object_release(&vbo->tbo.base); 72 - } 73 - 74 - /** 75 - * vmw_bo_free - vmw_bo destructor 76 - * 77 - * @bo: Pointer to the embedded struct ttm_buffer_object 78 - */ 79 - static void vmw_bo_free(struct ttm_buffer_object *bo) 80 - { 81 - struct vmw_bo *vbo = to_vmw_bo(&bo->base); 82 - 83 65 WARN_ON(!RB_EMPTY_ROOT(&vbo->res_tree)); 84 - vmw_bo_release(vbo); 66 + drm_gem_object_release(&vbo->tbo.base); 85 67 WARN_ON(vbo->dirty); 86 68 kfree(vbo); 87 69 }
+5 -5
drivers/gpu/drm/vmwgfx/vmwgfx_fence.c
··· 515 515 /** 516 516 * vmw_event_fence_action_seq_passed 517 517 * 518 - * @action: The struct vmw_fence_action embedded in a struct 519 - * vmw_event_fence_action. 518 + * @f: The struct dma_fence which provides timestamp for the action event 519 + * @cb: The struct dma_fence_cb callback for the action event. 520 520 * 521 - * This function is called when the seqno of the fence where @action is 522 - * attached has passed. It queues the event on the submitter's event list. 523 - * This function is always called from atomic context. 521 + * This function is called when the seqno of the fence has passed 522 + * and it is always called from atomic context. 523 + * It queues the event on the submitter's event list. 524 524 */ 525 525 static void vmw_event_fence_action_seq_passed(struct dma_fence *f, 526 526 struct dma_fence_cb *cb)
+8 -6
drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
··· 766 766 return ERR_PTR(ret); 767 767 } 768 768 769 - ttm_bo_reserve(&bo->tbo, false, false, NULL); 770 - ret = vmw_bo_dirty_add(bo); 771 - if (!ret && surface && surface->res.func->dirty_alloc) { 772 - surface->res.coherent = true; 773 - ret = surface->res.func->dirty_alloc(&surface->res); 769 + if (bo) { 770 + ttm_bo_reserve(&bo->tbo, false, false, NULL); 771 + ret = vmw_bo_dirty_add(bo); 772 + if (!ret && surface && surface->res.func->dirty_alloc) { 773 + surface->res.coherent = true; 774 + ret = surface->res.func->dirty_alloc(&surface->res); 775 + } 776 + ttm_bo_unreserve(&bo->tbo); 774 777 } 775 - ttm_bo_unreserve(&bo->tbo); 776 778 777 779 return &vfb->base; 778 780 }
+3 -1
drivers/gpu/drm/vmwgfx/vmwgfx_shader.c
··· 923 923 ttm_bo_unreserve(&buf->tbo); 924 924 925 925 res = vmw_shader_alloc(dev_priv, buf, size, 0, shader_type); 926 - if (unlikely(ret != 0)) 926 + if (IS_ERR(res)) { 927 + ret = PTR_ERR(res); 927 928 goto no_reserve; 929 + } 928 930 929 931 ret = vmw_cmdbuf_res_add(man, vmw_cmdbuf_res_shader, 930 932 vmw_shader_key(user_key, shader_type),
+1
include/drm/bridge/dw_hdmi_qp.h
··· 34 34 struct dw_hdmi_qp *dw_hdmi_qp_bind(struct platform_device *pdev, 35 35 struct drm_encoder *encoder, 36 36 const struct dw_hdmi_qp_plat_data *plat_data); 37 + void dw_hdmi_qp_suspend(struct device *dev, struct dw_hdmi_qp *hdmi); 37 38 void dw_hdmi_qp_resume(struct device *dev, struct dw_hdmi_qp *hdmi); 38 39 #endif /* __DW_HDMI_QP__ */
+37 -20
include/drm/display/drm_dp_helper.h
··· 552 552 void *buffer, size_t size); 553 553 554 554 /** 555 + * drm_dp_dpcd_readb() - read a single byte from the DPCD 556 + * @aux: DisplayPort AUX channel 557 + * @offset: address of the register to read 558 + * @valuep: location where the value of the register will be stored 559 + * 560 + * Returns the number of bytes transferred (1) on success, or a negative 561 + * error code on failure. In most of the cases you should be using 562 + * drm_dp_dpcd_read_byte() instead. 563 + */ 564 + static inline ssize_t drm_dp_dpcd_readb(struct drm_dp_aux *aux, 565 + unsigned int offset, u8 *valuep) 566 + { 567 + return drm_dp_dpcd_read(aux, offset, valuep, 1); 568 + } 569 + 570 + /** 555 571 * drm_dp_dpcd_read_data() - read a series of bytes from the DPCD 556 572 * @aux: DisplayPort AUX channel (SST or MST) 557 573 * @offset: address of the (first) register to read ··· 586 570 void *buffer, size_t size) 587 571 { 588 572 int ret; 573 + size_t i; 574 + u8 *buf = buffer; 589 575 590 576 ret = drm_dp_dpcd_read(aux, offset, buffer, size); 591 - if (ret < 0) 592 - return ret; 593 - if (ret < size) 594 - return -EPROTO; 577 + if (ret >= 0) { 578 + if (ret < size) 579 + return -EPROTO; 580 + return 0; 581 + } 582 + 583 + /* 584 + * Workaround for USB-C hubs/adapters with buggy firmware that fail 585 + * multi-byte AUX reads but work with single-byte reads. 586 + * Known affected devices: 587 + * - Lenovo USB-C to VGA adapter (VIA VL817, idVendor=17ef, idProduct=7217) 588 + * - Dell DA310 USB-C hub (idVendor=413c, idProduct=c010) 589 + * Attempt byte-by-byte reading as a fallback. 590 + */ 591 + for (i = 0; i < size; i++) { 592 + ret = drm_dp_dpcd_readb(aux, offset + i, &buf[i]); 593 + if (ret < 0) 594 + return ret; 595 + } 595 596 596 597 return 0; 597 598 } ··· 640 607 return -EPROTO; 641 608 642 609 return 0; 643 - } 644 - 645 - /** 646 - * drm_dp_dpcd_readb() - read a single byte from the DPCD 647 - * @aux: DisplayPort AUX channel 648 - * @offset: address of the register to read 649 - * @valuep: location where the value of the register will be stored 650 - * 651 - * Returns the number of bytes transferred (1) on success, or a negative 652 - * error code on failure. In most of the cases you should be using 653 - * drm_dp_dpcd_read_byte() instead. 654 - */ 655 - static inline ssize_t drm_dp_dpcd_readb(struct drm_dp_aux *aux, 656 - unsigned int offset, u8 *valuep) 657 - { 658 - return drm_dp_dpcd_read(aux, offset, valuep, 1); 659 610 } 660 611 661 612 /**