/* * (C) Copyright 2006 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * * SPDX-License-Identifier: GPL-2.0+ */ #include #include #include #include #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 */ #include #define FONT_WIDTH VIDEO_FONT_WIDTH DECLARE_GLOBAL_DATA_PTR; /* * LCD information */ vidinfo_t panel_info = { LCD_WIDTH, LCD_HEIGHT, LCD_BPP }; /* * The device we use to communicate with PSoC */ int serial_inited = 0; /* * 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; ifb_base)[i]); } #else { int x, y, pwidth; char *p = (char *)gd->fb_base; pwidth = ((panel_info.vl_col+7) >> 3); for (y=0; y>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 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 int bmp_display(ulong addr, int x, int y) { int ret; bmp_image_t *bmp = (bmp_image_t *)addr; if (!bmp) { printf("There is no valid bmp file at the given address\n"); return 1; } ret = lcd_display_bitmap((ulong)bmp, x, y); if ((unsigned long)bmp != addr) free(bmp); return ret; } #endif /* CONFIG_LCD */