Skip to content

Commit 9dd1f5f

Browse files
committed
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
2 parents 52456a6 + b91a565 commit 9dd1f5f

16 files changed

Lines changed: 203 additions & 149 deletions

File tree

drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ struct dw_hdmi_qp {
163163

164164
unsigned long ref_clk_rate;
165165
struct regmap *regm;
166+
int main_irq;
166167

167168
unsigned long tmds_char_rate;
168169
};
@@ -1271,6 +1272,7 @@ struct dw_hdmi_qp *dw_hdmi_qp_bind(struct platform_device *pdev,
12711272

12721273
dw_hdmi_qp_init_hw(hdmi);
12731274

1275+
hdmi->main_irq = plat_data->main_irq;
12741276
ret = devm_request_threaded_irq(dev, plat_data->main_irq,
12751277
dw_hdmi_qp_main_hardirq, NULL,
12761278
IRQF_SHARED, dev_name(dev), hdmi);
@@ -1331,9 +1333,16 @@ struct dw_hdmi_qp *dw_hdmi_qp_bind(struct platform_device *pdev,
13311333
}
13321334
EXPORT_SYMBOL_GPL(dw_hdmi_qp_bind);
13331335

1336+
void dw_hdmi_qp_suspend(struct device *dev, struct dw_hdmi_qp *hdmi)
1337+
{
1338+
disable_irq(hdmi->main_irq);
1339+
}
1340+
EXPORT_SYMBOL_GPL(dw_hdmi_qp_suspend);
1341+
13341342
void dw_hdmi_qp_resume(struct device *dev, struct dw_hdmi_qp *hdmi)
13351343
{
13361344
dw_hdmi_qp_init_hw(hdmi);
1345+
enable_irq(hdmi->main_irq);
13371346
}
13381347
EXPORT_SYMBOL_GPL(dw_hdmi_qp_resume);
13391348

drivers/gpu/drm/drm_gpuvm.c

Lines changed: 48 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1602,14 +1602,48 @@ drm_gpuvm_bo_create(struct drm_gpuvm *gpuvm,
16021602
}
16031603
EXPORT_SYMBOL_GPL(drm_gpuvm_bo_create);
16041604

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+
*/
1616+
static void
1617+
drm_gpuvm_bo_destroy_not_in_lists(struct drm_gpuvm_bo *vm_bo)
1618+
{
1619+
struct drm_gpuvm *gpuvm = vm_bo->vm;
1620+
const struct drm_gpuvm_ops *ops = gpuvm->ops;
1621+
struct drm_gem_object *obj = vm_bo->obj;
1622+
1623+
if (ops && ops->vm_bo_free)
1624+
ops->vm_bo_free(vm_bo);
1625+
else
1626+
kfree(vm_bo);
1627+
1628+
drm_gpuvm_put(gpuvm);
1629+
drm_gem_object_put(obj);
1630+
}
1631+
1632+
static void
1633+
drm_gpuvm_bo_destroy_not_in_lists_kref(struct kref *kref)
1634+
{
1635+
struct drm_gpuvm_bo *vm_bo = container_of(kref, struct drm_gpuvm_bo,
1636+
kref);
1637+
1638+
drm_gpuvm_bo_destroy_not_in_lists(vm_bo);
1639+
}
1640+
16051641
static void
16061642
drm_gpuvm_bo_destroy(struct kref *kref)
16071643
{
16081644
struct drm_gpuvm_bo *vm_bo = container_of(kref, struct drm_gpuvm_bo,
16091645
kref);
16101646
struct drm_gpuvm *gpuvm = vm_bo->vm;
1611-
const struct drm_gpuvm_ops *ops = gpuvm->ops;
1612-
struct drm_gem_object *obj = vm_bo->obj;
16131647
bool lock = !drm_gpuvm_resv_protected(gpuvm);
16141648

16151649
if (!lock)
@@ -1618,16 +1652,10 @@ drm_gpuvm_bo_destroy(struct kref *kref)
16181652
drm_gpuvm_bo_list_del(vm_bo, extobj, lock);
16191653
drm_gpuvm_bo_list_del(vm_bo, evict, lock);
16201654

1621-
drm_gem_gpuva_assert_lock_held(gpuvm, obj);
1655+
drm_gem_gpuva_assert_lock_held(gpuvm, vm_bo->obj);
16221656
list_del(&vm_bo->list.entry.gem);
16231657

1624-
if (ops && ops->vm_bo_free)
1625-
ops->vm_bo_free(vm_bo);
1626-
else
1627-
kfree(vm_bo);
1628-
1629-
drm_gpuvm_put(gpuvm);
1630-
drm_gem_object_put(obj);
1658+
drm_gpuvm_bo_destroy_not_in_lists(vm_bo);
16311659
}
16321660

16331661
/**
@@ -1745,9 +1773,7 @@ EXPORT_SYMBOL_GPL(drm_gpuvm_bo_put_deferred);
17451773
void
17461774
drm_gpuvm_bo_deferred_cleanup(struct drm_gpuvm *gpuvm)
17471775
{
1748-
const struct drm_gpuvm_ops *ops = gpuvm->ops;
17491776
struct drm_gpuvm_bo *vm_bo;
1750-
struct drm_gem_object *obj;
17511777
struct llist_node *bo_defer;
17521778

17531779
bo_defer = llist_del_all(&gpuvm->bo_defer);
@@ -1766,14 +1792,7 @@ drm_gpuvm_bo_deferred_cleanup(struct drm_gpuvm *gpuvm)
17661792
while (bo_defer) {
17671793
vm_bo = llist_entry(bo_defer, struct drm_gpuvm_bo, list.entry.bo_defer);
17681794
bo_defer = bo_defer->next;
1769-
obj = vm_bo->obj;
1770-
if (ops && ops->vm_bo_free)
1771-
ops->vm_bo_free(vm_bo);
1772-
else
1773-
kfree(vm_bo);
1774-
1775-
drm_gpuvm_put(gpuvm);
1776-
drm_gem_object_put(obj);
1795+
drm_gpuvm_bo_destroy_not_in_lists(vm_bo);
17771796
}
17781797
}
17791798
EXPORT_SYMBOL_GPL(drm_gpuvm_bo_deferred_cleanup);
@@ -1861,6 +1880,9 @@ EXPORT_SYMBOL_GPL(drm_gpuvm_bo_obtain);
18611880
* count is decreased. If not found @__vm_bo is returned without further
18621881
* increase of the reference count.
18631882
*
1883+
* The provided @__vm_bo must not already be in the gpuva, evict, or extobj
1884+
* lists prior to calling this method.
1885+
*
18641886
* A new &drm_gpuvm_bo is added to the GEMs gpuva list.
18651887
*
18661888
* Returns: a pointer to the found &drm_gpuvm_bo or @__vm_bo if no existing
@@ -1873,14 +1895,19 @@ drm_gpuvm_bo_obtain_prealloc(struct drm_gpuvm_bo *__vm_bo)
18731895
struct drm_gem_object *obj = __vm_bo->obj;
18741896
struct drm_gpuvm_bo *vm_bo;
18751897

1898+
drm_WARN_ON(gpuvm->drm, !drm_gpuvm_immediate_mode(gpuvm));
1899+
1900+
mutex_lock(&obj->gpuva.lock);
18761901
vm_bo = drm_gpuvm_bo_find(gpuvm, obj);
18771902
if (vm_bo) {
1878-
drm_gpuvm_bo_put(__vm_bo);
1903+
mutex_unlock(&obj->gpuva.lock);
1904+
kref_put(&__vm_bo->kref, drm_gpuvm_bo_destroy_not_in_lists_kref);
18791905
return vm_bo;
18801906
}
18811907

18821908
drm_gem_gpuva_assert_lock_held(gpuvm, obj);
18831909
list_add_tail(&__vm_bo->list.entry.gem, &obj->gpuva.list);
1910+
mutex_unlock(&obj->gpuva.lock);
18841911

18851912
return __vm_bo;
18861913
}

drivers/gpu/drm/gud/gud_pipe.c

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -457,27 +457,20 @@ int gud_plane_atomic_check(struct drm_plane *plane,
457457
struct drm_plane_state *old_plane_state = drm_atomic_get_old_plane_state(state, plane);
458458
struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state, plane);
459459
struct drm_crtc *crtc = new_plane_state->crtc;
460-
struct drm_crtc_state *crtc_state;
460+
struct drm_crtc_state *crtc_state = NULL;
461461
const struct drm_display_mode *mode;
462462
struct drm_framebuffer *old_fb = old_plane_state->fb;
463463
struct drm_connector_state *connector_state = NULL;
464464
struct drm_framebuffer *fb = new_plane_state->fb;
465-
const struct drm_format_info *format = fb->format;
465+
const struct drm_format_info *format;
466466
struct drm_connector *connector;
467467
unsigned int i, num_properties;
468468
struct gud_state_req *req;
469469
int idx, ret;
470470
size_t len;
471471

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);
481474

482475
ret = drm_atomic_helper_check_plane_state(new_plane_state, crtc_state,
483476
DRM_PLANE_NO_SCALING,
@@ -492,6 +485,9 @@ int gud_plane_atomic_check(struct drm_plane *plane,
492485
if (old_plane_state->rotation != new_plane_state->rotation)
493486
crtc_state->mode_changed = true;
494487

488+
mode = &crtc_state->mode;
489+
format = fb->format;
490+
495491
if (old_fb && old_fb->format != format)
496492
crtc_state->mode_changed = true;
497493

@@ -598,7 +594,7 @@ void gud_plane_atomic_update(struct drm_plane *plane,
598594
struct drm_atomic_helper_damage_iter iter;
599595
int ret, idx;
600596

601-
if (crtc->state->mode_changed || !crtc->state->enable) {
597+
if (!crtc || crtc->state->mode_changed || !crtc->state->enable) {
602598
cancel_work_sync(&gdrm->work);
603599
mutex_lock(&gdrm->damage_lock);
604600
if (gdrm->fb) {

drivers/gpu/drm/nouveau/dispnv50/curs507a.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ curs507a_prepare(struct nv50_wndw *wndw, struct nv50_head_atom *asyh,
8484
asyh->curs.handle = handle;
8585
asyh->curs.offset = offset;
8686
asyh->set.curs = asyh->curs.visible;
87+
nv50_atom(asyh->state.state)->lock_core = true;
8788
}
8889
}
8990

drivers/gpu/drm/nouveau/dispnv50/head.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@ nv50_head_flush_clr(struct nv50_head *head,
4343
union nv50_head_atom_mask clr = {
4444
.mask = asyh->clr.mask & ~(flush ? 0 : asyh->set.mask),
4545
};
46+
47+
lockdep_assert_held(&head->disp->mutex);
48+
4649
if (clr.crc) nv50_crc_atomic_clr(head);
4750
if (clr.olut) head->func->olut_clr(head);
4851
if (clr.core) head->func->core_clr(head);
@@ -65,6 +68,8 @@ nv50_head_flush_set_wndw(struct nv50_head *head, struct nv50_head_atom *asyh)
6568
void
6669
nv50_head_flush_set(struct nv50_head *head, struct nv50_head_atom *asyh)
6770
{
71+
lockdep_assert_held(&head->disp->mutex);
72+
6873
if (asyh->set.view ) head->func->view (head, asyh);
6974
if (asyh->set.mode ) head->func->mode (head, asyh);
7075
if (asyh->set.core ) head->func->core_set(head, asyh);

drivers/gpu/drm/panel/panel-simple.c

Lines changed: 45 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -623,49 +623,6 @@ static struct panel_simple *panel_simple_probe(struct device *dev)
623623
if (IS_ERR(desc))
624624
return ERR_CAST(desc);
625625

626-
panel = devm_drm_panel_alloc(dev, struct panel_simple, base,
627-
&panel_simple_funcs, desc->connector_type);
628-
if (IS_ERR(panel))
629-
return ERR_CAST(panel);
630-
631-
panel->desc = desc;
632-
633-
panel->supply = devm_regulator_get(dev, "power");
634-
if (IS_ERR(panel->supply))
635-
return ERR_CAST(panel->supply);
636-
637-
panel->enable_gpio = devm_gpiod_get_optional(dev, "enable",
638-
GPIOD_OUT_LOW);
639-
if (IS_ERR(panel->enable_gpio))
640-
return dev_err_cast_probe(dev, panel->enable_gpio,
641-
"failed to request GPIO\n");
642-
643-
err = of_drm_get_panel_orientation(dev->of_node, &panel->orientation);
644-
if (err) {
645-
dev_err(dev, "%pOF: failed to get orientation %d\n", dev->of_node, err);
646-
return ERR_PTR(err);
647-
}
648-
649-
ddc = of_parse_phandle(dev->of_node, "ddc-i2c-bus", 0);
650-
if (ddc) {
651-
panel->ddc = of_find_i2c_adapter_by_node(ddc);
652-
of_node_put(ddc);
653-
654-
if (!panel->ddc)
655-
return ERR_PTR(-EPROBE_DEFER);
656-
}
657-
658-
if (!of_device_is_compatible(dev->of_node, "panel-dpi") &&
659-
!of_get_display_timing(dev->of_node, "panel-timing", &dt))
660-
panel_simple_parse_panel_timing_node(dev, panel, &dt);
661-
662-
if (desc->connector_type == DRM_MODE_CONNECTOR_LVDS) {
663-
/* Optional data-mapping property for overriding bus format */
664-
err = panel_simple_override_nondefault_lvds_datamapping(dev, panel);
665-
if (err)
666-
goto free_ddc;
667-
}
668-
669626
connector_type = desc->connector_type;
670627
/* Catch common mistakes for panels. */
671628
switch (connector_type) {
@@ -690,8 +647,7 @@ static struct panel_simple *panel_simple_probe(struct device *dev)
690647
break;
691648
case DRM_MODE_CONNECTOR_eDP:
692649
dev_warn(dev, "eDP panels moved to panel-edp\n");
693-
err = -EINVAL;
694-
goto free_ddc;
650+
return ERR_PTR(-EINVAL);
695651
case DRM_MODE_CONNECTOR_DSI:
696652
if (desc->bpc != 6 && desc->bpc != 8)
697653
dev_warn(dev, "Expected bpc in {6,8} but got: %u\n", desc->bpc);
@@ -720,6 +676,49 @@ static struct panel_simple *panel_simple_probe(struct device *dev)
720676
break;
721677
}
722678

679+
panel = devm_drm_panel_alloc(dev, struct panel_simple, base,
680+
&panel_simple_funcs, connector_type);
681+
if (IS_ERR(panel))
682+
return ERR_CAST(panel);
683+
684+
panel->desc = desc;
685+
686+
panel->supply = devm_regulator_get(dev, "power");
687+
if (IS_ERR(panel->supply))
688+
return ERR_CAST(panel->supply);
689+
690+
panel->enable_gpio = devm_gpiod_get_optional(dev, "enable",
691+
GPIOD_OUT_LOW);
692+
if (IS_ERR(panel->enable_gpio))
693+
return dev_err_cast_probe(dev, panel->enable_gpio,
694+
"failed to request GPIO\n");
695+
696+
err = of_drm_get_panel_orientation(dev->of_node, &panel->orientation);
697+
if (err) {
698+
dev_err(dev, "%pOF: failed to get orientation %d\n", dev->of_node, err);
699+
return ERR_PTR(err);
700+
}
701+
702+
ddc = of_parse_phandle(dev->of_node, "ddc-i2c-bus", 0);
703+
if (ddc) {
704+
panel->ddc = of_find_i2c_adapter_by_node(ddc);
705+
of_node_put(ddc);
706+
707+
if (!panel->ddc)
708+
return ERR_PTR(-EPROBE_DEFER);
709+
}
710+
711+
if (!of_device_is_compatible(dev->of_node, "panel-dpi") &&
712+
!of_get_display_timing(dev->of_node, "panel-timing", &dt))
713+
panel_simple_parse_panel_timing_node(dev, panel, &dt);
714+
715+
if (desc->connector_type == DRM_MODE_CONNECTOR_LVDS) {
716+
/* Optional data-mapping property for overriding bus format */
717+
err = panel_simple_override_nondefault_lvds_datamapping(dev, panel);
718+
if (err)
719+
goto free_ddc;
720+
}
721+
723722
dev_set_drvdata(dev, panel);
724723

725724
/*
@@ -1900,6 +1899,7 @@ static const struct panel_desc dataimage_scf0700c48ggu18 = {
19001899
},
19011900
.bus_format = MEDIA_BUS_FMT_RGB888_1X24,
19021901
.bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE,
1902+
.connector_type = DRM_MODE_CONNECTOR_DPI,
19031903
};
19041904

19051905
static const struct display_timing dlc_dlc0700yzg_1_timing = {

drivers/gpu/drm/panthor/panthor_mmu.c

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1252,17 +1252,7 @@ static int panthor_vm_prepare_map_op_ctx(struct panthor_vm_op_ctx *op_ctx,
12521252
goto err_cleanup;
12531253
}
12541254

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);
12631255
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));
12661256

12671257
op_ctx->map.bo_offset = offset;
12681258

0 commit comments

Comments
 (0)