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

Merge tag 'drm-fixes-2020-07-17-1' of git://anongit.freedesktop.org/drm/drm into master

Pull drm fixes from Dave Airlie:
 "Weekly fixes pull, big bigger than I'd normally like, but they are
  fairly scattered and small individually.

  The vmwgfx one is a black screen regression, otherwise the largest is
  an MST encoder fix for amdgpu which results in a WARN in some cases,
  and a scattering of i915 fixes.

  I'm tracking two regressions at the moment that hopefully we get
  nailed down this week for rc7.

  dma-buf:
   - sleeping atomic fix

  amdgpu:
   - Fix a race condition with KIQ
   - Preemption fix
   - Fix handling of fake MST encoders
   - OLED panel fix
   - Handle allocation failure in stream construction
   - Renoir SMC fix
   - SDMA 5.x fix

  i915:
   - FBC w/a stride fix
   - Fix use-after-free fix on module reload
   - Ignore irq enabling on the virtual engines to fix device sleep
   - Use GTT when saving/restoring engine GPR
   - Fix selftest sort function

  vmwgfx:
   - black screen fix

  aspeed:
   - fbcon init warn fix"

* tag 'drm-fixes-2020-07-17-1' of git://anongit.freedesktop.org/drm/drm:
  drm/amdgpu/sdma5: fix wptr overwritten in ->get_wptr()
  drm/amdgpu/powerplay: Modify SMC message name for setting power profile mode
  drm/amd/display: handle failed allocation during stream construction
  drm/amd/display: OLED panel backlight adjust not work with external display connected
  drm/amdgpu/display: create fake mst encoders ahead of time (v4)
  drm/amdgpu: fix preemption unit test
  drm/amdgpu/gfx10: fix race condition for kiq
  drm/i915: Recalculate FBC w/a stride when needed
  drm/i915: Move cec_notifier to intel_hdmi_connector_unregister, v2.
  drm/i915/gt: Only swap to a random sibling once upon creation
  drm/i915/gt: Ignore irq enabling on the virtual engines
  drm/i915/perf: Use GTT when saving/restoring engine GPR
  drm/i915/selftests: Fix compare functions provided for sorting
  drm/vmwgfx: fix update of display surface when resolution changes
  dmabuf: use spinlock to access dmabuf->name
  drm/aspeed: Call drm_fbdev_generic_setup after drm_dev_register
parents 07a56bb8 adbe8a3c
Loading
Loading
Loading
Loading
+7 −4
Original line number Diff line number Diff line
@@ -45,10 +45,10 @@ static char *dmabuffs_dname(struct dentry *dentry, char *buffer, int buflen)
	size_t ret = 0;

	dmabuf = dentry->d_fsdata;
	dma_resv_lock(dmabuf->resv, NULL);
	spin_lock(&dmabuf->name_lock);
	if (dmabuf->name)
		ret = strlcpy(name, dmabuf->name, DMA_BUF_NAME_LEN);
	dma_resv_unlock(dmabuf->resv);
	spin_unlock(&dmabuf->name_lock);

	return dynamic_dname(dentry, buffer, buflen, "/%s:%s",
			     dentry->d_name.name, ret > 0 ? name : "");
@@ -338,8 +338,10 @@ static long dma_buf_set_name(struct dma_buf *dmabuf, const char __user *buf)
		kfree(name);
		goto out_unlock;
	}
	spin_lock(&dmabuf->name_lock);
	kfree(dmabuf->name);
	dmabuf->name = name;
	spin_unlock(&dmabuf->name_lock);

out_unlock:
	dma_resv_unlock(dmabuf->resv);
@@ -402,10 +404,10 @@ static void dma_buf_show_fdinfo(struct seq_file *m, struct file *file)
	/* Don't count the temporary reference taken inside procfs seq_show */
	seq_printf(m, "count:\t%ld\n", file_count(dmabuf->file) - 1);
	seq_printf(m, "exp_name:\t%s\n", dmabuf->exp_name);
	dma_resv_lock(dmabuf->resv, NULL);
	spin_lock(&dmabuf->name_lock);
	if (dmabuf->name)
		seq_printf(m, "name:\t%s\n", dmabuf->name);
	dma_resv_unlock(dmabuf->resv);
	spin_unlock(&dmabuf->name_lock);
}

static const struct file_operations dma_buf_fops = {
@@ -542,6 +544,7 @@ struct dma_buf *dma_buf_export(const struct dma_buf_export_info *exp_info)
	dmabuf->size = exp_info->size;
	dmabuf->exp_name = exp_info->exp_name;
	dmabuf->owner = exp_info->owner;
	spin_lock_init(&dmabuf->name_lock);
	init_waitqueue_head(&dmabuf->poll);
	dmabuf->cb_excl.poll = dmabuf->cb_shared.poll = &dmabuf->poll;
	dmabuf->cb_excl.active = dmabuf->cb_shared.active = 0;
+15 −5
Original line number Diff line number Diff line
@@ -1295,27 +1295,37 @@ static void amdgpu_ib_preempt_job_recovery(struct drm_gpu_scheduler *sched)
static void amdgpu_ib_preempt_mark_partial_job(struct amdgpu_ring *ring)
{
	struct amdgpu_job *job;
	struct drm_sched_job *s_job;
	struct drm_sched_job *s_job, *tmp;
	uint32_t preempt_seq;
	struct dma_fence *fence, **ptr;
	struct amdgpu_fence_driver *drv = &ring->fence_drv;
	struct drm_gpu_scheduler *sched = &ring->sched;
	bool preempted = true;

	if (ring->funcs->type != AMDGPU_RING_TYPE_GFX)
		return;

	preempt_seq = le32_to_cpu(*(drv->cpu_addr + 2));
	if (preempt_seq <= atomic_read(&drv->last_seq))
		return;
	if (preempt_seq <= atomic_read(&drv->last_seq)) {
		preempted = false;
		goto no_preempt;
	}

	preempt_seq &= drv->num_fences_mask;
	ptr = &drv->fences[preempt_seq];
	fence = rcu_dereference_protected(*ptr, 1);

no_preempt:
	spin_lock(&sched->job_list_lock);
	list_for_each_entry(s_job, &sched->ring_mirror_list, node) {
	list_for_each_entry_safe(s_job, tmp, &sched->ring_mirror_list, node) {
		if (dma_fence_is_signaled(&s_job->s_fence->finished)) {
			/* remove job from ring_mirror_list */
			list_del_init(&s_job->node);
			sched->ops->free_job(s_job);
			continue;
		}
		job = to_amdgpu_job(s_job);
		if (job->fence == fence)
		if (preempted && job->fence == fence)
			/* mark the job as preempted */
			job->preemption_status |= AMDGPU_IB_PREEMPTED;
	}
+8 −1
Original line number Diff line number Diff line
@@ -7513,12 +7513,17 @@ static int gfx_v10_0_ring_preempt_ib(struct amdgpu_ring *ring)
	struct amdgpu_device *adev = ring->adev;
	struct amdgpu_kiq *kiq = &adev->gfx.kiq;
	struct amdgpu_ring *kiq_ring = &kiq->ring;
	unsigned long flags;

	if (!kiq->pmf || !kiq->pmf->kiq_unmap_queues)
		return -EINVAL;

	if (amdgpu_ring_alloc(kiq_ring, kiq->pmf->unmap_queues_size))
	spin_lock_irqsave(&kiq->ring_lock, flags);

	if (amdgpu_ring_alloc(kiq_ring, kiq->pmf->unmap_queues_size)) {
		spin_unlock_irqrestore(&kiq->ring_lock, flags);
		return -ENOMEM;
	}

	/* assert preemption condition */
	amdgpu_ring_set_preempt_cond_exec(ring, false);
@@ -7529,6 +7534,8 @@ static int gfx_v10_0_ring_preempt_ib(struct amdgpu_ring *ring)
				   ++ring->trail_seq);
	amdgpu_ring_commit(kiq_ring);

	spin_unlock_irqrestore(&kiq->ring_lock, flags);

	/* poll the trailing fence */
	for (i = 0; i < adev->usec_timeout; i++) {
		if (ring->trail_seq ==
+8 −18
Original line number Diff line number Diff line
@@ -314,30 +314,20 @@ static uint64_t sdma_v5_0_ring_get_rptr(struct amdgpu_ring *ring)
static uint64_t sdma_v5_0_ring_get_wptr(struct amdgpu_ring *ring)
{
	struct amdgpu_device *adev = ring->adev;
	u64 *wptr = NULL;
	uint64_t local_wptr = 0;
	u64 wptr;

	if (ring->use_doorbell) {
		/* XXX check if swapping is necessary on BE */
		wptr = ((u64 *)&adev->wb.wb[ring->wptr_offs]);
		DRM_DEBUG("wptr/doorbell before shift == 0x%016llx\n", *wptr);
		*wptr = (*wptr) >> 2;
		DRM_DEBUG("wptr/doorbell after shift == 0x%016llx\n", *wptr);
		wptr = READ_ONCE(*((u64 *)&adev->wb.wb[ring->wptr_offs]));
		DRM_DEBUG("wptr/doorbell before shift == 0x%016llx\n", wptr);
	} else {
		u32 lowbit, highbit;

		wptr = &local_wptr;
		lowbit = RREG32(sdma_v5_0_get_reg_offset(adev, ring->me, mmSDMA0_GFX_RB_WPTR)) >> 2;
		highbit = RREG32(sdma_v5_0_get_reg_offset(adev, ring->me, mmSDMA0_GFX_RB_WPTR_HI)) >> 2;

		DRM_DEBUG("wptr [%i]high== 0x%08x low==0x%08x\n",
				ring->me, highbit, lowbit);
		*wptr = highbit;
		*wptr = (*wptr) << 32;
		*wptr |= lowbit;
		wptr = RREG32(sdma_v5_0_get_reg_offset(adev, ring->me, mmSDMA0_GFX_RB_WPTR_HI));
		wptr = wptr << 32;
		wptr |= RREG32(sdma_v5_0_get_reg_offset(adev, ring->me, mmSDMA0_GFX_RB_WPTR));
		DRM_DEBUG("wptr before shift [%i] wptr == 0x%016llx\n", ring->me, wptr);
	}

	return *wptr;
	return wptr >> 2;
}

/**
+14 −0
Original line number Diff line number Diff line
@@ -974,6 +974,9 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
	/* Update the actual used number of crtc */
	adev->mode_info.num_crtc = adev->dm.display_indexes_num;

	/* create fake encoders for MST */
	dm_dp_create_fake_mst_encoders(adev);

	/* TODO: Add_display_info? */

	/* TODO use dynamic cursor width */
@@ -997,6 +1000,12 @@ error:

static void amdgpu_dm_fini(struct amdgpu_device *adev)
{
	int i;

	for (i = 0; i < adev->dm.display_indexes_num; i++) {
		drm_encoder_cleanup(&adev->dm.mst_encoders[i].base);
	}

	amdgpu_dm_audio_fini(adev);

	amdgpu_dm_destroy_drm_device(&adev->dm);
@@ -2010,6 +2019,7 @@ static void update_connector_ext_caps(struct amdgpu_dm_connector *aconnector)
	struct amdgpu_display_manager *dm;
	struct drm_connector *conn_base;
	struct amdgpu_device *adev;
	struct dc_link *link = NULL;
	static const u8 pre_computed_values[] = {
		50, 51, 52, 53, 55, 56, 57, 58, 59, 61, 62, 63, 65, 66, 68, 69,
		71, 72, 74, 75, 77, 79, 81, 82, 84, 86, 88, 90, 92, 94, 96, 98};
@@ -2017,6 +2027,10 @@ static void update_connector_ext_caps(struct amdgpu_dm_connector *aconnector)
	if (!aconnector || !aconnector->dc_link)
		return;

	link = aconnector->dc_link;
	if (link->connector_signal != SIGNAL_TYPE_EDP)
		return;

	conn_base = &aconnector->base;
	adev = conn_base->dev->dev_private;
	dm = &adev->dm;
Loading