Commit e92e11b4 authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge tag 'drm-misc-fixes-2025-02-06' of...

Merge tag 'drm-misc-fixes-2025-02-06' of https://gitlab.freedesktop.org/drm/misc/kernel

 into drm-fixes

A couple of fixes for ivpu to error handling, komeda for format
handling, AST DP timeout fix when enabling the output, locking fix for
zynqmp DP support, tiled format handling in drm/client, and refcounting
fix for bochs

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

From: Maxime Ripard <mripard@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20250206-encouraging-judicious-quoll-adc1dc@houat
parents f2e6f002 2c1ed907
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -21,6 +21,11 @@

#define AMDXDNA_AUTOSUSPEND_DELAY	5000 /* milliseconds */

MODULE_FIRMWARE("amdnpu/1502_00/npu.sbin");
MODULE_FIRMWARE("amdnpu/17f0_10/npu.sbin");
MODULE_FIRMWARE("amdnpu/17f0_11/npu.sbin");
MODULE_FIRMWARE("amdnpu/17f0_20/npu.sbin");

/*
 * Bind the driver base on (vendor_id, device_id) pair and later use the
 * (device_id, rev_id) pair as a key to select the devices. The devices with
+6 −2
Original line number Diff line number Diff line
@@ -397,15 +397,19 @@ int ivpu_boot(struct ivpu_device *vdev)
	if (ivpu_fw_is_cold_boot(vdev)) {
		ret = ivpu_pm_dct_init(vdev);
		if (ret)
			goto err_diagnose_failure;
			goto err_disable_ipc;

		ret = ivpu_hw_sched_init(vdev);
		if (ret)
			goto err_diagnose_failure;
			goto err_disable_ipc;
	}

	return 0;

err_disable_ipc:
	ivpu_ipc_disable(vdev);
	ivpu_hw_irq_disable(vdev);
	disable_irq(vdev->irq);
err_diagnose_failure:
	ivpu_hw_diagnose_failure(vdev);
	ivpu_mmu_evtq_dump(vdev);
+47 −37
Original line number Diff line number Diff line
@@ -115,41 +115,57 @@ static int ivpu_resume(struct ivpu_device *vdev)
	return ret;
}

static void ivpu_pm_recovery_work(struct work_struct *work)
static void ivpu_pm_reset_begin(struct ivpu_device *vdev)
{
	struct ivpu_pm_info *pm = container_of(work, struct ivpu_pm_info, recovery_work);
	struct ivpu_device *vdev = pm->vdev;
	char *evt[2] = {"IVPU_PM_EVENT=IVPU_RECOVER", NULL};
	int ret;

	ivpu_err(vdev, "Recovering the NPU (reset #%d)\n", atomic_read(&vdev->pm->reset_counter));

	ret = pm_runtime_resume_and_get(vdev->drm.dev);
	if (ret)
		ivpu_err(vdev, "Failed to resume NPU: %d\n", ret);

	ivpu_jsm_state_dump(vdev);
	ivpu_dev_coredump(vdev);
	pm_runtime_disable(vdev->drm.dev);

	atomic_inc(&vdev->pm->reset_counter);
	atomic_set(&vdev->pm->reset_pending, 1);
	down_write(&vdev->pm->reset_lock);
}

static void ivpu_pm_reset_complete(struct ivpu_device *vdev)
{
	int ret;

	ivpu_suspend(vdev);
	ivpu_pm_prepare_cold_boot(vdev);
	ivpu_jobs_abort_all(vdev);
	ivpu_ms_cleanup_all(vdev);

	ret = ivpu_resume(vdev);
	if (ret)
	if (ret) {
		ivpu_err(vdev, "Failed to resume NPU: %d\n", ret);
		pm_runtime_set_suspended(vdev->drm.dev);
	} else {
		pm_runtime_set_active(vdev->drm.dev);
	}

	up_write(&vdev->pm->reset_lock);
	atomic_set(&vdev->pm->reset_pending, 0);

	kobject_uevent_env(&vdev->drm.dev->kobj, KOBJ_CHANGE, evt);
	pm_runtime_mark_last_busy(vdev->drm.dev);
	pm_runtime_put_autosuspend(vdev->drm.dev);
	pm_runtime_enable(vdev->drm.dev);
}

static void ivpu_pm_recovery_work(struct work_struct *work)
{
	struct ivpu_pm_info *pm = container_of(work, struct ivpu_pm_info, recovery_work);
	struct ivpu_device *vdev = pm->vdev;
	char *evt[2] = {"IVPU_PM_EVENT=IVPU_RECOVER", NULL};

	ivpu_err(vdev, "Recovering the NPU (reset #%d)\n", atomic_read(&vdev->pm->reset_counter));

	ivpu_pm_reset_begin(vdev);

	if (!pm_runtime_status_suspended(vdev->drm.dev)) {
		ivpu_jsm_state_dump(vdev);
		ivpu_dev_coredump(vdev);
		ivpu_suspend(vdev);
	}

	ivpu_pm_reset_complete(vdev);

	kobject_uevent_env(&vdev->drm.dev->kobj, KOBJ_CHANGE, evt);
}

void ivpu_pm_trigger_recovery(struct ivpu_device *vdev, const char *reason)
@@ -309,7 +325,10 @@ int ivpu_rpm_get(struct ivpu_device *vdev)
	int ret;

	ret = pm_runtime_resume_and_get(vdev->drm.dev);
	drm_WARN_ON(&vdev->drm, ret < 0);
	if (ret < 0) {
		ivpu_err(vdev, "Failed to resume NPU: %d\n", ret);
		pm_runtime_set_suspended(vdev->drm.dev);
	}

	return ret;
}
@@ -325,16 +344,13 @@ void ivpu_pm_reset_prepare_cb(struct pci_dev *pdev)
	struct ivpu_device *vdev = pci_get_drvdata(pdev);

	ivpu_dbg(vdev, PM, "Pre-reset..\n");
	atomic_inc(&vdev->pm->reset_counter);
	atomic_set(&vdev->pm->reset_pending, 1);

	pm_runtime_get_sync(vdev->drm.dev);
	down_write(&vdev->pm->reset_lock);
	ivpu_pm_reset_begin(vdev);

	if (!pm_runtime_status_suspended(vdev->drm.dev)) {
		ivpu_prepare_for_reset(vdev);
		ivpu_hw_reset(vdev);
	ivpu_pm_prepare_cold_boot(vdev);
	ivpu_jobs_abort_all(vdev);
	ivpu_ms_cleanup_all(vdev);
	}

	ivpu_dbg(vdev, PM, "Pre-reset done.\n");
}
@@ -342,18 +358,12 @@ void ivpu_pm_reset_prepare_cb(struct pci_dev *pdev)
void ivpu_pm_reset_done_cb(struct pci_dev *pdev)
{
	struct ivpu_device *vdev = pci_get_drvdata(pdev);
	int ret;

	ivpu_dbg(vdev, PM, "Post-reset..\n");
	ret = ivpu_resume(vdev);
	if (ret)
		ivpu_err(vdev, "Failed to set RESUME state: %d\n", ret);
	up_write(&vdev->pm->reset_lock);
	atomic_set(&vdev->pm->reset_pending, 0);
	ivpu_dbg(vdev, PM, "Post-reset done.\n");

	pm_runtime_mark_last_busy(vdev->drm.dev);
	pm_runtime_put_autosuspend(vdev->drm.dev);
	ivpu_pm_reset_complete(vdev);

	ivpu_dbg(vdev, PM, "Post-reset done.\n");
}

void ivpu_pm_init(struct ivpu_device *vdev)
+4 −0
Original line number Diff line number Diff line
@@ -160,6 +160,10 @@ static int komeda_wb_connector_add(struct komeda_kms_dev *kms,
	formats = komeda_get_layer_fourcc_list(&mdev->fmt_tbl,
					       kwb_conn->wb_layer->layer_type,
					       &n_formats);
	if (!formats) {
		kfree(kwb_conn);
		return -ENOMEM;
	}

	err = drm_writeback_connector_init(&kms->base, wb_conn,
					   &komeda_wb_connector_funcs,
+1 −1
Original line number Diff line number Diff line
@@ -195,7 +195,7 @@ static bool __ast_dp_wait_enable(struct ast_device *ast, bool enabled)
	if (enabled)
		vgacrdf_test |= AST_IO_VGACRDF_DP_VIDEO_ENABLE;

	for (i = 0; i < 200; ++i) {
	for (i = 0; i < 1000; ++i) {
		if (i)
			mdelay(1);
		vgacrdf = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xdf,
Loading