// 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)
{
	u64 seq64_addr, va_flags;
	struct amdgpu_bo *bo;
	struct drm_exec exec;
	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;

	va_flags = amdgpu_gem_va_map_flags(adev, AMDGPU_VM_PAGE_READABLE | AMDGPU_VM_MTYPE_UC);
	r = amdgpu_vm_bo_map(adev, *bo_va, seq64_addr, 0, AMDGPU_VA_RESERVED_SEQ64_SIZE,
			     va_flags);
	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;

	bit_pos = find_first_zero_bit(adev->seq64.used, adev->seq64.num_sem);
	if (bit_pos >= adev->seq64.num_sem)
		return -ENOSPC;

	__set_bit(bit_pos, adev->seq64.used);

	*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;
}
