Commit 1e394457 authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge tag 'amd-drm-next-5.16-2021-09-27' of...

Merge tag 'amd-drm-next-5.16-2021-09-27' of https://gitlab.freedesktop.org/agd5f/linux into drm-next

amd-drm-next-5.16-2021-09-27:

amdgpu:
- RAS improvements
- BACO fixes
- Yellow Carp updates
- Misc code cleanups
- Initial DP 2.0 support
- VCN priority handling
- Cyan Skillfish updates
- Rework IB handling for multimedia engine tests
- Backlight fixes
- DCN 3.1 power saving improvements
- Runtime PM fixes
- Modifier support for DCC image stores for gfx 10.3
- Hotplug fixes
- Clean up stack related warnings in display code
- DP alt mode fixes
- Display rework for better handling FP code
- Debugfs fixes

amdkfd:
- SVM fixes
- DMA map fixes

radeon:
- AGP fix

From: Alex Deucher <alexander.deucher@amd.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210927212653.4575-1-alexander.deucher@amd.com


Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parents f602a96e 2485e275
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -977,12 +977,12 @@ L: platform-driver-x86@vger.kernel.org
S:	Maintained
F:	drivers/platform/x86/amd-pmc.*
AMD POWERPLAY
AMD POWERPLAY AND SWSMU
M:	Evan Quan <evan.quan@amd.com>
L:	amd-gfx@lists.freedesktop.org
S:	Supported
T:	git https://gitlab.freedesktop.org/agd5f/linux.git
F:	drivers/gpu/drm/amd/pm/powerplay/
F:	drivers/gpu/drm/amd/pm/
AMD PTDMA DRIVER
M:	Sanjay R Mehta <sanju.mehta@amd.com>
+109 −34
Original line number Diff line number Diff line
@@ -43,14 +43,61 @@ const unsigned int amdgpu_ctx_num_entities[AMDGPU_HW_IP_NUM] = {
	[AMDGPU_HW_IP_VCN_JPEG]	=	1,
};

bool amdgpu_ctx_priority_is_valid(int32_t ctx_prio)
{
	switch (ctx_prio) {
	case AMDGPU_CTX_PRIORITY_UNSET:
	case AMDGPU_CTX_PRIORITY_VERY_LOW:
	case AMDGPU_CTX_PRIORITY_LOW:
	case AMDGPU_CTX_PRIORITY_NORMAL:
	case AMDGPU_CTX_PRIORITY_HIGH:
	case AMDGPU_CTX_PRIORITY_VERY_HIGH:
		return true;
	default:
		return false;
	}
}

static enum drm_sched_priority
amdgpu_ctx_to_drm_sched_prio(int32_t ctx_prio)
{
	switch (ctx_prio) {
	case AMDGPU_CTX_PRIORITY_UNSET:
		return DRM_SCHED_PRIORITY_UNSET;

	case AMDGPU_CTX_PRIORITY_VERY_LOW:
		return DRM_SCHED_PRIORITY_MIN;

	case AMDGPU_CTX_PRIORITY_LOW:
		return DRM_SCHED_PRIORITY_MIN;

	case AMDGPU_CTX_PRIORITY_NORMAL:
		return DRM_SCHED_PRIORITY_NORMAL;

	case AMDGPU_CTX_PRIORITY_HIGH:
		return DRM_SCHED_PRIORITY_HIGH;

	case AMDGPU_CTX_PRIORITY_VERY_HIGH:
		return DRM_SCHED_PRIORITY_HIGH;

	/* This should not happen as we sanitized userspace provided priority
	 * already, WARN if this happens.
	 */
	default:
		WARN(1, "Invalid context priority %d\n", ctx_prio);
		return DRM_SCHED_PRIORITY_NORMAL;
	}

}

static int amdgpu_ctx_priority_permit(struct drm_file *filp,
				      enum drm_sched_priority priority)
				      int32_t priority)
{
	if (priority < 0 || priority >= DRM_SCHED_PRIORITY_COUNT)
	if (!amdgpu_ctx_priority_is_valid(priority))
		return -EINVAL;

	/* NORMAL and below are accessible by everyone */
	if (priority <= DRM_SCHED_PRIORITY_NORMAL)
	if (priority <= AMDGPU_CTX_PRIORITY_NORMAL)
		return 0;

	if (capable(CAP_SYS_NICE))
@@ -62,26 +109,51 @@ static int amdgpu_ctx_priority_permit(struct drm_file *filp,
	return -EACCES;
}

static enum gfx_pipe_priority amdgpu_ctx_sched_prio_to_compute_prio(enum drm_sched_priority prio)
static enum amdgpu_gfx_pipe_priority amdgpu_ctx_prio_to_compute_prio(int32_t prio)
{
	switch (prio) {
	case DRM_SCHED_PRIORITY_HIGH:
	case DRM_SCHED_PRIORITY_KERNEL:
	case AMDGPU_CTX_PRIORITY_HIGH:
	case AMDGPU_CTX_PRIORITY_VERY_HIGH:
		return AMDGPU_GFX_PIPE_PRIO_HIGH;
	default:
		return AMDGPU_GFX_PIPE_PRIO_NORMAL;
	}
}

static unsigned int amdgpu_ctx_prio_sched_to_hw(struct amdgpu_device *adev,
						 enum drm_sched_priority prio,
						 u32 hw_ip)
static enum amdgpu_ring_priority_level amdgpu_ctx_sched_prio_to_ring_prio(int32_t prio)
{
	switch (prio) {
	case AMDGPU_CTX_PRIORITY_HIGH:
		return AMDGPU_RING_PRIO_1;
	case AMDGPU_CTX_PRIORITY_VERY_HIGH:
		return AMDGPU_RING_PRIO_2;
	default:
		return AMDGPU_RING_PRIO_0;
	}
}

static unsigned int amdgpu_ctx_get_hw_prio(struct amdgpu_ctx *ctx, u32 hw_ip)
{
	struct amdgpu_device *adev = ctx->adev;
	int32_t ctx_prio;
	unsigned int hw_prio;

	hw_prio = (hw_ip == AMDGPU_HW_IP_COMPUTE) ?
			amdgpu_ctx_sched_prio_to_compute_prio(prio) :
			AMDGPU_RING_PRIO_DEFAULT;
	ctx_prio = (ctx->override_priority == AMDGPU_CTX_PRIORITY_UNSET) ?
			ctx->init_priority : ctx->override_priority;

	switch (hw_ip) {
	case AMDGPU_HW_IP_COMPUTE:
		hw_prio = amdgpu_ctx_prio_to_compute_prio(ctx_prio);
		break;
	case AMDGPU_HW_IP_VCE:
	case AMDGPU_HW_IP_VCN_ENC:
		hw_prio = amdgpu_ctx_sched_prio_to_ring_prio(ctx_prio);
		break;
	default:
		hw_prio = AMDGPU_RING_PRIO_DEFAULT;
		break;
	}

	hw_ip = array_index_nospec(hw_ip, AMDGPU_HW_IP_NUM);
	if (adev->gpu_sched[hw_ip][hw_prio].num_scheds == 0)
		hw_prio = AMDGPU_RING_PRIO_DEFAULT;
@@ -89,6 +161,7 @@ static unsigned int amdgpu_ctx_prio_sched_to_hw(struct amdgpu_device *adev,
	return hw_prio;
}


static int amdgpu_ctx_init_entity(struct amdgpu_ctx *ctx, u32 hw_ip,
				  const u32 ring)
{
@@ -96,8 +169,9 @@ static int amdgpu_ctx_init_entity(struct amdgpu_ctx *ctx, u32 hw_ip,
	struct amdgpu_ctx_entity *entity;
	struct drm_gpu_scheduler **scheds = NULL, *sched = NULL;
	unsigned num_scheds = 0;
	int32_t ctx_prio;
	unsigned int hw_prio;
	enum drm_sched_priority priority;
	enum drm_sched_priority drm_prio;
	int r;

	entity = kzalloc(struct_size(entity, fences, amdgpu_sched_jobs),
@@ -105,10 +179,11 @@ static int amdgpu_ctx_init_entity(struct amdgpu_ctx *ctx, u32 hw_ip,
	if (!entity)
		return  -ENOMEM;

	entity->sequence = 1;
	priority = (ctx->override_priority == DRM_SCHED_PRIORITY_UNSET) ?
	ctx_prio = (ctx->override_priority == AMDGPU_CTX_PRIORITY_UNSET) ?
			ctx->init_priority : ctx->override_priority;
	hw_prio = amdgpu_ctx_prio_sched_to_hw(adev, priority, hw_ip);
	entity->sequence = 1;
	hw_prio = amdgpu_ctx_get_hw_prio(ctx, hw_ip);
	drm_prio = amdgpu_ctx_to_drm_sched_prio(ctx_prio);

	hw_ip = array_index_nospec(hw_ip, AMDGPU_HW_IP_NUM);
	scheds = adev->gpu_sched[hw_ip][hw_prio].sched;
@@ -124,7 +199,7 @@ static int amdgpu_ctx_init_entity(struct amdgpu_ctx *ctx, u32 hw_ip,
		num_scheds = 1;
	}

	r = drm_sched_entity_init(&entity->entity, priority, scheds, num_scheds,
	r = drm_sched_entity_init(&entity->entity, drm_prio, scheds, num_scheds,
				  &ctx->guilty);
	if (r)
		goto error_free_entity;
@@ -139,7 +214,7 @@ static int amdgpu_ctx_init_entity(struct amdgpu_ctx *ctx, u32 hw_ip,
}

static int amdgpu_ctx_init(struct amdgpu_device *adev,
			   enum drm_sched_priority priority,
			   int32_t priority,
			   struct drm_file *filp,
			   struct amdgpu_ctx *ctx)
{
@@ -161,7 +236,7 @@ static int amdgpu_ctx_init(struct amdgpu_device *adev,
	ctx->reset_counter_query = ctx->reset_counter;
	ctx->vram_lost_counter = atomic_read(&adev->vram_lost_counter);
	ctx->init_priority = priority;
	ctx->override_priority = DRM_SCHED_PRIORITY_UNSET;
	ctx->override_priority = AMDGPU_CTX_PRIORITY_UNSET;

	return 0;
}
@@ -234,7 +309,7 @@ int amdgpu_ctx_get_entity(struct amdgpu_ctx *ctx, u32 hw_ip, u32 instance,
static int amdgpu_ctx_alloc(struct amdgpu_device *adev,
			    struct amdgpu_fpriv *fpriv,
			    struct drm_file *filp,
			    enum drm_sched_priority priority,
			    int32_t priority,
			    uint32_t *id)
{
	struct amdgpu_ctx_mgr *mgr = &fpriv->ctx_mgr;
@@ -397,19 +472,19 @@ int amdgpu_ctx_ioctl(struct drm_device *dev, void *data,
{
	int r;
	uint32_t id;
	enum drm_sched_priority priority;
	int32_t priority;

	union drm_amdgpu_ctx *args = data;
	struct amdgpu_device *adev = drm_to_adev(dev);
	struct amdgpu_fpriv *fpriv = filp->driver_priv;

	id = args->in.ctx_id;
	r = amdgpu_to_sched_priority(args->in.priority, &priority);
	priority = args->in.priority;

	/* For backwards compatibility reasons, we need to accept
	 * ioctls with garbage in the priority field */
	if (r == -EINVAL)
		priority = DRM_SCHED_PRIORITY_NORMAL;
	if (!amdgpu_ctx_priority_is_valid(priority))
		priority = AMDGPU_CTX_PRIORITY_NORMAL;

	switch (args->in.op) {
	case AMDGPU_CTX_OP_ALLOC_CTX:
@@ -517,7 +592,7 @@ struct dma_fence *amdgpu_ctx_get_fence(struct amdgpu_ctx *ctx,
static void amdgpu_ctx_set_entity_priority(struct amdgpu_ctx *ctx,
					   struct amdgpu_ctx_entity *aentity,
					   int hw_ip,
					    enum drm_sched_priority priority)
					   int32_t priority)
{
	struct amdgpu_device *adev = ctx->adev;
	unsigned int hw_prio;
@@ -525,12 +600,12 @@ static void amdgpu_ctx_set_entity_priority(struct amdgpu_ctx *ctx,
	unsigned num_scheds;

	/* set sw priority */
	drm_sched_entity_set_priority(&aentity->entity, priority);
	drm_sched_entity_set_priority(&aentity->entity,
				      amdgpu_ctx_to_drm_sched_prio(priority));

	/* set hw priority */
	if (hw_ip == AMDGPU_HW_IP_COMPUTE) {
		hw_prio = amdgpu_ctx_prio_sched_to_hw(adev, priority,
						      AMDGPU_HW_IP_COMPUTE);
		hw_prio = amdgpu_ctx_get_hw_prio(ctx, hw_ip);
		hw_prio = array_index_nospec(hw_prio, AMDGPU_RING_PRIO_MAX);
		scheds = adev->gpu_sched[hw_ip][hw_prio].sched;
		num_scheds = adev->gpu_sched[hw_ip][hw_prio].num_scheds;
@@ -540,14 +615,14 @@ static void amdgpu_ctx_set_entity_priority(struct amdgpu_ctx *ctx,
}

void amdgpu_ctx_priority_override(struct amdgpu_ctx *ctx,
				  enum drm_sched_priority priority)
				  int32_t priority)
{
	enum drm_sched_priority ctx_prio;
	int32_t ctx_prio;
	unsigned i, j;

	ctx->override_priority = priority;

	ctx_prio = (ctx->override_priority == DRM_SCHED_PRIORITY_UNSET) ?
	ctx_prio = (ctx->override_priority == AMDGPU_CTX_PRIORITY_UNSET) ?
			ctx->init_priority : ctx->override_priority;
	for (i = 0; i < AMDGPU_HW_IP_NUM; ++i) {
		for (j = 0; j < amdgpu_ctx_num_entities[i]; ++j) {
+4 −4
Original line number Diff line number Diff line
@@ -47,8 +47,8 @@ struct amdgpu_ctx {
	spinlock_t			ring_lock;
	struct amdgpu_ctx_entity	*entities[AMDGPU_HW_IP_NUM][AMDGPU_MAX_ENTITY_NUM];
	bool				preamble_presented;
	enum drm_sched_priority		init_priority;
	enum drm_sched_priority		override_priority;
	int32_t				init_priority;
	int32_t				override_priority;
	struct mutex			lock;
	atomic_t			guilty;
	unsigned long			ras_counter_ce;
@@ -75,8 +75,8 @@ void amdgpu_ctx_add_fence(struct amdgpu_ctx *ctx,
struct dma_fence *amdgpu_ctx_get_fence(struct amdgpu_ctx *ctx,
				       struct drm_sched_entity *entity,
				       uint64_t seq);
void amdgpu_ctx_priority_override(struct amdgpu_ctx *ctx,
				  enum drm_sched_priority priority);
bool amdgpu_ctx_priority_is_valid(int32_t ctx_prio);
void amdgpu_ctx_priority_override(struct amdgpu_ctx *ctx, int32_t ctx_prio);

int amdgpu_ctx_ioctl(struct drm_device *dev, void *data,
		     struct drm_file *filp);
+155 −5
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@
#include "amdgpu_rap.h"
#include "amdgpu_securedisplay.h"
#include "amdgpu_fw_attestation.h"
#include "amdgpu_umr.h"

int amdgpu_debugfs_wait_dump(struct amdgpu_device *adev)
{
@@ -279,6 +280,145 @@ static ssize_t amdgpu_debugfs_regs_write(struct file *f, const char __user *buf,
	return amdgpu_debugfs_process_reg_op(false, f, (char __user *)buf, size, pos);
}

static int amdgpu_debugfs_regs2_open(struct inode *inode, struct file *file)
{
	struct amdgpu_debugfs_regs2_data *rd;

	rd = kzalloc(sizeof *rd, GFP_KERNEL);
	if (!rd)
		return -ENOMEM;
	rd->adev = file_inode(file)->i_private;
	file->private_data = rd;
	mutex_init(&rd->lock);

	return 0;
}

static int amdgpu_debugfs_regs2_release(struct inode *inode, struct file *file)
{
	struct amdgpu_debugfs_regs2_data *rd = file->private_data;
	mutex_destroy(&rd->lock);
	kfree(file->private_data);
	return 0;
}

static ssize_t amdgpu_debugfs_regs2_op(struct file *f, char __user *buf, u32 offset, size_t size, int write_en)
{
	struct amdgpu_debugfs_regs2_data *rd = f->private_data;
	struct amdgpu_device *adev = rd->adev;
	ssize_t result = 0;
	int r;
	uint32_t value;

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

	r = pm_runtime_get_sync(adev_to_drm(adev)->dev);
	if (r < 0) {
		pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
		return r;
	}

	r = amdgpu_virt_enable_access_debugfs(adev);
	if (r < 0) {
		pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
		return r;
	}

	mutex_lock(&rd->lock);

	if (rd->id.use_grbm) {
		if ((rd->id.grbm.sh != 0xFFFFFFFF && rd->id.grbm.sh >= adev->gfx.config.max_sh_per_se) ||
		    (rd->id.grbm.se != 0xFFFFFFFF && rd->id.grbm.se >= adev->gfx.config.max_shader_engines)) {
			pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
			pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
			amdgpu_virt_disable_access_debugfs(adev);
			mutex_unlock(&rd->lock);
			return -EINVAL;
		}
		mutex_lock(&adev->grbm_idx_mutex);
		amdgpu_gfx_select_se_sh(adev, rd->id.grbm.se,
								rd->id.grbm.sh,
								rd->id.grbm.instance);
	}

	if (rd->id.use_srbm) {
		mutex_lock(&adev->srbm_mutex);
		amdgpu_gfx_select_me_pipe_q(adev, rd->id.srbm.me, rd->id.srbm.pipe,
									rd->id.srbm.queue, rd->id.srbm.vmid);
	}

	if (rd->id.pg_lock)
		mutex_lock(&adev->pm.mutex);

	while (size) {
		if (!write_en) {
			value = RREG32(offset >> 2);
			r = put_user(value, (uint32_t *)buf);
		} else {
			r = get_user(value, (uint32_t *)buf);
			if (!r)
				amdgpu_mm_wreg_mmio_rlc(adev, offset >> 2, value);
		}
		if (r) {
			result = r;
			goto end;
		}
		offset += 4;
		size -= 4;
		result += 4;
		buf += 4;
	}
end:
	if (rd->id.use_grbm) {
		amdgpu_gfx_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff);
		mutex_unlock(&adev->grbm_idx_mutex);
	}

	if (rd->id.use_srbm) {
		amdgpu_gfx_select_me_pipe_q(adev, 0, 0, 0, 0);
		mutex_unlock(&adev->srbm_mutex);
	}

	if (rd->id.pg_lock)
		mutex_unlock(&adev->pm.mutex);

	mutex_unlock(&rd->lock);

	pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
	pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);

	amdgpu_virt_disable_access_debugfs(adev);
	return result;
}

static long amdgpu_debugfs_regs2_ioctl(struct file *f, unsigned int cmd, unsigned long data)
{
	struct amdgpu_debugfs_regs2_data *rd = f->private_data;
	int r;

	switch (cmd) {
	case AMDGPU_DEBUGFS_REGS2_IOC_SET_STATE:
		mutex_lock(&rd->lock);
		r = copy_from_user(&rd->id, (struct amdgpu_debugfs_regs2_iocdata *)data, sizeof rd->id);
		mutex_unlock(&rd->lock);
		return r ? -EINVAL : 0;
	default:
		return -EINVAL;
	}
	return 0;
}

static ssize_t amdgpu_debugfs_regs2_read(struct file *f, char __user *buf, size_t size, loff_t *pos)
{
	return amdgpu_debugfs_regs2_op(f, buf, *pos, size, 0);
}

static ssize_t amdgpu_debugfs_regs2_write(struct file *f, const char __user *buf, size_t size, loff_t *pos)
{
	return amdgpu_debugfs_regs2_op(f, (char __user *)buf, *pos, size, 1);
}


/**
 * amdgpu_debugfs_regs_pcie_read - Read from a PCIE register
@@ -1091,6 +1231,16 @@ static ssize_t amdgpu_debugfs_gfxoff_read(struct file *f, char __user *buf,
	return result;
}

static const struct file_operations amdgpu_debugfs_regs2_fops = {
	.owner = THIS_MODULE,
	.unlocked_ioctl = amdgpu_debugfs_regs2_ioctl,
	.read = amdgpu_debugfs_regs2_read,
	.write = amdgpu_debugfs_regs2_write,
	.open = amdgpu_debugfs_regs2_open,
	.release = amdgpu_debugfs_regs2_release,
	.llseek = default_llseek
};

static const struct file_operations amdgpu_debugfs_regs_fops = {
	.owner = THIS_MODULE,
	.read = amdgpu_debugfs_regs_read,
@@ -1148,6 +1298,7 @@ static const struct file_operations amdgpu_debugfs_gfxoff_fops = {

static const struct file_operations *debugfs_regs[] = {
	&amdgpu_debugfs_regs_fops,
	&amdgpu_debugfs_regs2_fops,
	&amdgpu_debugfs_regs_didt_fops,
	&amdgpu_debugfs_regs_pcie_fops,
	&amdgpu_debugfs_regs_smc_fops,
@@ -1160,6 +1311,7 @@ static const struct file_operations *debugfs_regs[] = {

static const char *debugfs_regs_names[] = {
	"amdgpu_regs",
	"amdgpu_regs2",
	"amdgpu_regs_didt",
	"amdgpu_regs_pcie",
	"amdgpu_regs_smc",
@@ -1206,7 +1358,7 @@ static int amdgpu_debugfs_test_ib_show(struct seq_file *m, void *unused)
	}

	/* Avoid accidently unparking the sched thread during GPU reset */
	r = down_read_killable(&adev->reset_sem);
	r = down_write_killable(&adev->reset_sem);
	if (r)
		return r;

@@ -1235,7 +1387,7 @@ static int amdgpu_debugfs_test_ib_show(struct seq_file *m, void *unused)
		kthread_unpark(ring->sched.thread);
	}

	up_read(&adev->reset_sem);
	up_write(&adev->reset_sem);

	pm_runtime_mark_last_busy(dev->dev);
	pm_runtime_put_autosuspend(dev->dev);
@@ -1582,9 +1734,7 @@ int amdgpu_debugfs_init(struct amdgpu_device *adev)
		if (!ring)
			continue;

		if (amdgpu_debugfs_ring_init(adev, ring)) {
			DRM_ERROR("Failed to register debugfs file for rings !\n");
		}
		amdgpu_debugfs_ring_init(adev, ring);
	}

	amdgpu_ras_debugfs_create_all(adev);
+0 −1
Original line number Diff line number Diff line
@@ -22,7 +22,6 @@
 * OTHER DEALINGS IN THE SOFTWARE.
 *
 */

/*
 * Debugfs
 */
Loading