1
0
Fork 0
mirror of synced 2025-03-06 20:59:54 +01:00

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
 -----BEGIN PGP SIGNATURE-----
 
 iJUEABMJAB0WIQTkHFbLp4ejekA/qfgnX84Zoj2+dgUCZ6R9jwAKCRAnX84Zoj2+
 drO1AYCRRlokrTPy9jqL1EFfpvI7aqq02jA/87CcaDd19DS2phZyx6UEAIMFaXdp
 E+fNafgBgKg5Wi64Ht7gyjJaI+FZv9qSXBo/9YMAk98xGstdT9HJ23nVHSeQ17XV
 HKo7LM3Crw==
 =WODG
 -----END PGP SIGNATURE-----

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: Dave Airlie <airlied@redhat.com>

From: Maxime Ripard <mripard@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20250206-encouraging-judicious-quoll-adc1dc@houat
This commit is contained in:
Dave Airlie 2025-02-07 14:47:11 +10:00
commit e92e11b462
7 changed files with 67 additions and 51 deletions

View file

@ -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

View file

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

View file

@ -115,41 +115,57 @@ err_power_down:
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_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_pm_reset_begin(vdev);
if (!pm_runtime_status_suspended(vdev->drm.dev)) {
ivpu_prepare_for_reset(vdev);
ivpu_hw_reset(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)

View file

@ -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,

View file

@ -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,

View file

@ -311,16 +311,6 @@ void drm_dp_cec_attach(struct drm_dp_aux *aux, u16 source_physical_address)
if (!aux->transfer)
return;
#ifndef CONFIG_MEDIA_CEC_RC
/*
* CEC_CAP_RC is part of CEC_CAP_DEFAULTS, but it is stripped by
* cec_allocate_adapter() if CONFIG_MEDIA_CEC_RC is undefined.
*
* Do this here as well to ensure the tests against cec_caps are
* correct.
*/
cec_caps &= ~CEC_CAP_RC;
#endif
cancel_delayed_work_sync(&aux->cec.unregister_work);
mutex_lock(&aux->cec.lock);
@ -337,7 +327,9 @@ void drm_dp_cec_attach(struct drm_dp_aux *aux, u16 source_physical_address)
num_las = CEC_MAX_LOG_ADDRS;
if (aux->cec.adap) {
if (aux->cec.adap->capabilities == cec_caps &&
/* Check if the adapter properties have changed */
if ((aux->cec.adap->capabilities & CEC_CAP_MONITOR_ALL) ==
(cec_caps & CEC_CAP_MONITOR_ALL) &&
aux->cec.adap->available_log_addrs == num_las) {
/* Unchanged, so just set the phys addr */
cec_s_phys_addr(aux->cec.adap, source_physical_address, false);

View file

@ -32,6 +32,7 @@
#include <linux/dynamic_debug.h>
#include <drm/drm.h>
#include <drm/drm_device.h>
struct debugfs_regset32;
struct drm_device;