Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

Merge branch 'drm-next-4.3' of git://people.freedesktop.org/~agd5f/linux into drm-next

More fixes for radeon and amdgpu for 4.3:
- Send full DP aux address fixes for radeon and amdgpu
- Fix an HDMI display regression for pre-DCE5 parts
- UVD suspend fixes for amdgpu
- Add an rs480 suspend quirk
- Fix bo reserve handling in amdgpu GEM_OP ioctl
- GPU scheduler fixes
- SDMA optimizations
- MEC fix for Fiji

* 'drm-next-4.3' of git://people.freedesktop.org/~agd5f/linux: (21 commits)
  drm/amdgpu: set MEC doorbell range for Fiji
  drm/amdgpu: implement burst NOP for SDMA
  drm/amdgpu: add insert_nop ring func and default implementation
  drm/amdgpu: add amdgpu_get_sdma_instance helper function
  drm/amdgpu: add AMDGPU_MAX_SDMA_INSTANCES
  drm/amdgpu: add burst_nop flag for sdma
  drm/amdgpu: add count field for the SDMA NOP packet v2
  drm/amdgpu: use PT for VM sync on unmap
  drm/amdgpu: make wait_event uninterruptible in push_job
  drm/amdgpu: fix amdgpu_bo_unreserve order in GEM_OP IOCTL v2
  drm/amdgpu: partially revert "modify amdgpu_fence_wait_any() to amdgpu_fence_wait_multiple()" v2
  Add radeon suspend/resume quirk for HP Compaq dc5750.
  drm/amdgpu: re-work sync_resv
  drm/amdgpu/atom: Send out the full AUX address
  drm/radeon/native: Send out the full AUX address
  drm/radeon/atom: Send out the full AUX address
  drm/amdgpu: use IB for fill_buffer instead of direct command
  drm/amdgpu: stop trying to suspend UVD sessions v2
  drm/amdgpu: add scheduler dependency callback v2
  drm/amdgpu: let the scheduler work more with jobs v2
  ...
parents 879a37d0 bddf8026
Loading
Loading
Loading
Loading
+31 −10
Original line number Diff line number Diff line
@@ -98,6 +98,9 @@ extern int amdgpu_sched_hw_submission;
#define AMDGPU_MAX_COMPUTE_RINGS		8
#define AMDGPU_MAX_VCE_RINGS			2

/* max number of IP instances */
#define AMDGPU_MAX_SDMA_INSTANCES		2

/* number of hw syncs before falling back on blocking */
#define AMDGPU_NUM_SYNCS			4

@@ -262,7 +265,7 @@ struct amdgpu_buffer_funcs {
	unsigned	fill_num_dw;

	/* used for buffer clearing */
	void (*emit_fill_buffer)(struct amdgpu_ring *ring,
	void (*emit_fill_buffer)(struct amdgpu_ib *ib,
				 /* value to write to memory */
				 uint32_t src_data,
				 /* dst addr in bytes */
@@ -340,6 +343,8 @@ struct amdgpu_ring_funcs {
	int (*test_ring)(struct amdgpu_ring *ring);
	int (*test_ib)(struct amdgpu_ring *ring);
	bool (*is_lockup)(struct amdgpu_ring *ring);
	/* insert NOP packets */
	void (*insert_nop)(struct amdgpu_ring *ring, uint32_t count);
};

/*
@@ -440,10 +445,9 @@ int amdgpu_fence_wait_next(struct amdgpu_ring *ring);
int amdgpu_fence_wait_empty(struct amdgpu_ring *ring);
unsigned amdgpu_fence_count_emitted(struct amdgpu_ring *ring);

signed long amdgpu_fence_wait_multiple(struct amdgpu_device *adev,
signed long amdgpu_fence_wait_any(struct amdgpu_device *adev,
				  struct fence **array,
				  uint32_t count,
				       bool wait_all,
				  bool intr,
				  signed long t);
struct amdgpu_fence *amdgpu_fence_ref(struct amdgpu_fence *fence);
@@ -717,6 +721,7 @@ int amdgpu_sync_resv(struct amdgpu_device *adev,
		     void *owner);
int amdgpu_sync_rings(struct amdgpu_sync *sync,
		      struct amdgpu_ring *ring);
struct fence *amdgpu_sync_get_fence(struct amdgpu_sync *sync);
int amdgpu_sync_wait(struct amdgpu_sync *sync);
void amdgpu_sync_free(struct amdgpu_device *adev, struct amdgpu_sync *sync,
		      struct fence *fence);
@@ -1214,6 +1219,7 @@ int amdgpu_ib_ring_tests(struct amdgpu_device *adev);
void amdgpu_ring_free_size(struct amdgpu_ring *ring);
int amdgpu_ring_alloc(struct amdgpu_ring *ring, unsigned ndw);
int amdgpu_ring_lock(struct amdgpu_ring *ring, unsigned ndw);
void amdgpu_ring_insert_nop(struct amdgpu_ring *ring, uint32_t count);
void amdgpu_ring_commit(struct amdgpu_ring *ring);
void amdgpu_ring_unlock_commit(struct amdgpu_ring *ring);
void amdgpu_ring_undo(struct amdgpu_ring *ring);
@@ -1665,7 +1671,6 @@ struct amdgpu_uvd {
	struct amdgpu_bo	*vcpu_bo;
	void			*cpu_addr;
	uint64_t		gpu_addr;
	void			*saved_bo;
	atomic_t		handles[AMDGPU_MAX_UVD_HANDLES];
	struct drm_file		*filp[AMDGPU_MAX_UVD_HANDLES];
	struct delayed_work	idle_work;
@@ -1709,6 +1714,7 @@ struct amdgpu_sdma {
	uint32_t		feature_version;

	struct amdgpu_ring	ring;
	bool			burst_nop;
};

/*
@@ -2057,7 +2063,7 @@ struct amdgpu_device {
	struct amdgpu_gfx		gfx;

	/* sdma */
	struct amdgpu_sdma		sdma[2];
	struct amdgpu_sdma		sdma[AMDGPU_MAX_SDMA_INSTANCES];
	struct amdgpu_irq_src		sdma_trap_irq;
	struct amdgpu_irq_src		sdma_illegal_inst_irq;

@@ -2196,6 +2202,21 @@ static inline void amdgpu_ring_write(struct amdgpu_ring *ring, uint32_t v)
	ring->ring_free_dw--;
}

static inline struct amdgpu_sdma * amdgpu_get_sdma_instance(struct amdgpu_ring *ring)
{
	struct amdgpu_device *adev = ring->adev;
	int i;

	for (i = 0; i < AMDGPU_MAX_SDMA_INSTANCES; i++)
		if (&adev->sdma[i].ring == ring)
			break;

	if (i < AMDGPU_MAX_SDMA_INSTANCES)
		return &adev->sdma[i];
	else
		return NULL;
}

/*
 * ASICs macro.
 */
@@ -2248,7 +2269,7 @@ static inline void amdgpu_ring_write(struct amdgpu_ring *ring, uint32_t v)
#define amdgpu_display_stop_mc_access(adev, s) (adev)->mode_info.funcs->stop_mc_access((adev), (s))
#define amdgpu_display_resume_mc_access(adev, s) (adev)->mode_info.funcs->resume_mc_access((adev), (s))
#define amdgpu_emit_copy_buffer(adev, ib, s, d, b) (adev)->mman.buffer_funcs->emit_copy_buffer((ib),  (s), (d), (b))
#define amdgpu_emit_fill_buffer(adev, r, s, d, b) (adev)->mman.buffer_funcs->emit_fill_buffer((r), (s), (d), (b))
#define amdgpu_emit_fill_buffer(adev, ib, s, d, b) (adev)->mman.buffer_funcs->emit_fill_buffer((ib), (s), (d), (b))
#define amdgpu_dpm_get_temperature(adev) (adev)->pm.funcs->get_temperature((adev))
#define amdgpu_dpm_pre_set_power_state(adev) (adev)->pm.funcs->pre_set_power_state((adev))
#define amdgpu_dpm_set_power_state(adev) (adev)->pm.funcs->set_power_state((adev))
+9 −35
Original line number Diff line number Diff line
@@ -851,22 +851,6 @@ static bool amdgpu_test_signaled_any(struct fence **fences, uint32_t count)
	return false;
}

static bool amdgpu_test_signaled_all(struct fence **fences, uint32_t count)
{
	int idx;
	struct fence *fence;

	for (idx = 0; idx < count; ++idx) {
		fence = fences[idx];
		if (fence) {
			if (!test_bit(FENCE_FLAG_SIGNALED_BIT, &fence->flags))
				return false;
		}
	}

	return true;
}

struct amdgpu_wait_cb {
	struct fence_cb base;
	struct task_struct *task;
@@ -885,7 +869,7 @@ static signed long amdgpu_fence_default_wait(struct fence *f, bool intr,
	struct amdgpu_fence *fence = to_amdgpu_fence(f);
	struct amdgpu_device *adev = fence->ring->adev;

	return amdgpu_fence_wait_multiple(adev, &f, 1, false, intr, t);
	return amdgpu_fence_wait_any(adev, &f, 1, intr, t);
}

/**
@@ -894,23 +878,18 @@ static signed long amdgpu_fence_default_wait(struct fence *f, bool intr,
 * @adev:     amdgpu device
 * @array:    the fence array with amdgpu fence pointer
 * @count:    the number of the fence array
 * @wait_all: the flag of wait all(true) or wait any(false)
 * @intr:     when sleep, set the current task interruptable or not
 * @t:        timeout to wait
 *
 * If wait_all is true, it will return when all fences are signaled or timeout.
 * If wait_all is false, it will return when any fence is signaled or timeout.
 * It will return when any fence is signaled or timeout.
 */
signed long amdgpu_fence_wait_multiple(struct amdgpu_device *adev,
				       struct fence **array,
				       uint32_t count,
				       bool wait_all,
				       bool intr,
				       signed long t)
signed long amdgpu_fence_wait_any(struct amdgpu_device *adev,
				  struct fence **array, uint32_t count,
				  bool intr, signed long t)
{
	long idx = 0;
	struct amdgpu_wait_cb *cb;
	struct fence *fence;
	unsigned idx;

	BUG_ON(!array);

@@ -927,9 +906,6 @@ signed long amdgpu_fence_wait_multiple(struct amdgpu_device *adev,
			if (fence_add_callback(fence,
					&cb[idx].base, amdgpu_fence_wait_cb)) {
				/* The fence is already signaled */
				if (wait_all)
					continue;
				else
				goto fence_rm_cb;
			}
		}
@@ -945,9 +921,7 @@ signed long amdgpu_fence_wait_multiple(struct amdgpu_device *adev,
		 * amdgpu_test_signaled_any must be called after
		 * set_current_state to prevent a race with wake_up_process
		 */
		if (!wait_all && amdgpu_test_signaled_any(array, count))
			break;
		if (wait_all && amdgpu_test_signaled_all(array, count))
		if (amdgpu_test_signaled_any(array, count))
			break;

		if (adev->needs_reset) {
+4 −1
Original line number Diff line number Diff line
@@ -615,6 +615,7 @@ int amdgpu_gem_op_ioctl(struct drm_device *dev, void *data,
		info.alignment = robj->tbo.mem.page_alignment << PAGE_SHIFT;
		info.domains = robj->initial_domain;
		info.domain_flags = robj->flags;
		amdgpu_bo_unreserve(robj);
		if (copy_to_user(out, &info, sizeof(info)))
			r = -EFAULT;
		break;
@@ -622,17 +623,19 @@ int amdgpu_gem_op_ioctl(struct drm_device *dev, void *data,
	case AMDGPU_GEM_OP_SET_PLACEMENT:
		if (amdgpu_ttm_tt_has_userptr(robj->tbo.ttm)) {
			r = -EPERM;
			amdgpu_bo_unreserve(robj);
			break;
		}
		robj->initial_domain = args->value & (AMDGPU_GEM_DOMAIN_VRAM |
						      AMDGPU_GEM_DOMAIN_GTT |
						      AMDGPU_GEM_DOMAIN_CPU);
		amdgpu_bo_unreserve(robj);
		break;
	default:
		amdgpu_bo_unreserve(robj);
		r = -EINVAL;
	}

	amdgpu_bo_unreserve(robj);
out:
	drm_gem_object_unreference_unlocked(gobj);
	return r;
+21 −3
Original line number Diff line number Diff line
@@ -131,6 +131,21 @@ int amdgpu_ring_lock(struct amdgpu_ring *ring, unsigned ndw)
	return 0;
}

/** amdgpu_ring_insert_nop - insert NOP packets
 *
 * @ring: amdgpu_ring structure holding ring information
 * @count: the number of NOP packets to insert
 *
 * This is the generic insert_nop function for rings except SDMA
 */
void amdgpu_ring_insert_nop(struct amdgpu_ring *ring, uint32_t count)
{
	int i;

	for (i = 0; i < count; i++)
		amdgpu_ring_write(ring, ring->nop);
}

/**
 * amdgpu_ring_commit - tell the GPU to execute the new
 * commands on the ring buffer
@@ -143,10 +158,13 @@ int amdgpu_ring_lock(struct amdgpu_ring *ring, unsigned ndw)
 */
void amdgpu_ring_commit(struct amdgpu_ring *ring)
{
	uint32_t count;

	/* We pad to match fetch size */
	while (ring->wptr & ring->align_mask) {
		amdgpu_ring_write(ring, ring->nop);
	}
	count = ring->align_mask + 1 - (ring->wptr & ring->align_mask);
	count %= ring->align_mask + 1;
	ring->funcs->insert_nop(ring, count);

	mb();
	amdgpu_ring_set_wptr(ring);
}
+2 −2
Original line number Diff line number Diff line
@@ -367,8 +367,8 @@ int amdgpu_sa_bo_new(struct amdgpu_device *adev,
		} while (amdgpu_sa_bo_next_hole(sa_manager, fences, tries));

		spin_unlock(&sa_manager->wq.lock);
		t = amdgpu_fence_wait_multiple(adev, fences, AMDGPU_MAX_RINGS, false, false,
						MAX_SCHEDULE_TIMEOUT);
		t = amdgpu_fence_wait_any(adev, fences, AMDGPU_MAX_RINGS,
					  false, MAX_SCHEDULE_TIMEOUT);
		r = (t > 0) ? 0 : t;
		spin_lock(&sa_manager->wq.lock);
		/* if we have nothing to wait for block */
Loading