/*
 * Copyright 2019 Advanced Micro Devices, Inc.
 *
 * 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 "amdgpu_mes.h"
#include "amdgpu.h"
#include "soc15_common.h"
#include "amdgpu_mes_ctx.h"

#define AMDGPU_MES_MAX_NUM_OF_QUEUES_PER_PROCESS 1024
#define AMDGPU_ONE_DOORBELL_SIZE 8

int amdgpu_mes_doorbell_process_slice(struct amdgpu_device *adev)
{
	return roundup(AMDGPU_ONE_DOORBELL_SIZE *
		       AMDGPU_MES_MAX_NUM_OF_QUEUES_PER_PROCESS,
		       PAGE_SIZE);
}

int amdgpu_mes_alloc_process_doorbells(struct amdgpu_device *adev,
				      unsigned int *doorbell_index)
{
	int r = ida_simple_get(&adev->mes.doorbell_ida, 2,
			       adev->mes.max_doorbell_slices,
			       GFP_KERNEL);
	if (r > 0)
		*doorbell_index = r;

	return r;
}

void amdgpu_mes_free_process_doorbells(struct amdgpu_device *adev,
				      unsigned int doorbell_index)
{
	if (doorbell_index)
		ida_simple_remove(&adev->mes.doorbell_ida, doorbell_index);
}

unsigned int amdgpu_mes_get_doorbell_dw_offset_in_bar(
					struct amdgpu_device *adev,
					uint32_t doorbell_index,
					unsigned int doorbell_id)
{
	return ((doorbell_index *
		amdgpu_mes_doorbell_process_slice(adev)) / sizeof(u32) +
		doorbell_id * 2);
}

static int amdgpu_mes_queue_doorbell_get(struct amdgpu_device *adev,
					 struct amdgpu_mes_process *process,
					 int ip_type, uint64_t *doorbell_index)
{
	unsigned int offset, found;

	if (ip_type == AMDGPU_RING_TYPE_SDMA) {
		offset = adev->doorbell_index.sdma_engine[0];
		found = find_next_zero_bit(process->doorbell_bitmap,
					   AMDGPU_MES_MAX_NUM_OF_QUEUES_PER_PROCESS,
					   offset);
	} else {
		found = find_first_zero_bit(process->doorbell_bitmap,
					    AMDGPU_MES_MAX_NUM_OF_QUEUES_PER_PROCESS);
	}

	if (found >= AMDGPU_MES_MAX_NUM_OF_QUEUES_PER_PROCESS) {
		DRM_WARN("No doorbell available\n");
		return -ENOSPC;
	}

	set_bit(found, process->doorbell_bitmap);

	*doorbell_index = amdgpu_mes_get_doorbell_dw_offset_in_bar(adev,
				process->doorbell_index, found);

	return 0;
}

static void amdgpu_mes_queue_doorbell_free(struct amdgpu_device *adev,
					   struct amdgpu_mes_process *process,
					   uint32_t doorbell_index)
{
	unsigned int old, doorbell_id;

	doorbell_id = doorbell_index -
		(process->doorbell_index *
		 amdgpu_mes_doorbell_process_slice(adev)) / sizeof(u32);
	doorbell_id /= 2;

	old = test_and_clear_bit(doorbell_id, process->doorbell_bitmap);
	WARN_ON(!old);
}

static int amdgpu_mes_doorbell_init(struct amdgpu_device *adev)
{
	size_t doorbell_start_offset;
	size_t doorbell_aperture_size;
	size_t doorbell_process_limit;
	size_t aggregated_doorbell_start;
	int i;

	aggregated_doorbell_start = (adev->doorbell_index.max_assignment + 1) * sizeof(u32);
	aggregated_doorbell_start =
		roundup(aggregated_doorbell_start, PAGE_SIZE);

	doorbell_start_offset = aggregated_doorbell_start + PAGE_SIZE;
	doorbell_start_offset =
		roundup(doorbell_start_offset,
			amdgpu_mes_doorbell_process_slice(adev));

	doorbell_aperture_size = adev->doorbell.size;
	doorbell_aperture_size =
			rounddown(doorbell_aperture_size,
				  amdgpu_mes_doorbell_process_slice(adev));

	if (doorbell_aperture_size > doorbell_start_offset)
		doorbell_process_limit =
			(doorbell_aperture_size - doorbell_start_offset) /
			amdgpu_mes_doorbell_process_slice(adev);
	else
		return -ENOSPC;

	adev->mes.doorbell_id_offset = doorbell_start_offset / sizeof(u32);
	adev->mes.max_doorbell_slices = doorbell_process_limit;

	/* allocate Qword range for aggregated doorbell */
	for (i = 0; i < AMDGPU_MES_PRIORITY_NUM_LEVELS; i++)
		adev->mes.aggregated_doorbells[i] =
			aggregated_doorbell_start / sizeof(u32) + i * 2;

	DRM_INFO("max_doorbell_slices=%zu\n", doorbell_process_limit);
	return 0;
}

int amdgpu_mes_init(struct amdgpu_device *adev)
{
	int i, r;

	adev->mes.adev = adev;

	idr_init(&adev->mes.pasid_idr);
	idr_init(&adev->mes.gang_id_idr);
	idr_init(&adev->mes.queue_id_idr);
	ida_init(&adev->mes.doorbell_ida);
	spin_lock_init(&adev->mes.queue_id_lock);
	spin_lock_init(&adev->mes.ring_lock);
	mutex_init(&adev->mes.mutex_hidden);

	adev->mes.total_max_queue = AMDGPU_FENCE_MES_QUEUE_ID_MASK;
	adev->mes.vmid_mask_mmhub = 0xffffff00;
	adev->mes.vmid_mask_gfxhub = 0xffffff00;

	for (i = 0; i < AMDGPU_MES_MAX_COMPUTE_PIPES; i++) {
		/* use only 1st MEC pipes */
		if (i >= 4)
			continue;
		adev->mes.compute_hqd_mask[i] = 0xc;
	}

	for (i = 0; i < AMDGPU_MES_MAX_GFX_PIPES; i++)
		adev->mes.gfx_hqd_mask[i] = i ? 0 : 0xfffffffe;

	for (i = 0; i < AMDGPU_MES_MAX_SDMA_PIPES; i++) {
		if (adev->ip_versions[SDMA0_HWIP][0] < IP_VERSION(6, 0, 0))
			adev->mes.sdma_hqd_mask[i] = i ? 0 : 0x3fc;
		/* zero sdma_hqd_mask for non-existent engine */
		else if (adev->sdma.num_instances == 1)
			adev->mes.sdma_hqd_mask[i] = i ? 0 : 0xfc;
		else
			adev->mes.sdma_hqd_mask[i] = 0xfc;
	}

	r = amdgpu_device_wb_get(adev, &adev->mes.sch_ctx_offs);
	if (r) {
		dev_err(adev->dev,
			"(%d) ring trail_fence_offs wb alloc failed\n", r);
		goto error_ids;
	}
	adev->mes.sch_ctx_gpu_addr =
		adev->wb.gpu_addr + (adev->mes.sch_ctx_offs * 4);
	adev->mes.sch_ctx_ptr =
		(uint64_t *)&adev->wb.wb[adev->mes.sch_ctx_offs];

	r = amdgpu_device_wb_get(adev, &adev->mes.query_status_fence_offs);
	if (r) {
		amdgpu_device_wb_free(adev, adev->mes.sch_ctx_offs);
		dev_err(adev->dev,
			"(%d) query_status_fence_offs wb alloc failed\n", r);
		goto error_ids;
	}
	adev->mes.query_status_fence_gpu_addr =
		adev->wb.gpu_addr + (adev->mes.query_status_fence_offs * 4);
	adev->mes.query_status_fence_ptr =
		(uint64_t *)&adev->wb.wb[adev->mes.query_status_fence_offs];

	r = amdgpu_device_wb_get(adev, &adev->mes.read_val_offs);
	if (r) {
		amdgpu_device_wb_free(adev, adev->mes.sch_ctx_offs);
		amdgpu_device_wb_free(adev, adev->mes.query_status_fence_offs);
		dev_err(adev->dev,
			"(%d) read_val_offs alloc failed\n", r);
		goto error_ids;
	}
	adev->mes.read_val_gpu_addr =
		adev->wb.gpu_addr + (adev->mes.read_val_offs * 4);
	adev->mes.read_val_ptr =
		(uint32_t *)&adev->wb.wb[adev->mes.read_val_offs];

	r = amdgpu_mes_doorbell_init(adev);
	if (r)
		goto error;

	return 0;

error:
	amdgpu_device_wb_free(adev, adev->mes.sch_ctx_offs);
	amdgpu_device_wb_free(adev, adev->mes.query_status_fence_offs);
	amdgpu_device_wb_free(adev, adev->mes.read_val_offs);
error_ids:
	idr_destroy(&adev->mes.pasid_idr);
	idr_destroy(&adev->mes.gang_id_idr);
	idr_destroy(&adev->mes.queue_id_idr);
	ida_destroy(&adev->mes.doorbell_ida);
	mutex_destroy(&adev->mes.mutex_hidden);
	return r;
}

void amdgpu_mes_fini(struct amdgpu_device *adev)
{
	amdgpu_device_wb_free(adev, adev->mes.sch_ctx_offs);
	amdgpu_device_wb_free(adev, adev->mes.query_status_fence_offs);
	amdgpu_device_wb_free(adev, adev->mes.read_val_offs);

	idr_destroy(&adev->mes.pasid_idr);
	idr_destroy(&adev->mes.gang_id_idr);
	idr_destroy(&adev->mes.queue_id_idr);
	ida_destroy(&adev->mes.doorbell_ida);
	mutex_destroy(&adev->mes.mutex_hidden);
}

static void amdgpu_mes_queue_free_mqd(struct amdgpu_mes_queue *q)
{
	amdgpu_bo_free_kernel(&q->mqd_obj,
			      &q->mqd_gpu_addr,
			      &q->mqd_cpu_ptr);
}

int amdgpu_mes_create_process(struct amdgpu_device *adev, int pasid,
			      struct amdgpu_vm *vm)
{
	struct amdgpu_mes_process *process;
	int r;

	/* allocate the mes process buffer */
	process = kzalloc(sizeof(struct amdgpu_mes_process), GFP_KERNEL);
	if (!process) {
		DRM_ERROR("no more memory to create mes process\n");
		return -ENOMEM;
	}

	process->doorbell_bitmap =
		kzalloc(DIV_ROUND_UP(AMDGPU_MES_MAX_NUM_OF_QUEUES_PER_PROCESS,
				     BITS_PER_BYTE), GFP_KERNEL);
	if (!process->doorbell_bitmap) {
		DRM_ERROR("failed to allocate doorbell bitmap\n");
		kfree(process);
		return -ENOMEM;
	}

	/* allocate the process context bo and map it */
	r = amdgpu_bo_create_kernel(adev, AMDGPU_MES_PROC_CTX_SIZE, PAGE_SIZE,
				    AMDGPU_GEM_DOMAIN_GTT,
				    &process->proc_ctx_bo,
				    &process->proc_ctx_gpu_addr,
				    &process->proc_ctx_cpu_ptr);
	if (r) {
		DRM_ERROR("failed to allocate process context bo\n");
		goto clean_up_memory;
	}
	memset(process->proc_ctx_cpu_ptr, 0, AMDGPU_MES_PROC_CTX_SIZE);

	/*
	 * Avoid taking any other locks under MES lock to avoid circular
	 * lock dependencies.
	 */
	amdgpu_mes_lock(&adev->mes);

	/* add the mes process to idr list */
	r = idr_alloc(&adev->mes.pasid_idr, process, pasid, pasid + 1,
		      GFP_KERNEL);
	if (r < 0) {
		DRM_ERROR("failed to lock pasid=%d\n", pasid);
		goto clean_up_ctx;
	}

	/* allocate the starting doorbell index of the process */
	r = amdgpu_mes_alloc_process_doorbells(adev, &process->doorbell_index);
	if (r < 0) {
		DRM_ERROR("failed to allocate doorbell for process\n");
		goto clean_up_pasid;
	}

	DRM_DEBUG("process doorbell index = %d\n", process->doorbell_index);

	INIT_LIST_HEAD(&process->gang_list);
	process->vm = vm;
	process->pasid = pasid;
	process->process_quantum = adev->mes.default_process_quantum;
	process->pd_gpu_addr = amdgpu_bo_gpu_offset(vm->root.bo);

	amdgpu_mes_unlock(&adev->mes);
	return 0;

clean_up_pasid:
	idr_remove(&adev->mes.pasid_idr, pasid);
	amdgpu_mes_unlock(&adev->mes);
clean_up_ctx:
	amdgpu_bo_free_kernel(&process->proc_ctx_bo,
			      &process->proc_ctx_gpu_addr,
			      &process->proc_ctx_cpu_ptr);
clean_up_memory:
	kfree(process->doorbell_bitmap);
	kfree(process);
	return r;
}

void amdgpu_mes_destroy_process(struct amdgpu_device *adev, int pasid)
{
	struct amdgpu_mes_process *process;
	struct amdgpu_mes_gang *gang, *tmp1;
	struct amdgpu_mes_queue *queue, *tmp2;
	struct mes_remove_queue_input queue_input;
	unsigned long flags;
	int r;

	/*
	 * Avoid taking any other locks under MES lock to avoid circular
	 * lock dependencies.
	 */
	amdgpu_mes_lock(&adev->mes);

	process = idr_find(&adev->mes.pasid_idr, pasid);
	if (!process) {
		DRM_WARN("pasid %d doesn't exist\n", pasid);
		amdgpu_mes_unlock(&adev->mes);
		return;
	}

	/* Remove all queues from hardware */
	list_for_each_entry_safe(gang, tmp1, &process->gang_list, list) {
		list_for_each_entry_safe(queue, tmp2, &gang->queue_list, list) {
			spin_lock_irqsave(&adev->mes.queue_id_lock, flags);
			idr_remove(&adev->mes.queue_id_idr, queue->queue_id);
			spin_unlock_irqrestore(&adev->mes.queue_id_lock, flags);

			queue_input.doorbell_offset = queue->doorbell_off;
			queue_input.gang_context_addr = gang->gang_ctx_gpu_addr;

			r = adev->mes.funcs->remove_hw_queue(&adev->mes,
							     &queue_input);
			if (r)
				DRM_WARN("failed to remove hardware queue\n");
		}

		idr_remove(&adev->mes.gang_id_idr, gang->gang_id);
	}

	amdgpu_mes_free_process_doorbells(adev, process->doorbell_index);
	idr_remove(&adev->mes.pasid_idr, pasid);
	amdgpu_mes_unlock(&adev->mes);

	/* free all memory allocated by the process */
	list_for_each_entry_safe(gang, tmp1, &process->gang_list, list) {
		/* free all queues in the gang */
		list_for_each_entry_safe(queue, tmp2, &gang->queue_list, list) {
			amdgpu_mes_queue_free_mqd(queue);
			list_del(&queue->list);
			kfree(queue);
		}
		amdgpu_bo_free_kernel(&gang->gang_ctx_bo,
				      &gang->gang_ctx_gpu_addr,
				      &gang->gang_ctx_cpu_ptr);
		list_del(&gang->list);
		kfree(gang);

	}
	amdgpu_bo_free_kernel(&process->proc_ctx_bo,
			      &process->proc_ctx_gpu_addr,
			      &process->proc_ctx_cpu_ptr);
	kfree(process->doorbell_bitmap);
	kfree(process);
}

int amdgpu_mes_add_gang(struct amdgpu_device *adev, int pasid,
			struct amdgpu_mes_gang_properties *gprops,
			int *gang_id)
{
	struct amdgpu_mes_process *process;
	struct amdgpu_mes_gang *gang;
	int r;

	/* allocate the mes gang buffer */
	gang = kzalloc(sizeof(struct amdgpu_mes_gang), GFP_KERNEL);
	if (!gang) {
		return -ENOMEM;
	}

	/* allocate the gang context bo and map it to cpu space */
	r = amdgpu_bo_create_kernel(adev, AMDGPU_MES_GANG_CTX_SIZE, PAGE_SIZE,
				    AMDGPU_GEM_DOMAIN_GTT,
				    &gang->gang_ctx_bo,
				    &gang->gang_ctx_gpu_addr,
				    &gang->gang_ctx_cpu_ptr);
	if (r) {
		DRM_ERROR("failed to allocate process context bo\n");
		goto clean_up_mem;
	}
	memset(gang->gang_ctx_cpu_ptr, 0, AMDGPU_MES_GANG_CTX_SIZE);

	/*
	 * Avoid taking any other locks under MES lock to avoid circular
	 * lock dependencies.
	 */
	amdgpu_mes_lock(&adev->mes);

	process = idr_find(&adev->mes.pasid_idr, pasid);
	if (!process) {
		DRM_ERROR("pasid %d doesn't exist\n", pasid);
		r = -EINVAL;
		goto clean_up_ctx;
	}

	/* add the mes gang to idr list */
	r = idr_alloc(&adev->mes.gang_id_idr, gang, 1, 0,
		      GFP_KERNEL);
	if (r < 0) {
		DRM_ERROR("failed to allocate idr for gang\n");
		goto clean_up_ctx;
	}

	gang->gang_id = r;
	*gang_id = r;

	INIT_LIST_HEAD(&gang->queue_list);
	gang->process = process;
	gang->priority = gprops->priority;
	gang->gang_quantum = gprops->gang_quantum ?
		gprops->gang_quantum : adev->mes.default_gang_quantum;
	gang->global_priority_level = gprops->global_priority_level;
	gang->inprocess_gang_priority = gprops->inprocess_gang_priority;
	list_add_tail(&gang->list, &process->gang_list);

	amdgpu_mes_unlock(&adev->mes);
	return 0;

clean_up_ctx:
	amdgpu_mes_unlock(&adev->mes);
	amdgpu_bo_free_kernel(&gang->gang_ctx_bo,
			      &gang->gang_ctx_gpu_addr,
			      &gang->gang_ctx_cpu_ptr);
clean_up_mem:
	kfree(gang);
	return r;
}

int amdgpu_mes_remove_gang(struct amdgpu_device *adev, int gang_id)
{
	struct amdgpu_mes_gang *gang;

	/*
	 * Avoid taking any other locks under MES lock to avoid circular
	 * lock dependencies.
	 */
	amdgpu_mes_lock(&adev->mes);

	gang = idr_find(&adev->mes.gang_id_idr, gang_id);
	if (!gang) {
		DRM_ERROR("gang id %d doesn't exist\n", gang_id);
		amdgpu_mes_unlock(&adev->mes);
		return -EINVAL;
	}

	if (!list_empty(&gang->queue_list)) {
		DRM_ERROR("queue list is not empty\n");
		amdgpu_mes_unlock(&adev->mes);
		return -EBUSY;
	}

	idr_remove(&adev->mes.gang_id_idr, gang->gang_id);
	list_del(&gang->list);
	amdgpu_mes_unlock(&adev->mes);

	amdgpu_bo_free_kernel(&gang->gang_ctx_bo,
			      &gang->gang_ctx_gpu_addr,
			      &gang->gang_ctx_cpu_ptr);

	kfree(gang);

	return 0;
}

int amdgpu_mes_suspend(struct amdgpu_device *adev)
{
	struct idr *idp;
	struct amdgpu_mes_process *process;
	struct amdgpu_mes_gang *gang;
	struct mes_suspend_gang_input input;
	int r, pasid;

	/*
	 * Avoid taking any other locks under MES lock to avoid circular
	 * lock dependencies.
	 */
	amdgpu_mes_lock(&adev->mes);

	idp = &adev->mes.pasid_idr;

	idr_for_each_entry(idp, process, pasid) {
		list_for_each_entry(gang, &process->gang_list, list) {
			r = adev->mes.funcs->suspend_gang(&adev->mes, &input);
			if (r)
				DRM_ERROR("failed to suspend pasid %d gangid %d",
					 pasid, gang->gang_id);
		}
	}

	amdgpu_mes_unlock(&adev->mes);
	return 0;
}

int amdgpu_mes_resume(struct amdgpu_device *adev)
{
	struct idr *idp;
	struct amdgpu_mes_process *process;
	struct amdgpu_mes_gang *gang;
	struct mes_resume_gang_input input;
	int r, pasid;

	/*
	 * Avoid taking any other locks under MES lock to avoid circular
	 * lock dependencies.
	 */
	amdgpu_mes_lock(&adev->mes);

	idp = &adev->mes.pasid_idr;

	idr_for_each_entry(idp, process, pasid) {
		list_for_each_entry(gang, &process->gang_list, list) {
			r = adev->mes.funcs->resume_gang(&adev->mes, &input);
			if (r)
				DRM_ERROR("failed to resume pasid %d gangid %d",
					 pasid, gang->gang_id);
		}
	}

	amdgpu_mes_unlock(&adev->mes);
	return 0;
}

static int amdgpu_mes_queue_alloc_mqd(struct amdgpu_device *adev,
				     struct amdgpu_mes_queue *q,
				     struct amdgpu_mes_queue_properties *p)
{
	struct amdgpu_mqd *mqd_mgr = &adev->mqds[p->queue_type];
	u32 mqd_size = mqd_mgr->mqd_size;
	int r;

	r = amdgpu_bo_create_kernel(adev, mqd_size, PAGE_SIZE,
				    AMDGPU_GEM_DOMAIN_GTT,
				    &q->mqd_obj,
				    &q->mqd_gpu_addr, &q->mqd_cpu_ptr);
	if (r) {
		dev_warn(adev->dev, "failed to create queue mqd bo (%d)", r);
		return r;
	}
	memset(q->mqd_cpu_ptr, 0, mqd_size);

	r = amdgpu_bo_reserve(q->mqd_obj, false);
	if (unlikely(r != 0))
		goto clean_up;

	return 0;

clean_up:
	amdgpu_bo_free_kernel(&q->mqd_obj,
			      &q->mqd_gpu_addr,
			      &q->mqd_cpu_ptr);
	return r;
}

static void amdgpu_mes_queue_init_mqd(struct amdgpu_device *adev,
				     struct amdgpu_mes_queue *q,
				     struct amdgpu_mes_queue_properties *p)
{
	struct amdgpu_mqd *mqd_mgr = &adev->mqds[p->queue_type];
	struct amdgpu_mqd_prop mqd_prop = {0};

	mqd_prop.mqd_gpu_addr = q->mqd_gpu_addr;
	mqd_prop.hqd_base_gpu_addr = p->hqd_base_gpu_addr;
	mqd_prop.rptr_gpu_addr = p->rptr_gpu_addr;
	mqd_prop.wptr_gpu_addr = p->wptr_gpu_addr;
	mqd_prop.queue_size = p->queue_size;
	mqd_prop.use_doorbell = true;
	mqd_prop.doorbell_index = p->doorbell_off;
	mqd_prop.eop_gpu_addr = p->eop_gpu_addr;
	mqd_prop.hqd_pipe_priority = p->hqd_pipe_priority;
	mqd_prop.hqd_queue_priority = p->hqd_queue_priority;
	mqd_prop.hqd_active = false;

	mqd_mgr->init_mqd(adev, q->mqd_cpu_ptr, &mqd_prop);

	amdgpu_bo_unreserve(q->mqd_obj);
}

int amdgpu_mes_add_hw_queue(struct amdgpu_device *adev, int gang_id,
			    struct amdgpu_mes_queue_properties *qprops,
			    int *queue_id)
{
	struct amdgpu_mes_queue *queue;
	struct amdgpu_mes_gang *gang;
	struct mes_add_queue_input queue_input;
	unsigned long flags;
	int r;

	/* allocate the mes queue buffer */
	queue = kzalloc(sizeof(struct amdgpu_mes_queue), GFP_KERNEL);
	if (!queue) {
		DRM_ERROR("Failed to allocate memory for queue\n");
		return -ENOMEM;
	}

	/* Allocate the queue mqd */
	r = amdgpu_mes_queue_alloc_mqd(adev, queue, qprops);
	if (r)
		goto clean_up_memory;

	/*
	 * Avoid taking any other locks under MES lock to avoid circular
	 * lock dependencies.
	 */
	amdgpu_mes_lock(&adev->mes);

	gang = idr_find(&adev->mes.gang_id_idr, gang_id);
	if (!gang) {
		DRM_ERROR("gang id %d doesn't exist\n", gang_id);
		r = -EINVAL;
		goto clean_up_mqd;
	}

	/* add the mes gang to idr list */
	spin_lock_irqsave(&adev->mes.queue_id_lock, flags);
	r = idr_alloc(&adev->mes.queue_id_idr, queue, 1, 0,
		      GFP_ATOMIC);
	if (r < 0) {
		spin_unlock_irqrestore(&adev->mes.queue_id_lock, flags);
		goto clean_up_mqd;
	}
	spin_unlock_irqrestore(&adev->mes.queue_id_lock, flags);
	*queue_id = queue->queue_id = r;

	/* allocate a doorbell index for the queue */
	r = amdgpu_mes_queue_doorbell_get(adev, gang->process,
					  qprops->queue_type,
					  &qprops->doorbell_off);
	if (r)
		goto clean_up_queue_id;

	/* initialize the queue mqd */
	amdgpu_mes_queue_init_mqd(adev, queue, qprops);

	/* add hw queue to mes */
	queue_input.process_id = gang->process->pasid;

	queue_input.page_table_base_addr =
		adev->vm_manager.vram_base_offset + gang->process->pd_gpu_addr -
		adev->gmc.vram_start;

	queue_input.process_va_start = 0;
	queue_input.process_va_end =
		(adev->vm_manager.max_pfn - 1) << AMDGPU_GPU_PAGE_SHIFT;
	queue_input.process_quantum = gang->process->process_quantum;
	queue_input.process_context_addr = gang->process->proc_ctx_gpu_addr;
	queue_input.gang_quantum = gang->gang_quantum;
	queue_input.gang_context_addr = gang->gang_ctx_gpu_addr;
	queue_input.inprocess_gang_priority = gang->inprocess_gang_priority;
	queue_input.gang_global_priority_level = gang->global_priority_level;
	queue_input.doorbell_offset = qprops->doorbell_off;
	queue_input.mqd_addr = queue->mqd_gpu_addr;
	queue_input.wptr_addr = qprops->wptr_gpu_addr;
	queue_input.wptr_mc_addr = qprops->wptr_mc_addr;
	queue_input.queue_type = qprops->queue_type;
	queue_input.paging = qprops->paging;
	queue_input.is_kfd_process = 0;

	r = adev->mes.funcs->add_hw_queue(&adev->mes, &queue_input);
	if (r) {
		DRM_ERROR("failed to add hardware queue to MES, doorbell=0x%llx\n",
			  qprops->doorbell_off);
		goto clean_up_doorbell;
	}

	DRM_DEBUG("MES hw queue was added, pasid=%d, gang id=%d, "
		  "queue type=%d, doorbell=0x%llx\n",
		  gang->process->pasid, gang_id, qprops->queue_type,
		  qprops->doorbell_off);

	queue->ring = qprops->ring;
	queue->doorbell_off = qprops->doorbell_off;
	queue->wptr_gpu_addr = qprops->wptr_gpu_addr;
	queue->queue_type = qprops->queue_type;
	queue->paging = qprops->paging;
	queue->gang = gang;
	queue->ring->mqd_ptr = queue->mqd_cpu_ptr;
	list_add_tail(&queue->list, &gang->queue_list);

	amdgpu_mes_unlock(&adev->mes);
	return 0;

clean_up_doorbell:
	amdgpu_mes_queue_doorbell_free(adev, gang->process,
				       qprops->doorbell_off);
clean_up_queue_id:
	spin_lock_irqsave(&adev->mes.queue_id_lock, flags);
	idr_remove(&adev->mes.queue_id_idr, queue->queue_id);
	spin_unlock_irqrestore(&adev->mes.queue_id_lock, flags);
clean_up_mqd:
	amdgpu_mes_unlock(&adev->mes);
	amdgpu_mes_queue_free_mqd(queue);
clean_up_memory:
	kfree(queue);
	return r;
}

int amdgpu_mes_remove_hw_queue(struct amdgpu_device *adev, int queue_id)
{
	unsigned long flags;
	struct amdgpu_mes_queue *queue;
	struct amdgpu_mes_gang *gang;
	struct mes_remove_queue_input queue_input;
	int r;

	/*
	 * Avoid taking any other locks under MES lock to avoid circular
	 * lock dependencies.
	 */
	amdgpu_mes_lock(&adev->mes);

	/* remove the mes gang from idr list */
	spin_lock_irqsave(&adev->mes.queue_id_lock, flags);

	queue = idr_find(&adev->mes.queue_id_idr, queue_id);
	if (!queue) {
		spin_unlock_irqrestore(&adev->mes.queue_id_lock, flags);
		amdgpu_mes_unlock(&adev->mes);
		DRM_ERROR("queue id %d doesn't exist\n", queue_id);
		return -EINVAL;
	}

	idr_remove(&adev->mes.queue_id_idr, queue_id);
	spin_unlock_irqrestore(&adev->mes.queue_id_lock, flags);

	DRM_DEBUG("try to remove queue, doorbell off = 0x%llx\n",
		  queue->doorbell_off);

	gang = queue->gang;
	queue_input.doorbell_offset = queue->doorbell_off;
	queue_input.gang_context_addr = gang->gang_ctx_gpu_addr;

	r = adev->mes.funcs->remove_hw_queue(&adev->mes, &queue_input);
	if (r)
		DRM_ERROR("failed to remove hardware queue, queue id = %d\n",
			  queue_id);

	list_del(&queue->list);
	amdgpu_mes_queue_doorbell_free(adev, gang->process,
				       queue->doorbell_off);
	amdgpu_mes_unlock(&adev->mes);

	amdgpu_mes_queue_free_mqd(queue);
	kfree(queue);
	return 0;
}

int amdgpu_mes_unmap_legacy_queue(struct amdgpu_device *adev,
				  struct amdgpu_ring *ring,
				  enum amdgpu_unmap_queues_action action,
				  u64 gpu_addr, u64 seq)
{
	struct mes_unmap_legacy_queue_input queue_input;
	int r;

	queue_input.action = action;
	queue_input.queue_type = ring->funcs->type;
	queue_input.doorbell_offset = ring->doorbell_index;
	queue_input.pipe_id = ring->pipe;
	queue_input.queue_id = ring->queue;
	queue_input.trail_fence_addr = gpu_addr;
	queue_input.trail_fence_data = seq;

	r = adev->mes.funcs->unmap_legacy_queue(&adev->mes, &queue_input);
	if (r)
		DRM_ERROR("failed to unmap legacy queue\n");

	return r;
}

uint32_t amdgpu_mes_rreg(struct amdgpu_device *adev, uint32_t reg)
{
	struct mes_misc_op_input op_input;
	int r, val = 0;

	op_input.op = MES_MISC_OP_READ_REG;
	op_input.read_reg.reg_offset = reg;
	op_input.read_reg.buffer_addr = adev->mes.read_val_gpu_addr;

	if (!adev->mes.funcs->misc_op) {
		DRM_ERROR("mes rreg is not supported!\n");
		goto error;
	}

	r = adev->mes.funcs->misc_op(&adev->mes, &op_input);
	if (r)
		DRM_ERROR("failed to read reg (0x%x)\n", reg);
	else
		val = *(adev->mes.read_val_ptr);

error:
	return val;
}

int amdgpu_mes_wreg(struct amdgpu_device *adev,
		    uint32_t reg, uint32_t val)
{
	struct mes_misc_op_input op_input;
	int r;

	op_input.op = MES_MISC_OP_WRITE_REG;
	op_input.write_reg.reg_offset = reg;
	op_input.write_reg.reg_value = val;

	if (!adev->mes.funcs->misc_op) {
		DRM_ERROR("mes wreg is not supported!\n");
		r = -EINVAL;
		goto error;
	}

	r = adev->mes.funcs->misc_op(&adev->mes, &op_input);
	if (r)
		DRM_ERROR("failed to write reg (0x%x)\n", reg);

error:
	return r;
}

int amdgpu_mes_reg_write_reg_wait(struct amdgpu_device *adev,
				  uint32_t reg0, uint32_t reg1,
				  uint32_t ref, uint32_t mask)
{
	struct mes_misc_op_input op_input;
	int r;

	op_input.op = MES_MISC_OP_WRM_REG_WR_WAIT;
	op_input.wrm_reg.reg0 = reg0;
	op_input.wrm_reg.reg1 = reg1;
	op_input.wrm_reg.ref = ref;
	op_input.wrm_reg.mask = mask;

	if (!adev->mes.funcs->misc_op) {
		DRM_ERROR("mes reg_write_reg_wait is not supported!\n");
		r = -EINVAL;
		goto error;
	}

	r = adev->mes.funcs->misc_op(&adev->mes, &op_input);
	if (r)
		DRM_ERROR("failed to reg_write_reg_wait\n");

error:
	return r;
}

int amdgpu_mes_reg_wait(struct amdgpu_device *adev, uint32_t reg,
			uint32_t val, uint32_t mask)
{
	struct mes_misc_op_input op_input;
	int r;

	op_input.op = MES_MISC_OP_WRM_REG_WAIT;
	op_input.wrm_reg.reg0 = reg;
	op_input.wrm_reg.ref = val;
	op_input.wrm_reg.mask = mask;

	if (!adev->mes.funcs->misc_op) {
		DRM_ERROR("mes reg wait is not supported!\n");
		r = -EINVAL;
		goto error;
	}

	r = adev->mes.funcs->misc_op(&adev->mes, &op_input);
	if (r)
		DRM_ERROR("failed to reg_write_reg_wait\n");

error:
	return r;
}

static void
amdgpu_mes_ring_to_queue_props(struct amdgpu_device *adev,
			       struct amdgpu_ring *ring,
			       struct amdgpu_mes_queue_properties *props)
{
	props->queue_type = ring->funcs->type;
	props->hqd_base_gpu_addr = ring->gpu_addr;
	props->rptr_gpu_addr = ring->rptr_gpu_addr;
	props->wptr_gpu_addr = ring->wptr_gpu_addr;
	props->wptr_mc_addr =
		ring->mes_ctx->meta_data_mc_addr + ring->wptr_offs;
	props->queue_size = ring->ring_size;
	props->eop_gpu_addr = ring->eop_gpu_addr;
	props->hqd_pipe_priority = AMDGPU_GFX_PIPE_PRIO_NORMAL;
	props->hqd_queue_priority = AMDGPU_GFX_QUEUE_PRIORITY_MINIMUM;
	props->paging = false;
	props->ring = ring;
}

#define DEFINE_AMDGPU_MES_CTX_GET_OFFS_ENG(_eng)			\
do {									\
       if (id_offs < AMDGPU_MES_CTX_MAX_OFFS)				\
		return offsetof(struct amdgpu_mes_ctx_meta_data,	\
				_eng[ring->idx].slots[id_offs]);        \
       else if (id_offs == AMDGPU_MES_CTX_RING_OFFS)			\
		return offsetof(struct amdgpu_mes_ctx_meta_data,        \
				_eng[ring->idx].ring);                  \
       else if (id_offs == AMDGPU_MES_CTX_IB_OFFS)			\
		return offsetof(struct amdgpu_mes_ctx_meta_data,        \
				_eng[ring->idx].ib);                    \
       else if (id_offs == AMDGPU_MES_CTX_PADDING_OFFS)			\
		return offsetof(struct amdgpu_mes_ctx_meta_data,        \
				_eng[ring->idx].padding);               \
} while(0)

int amdgpu_mes_ctx_get_offs(struct amdgpu_ring *ring, unsigned int id_offs)
{
	switch (ring->funcs->type) {
	case AMDGPU_RING_TYPE_GFX:
		DEFINE_AMDGPU_MES_CTX_GET_OFFS_ENG(gfx);
		break;
	case AMDGPU_RING_TYPE_COMPUTE:
		DEFINE_AMDGPU_MES_CTX_GET_OFFS_ENG(compute);
		break;
	case AMDGPU_RING_TYPE_SDMA:
		DEFINE_AMDGPU_MES_CTX_GET_OFFS_ENG(sdma);
		break;
	default:
		break;
	}

	WARN_ON(1);
	return -EINVAL;
}

int amdgpu_mes_add_ring(struct amdgpu_device *adev, int gang_id,
			int queue_type, int idx,
			struct amdgpu_mes_ctx_data *ctx_data,
			struct amdgpu_ring **out)
{
	struct amdgpu_ring *ring;
	struct amdgpu_mes_gang *gang;
	struct amdgpu_mes_queue_properties qprops = {0};
	int r, queue_id, pasid;

	/*
	 * Avoid taking any other locks under MES lock to avoid circular
	 * lock dependencies.
	 */
	amdgpu_mes_lock(&adev->mes);
	gang = idr_find(&adev->mes.gang_id_idr, gang_id);
	if (!gang) {
		DRM_ERROR("gang id %d doesn't exist\n", gang_id);
		amdgpu_mes_unlock(&adev->mes);
		return -EINVAL;
	}
	pasid = gang->process->pasid;

	ring = kzalloc(sizeof(struct amdgpu_ring), GFP_KERNEL);
	if (!ring) {
		amdgpu_mes_unlock(&adev->mes);
		return -ENOMEM;
	}

	ring->ring_obj = NULL;
	ring->use_doorbell = true;
	ring->is_mes_queue = true;
	ring->mes_ctx = ctx_data;
	ring->idx = idx;
	ring->no_scheduler = true;

	if (queue_type == AMDGPU_RING_TYPE_COMPUTE) {
		int offset = offsetof(struct amdgpu_mes_ctx_meta_data,
				      compute[ring->idx].mec_hpd);
		ring->eop_gpu_addr =
			amdgpu_mes_ctx_get_offs_gpu_addr(ring, offset);
	}

	switch (queue_type) {
	case AMDGPU_RING_TYPE_GFX:
		ring->funcs = adev->gfx.gfx_ring[0].funcs;
		break;
	case AMDGPU_RING_TYPE_COMPUTE:
		ring->funcs = adev->gfx.compute_ring[0].funcs;
		break;
	case AMDGPU_RING_TYPE_SDMA:
		ring->funcs = adev->sdma.instance[0].ring.funcs;
		break;
	default:
		BUG();
	}

	r = amdgpu_ring_init(adev, ring, 1024, NULL, 0,
			     AMDGPU_RING_PRIO_DEFAULT, NULL);
	if (r)
		goto clean_up_memory;

	amdgpu_mes_ring_to_queue_props(adev, ring, &qprops);

	dma_fence_wait(gang->process->vm->last_update, false);
	dma_fence_wait(ctx_data->meta_data_va->last_pt_update, false);
	amdgpu_mes_unlock(&adev->mes);

	r = amdgpu_mes_add_hw_queue(adev, gang_id, &qprops, &queue_id);
	if (r)
		goto clean_up_ring;

	ring->hw_queue_id = queue_id;
	ring->doorbell_index = qprops.doorbell_off;

	if (queue_type == AMDGPU_RING_TYPE_GFX)
		sprintf(ring->name, "gfx_%d.%d.%d", pasid, gang_id, queue_id);
	else if (queue_type == AMDGPU_RING_TYPE_COMPUTE)
		sprintf(ring->name, "compute_%d.%d.%d", pasid, gang_id,
			queue_id);
	else if (queue_type == AMDGPU_RING_TYPE_SDMA)
		sprintf(ring->name, "sdma_%d.%d.%d", pasid, gang_id,
			queue_id);
	else
		BUG();

	*out = ring;
	return 0;

clean_up_ring:
	amdgpu_ring_fini(ring);
clean_up_memory:
	kfree(ring);
	amdgpu_mes_unlock(&adev->mes);
	return r;
}

void amdgpu_mes_remove_ring(struct amdgpu_device *adev,
			    struct amdgpu_ring *ring)
{
	if (!ring)
		return;

	amdgpu_mes_remove_hw_queue(adev, ring->hw_queue_id);
	amdgpu_ring_fini(ring);
	kfree(ring);
}

uint32_t amdgpu_mes_get_aggregated_doorbell_index(struct amdgpu_device *adev,
						   enum amdgpu_mes_priority_level prio)
{
	return adev->mes.aggregated_doorbells[prio];
}

int amdgpu_mes_ctx_alloc_meta_data(struct amdgpu_device *adev,
				   struct amdgpu_mes_ctx_data *ctx_data)
{
	int r;

	r = amdgpu_bo_create_kernel(adev,
			    sizeof(struct amdgpu_mes_ctx_meta_data),
			    PAGE_SIZE, AMDGPU_GEM_DOMAIN_GTT,
			    &ctx_data->meta_data_obj,
			    &ctx_data->meta_data_mc_addr,
			    &ctx_data->meta_data_ptr);
	if (!ctx_data->meta_data_obj)
		return -ENOMEM;

	memset(ctx_data->meta_data_ptr, 0,
	       sizeof(struct amdgpu_mes_ctx_meta_data));

	return 0;
}

void amdgpu_mes_ctx_free_meta_data(struct amdgpu_mes_ctx_data *ctx_data)
{
	if (ctx_data->meta_data_obj)
		amdgpu_bo_free_kernel(&ctx_data->meta_data_obj,
				      &ctx_data->meta_data_mc_addr,
				      &ctx_data->meta_data_ptr);
}

int amdgpu_mes_ctx_map_meta_data(struct amdgpu_device *adev,
				 struct amdgpu_vm *vm,
				 struct amdgpu_mes_ctx_data *ctx_data)
{
	struct amdgpu_bo_va *bo_va;
	struct ww_acquire_ctx ticket;
	struct list_head list;
	struct amdgpu_bo_list_entry pd;
	struct ttm_validate_buffer csa_tv;
	struct amdgpu_sync sync;
	int r;

	amdgpu_sync_create(&sync);
	INIT_LIST_HEAD(&list);
	INIT_LIST_HEAD(&csa_tv.head);

	csa_tv.bo = &ctx_data->meta_data_obj->tbo;
	csa_tv.num_shared = 1;

	list_add(&csa_tv.head, &list);
	amdgpu_vm_get_pd_bo(vm, &list, &pd);

	r = ttm_eu_reserve_buffers(&ticket, &list, true, NULL);
	if (r) {
		DRM_ERROR("failed to reserve meta data BO: err=%d\n", r);
		return r;
	}

	bo_va = amdgpu_vm_bo_add(adev, vm, ctx_data->meta_data_obj);
	if (!bo_va) {
		ttm_eu_backoff_reservation(&ticket, &list);
		DRM_ERROR("failed to create bo_va for meta data BO\n");
		return -ENOMEM;
	}

	r = amdgpu_vm_bo_map(adev, bo_va, ctx_data->meta_data_gpu_addr, 0,
			     sizeof(struct amdgpu_mes_ctx_meta_data),
			     AMDGPU_PTE_READABLE | AMDGPU_PTE_WRITEABLE |
			     AMDGPU_PTE_EXECUTABLE);

	if (r) {
		DRM_ERROR("failed to do bo_map on meta data, err=%d\n", r);
		goto error;
	}

	r = amdgpu_vm_bo_update(adev, bo_va, false);
	if (r) {
		DRM_ERROR("failed to do vm_bo_update on meta data\n");
		goto error;
	}
	amdgpu_sync_fence(&sync, bo_va->last_pt_update);

	r = amdgpu_vm_update_pdes(adev, vm, false);
	if (r) {
		DRM_ERROR("failed to update pdes on meta data\n");
		goto error;
	}
	amdgpu_sync_fence(&sync, vm->last_update);

	amdgpu_sync_wait(&sync, false);
	ttm_eu_backoff_reservation(&ticket, &list);

	amdgpu_sync_free(&sync);
	ctx_data->meta_data_va = bo_va;
	return 0;

error:
	amdgpu_vm_bo_del(adev, bo_va);
	ttm_eu_backoff_reservation(&ticket, &list);
	amdgpu_sync_free(&sync);
	return r;
}

int amdgpu_mes_ctx_unmap_meta_data(struct amdgpu_device *adev,
				   struct amdgpu_mes_ctx_data *ctx_data)
{
	struct amdgpu_bo_va *bo_va = ctx_data->meta_data_va;
	struct amdgpu_bo *bo = ctx_data->meta_data_obj;
	struct amdgpu_vm *vm = bo_va->base.vm;
	struct amdgpu_bo_list_entry vm_pd;
	struct list_head list, duplicates;
	struct dma_fence *fence = NULL;
	struct ttm_validate_buffer tv;
	struct ww_acquire_ctx ticket;
	long r = 0;

	INIT_LIST_HEAD(&list);
	INIT_LIST_HEAD(&duplicates);

	tv.bo = &bo->tbo;
	tv.num_shared = 2;
	list_add(&tv.head, &list);

	amdgpu_vm_get_pd_bo(vm, &list, &vm_pd);

	r = ttm_eu_reserve_buffers(&ticket, &list, false, &duplicates);
	if (r) {
		dev_err(adev->dev, "leaking bo va because "
			"we fail to reserve bo (%ld)\n", r);
		return r;
	}

	amdgpu_vm_bo_del(adev, bo_va);
	if (!amdgpu_vm_ready(vm))
		goto out_unlock;

	r = dma_resv_get_singleton(bo->tbo.base.resv, DMA_RESV_USAGE_BOOKKEEP, &fence);
	if (r)
		goto out_unlock;
	if (fence) {
		amdgpu_bo_fence(bo, fence, true);
		fence = NULL;
	}

	r = amdgpu_vm_clear_freed(adev, vm, &fence);
	if (r || !fence)
		goto out_unlock;

	dma_fence_wait(fence, false);
	amdgpu_bo_fence(bo, fence, true);
	dma_fence_put(fence);

out_unlock:
	if (unlikely(r < 0))
		dev_err(adev->dev, "failed to clear page tables (%ld)\n", r);
	ttm_eu_backoff_reservation(&ticket, &list);

	return r;
}

static int amdgpu_mes_test_create_gang_and_queues(struct amdgpu_device *adev,
					  int pasid, int *gang_id,
					  int queue_type, int num_queue,
					  struct amdgpu_ring **added_rings,
					  struct amdgpu_mes_ctx_data *ctx_data)
{
	struct amdgpu_ring *ring;
	struct amdgpu_mes_gang_properties gprops = {0};
	int r, j;

	/* create a gang for the process */
	gprops.priority = AMDGPU_MES_PRIORITY_LEVEL_NORMAL;
	gprops.gang_quantum = adev->mes.default_gang_quantum;
	gprops.inprocess_gang_priority = AMDGPU_MES_PRIORITY_LEVEL_NORMAL;
	gprops.priority_level = AMDGPU_MES_PRIORITY_LEVEL_NORMAL;
	gprops.global_priority_level = AMDGPU_MES_PRIORITY_LEVEL_NORMAL;

	r = amdgpu_mes_add_gang(adev, pasid, &gprops, gang_id);
	if (r) {
		DRM_ERROR("failed to add gang\n");
		return r;
	}

	/* create queues for the gang */
	for (j = 0; j < num_queue; j++) {
		r = amdgpu_mes_add_ring(adev, *gang_id, queue_type, j,
					ctx_data, &ring);
		if (r) {
			DRM_ERROR("failed to add ring\n");
			break;
		}

		DRM_INFO("ring %s was added\n", ring->name);
		added_rings[j] = ring;
	}

	return 0;
}

static int amdgpu_mes_test_queues(struct amdgpu_ring **added_rings)
{
	struct amdgpu_ring *ring;
	int i, r;

	for (i = 0; i < AMDGPU_MES_CTX_MAX_RINGS; i++) {
		ring = added_rings[i];
		if (!ring)
			continue;

		r = amdgpu_ring_test_ring(ring);
		if (r) {
			DRM_DEV_ERROR(ring->adev->dev,
				      "ring %s test failed (%d)\n",
				      ring->name, r);
			return r;
		} else
			DRM_INFO("ring %s test pass\n", ring->name);

		r = amdgpu_ring_test_ib(ring, 1000 * 10);
		if (r) {
			DRM_DEV_ERROR(ring->adev->dev,
				      "ring %s ib test failed (%d)\n",
				      ring->name, r);
			return r;
		} else
			DRM_INFO("ring %s ib test pass\n", ring->name);
	}

	return 0;
}

int amdgpu_mes_self_test(struct amdgpu_device *adev)
{
	struct amdgpu_vm *vm = NULL;
	struct amdgpu_mes_ctx_data ctx_data = {0};
	struct amdgpu_ring *added_rings[AMDGPU_MES_CTX_MAX_RINGS] = { NULL };
	int gang_ids[3] = {0};
	int queue_types[][2] = { { AMDGPU_RING_TYPE_GFX,
				   AMDGPU_MES_CTX_MAX_GFX_RINGS},
				 { AMDGPU_RING_TYPE_COMPUTE,
				   AMDGPU_MES_CTX_MAX_COMPUTE_RINGS},
				 { AMDGPU_RING_TYPE_SDMA,
				   AMDGPU_MES_CTX_MAX_SDMA_RINGS } };
	int i, r, pasid, k = 0;

	pasid = amdgpu_pasid_alloc(16);
	if (pasid < 0) {
		dev_warn(adev->dev, "No more PASIDs available!");
		pasid = 0;
	}

	vm = kzalloc(sizeof(*vm), GFP_KERNEL);
	if (!vm) {
		r = -ENOMEM;
		goto error_pasid;
	}

	r = amdgpu_vm_init(adev, vm);
	if (r) {
		DRM_ERROR("failed to initialize vm\n");
		goto error_pasid;
	}

	r = amdgpu_mes_ctx_alloc_meta_data(adev, &ctx_data);
	if (r) {
		DRM_ERROR("failed to alloc ctx meta data\n");
		goto error_fini;
	}

	ctx_data.meta_data_gpu_addr = AMDGPU_VA_RESERVED_SIZE;
	r = amdgpu_mes_ctx_map_meta_data(adev, vm, &ctx_data);
	if (r) {
		DRM_ERROR("failed to map ctx meta data\n");
		goto error_vm;
	}

	r = amdgpu_mes_create_process(adev, pasid, vm);
	if (r) {
		DRM_ERROR("failed to create MES process\n");
		goto error_vm;
	}

	for (i = 0; i < ARRAY_SIZE(queue_types); i++) {
		/* On GFX v10.3, fw hasn't supported to map sdma queue. */
		if (adev->ip_versions[GC_HWIP][0] >= IP_VERSION(10, 3, 0) &&
		    adev->ip_versions[GC_HWIP][0] < IP_VERSION(11, 0, 0) &&
		    queue_types[i][0] == AMDGPU_RING_TYPE_SDMA)
			continue;

		r = amdgpu_mes_test_create_gang_and_queues(adev, pasid,
							   &gang_ids[i],
							   queue_types[i][0],
							   queue_types[i][1],
							   &added_rings[k],
							   &ctx_data);
		if (r)
			goto error_queues;

		k += queue_types[i][1];
	}

	/* start ring test and ib test for MES queues */
	amdgpu_mes_test_queues(added_rings);

error_queues:
	/* remove all queues */
	for (i = 0; i < ARRAY_SIZE(added_rings); i++) {
		if (!added_rings[i])
			continue;
		amdgpu_mes_remove_ring(adev, added_rings[i]);
	}

	for (i = 0; i < ARRAY_SIZE(gang_ids); i++) {
		if (!gang_ids[i])
			continue;
		amdgpu_mes_remove_gang(adev, gang_ids[i]);
	}

	amdgpu_mes_destroy_process(adev, pasid);

error_vm:
	amdgpu_mes_ctx_unmap_meta_data(adev, &ctx_data);

error_fini:
	amdgpu_vm_fini(adev, vm);

error_pasid:
	if (pasid)
		amdgpu_pasid_free(pasid);

	amdgpu_mes_ctx_free_meta_data(&ctx_data);
	kfree(vm);
	return 0;
}
