/*
 * (C) Copyright 2003-2004
 * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com
 *
 * (C) Copyright 2005
 * Stefan Roese, DENX Software Engineering, sr@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
 */

#include "lcd.h"


extern int video_display_bitmap (ulong, int, int);


int palette_index;
int palette_value;
int lcd_depth;
unsigned char *glob_lcd_reg;
unsigned char *glob_lcd_mem;

#ifdef CFG_LCD_ENDIAN
void lcd_setup(int lcd, int config)
{
	if (lcd == 0) {
		/*
		 * Set endianess and reset lcd controller 0 (small)
		 */
		out32(GPIO0_OR, in32(GPIO0_OR) & ~CFG_LCD0_RST); /* set reset to low */
		udelay(10); /* wait 10us */
		if (config == 1) {
			out32(GPIO0_OR, in32(GPIO0_OR) | CFG_LCD_ENDIAN); /* big-endian */
		} else {
			out32(GPIO0_OR, in32(GPIO0_OR) & ~CFG_LCD_ENDIAN); /* little-endian */
		}
		udelay(10); /* wait 10us */
		out32(GPIO0_OR, in32(GPIO0_OR) | CFG_LCD0_RST); /* set reset to high */
	} else {
		/*
		 * Set endianess and reset lcd controller 1 (big)
		 */
		out32(GPIO0_OR, in32(GPIO0_OR) & ~CFG_LCD1_RST); /* set reset to low */
		udelay(10); /* wait 10us */
		if (config == 1) {
			out32(GPIO0_OR, in32(GPIO0_OR) | CFG_LCD_ENDIAN); /* big-endian */
		} else {
			out32(GPIO0_OR, in32(GPIO0_OR) & ~CFG_LCD_ENDIAN); /* little-endian */
		}
		udelay(10); /* wait 10us */
		out32(GPIO0_OR, in32(GPIO0_OR) | CFG_LCD1_RST); /* set reset to high */
	}

	/*
	 * CFG_LCD_ENDIAN may also be FPGA_RESET, so set inactive
	 */
	out32(GPIO0_OR, in32(GPIO0_OR) | CFG_LCD_ENDIAN); /* set reset high again */
}
#endif /* #ifdef CFG_LCD_ENDIAN */


void lcd_bmp(uchar *logo_bmp)
{
	int i;
	uchar *ptr;
	ushort *ptr2;
	ushort val;
	unsigned char *dst = NULL;
	int x, y;
	int width, height, bpp, colors, line_size;
	int header_size;
	unsigned char *bmp;
	unsigned char r, g, b;
	BITMAPINFOHEADER *bm_info;
	ulong len;

	/*
	 * Check for bmp mark 'BM'
	 */
	if (*(ushort *)logo_bmp != 0x424d) {

		/*
		 * Decompress bmp image
		 */
		len = CFG_VIDEO_LOGO_MAX_SIZE;
		dst = malloc(CFG_VIDEO_LOGO_MAX_SIZE);
		if (dst == NULL) {
			printf("Error: malloc in gunzip failed!\n");
			return;
		}
		if (gunzip(dst, CFG_VIDEO_LOGO_MAX_SIZE, (uchar *)logo_bmp, &len) != 0) {
			return;
		}
		if (len == CFG_VIDEO_LOGO_MAX_SIZE) {
			printf("Image could be truncated (increase CFG_VIDEO_LOGO_MAX_SIZE)!\n");
		}

		/*
		 * Check for bmp mark 'BM'
		 */
		if (*(ushort *)dst != 0x424d) {
			printf("LCD: Unknown image format!\n");
			free(dst);
			return;
		}
	} else {
		/*
		 * Uncompressed BMP image, just use this pointer
		 */
		dst = (uchar *)logo_bmp;
	}

	/*
	 * Get image info from bmp-header
	 */
	bm_info = (BITMAPINFOHEADER *)(dst + 14);
	bpp = LOAD_SHORT(bm_info->biBitCount);
	width = LOAD_LONG(bm_info->biWidth);
	height = LOAD_LONG(bm_info->biHeight);
	switch (bpp) {
	case 1:
		colors = 1;
		line_size = width >> 3;
		break;
	case 4:
		colors = 16;
		line_size = width >> 1;
		break;
	case 8:
		colors = 256;
		line_size = width;
		break;
	case 24:
		colors = 0;
		line_size = width * 3;
		break;
	default:
		printf("LCD: Unknown bpp (%d) im image!\n", bpp);
		if ((dst != NULL) && (dst != (uchar *)logo_bmp)) {
			free(dst);
		}
		return;
	}
	printf(" (%d*%d, %dbpp)\n", width, height, bpp);

	/*
	 * Write color palette
	 */
	if ((colors <= 256) && (lcd_depth <= 8)) {
		ptr = (unsigned char *)(dst + 14 + 40);
		for (i=0; i<colors; i++) {
			b = *ptr++;
			g = *ptr++;
			r = *ptr++;
			ptr++;
			S1D_WRITE_PALETTE(glob_lcd_reg, i, r, g, b);
		}
	}

	/*
	 * Write bitmap data into framebuffer
	 */
	ptr = glob_lcd_mem;
	ptr2 = (ushort *)glob_lcd_mem;
	header_size = 14 + 40 + 4*colors;          /* skip bmp header */
	for (y=0; y<height; y++) {
		bmp = &dst[(height-1-y)*line_size + header_size];
		if (lcd_depth == 16) {
			if (bpp == 24) {
				for (x=0; x<width; x++) {
					/*
					 * Generate epson 16bpp fb-format from 24bpp image
					 */
					b = *bmp++ >> 3;
					g = *bmp++ >> 2;
					r = *bmp++ >> 3;
					val = ((r & 0x1f) << 11) | ((g & 0x3f) << 5) | (b & 0x1f);
					*ptr2++ = val;
				}
			} else if (bpp == 8) {
				for (x=0; x<line_size; x++) {
					/* query rgb value from palette */
					ptr = (unsigned char *)(dst + 14 + 40) ;
					ptr += (*bmp++) << 2;
					b = *ptr++ >> 3;
					g = *ptr++ >> 2;
					r = *ptr++ >> 3;
					val = ((r & 0x1f) << 11) | ((g & 0x3f) << 5) | (b & 0x1f);
					*ptr2++ = val;
				}
			}
		} else {
			for (x=0; x<line_size; x++) {
				*ptr++ = *bmp++;
			}
		}
	}

	if ((dst != NULL) && (dst != (uchar *)logo_bmp)) {
		free(dst);
	}
}


void lcd_init(uchar *lcd_reg, uchar *lcd_mem, S1D_REGS *regs, int reg_count,
	      uchar *logo_bmp, ulong len)
{
	int i;
	ushort s1dReg;
	uchar s1dValue;
	int reg_byte_swap;

	/*
	 * Detect epson
	 */
	lcd_reg[0] = 0x00;
	lcd_reg[1] = 0x00;

	if (lcd_reg[0] == 0x1c) {
		/*
		 * Big epson detected
		 */
		reg_byte_swap = FALSE;
		palette_index = 0x1e2;
		palette_value = 0x1e4;
		lcd_depth = 16;
		puts("LCD:   S1D13806");
	} else if (lcd_reg[1] == 0x1c) {
		/*
		 * Big epson detected (with register swap bug)
		 */
		reg_byte_swap = TRUE;
		palette_index = 0x1e3;
		palette_value = 0x1e5;
		lcd_depth = 16;
		puts("LCD:   S1D13806S");
	} else if (lcd_reg[0] == 0x18) {
		/*
		 * Small epson detected (704)
		 */
		reg_byte_swap = FALSE;
		palette_index = 0x15;
		palette_value = 0x17;
		lcd_depth = 8;
		puts("LCD:   S1D13704");
	} else if (lcd_reg[0x10000] == 0x24) {
		/*
		 * Small epson detected (705)
		 */
		reg_byte_swap = FALSE;
		palette_index = 0x15;
		palette_value = 0x17;
		lcd_depth = 8;
		lcd_reg += 0x10000; /* add offset for 705 regs */
		puts("LCD:   S1D13705");
	} else {
		puts("LCD:   No controller detected!\n");
		return;
	}

	/*
	 * Setup lcd controller regs
	 */
	for (i = 0; i<reg_count; i++) {
		s1dReg = regs[i].Index;
		if (reg_byte_swap) {
			if ((s1dReg & 0x0001) == 0)
				s1dReg |= 0x0001;
			else
				s1dReg &= ~0x0001;
		}
		s1dValue = regs[i].Value;
		lcd_reg[s1dReg] = s1dValue;
	}

	/*
	 * Save reg & mem pointer for later usage (e.g. bmp command)
	 */
	glob_lcd_reg = lcd_reg;
	glob_lcd_mem = lcd_mem;

	/*
	 * Display bmp image
	 */
	lcd_bmp(logo_bmp);
}

#ifdef CONFIG_VIDEO_SM501
int do_esdbmp(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
	ulong addr;
	char *str;

	if (argc != 2) {
		printf ("Usage:\n%s\n", cmdtp->usage);
		return 1;
	}

	addr = simple_strtoul(argv[1], NULL, 16);

	str = getenv("bd_type");
	if ((strcmp(str, "ppc221") == 0) || (strcmp(str, "ppc231") == 0)) {
		/*
		 * SM501 available, use standard bmp command
		 */
		return (video_display_bitmap(addr, 0, 0));
	} else {
		/*
		 * No SM501 available, use esd epson bmp command
		 */
		lcd_bmp((uchar *)addr);
		return 0;
	}
}

U_BOOT_CMD(
	esdbmp,	2,	1,	do_esdbmp,
	"esdbmp   - display BMP image\n",
	"<imageAddr> - display image\n"
);
#endif
