/*
 * AMLOGIC Canvas management driver.
 *
 * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
 *
 * 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.
 *
 */

/* System Headers */
#include <common.h>
#include <asm/arch/io.h>
#include <asm/arch/secure_apb.h>


/* Amlogic Headers */
#include <amlogic/canvas.h>

#ifdef BL33_DEBUG_PRINT
#define CANVAS_DEBUG_ENABLE
#endif
#ifdef CANVAS_DEBUG_ENABLE
#define canvas_log(fmt, args...) \
	do { \
		printf("[CANVAS]"fmt"\n", ##args); \
	} while (0)
#else
#define canvas_log(fmt, args...)
#endif

#define canvas_reg_read(reg) readl(DMC_REG_BASE + reg)
#define canvas_reg_write(val, reg) writel(val, (DMC_REG_BASE + reg))

#define CANVAS_NUM 256
static canvas_t canvasPool[CANVAS_NUM];
static int canvas_inited = 0;

void canvas_init(void)
{
	int index = 0;

	if (canvas_inited == 1)
		return;

	canvas_log("canvas init");
	canvas_reg_write(0, DC_CAV_LUT_DATAL);
	canvas_reg_write(0, DC_CAV_LUT_DATAH);
	for (index = 0; index < CANVAS_NUM; index++) {
		canvas_reg_write(CANVAS_LUT_WR_EN | index, DC_CAV_LUT_ADDR);
		canvas_reg_read(DC_CAV_LUT_DATAH);
	}

	canvas_inited = 1;
}

void canvas_config(u32 index, ulong addr, u32 width,
		   u32 height, u32 wrap, u32 blkmode)
{
	canvas_t *canvasP = &canvasPool[index];

	if (index >= CANVAS_NUM)
		return;

	canvas_init();

	canvas_log("addr=0x%08lx width=%d, height=%d", addr, width, height);
	canvas_reg_write((((addr + 7) >> 3) & CANVAS_ADDR_LMASK) |
			 ((((width + 7) >> 3) & CANVAS_WIDTH_LMASK) << CANVAS_WIDTH_LBIT),
			 DC_CAV_LUT_DATAL);
	canvas_reg_write(((((width + 7) >> 3) >> CANVAS_WIDTH_LWID) <<
			  CANVAS_WIDTH_HBIT) |
			 ((height & CANVAS_HEIGHT_MASK) << CANVAS_HEIGHT_BIT)	|
			 ((wrap & CANVAS_XWRAP) ? CANVAS_XWRAP : 0)              |
			 ((wrap & CANVAS_YWRAP) ? CANVAS_YWRAP : 0)              |
			 ((blkmode & CANVAS_BLKMODE_MASK) << CANVAS_BLKMODE_BIT),
			 DC_CAV_LUT_DATAH);
	canvas_reg_write(CANVAS_LUT_WR_EN | index, DC_CAV_LUT_ADDR);
	// read a cbus to make sure last write finish.
	canvas_reg_read(DC_CAV_LUT_DATAH);

	canvasP->addr = addr;
	canvasP->width = width;
	canvasP->height = height;
	canvasP->wrap = wrap;
	canvasP->blkmode = blkmode;

}

void canvas_read(u32 index, canvas_t *p)
{
	if (index < CANVAS_NUM)
		*p = canvasPool[index];
}

void canvas_copy(u32 src, u32 dst)
{
	unsigned long addr;
	unsigned width, height, wrap, blkmode;

	if ((src >= CANVAS_NUM) || (dst >= CANVAS_NUM))
		return;

	addr = canvasPool[src].addr;
	width = canvasPool[src].width;
	height = canvasPool[src].height;
	wrap = canvasPool[src].wrap;
	blkmode = canvasPool[src].blkmode;

	canvas_reg_write((((addr + 7) >> 3) & CANVAS_ADDR_LMASK) |
			 ((((width + 7) >> 3) & CANVAS_WIDTH_LMASK) << CANVAS_WIDTH_LBIT),
			 DC_CAV_LUT_DATAL);
	canvas_reg_write(((((width + 7) >> 3) >> CANVAS_WIDTH_LWID) <<
			  CANVAS_WIDTH_HBIT) |
			 ((height & CANVAS_HEIGHT_MASK) << CANVAS_HEIGHT_BIT)    |
			 ((wrap & CANVAS_XWRAP) ? CANVAS_XWRAP : 0)              |
			 ((wrap & CANVAS_YWRAP) ? CANVAS_YWRAP : 0)              |
			 ((blkmode & CANVAS_BLKMODE_MASK) << CANVAS_BLKMODE_BIT),
			 DC_CAV_LUT_DATAH);
	canvas_reg_write(CANVAS_LUT_WR_EN | dst, DC_CAV_LUT_ADDR);
	// read a cbus to make sure last write finish.
	canvas_reg_read(DC_CAV_LUT_DATAH);

	canvasPool[dst].addr = addr;
	canvasPool[dst].width = width;
	canvasPool[dst].height = height;
	canvasPool[dst].wrap = wrap;
	canvasPool[dst].blkmode = blkmode;

	return;
}

void canvas_update_addr(u32 index, u32 addr)
{
	if (index >= CANVAS_NUM)
		return;

	canvasPool[index].addr = addr;

	canvas_reg_write((((canvasPool[index].addr + 7) >> 3) & CANVAS_ADDR_LMASK) |
			 ((((canvasPool[index].width + 7) >> 3) & CANVAS_WIDTH_LMASK) <<
			  CANVAS_WIDTH_LBIT), DC_CAV_LUT_DATAL);
	canvas_reg_write(((((canvasPool[index].width + 7) >> 3) >> CANVAS_WIDTH_LWID) <<
			  CANVAS_WIDTH_HBIT) |
			 ((canvasPool[index].height & CANVAS_HEIGHT_MASK) << CANVAS_HEIGHT_BIT)   |
			 ((canvasPool[index].wrap & CANVAS_XWRAP) ? CANVAS_XWRAP : 0)             |
			 ((canvasPool[index].wrap & CANVAS_YWRAP) ? CANVAS_YWRAP : 0)             |
			 ((canvasPool[index].blkmode & CANVAS_BLKMODE_MASK) << CANVAS_BLKMODE_BIT),
			 DC_CAV_LUT_DATAH);
	canvas_reg_write(CANVAS_LUT_WR_EN | index, DC_CAV_LUT_ADDR);
	// read a cbus to make sure last write finish.
	canvas_reg_read(DC_CAV_LUT_DATAH);

	return;
}

unsigned int canvas_get_addr(u32 index)
{
	return canvasPool[index].addr;
}
