/*
 * Copyright 2014 Advanced Micro Devices, Inc.
 * Copyright 2008 Red Hat Inc.
 * Copyright 2009 Jerome Glisse.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 *
 */

#include <linux/firmware.h>
#include "amdgpu.h"
#include "amdgpu_gfx.h"
#include "amdgpu_rlc.h"
#include "amdgpu_ras.h"
#include "amdgpu_xcp.h"
#include "amdgpu_xgmi.h"

/* delay 0.1 second to enable gfx off feature */
#define GFX_OFF_DELAY_ENABLE         msecs_to_jiffies(100)

#define GFX_OFF_NO_DELAY 0

/*
 * GPU GFX IP block helpers function.
 */

int amdgpu_gfx_mec_queue_to_bit(struct amdgpu_device *adev, int mec,
				int pipe, int queue)
{
	int bit = 0;

	bit += mec * adev->gfx.mec.num_pipe_per_mec
		* adev->gfx.mec.num_queue_per_pipe;
	bit += pipe * adev->gfx.mec.num_queue_per_pipe;
	bit += queue;

	return bit;
}

void amdgpu_queue_mask_bit_to_mec_queue(struct amdgpu_device *adev, int bit,
				 int *mec, int *pipe, int *queue)
{
	*queue = bit % adev->gfx.mec.num_queue_per_pipe;
	*pipe = (bit / adev->gfx.mec.num_queue_per_pipe)
		% adev->gfx.mec.num_pipe_per_mec;
	*mec = (bit / adev->gfx.mec.num_queue_per_pipe)
	       / adev->gfx.mec.num_pipe_per_mec;

}

bool amdgpu_gfx_is_mec_queue_enabled(struct amdgpu_device *adev,
				     int xcc_id, int mec, int pipe, int queue)
{
	return test_bit(amdgpu_gfx_mec_queue_to_bit(adev, mec, pipe, queue),
			adev->gfx.mec_bitmap[xcc_id].queue_bitmap);
}

int amdgpu_gfx_me_queue_to_bit(struct amdgpu_device *adev,
			       int me, int pipe, int queue)
{
	int bit = 0;

	bit += me * adev->gfx.me.num_pipe_per_me
		* adev->gfx.me.num_queue_per_pipe;
	bit += pipe * adev->gfx.me.num_queue_per_pipe;
	bit += queue;

	return bit;
}

void amdgpu_gfx_bit_to_me_queue(struct amdgpu_device *adev, int bit,
				int *me, int *pipe, int *queue)
{
	*queue = bit % adev->gfx.me.num_queue_per_pipe;
	*pipe = (bit / adev->gfx.me.num_queue_per_pipe)
		% adev->gfx.me.num_pipe_per_me;
	*me = (bit / adev->gfx.me.num_queue_per_pipe)
		/ adev->gfx.me.num_pipe_per_me;
}

bool amdgpu_gfx_is_me_queue_enabled(struct amdgpu_device *adev,
				    int me, int pipe, int queue)
{
	return test_bit(amdgpu_gfx_me_queue_to_bit(adev, me, pipe, queue),
			adev->gfx.me.queue_bitmap);
}

/**
 * amdgpu_gfx_parse_disable_cu - Parse the disable_cu module parameter
 *
 * @mask: array in which the per-shader array disable masks will be stored
 * @max_se: number of SEs
 * @max_sh: number of SHs
 *
 * The bitmask of CUs to be disabled in the shader array determined by se and
 * sh is stored in mask[se * max_sh + sh].
 */
void amdgpu_gfx_parse_disable_cu(unsigned int *mask, unsigned int max_se, unsigned int max_sh)
{
	unsigned int se, sh, cu;
	const char *p;

	memset(mask, 0, sizeof(*mask) * max_se * max_sh);

	if (!amdgpu_disable_cu || !*amdgpu_disable_cu)
		return;

	p = amdgpu_disable_cu;
	for (;;) {
		char *next;
		int ret = sscanf(p, "%u.%u.%u", &se, &sh, &cu);

		if (ret < 3) {
			DRM_ERROR("amdgpu: could not parse disable_cu\n");
			return;
		}

		if (se < max_se && sh < max_sh && cu < 16) {
			DRM_INFO("amdgpu: disabling CU %u.%u.%u\n", se, sh, cu);
			mask[se * max_sh + sh] |= 1u << cu;
		} else {
			DRM_ERROR("amdgpu: disable_cu %u.%u.%u is out of range\n",
				  se, sh, cu);
		}

		next = strchr(p, ',');
		if (!next)
			break;
		p = next + 1;
	}
}

static bool amdgpu_gfx_is_graphics_multipipe_capable(struct amdgpu_device *adev)
{
	return amdgpu_async_gfx_ring && adev->gfx.me.num_pipe_per_me > 1;
}

static bool amdgpu_gfx_is_compute_multipipe_capable(struct amdgpu_device *adev)
{
	if (amdgpu_compute_multipipe != -1) {
		DRM_INFO("amdgpu: forcing compute pipe policy %d\n",
			 amdgpu_compute_multipipe);
		return amdgpu_compute_multipipe == 1;
	}

	if (amdgpu_ip_version(adev, GC_HWIP, 0) > IP_VERSION(9, 0, 0))
		return true;

	/* FIXME: spreading the queues across pipes causes perf regressions
	 * on POLARIS11 compute workloads */
	if (adev->asic_type == CHIP_POLARIS11)
		return false;

	return adev->gfx.mec.num_mec > 1;
}

bool amdgpu_gfx_is_high_priority_graphics_queue(struct amdgpu_device *adev,
						struct amdgpu_ring *ring)
{
	int queue = ring->queue;
	int pipe = ring->pipe;

	/* Policy: use pipe1 queue0 as high priority graphics queue if we
	 * have more than one gfx pipe.
	 */
	if (amdgpu_gfx_is_graphics_multipipe_capable(adev) &&
	    adev->gfx.num_gfx_rings > 1 && pipe == 1 && queue == 0) {
		int me = ring->me;
		int bit;

		bit = amdgpu_gfx_me_queue_to_bit(adev, me, pipe, queue);
		if (ring == &adev->gfx.gfx_ring[bit])
			return true;
	}

	return false;
}

bool amdgpu_gfx_is_high_priority_compute_queue(struct amdgpu_device *adev,
					       struct amdgpu_ring *ring)
{
	/* Policy: use 1st queue as high priority compute queue if we
	 * have more than one compute queue.
	 */
	if (adev->gfx.num_compute_rings > 1 &&
	    ring == &adev->gfx.compute_ring[0])
		return true;

	return false;
}

void amdgpu_gfx_compute_queue_acquire(struct amdgpu_device *adev)
{
	int i, j, queue, pipe;
	bool multipipe_policy = amdgpu_gfx_is_compute_multipipe_capable(adev);
	int max_queues_per_mec = min(adev->gfx.mec.num_pipe_per_mec *
				     adev->gfx.mec.num_queue_per_pipe,
				     adev->gfx.num_compute_rings);
	int num_xcc = adev->gfx.xcc_mask ? NUM_XCC(adev->gfx.xcc_mask) : 1;

	if (multipipe_policy) {
		/* policy: make queues evenly cross all pipes on MEC1 only
		 * for multiple xcc, just use the original policy for simplicity */
		for (j = 0; j < num_xcc; j++) {
			for (i = 0; i < max_queues_per_mec; i++) {
				pipe = i % adev->gfx.mec.num_pipe_per_mec;
				queue = (i / adev->gfx.mec.num_pipe_per_mec) %
					 adev->gfx.mec.num_queue_per_pipe;

				set_bit(pipe * adev->gfx.mec.num_queue_per_pipe + queue,
					adev->gfx.mec_bitmap[j].queue_bitmap);
			}
		}
	} else {
		/* policy: amdgpu owns all queues in the given pipe */
		for (j = 0; j < num_xcc; j++) {
			for (i = 0; i < max_queues_per_mec; ++i)
				set_bit(i, adev->gfx.mec_bitmap[j].queue_bitmap);
		}
	}

	for (j = 0; j < num_xcc; j++) {
		dev_dbg(adev->dev, "mec queue bitmap weight=%d\n",
			bitmap_weight(adev->gfx.mec_bitmap[j].queue_bitmap, AMDGPU_MAX_COMPUTE_QUEUES));
	}
}

void amdgpu_gfx_graphics_queue_acquire(struct amdgpu_device *adev)
{
	int i, queue, pipe;
	bool multipipe_policy = amdgpu_gfx_is_graphics_multipipe_capable(adev);
	int max_queues_per_me = adev->gfx.me.num_pipe_per_me *
					adev->gfx.me.num_queue_per_pipe;

	if (multipipe_policy) {
		/* policy: amdgpu owns the first queue per pipe at this stage
		 * will extend to mulitple queues per pipe later */
		for (i = 0; i < max_queues_per_me; i++) {
			pipe = i % adev->gfx.me.num_pipe_per_me;
			queue = (i / adev->gfx.me.num_pipe_per_me) %
				adev->gfx.me.num_queue_per_pipe;

			set_bit(pipe * adev->gfx.me.num_queue_per_pipe + queue,
				adev->gfx.me.queue_bitmap);
		}
	} else {
		for (i = 0; i < max_queues_per_me; ++i)
			set_bit(i, adev->gfx.me.queue_bitmap);
	}

	/* update the number of active graphics rings */
	adev->gfx.num_gfx_rings =
		bitmap_weight(adev->gfx.me.queue_bitmap, AMDGPU_MAX_GFX_QUEUES);
}

static int amdgpu_gfx_kiq_acquire(struct amdgpu_device *adev,
				  struct amdgpu_ring *ring, int xcc_id)
{
	int queue_bit;
	int mec, pipe, queue;

	queue_bit = adev->gfx.mec.num_mec
		    * adev->gfx.mec.num_pipe_per_mec
		    * adev->gfx.mec.num_queue_per_pipe;

	while (--queue_bit >= 0) {
		if (test_bit(queue_bit, adev->gfx.mec_bitmap[xcc_id].queue_bitmap))
			continue;

		amdgpu_queue_mask_bit_to_mec_queue(adev, queue_bit, &mec, &pipe, &queue);

		/*
		 * 1. Using pipes 2/3 from MEC 2 seems cause problems.
		 * 2. It must use queue id 0, because CGPG_IDLE/SAVE/LOAD/RUN
		 * only can be issued on queue 0.
		 */
		if ((mec == 1 && pipe > 1) || queue != 0)
			continue;

		ring->me = mec + 1;
		ring->pipe = pipe;
		ring->queue = queue;

		return 0;
	}

	dev_err(adev->dev, "Failed to find a queue for KIQ\n");
	return -EINVAL;
}

int amdgpu_gfx_kiq_init_ring(struct amdgpu_device *adev, int xcc_id)
{
	struct amdgpu_kiq *kiq = &adev->gfx.kiq[xcc_id];
	struct amdgpu_irq_src *irq = &kiq->irq;
	struct amdgpu_ring *ring = &kiq->ring;
	int r = 0;

	spin_lock_init(&kiq->ring_lock);

	ring->adev = NULL;
	ring->ring_obj = NULL;
	ring->use_doorbell = true;
	ring->xcc_id = xcc_id;
	ring->vm_hub = AMDGPU_GFXHUB(xcc_id);
	ring->doorbell_index =
		(adev->doorbell_index.kiq +
		 xcc_id * adev->doorbell_index.xcc_doorbell_range)
		<< 1;

	r = amdgpu_gfx_kiq_acquire(adev, ring, xcc_id);
	if (r)
		return r;

	ring->eop_gpu_addr = kiq->eop_gpu_addr;
	ring->no_scheduler = true;
	snprintf(ring->name, sizeof(ring->name), "kiq_%d.%d.%d.%d",
		 xcc_id, ring->me, ring->pipe, ring->queue);
	r = amdgpu_ring_init(adev, ring, 1024, irq, AMDGPU_CP_KIQ_IRQ_DRIVER0,
			     AMDGPU_RING_PRIO_DEFAULT, NULL);
	if (r)
		dev_warn(adev->dev, "(%d) failed to init kiq ring\n", r);

	return r;
}

void amdgpu_gfx_kiq_free_ring(struct amdgpu_ring *ring)
{
	amdgpu_ring_fini(ring);
}

void amdgpu_gfx_kiq_fini(struct amdgpu_device *adev, int xcc_id)
{
	struct amdgpu_kiq *kiq = &adev->gfx.kiq[xcc_id];

	amdgpu_bo_free_kernel(&kiq->eop_obj, &kiq->eop_gpu_addr, NULL);
}

int amdgpu_gfx_kiq_init(struct amdgpu_device *adev,
			unsigned int hpd_size, int xcc_id)
{
	int r;
	u32 *hpd;
	struct amdgpu_kiq *kiq = &adev->gfx.kiq[xcc_id];

	r = amdgpu_bo_create_kernel(adev, hpd_size, PAGE_SIZE,
				    AMDGPU_GEM_DOMAIN_GTT, &kiq->eop_obj,
				    &kiq->eop_gpu_addr, (void **)&hpd);
	if (r) {
		dev_warn(adev->dev, "failed to create KIQ bo (%d).\n", r);
		return r;
	}

	memset(hpd, 0, hpd_size);

	r = amdgpu_bo_reserve(kiq->eop_obj, true);
	if (unlikely(r != 0))
		dev_warn(adev->dev, "(%d) reserve kiq eop bo failed\n", r);
	amdgpu_bo_kunmap(kiq->eop_obj);
	amdgpu_bo_unreserve(kiq->eop_obj);

	return 0;
}

/* create MQD for each compute/gfx queue */
int amdgpu_gfx_mqd_sw_init(struct amdgpu_device *adev,
			   unsigned int mqd_size, int xcc_id)
{
	int r, i, j;
	struct amdgpu_kiq *kiq = &adev->gfx.kiq[xcc_id];
	struct amdgpu_ring *ring = &kiq->ring;
	u32 domain = AMDGPU_GEM_DOMAIN_GTT;

#if !defined(CONFIG_ARM) && !defined(CONFIG_ARM64)
	/* Only enable on gfx10 and 11 for now to avoid changing behavior on older chips */
	if (amdgpu_ip_version(adev, GC_HWIP, 0) >= IP_VERSION(10, 0, 0))
		domain |= AMDGPU_GEM_DOMAIN_VRAM;
#endif

	/* create MQD for KIQ */
	if (!adev->enable_mes_kiq && !ring->mqd_obj) {
		/* originaly the KIQ MQD is put in GTT domain, but for SRIOV VRAM domain is a must
		 * otherwise hypervisor trigger SAVE_VF fail after driver unloaded which mean MQD
		 * deallocated and gart_unbind, to strict diverage we decide to use VRAM domain for
		 * KIQ MQD no matter SRIOV or Bare-metal
		 */
		r = amdgpu_bo_create_kernel(adev, mqd_size, PAGE_SIZE,
					    AMDGPU_GEM_DOMAIN_VRAM |
					    AMDGPU_GEM_DOMAIN_GTT,
					    &ring->mqd_obj,
					    &ring->mqd_gpu_addr,
					    &ring->mqd_ptr);
		if (r) {
			dev_warn(adev->dev, "failed to create ring mqd ob (%d)", r);
			return r;
		}

		/* prepare MQD backup */
		kiq->mqd_backup = kmalloc(mqd_size, GFP_KERNEL);
		if (!kiq->mqd_backup) {
			dev_warn(adev->dev,
				 "no memory to create MQD backup for ring %s\n", ring->name);
			return -ENOMEM;
		}
	}

	if (adev->asic_type >= CHIP_NAVI10 && amdgpu_async_gfx_ring) {
		/* create MQD for each KGQ */
		for (i = 0; i < adev->gfx.num_gfx_rings; i++) {
			ring = &adev->gfx.gfx_ring[i];
			if (!ring->mqd_obj) {
				r = amdgpu_bo_create_kernel(adev, mqd_size, PAGE_SIZE,
							    domain, &ring->mqd_obj,
							    &ring->mqd_gpu_addr, &ring->mqd_ptr);
				if (r) {
					dev_warn(adev->dev, "failed to create ring mqd bo (%d)", r);
					return r;
				}

				ring->mqd_size = mqd_size;
				/* prepare MQD backup */
				adev->gfx.me.mqd_backup[i] = kmalloc(mqd_size, GFP_KERNEL);
				if (!adev->gfx.me.mqd_backup[i]) {
					dev_warn(adev->dev, "no memory to create MQD backup for ring %s\n", ring->name);
					return -ENOMEM;
				}
			}
		}
	}

	/* create MQD for each KCQ */
	for (i = 0; i < adev->gfx.num_compute_rings; i++) {
		j = i + xcc_id * adev->gfx.num_compute_rings;
		ring = &adev->gfx.compute_ring[j];
		if (!ring->mqd_obj) {
			r = amdgpu_bo_create_kernel(adev, mqd_size, PAGE_SIZE,
						    domain, &ring->mqd_obj,
						    &ring->mqd_gpu_addr, &ring->mqd_ptr);
			if (r) {
				dev_warn(adev->dev, "failed to create ring mqd bo (%d)", r);
				return r;
			}

			ring->mqd_size = mqd_size;
			/* prepare MQD backup */
			adev->gfx.mec.mqd_backup[j] = kmalloc(mqd_size, GFP_KERNEL);
			if (!adev->gfx.mec.mqd_backup[j]) {
				dev_warn(adev->dev, "no memory to create MQD backup for ring %s\n", ring->name);
				return -ENOMEM;
			}
		}
	}

	return 0;
}

void amdgpu_gfx_mqd_sw_fini(struct amdgpu_device *adev, int xcc_id)
{
	struct amdgpu_ring *ring = NULL;
	int i, j;
	struct amdgpu_kiq *kiq = &adev->gfx.kiq[xcc_id];

	if (adev->asic_type >= CHIP_NAVI10 && amdgpu_async_gfx_ring) {
		for (i = 0; i < adev->gfx.num_gfx_rings; i++) {
			ring = &adev->gfx.gfx_ring[i];
			kfree(adev->gfx.me.mqd_backup[i]);
			amdgpu_bo_free_kernel(&ring->mqd_obj,
					      &ring->mqd_gpu_addr,
					      &ring->mqd_ptr);
		}
	}

	for (i = 0; i < adev->gfx.num_compute_rings; i++) {
		j = i + xcc_id * adev->gfx.num_compute_rings;
		ring = &adev->gfx.compute_ring[j];
		kfree(adev->gfx.mec.mqd_backup[j]);
		amdgpu_bo_free_kernel(&ring->mqd_obj,
				      &ring->mqd_gpu_addr,
				      &ring->mqd_ptr);
	}

	ring = &kiq->ring;
	kfree(kiq->mqd_backup);
	amdgpu_bo_free_kernel(&ring->mqd_obj,
			      &ring->mqd_gpu_addr,
			      &ring->mqd_ptr);
}

int amdgpu_gfx_disable_kcq(struct amdgpu_device *adev, int xcc_id)
{
	struct amdgpu_kiq *kiq = &adev->gfx.kiq[xcc_id];
	struct amdgpu_ring *kiq_ring = &kiq->ring;
	struct amdgpu_hive_info *hive;
	struct amdgpu_ras *ras;
	int hive_ras_recovery = 0;
	int i, r = 0;
	int j;

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

	spin_lock(&kiq->ring_lock);
	if (amdgpu_ring_alloc(kiq_ring, kiq->pmf->unmap_queues_size *
					adev->gfx.num_compute_rings)) {
		spin_unlock(&kiq->ring_lock);
		return -ENOMEM;
	}

	for (i = 0; i < adev->gfx.num_compute_rings; i++) {
		j = i + xcc_id * adev->gfx.num_compute_rings;
		kiq->pmf->kiq_unmap_queues(kiq_ring,
					   &adev->gfx.compute_ring[j],
					   RESET_QUEUES, 0, 0);
	}

	/**
	 * This is workaround: only skip kiq_ring test
	 * during ras recovery in suspend stage for gfx9.4.3
	 */
	hive = amdgpu_get_xgmi_hive(adev);
	if (hive) {
		hive_ras_recovery = atomic_read(&hive->ras_recovery);
		amdgpu_put_xgmi_hive(hive);
	}

	ras = amdgpu_ras_get_context(adev);
	if ((amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(9, 4, 3)) &&
		ras && (atomic_read(&ras->in_recovery) || hive_ras_recovery)) {
		spin_unlock(&kiq->ring_lock);
		return 0;
	}

	if (kiq_ring->sched.ready && !adev->job_hang)
		r = amdgpu_ring_test_helper(kiq_ring);
	spin_unlock(&kiq->ring_lock);

	return r;
}

int amdgpu_gfx_disable_kgq(struct amdgpu_device *adev, int xcc_id)
{
	struct amdgpu_kiq *kiq = &adev->gfx.kiq[xcc_id];
	struct amdgpu_ring *kiq_ring = &kiq->ring;
	int i, r = 0;
	int j;

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

	spin_lock(&kiq->ring_lock);
	if (amdgpu_gfx_is_master_xcc(adev, xcc_id)) {
		if (amdgpu_ring_alloc(kiq_ring, kiq->pmf->unmap_queues_size *
						adev->gfx.num_gfx_rings)) {
			spin_unlock(&kiq->ring_lock);
			return -ENOMEM;
		}

		for (i = 0; i < adev->gfx.num_gfx_rings; i++) {
			j = i + xcc_id * adev->gfx.num_gfx_rings;
			kiq->pmf->kiq_unmap_queues(kiq_ring,
						   &adev->gfx.gfx_ring[j],
						   PREEMPT_QUEUES, 0, 0);
		}
	}

	if (adev->gfx.kiq[0].ring.sched.ready && !adev->job_hang)
		r = amdgpu_ring_test_helper(kiq_ring);
	spin_unlock(&kiq->ring_lock);

	return r;
}

int amdgpu_queue_mask_bit_to_set_resource_bit(struct amdgpu_device *adev,
					int queue_bit)
{
	int mec, pipe, queue;
	int set_resource_bit = 0;

	amdgpu_queue_mask_bit_to_mec_queue(adev, queue_bit, &mec, &pipe, &queue);

	set_resource_bit = mec * 4 * 8 + pipe * 8 + queue;

	return set_resource_bit;
}

int amdgpu_gfx_enable_kcq(struct amdgpu_device *adev, int xcc_id)
{
	struct amdgpu_kiq *kiq = &adev->gfx.kiq[xcc_id];
	struct amdgpu_ring *kiq_ring = &kiq->ring;
	uint64_t queue_mask = 0;
	int r, i, j;

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

	for (i = 0; i < AMDGPU_MAX_COMPUTE_QUEUES; ++i) {
		if (!test_bit(i, adev->gfx.mec_bitmap[xcc_id].queue_bitmap))
			continue;

		/* This situation may be hit in the future if a new HW
		 * generation exposes more than 64 queues. If so, the
		 * definition of queue_mask needs updating */
		if (WARN_ON(i > (sizeof(queue_mask)*8))) {
			DRM_ERROR("Invalid KCQ enabled: %d\n", i);
			break;
		}

		queue_mask |= (1ull << amdgpu_queue_mask_bit_to_set_resource_bit(adev, i));
	}

	DRM_INFO("kiq ring mec %d pipe %d q %d\n", kiq_ring->me, kiq_ring->pipe,
							kiq_ring->queue);
	amdgpu_device_flush_hdp(adev, NULL);

	spin_lock(&kiq->ring_lock);
	r = amdgpu_ring_alloc(kiq_ring, kiq->pmf->map_queues_size *
					adev->gfx.num_compute_rings +
					kiq->pmf->set_resources_size);
	if (r) {
		DRM_ERROR("Failed to lock KIQ (%d).\n", r);
		spin_unlock(&kiq->ring_lock);
		return r;
	}

	if (adev->enable_mes)
		queue_mask = ~0ULL;

	kiq->pmf->kiq_set_resources(kiq_ring, queue_mask);
	for (i = 0; i < adev->gfx.num_compute_rings; i++) {
		j = i + xcc_id * adev->gfx.num_compute_rings;
		kiq->pmf->kiq_map_queues(kiq_ring,
					 &adev->gfx.compute_ring[j]);
	}

	r = amdgpu_ring_test_helper(kiq_ring);
	spin_unlock(&kiq->ring_lock);
	if (r)
		DRM_ERROR("KCQ enable failed\n");

	return r;
}

int amdgpu_gfx_enable_kgq(struct amdgpu_device *adev, int xcc_id)
{
	struct amdgpu_kiq *kiq = &adev->gfx.kiq[xcc_id];
	struct amdgpu_ring *kiq_ring = &kiq->ring;
	int r, i, j;

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

	amdgpu_device_flush_hdp(adev, NULL);

	spin_lock(&kiq->ring_lock);
	/* No need to map kcq on the slave */
	if (amdgpu_gfx_is_master_xcc(adev, xcc_id)) {
		r = amdgpu_ring_alloc(kiq_ring, kiq->pmf->map_queues_size *
						adev->gfx.num_gfx_rings);
		if (r) {
			DRM_ERROR("Failed to lock KIQ (%d).\n", r);
			spin_unlock(&kiq->ring_lock);
			return r;
		}

		for (i = 0; i < adev->gfx.num_gfx_rings; i++) {
			j = i + xcc_id * adev->gfx.num_gfx_rings;
			kiq->pmf->kiq_map_queues(kiq_ring,
						 &adev->gfx.gfx_ring[j]);
		}
	}

	r = amdgpu_ring_test_helper(kiq_ring);
	spin_unlock(&kiq->ring_lock);
	if (r)
		DRM_ERROR("KCQ enable failed\n");

	return r;
}

/* amdgpu_gfx_off_ctrl - Handle gfx off feature enable/disable
 *
 * @adev: amdgpu_device pointer
 * @bool enable true: enable gfx off feature, false: disable gfx off feature
 *
 * 1. gfx off feature will be enabled by gfx ip after gfx cg gp enabled.
 * 2. other client can send request to disable gfx off feature, the request should be honored.
 * 3. other client can cancel their request of disable gfx off feature
 * 4. other client should not send request to enable gfx off feature before disable gfx off feature.
 */

void amdgpu_gfx_off_ctrl(struct amdgpu_device *adev, bool enable)
{
	unsigned long delay = GFX_OFF_DELAY_ENABLE;

	if (!(adev->pm.pp_feature & PP_GFXOFF_MASK))
		return;

	mutex_lock(&adev->gfx.gfx_off_mutex);

	if (enable) {
		/* If the count is already 0, it means there's an imbalance bug somewhere.
		 * Note that the bug may be in a different caller than the one which triggers the
		 * WARN_ON_ONCE.
		 */
		if (WARN_ON_ONCE(adev->gfx.gfx_off_req_count == 0))
			goto unlock;

		adev->gfx.gfx_off_req_count--;

		if (adev->gfx.gfx_off_req_count == 0 &&
		    !adev->gfx.gfx_off_state) {
			/* If going to s2idle, no need to wait */
			if (adev->in_s0ix) {
				if (!amdgpu_dpm_set_powergating_by_smu(adev,
						AMD_IP_BLOCK_TYPE_GFX, true))
					adev->gfx.gfx_off_state = true;
			} else {
				schedule_delayed_work(&adev->gfx.gfx_off_delay_work,
					      delay);
			}
		}
	} else {
		if (adev->gfx.gfx_off_req_count == 0) {
			cancel_delayed_work_sync(&adev->gfx.gfx_off_delay_work);

			if (adev->gfx.gfx_off_state &&
			    !amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_GFX, false)) {
				adev->gfx.gfx_off_state = false;

				if (adev->gfx.funcs->init_spm_golden) {
					dev_dbg(adev->dev,
						"GFXOFF is disabled, re-init SPM golden settings\n");
					amdgpu_gfx_init_spm_golden(adev);
				}
			}
		}

		adev->gfx.gfx_off_req_count++;
	}

unlock:
	mutex_unlock(&adev->gfx.gfx_off_mutex);
}

int amdgpu_set_gfx_off_residency(struct amdgpu_device *adev, bool value)
{
	int r = 0;

	mutex_lock(&adev->gfx.gfx_off_mutex);

	r = amdgpu_dpm_set_residency_gfxoff(adev, value);

	mutex_unlock(&adev->gfx.gfx_off_mutex);

	return r;
}

int amdgpu_get_gfx_off_residency(struct amdgpu_device *adev, u32 *value)
{
	int r = 0;

	mutex_lock(&adev->gfx.gfx_off_mutex);

	r = amdgpu_dpm_get_residency_gfxoff(adev, value);

	mutex_unlock(&adev->gfx.gfx_off_mutex);

	return r;
}

int amdgpu_get_gfx_off_entrycount(struct amdgpu_device *adev, u64 *value)
{
	int r = 0;

	mutex_lock(&adev->gfx.gfx_off_mutex);

	r = amdgpu_dpm_get_entrycount_gfxoff(adev, value);

	mutex_unlock(&adev->gfx.gfx_off_mutex);

	return r;
}

int amdgpu_get_gfx_off_status(struct amdgpu_device *adev, uint32_t *value)
{

	int r = 0;

	mutex_lock(&adev->gfx.gfx_off_mutex);

	r = amdgpu_dpm_get_status_gfxoff(adev, value);

	mutex_unlock(&adev->gfx.gfx_off_mutex);

	return r;
}

int amdgpu_gfx_ras_late_init(struct amdgpu_device *adev, struct ras_common_if *ras_block)
{
	int r;

	if (amdgpu_ras_is_supported(adev, ras_block->block)) {
		if (!amdgpu_persistent_edc_harvesting_supported(adev))
			amdgpu_ras_reset_error_status(adev, AMDGPU_RAS_BLOCK__GFX);

		r = amdgpu_ras_block_late_init(adev, ras_block);
		if (r)
			return r;

		if (adev->gfx.cp_ecc_error_irq.funcs) {
			r = amdgpu_irq_get(adev, &adev->gfx.cp_ecc_error_irq, 0);
			if (r)
				goto late_fini;
		}
	} else {
		amdgpu_ras_feature_enable_on_boot(adev, ras_block, 0);
	}

	return 0;
late_fini:
	amdgpu_ras_block_late_fini(adev, ras_block);
	return r;
}

int amdgpu_gfx_ras_sw_init(struct amdgpu_device *adev)
{
	int err = 0;
	struct amdgpu_gfx_ras *ras = NULL;

	/* adev->gfx.ras is NULL, which means gfx does not
	 * support ras function, then do nothing here.
	 */
	if (!adev->gfx.ras)
		return 0;

	ras = adev->gfx.ras;

	err = amdgpu_ras_register_ras_block(adev, &ras->ras_block);
	if (err) {
		dev_err(adev->dev, "Failed to register gfx ras block!\n");
		return err;
	}

	strcpy(ras->ras_block.ras_comm.name, "gfx");
	ras->ras_block.ras_comm.block = AMDGPU_RAS_BLOCK__GFX;
	ras->ras_block.ras_comm.type = AMDGPU_RAS_ERROR__MULTI_UNCORRECTABLE;
	adev->gfx.ras_if = &ras->ras_block.ras_comm;

	/* If not define special ras_late_init function, use gfx default ras_late_init */
	if (!ras->ras_block.ras_late_init)
		ras->ras_block.ras_late_init = amdgpu_gfx_ras_late_init;

	/* If not defined special ras_cb function, use default ras_cb */
	if (!ras->ras_block.ras_cb)
		ras->ras_block.ras_cb = amdgpu_gfx_process_ras_data_cb;

	return 0;
}

int amdgpu_gfx_poison_consumption_handler(struct amdgpu_device *adev,
						struct amdgpu_iv_entry *entry)
{
	if (adev->gfx.ras && adev->gfx.ras->poison_consumption_handler)
		return adev->gfx.ras->poison_consumption_handler(adev, entry);

	return 0;
}

int amdgpu_gfx_process_ras_data_cb(struct amdgpu_device *adev,
		void *err_data,
		struct amdgpu_iv_entry *entry)
{
	/* TODO ue will trigger an interrupt.
	 *
	 * When “Full RAS” is enabled, the per-IP interrupt sources should
	 * be disabled and the driver should only look for the aggregated
	 * interrupt via sync flood
	 */
	if (!amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__GFX)) {
		kgd2kfd_set_sram_ecc_flag(adev->kfd.dev);
		if (adev->gfx.ras && adev->gfx.ras->ras_block.hw_ops &&
		    adev->gfx.ras->ras_block.hw_ops->query_ras_error_count)
			adev->gfx.ras->ras_block.hw_ops->query_ras_error_count(adev, err_data);
		amdgpu_ras_reset_gpu(adev);
	}
	return AMDGPU_RAS_SUCCESS;
}

int amdgpu_gfx_cp_ecc_error_irq(struct amdgpu_device *adev,
				  struct amdgpu_irq_src *source,
				  struct amdgpu_iv_entry *entry)
{
	struct ras_common_if *ras_if = adev->gfx.ras_if;
	struct ras_dispatch_if ih_data = {
		.entry = entry,
	};

	if (!ras_if)
		return 0;

	ih_data.head = *ras_if;

	DRM_ERROR("CP ECC ERROR IRQ\n");
	amdgpu_ras_interrupt_dispatch(adev, &ih_data);
	return 0;
}

void amdgpu_gfx_ras_error_func(struct amdgpu_device *adev,
		void *ras_error_status,
		void (*func)(struct amdgpu_device *adev, void *ras_error_status,
				int xcc_id))
{
	int i;
	int num_xcc = adev->gfx.xcc_mask ? NUM_XCC(adev->gfx.xcc_mask) : 1;
	uint32_t xcc_mask = GENMASK(num_xcc - 1, 0);
	struct ras_err_data *err_data = (struct ras_err_data *)ras_error_status;

	if (err_data) {
		err_data->ue_count = 0;
		err_data->ce_count = 0;
	}

	for_each_inst(i, xcc_mask)
		func(adev, ras_error_status, i);
}

uint32_t amdgpu_kiq_rreg(struct amdgpu_device *adev, uint32_t reg, uint32_t xcc_id)
{
	signed long r, cnt = 0;
	unsigned long flags;
	uint32_t seq, reg_val_offs = 0, value = 0;
	struct amdgpu_kiq *kiq = &adev->gfx.kiq[xcc_id];
	struct amdgpu_ring *ring = &kiq->ring;

	if (amdgpu_device_skip_hw_access(adev))
		return 0;

	if (adev->mes.ring.sched.ready)
		return amdgpu_mes_rreg(adev, reg);

	BUG_ON(!ring->funcs->emit_rreg);

	spin_lock_irqsave(&kiq->ring_lock, flags);
	if (amdgpu_device_wb_get(adev, &reg_val_offs)) {
		pr_err("critical bug! too many kiq readers\n");
		goto failed_unlock;
	}
	amdgpu_ring_alloc(ring, 32);
	amdgpu_ring_emit_rreg(ring, reg, reg_val_offs);
	r = amdgpu_fence_emit_polling(ring, &seq, MAX_KIQ_REG_WAIT);
	if (r)
		goto failed_undo;

	amdgpu_ring_commit(ring);
	spin_unlock_irqrestore(&kiq->ring_lock, flags);

	r = amdgpu_fence_wait_polling(ring, seq, MAX_KIQ_REG_WAIT);

	/* don't wait anymore for gpu reset case because this way may
	 * block gpu_recover() routine forever, e.g. this virt_kiq_rreg
	 * is triggered in TTM and ttm_bo_lock_delayed_workqueue() will
	 * never return if we keep waiting in virt_kiq_rreg, which cause
	 * gpu_recover() hang there.
	 *
	 * also don't wait anymore for IRQ context
	 * */
	if (r < 1 && (amdgpu_in_reset(adev) || in_interrupt()))
		goto failed_kiq_read;

	might_sleep();
	while (r < 1 && cnt++ < MAX_KIQ_REG_TRY) {
		msleep(MAX_KIQ_REG_BAILOUT_INTERVAL);
		r = amdgpu_fence_wait_polling(ring, seq, MAX_KIQ_REG_WAIT);
	}

	if (cnt > MAX_KIQ_REG_TRY)
		goto failed_kiq_read;

	mb();
	value = adev->wb.wb[reg_val_offs];
	amdgpu_device_wb_free(adev, reg_val_offs);
	return value;

failed_undo:
	amdgpu_ring_undo(ring);
failed_unlock:
	spin_unlock_irqrestore(&kiq->ring_lock, flags);
failed_kiq_read:
	if (reg_val_offs)
		amdgpu_device_wb_free(adev, reg_val_offs);
	dev_err(adev->dev, "failed to read reg:%x\n", reg);
	return ~0;
}

void amdgpu_kiq_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v, uint32_t xcc_id)
{
	signed long r, cnt = 0;
	unsigned long flags;
	uint32_t seq;
	struct amdgpu_kiq *kiq = &adev->gfx.kiq[xcc_id];
	struct amdgpu_ring *ring = &kiq->ring;

	BUG_ON(!ring->funcs->emit_wreg);

	if (amdgpu_device_skip_hw_access(adev))
		return;

	if (adev->mes.ring.sched.ready) {
		amdgpu_mes_wreg(adev, reg, v);
		return;
	}

	spin_lock_irqsave(&kiq->ring_lock, flags);
	amdgpu_ring_alloc(ring, 32);
	amdgpu_ring_emit_wreg(ring, reg, v);
	r = amdgpu_fence_emit_polling(ring, &seq, MAX_KIQ_REG_WAIT);
	if (r)
		goto failed_undo;

	amdgpu_ring_commit(ring);
	spin_unlock_irqrestore(&kiq->ring_lock, flags);

	r = amdgpu_fence_wait_polling(ring, seq, MAX_KIQ_REG_WAIT);

	/* don't wait anymore for gpu reset case because this way may
	 * block gpu_recover() routine forever, e.g. this virt_kiq_rreg
	 * is triggered in TTM and ttm_bo_lock_delayed_workqueue() will
	 * never return if we keep waiting in virt_kiq_rreg, which cause
	 * gpu_recover() hang there.
	 *
	 * also don't wait anymore for IRQ context
	 * */
	if (r < 1 && (amdgpu_in_reset(adev) || in_interrupt()))
		goto failed_kiq_write;

	might_sleep();
	while (r < 1 && cnt++ < MAX_KIQ_REG_TRY) {

		msleep(MAX_KIQ_REG_BAILOUT_INTERVAL);
		r = amdgpu_fence_wait_polling(ring, seq, MAX_KIQ_REG_WAIT);
	}

	if (cnt > MAX_KIQ_REG_TRY)
		goto failed_kiq_write;

	return;

failed_undo:
	amdgpu_ring_undo(ring);
	spin_unlock_irqrestore(&kiq->ring_lock, flags);
failed_kiq_write:
	dev_err(adev->dev, "failed to write reg:%x\n", reg);
}

int amdgpu_gfx_get_num_kcq(struct amdgpu_device *adev)
{
	if (amdgpu_num_kcq == -1) {
		return 8;
	} else if (amdgpu_num_kcq > 8 || amdgpu_num_kcq < 0) {
		dev_warn(adev->dev, "set kernel compute queue number to 8 due to invalid parameter provided by user\n");
		return 8;
	}
	return amdgpu_num_kcq;
}

void amdgpu_gfx_cp_init_microcode(struct amdgpu_device *adev,
				  uint32_t ucode_id)
{
	const struct gfx_firmware_header_v1_0 *cp_hdr;
	const struct gfx_firmware_header_v2_0 *cp_hdr_v2_0;
	struct amdgpu_firmware_info *info = NULL;
	const struct firmware *ucode_fw;
	unsigned int fw_size;

	switch (ucode_id) {
	case AMDGPU_UCODE_ID_CP_PFP:
		cp_hdr = (const struct gfx_firmware_header_v1_0 *)
			adev->gfx.pfp_fw->data;
		adev->gfx.pfp_fw_version =
			le32_to_cpu(cp_hdr->header.ucode_version);
		adev->gfx.pfp_feature_version =
			le32_to_cpu(cp_hdr->ucode_feature_version);
		ucode_fw = adev->gfx.pfp_fw;
		fw_size = le32_to_cpu(cp_hdr->header.ucode_size_bytes);
		break;
	case AMDGPU_UCODE_ID_CP_RS64_PFP:
		cp_hdr_v2_0 = (const struct gfx_firmware_header_v2_0 *)
			adev->gfx.pfp_fw->data;
		adev->gfx.pfp_fw_version =
			le32_to_cpu(cp_hdr_v2_0->header.ucode_version);
		adev->gfx.pfp_feature_version =
			le32_to_cpu(cp_hdr_v2_0->ucode_feature_version);
		ucode_fw = adev->gfx.pfp_fw;
		fw_size = le32_to_cpu(cp_hdr_v2_0->ucode_size_bytes);
		break;
	case AMDGPU_UCODE_ID_CP_RS64_PFP_P0_STACK:
	case AMDGPU_UCODE_ID_CP_RS64_PFP_P1_STACK:
		cp_hdr_v2_0 = (const struct gfx_firmware_header_v2_0 *)
			adev->gfx.pfp_fw->data;
		ucode_fw = adev->gfx.pfp_fw;
		fw_size = le32_to_cpu(cp_hdr_v2_0->data_size_bytes);
		break;
	case AMDGPU_UCODE_ID_CP_ME:
		cp_hdr = (const struct gfx_firmware_header_v1_0 *)
			adev->gfx.me_fw->data;
		adev->gfx.me_fw_version =
			le32_to_cpu(cp_hdr->header.ucode_version);
		adev->gfx.me_feature_version =
			le32_to_cpu(cp_hdr->ucode_feature_version);
		ucode_fw = adev->gfx.me_fw;
		fw_size = le32_to_cpu(cp_hdr->header.ucode_size_bytes);
		break;
	case AMDGPU_UCODE_ID_CP_RS64_ME:
		cp_hdr_v2_0 = (const struct gfx_firmware_header_v2_0 *)
			adev->gfx.me_fw->data;
		adev->gfx.me_fw_version =
			le32_to_cpu(cp_hdr_v2_0->header.ucode_version);
		adev->gfx.me_feature_version =
			le32_to_cpu(cp_hdr_v2_0->ucode_feature_version);
		ucode_fw = adev->gfx.me_fw;
		fw_size = le32_to_cpu(cp_hdr_v2_0->ucode_size_bytes);
		break;
	case AMDGPU_UCODE_ID_CP_RS64_ME_P0_STACK:
	case AMDGPU_UCODE_ID_CP_RS64_ME_P1_STACK:
		cp_hdr_v2_0 = (const struct gfx_firmware_header_v2_0 *)
			adev->gfx.me_fw->data;
		ucode_fw = adev->gfx.me_fw;
		fw_size = le32_to_cpu(cp_hdr_v2_0->data_size_bytes);
		break;
	case AMDGPU_UCODE_ID_CP_CE:
		cp_hdr = (const struct gfx_firmware_header_v1_0 *)
			adev->gfx.ce_fw->data;
		adev->gfx.ce_fw_version =
			le32_to_cpu(cp_hdr->header.ucode_version);
		adev->gfx.ce_feature_version =
			le32_to_cpu(cp_hdr->ucode_feature_version);
		ucode_fw = adev->gfx.ce_fw;
		fw_size = le32_to_cpu(cp_hdr->header.ucode_size_bytes);
		break;
	case AMDGPU_UCODE_ID_CP_MEC1:
		cp_hdr = (const struct gfx_firmware_header_v1_0 *)
			adev->gfx.mec_fw->data;
		adev->gfx.mec_fw_version =
			le32_to_cpu(cp_hdr->header.ucode_version);
		adev->gfx.mec_feature_version =
			le32_to_cpu(cp_hdr->ucode_feature_version);
		ucode_fw = adev->gfx.mec_fw;
		fw_size = le32_to_cpu(cp_hdr->header.ucode_size_bytes) -
			  le32_to_cpu(cp_hdr->jt_size) * 4;
		break;
	case AMDGPU_UCODE_ID_CP_MEC1_JT:
		cp_hdr = (const struct gfx_firmware_header_v1_0 *)
			adev->gfx.mec_fw->data;
		ucode_fw = adev->gfx.mec_fw;
		fw_size = le32_to_cpu(cp_hdr->jt_size) * 4;
		break;
	case AMDGPU_UCODE_ID_CP_MEC2:
		cp_hdr = (const struct gfx_firmware_header_v1_0 *)
			adev->gfx.mec2_fw->data;
		adev->gfx.mec2_fw_version =
			le32_to_cpu(cp_hdr->header.ucode_version);
		adev->gfx.mec2_feature_version =
			le32_to_cpu(cp_hdr->ucode_feature_version);
		ucode_fw = adev->gfx.mec2_fw;
		fw_size = le32_to_cpu(cp_hdr->header.ucode_size_bytes) -
			  le32_to_cpu(cp_hdr->jt_size) * 4;
		break;
	case AMDGPU_UCODE_ID_CP_MEC2_JT:
		cp_hdr = (const struct gfx_firmware_header_v1_0 *)
			adev->gfx.mec2_fw->data;
		ucode_fw = adev->gfx.mec2_fw;
		fw_size = le32_to_cpu(cp_hdr->jt_size) * 4;
		break;
	case AMDGPU_UCODE_ID_CP_RS64_MEC:
		cp_hdr_v2_0 = (const struct gfx_firmware_header_v2_0 *)
			adev->gfx.mec_fw->data;
		adev->gfx.mec_fw_version =
			le32_to_cpu(cp_hdr_v2_0->header.ucode_version);
		adev->gfx.mec_feature_version =
			le32_to_cpu(cp_hdr_v2_0->ucode_feature_version);
		ucode_fw = adev->gfx.mec_fw;
		fw_size = le32_to_cpu(cp_hdr_v2_0->ucode_size_bytes);
		break;
	case AMDGPU_UCODE_ID_CP_RS64_MEC_P0_STACK:
	case AMDGPU_UCODE_ID_CP_RS64_MEC_P1_STACK:
	case AMDGPU_UCODE_ID_CP_RS64_MEC_P2_STACK:
	case AMDGPU_UCODE_ID_CP_RS64_MEC_P3_STACK:
		cp_hdr_v2_0 = (const struct gfx_firmware_header_v2_0 *)
			adev->gfx.mec_fw->data;
		ucode_fw = adev->gfx.mec_fw;
		fw_size = le32_to_cpu(cp_hdr_v2_0->data_size_bytes);
		break;
	default:
		break;
	}

	if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
		info = &adev->firmware.ucode[ucode_id];
		info->ucode_id = ucode_id;
		info->fw = ucode_fw;
		adev->firmware.fw_size += ALIGN(fw_size, PAGE_SIZE);
	}
}

bool amdgpu_gfx_is_master_xcc(struct amdgpu_device *adev, int xcc_id)
{
	return !(xcc_id % (adev->gfx.num_xcc_per_xcp ?
			adev->gfx.num_xcc_per_xcp : 1));
}

static ssize_t amdgpu_gfx_get_current_compute_partition(struct device *dev,
						struct device_attribute *addr,
						char *buf)
{
	struct drm_device *ddev = dev_get_drvdata(dev);
	struct amdgpu_device *adev = drm_to_adev(ddev);
	int mode;

	mode = amdgpu_xcp_query_partition_mode(adev->xcp_mgr,
					       AMDGPU_XCP_FL_NONE);

	return sysfs_emit(buf, "%s\n", amdgpu_gfx_compute_mode_desc(mode));
}

static ssize_t amdgpu_gfx_set_compute_partition(struct device *dev,
						struct device_attribute *addr,
						const char *buf, size_t count)
{
	struct drm_device *ddev = dev_get_drvdata(dev);
	struct amdgpu_device *adev = drm_to_adev(ddev);
	enum amdgpu_gfx_partition mode;
	int ret = 0, num_xcc;

	num_xcc = NUM_XCC(adev->gfx.xcc_mask);
	if (num_xcc % 2 != 0)
		return -EINVAL;

	if (!strncasecmp("SPX", buf, strlen("SPX"))) {
		mode = AMDGPU_SPX_PARTITION_MODE;
	} else if (!strncasecmp("DPX", buf, strlen("DPX"))) {
		/*
		 * DPX mode needs AIDs to be in multiple of 2.
		 * Each AID connects 2 XCCs.
		 */
		if (num_xcc%4)
			return -EINVAL;
		mode = AMDGPU_DPX_PARTITION_MODE;
	} else if (!strncasecmp("TPX", buf, strlen("TPX"))) {
		if (num_xcc != 6)
			return -EINVAL;
		mode = AMDGPU_TPX_PARTITION_MODE;
	} else if (!strncasecmp("QPX", buf, strlen("QPX"))) {
		if (num_xcc != 8)
			return -EINVAL;
		mode = AMDGPU_QPX_PARTITION_MODE;
	} else if (!strncasecmp("CPX", buf, strlen("CPX"))) {
		mode = AMDGPU_CPX_PARTITION_MODE;
	} else {
		return -EINVAL;
	}

	ret = amdgpu_xcp_switch_partition_mode(adev->xcp_mgr, mode);

	if (ret)
		return ret;

	return count;
}

static ssize_t amdgpu_gfx_get_available_compute_partition(struct device *dev,
						struct device_attribute *addr,
						char *buf)
{
	struct drm_device *ddev = dev_get_drvdata(dev);
	struct amdgpu_device *adev = drm_to_adev(ddev);
	char *supported_partition;

	/* TBD */
	switch (NUM_XCC(adev->gfx.xcc_mask)) {
	case 8:
		supported_partition = "SPX, DPX, QPX, CPX";
		break;
	case 6:
		supported_partition = "SPX, TPX, CPX";
		break;
	case 4:
		supported_partition = "SPX, DPX, CPX";
		break;
	/* this seems only existing in emulation phase */
	case 2:
		supported_partition = "SPX, CPX";
		break;
	default:
		supported_partition = "Not supported";
		break;
	}

	return sysfs_emit(buf, "%s\n", supported_partition);
}

static DEVICE_ATTR(current_compute_partition, 0644,
		   amdgpu_gfx_get_current_compute_partition,
		   amdgpu_gfx_set_compute_partition);

static DEVICE_ATTR(available_compute_partition, 0444,
		   amdgpu_gfx_get_available_compute_partition, NULL);

int amdgpu_gfx_sysfs_init(struct amdgpu_device *adev)
{
	int r;

	r = device_create_file(adev->dev, &dev_attr_current_compute_partition);
	if (r)
		return r;

	r = device_create_file(adev->dev, &dev_attr_available_compute_partition);

	return r;
}

void amdgpu_gfx_sysfs_fini(struct amdgpu_device *adev)
{
	device_remove_file(adev->dev, &dev_attr_current_compute_partition);
	device_remove_file(adev->dev, &dev_attr_available_compute_partition);
}
