Commit 38df7e5e authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge tag 'drm-misc-fixes-2024-02-15' of git://anongit.freedesktop.org/drm/drm-misc into drm-fixes



A suspend/resume error fix for ivpu, a couple of scheduler fixes for
nouveau, a patch to support large page arrays in prime, a uninitialized
variable fix in crtc, a locking fix in rockchip/vop2 and a buddy
allocator error reporting fix.

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

From: Maxime Ripard <mripard@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/b4ffqzigtfh6cgzdpwuk6jlrv3dnk4hu6etiizgvibysqgtl2p@42n2gdfdd5eu
parents 841c3516 a64056bb
Loading
Loading
Loading
Loading
+32 −12
Original line number Diff line number Diff line
@@ -510,16 +510,6 @@ static int ivpu_boot_pwr_domain_enable(struct ivpu_device *vdev)
	return ret;
}

static int ivpu_boot_pwr_domain_disable(struct ivpu_device *vdev)
{
	ivpu_boot_dpu_active_drive(vdev, false);
	ivpu_boot_pwr_island_isolation_drive(vdev, true);
	ivpu_boot_pwr_island_trickle_drive(vdev, false);
	ivpu_boot_pwr_island_drive(vdev, false);

	return ivpu_boot_wait_for_pwr_island_status(vdev, 0x0);
}

static void ivpu_boot_no_snoop_enable(struct ivpu_device *vdev)
{
	u32 val = REGV_RD32(VPU_37XX_HOST_IF_TCU_PTW_OVERRIDES);
@@ -616,12 +606,37 @@ static int ivpu_hw_37xx_info_init(struct ivpu_device *vdev)
	return 0;
}

static int ivpu_hw_37xx_ip_reset(struct ivpu_device *vdev)
{
	int ret;
	u32 val;

	if (IVPU_WA(punit_disabled))
		return 0;

	ret = REGB_POLL_FLD(VPU_37XX_BUTTRESS_VPU_IP_RESET, TRIGGER, 0, TIMEOUT_US);
	if (ret) {
		ivpu_err(vdev, "Timed out waiting for TRIGGER bit\n");
		return ret;
	}

	val = REGB_RD32(VPU_37XX_BUTTRESS_VPU_IP_RESET);
	val = REG_SET_FLD(VPU_37XX_BUTTRESS_VPU_IP_RESET, TRIGGER, val);
	REGB_WR32(VPU_37XX_BUTTRESS_VPU_IP_RESET, val);

	ret = REGB_POLL_FLD(VPU_37XX_BUTTRESS_VPU_IP_RESET, TRIGGER, 0, TIMEOUT_US);
	if (ret)
		ivpu_err(vdev, "Timed out waiting for RESET completion\n");

	return ret;
}

static int ivpu_hw_37xx_reset(struct ivpu_device *vdev)
{
	int ret = 0;

	if (ivpu_boot_pwr_domain_disable(vdev)) {
		ivpu_err(vdev, "Failed to disable power domain\n");
	if (ivpu_hw_37xx_ip_reset(vdev)) {
		ivpu_err(vdev, "Failed to reset NPU\n");
		ret = -EIO;
	}

@@ -661,6 +676,11 @@ static int ivpu_hw_37xx_power_up(struct ivpu_device *vdev)
{
	int ret;

	/* PLL requests may fail when powering down, so issue WP 0 here */
	ret = ivpu_pll_disable(vdev);
	if (ret)
		ivpu_warn(vdev, "Failed to disable PLL: %d\n", ret);

	ret = ivpu_hw_37xx_d0i3_disable(vdev);
	if (ret)
		ivpu_warn(vdev, "Failed to disable D0I3: %d\n", ret);
+22 −17
Original line number Diff line number Diff line
@@ -58,11 +58,14 @@ static int ivpu_suspend(struct ivpu_device *vdev)
{
	int ret;

	/* Save PCI state before powering down as it sometimes gets corrupted if NPU hangs */
	pci_save_state(to_pci_dev(vdev->drm.dev));

	ret = ivpu_shutdown(vdev);
	if (ret) {
	if (ret)
		ivpu_err(vdev, "Failed to shutdown VPU: %d\n", ret);
		return ret;
	}

	pci_set_power_state(to_pci_dev(vdev->drm.dev), PCI_D3hot);

	return ret;
}
@@ -71,6 +74,9 @@ static int ivpu_resume(struct ivpu_device *vdev)
{
	int ret;

	pci_set_power_state(to_pci_dev(vdev->drm.dev), PCI_D0);
	pci_restore_state(to_pci_dev(vdev->drm.dev));

retry:
	ret = ivpu_hw_power_up(vdev);
	if (ret) {
@@ -120,15 +126,20 @@ static void ivpu_pm_recovery_work(struct work_struct *work)

	ivpu_fw_log_dump(vdev);

retry:
	ret = pci_try_reset_function(to_pci_dev(vdev->drm.dev));
	if (ret == -EAGAIN && !drm_dev_is_unplugged(&vdev->drm)) {
		cond_resched();
		goto retry;
	}
	atomic_inc(&vdev->pm->reset_counter);
	atomic_set(&vdev->pm->reset_pending, 1);
	down_write(&vdev->pm->reset_lock);

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

	ret = ivpu_resume(vdev);
	if (ret)
		ivpu_err(vdev, "Failed to resume NPU: %d\n", ret);

	if (ret && ret != -EAGAIN)
		ivpu_err(vdev, "Failed to reset VPU: %d\n", ret);
	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);
@@ -200,9 +211,6 @@ int ivpu_pm_suspend_cb(struct device *dev)
	ivpu_suspend(vdev);
	ivpu_pm_prepare_warm_boot(vdev);

	pci_save_state(to_pci_dev(dev));
	pci_set_power_state(to_pci_dev(dev), PCI_D3hot);

	ivpu_dbg(vdev, PM, "Suspend done.\n");

	return 0;
@@ -216,9 +224,6 @@ int ivpu_pm_resume_cb(struct device *dev)

	ivpu_dbg(vdev, PM, "Resume..\n");

	pci_set_power_state(to_pci_dev(dev), PCI_D0);
	pci_restore_state(to_pci_dev(dev));

	ret = ivpu_resume(vdev);
	if (ret)
		ivpu_err(vdev, "Failed to resume: %d\n", ret);
+6 −0
Original line number Diff line number Diff line
@@ -539,6 +539,12 @@ static int __alloc_range(struct drm_buddy *mm,
	} while (1);

	list_splice_tail(&allocated, blocks);

	if (total_allocated < size) {
		err = -ENOSPC;
		goto err_free;
	}

	return 0;

err_undo:
+1 −0
Original line number Diff line number Diff line
@@ -904,6 +904,7 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
	connector_set = NULL;
	fb = NULL;
	mode = NULL;
	num_connectors = 0;

	DRM_MODESET_LOCK_ALL_END(dev, ctx, ret);

+1 −1
Original line number Diff line number Diff line
@@ -820,7 +820,7 @@ struct sg_table *drm_prime_pages_to_sg(struct drm_device *dev,
	if (max_segment == 0)
		max_segment = UINT_MAX;
	err = sg_alloc_table_from_pages_segment(sg, pages, nr_pages, 0,
						nr_pages << PAGE_SHIFT,
						(unsigned long)nr_pages << PAGE_SHIFT,
						max_segment, GFP_KERNEL);
	if (err) {
		kfree(sg);
Loading