/*
 * Copyright © 2016 Broadcom
 *
 * 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.
 */

#include <assert.h>
#include <string.h>
#include <signal.h>
#include <errno.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>

#include "drmtest.h"
#include "igt_aux.h"
#include "igt_core.h"
#include "igt_fb.h"
#include "igt_vc4.h"
#include "ioctl_wrappers.h"
#include "intel_reg.h"
#include "intel_chipset.h"
#include "vc4_drm.h"
#include "vc4_packet.h"

#if NEW_CONTEXT_PARAM_NO_ERROR_CAPTURE_API
#define LOCAL_CONTEXT_PARAM_NO_ERROR_CAPTURE 0x4
#endif

/**
 * SECTION:igt_vc4
 * @short_description: VC4 support library
 * @title: VC4
 * @include: igt.h
 *
 * This library provides various auxiliary helper functions for writing VC4
 * tests.
 */

/**
 * igt_vc4_get_cleared_bo:
 * @fd: device file descriptor
 * @size: size of the BO in bytes
 * @clearval: u32 value that the buffer should be completely cleared with
 *
 * This helper returns a new BO with the given size, which has just been
 * cleared using the render engine.
 */
uint32_t igt_vc4_get_cleared_bo(int fd, size_t size, uint32_t clearval)
{
	/* A single row will be a page. */
	uint32_t width = 1024;
	uint32_t height = size / (width * 4);
	uint32_t handle = igt_vc4_create_bo(fd, size);
	struct drm_vc4_submit_cl submit = {
		.color_write = {
			.hindex = 0,
			.bits = VC4_SET_FIELD(VC4_RENDER_CONFIG_FORMAT_RGBA8888,
					      VC4_RENDER_CONFIG_FORMAT),
		},

		.color_read = { .hindex = ~0 },
		.zs_read = { .hindex = ~0 },
		.zs_write = { .hindex = ~0 },
		.msaa_color_write = { .hindex = ~0 },
		.msaa_zs_write = { .hindex = ~0 },

		.bo_handles = to_user_pointer(&handle),
		.bo_handle_count = 1,
		.width = width,
		.height = height,
		.max_x_tile = ALIGN(width, 64) / 64 - 1,
		.max_y_tile = ALIGN(height, 64) / 64 - 1,
		.clear_color = { clearval, clearval },
		.flags = VC4_SUBMIT_CL_USE_CLEAR_COLOR,
	};

	igt_assert_eq_u32(width * height * 4, size);

	do_ioctl(fd, DRM_IOCTL_VC4_SUBMIT_CL, &submit);

	return handle;
}

int
igt_vc4_create_bo(int fd, size_t size)
{
	struct drm_vc4_create_bo create = {
		.size = size,
	};

	do_ioctl(fd, DRM_IOCTL_VC4_CREATE_BO, &create);

	return create.handle;
}

void *
igt_vc4_mmap_bo(int fd, uint32_t handle, uint32_t size, unsigned prot)
{
	struct drm_vc4_mmap_bo mmap_bo = {
		.handle = handle,
	};
	void *ptr;

	do_ioctl(fd, DRM_IOCTL_VC4_MMAP_BO, &mmap_bo);

	ptr = mmap(0, size, prot, MAP_SHARED, fd, mmap_bo.offset);
	if (ptr == MAP_FAILED)
		return NULL;
	else
		return ptr;
}

void igt_vc4_set_tiling(int fd, uint32_t handle, uint64_t modifier)
{
	struct drm_vc4_set_tiling set = {
		.handle = handle,
		.modifier = modifier,
	};

	do_ioctl(fd, DRM_IOCTL_VC4_SET_TILING, &set);
}

uint64_t igt_vc4_get_tiling(int fd, uint32_t handle)
{
	struct drm_vc4_get_tiling get = {
		.handle = handle,
	};

	do_ioctl(fd, DRM_IOCTL_VC4_GET_TILING, &get);

	return get.modifier;
}

int igt_vc4_get_param(int fd, uint32_t param, uint64_t *val)
{
	struct drm_vc4_get_param arg = {
		.param = param,
	};
	int ret;

	ret = igt_ioctl(fd, DRM_IOCTL_VC4_GET_PARAM, &arg);
	if (ret)
		return ret;

	*val = arg.value;
	return 0;
}

bool igt_vc4_purgeable_bo(int fd, int handle, bool purgeable)
{
	struct drm_vc4_gem_madvise arg = {
		.handle = handle,
		.madv = purgeable ? VC4_MADV_DONTNEED : VC4_MADV_WILLNEED,
	};

	do_ioctl(fd, DRM_IOCTL_VC4_GEM_MADVISE, &arg);

	return arg.retained;
}

unsigned int igt_vc4_fb_t_tiled_convert(struct igt_fb *dst, struct igt_fb *src)
{
	unsigned int fb_id;
	unsigned int i, j;
	void *src_buf;
	void *dst_buf;
	size_t bpp = src->plane_bpp[0];
	size_t dst_stride = ALIGN(src->strides[0], 128);

	fb_id = igt_create_fb_with_bo_size(src->fd, src->width, src->height,
					   src->drm_format,
					   DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED,
					   dst, 0, dst_stride);
	igt_assert(fb_id > 0);

	igt_assert(bpp == 16 || bpp == 32);

	src_buf = igt_fb_map_buffer(src->fd, src);
	igt_assert(src_buf);

	dst_buf = igt_fb_map_buffer(dst->fd, dst);
	igt_assert(dst_buf);

	for (i = 0; i < src->height; i++) {
		for (j = 0; j < src->width; j++) {
			size_t src_offset = src->offsets[0];
			size_t dst_offset = dst->offsets[0];

			src_offset += src->strides[0] * i + j * bpp / 8;
			dst_offset += igt_vc4_t_tiled_offset(dst_stride,
							     src->height,
							     bpp, j, i);

			switch (bpp) {
			case 16:
				*(uint16_t *)(dst_buf + dst_offset) =
					*(uint16_t *)(src_buf + src_offset);
				break;
			case 32:
				*(uint32_t *)(dst_buf + dst_offset) =
					*(uint32_t *)(src_buf + src_offset);
				break;
			}
		}
	}

	igt_fb_unmap_buffer(src, src_buf);
	igt_fb_unmap_buffer(dst, dst_buf);

	return fb_id;
}

/* Calculate the t-tile width so that size = width * height * bpp / 8. */
#define VC4_T_TILE_W(size, height, bpp) ((size) / (height) / ((bpp) / 8))

size_t igt_vc4_t_tiled_offset(size_t stride, size_t height, size_t bpp,
			      size_t x, size_t y)
{
	const size_t t1k_map_even[] = { 0, 3, 1, 2 };
	const size_t t1k_map_odd[] = { 2, 1, 3, 0 };
	const size_t t4k_t_h = 32;
	const size_t t1k_t_h = 16;
	const size_t t64_t_h = 4;
	size_t offset = 0;
	size_t t4k_t_w, t4k_w, t4k_x, t4k_y;
	size_t t1k_t_w, t1k_x, t1k_y;
	size_t t64_t_w, t64_x, t64_y;
	size_t pix_x, pix_y;
	unsigned int index;

	/* T-tiling is only supported for 16 and 32 bpp. */
	igt_assert(bpp == 16 || bpp == 32);

	/* T-tiling stride must be aligned to the 4K tiles strides. */
	igt_assert((stride % (4096 / t4k_t_h)) == 0);

	/* Calculate the tile width for the bpp. */
	t4k_t_w = VC4_T_TILE_W(4096, t4k_t_h, bpp);
	t1k_t_w = VC4_T_TILE_W(1024, t1k_t_h, bpp);
	t64_t_w = VC4_T_TILE_W(64, t64_t_h, bpp);

	/* Aligned total width in number of 4K tiles. */
	t4k_w = (stride / (bpp / 8)) / t4k_t_w;

	/* X and y coordinates in number of 4K tiles. */
	t4k_x = x / t4k_t_w;
	t4k_y = y / t4k_t_h;

	/* Increase offset to the beginning of the 4K tile row. */
	offset += t4k_y * t4k_w * 4096;

	/* X and Y coordinates in number of 1K tiles within the 4K tile. */
	t1k_x = (x % t4k_t_w) / t1k_t_w;
	t1k_y = (y % t4k_t_h) / t1k_t_h;

	/* Index for 1K tile map lookup. */
	index = 2 * t1k_y + t1k_x;

	/* Odd rows start from the right, even rows from the left. */
	if (t4k_y % 2) {
		/* Increase offset to the 4K tile (starting from the right). */
		offset += (t4k_w - t4k_x - 1) * 4096;

		/* Incrase offset to the beginning of the (odd) 1K tile. */
		offset += t1k_map_odd[index] * 1024;
	} else {
		/* Increase offset to the 4K tile (starting from the left). */
		offset += t4k_x * 4096;

		/* Incrase offset to the beginning of the (even) 1K tile. */
		offset += t1k_map_even[index] * 1024;
	}

	/* X and Y coordinates in number of 64 byte tiles within the 1K tile. */
	t64_x = (x % t1k_t_w) / t64_t_w;
	t64_y = (y % t1k_t_h) / t64_t_h;

	/* Increase offset to the beginning of the 64-byte tile. */
	offset += (t64_y * (t1k_t_w / t64_t_w) + t64_x) * 64;

	/* X and Y coordinates in number of pixels within the 64-byte tile. */
	pix_x = x % t64_t_w;
	pix_y = y % t64_t_h;

	/* Increase offset to the correct pixel. */
	offset += (pix_y * t64_t_w + pix_x) * bpp / 8;

	return offset;
}

static void vc4_fb_sand_tiled_convert_plane(struct igt_fb *dst, void *dst_buf,
					    struct igt_fb *src, void *src_buf,
					    size_t column_width_bytes,
					    size_t column_height,
					    unsigned int plane)
{
	size_t bpp = dst->plane_bpp[plane];
	size_t column_width = column_width_bytes * dst->plane_width[plane] /
			      dst->width;
	size_t column_size = column_width_bytes * column_height;
	unsigned int i, j;

	for (i = 0; i < dst->plane_height[plane]; i++) {
		for (j = 0; j < src->plane_width[plane]; j++) {
			size_t src_offset = src->offsets[plane];
			size_t dst_offset = dst->offsets[plane];

			src_offset += src->strides[plane] * i + j * bpp / 8;
			dst_offset += vc4_sand_tiled_offset(column_width,
							    column_size, j, i,
							    bpp);

			switch (bpp) {
			case 8:
				*(uint8_t *)(dst_buf + dst_offset) =
					*(uint8_t *)(src_buf + src_offset);
				break;
			case 16:
				*(uint16_t *)(dst_buf + dst_offset) =
					*(uint16_t *)(src_buf + src_offset);
				break;
			default:
				igt_assert(false);
			}
		}
	}
}

unsigned int vc4_fb_sand_tiled_convert(struct igt_fb *dst, struct igt_fb *src,
				       uint64_t modifier)
{
	uint64_t modifier_base;
	size_t column_width_bytes;
	size_t column_height;
	unsigned int fb_id;
	unsigned int i;
	void *src_buf;
	void *dst_buf;

	modifier_base = fourcc_mod_broadcom_mod(modifier);
	column_height = fourcc_mod_broadcom_param(modifier);

	switch (modifier_base) {
	case DRM_FORMAT_MOD_BROADCOM_SAND32:
		column_width_bytes = 32;
		break;
	case DRM_FORMAT_MOD_BROADCOM_SAND64:
		column_width_bytes = 64;
		break;
	case DRM_FORMAT_MOD_BROADCOM_SAND128:
		column_width_bytes = 128;
		break;
	case DRM_FORMAT_MOD_BROADCOM_SAND256:
		column_width_bytes = 256;
		break;
	default:
		igt_assert(false);
	}

	fb_id = igt_create_fb(src->fd, src->width, src->height, src->drm_format,
			      modifier, dst);
	igt_assert(fb_id > 0);

	src_buf = igt_fb_map_buffer(src->fd, src);
	igt_assert(src_buf);

	dst_buf = igt_fb_map_buffer(dst->fd, dst);
	igt_assert(dst_buf);

	for (i = 0; i < dst->num_planes; i++)
		vc4_fb_sand_tiled_convert_plane(dst, dst_buf, src, src_buf,
						column_width_bytes,
						column_height, i);

	igt_fb_unmap_buffer(src, src_buf);
	igt_fb_unmap_buffer(dst, dst_buf);

	return fb_id;
}

size_t vc4_sand_tiled_offset(size_t column_width, size_t column_size, size_t x,
			     size_t y, size_t bpp)
{
	size_t offset = 0;
	size_t cols_x;
	size_t pix_x;

	/* Offset to the beginning of the relevant column. */
	cols_x = x / column_width;
	offset += cols_x * column_size;

	/* Offset to the relevant pixel. */
	pix_x = x % column_width;
	offset += (column_width * y + pix_x) * bpp / 8;

	return offset;
}
