Commit ea34704d authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'drm-fixes-2025-05-10' of https://gitlab.freedesktop.org/drm/kernel

Pull drm fixes from Dave Airlie:
 "Weekly drm fixes, bit bigger than last week, but overall amdgpu/xe
  with some ivpu bits and a random few fixes, and dropping the
  ttm_backup struct which wrapped struct file and was recently
  frowned at.

  drm:
   - Fix overflow when generating wedged event

  ttm:
   - Fix documentation
   - Remove struct ttm_backup

  panel:
   - simple: Fix timings for AUO G101EVN010

  amdgpu:
   - DC FP fixes
   - Freesync fix
   - DMUB AUX fixes
   - VCN fix
   - Hibernation fixes
   - HDP fixes

  xe:
   - Prevent PF queue overflow
   - Hold all forcewake during mocs test
   - Remove GSC flush on reset path
   - Fix forcewake put on error path
   - Fix runtime warning when building without svm

  i915:
   - Fix oops on resume after disconnecting DP MST sinks during suspend
   - Fix SPLC num_waiters refcounting

  ivpu:
   - Increase timeouts
   - Fix deadlock in cmdq ioctl
   - Unlock mutices in correct order

  v3d:
   - Avoid memory leak in job handling"

* tag 'drm-fixes-2025-05-10' of https://gitlab.freedesktop.org/drm/kernel: (32 commits)
  drm/i915/dp: Fix determining SST/MST mode during MTP TU state computation
  drm/xe: Add config control for svm flush work
  drm/xe: Release force wake first then runtime power
  drm/xe/gsc: do not flush the GSC worker from the reset path
  drm/xe/tests/mocs: Hold XE_FORCEWAKE_ALL for LNCF regs
  drm/xe: Add page queue multiplier
  drm/amdgpu/hdp7: use memcfg register to post the write for HDP flush
  drm/amdgpu/hdp6: use memcfg register to post the write for HDP flush
  drm/amdgpu/hdp5.2: use memcfg register to post the write for HDP flush
  drm/amdgpu/hdp5: use memcfg register to post the write for HDP flush
  drm/amdgpu/hdp4: use memcfg register to post the write for HDP flush
  drm/amdgpu: fix pm notifier handling
  Revert "drm/amd: Stop evicting resources on APUs in suspend"
  drm/amdgpu/vcn: using separate VCN1_AON_SOC offset
  drm/amd/display: Fix wrong handling for AUX_DEFER case
  drm/amd/display: Copy AUX read reply data whenever length > 0
  drm/amd/display: Remove incorrect checking in dmub aux handler
  drm/amd/display: Fix the checking condition in dmub aux handling
  drm/amd/display: Shift DMUB AUX reply command if necessary
  drm/amd/display: Call FP Protect Before Mode Programming/Mode Support
  ...
parents 50358c25 c2c64ed0
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -119,7 +119,7 @@ static void timeouts_init(struct ivpu_device *vdev)
		else
			vdev->timeout.autosuspend = 100;
		vdev->timeout.d0i3_entry_msg = 5;
		vdev->timeout.state_dump_msg = 10;
		vdev->timeout.state_dump_msg = 100;
	}
}

+25 −10
Original line number Diff line number Diff line
@@ -681,8 +681,8 @@ static int ivpu_job_submit(struct ivpu_job *job, u8 priority, u32 cmdq_id)
err_erase_xa:
	xa_erase(&vdev->submitted_jobs_xa, job->job_id);
err_unlock:
	mutex_unlock(&vdev->submitted_jobs_lock);
	mutex_unlock(&file_priv->lock);
	mutex_unlock(&vdev->submitted_jobs_lock);
	ivpu_rpm_put(vdev);
	return ret;
}
@@ -874,15 +874,21 @@ int ivpu_cmdq_submit_ioctl(struct drm_device *dev, void *data, struct drm_file *
int ivpu_cmdq_create_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
{
	struct ivpu_file_priv *file_priv = file->driver_priv;
	struct ivpu_device *vdev = file_priv->vdev;
	struct drm_ivpu_cmdq_create *args = data;
	struct ivpu_cmdq *cmdq;
	int ret;

	if (!ivpu_is_capable(file_priv->vdev, DRM_IVPU_CAP_MANAGE_CMDQ))
	if (!ivpu_is_capable(vdev, DRM_IVPU_CAP_MANAGE_CMDQ))
		return -ENODEV;

	if (args->priority > DRM_IVPU_JOB_PRIORITY_REALTIME)
		return -EINVAL;

	ret = ivpu_rpm_get(vdev);
	if (ret < 0)
		return ret;

	mutex_lock(&file_priv->lock);

	cmdq = ivpu_cmdq_create(file_priv, ivpu_job_to_jsm_priority(args->priority), false);
@@ -891,6 +897,8 @@ int ivpu_cmdq_create_ioctl(struct drm_device *dev, void *data, struct drm_file *

	mutex_unlock(&file_priv->lock);

	ivpu_rpm_put(vdev);

	return cmdq ? 0 : -ENOMEM;
}

@@ -900,28 +908,35 @@ int ivpu_cmdq_destroy_ioctl(struct drm_device *dev, void *data, struct drm_file
	struct ivpu_device *vdev = file_priv->vdev;
	struct drm_ivpu_cmdq_destroy *args = data;
	struct ivpu_cmdq *cmdq;
	u32 cmdq_id;
	u32 cmdq_id = 0;
	int ret;

	if (!ivpu_is_capable(vdev, DRM_IVPU_CAP_MANAGE_CMDQ))
		return -ENODEV;

	ret = ivpu_rpm_get(vdev);
	if (ret < 0)
		return ret;

	mutex_lock(&file_priv->lock);

	cmdq = xa_load(&file_priv->cmdq_xa, args->cmdq_id);
	if (!cmdq || cmdq->is_legacy) {
		ret = -ENOENT;
		goto err_unlock;
	}

	} else {
		cmdq_id = cmdq->id;
		ivpu_cmdq_destroy(file_priv, cmdq);
		ret = 0;
	}

	mutex_unlock(&file_priv->lock);

	/* Abort any pending jobs only if cmdq was destroyed */
	if (!ret)
		ivpu_cmdq_abort_all_jobs(vdev, file_priv->ctx.id, cmdq_id);
	return 0;

err_unlock:
	mutex_unlock(&file_priv->lock);
	ivpu_rpm_put(vdev);

	return ret;
}

+0 −2
Original line number Diff line number Diff line
@@ -1614,11 +1614,9 @@ static inline void amdgpu_acpi_get_backlight_caps(struct amdgpu_dm_backlight_cap
#if defined(CONFIG_ACPI) && defined(CONFIG_SUSPEND)
bool amdgpu_acpi_is_s3_active(struct amdgpu_device *adev);
bool amdgpu_acpi_is_s0ix_active(struct amdgpu_device *adev);
void amdgpu_choose_low_power_state(struct amdgpu_device *adev);
#else
static inline bool amdgpu_acpi_is_s0ix_active(struct amdgpu_device *adev) { return false; }
static inline bool amdgpu_acpi_is_s3_active(struct amdgpu_device *adev) { return false; }
static inline void amdgpu_choose_low_power_state(struct amdgpu_device *adev) { }
#endif

void amdgpu_register_gpu_instance(struct amdgpu_device *adev);
+0 −18
Original line number Diff line number Diff line
@@ -1533,22 +1533,4 @@ bool amdgpu_acpi_is_s0ix_active(struct amdgpu_device *adev)
#endif /* CONFIG_AMD_PMC */
}

/**
 * amdgpu_choose_low_power_state
 *
 * @adev: amdgpu_device_pointer
 *
 * Choose the target low power state for the GPU
 */
void amdgpu_choose_low_power_state(struct amdgpu_device *adev)
{
	if (adev->in_runpm)
		return;

	if (amdgpu_acpi_is_s0ix_active(adev))
		adev->in_s0ix = true;
	else if (amdgpu_acpi_is_s3_active(adev))
		adev->in_s3 = true;
}

#endif /* CONFIG_SUSPEND */
+7 −22
Original line number Diff line number Diff line
@@ -4907,28 +4907,20 @@ static int amdgpu_device_evict_resources(struct amdgpu_device *adev)
 * @data: data
 *
 * This function is called when the system is about to suspend or hibernate.
 * It is used to evict resources from the device before the system goes to
 * sleep while there is still access to swap.
 * It is used to set the appropriate flags so that eviction can be optimized
 * in the pm prepare callback.
 */
static int amdgpu_device_pm_notifier(struct notifier_block *nb, unsigned long mode,
				     void *data)
{
	struct amdgpu_device *adev = container_of(nb, struct amdgpu_device, pm_nb);
	int r;

	switch (mode) {
	case PM_HIBERNATION_PREPARE:
		adev->in_s4 = true;
		fallthrough;
	case PM_SUSPEND_PREPARE:
		r = amdgpu_device_evict_resources(adev);
		/*
		 * This is considered non-fatal at this time because
		 * amdgpu_device_prepare() will also fatally evict resources.
		 * See https://gitlab.freedesktop.org/drm/amd/-/issues/3781
		 */
		if (r)
			drm_warn(adev_to_drm(adev), "Failed to evict resources, freeze active processes if problems occur: %d\n", r);
		break;
	case PM_POST_HIBERNATION:
		adev->in_s4 = false;
		break;
	}

@@ -4949,15 +4941,13 @@ int amdgpu_device_prepare(struct drm_device *dev)
	struct amdgpu_device *adev = drm_to_adev(dev);
	int i, r;

	amdgpu_choose_low_power_state(adev);

	if (dev->switch_power_state == DRM_SWITCH_POWER_OFF)
		return 0;

	/* Evict the majority of BOs before starting suspend sequence */
	r = amdgpu_device_evict_resources(adev);
	if (r)
		goto unprepare;
		return r;

	flush_delayed_work(&adev->gfx.gfx_off_delay_work);

@@ -4968,15 +4958,10 @@ int amdgpu_device_prepare(struct drm_device *dev)
			continue;
		r = adev->ip_blocks[i].version->funcs->prepare_suspend(&adev->ip_blocks[i]);
		if (r)
			goto unprepare;
			return r;
	}

	return 0;

unprepare:
	adev->in_s0ix = adev->in_s3 = adev->in_s4 = false;

	return r;
}

/**
Loading