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