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

Commit 871e899d authored by Dave Airlie's avatar Dave Airlie
Browse files

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

A few fixes for 4.17:
- Fix a potential use after free in a error case
- Fix pcie lane handling in amdgpu SI dpm
- sdma pipeline sync fix
- A few vega12 cleanups and fixes
- Misc other fixes

* 'drm-next-4.17' of git://people.freedesktop.org/~agd5f/linux:
  drm/amdgpu: Fix memory leaks at amdgpu_init() error path
  drm/amdgpu: Fix PCIe lane width calculation
  drm/radeon: Fix PCIe lane width calculation
  drm/amdgpu/si: implement get/set pcie_lanes asic callback
  drm/amdgpu: Add support for SRBM selection v3
  Revert "drm/amdgpu: Don't change preferred domian when fallback GTT v5"
  drm/amd/powerply: fix power reading on Fiji
  drm/amd/powerplay: Enable ACG SS feature
  drm/amdgpu/sdma: fix mask in emit_pipeline_sync
  drm/amdgpu: Fix KIQ hang on bare metal for device unbind/bind back v2.
  drm/amd/pp: Clean header file in vega12_smumgr.c
  drm/amd/pp: Remove Dead functions on Vega12
  drm/amd/pp: silence a static checker warning
  drm/amdgpu: drop compute ring timeout setting for non-sriov only (v2)
  drm/amdgpu: fix typo of domain fallback
parents c975f17d c60e22f7
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -890,6 +890,7 @@ struct amdgpu_gfx_funcs {
	void (*read_wave_data)(struct amdgpu_device *adev, uint32_t simd, uint32_t wave, uint32_t *dst, int *no_fields);
	void (*read_wave_vgprs)(struct amdgpu_device *adev, uint32_t simd, uint32_t wave, uint32_t thread, uint32_t start, uint32_t size, uint32_t *dst);
	void (*read_wave_sgprs)(struct amdgpu_device *adev, uint32_t simd, uint32_t wave, uint32_t start, uint32_t size, uint32_t *dst);
	void (*select_me_pipe_q)(struct amdgpu_device *adev, u32 me, u32 pipe, u32 queue);
};

struct amdgpu_ngg_buf {
@@ -1812,6 +1813,7 @@ amdgpu_get_sdma_instance(struct amdgpu_ring *ring)
#define amdgpu_gfx_select_se_sh(adev, se, sh, instance) (adev)->gfx.funcs->select_se_sh((adev), (se), (sh), (instance))
#define amdgpu_gds_switch(adev, r, v, d, w, a) (adev)->gds.funcs->patch_gds_switch((r), (v), (d), (w), (a))
#define amdgpu_psp_check_fw_loading_status(adev, i) (adev)->firmware.funcs->check_fw_loading_status((adev), (i))
#define amdgpu_gfx_select_me_pipe_q(adev, me, pipe, q) (adev)->gfx.funcs->select_me_pipe_q((adev), (me), (pipe), (q))

/* Common functions */
int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
+40 −77
Original line number Diff line number Diff line
@@ -64,16 +64,21 @@ int amdgpu_debugfs_add_files(struct amdgpu_device *adev,

#if defined(CONFIG_DEBUG_FS)

static ssize_t amdgpu_debugfs_regs_read(struct file *f, char __user *buf,
					size_t size, loff_t *pos)

static int  amdgpu_debugfs_process_reg_op(bool read, struct file *f,
		char __user *buf, size_t size, loff_t *pos)
{
	struct amdgpu_device *adev = file_inode(f)->i_private;
	ssize_t result = 0;
	int r;
	bool pm_pg_lock, use_bank;
	unsigned instance_bank, sh_bank, se_bank;
	bool pm_pg_lock, use_bank, use_ring;
	unsigned instance_bank, sh_bank, se_bank, me, pipe, queue;

	if (size & 0x3 || *pos & 0x3)
	pm_pg_lock = use_bank = use_ring = false;
	instance_bank = sh_bank = se_bank = me = pipe = queue = 0;

	if (size & 0x3 || *pos & 0x3 ||
			((*pos & (1ULL << 62)) && (*pos & (1ULL << 61))))
		return -EINVAL;

	/* are we reading registers for which a PG lock is necessary? */
@@ -91,8 +96,15 @@ static ssize_t amdgpu_debugfs_regs_read(struct file *f, char __user *buf,
		if (instance_bank == 0x3FF)
			instance_bank = 0xFFFFFFFF;
		use_bank = 1;
	} else if (*pos & (1ULL << 61)) {

		me = (*pos & GENMASK_ULL(33, 24)) >> 24;
		pipe = (*pos & GENMASK_ULL(43, 34)) >> 34;
		queue = (*pos & GENMASK_ULL(53, 44)) >> 44;

		use_ring = 1;
	} else {
		use_bank = 0;
		use_bank = use_ring = 0;
	}

	*pos &= (1UL << 22) - 1;
@@ -104,6 +116,9 @@ static ssize_t amdgpu_debugfs_regs_read(struct file *f, char __user *buf,
		mutex_lock(&adev->grbm_idx_mutex);
		amdgpu_gfx_select_se_sh(adev, se_bank,
					sh_bank, instance_bank);
	} else if (use_ring) {
		mutex_lock(&adev->srbm_mutex);
		amdgpu_gfx_select_me_pipe_q(adev, me, pipe, queue);
	}

	if (pm_pg_lock)
@@ -115,8 +130,14 @@ static ssize_t amdgpu_debugfs_regs_read(struct file *f, char __user *buf,
		if (*pos > adev->rmmio_size)
			goto end;

		if (read) {
			value = RREG32(*pos >> 2);
			r = put_user(value, (uint32_t *)buf);
		} else {
			r = get_user(value, (uint32_t *)buf);
			if (!r)
				WREG32(*pos >> 2, value);
		}
		if (r) {
			result = r;
			goto end;
@@ -132,6 +153,9 @@ static ssize_t amdgpu_debugfs_regs_read(struct file *f, char __user *buf,
	if (use_bank) {
		amdgpu_gfx_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff);
		mutex_unlock(&adev->grbm_idx_mutex);
	} else if (use_ring) {
		amdgpu_gfx_select_me_pipe_q(adev, 0, 0, 0);
		mutex_unlock(&adev->srbm_mutex);
	}

	if (pm_pg_lock)
@@ -140,78 +164,17 @@ static ssize_t amdgpu_debugfs_regs_read(struct file *f, char __user *buf,
	return result;
}

static ssize_t amdgpu_debugfs_regs_write(struct file *f, const char __user *buf,

static ssize_t amdgpu_debugfs_regs_read(struct file *f, char __user *buf,
					size_t size, loff_t *pos)
{
	struct amdgpu_device *adev = file_inode(f)->i_private;
	ssize_t result = 0;
	int r;
	bool pm_pg_lock, use_bank;
	unsigned instance_bank, sh_bank, se_bank;

	if (size & 0x3 || *pos & 0x3)
		return -EINVAL;

	/* are we reading registers for which a PG lock is necessary? */
	pm_pg_lock = (*pos >> 23) & 1;

	if (*pos & (1ULL << 62)) {
		se_bank = (*pos & GENMASK_ULL(33, 24)) >> 24;
		sh_bank = (*pos & GENMASK_ULL(43, 34)) >> 34;
		instance_bank = (*pos & GENMASK_ULL(53, 44)) >> 44;

		if (se_bank == 0x3FF)
			se_bank = 0xFFFFFFFF;
		if (sh_bank == 0x3FF)
			sh_bank = 0xFFFFFFFF;
		if (instance_bank == 0x3FF)
			instance_bank = 0xFFFFFFFF;
		use_bank = 1;
	} else {
		use_bank = 0;
	return amdgpu_debugfs_process_reg_op(true, f, buf, size, pos);
}

	*pos &= (1UL << 22) - 1;

	if (use_bank) {
		if ((sh_bank != 0xFFFFFFFF && sh_bank >= adev->gfx.config.max_sh_per_se) ||
		    (se_bank != 0xFFFFFFFF && se_bank >= adev->gfx.config.max_shader_engines))
			return -EINVAL;
		mutex_lock(&adev->grbm_idx_mutex);
		amdgpu_gfx_select_se_sh(adev, se_bank,
					sh_bank, instance_bank);
	}

	if (pm_pg_lock)
		mutex_lock(&adev->pm.mutex);

	while (size) {
		uint32_t value;

		if (*pos > adev->rmmio_size)
			return result;

		r = get_user(value, (uint32_t *)buf);
		if (r)
			return r;

		WREG32(*pos >> 2, value);

		result += 4;
		buf += 4;
		*pos += 4;
		size -= 4;
	}

	if (use_bank) {
		amdgpu_gfx_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff);
		mutex_unlock(&adev->grbm_idx_mutex);
	}

	if (pm_pg_lock)
		mutex_unlock(&adev->pm.mutex);

	return result;
static ssize_t amdgpu_debugfs_regs_write(struct file *f, const char __user *buf,
					 size_t size, loff_t *pos)
{
	return amdgpu_debugfs_process_reg_op(false, f, (char __user *)buf, size, pos);
}

static ssize_t amdgpu_debugfs_regs_pcie_read(struct file *f, char __user *buf,
+5 −4
Original line number Diff line number Diff line
@@ -922,6 +922,11 @@ static int __init amdgpu_init(void)
{
	int r;

	if (vgacon_text_force()) {
		DRM_ERROR("VGACON disables amdgpu kernel modesetting.\n");
		return -EINVAL;
	}

	r = amdgpu_sync_init();
	if (r)
		goto error_sync;
@@ -930,10 +935,6 @@ static int __init amdgpu_init(void)
	if (r)
		goto error_fence;

	if (vgacon_text_force()) {
		DRM_ERROR("VGACON disables amdgpu kernel modesetting.\n");
		return -EINVAL;
	}
	DRM_INFO("amdgpu kernel modesetting enabled.\n");
	driver = &kms_driver;
	pdriver = &amdgpu_kms_pci_driver;
+9 −3
Original line number Diff line number Diff line
@@ -410,6 +410,7 @@ int amdgpu_fence_driver_start_ring(struct amdgpu_ring *ring,
int amdgpu_fence_driver_init_ring(struct amdgpu_ring *ring,
				  unsigned num_hw_submission)
{
	long timeout;
	int r;

	/* Check that num_hw_submission is a power of two */
@@ -433,11 +434,16 @@ int amdgpu_fence_driver_init_ring(struct amdgpu_ring *ring,

	/* No need to setup the GPU scheduler for KIQ ring */
	if (ring->funcs->type != AMDGPU_RING_TYPE_KIQ) {
		/* for non-sriov case, no timeout enforce on compute ring */
		if ((ring->funcs->type == AMDGPU_RING_TYPE_COMPUTE)
				&& !amdgpu_sriov_vf(ring->adev))
			timeout = MAX_SCHEDULE_TIMEOUT;
		else
			timeout = msecs_to_jiffies(amdgpu_lockup_timeout);

		r = drm_sched_init(&ring->sched, &amdgpu_sched_ops,
				   num_hw_submission, amdgpu_job_hang_limit,
				   (ring->funcs->type == AMDGPU_RING_TYPE_COMPUTE) ?
				   MAX_SCHEDULE_TIMEOUT : msecs_to_jiffies(amdgpu_lockup_timeout),
				   ring->name);
				   timeout, ring->name);
		if (r) {
			DRM_ERROR("Failed to create scheduler on ring %s.\n",
				  ring->name);
+14 −2
Original line number Diff line number Diff line
@@ -56,11 +56,23 @@ int amdgpu_gem_object_create(struct amdgpu_device *adev, unsigned long size,
		alignment = PAGE_SIZE;
	}

retry:
	r = amdgpu_bo_create(adev, size, alignment, initial_domain,
			     flags, type, resv, &bo);
	if (r) {
		if (r != -ERESTARTSYS) {
			if (flags & AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED) {
				flags &= ~AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED;
				goto retry;
			}

			if (initial_domain == AMDGPU_GEM_DOMAIN_VRAM) {
				initial_domain |= AMDGPU_GEM_DOMAIN_GTT;
				goto retry;
			}
			DRM_DEBUG("Failed to allocate GEM object (%ld, %d, %u, %d)\n",
				  size, initial_domain, alignment, r);
		}
		return r;
	}
	*obj = &bo->gem_base;
Loading