/*
 * (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;
	u32 i;

	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;
}
