/*
 * udl_cursor.c
 *
 * Copyright (c) 2015 The Chromium OS Authors
 *
 * This program is free software; you can redistribute  it and/or modify it
 * under  the terms of  the GNU General  Public License as published by the
 * Free Software Foundation;  either version 2 of the  License, or (at your
 * option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

#include <drm/drmP.h>
#include <drm/drm_crtc_helper.h>

#include "udl_cursor.h"
#include "udl_drv.h"

#define UDL_CURSOR_W 64
#define UDL_CURSOR_H 64
#define UDL_CURSOR_BUF (UDL_CURSOR_W * UDL_CURSOR_H)

/*
 * UDL drm cursor private structure.
 */
struct udl_cursor {
	uint32_t buffer[UDL_CURSOR_BUF];
	bool enabled;
	int x;
	int y;
};

int udl_cursor_alloc(struct udl_cursor **cursor)
{
	struct udl_cursor *new_cursor = kzalloc(sizeof(struct udl_cursor),
		GFP_KERNEL);
	if (!new_cursor)
		return -ENOMEM;
	*cursor = new_cursor;
	return 0;
}

void udl_cursor_free(struct udl_cursor *cursor)
{
	BUG_ON(!cursor);
	kfree(cursor);
}

void udl_cursor_copy(struct udl_cursor *dst, struct udl_cursor *src)
{
	memcpy(dst, src, sizeof(struct udl_cursor));
}

bool udl_cursor_enabled(struct udl_cursor *cursor)
{
	return cursor->enabled;
}

void udl_cursor_get_hline(struct udl_cursor *cursor, int x, int y,
		struct udl_cursor_hline *hline)
{
	if (!cursor || !cursor->enabled ||
		x >= cursor->x + UDL_CURSOR_W ||
		y < cursor->y || y >= cursor->y + UDL_CURSOR_H) {
		hline->buffer = NULL;
		return;
	}

	hline->buffer = &cursor->buffer[UDL_CURSOR_W * (y - cursor->y)];
	hline->width = UDL_CURSOR_W;
	hline->offset = x - cursor->x;
}

/*
 * Return pre-computed cursor blend value defined as:
 * R: 5 bits (bit 0:4)
 * G: 6 bits (bit 5:10)
 * B: 5 bits (bit 11:15)
 * A: 7 bits (bit 16:22)
 */
static uint32_t cursor_blend_val32(uint32_t pix)
{
	/* range of alpha_scaled is 0..64 */
	uint32_t alpha_scaled = ((pix >> 24) * 65) >> 8;
	return ((pix >> 3) & 0x1f) |
		((pix >> 5) & 0x7e0) |
		((pix >> 8) & 0xf800) |
		(alpha_scaled << 16);
}

static int udl_cursor_download(struct udl_cursor *cursor,
		struct drm_gem_object *obj)
{
	struct udl_gem_object *udl_gem_obj = to_udl_bo(obj);
	uint32_t *src_ptr, *dst_ptr;
	size_t i;

	int ret = udl_gem_vmap(udl_gem_obj);
	if (ret != 0) {
		DRM_ERROR("failed to vmap cursor\n");
		return ret;
	}

	src_ptr = udl_gem_obj->vmapping;
	dst_ptr = cursor->buffer;
	for (i = 0; i < UDL_CURSOR_BUF; ++i)
		dst_ptr[i] = cursor_blend_val32(le32_to_cpu(src_ptr[i]));
	return 0;
}

int udl_cursor_set(struct drm_crtc *crtc, struct drm_file *file,
		uint32_t handle, uint32_t width, uint32_t height,
		struct udl_cursor *cursor)
{
	if (handle) {
		struct drm_gem_object *obj;
		int err;
		/* Currently we only support 64x64 cursors */
		if (width != UDL_CURSOR_W || height != UDL_CURSOR_H) {
			DRM_ERROR("we currently only support %dx%d cursors\n",
					UDL_CURSOR_W, UDL_CURSOR_H);
			return -EINVAL;
		}
		obj = drm_gem_object_lookup(file, handle);
		if (!obj) {
			DRM_ERROR("failed to lookup gem object.\n");
			return -EINVAL;
		}
		err = udl_cursor_download(cursor, obj);
		drm_gem_object_put_locked(obj);
		if (err != 0) {
			DRM_ERROR("failed to copy cursor.\n");
			return err;
		}
		cursor->enabled = true;
	} else {
		cursor->enabled = false;
	}

	return 0;
}

int udl_cursor_move(struct drm_crtc *crtc, int x, int y,
		struct udl_cursor *cursor)
{
	cursor->x = x;
	cursor->y = y;
	return 0;
}
