/*
 * 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/time.h"
#include "base/xalloc.h"
#include "drivers/framebuffer/rockchip.h"

#define RK_CLRSETBITS(clr, set) ((((clr) | (set)) << 16) | set)
#define RK_SETBITS(set) RK_CLRSETBITS(0, set)
#define RK_CLRBITS(clr) RK_CLRSETBITS(clr, 0)

enum {
	VopStandbyEn = 22
};

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

	if (!fb->initialized) {
		write32((uint32_t *)fb->vop0_sys_ctrl,
			RK_CLRBITS(1 << VopStandbyEn));

		write32((uint32_t *)fb->vop1_sys_ctrl,
			RK_CLRBITS(1 << VopStandbyEn));

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

	return framebuffer_read_from_fwdb(buf);
}

int rockchip_framebuffer_disable(RockchipFramebuffer *fb)
{
	// Set vop0 to standby.
	write32((uint32_t *)fb->vop0_sys_ctrl,
		RK_SETBITS(1 << VopStandbyEn));

	// Set vop1 to standby.
	write32((uint32_t *)fb->vop1_sys_ctrl,
		RK_SETBITS(1 << VopStandbyEn));

	// Wait frame complete (60Hz) to enter standby.
	mdelay(17);

	fb->initialized = 0;
	return 0;
}

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

	return rockchip_framebuffer_disable(fb);
}

RockchipFramebuffer *new_rockchip_framebuffer(uintptr_t vop0_sys_ctrl,
					      uintptr_t vop1_sys_ctrl)
{
	RockchipFramebuffer *fb = xzalloc(sizeof(*fb));

	fb->ops.prepare = &rockchip_framebuffer_prepare;

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

	fb->vop0_sys_ctrl = vop0_sys_ctrl;
	fb->vop1_sys_ctrl = vop1_sys_ctrl;

	return fb;
}
