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

#include <common.h>
#include <lcd.h>
#include <mpc5xxx.h>

#ifdef CONFIG_LCD

#undef SWAPPED_LCD /* For the previous h/w version */
/*
 *  The name of the device used for communication
 * with the PSoC.
 */
#define PSOC_PSC	MPC5XXX_PSC2
#define PSOC_BAUD	230400UL

#define RTS_ASSERT	1
#define RTS_NEGATE	0
#define CTS_ASSERT	1
#define CTS_NEGATE	0

/*
 * Dimensions in pixels
 */
#define LCD_WIDTH	160
#define LCD_HEIGHT	100

/*
 * Dimensions in bytes
 */
#define LCD_BUF_SIZE	((LCD_WIDTH*LCD_HEIGHT)>>3)

#if LCD_BPP != LCD_MONOCHROME
#error "MCC200 support only monochrome displays (1 bpp)!"
#endif

#define PSOC_RETRIES	10	/* each of PSOC_WAIT_TIME */
#define PSOC_WAIT_TIME	10	/* usec */

DECLARE_GLOBAL_DATA_PTR;

/*
 * LCD information
 */
vidinfo_t panel_info = {
	LCD_WIDTH, LCD_HEIGHT, LCD_BPP
};

int lcd_line_length;

int lcd_color_fg;
int lcd_color_bg;

/*
 * Frame buffer memory information
 */
void *lcd_base;			/* Start of framebuffer memory  */
void *lcd_console_address;	/* Start of console buffer      */

short console_col = 0;
short console_row = 0;

/*
 *  The device we use to communicate with PSoC
 */
int serial_inited = 0;

/*
 * Exported functions
 */
void lcd_initcolregs (void);
void lcd_ctrl_init (void *lcdbase);
void lcd_enable (void);

/*
 *  Imported functions to support the PSoC protocol
 */
extern int serial_init_dev (unsigned long dev_base);
extern void serial_setrts_dev (unsigned long dev_base, int s);
extern int serial_getcts_dev (unsigned long dev_base);
extern void serial_putc_raw_dev(unsigned long dev_base, const char c);

/*
 *  Just stubs for our driver, needed for compiling compabilty with
 * the common LCD driver code.
 */
void lcd_initcolregs (void)
{
}

void lcd_ctrl_init (void *lcdbase)
{
}

/*
 * Function sends the contents of the frame-buffer to the LCD
 */
void lcd_enable (void)
{
	int i, retries, fb_size;

	if (!serial_inited) {
		unsigned long baud;

		baud = gd->baudrate;
		gd->baudrate = PSOC_BAUD;
		serial_init_dev(PSOC_PSC);
		gd->baudrate = baud;
		serial_setrts_dev (PSOC_PSC, RTS_ASSERT);
		serial_inited = 1;
	}

	/*
	 *  Implement PSoC communication protocol:
	 * 1. Assert RTS, wait CTS assertion
	 * 2. Transmit data
	 * 3. Negate RTS, wait CTS negation
	 */

	/* 1 */
	serial_setrts_dev (PSOC_PSC, RTS_ASSERT);
	for (retries = PSOC_RETRIES; retries; retries--) {
		if (serial_getcts_dev(PSOC_PSC) == CTS_ASSERT)
			break;
		udelay (PSOC_WAIT_TIME);
	}
	if (!retries) {
		printf ("%s Error: PSoC doesn't respond on "
			"RTS ASSERT\n",	__FUNCTION__);
	}

	/* 2 */
	fb_size = panel_info.vl_row * (panel_info.vl_col >> 3);

#if !defined(SWAPPED_LCD)
	for (i=0; i<fb_size; i++) {
		serial_putc_raw_dev (PSOC_PSC, ((char *)lcd_base)[i]);
	}
#else
    {
	int x, y, pwidth;
	char *p = (char *)lcd_base;

	pwidth = ((panel_info.vl_col+7) >> 3);
	for (y=0; y<panel_info.vl_row; y++) {
		i = y * pwidth;
		for (x=0; x<pwidth; x+=5) {
			serial_putc_raw_dev (PSOC_PSC, (p[i+x+2]<<4 & 0xF0) | (p[i+x+3]>>4 & 0x0F));
			serial_putc_raw_dev (PSOC_PSC, (p[i+x+3]<<4 & 0xF0) | (p[i+x+4]>>4 & 0x0F));
			serial_putc_raw_dev (PSOC_PSC, (p[i+x+4]<<4 & 0xF0) | (p[i+x]>>4 & 0x0F));
			serial_putc_raw_dev (PSOC_PSC, (p[i+x]<<4 & 0xF0) | (p[i+x+1]>>4 & 0x0F));
			serial_putc_raw_dev (PSOC_PSC, (p[i+x+1]<<4 & 0xF0) | (p[i+x+2]>>4 & 0x0F));
		}
	}
    }
#endif

	/* 3 */
	serial_setrts_dev (PSOC_PSC, RTS_NEGATE);
	for (retries = PSOC_RETRIES; retries; retries--) {
		if (serial_getcts_dev(PSOC_PSC) == CTS_NEGATE)
			break;
		udelay (PSOC_WAIT_TIME);
	}

	return;
}
#ifdef CONFIG_PROGRESSBAR

#define FONT_WIDTH      8 /* the same as VIDEO_FONT_WIDTH in video_font.h */
void show_progress (int size, int tot)
{
	int cnt;
	int i;
	static int rc = 0;

	rc += size;

	cnt = ((LCD_WIDTH/FONT_WIDTH) * rc) / tot;

	rc -= (cnt * tot) / (LCD_WIDTH/FONT_WIDTH);

	for (i = 0; i < cnt; i++) {
		lcd_putc(0xdc);
	}

	if (cnt) {
		lcd_enable(); /* MCC200-specific - send the framebuffer to PSoC */
	}
}

#endif
#endif /* CONFIG_LCD */
