/*
 * Copyright (c) 2015 Google, Inc
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <common.h>
#include <dm.h>
#include <mapmem.h>
#include <stdio_dev.h>
#include <video.h>
#include <video_console.h>
#include <dm/lists.h>
#include <dm/device-internal.h>
#include <dm/uclass-internal.h>
#ifdef CONFIG_SANDBOX
#include <asm/sdl.h>
#endif

/*
 * Theory of operation:
 *
 * Before relocation each device is bound. The driver for each device must
 * set the @align and @size values in struct video_uc_platdata. This
 * information represents the requires size and alignment of the frame buffer
 * for the device. The values can be an over-estimate but cannot be too
 * small. The actual values will be suppled (in the same manner) by the bind()
 * method after relocation.
 *
 * This information is then picked up by video_reserve() which works out how
 * much memory is needed for all devices. This is allocated between
 * gd->video_bottom and gd->video_top.
 *
 * After relocation the same process occurs. The driver supplies the same
 * @size and @align information and this time video_post_bind() checks that
 * the drivers does not overflow the allocated memory.
 *
 * The frame buffer address is actually set (to plat->base) in
 * video_post_probe(). This function also clears the frame buffer and
 * allocates a suitable text console device. This can then be used to write
 * text to the video device.
 */
DECLARE_GLOBAL_DATA_PTR;

void video_set_flush_dcache(struct udevice *dev, bool flush)
{
	struct video_priv *priv = dev_get_uclass_priv(dev);

	priv->flush_dcache = flush;
}

static ulong alloc_fb(struct udevice *dev, ulong *addrp)
{
	struct video_uc_platdata *plat = dev_get_uclass_platdata(dev);
	ulong base, align, size;

	align = plat->align ? plat->align : 1 << 20;
	base = *addrp - plat->size;
	base &= ~(align - 1);
	plat->base = base;
	size = *addrp - base;
	*addrp = base;

	return size;
}

int video_reserve(ulong *addrp)
{
	struct udevice *dev;
	ulong size;

	gd->video_top = *addrp;
	for (uclass_find_first_device(UCLASS_VIDEO, &dev);
	     dev;
	     uclass_find_next_device(&dev)) {
		size = alloc_fb(dev, addrp);
		debug("%s: Reserving %lx bytes at %lx for video device '%s'\n",
		      __func__, size, *addrp, dev->name);
	}
	gd->video_bottom = *addrp;
	debug("Video frame buffers from %lx to %lx\n", gd->video_bottom,
	      gd->video_top);

	return 0;
}

static int video_clear(struct udevice *dev)
{
	struct video_priv *priv = dev_get_uclass_priv(dev);

	if (priv->bpix == VIDEO_BPP32) {
		u32 *ppix = priv->fb;
		u32 *end = priv->fb + priv->fb_size;

		while (ppix < end)
			*ppix++ = priv->colour_bg;
	} else {
		memset(priv->fb, priv->colour_bg, priv->fb_size);
	}

	return 0;
}

/* Flush video activity to the caches */
void video_sync(struct udevice *vid)
{
	/*
	 * flush_dcache_range() is declared in common.h but it seems that some
	 * architectures do not actually implement it. Is there a way to find
	 * out whether it exists? For now, ARM is safe.
	 */
#if defined(CONFIG_ARM) && !defined(CONFIG_SYS_DCACHE_OFF)
	struct video_priv *priv = dev_get_uclass_priv(vid);

	if (priv->flush_dcache) {
		flush_dcache_range((ulong)priv->fb,
				   (ulong)priv->fb + priv->fb_size);
	}
#elif defined(CONFIG_VIDEO_SANDBOX_SDL)
	struct video_priv *priv = dev_get_uclass_priv(vid);
	static ulong last_sync;

	if (get_timer(last_sync) > 10) {
		sandbox_sdl_sync(priv->fb);
		last_sync = get_timer(0);
	}
#endif
}

void video_sync_all(void)
{
	struct udevice *dev;

	for (uclass_find_first_device(UCLASS_VIDEO, &dev);
	     dev;
	     uclass_find_next_device(&dev)) {
		if (device_active(dev))
			video_sync(dev);
	}
}

int video_get_xsize(struct udevice *dev)
{
	struct video_priv *priv = dev_get_uclass_priv(dev);

	return priv->xsize;
}

int video_get_ysize(struct udevice *dev)
{
	struct video_priv *priv = dev_get_uclass_priv(dev);

	return priv->ysize;
}

/* Set up the colour map */
static int video_pre_probe(struct udevice *dev)
{
	struct video_priv *priv = dev_get_uclass_priv(dev);

	priv->cmap = calloc(256, sizeof(ushort));
	if (!priv->cmap)
		return -ENOMEM;

	return 0;
}

static int video_pre_remove(struct udevice *dev)
{
	struct video_priv *priv = dev_get_uclass_priv(dev);

	free(priv->cmap);

	return 0;
}

/* Set up the display ready for use */
static int video_post_probe(struct udevice *dev)
{
	struct video_uc_platdata *plat = dev_get_uclass_platdata(dev);
	struct video_priv *priv = dev_get_uclass_priv(dev);
	char name[30], drv[15], *str;
	struct udevice *cons;
	int ret;

	/* Set up the line and display size */
	priv->fb = map_sysmem(plat->base, plat->size);
	priv->line_length = priv->xsize * VNBYTES(priv->bpix);
	priv->fb_size = priv->line_length * priv->ysize;

	/* Set up colours - we could in future support other colours */
#ifdef CONFIG_SYS_WHITE_ON_BLACK
	priv->colour_fg = 0xffffff;
#else
	priv->colour_bg = 0xffffff;
#endif
	video_clear(dev);

	/*
	 * Create a text console devices. For now we always do this, although
	 * it might be useful to support only bitmap drawing on the device
	 * for boards that don't need to display text.
	 */
	snprintf(name, sizeof(name), "%s.vidconsole", dev->name);
	str = strdup(name);
	if (!str)
		return -ENOMEM;
	snprintf(drv, sizeof(drv), "vidconsole%d", priv->rot);
	ret = device_bind_driver(dev, drv, str, &cons);
	if (ret) {
		debug("%s: Cannot bind console driver\n", __func__);
		return ret;
	}
	ret = device_probe(cons);
	if (ret) {
		debug("%s: Cannot probe console driver\n", __func__);
		return ret;
	}

	return 0;
};

/* Post-relocation, allocate memory for the frame buffer */
static int video_post_bind(struct udevice *dev)
{
	ulong addr = gd->video_top;
	ulong size;

	/* Before relocation there is nothing to do here */
	if ((!gd->flags & GD_FLG_RELOC))
		return 0;
	size = alloc_fb(dev, &addr);
	if (addr < gd->video_bottom) {
		/* Device tree node may need the 'u-boot,dm-pre-reloc' tag */
		printf("Video device '%s' cannot allocate frame buffer memory -ensure the device is set up before relocation\n",
		       dev->name);
		return -ENOSPC;
	}
	debug("%s: Claiming %lx bytes at %lx for video device '%s'\n",
	      __func__, size, addr, dev->name);
	gd->video_bottom = addr;

	return 0;
}

UCLASS_DRIVER(video) = {
	.id		= UCLASS_VIDEO,
	.name		= "video",
	.flags		= DM_UC_FLAG_SEQ_ALIAS,
	.post_bind	= video_post_bind,
	.pre_probe	= video_pre_probe,
	.post_probe	= video_post_probe,
	.pre_remove	= video_pre_remove,
	.per_device_auto_alloc_size	= sizeof(struct video_priv),
	.per_device_platdata_auto_alloc_size = sizeof(struct video_uc_platdata),
};
