// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
/*
 * Copyright 2020 Intel Corporation. All rights reserved. See COPYING file
 */

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <drm.h>
#include <i915_drm.h>
#include <amdgpu_drm.h>
#include "dmabuf_alloc.h"

/*
 * Abstraction of the buffer allocation mechanism using the DRM interface.
 * The interface is accessed by ioctl() calls over the '/dev/dri/renderD*'
 * device. Successful access usually requires the effective user id being
 * in the 'render' group.
 */

struct drm {
	int fd;
	int (*alloc)(struct drm *drm, uint64_t size, uint32_t *handle, int gtt);
	int (*mmap_offset)(struct drm *drm, uint32_t handle, uint64_t *offset);
};

static int i915_alloc(struct drm *drm, uint64_t size, uint32_t *handle, int gtt)
{
	struct drm_i915_gem_create gem_create = {};
	int err;

	gem_create.size = size;
	err = ioctl(drm->fd, DRM_IOCTL_I915_GEM_CREATE, &gem_create);
	if (err)
		return err;

	*handle = gem_create.handle;
	return 0;
}

static int amdgpu_alloc(struct drm *drm, uint64_t size, uint32_t *handle, int gtt)
{
	union drm_amdgpu_gem_create gem_create = {{}};
	int err;

	gem_create.in.bo_size = size;
	if (gtt) {
		gem_create.in.domains = AMDGPU_GEM_DOMAIN_GTT;
		gem_create.in.domain_flags = AMDGPU_GEM_CREATE_CPU_GTT_USWC;
	} else {
		gem_create.in.domains = AMDGPU_GEM_DOMAIN_VRAM;
		gem_create.in.domain_flags =
			AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED;
	}
	err = ioctl(drm->fd, DRM_IOCTL_AMDGPU_GEM_CREATE, &gem_create);
	if (err)
		return err;

	*handle = gem_create.out.handle;
	return 0;
}

static int i915_mmap_offset(struct drm *drm, uint32_t handle, uint64_t *offset)
{
	struct drm_i915_gem_mmap_gtt gem_mmap = {};
	int err;

	gem_mmap.handle = handle;
	err = ioctl(drm->fd, DRM_IOCTL_I915_GEM_MMAP_GTT, &gem_mmap);
	if (err)
		return err;

	*offset = gem_mmap.offset;
	return 0;
}

static int amdgpu_mmap_offset(struct drm *drm, uint32_t handle,
			      uint64_t *offset)
{
	union drm_amdgpu_gem_mmap gem_mmap = {{}};
	int err;

	gem_mmap.in.handle = handle;
	err = ioctl(drm->fd, DRM_IOCTL_AMDGPU_GEM_MMAP, &gem_mmap);
	if (err)
		return err;

	*offset = gem_mmap.out.addr_ptr;
	return 0;
}

static struct drm *drm_open(int gpu)
{
	char path[32];
	struct drm_version version = {};
	char name[16] = {};
	int err;
	struct drm *drm;

	drm = malloc(sizeof(*drm));
	if (!drm)
		return NULL;

	snprintf(path, sizeof(path), "/dev/dri/renderD%d", gpu + 128);

	drm->fd = open(path, O_RDWR);
	if (drm->fd < 0)
		goto out_free;

	version.name = name;
	version.name_len = 16;
	err = ioctl(drm->fd, DRM_IOCTL_VERSION, &version);
	if (err)
		goto out_close;

	if (!strcmp(name, "amdgpu")) {
		drm->alloc = amdgpu_alloc;
		drm->mmap_offset = amdgpu_mmap_offset;
	} else if (!strcmp(name, "i915")) {
		drm->alloc = i915_alloc;
		drm->mmap_offset = i915_mmap_offset;
	} else {
		errno = EOPNOTSUPP;
		goto out_close;
	}
	return drm;

out_close:
	close(drm->fd);

out_free:
	free(drm);
	return NULL;
}

static void drm_close(struct drm *drm)
{
	if (!drm || drm->fd < 0)
		return;

	close(drm->fd);
	free(drm);
}

static void drm_free_buf(struct drm *drm, uint32_t handle)
{
	struct drm_gem_close close = {};

	close.handle = handle;
	ioctl(drm->fd, DRM_IOCTL_GEM_CLOSE, &close);
}

static int drm_alloc_buf(struct drm *drm, size_t size, uint32_t *handle,
			 int *fd, int gtt)
{
	struct drm_prime_handle prime_handle = {};
	int err;

	if (!drm || drm->fd < 0)
		return -EINVAL;

	err = drm->alloc(drm, size, handle, gtt);
	if (err)
		return err;

	prime_handle.handle = *handle;
	prime_handle.flags = O_RDWR;
	err = ioctl(drm->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &prime_handle);
	if (err) {
		drm_free_buf(drm, *handle);
		return err;
	}

	*fd = prime_handle.fd;
	return 0;
}

static int drm_map_buf(struct drm *drm, uint32_t handle, uint64_t *offset)
{
	if (!drm || drm->fd < 0)
		return -EINVAL;

	return drm->mmap_offset(drm, handle, offset);
}

/*
 * Abstraction of dmabuf object, allocated using the DRI abstraction defined
 * above.
 */

struct dmabuf {
	struct drm *drm;
	int fd;
	uint32_t handle;
	uint64_t map_offset;
};

/*
 * dmabuf_alloc - allocate a dmabuf from GPU
 * @size - byte size of the buffer to allocate
 * @gpu - the GPU unit to use
 * @gtt - if true, allocate from GTT (Graphics Translation Table) instead of VRAM
 */
struct dmabuf *dmabuf_alloc(uint64_t size, int gpu, int gtt)
{
	struct dmabuf *dmabuf;
	int err;

	dmabuf = malloc(sizeof(*dmabuf));
	if (!dmabuf)
		return NULL;

	dmabuf->drm = drm_open(gpu);
	if (!dmabuf->drm)
		goto out_free;

	err = drm_alloc_buf(dmabuf->drm, size, &dmabuf->handle, &dmabuf->fd, gtt);
	if (err)
		goto out_close;

	err = drm_map_buf(dmabuf->drm, dmabuf->handle, &dmabuf->map_offset);
	if (err)
		goto out_free_buf;

	return dmabuf;

out_free_buf:
	drm_free_buf(dmabuf->drm, dmabuf->handle);

out_close:
	drm_close(dmabuf->drm);

out_free:
	free(dmabuf);
	return NULL;
}

void dmabuf_free(struct dmabuf *dmabuf)
{
	if (!dmabuf)
		return;

	close(dmabuf->fd);
	drm_free_buf(dmabuf->drm, dmabuf->handle);
	drm_close(dmabuf->drm);
	free(dmabuf);
}

int dmabuf_get_drm_fd(struct dmabuf *dmabuf)
{
	if (!dmabuf || !dmabuf->drm)
		return -1;

	return dmabuf->drm->fd;
}

int dmabuf_get_fd(struct dmabuf *dmabuf)
{
	if (!dmabuf)
		return -1;

	return dmabuf->fd;
}

uint64_t dmabuf_get_offset(struct dmabuf *dmabuf)
{
	if (!dmabuf)
		return -1;

	return dmabuf->map_offset;
}

