/*
 * (C) Copyright 2001
 * Wolfgang Denk, DENX Software Engineering -- wd@denx.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
 */

/************************************************************************/
/* ** DEBUG SETTINGS							*/
/************************************************************************/

/* #define DEBUG	*/

/************************************************************************/
/* ** HEADER FILES							*/
/************************************************************************/

#include <config.h>
#include <common.h>
#include <version.h>
#include <stdarg.h>
#include <linux/types.h>
#include <devices.h>
#include <s3c2400.h>

DECLARE_GLOBAL_DATA_PTR;

#ifdef CONFIG_VFD

/************************************************************************/
/* ** CONFIG STUFF -- should be moved to board config file		*/
/************************************************************************/

/************************************************************************/

#ifndef PAGE_SIZE
#define	PAGE_SIZE	4096
#endif

#define ROT	0x09
#define BLAU	0x0C
#define VIOLETT	0X0D

/* MAGIC */
#define	FRAME_BUF_SIZE	((256*4*56)/8)
#define frame_buf_offs 4

/* defines for starting Timer3 as CPLD-Clk */
#define START3			(1 << 16)
#define UPDATE3			(1 << 17)
#define INVERT3			(1 << 18)
#define RELOAD3			(1 << 19)

/* CPLD-Register for controlling vfd-blank-signal */
#define VFD_DISABLE	(*(volatile uchar *)0x04038000=0x0000)
#define VFD_ENABLE	(*(volatile uchar *)0x04038000=0x0001)

/* Supported VFD Types */
#define	VFD_TYPE_T119C		1	/* Noritake T119C VFD */
#define	VFD_TYPE_MN11236	2

/*#define NEW_CPLD_CLK*/

int vfd_board_id;

/* taken from armboot/common/vfd.c */
unsigned long adr_vfd_table[112][18][2][4][2];
unsigned char bit_vfd_table[112][18][2][4][2];

/*
 * initialize the values for the VFD-grid-control in the framebuffer
 */
void init_grid_ctrl(void)
{
	ulong adr, grid_cycle;
	unsigned int bit, display;
	unsigned char temp, bit_nr;

	/*
	 * clear frame buffer (logical clear => set to "black")
	 */
	memset ((void *)(gd->fb_base), 0, FRAME_BUF_SIZE);

	switch (gd->vfd_type) {
	case VFD_TYPE_T119C:
	    for (display=0; display<4; display++) {
		for(grid_cycle=0; grid_cycle<56; grid_cycle++) {
			bit = grid_cycle * 256  * 4 +
			     (grid_cycle + 200) * 4 +
			     frame_buf_offs + display;
			/* wrap arround if offset (see manual S3C2400) */
			if (bit>=FRAME_BUF_SIZE*8)
				bit = bit - (FRAME_BUF_SIZE * 8);
			adr = gd->fb_base + (bit/32) * 4 + (3 - (bit%32) / 8);
			bit_nr = bit % 8;
			bit_nr = (bit_nr > 3) ? bit_nr-4 : bit_nr+4;
			temp=(*(volatile unsigned char*)(adr));
			temp |=  (1<<bit_nr);
			(*(volatile unsigned char*)(adr))=temp;

			if(grid_cycle<55)
				bit = grid_cycle*256*4+(grid_cycle+201)*4+frame_buf_offs+display;
			else
				bit = grid_cycle*256*4+200*4+frame_buf_offs+display-4;	/* grid nr. 0 */
			/* wrap arround if offset (see manual S3C2400) */
			if (bit>=FRAME_BUF_SIZE*8)
				bit = bit-(FRAME_BUF_SIZE*8);
			adr = gd->fb_base+(bit/32)*4+(3-(bit%32)/8);
			bit_nr = bit%8;
			bit_nr = (bit_nr>3)?bit_nr-4:bit_nr+4;
			temp=(*(volatile unsigned char*)(adr));
			temp |=  (1<<bit_nr);
			(*(volatile unsigned char*)(adr))=temp;
		}
	    }
	    break;
	case VFD_TYPE_MN11236:
	    for (display=0; display<4; display++) {
		for (grid_cycle=0; grid_cycle<38; grid_cycle++) {
			bit = grid_cycle * 256  * 4 +
			     (253 - grid_cycle) * 4 +
			     frame_buf_offs + display;
			/* wrap arround if offset (see manual S3C2400) */
			if (bit>=FRAME_BUF_SIZE*8)
				bit = bit - (FRAME_BUF_SIZE * 8);
			adr = gd->fb_base + (bit/32) * 4 + (3 - (bit%32) / 8);
			bit_nr = bit % 8;
			bit_nr = (bit_nr > 3) ? bit_nr-4 : bit_nr+4;
			temp=(*(volatile unsigned char*)(adr));
			temp |=  (1<<bit_nr);
			(*(volatile unsigned char*)(adr))=temp;

			if(grid_cycle<37)
				bit = grid_cycle*256*4+(252-grid_cycle)*4+frame_buf_offs+display;

			/* wrap arround if offset (see manual S3C2400) */
			if (bit>=FRAME_BUF_SIZE*8)
				bit = bit-(FRAME_BUF_SIZE*8);
			adr = gd->fb_base+(bit/32)*4+(3-(bit%32)/8);
			bit_nr = bit%8;
			bit_nr = (bit_nr>3)?bit_nr-4:bit_nr+4;
			temp=(*(volatile unsigned char*)(adr));
			temp |=  (1<<bit_nr);
			(*(volatile unsigned char*)(adr))=temp;
		}
	    }
	    break;
	default:
	    printf ("Warning: unknown display type\n");
	    break;
	}
}

/*
 *create translation table for getting easy the right position in the
 *physical framebuffer for some x/y-coordinates of the VFDs
 */
void create_vfd_table(void)
{
	unsigned long vfd_table[112][18][2][4][2];
	unsigned int x, y, color, display, entry, pixel;
	unsigned int x_abcdef = 0;

	switch (gd->vfd_type) {
	case VFD_TYPE_T119C:
	    for(y=0; y<=17; y++) {	/* Line */
		for(x=0; x<=111; x++) {	/* Column */
		    for(display=0; display <=3; display++) {

			    /* Display 0 blue pixels */
			    vfd_table[x][y][0][display][0] =
				(x==0) ? y*16+display
				       : (x%4)*4+y*16+((x-1)/2)*1024+display;
			    /* Display 0 red pixels */
			    vfd_table[x][y][1][display][0] =
				(x==0) ? y*16+512+display
				       : (x%4)*4+y*16+((x-1)/2)*1024+512+display;
		    }
		}
	    }
	    break;
	case VFD_TYPE_MN11236:
	    for(y=0; y<=17; y++) {	/* Line */
		for(x=0; x<=111; x++) {	/* Column */
		    for(display=0; display <=3; display++) {

			    vfd_table[x][y][0][display][0]=0;
			    vfd_table[x][y][0][display][1]=0;
			    vfd_table[x][y][1][display][0]=0;
			    vfd_table[x][y][1][display][1]=0;

			    switch (x%6) {
			    case 0: x_abcdef=0; break; /* a -> a */
			    case 1: x_abcdef=2; break; /* b -> c */
			    case 2: x_abcdef=4; break; /* c -> e */
			    case 3: x_abcdef=5; break; /* d -> f */
			    case 4: x_abcdef=3; break; /* e -> d */
			    case 5: x_abcdef=1; break; /* f -> b */
			    }

			    /* blue pixels */
			    vfd_table[x][y][0][display][0] =
				(x>1) ? x_abcdef*4+((x-1)/3)*1024+y*48+display
				      : x_abcdef*4+             0+y*48+display;
			    /* blue pixels */
			    if (x>1 && (x-1)%3)
				    vfd_table[x][y][0][display][1] = x_abcdef*4+((x-1)/3+1)*1024+y*48+display;

			    /* red pixels */
			    vfd_table[x][y][1][display][0] =
				(x>1) ? x_abcdef*4+24+((x-1)/3)*1024+y*48+display
				      : x_abcdef*4+24+             0+y*48+display;
			    /* red pixels */
			    if (x>1 && (x-1)%3)
				    vfd_table[x][y][1][display][1] = x_abcdef*4+24+((x-1)/3+1)*1024+y*48+display;
		    }
		}
	    }
	    break;
	default:
	    /* do nothing */
	    return;
	}

	/*
	 * Create table with entries for physical byte adresses and
	 * bit-number within the byte
	 * from table with bit-numbers within the total framebuffer
	 */
	for(y=0;y<18;y++) {
	    for(x=0;x<112;x++) {
		for(color=0;color<2;color++) {
		    for(display=0;display<4;display++) {
			for(entry=0;entry<2;entry++) {
			    unsigned long adr  = gd->fb_base;
			    unsigned int bit_nr = 0;

			    pixel  = vfd_table[x][y][color][display][entry] + frame_buf_offs;
			    /*
			     * wrap arround if offset
			     * (see manual S3C2400)
			     */
			    if (pixel>=FRAME_BUF_SIZE*8)
				    pixel = pixel-(FRAME_BUF_SIZE*8);
			    adr    = gd->fb_base+(pixel/32)*4+(3-(pixel%32)/8);
			    bit_nr = pixel%8;
			    bit_nr = (bit_nr>3)?bit_nr-4:bit_nr+4;

			    adr_vfd_table[x][y][color][display][entry] = adr;
			    bit_vfd_table[x][y][color][display][entry] = bit_nr;
			}
		    }
		}
	    }
	}
}

/*
 * Set/clear pixel of the VFDs
 */
void set_vfd_pixel(unsigned char x, unsigned char y,
		   unsigned char color, unsigned char display,
		   unsigned char value)
{
	ulong adr;
	unsigned char bit_nr, temp;

	if (! gd->vfd_type) {
		/* Unknown type. */
		return;
	}

	/* Pixel-Eintrag Nr. 1 */
	adr = adr_vfd_table[x][y][color][display][0];
	/* Pixel-Eintrag Nr. 1 */
	bit_nr = bit_vfd_table[x][y][color][display][0];
	temp=(*(volatile unsigned char*)(adr));

	if (value)
		temp |=  (1<<bit_nr);
	else
		temp &= ~(1<<bit_nr);

	(*(volatile unsigned char*)(adr))=temp;
}

/*
 * transfer image from BMP-File
 */
void transfer_pic(int display, unsigned char *adr, int height, int width)
{
	int x, y;
	unsigned char temp;

	for (; height > 0; height -= 18)
	{
		if (height > 18)
			y = 18;
		else
			y = height;
		for (; y > 0; y--)
		{
			for (x = 0; x < width; x += 2)
			{
				temp = *adr++;
				set_vfd_pixel(x, y-1, 0, display, 0);
				set_vfd_pixel(x, y-1, 1, display, 0);
				if ((temp >> 4) == BLAU)
					set_vfd_pixel(x, y-1, 0, display, 1);
				else if ((temp >> 4) == ROT)
					set_vfd_pixel(x, y-1, 1, display, 1);
				else if ((temp >> 4) == VIOLETT)
				{
					set_vfd_pixel(x, y-1, 0, display, 1);
					set_vfd_pixel(x, y-1, 1, display, 1);
				}
				set_vfd_pixel(x+1, y-1, 0, display, 0);
				set_vfd_pixel(x+1, y-1, 1, display, 0);
				if ((temp & 0x0F) == BLAU)
					set_vfd_pixel(x+1, y-1, 0, display, 1);
				else if ((temp & 0x0F) == ROT)
					set_vfd_pixel(x+1, y-1, 1, display, 1);
				else if ((temp & 0x0F) == VIOLETT)
				{
					set_vfd_pixel(x+1, y-1, 0, display, 1);
					set_vfd_pixel(x+1, y-1, 1, display, 1);
				}
			}
		}
		if (display > 0)
			display--;
		else
			display = 3;
	}
}

/*
 * This function initializes VFD clock that is needed for the CPLD that
 * manages the keyboard.
 */
int vfd_init_clocks (void)
{
	int i;

	S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
	S3C24X0_TIMERS * const timers = S3C24X0_GetBase_TIMERS();
	S3C24X0_LCD * const lcd = S3C24X0_GetBase_LCD();

	/* try to determine display type from the value
	 * defined by pull-ups
	 */
	gpio->PCUP = (gpio->PCUP & 0xFFF0);	/* activate  GPC0...GPC3 pullups */
	gpio->PCCON = (gpio->PCCON & 0xFFFFFF00);	/* configure GPC0...GPC3 as inputs */
	/* allow signals to settle */
	for (i=0; i<10000; i++)	/* udelay isn't working yet at this point! */
		__asm__("NOP");
	vfd_board_id = (~gpio->PCDAT) & 0x000F;	/* read GPC0...GPC3 port pins */

	VFD_DISABLE;				/* activate blank for the vfd */

#define	NEW_CPLD_CLK

#ifdef NEW_CPLD_CLK
	if (vfd_board_id) {
		/* If new board revision, then use PWM 3 as cpld-clock */
		/* Enable 500 Hz timer for fill level sensor to operate properly */
		/* Configure TOUT3 as functional pin, disable pull-up */
		gpio->PDCON &= ~0x30000;
		gpio->PDCON |= 0x20000;
		gpio->PDUP |= (1 << 8);

		/* Configure the prescaler */
		timers->TCFG0 &= ~0xff00;
		timers->TCFG0 |= 0x0f00;

		/* Select MUX input (divider) for timer3 (1/16) */
		timers->TCFG1 &= ~0xf000;
		timers->TCFG1 |= 0x3000;

		/* Enable autoreload and set the counter and compare
		 * registers to values for the 500 Hz clock
		 * (for a given  prescaler (15) and divider (16)):
		 * counter = (66000000 / 500) >> 9;
		 */
		timers->ch[3].TCNTB = 0x101;
		timers->ch[3].TCMPB = 0x101 / 2;

		/* Start timer */
		timers->TCON = (timers->TCON | UPDATE3 | RELOAD3) & ~INVERT3;
		timers->TCON = (timers->TCON | START3) & ~UPDATE3;
	}
#endif
	/* If old board revision, then use vm-signal as cpld-clock */
	lcd->LCDCON2 = 0x00FFC000;
	lcd->LCDCON3 = 0x0007FF00;
	lcd->LCDCON4 = 0x00000000;
	lcd->LCDCON5 = 0x00000400;
	lcd->LCDCON1 = 0x00000B75;
	/* VM (GPD1) is used as clock for the CPLD */
	gpio->PDCON = (gpio->PDCON & 0xFFFFFFF3) | 0x00000008;

	return 0;
}

/*
 * initialize LCD-Controller of the S3C2400 for using VFDs
 *
 * VFD detection depends on the board revision:
 * starting from Rev. 200 a type code can be read from the data pins,
 * driven by some pull-up resistors; all earlier systems must be
 * manually configured. The type is set in the "vfd_type" environment
 * variable.
 */
int drv_vfd_init(void)
{
	S3C24X0_LCD * const lcd = S3C24X0_GetBase_LCD();
	S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
	char *tmp;
	ulong palette;
	static int vfd_init_done = 0;
	int vfd_inv_data = 0;

	if (vfd_init_done != 0)
		return (0);
	vfd_init_done = 1;

	debug("Detecting Revison of WA4-VFD: ID=0x%X\n", vfd_board_id);

	switch (vfd_board_id) {
	case 0:			/* board revision < Rev.200 */
		if ((tmp = getenv ("vfd_type")) == NULL) {
			break;
		}
		if (strcmp(tmp, "T119C") == 0) {
			gd->vfd_type = VFD_TYPE_T119C;
		} else if (strcmp(tmp, "MN11236") == 0) {
			gd->vfd_type = VFD_TYPE_MN11236;
		} else {
			/* cannot use printf for a warning here */
			gd->vfd_type = 0;	/* unknown */
		}

		break;
	default:		/* default to MN11236, data inverted */
		gd->vfd_type = VFD_TYPE_MN11236;
		vfd_inv_data = 1;
		setenv ("vfd_type", "MN11236");
	}
	debug ("VFD type: %s%s\n",
		(gd->vfd_type == VFD_TYPE_T119C)   ? "T119C" :
		(gd->vfd_type == VFD_TYPE_MN11236) ? "MN11236" :
		"unknown",
		vfd_inv_data ? ", inverted data" : "");

	gd->fb_base = gd->fb_base;
	create_vfd_table();
	init_grid_ctrl();

	for (palette=0; palette < 16; palette++)
		(*(volatile unsigned int*)(PALETTE+(palette*4)))=palette;
	for (palette=16; palette < 256; palette++)
		(*(volatile unsigned int*)(PALETTE+(palette*4)))=0x00;

	/*
	 * Hinweis: Der Framebuffer ist um genau ein Nibble verschoben
	 * Das erste angezeigte Pixel wird aus dem zweiten Nibble geholt
	 * das letzte angezeigte Pixel wird aus dem ersten Nibble geholt
	 * (wrap around)
	 * see manual S3C2400
	 */
	/* Stopp LCD-Controller */
	lcd->LCDCON1 = 0x00000000;
	/* frame buffer startadr */
	lcd->LCDSADDR1 = gd->fb_base >> 1;
	/* frame buffer endadr */
	lcd->LCDSADDR2 = (gd->fb_base + FRAME_BUF_SIZE) >> 1;
	lcd->LCDSADDR3 = ((256/4));
	lcd->LCDCON2 = 0x000DC000;
	if(gd->vfd_type == VFD_TYPE_MN11236)
		lcd->LCDCON2 = 37 << 14;	/* MN11236: 38 lines */
	else
		lcd->LCDCON2 = 55 << 14;	/* T119C:   56 lines */
	lcd->LCDCON3 = 0x0051000A;
	lcd->LCDCON4 = 0x00000001;
	if (gd->vfd_type && vfd_inv_data)
		lcd->LCDCON5 = 0x000004C0;
	else
		lcd->LCDCON5 = 0x00000440;

	/* Port pins as LCD output */
	gpio->PCCON =   (gpio->PCCON & 0xFFFFFF00)| 0x000000AA;
	gpio->PDCON =   (gpio->PDCON & 0xFFFFFF03)| 0x000000A8;

	/* Synchronize VFD enable with LCD controller to avoid flicker	*/
	lcd->LCDCON1 = 0x00000B75;			/* Start LCD-Controller	*/
	while((lcd->LCDCON5 & 0x180000)!=0x100000);	/* Wait for end of VSYNC */
	while((lcd->LCDCON5 & 0x060000)!=0x040000);	/* Wait for next HSYNC	*/
	while((lcd->LCDCON5 & 0x060000)==0x040000);
	while((lcd->LCDCON5 & 0x060000)!=0x000000);
	if(gd->vfd_type)
		VFD_ENABLE;

	debug ("LCDSADDR1: %lX\n", lcd->LCDSADDR1);
	debug ("LCDSADDR2: %lX\n", lcd->LCDSADDR2);
	debug ("LCDSADDR3: %lX\n", lcd->LCDSADDR3);

	return 0;
}

/*
 * Disable VFD: should be run before resetting the system:
 * disable VM, enable pull-up
 */
void disable_vfd (void)
{
	S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();

	VFD_DISABLE;
	gpio->PDCON &= ~0xC;
	gpio->PDUP  &= ~0x2;
}

/************************************************************************/
/* ** ROM capable initialization part - needed to reserve FB memory	*/
/************************************************************************/

/*
 * This is called early in the system initialization to grab memory
 * for the VFD controller.
 *
 * Note that this is running from ROM, so no write access to global data.
 */
ulong vfd_setmem (ulong addr)
{
	ulong size;

	/* Round up to nearest full page */
	size = (FRAME_BUF_SIZE + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);

	debug ("Reserving %ldk for VFD Framebuffer at: %08lx\n", size>>10, addr);

	return (size);
}

/*
 * Calculate fb size for VIDEOLFB_ATAG. Size returned contains fb,
 * descriptors and palette areas.
 */
ulong calc_fbsize (void)
{
	return FRAME_BUF_SIZE;
}

#endif /* CONFIG_VFD */
