// SPDX-License-Identifier: MIT
/*
 * Copyright 2023 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_seq64.h"

#include <drm/drm_exec.h>

/**
 * DOC: amdgpu_seq64
 *
 * amdgpu_seq64 allocates a 64bit memory on each request in sequence order.
 * seq64 driver is required for user queue fence memory allocation, TLB
 * counters and VM updates. It has maximum count of 32768 64 bit slots.
 */

/**
 * amdgpu_seq64_get_va_base - Get the seq64 va base address
 *
 * @adev: amdgpu_device pointer
 *
 * Returns:
 * va base address on success
 */
static inline u64 amdgpu_seq64_get_va_base(struct amdgpu_device *adev)
{
	u64 addr = AMDGPU_VA_RESERVED_SEQ64_START(adev);

	addr = amdgpu_gmc_sign_extend(addr);

	return addr;
}

/**
 * amdgpu_seq64_map - Map the seq64 memory to VM
 *
 * @adev: amdgpu_device pointer
 * @vm: vm pointer
 * @bo_va: bo_va pointer
 *
 * Map the seq64 memory to the given VM.
 *
 * Returns:
 * 0 on success or a negative error code on failure
 */
int amdgpu_seq64_map(struct amdgpu_device *adev, struct amdgpu_vm *vm,
		     struct amdgpu_bo_va **bo_va)
{
	struct amdgpu_bo *bo;
	struct drm_exec exec;
	u64 seq64_addr;
	int r;

	bo = adev->seq64.sbo;
	if (!bo)
		return -EINVAL;

	drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT, 0);
	drm_exec_until_all_locked(&exec) {
		r = amdgpu_vm_lock_pd(vm, &exec, 0);
		if (likely(!r))
			r = drm_exec_lock_obj(&exec, &bo->tbo.base);
		drm_exec_retry_on_contention(&exec);
		if (unlikely(r))
			goto error;
	}

	*bo_va = amdgpu_vm_bo_add(adev, vm, bo);
	if (!*bo_va) {
		r = -ENOMEM;
		goto error;
	}

	seq64_addr = amdgpu_seq64_get_va_base(adev) & AMDGPU_GMC_HOLE_MASK;

	r = amdgpu_vm_bo_map(adev, *bo_va, seq64_addr, 0,
			     AMDGPU_VA_RESERVED_SEQ64_SIZE,
			     AMDGPU_VM_PAGE_READABLE | AMDGPU_VM_MTYPE_UC);
	if (r) {
		DRM_ERROR("failed to do bo_map on userq sem, err=%d\n", r);
		amdgpu_vm_bo_del(adev, *bo_va);
		goto error;
	}

	r = amdgpu_vm_bo_update(adev, *bo_va, false);
	if (r) {
		DRM_ERROR("failed to do vm_bo_update on userq sem\n");
		amdgpu_vm_bo_del(adev, *bo_va);
		goto error;
	}

error:
	drm_exec_fini(&exec);
	return r;
}

/**
 * amdgpu_seq64_unmap - Unmap the seq64 memory
 *
 * @adev: amdgpu_device pointer
 * @fpriv: DRM file private
 *
 * Unmap the seq64 memory from the given VM.
 */
void amdgpu_seq64_unmap(struct amdgpu_device *adev, struct amdgpu_fpriv *fpriv)
{
	struct amdgpu_vm *vm;
	struct amdgpu_bo *bo;
	struct drm_exec exec;
	int r;

	if (!fpriv->seq64_va)
		return;

	bo = adev->seq64.sbo;
	if (!bo)
		return;

	vm = &fpriv->vm;

	drm_exec_init(&exec, 0, 0);
	drm_exec_until_all_locked(&exec) {
		r = amdgpu_vm_lock_pd(vm, &exec, 0);
		if (likely(!r))
			r = drm_exec_lock_obj(&exec, &bo->tbo.base);
		drm_exec_retry_on_contention(&exec);
		if (unlikely(r))
			goto error;
	}

	amdgpu_vm_bo_del(adev, fpriv->seq64_va);

	fpriv->seq64_va = NULL;

error:
	drm_exec_fini(&exec);
}

/**
 * amdgpu_seq64_alloc - Allocate a 64 bit memory
 *
 * @adev: amdgpu_device pointer
 * @va: VA to access the seq in process address space
 * @gpu_addr: GPU address to access the seq
 * @cpu_addr: CPU address to access the seq
 *
 * Alloc a 64 bit memory from seq64 pool.
 *
 * Returns:
 * 0 on success or a negative error code on failure
 */
int amdgpu_seq64_alloc(struct amdgpu_device *adev, u64 *va,
		       u64 *gpu_addr, u64 **cpu_addr)
{
	unsigned long bit_pos = 0;

	do {
		bit_pos = find_next_zero_bit(adev->seq64.used,
				     adev->seq64.num_sem, bit_pos);
		if (bit_pos >= adev->seq64.num_sem)
			return -ENOSPC;
		if (!test_and_set_bit(bit_pos, adev->seq64.used))
			break;
		bit_pos++;
	} while (1);

	*va = bit_pos * sizeof(u64) + amdgpu_seq64_get_va_base(adev);

	if (gpu_addr)
		*gpu_addr = bit_pos * sizeof(u64) + adev->seq64.gpu_addr;

	*cpu_addr = bit_pos + adev->seq64.cpu_base_addr;

	return 0;
}

/**
 * amdgpu_seq64_free - Free the given 64 bit memory
 *
 * @adev: amdgpu_device pointer
 * @va: gpu start address to be freed
 *
 * Free the given 64 bit memory from seq64 pool.
 */
void amdgpu_seq64_free(struct amdgpu_device *adev, u64 va)
{
	unsigned long bit_pos;

	bit_pos = (va - amdgpu_seq64_get_va_base(adev)) / sizeof(u64);
	if (bit_pos < adev->seq64.num_sem)
		clear_bit(bit_pos, adev->seq64.used);
}

/**
 * amdgpu_seq64_fini - Cleanup seq64 driver
 *
 * @adev: amdgpu_device pointer
 *
 * Free the memory space allocated for seq64.
 *
 */
void amdgpu_seq64_fini(struct amdgpu_device *adev)
{
	amdgpu_bo_free_kernel(&adev->seq64.sbo,
			      NULL,
			      (void **)&adev->seq64.cpu_base_addr);
}

/**
 * amdgpu_seq64_init - Initialize seq64 driver
 *
 * @adev: amdgpu_device pointer
 *
 * Allocate the required memory space for seq64.
 *
 * Returns:
 * 0 on success or a negative error code on failure
 */
int amdgpu_seq64_init(struct amdgpu_device *adev)
{
	int r;

	if (adev->seq64.sbo)
		return 0;

	/*
	 * AMDGPU_MAX_SEQ64_SLOTS * sizeof(u64) * 8 = AMDGPU_MAX_SEQ64_SLOTS
	 * 64bit slots
	 */
	r = amdgpu_bo_create_kernel(adev, AMDGPU_VA_RESERVED_SEQ64_SIZE,
				    PAGE_SIZE, AMDGPU_GEM_DOMAIN_GTT,
				    &adev->seq64.sbo, &adev->seq64.gpu_addr,
				    (void **)&adev->seq64.cpu_base_addr);
	if (r) {
		dev_warn(adev->dev, "(%d) create seq64 failed\n", r);
		return r;
	}

	memset(adev->seq64.cpu_base_addr, 0, AMDGPU_VA_RESERVED_SEQ64_SIZE);

	adev->seq64.num_sem = AMDGPU_MAX_SEQ64_SLOTS;
	memset(&adev->seq64.used, 0, sizeof(adev->seq64.used));

	return 0;
}
