/*
 * Copyright 2022 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.h"
#include "amdgpu_xcp.h"
#include "amdgpu_drv.h"

#include <drm/drm_drv.h>
#include "../amdxcp/amdgpu_xcp_drv.h"

static int __amdgpu_xcp_run(struct amdgpu_xcp_mgr *xcp_mgr,
			    struct amdgpu_xcp_ip *xcp_ip, int xcp_state)
{
	int (*run_func)(void *handle, uint32_t inst_mask);
	int ret = 0;

	if (!xcp_ip || !xcp_ip->valid || !xcp_ip->ip_funcs)
		return 0;

	run_func = NULL;

	switch (xcp_state) {
	case AMDGPU_XCP_PREPARE_SUSPEND:
		run_func = xcp_ip->ip_funcs->prepare_suspend;
		break;
	case AMDGPU_XCP_SUSPEND:
		run_func = xcp_ip->ip_funcs->suspend;
		break;
	case AMDGPU_XCP_PREPARE_RESUME:
		run_func = xcp_ip->ip_funcs->prepare_resume;
		break;
	case AMDGPU_XCP_RESUME:
		run_func = xcp_ip->ip_funcs->resume;
		break;
	}

	if (run_func)
		ret = run_func(xcp_mgr->adev, xcp_ip->inst_mask);

	return ret;
}

static int amdgpu_xcp_run_transition(struct amdgpu_xcp_mgr *xcp_mgr, int xcp_id,
				     int state)
{
	struct amdgpu_xcp_ip *xcp_ip;
	struct amdgpu_xcp *xcp;
	int i, ret;

	if (xcp_id >= MAX_XCP || !xcp_mgr->xcp[xcp_id].valid)
		return -EINVAL;

	xcp = &xcp_mgr->xcp[xcp_id];
	for (i = 0; i < AMDGPU_XCP_MAX_BLOCKS; ++i) {
		xcp_ip = &xcp->ip[i];
		ret = __amdgpu_xcp_run(xcp_mgr, xcp_ip, state);
		if (ret)
			break;
	}

	return ret;
}

int amdgpu_xcp_prepare_suspend(struct amdgpu_xcp_mgr *xcp_mgr, int xcp_id)
{
	return amdgpu_xcp_run_transition(xcp_mgr, xcp_id,
					 AMDGPU_XCP_PREPARE_SUSPEND);
}

int amdgpu_xcp_suspend(struct amdgpu_xcp_mgr *xcp_mgr, int xcp_id)
{
	return amdgpu_xcp_run_transition(xcp_mgr, xcp_id, AMDGPU_XCP_SUSPEND);
}

int amdgpu_xcp_prepare_resume(struct amdgpu_xcp_mgr *xcp_mgr, int xcp_id)
{
	return amdgpu_xcp_run_transition(xcp_mgr, xcp_id,
					 AMDGPU_XCP_PREPARE_RESUME);
}

int amdgpu_xcp_resume(struct amdgpu_xcp_mgr *xcp_mgr, int xcp_id)
{
	return amdgpu_xcp_run_transition(xcp_mgr, xcp_id, AMDGPU_XCP_RESUME);
}

static void __amdgpu_xcp_add_block(struct amdgpu_xcp_mgr *xcp_mgr, int xcp_id,
				   struct amdgpu_xcp_ip *ip)
{
	struct amdgpu_xcp *xcp;

	if (!ip)
		return;

	xcp = &xcp_mgr->xcp[xcp_id];
	xcp->ip[ip->ip_id] = *ip;
	xcp->ip[ip->ip_id].valid = true;

	xcp->valid = true;
}

int amdgpu_xcp_init(struct amdgpu_xcp_mgr *xcp_mgr, int num_xcps, int mode)
{
	struct amdgpu_device *adev = xcp_mgr->adev;
	struct amdgpu_xcp_ip ip;
	uint8_t mem_id;
	int i, j, ret;

	if (!num_xcps || num_xcps > MAX_XCP)
		return -EINVAL;

	xcp_mgr->mode = mode;

	for (i = 0; i < MAX_XCP; ++i)
		xcp_mgr->xcp[i].valid = false;

	/* This is needed for figuring out memory id of xcp */
	xcp_mgr->num_xcp_per_mem_partition = num_xcps / xcp_mgr->adev->gmc.num_mem_partitions;

	for (i = 0; i < num_xcps; ++i) {
		for (j = AMDGPU_XCP_GFXHUB; j < AMDGPU_XCP_MAX_BLOCKS; ++j) {
			ret = xcp_mgr->funcs->get_ip_details(xcp_mgr, i, j,
							     &ip);
			if (ret)
				continue;

			__amdgpu_xcp_add_block(xcp_mgr, i, &ip);
		}

		xcp_mgr->xcp[i].id = i;

		if (xcp_mgr->funcs->get_xcp_mem_id) {
			ret = xcp_mgr->funcs->get_xcp_mem_id(
				xcp_mgr, &xcp_mgr->xcp[i], &mem_id);
			if (ret)
				continue;
			else
				xcp_mgr->xcp[i].mem_id = mem_id;
		}
	}

	xcp_mgr->num_xcps = num_xcps;
	amdgpu_xcp_update_partition_sched_list(adev);

	return 0;
}

static int __amdgpu_xcp_switch_partition_mode(struct amdgpu_xcp_mgr *xcp_mgr,
					      int mode)
{
	int ret, curr_mode, num_xcps = 0;

	if (!xcp_mgr->funcs || !xcp_mgr->funcs->switch_partition_mode)
		return 0;

	mutex_lock(&xcp_mgr->xcp_lock);

	curr_mode = xcp_mgr->mode;
	/* State set to transient mode */
	xcp_mgr->mode = AMDGPU_XCP_MODE_TRANS;

	ret = xcp_mgr->funcs->switch_partition_mode(xcp_mgr, mode, &num_xcps);

	if (ret) {
		/* Failed, get whatever mode it's at now */
		if (xcp_mgr->funcs->query_partition_mode)
			xcp_mgr->mode = amdgpu_xcp_query_partition_mode(
				xcp_mgr, AMDGPU_XCP_FL_LOCKED);
		else
			xcp_mgr->mode = curr_mode;

		goto out;
	}

out:
	mutex_unlock(&xcp_mgr->xcp_lock);

	return ret;
}

int amdgpu_xcp_switch_partition_mode(struct amdgpu_xcp_mgr *xcp_mgr, int mode)
{
	if (!xcp_mgr || mode == AMDGPU_XCP_MODE_NONE)
		return -EINVAL;

	if (xcp_mgr->mode == mode)
		return 0;

	return __amdgpu_xcp_switch_partition_mode(xcp_mgr, mode);
}

int amdgpu_xcp_restore_partition_mode(struct amdgpu_xcp_mgr *xcp_mgr)
{
	if (!xcp_mgr || xcp_mgr->mode == AMDGPU_XCP_MODE_NONE)
		return 0;

	return __amdgpu_xcp_switch_partition_mode(xcp_mgr, xcp_mgr->mode);
}

int amdgpu_xcp_query_partition_mode(struct amdgpu_xcp_mgr *xcp_mgr, u32 flags)
{
	int mode;

	if (!amdgpu_sriov_vf(xcp_mgr->adev) &&
	    xcp_mgr->mode == AMDGPU_XCP_MODE_NONE)
		return xcp_mgr->mode;

	if (!xcp_mgr->funcs || !xcp_mgr->funcs->query_partition_mode)
		return xcp_mgr->mode;

	if (!(flags & AMDGPU_XCP_FL_LOCKED))
		mutex_lock(&xcp_mgr->xcp_lock);
	mode = xcp_mgr->funcs->query_partition_mode(xcp_mgr);

	/* First time query for VF, set the mode here */
	if (amdgpu_sriov_vf(xcp_mgr->adev) &&
	    xcp_mgr->mode == AMDGPU_XCP_MODE_NONE)
		xcp_mgr->mode = mode;

	if (xcp_mgr->mode != AMDGPU_XCP_MODE_TRANS && mode != xcp_mgr->mode)
		dev_WARN(
			xcp_mgr->adev->dev,
			"Cached partition mode %d not matching with device mode %d",
			xcp_mgr->mode, mode);

	if (!(flags & AMDGPU_XCP_FL_LOCKED))
		mutex_unlock(&xcp_mgr->xcp_lock);

	return mode;
}

static int amdgpu_xcp_dev_alloc(struct amdgpu_device *adev)
{
	struct drm_device *p_ddev;
	struct drm_device *ddev;
	int i, ret;

	ddev = adev_to_drm(adev);

	/* xcp #0 shares drm device setting with adev */
	adev->xcp_mgr->xcp->ddev = ddev;

	for (i = 1; i < MAX_XCP; i++) {
		ret = amdgpu_xcp_drm_dev_alloc(&p_ddev);
		if (ret == -ENOSPC) {
			dev_warn(adev->dev,
			"Skip xcp node #%d when out of drm node resource.", i);
			return 0;
		} else if (ret) {
			return ret;
		}

		/* Redirect all IOCTLs to the primary device */
		adev->xcp_mgr->xcp[i].rdev = p_ddev->render->dev;
		adev->xcp_mgr->xcp[i].pdev = p_ddev->primary->dev;
		adev->xcp_mgr->xcp[i].driver = (struct drm_driver *)p_ddev->driver;
		adev->xcp_mgr->xcp[i].vma_offset_manager = p_ddev->vma_offset_manager;
		p_ddev->render->dev = ddev;
		p_ddev->primary->dev = ddev;
		p_ddev->vma_offset_manager = ddev->vma_offset_manager;
		p_ddev->driver = &amdgpu_partition_driver;
		adev->xcp_mgr->xcp[i].ddev = p_ddev;
	}

	return 0;
}

int amdgpu_xcp_mgr_init(struct amdgpu_device *adev, int init_mode,
			int init_num_xcps,
			struct amdgpu_xcp_mgr_funcs *xcp_funcs)
{
	struct amdgpu_xcp_mgr *xcp_mgr;

	if (!xcp_funcs || !xcp_funcs->get_ip_details)
		return -EINVAL;

	xcp_mgr = kzalloc(sizeof(*xcp_mgr), GFP_KERNEL);

	if (!xcp_mgr)
		return -ENOMEM;

	xcp_mgr->adev = adev;
	xcp_mgr->funcs = xcp_funcs;
	xcp_mgr->mode = init_mode;
	mutex_init(&xcp_mgr->xcp_lock);

	if (init_mode != AMDGPU_XCP_MODE_NONE)
		amdgpu_xcp_init(xcp_mgr, init_num_xcps, init_mode);

	adev->xcp_mgr = xcp_mgr;

	return amdgpu_xcp_dev_alloc(adev);
}

int amdgpu_xcp_get_partition(struct amdgpu_xcp_mgr *xcp_mgr,
			     enum AMDGPU_XCP_IP_BLOCK ip, int instance)
{
	struct amdgpu_xcp *xcp;
	int i, id_mask = 0;

	if (ip >= AMDGPU_XCP_MAX_BLOCKS)
		return -EINVAL;

	for (i = 0; i < xcp_mgr->num_xcps; ++i) {
		xcp = &xcp_mgr->xcp[i];
		if ((xcp->valid) && (xcp->ip[ip].valid) &&
		    (xcp->ip[ip].inst_mask & BIT(instance)))
			id_mask |= BIT(i);
	}

	if (!id_mask)
		id_mask = -ENXIO;

	return id_mask;
}

int amdgpu_xcp_get_inst_details(struct amdgpu_xcp *xcp,
				enum AMDGPU_XCP_IP_BLOCK ip,
				uint32_t *inst_mask)
{
	if (!xcp->valid || !inst_mask || !(xcp->ip[ip].valid))
		return -EINVAL;

	*inst_mask = xcp->ip[ip].inst_mask;

	return 0;
}

int amdgpu_xcp_dev_register(struct amdgpu_device *adev,
			const struct pci_device_id *ent)
{
	int i, ret;

	if (!adev->xcp_mgr)
		return 0;

	for (i = 1; i < MAX_XCP; i++) {
		if (!adev->xcp_mgr->xcp[i].ddev)
			break;

		ret = drm_dev_register(adev->xcp_mgr->xcp[i].ddev, ent->driver_data);
		if (ret)
			return ret;
	}

	return 0;
}

void amdgpu_xcp_dev_unplug(struct amdgpu_device *adev)
{
	struct drm_device *p_ddev;
	int i;

	if (!adev->xcp_mgr)
		return;

	for (i = 1; i < MAX_XCP; i++) {
		if (!adev->xcp_mgr->xcp[i].ddev)
			break;

		p_ddev = adev->xcp_mgr->xcp[i].ddev;
		drm_dev_unplug(p_ddev);
		p_ddev->render->dev = adev->xcp_mgr->xcp[i].rdev;
		p_ddev->primary->dev = adev->xcp_mgr->xcp[i].pdev;
		p_ddev->driver =  adev->xcp_mgr->xcp[i].driver;
		p_ddev->vma_offset_manager = adev->xcp_mgr->xcp[i].vma_offset_manager;
	}
}

int amdgpu_xcp_open_device(struct amdgpu_device *adev,
			   struct amdgpu_fpriv *fpriv,
			   struct drm_file *file_priv)
{
	int i;

	if (!adev->xcp_mgr)
		return 0;

	fpriv->xcp_id = AMDGPU_XCP_NO_PARTITION;
	for (i = 0; i < MAX_XCP; ++i) {
		if (!adev->xcp_mgr->xcp[i].ddev)
			break;

		if (file_priv->minor == adev->xcp_mgr->xcp[i].ddev->render) {
			if (adev->xcp_mgr->xcp[i].valid == FALSE) {
				dev_err(adev->dev, "renderD%d partition %d not valid!",
						file_priv->minor->index, i);
				return -ENOENT;
			}
			dev_dbg(adev->dev, "renderD%d partition %d opened!",
					file_priv->minor->index, i);
			fpriv->xcp_id = i;
			break;
		}
	}

	fpriv->vm.mem_id = fpriv->xcp_id == AMDGPU_XCP_NO_PARTITION ? -1 :
				adev->xcp_mgr->xcp[fpriv->xcp_id].mem_id;
	return 0;
}

void amdgpu_xcp_release_sched(struct amdgpu_device *adev,
				  struct amdgpu_ctx_entity *entity)
{
	struct drm_gpu_scheduler *sched;
	struct amdgpu_ring *ring;

	if (!adev->xcp_mgr)
		return;

	sched = entity->entity.rq->sched;
	if (sched->ready) {
		ring = to_amdgpu_ring(entity->entity.rq->sched);
		atomic_dec(&adev->xcp_mgr->xcp[ring->xcp_id].ref_cnt);
	}
}

