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

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

Merge branch 'drm-fixes' of git://people.freedesktop.org/~airlied/linux

Pull drm fixes from Dave Airlie:
 "This has a bunch of nouveau fixes, as Ben has been hibernating and has
  lots of small fixes for lots of bugs across nouveau.

  Radeon has one major fix for hdmi/dp audio regression that is larger
  than Alex would like, but seems to fix up a fair few bugs, along with
  some misc fixes.

  And a few msm fixes, one of which is also a bit large.

  But nothing in here seems insane or crazy for this stage, just more
  than I'd like"

* 'drm-fixes' of git://people.freedesktop.org/~airlied/linux: (33 commits)
  drm/msm/mdp5: release SMB (shared memory blocks) in various cases
  drm/msm: change to uninterruptible wait in atomic commit
  drm/msm: mdp4: Fix drm_framebuffer dereference crash
  drm/msm: fix msm_gem_prime_get_sg_table()
  drm/amdgpu: add new parameter to seperate map and unmap
  drm/amdgpu: hdp_flush is not needed for inside IB
  drm/amdgpu: different emit_ib for gfx and compute
  drm/amdgpu: information leak in amdgpu_info_ioctl()
  drm/amdgpu: clean up init sequence for failures
  drm/radeon/combios: add some validation of lvds values
  drm/radeon: rework audio modeset to handle non-audio hdmi features
  drm/radeon: rework audio detect (v4)
  drm/amdgpu: Drop drm/ prefix for including drm.h in amdgpu_drm.h
  drm/radeon: Drop drm/ prefix for including drm.h in radeon_drm.h
  drm/nouveau/nouveau/ttm: fix tiled system memory with Maxwell
  drm/nouveau/kms/nv50-: guard against enabling cursor on disabled heads
  drm/nouveau/fbcon/g80: reduce PUSH_SPACE alloc, fire ring on accel init
  drm/nouveau/fbcon/gf100-: reduce RING_SPACE allocation
  drm/nouveau/fbcon/nv11-: correctly account for ring space usage
  drm/nouveau/bios: add proper support for opcode 0x59
  ...
parents 84009357 bdce3e7c
Loading
Loading
Loading
Loading
+7 −1
Original line number Diff line number Diff line
@@ -1866,6 +1866,12 @@ typedef void (*amdgpu_wreg_t)(struct amdgpu_device*, uint32_t, uint32_t);
typedef uint32_t (*amdgpu_block_rreg_t)(struct amdgpu_device*, uint32_t, uint32_t);
typedef void (*amdgpu_block_wreg_t)(struct amdgpu_device*, uint32_t, uint32_t, uint32_t);

struct amdgpu_ip_block_status {
	bool valid;
	bool sw;
	bool hw;
};

struct amdgpu_device {
	struct device			*dev;
	struct drm_device		*ddev;
@@ -2008,7 +2014,7 @@ struct amdgpu_device {

	const struct amdgpu_ip_block_version *ip_blocks;
	int				num_ip_blocks;
	bool				*ip_block_enabled;
	struct amdgpu_ip_block_status	*ip_block_status;
	struct mutex	mn_lock;
	DECLARE_HASHTABLE(mn_hash, 7);

+22 −16
Original line number Diff line number Diff line
@@ -1191,8 +1191,9 @@ static int amdgpu_early_init(struct amdgpu_device *adev)
		return -EINVAL;
	}

	adev->ip_block_enabled = kcalloc(adev->num_ip_blocks, sizeof(bool), GFP_KERNEL);
	if (adev->ip_block_enabled == NULL)
	adev->ip_block_status = kcalloc(adev->num_ip_blocks,
					sizeof(struct amdgpu_ip_block_status), GFP_KERNEL);
	if (adev->ip_block_status == NULL)
		return -ENOMEM;

	if (adev->ip_blocks == NULL) {
@@ -1203,18 +1204,18 @@ static int amdgpu_early_init(struct amdgpu_device *adev)
	for (i = 0; i < adev->num_ip_blocks; i++) {
		if ((amdgpu_ip_block_mask & (1 << i)) == 0) {
			DRM_ERROR("disabled ip block: %d\n", i);
			adev->ip_block_enabled[i] = false;
			adev->ip_block_status[i].valid = false;
		} else {
			if (adev->ip_blocks[i].funcs->early_init) {
				r = adev->ip_blocks[i].funcs->early_init((void *)adev);
				if (r == -ENOENT)
					adev->ip_block_enabled[i] = false;
					adev->ip_block_status[i].valid = false;
				else if (r)
					return r;
				else
					adev->ip_block_enabled[i] = true;
					adev->ip_block_status[i].valid = true;
			} else {
				adev->ip_block_enabled[i] = true;
				adev->ip_block_status[i].valid = true;
			}
		}
	}
@@ -1227,11 +1228,12 @@ static int amdgpu_init(struct amdgpu_device *adev)
	int i, r;

	for (i = 0; i < adev->num_ip_blocks; i++) {
		if (!adev->ip_block_enabled[i])
		if (!adev->ip_block_status[i].valid)
			continue;
		r = adev->ip_blocks[i].funcs->sw_init((void *)adev);
		if (r)
			return r;
		adev->ip_block_status[i].sw = true;
		/* need to do gmc hw init early so we can allocate gpu mem */
		if (adev->ip_blocks[i].type == AMD_IP_BLOCK_TYPE_GMC) {
			r = amdgpu_vram_scratch_init(adev);
@@ -1243,11 +1245,12 @@ static int amdgpu_init(struct amdgpu_device *adev)
			r = amdgpu_wb_init(adev);
			if (r)
				return r;
			adev->ip_block_status[i].hw = true;
		}
	}

	for (i = 0; i < adev->num_ip_blocks; i++) {
		if (!adev->ip_block_enabled[i])
		if (!adev->ip_block_status[i].sw)
			continue;
		/* gmc hw init is done early */
		if (adev->ip_blocks[i].type == AMD_IP_BLOCK_TYPE_GMC)
@@ -1255,6 +1258,7 @@ static int amdgpu_init(struct amdgpu_device *adev)
		r = adev->ip_blocks[i].funcs->hw_init((void *)adev);
		if (r)
			return r;
		adev->ip_block_status[i].hw = true;
	}

	return 0;
@@ -1265,7 +1269,7 @@ static int amdgpu_late_init(struct amdgpu_device *adev)
	int i = 0, r;

	for (i = 0; i < adev->num_ip_blocks; i++) {
		if (!adev->ip_block_enabled[i])
		if (!adev->ip_block_status[i].valid)
			continue;
		/* enable clockgating to save power */
		r = adev->ip_blocks[i].funcs->set_clockgating_state((void *)adev,
@@ -1287,7 +1291,7 @@ static int amdgpu_fini(struct amdgpu_device *adev)
	int i, r;

	for (i = adev->num_ip_blocks - 1; i >= 0; i--) {
		if (!adev->ip_block_enabled[i])
		if (!adev->ip_block_status[i].hw)
			continue;
		if (adev->ip_blocks[i].type == AMD_IP_BLOCK_TYPE_GMC) {
			amdgpu_wb_fini(adev);
@@ -1300,14 +1304,16 @@ static int amdgpu_fini(struct amdgpu_device *adev)
			return r;
		r = adev->ip_blocks[i].funcs->hw_fini((void *)adev);
		/* XXX handle errors */
		adev->ip_block_status[i].hw = false;
	}

	for (i = adev->num_ip_blocks - 1; i >= 0; i--) {
		if (!adev->ip_block_enabled[i])
		if (!adev->ip_block_status[i].sw)
			continue;
		r = adev->ip_blocks[i].funcs->sw_fini((void *)adev);
		/* XXX handle errors */
		adev->ip_block_enabled[i] = false;
		adev->ip_block_status[i].sw = false;
		adev->ip_block_status[i].valid = false;
	}

	return 0;
@@ -1318,7 +1324,7 @@ static int amdgpu_suspend(struct amdgpu_device *adev)
	int i, r;

	for (i = adev->num_ip_blocks - 1; i >= 0; i--) {
		if (!adev->ip_block_enabled[i])
		if (!adev->ip_block_status[i].valid)
			continue;
		/* ungate blocks so that suspend can properly shut them down */
		r = adev->ip_blocks[i].funcs->set_clockgating_state((void *)adev,
@@ -1336,7 +1342,7 @@ static int amdgpu_resume(struct amdgpu_device *adev)
	int i, r;

	for (i = 0; i < adev->num_ip_blocks; i++) {
		if (!adev->ip_block_enabled[i])
		if (!adev->ip_block_status[i].valid)
			continue;
		r = adev->ip_blocks[i].funcs->resume(adev);
		if (r)
@@ -1582,8 +1588,8 @@ void amdgpu_device_fini(struct amdgpu_device *adev)
	amdgpu_fence_driver_fini(adev);
	amdgpu_fbdev_fini(adev);
	r = amdgpu_fini(adev);
	kfree(adev->ip_block_enabled);
	adev->ip_block_enabled = NULL;
	kfree(adev->ip_block_status);
	adev->ip_block_status = NULL;
	adev->accel_working = false;
	/* free i2c buses */
	amdgpu_i2c_fini(adev);
+5 −3
Original line number Diff line number Diff line
@@ -449,7 +449,7 @@ int amdgpu_gem_metadata_ioctl(struct drm_device *dev, void *data,
 * vital here, so they are not reported back to userspace.
 */
static void amdgpu_gem_va_update_vm(struct amdgpu_device *adev,
				    struct amdgpu_bo_va *bo_va)
				    struct amdgpu_bo_va *bo_va, uint32_t operation)
{
	struct ttm_validate_buffer tv, *entry;
	struct amdgpu_bo_list_entry *vm_bos;
@@ -485,6 +485,8 @@ static void amdgpu_gem_va_update_vm(struct amdgpu_device *adev,
	if (r)
		goto error_unlock;


	if (operation == AMDGPU_VA_OP_MAP)
		r = amdgpu_vm_bo_update(adev, bo_va, &bo_va->bo->tbo.mem);

error_unlock:
@@ -580,7 +582,7 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data,
	}

	if (!r && !(args->flags & AMDGPU_VM_DELAY_UPDATE))
		amdgpu_gem_va_update_vm(adev, bo_va);
		amdgpu_gem_va_update_vm(adev, bo_va, args->operation);

	drm_gem_object_unreference_unlocked(gobj);
	return r;
+8 −8
Original line number Diff line number Diff line
@@ -180,9 +180,8 @@ int amdgpu_ib_schedule(struct amdgpu_device *adev, unsigned num_ibs,
	if (vm) {
		/* do context switch */
		amdgpu_vm_flush(ring, vm, ib->sync.last_vm_update);
	}

	if (vm && ring->funcs->emit_gds_switch)
		if (ring->funcs->emit_gds_switch)
			amdgpu_ring_emit_gds_switch(ring, ib->vm->ids[ring->idx].id,
						    ib->gds_base, ib->gds_size,
						    ib->gws_base, ib->gws_size,
@@ -190,6 +189,7 @@ int amdgpu_ib_schedule(struct amdgpu_device *adev, unsigned num_ibs,

		if (ring->funcs->emit_hdp_flush)
			amdgpu_ring_emit_hdp_flush(ring);
	}

	old_ctx = ring->current_ctx;
	for (i = 0; i < num_ibs; ++i) {
+3 −3
Original line number Diff line number Diff line
@@ -235,7 +235,7 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file

		for (i = 0; i < adev->num_ip_blocks; i++) {
			if (adev->ip_blocks[i].type == type &&
			    adev->ip_block_enabled[i]) {
			    adev->ip_block_status[i].valid) {
				ip.hw_ip_version_major = adev->ip_blocks[i].major;
				ip.hw_ip_version_minor = adev->ip_blocks[i].minor;
				ip.capabilities_flags = 0;
@@ -274,7 +274,7 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file

		for (i = 0; i < adev->num_ip_blocks; i++)
			if (adev->ip_blocks[i].type == type &&
			    adev->ip_block_enabled[i] &&
			    adev->ip_block_status[i].valid &&
			    count < AMDGPU_HW_IP_INSTANCE_MAX_COUNT)
				count++;

@@ -416,7 +416,7 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file
		return n ? -EFAULT : 0;
	}
	case AMDGPU_INFO_DEV_INFO: {
		struct drm_amdgpu_info_device dev_info;
		struct drm_amdgpu_info_device dev_info = {};
		struct amdgpu_cu_info cu_info;

		dev_info.device_id = dev->pdev->device;
Loading