/*
 * (C) Copyright 2010
 * Matthias Weisser <weisserm@arcor.de>
 *
 * 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
 */

/*
 * mb86r0xgdc.c - Graphic interface for Fujitsu MB86R0x integrated graphic
 * controller.
 */

#include <common.h>

#include <malloc.h>
#include <asm/io.h>
#include <asm/arch/hardware.h>
#include <video_fb.h>
#include "videomodes.h"

/*
 * 4MB (at the end of system RAM)
 */
#define VIDEO_MEM_SIZE		0x400000

#define FB_SYNC_CLK_INV		(1<<16)	/* pixel clock inverted */

/*
 * Graphic Device
 */
static GraphicDevice mb86r0x;

static void dsp_init(struct mb86r0x_gdc_dsp *dsp, char *modestr,
			u32 *videomem)
{
	struct ctfb_res_modes var_mode;
	u32 dcm1, dcm2, dcm3;
	u16 htp, hdp, hdb, hsp, vtr, vsp, vdp;
	u8 hsw, vsw;
	u32 l2m, l2em, l2oa0, l2da0, l2oa1, l2da1;
	u16 l2dx, l2dy, l2wx, l2wy, l2ww, l2wh;
	unsigned long div;
	int bpp;

	bpp = video_get_params(&var_mode, modestr);

	if (bpp == 0) {
		var_mode.xres = 640;
		var_mode.yres = 480;
		var_mode.pixclock = 39721;	/* 25MHz */
		var_mode.left_margin = 48;
		var_mode.right_margin = 16;
		var_mode.upper_margin = 33;
		var_mode.lower_margin = 10;
		var_mode.hsync_len = 96;
		var_mode.vsync_len = 2;
		var_mode.sync = 0;
		var_mode.vmode = 0;
		bpp = 15;
	}

	/* Fill memory with white */
	memset(videomem, 0xFF, var_mode.xres * var_mode.yres * 2);

	mb86r0x.winSizeX = var_mode.xres;
	mb86r0x.winSizeY = var_mode.yres;

	/* LCD base clock is ~ 660MHZ. We do calculations in kHz */
	div = 660000 / (1000000000L / var_mode.pixclock);
	if (div > 64)
		div = 64;
	if (0 == div)
		div = 1;

	dcm1 = (div - 1) << 8;
	dcm2 = 0x00000000;
	if (var_mode.sync & FB_SYNC_CLK_INV)
		dcm3 = 0x00000100;
	else
		dcm3 = 0x00000000;

	htp = var_mode.left_margin + var_mode.xres +
		var_mode.hsync_len + var_mode.right_margin;
	hdp = var_mode.xres;
	hdb = var_mode.xres;
	hsp = var_mode.xres + var_mode.right_margin;
	hsw = var_mode.hsync_len;

	vsw = var_mode.vsync_len;
	vtr = var_mode.upper_margin + var_mode.yres +
		var_mode.vsync_len + var_mode.lower_margin;
	vsp = var_mode.yres + var_mode.lower_margin;
	vdp = var_mode.yres;

	l2m =	((var_mode.yres - 1) << (0)) |
		(((var_mode.xres * 2) / 64) << (16)) |
		((1) << (31));

	l2em = (1 << 0) | (1 << 1);

	l2oa0 = mb86r0x.frameAdrs;
	l2da0 = mb86r0x.frameAdrs;
	l2oa1 = mb86r0x.frameAdrs;
	l2da1 = mb86r0x.frameAdrs;
	l2dx = 0;
	l2dy = 0;
	l2wx = 0;
	l2wy = 0;
	l2ww = var_mode.xres;
	l2wh = var_mode.yres - 1;

	writel(dcm1, &dsp->dcm1);
	writel(dcm2, &dsp->dcm2);
	writel(dcm3, &dsp->dcm3);

	writew(htp, &dsp->htp);
	writew(hdp, &dsp->hdp);
	writew(hdb, &dsp->hdb);
	writew(hsp, &dsp->hsp);
	writeb(hsw, &dsp->hsw);

	writeb(vsw, &dsp->vsw);
	writew(vtr, &dsp->vtr);
	writew(vsp, &dsp->vsp);
	writew(vdp, &dsp->vdp);

	writel(l2m, &dsp->l2m);
	writel(l2em, &dsp->l2em);
	writel(l2oa0, &dsp->l2oa0);
	writel(l2da0, &dsp->l2da0);
	writel(l2oa1, &dsp->l2oa1);
	writel(l2da1, &dsp->l2da1);
	writew(l2dx, &dsp->l2dx);
	writew(l2dy, &dsp->l2dy);
	writew(l2wx, &dsp->l2wx);
	writew(l2wy, &dsp->l2wy);
	writew(l2ww, &dsp->l2ww);
	writew(l2wh, &dsp->l2wh);

	writel(dcm1 | (1 << 18) | (1 << 31), &dsp->dcm1);
}

void *video_hw_init(void)
{
	struct mb86r0x_gdc *gdc = (struct mb86r0x_gdc *) MB86R0x_GDC_BASE;
	GraphicDevice *pGD = &mb86r0x;
	char *s;
	u32 *vid;

	memset(pGD, 0, sizeof(GraphicDevice));

	pGD->gdfIndex = GDF_15BIT_555RGB;
	pGD->gdfBytesPP = 2;
	pGD->memSize = VIDEO_MEM_SIZE;
	pGD->frameAdrs = PHYS_SDRAM + PHYS_SDRAM_SIZE - VIDEO_MEM_SIZE;

	vid = (u32 *)pGD->frameAdrs;

	s = getenv("videomode");
	if (s != NULL)
		dsp_init(&gdc->dsp0, s, vid);

	s = getenv("videomode1");
	if (s != NULL)
		dsp_init(&gdc->dsp1, s, vid);

	return pGD;
}
