Commit b96a2253 authored by Vasily Khoruzhick's avatar Vasily Khoruzhick Committed by Danilo Krummrich
Browse files

drm/nouveau: don't attempt to schedule hpd_work on headless cards

If the card doesn't have display hardware, hpd_work and hpd_lock are
left uninitialized which causes BUG when attempting to schedule hpd_work
on runtime PM resume.

Fix it by adding headless flag to DRM and skip any hpd if it's set.

Fixes: ae1aadb1 ("nouveau: don't fail driver load if no display hw present.")
Link: https://gitlab.freedesktop.org/drm/nouveau/-/issues/337


Signed-off-by: default avatarVasily Khoruzhick <anarsoul@gmail.com>
Reviewed-by: default avatarBen Skeggs <bskeggs@nvidia.com>
Signed-off-by: default avatarDanilo Krummrich <dakr@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20240607221032.25918-1-anarsoul@gmail.com
parent 31849bf0
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -68,7 +68,7 @@ nv04_display_fini(struct drm_device *dev, bool runtime, bool suspend)
	if (nv_two_heads(dev))
		NVWriteCRTC(dev, 1, NV_PCRTC_INTR_EN_0, 0);

	if (!runtime)
	if (!runtime && !drm->headless)
		cancel_work_sync(&drm->hpd_work);

	if (!suspend)
+1 −1
Original line number Diff line number Diff line
@@ -2680,7 +2680,7 @@ nv50_display_fini(struct drm_device *dev, bool runtime, bool suspend)
			nv50_mstm_fini(nouveau_encoder(encoder));
	}

	if (!runtime)
	if (!runtime && !drm->headless)
		cancel_work_sync(&drm->hpd_work);
}

+5 −1
Original line number Diff line number Diff line
@@ -450,6 +450,9 @@ nouveau_display_hpd_resume(struct drm_device *dev)
{
	struct nouveau_drm *drm = nouveau_drm(dev);

	if (drm->headless)
		return;

	spin_lock_irq(&drm->hpd_lock);
	drm->hpd_pending = ~0;
	spin_unlock_irq(&drm->hpd_lock);
@@ -635,7 +638,7 @@ nouveau_display_fini(struct drm_device *dev, bool suspend, bool runtime)
	}
	drm_connector_list_iter_end(&conn_iter);

	if (!runtime)
	if (!runtime && !drm->headless)
		cancel_work_sync(&drm->hpd_work);

	drm_kms_helper_poll_disable(dev);
@@ -729,6 +732,7 @@ nouveau_display_create(struct drm_device *dev)
		/* no display hw */
		if (ret == -ENODEV) {
			ret = 0;
			drm->headless = true;
			goto disp_create_err;
		}

+1 −0
Original line number Diff line number Diff line
@@ -276,6 +276,7 @@ struct nouveau_drm {
	/* modesetting */
	struct nvbios vbios;
	struct nouveau_display *display;
	bool headless;
	struct work_struct hpd_work;
	spinlock_t hpd_lock;
	u32 hpd_pending;