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