/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */

/*
 * Copyright (C) 2013 Rob Clark <robclark@freedesktop.org>
 *
 * 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 (including the next
 * paragraph) 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 AUTHORS OR COPYRIGHT HOLDERS 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.
 *
 * Authors:
 *    Rob Clark <robclark@freedesktop.org>
 */

#ifdef HAVE_CONFIG_H
# include <config.h>
#endif

#include "msm_priv.h"

static int bo_allocate(struct msm_bo *msm_bo)
{
	struct fd_bo *bo = &msm_bo->base;
	if (!msm_bo->offset) {
		struct drm_msm_gem_info req = {
				.handle = bo->handle,
		};
		int ret;

		/* if the buffer is already backed by pages then this
		 * doesn't actually do anything (other than giving us
		 * the offset)
		 */
		ret = drmCommandWriteRead(bo->dev->fd, DRM_MSM_GEM_INFO,
				&req, sizeof(req));
		if (ret) {
			ERROR_MSG("alloc failed: %s", strerror(errno));
			return ret;
		}

		msm_bo->offset = req.offset;
	}

	return 0;
}

static int msm_bo_offset(struct fd_bo *bo, uint64_t *offset)
{
	struct msm_bo *msm_bo = to_msm_bo(bo);
	int ret = bo_allocate(msm_bo);
	if (ret)
		return ret;
	*offset = msm_bo->offset;
	return 0;
}

static int msm_bo_cpu_prep(struct fd_bo *bo, struct fd_pipe *pipe, uint32_t op)
{
	struct drm_msm_gem_cpu_prep req = {
			.handle = bo->handle,
			.op = op,
	};

	get_abs_timeout(&req.timeout, 5000000000);

	return drmCommandWrite(bo->dev->fd, DRM_MSM_GEM_CPU_PREP, &req, sizeof(req));
}

static void msm_bo_cpu_fini(struct fd_bo *bo)
{
	struct drm_msm_gem_cpu_fini req = {
			.handle = bo->handle,
	};

	drmCommandWrite(bo->dev->fd, DRM_MSM_GEM_CPU_FINI, &req, sizeof(req));
}

static int msm_bo_madvise(struct fd_bo *bo, int willneed)
{
	struct drm_msm_gem_madvise req = {
			.handle = bo->handle,
			.madv = willneed ? MSM_MADV_WILLNEED : MSM_MADV_DONTNEED,
	};
	int ret;

	/* older kernels do not support this: */
	if (bo->dev->version < FD_VERSION_MADVISE)
		return willneed;

	ret = drmCommandWriteRead(bo->dev->fd, DRM_MSM_GEM_MADVISE, &req, sizeof(req));
	if (ret)
		return ret;

	return req.retained;
}

static void msm_bo_destroy(struct fd_bo *bo)
{
	struct msm_bo *msm_bo = to_msm_bo(bo);
	free(msm_bo);

}

static const struct fd_bo_funcs funcs = {
		.offset = msm_bo_offset,
		.cpu_prep = msm_bo_cpu_prep,
		.cpu_fini = msm_bo_cpu_fini,
		.madvise = msm_bo_madvise,
		.destroy = msm_bo_destroy,
};

/* allocate a buffer handle: */
drm_private int msm_bo_new_handle(struct fd_device *dev,
		uint32_t size, uint32_t flags, uint32_t *handle)
{
	struct drm_msm_gem_new req = {
			.size = size,
			.flags = MSM_BO_WC,  // TODO figure out proper flags..
	};
	int ret;

	ret = drmCommandWriteRead(dev->fd, DRM_MSM_GEM_NEW,
			&req, sizeof(req));
	if (ret)
		return ret;

	*handle = req.handle;

	return 0;
}

/* allocate a new buffer object */
drm_private struct fd_bo * msm_bo_from_handle(struct fd_device *dev,
		uint32_t size, uint32_t handle)
{
	struct msm_bo *msm_bo;
	struct fd_bo *bo;

	msm_bo = calloc(1, sizeof(*msm_bo));
	if (!msm_bo)
		return NULL;

	bo = &msm_bo->base;
	bo->funcs = &funcs;

	return bo;
}
