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

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

drm-misc-fixes for v6.13:

- itee-it6263 error handling fix.
- Fix warn when unloading v3d.
- Fix W=1 build for kunit tests.
- Fix backlight regression for macbooks 5,1 in nouveau.
- Handle YCbCr420 better in bridge code, with tests.
- Fix cross-device fence handling in nouveau.
- Fix BO reservation handling in vmwgfx.

Signed-off-by: Dave Airlie <airlied@redhat.com>
From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/a89adcd5-2042-4e7f-93f4-2b299bb1ef17@linux.intel.com

+111 -30
+2 -2
drivers/gpu/drm/bridge/ite-it6263.c
··· 845 845 it->lvds_i2c = devm_i2c_new_dummy_device(dev, client->adapter, 846 846 LVDS_INPUT_CTRL_I2C_ADDR); 847 847 if (IS_ERR(it->lvds_i2c)) 848 - dev_err_probe(it->dev, PTR_ERR(it->lvds_i2c), 849 - "failed to allocate I2C device for LVDS\n"); 848 + return dev_err_probe(it->dev, PTR_ERR(it->lvds_i2c), 849 + "failed to allocate I2C device for LVDS\n"); 850 850 851 851 it->lvds_regmap = devm_regmap_init_i2c(it->lvds_i2c, 852 852 &it6263_lvds_regmap_config);
+6 -2
drivers/gpu/drm/display/drm_bridge_connector.c
··· 459 459 if (connector_type == DRM_MODE_CONNECTOR_Unknown) 460 460 return ERR_PTR(-EINVAL); 461 461 462 - if (bridge_connector->bridge_hdmi) 462 + if (bridge_connector->bridge_hdmi) { 463 + if (!connector->ycbcr_420_allowed) 464 + supported_formats &= ~BIT(HDMI_COLORSPACE_YUV420); 465 + 463 466 ret = drmm_connector_hdmi_init(drm, connector, 464 467 bridge_connector->bridge_hdmi->vendor, 465 468 bridge_connector->bridge_hdmi->product, ··· 471 468 connector_type, ddc, 472 469 supported_formats, 473 470 max_bpc); 474 - else 471 + } else { 475 472 ret = drmm_connector_init(drm, connector, 476 473 &drm_bridge_connector_funcs, 477 474 connector_type, ddc); 475 + } 478 476 if (ret) 479 477 return ERR_PTR(ret); 480 478
+4
drivers/gpu/drm/drm_bridge.c
··· 207 207 { 208 208 mutex_init(&bridge->hpd_mutex); 209 209 210 + if (bridge->ops & DRM_BRIDGE_OP_HDMI) 211 + bridge->ycbcr_420_allowed = !!(bridge->supported_formats & 212 + BIT(HDMI_COLORSPACE_YUV420)); 213 + 210 214 mutex_lock(&bridge_lock); 211 215 list_add_tail(&bridge->list, &bridge_list); 212 216 mutex_unlock(&bridge_lock);
+3
drivers/gpu/drm/drm_connector.c
··· 507 507 if (!supported_formats || !(supported_formats & BIT(HDMI_COLORSPACE_RGB))) 508 508 return -EINVAL; 509 509 510 + if (connector->ycbcr_420_allowed != !!(supported_formats & BIT(HDMI_COLORSPACE_YUV420))) 511 + return -EINVAL; 512 + 510 513 if (!(max_bpc == 8 || max_bpc == 10 || max_bpc == 12)) 511 514 return -EINVAL; 512 515
+4 -2
drivers/gpu/drm/nouveau/nouveau_fence.c
··· 387 387 if (f) { 388 388 struct nouveau_channel *prev; 389 389 bool must_wait = true; 390 + bool local; 390 391 391 392 rcu_read_lock(); 392 393 prev = rcu_dereference(f->channel); 393 - if (prev && (prev == chan || 394 - fctx->sync(f, prev, chan) == 0)) 394 + local = prev && prev->cli->drm == chan->cli->drm; 395 + if (local && (prev == chan || 396 + fctx->sync(f, prev, chan) == 0)) 395 397 must_wait = false; 396 398 rcu_read_unlock(); 397 399 if (!must_wait)
+1
drivers/gpu/drm/nouveau/nvkm/engine/disp/mcp77.c
··· 31 31 .state = g94_sor_state, 32 32 .power = nv50_sor_power, 33 33 .clock = nv50_sor_clock, 34 + .bl = &nv50_sor_bl, 34 35 .hdmi = &g84_sor_hdmi, 35 36 .dp = &g94_sor_dp, 36 37 };
+60
drivers/gpu/drm/tests/drm_connector_test.c
··· 635 635 KUNIT_EXPECT_LT(test, ret, 0); 636 636 } 637 637 638 + struct drm_connector_hdmi_init_formats_yuv420_allowed_test { 639 + unsigned long supported_formats; 640 + bool yuv420_allowed; 641 + int expected_result; 642 + }; 643 + 644 + #define YUV420_ALLOWED_TEST(_formats, _allowed, _result) \ 645 + { \ 646 + .supported_formats = BIT(HDMI_COLORSPACE_RGB) | (_formats), \ 647 + .yuv420_allowed = _allowed, \ 648 + .expected_result = _result, \ 649 + } 650 + 651 + static const struct drm_connector_hdmi_init_formats_yuv420_allowed_test 652 + drm_connector_hdmi_init_formats_yuv420_allowed_tests[] = { 653 + YUV420_ALLOWED_TEST(BIT(HDMI_COLORSPACE_YUV420), true, 0), 654 + YUV420_ALLOWED_TEST(BIT(HDMI_COLORSPACE_YUV420), false, -EINVAL), 655 + YUV420_ALLOWED_TEST(BIT(HDMI_COLORSPACE_YUV422), true, -EINVAL), 656 + YUV420_ALLOWED_TEST(BIT(HDMI_COLORSPACE_YUV422), false, 0), 657 + }; 658 + 659 + static void 660 + drm_connector_hdmi_init_formats_yuv420_allowed_desc(const struct drm_connector_hdmi_init_formats_yuv420_allowed_test *t, 661 + char *desc) 662 + { 663 + sprintf(desc, "supported_formats=0x%lx yuv420_allowed=%d", 664 + t->supported_formats, t->yuv420_allowed); 665 + } 666 + 667 + KUNIT_ARRAY_PARAM(drm_connector_hdmi_init_formats_yuv420_allowed, 668 + drm_connector_hdmi_init_formats_yuv420_allowed_tests, 669 + drm_connector_hdmi_init_formats_yuv420_allowed_desc); 670 + 671 + /* 672 + * Test that the registration of an HDMI connector succeeds only when 673 + * the presence of YUV420 in the supported formats matches the value 674 + * of the ycbcr_420_allowed flag. 675 + */ 676 + static void drm_test_connector_hdmi_init_formats_yuv420_allowed(struct kunit *test) 677 + { 678 + const struct drm_connector_hdmi_init_formats_yuv420_allowed_test *params; 679 + struct drm_connector_init_priv *priv = test->priv; 680 + int ret; 681 + 682 + params = test->param_value; 683 + priv->connector.ycbcr_420_allowed = params->yuv420_allowed; 684 + 685 + ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, 686 + "Vendor", "Product", 687 + &dummy_funcs, 688 + &dummy_hdmi_funcs, 689 + DRM_MODE_CONNECTOR_HDMIA, 690 + &priv->ddc, 691 + params->supported_formats, 692 + 8); 693 + KUNIT_EXPECT_EQ(test, ret, params->expected_result); 694 + } 695 + 638 696 /* 639 697 * Test that the registration of an HDMI connector with an HDMI 640 698 * connector type succeeds. ··· 784 726 KUNIT_CASE(drm_test_connector_hdmi_init_bpc_null), 785 727 KUNIT_CASE(drm_test_connector_hdmi_init_formats_empty), 786 728 KUNIT_CASE(drm_test_connector_hdmi_init_formats_no_rgb), 729 + KUNIT_CASE_PARAM(drm_test_connector_hdmi_init_formats_yuv420_allowed, 730 + drm_connector_hdmi_init_formats_yuv420_allowed_gen_params), 787 731 KUNIT_CASE(drm_test_connector_hdmi_init_null_ddc), 788 732 KUNIT_CASE(drm_test_connector_hdmi_init_null_product), 789 733 KUNIT_CASE(drm_test_connector_hdmi_init_null_vendor),
+1 -2
drivers/gpu/drm/tests/drm_kunit_helpers.c
··· 320 320 } 321 321 322 322 /** 323 - * drm_kunit_display_mode_from_cea_vic() - return a mode for CEA VIC 324 - for a KUnit test 323 + * drm_kunit_display_mode_from_cea_vic() - return a mode for CEA VIC for a KUnit test 325 324 * @test: The test context object 326 325 * @dev: DRM device 327 326 * @video_code: CEA VIC of the mode
+4
drivers/gpu/drm/v3d/v3d_irq.c
··· 108 108 v3d_job_update_stats(&v3d->bin_job->base, V3D_BIN); 109 109 trace_v3d_bcl_irq(&v3d->drm, fence->seqno); 110 110 dma_fence_signal(&fence->base); 111 + v3d->bin_job = NULL; 111 112 status = IRQ_HANDLED; 112 113 } 113 114 ··· 119 118 v3d_job_update_stats(&v3d->render_job->base, V3D_RENDER); 120 119 trace_v3d_rcl_irq(&v3d->drm, fence->seqno); 121 120 dma_fence_signal(&fence->base); 121 + v3d->render_job = NULL; 122 122 status = IRQ_HANDLED; 123 123 } 124 124 ··· 130 128 v3d_job_update_stats(&v3d->csd_job->base, V3D_CSD); 131 129 trace_v3d_csd_irq(&v3d->drm, fence->seqno); 132 130 dma_fence_signal(&fence->base); 131 + v3d->csd_job = NULL; 133 132 status = IRQ_HANDLED; 134 133 } 135 134 ··· 168 165 v3d_job_update_stats(&v3d->tfu_job->base, V3D_TFU); 169 166 trace_v3d_tfu_irq(&v3d->drm, fence->seqno); 170 167 dma_fence_signal(&fence->base); 168 + v3d->tfu_job = NULL; 171 169 status = IRQ_HANDLED; 172 170 } 173 171
+2 -2
drivers/gpu/drm/vmwgfx/vmwgfx_bo.c
··· 228 228 VMW_BO_DOMAIN_VRAM, 229 229 VMW_BO_DOMAIN_VRAM); 230 230 buf->places[0].lpfn = PFN_UP(bo->resource->size); 231 - buf->busy_places[0].lpfn = PFN_UP(bo->resource->size); 232 231 ret = ttm_bo_validate(bo, &buf->placement, &ctx); 233 232 234 233 /* For some reason we didn't end up at the start of vram */ ··· 442 443 443 444 if (params->pin) 444 445 ttm_bo_pin(&vmw_bo->tbo); 445 - ttm_bo_unreserve(&vmw_bo->tbo); 446 + if (!params->keep_resv) 447 + ttm_bo_unreserve(&vmw_bo->tbo); 446 448 447 449 return 0; 448 450 }
+2 -2
drivers/gpu/drm/vmwgfx/vmwgfx_bo.h
··· 56 56 u32 domain; 57 57 u32 busy_domain; 58 58 enum ttm_bo_type bo_type; 59 - size_t size; 60 59 bool pin; 60 + bool keep_resv; 61 + size_t size; 61 62 struct dma_resv *resv; 62 63 struct sg_table *sg; 63 64 }; ··· 84 83 85 84 struct ttm_placement placement; 86 85 struct ttm_place places[5]; 87 - struct ttm_place busy_places[5]; 88 86 89 87 /* Protected by reservation */ 90 88 struct ttm_bo_kmap_obj map;
+2 -5
drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
··· 403 403 .busy_domain = VMW_BO_DOMAIN_SYS, 404 404 .bo_type = ttm_bo_type_kernel, 405 405 .size = PAGE_SIZE, 406 - .pin = true 406 + .pin = true, 407 + .keep_resv = true, 407 408 }; 408 409 409 410 /* ··· 415 414 ret = vmw_bo_create(dev_priv, &bo_params, &vbo); 416 415 if (unlikely(ret != 0)) 417 416 return ret; 418 - 419 - ret = ttm_bo_reserve(&vbo->tbo, false, true, NULL); 420 - BUG_ON(ret != 0); 421 - vmw_bo_pin_reserved(vbo, true); 422 417 423 418 ret = ttm_bo_kmap(&vbo->tbo, 0, 1, &map); 424 419 if (likely(ret == 0)) {
+1
drivers/gpu/drm/vmwgfx/vmwgfx_gem.c
··· 206 206 .bo_type = ttm_bo_type_sg, 207 207 .size = attach->dmabuf->size, 208 208 .pin = false, 209 + .keep_resv = true, 209 210 .resv = attach->dmabuf->resv, 210 211 .sg = table, 211 212
+15 -5
drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
··· 750 750 struct vmw_plane_state *old_vps = vmw_plane_state_to_vps(old_state); 751 751 struct vmw_bo *old_bo = NULL; 752 752 struct vmw_bo *new_bo = NULL; 753 + struct ww_acquire_ctx ctx; 753 754 s32 hotspot_x, hotspot_y; 754 755 int ret; 755 756 ··· 770 769 if (du->cursor_surface) 771 770 du->cursor_age = du->cursor_surface->snooper.age; 772 771 772 + ww_acquire_init(&ctx, &reservation_ww_class); 773 + 773 774 if (!vmw_user_object_is_null(&old_vps->uo)) { 774 775 old_bo = vmw_user_object_buffer(&old_vps->uo); 775 - ret = ttm_bo_reserve(&old_bo->tbo, false, false, NULL); 776 + ret = ttm_bo_reserve(&old_bo->tbo, false, false, &ctx); 776 777 if (ret != 0) 777 778 return; 778 779 } ··· 782 779 if (!vmw_user_object_is_null(&vps->uo)) { 783 780 new_bo = vmw_user_object_buffer(&vps->uo); 784 781 if (old_bo != new_bo) { 785 - ret = ttm_bo_reserve(&new_bo->tbo, false, false, NULL); 786 - if (ret != 0) 782 + ret = ttm_bo_reserve(&new_bo->tbo, false, false, &ctx); 783 + if (ret != 0) { 784 + if (old_bo) { 785 + ttm_bo_unreserve(&old_bo->tbo); 786 + ww_acquire_fini(&ctx); 787 + } 787 788 return; 789 + } 788 790 } else { 789 791 new_bo = NULL; 790 792 } ··· 811 803 hotspot_x, hotspot_y); 812 804 } 813 805 814 - if (old_bo) 815 - ttm_bo_unreserve(&old_bo->tbo); 816 806 if (new_bo) 817 807 ttm_bo_unreserve(&new_bo->tbo); 808 + if (old_bo) 809 + ttm_bo_unreserve(&old_bo->tbo); 810 + 811 + ww_acquire_fini(&ctx); 818 812 819 813 du->cursor_x = new_state->crtc_x + du->set_gui_x; 820 814 du->cursor_y = new_state->crtc_y + du->set_gui_y;
+2 -5
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 = true, 900 + .keep_resv = true, 900 901 }; 901 902 902 903 if (!vmw_shader_id_ok(user_key, shader_type)) ··· 906 905 ret = vmw_bo_create(dev_priv, &bo_params, &buf); 907 906 if (unlikely(ret != 0)) 908 907 goto out; 909 - 910 - ret = ttm_bo_reserve(&buf->tbo, false, true, NULL); 911 - if (unlikely(ret != 0)) 912 - goto no_reserve; 913 908 914 909 /* Map and copy shader bytecode. */ 915 910 ret = ttm_bo_kmap(&buf->tbo, 0, PFN_UP(size), &map);
+2 -3
drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c
··· 572 572 .busy_domain = domain, 573 573 .bo_type = ttm_bo_type_kernel, 574 574 .size = bo_size, 575 - .pin = true 575 + .pin = true, 576 + .keep_resv = true, 576 577 }; 577 578 578 579 ret = vmw_bo_create(dev_priv, &bo_params, &vbo); 579 580 if (unlikely(ret != 0)) 580 581 return ret; 581 582 582 - ret = ttm_bo_reserve(&vbo->tbo, false, true, NULL); 583 - BUG_ON(ret != 0); 584 583 ret = vmw_ttm_populate(vbo->tbo.bdev, vbo->tbo.ttm, &ctx); 585 584 if (likely(ret == 0)) { 586 585 struct vmw_ttm_tt *vmw_tt =