/*
 * (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>

#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)
{
	DECLARE_GLOBAL_DATA_PTR;
	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)
{
	DECLARE_GLOBAL_DATA_PTR;
	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;

			    if (vfd_table[x][y][color][display][entry]) {

				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)
{
	DECLARE_GLOBAL_DATA_PTR;
	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)
{
	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 */
	udelay (10);				/* allow signals to settle */
	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;

	DECLARE_GLOBAL_DATA_PTR;

	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 */
