/*
 * Copyright 2016 Google Inc.
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * 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, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */

#include <stdint.h>

#include "base/cleanup.h"
#include "base/container_of.h"
#include "base/io.h"
#include "base/xalloc.h"
#include "drivers/framebuffer/tegra132.h"

enum {
	WinEnable = 1 << 30,
};

static int tegra132_framebuffer_prepare(FrameBufferOps *me, FrameBuffer *buf)
{
	Tegra132Framebuffer *fb = container_of(me, Tegra132Framebuffer, ops);

	int ret = framebuffer_read_from_fwdb(buf);
	if (ret)
		return ret;

	if (!fb->initialized) {
		// Set the framebuffer address and enable the T window.
		write32((uint32_t *)fb->winbuf_t_start_addr,
			(uintptr_t)buf->buffer);
		write32((uint32_t *)fb->win_t_win_options,
			read32((uint32_t *)fb->win_t_win_options) | WinEnable);

		cleanup_add(&fb->cleanup);
		fb->initialized = 1;
	}

	return 0;
}

int tegra132_framebuffer_disable(Tegra132Framebuffer *fb)
{
	// Disable the T Window.
	write32((uint32_t *)fb->win_t_win_options,
		read32((uint32_t *)fb->win_t_win_options) & ~WinEnable);

	fb->initialized = 0;
	return 0;
}

static int tegra132_framebuffer_cleanup(DcEvent *me)
{
	Tegra132Framebuffer *fb =
		container_of(me, Tegra132Framebuffer, cleanup.event);

	return tegra132_framebuffer_disable(fb);
}

Tegra132Framebuffer *new_tegra132_framebuffer(uintptr_t winbuf_t_start_addr,
					      uintptr_t win_t_win_options)
{
	Tegra132Framebuffer *fb = xzalloc(sizeof(*fb));

	fb->ops.prepare = &tegra132_framebuffer_prepare;

	fb->cleanup.types = CleanupOnHandoff | CleanupOnLegacy;
	fb->cleanup.event.trigger = &tegra132_framebuffer_cleanup;

	fb->winbuf_t_start_addr = winbuf_t_start_addr;
	fb->win_t_win_options = win_t_win_options;

	return fb;
}
