From 676d319ef5f450ca7845555f75de496b96cd688e Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 17 Oct 2012 13:24:54 +0000 Subject: lcd: Add CONFIG_LCD_ALIGNMENT to select frame buffer alignment The normal alignment is PAGE_SIZE, but if this is defined, we can support other alignments. The motivation for this change is to make the display section-aligned on ARM so that we can easily turn off data caching for the frame buffer region without resorting to level 2 page tables. Signed-off-by: Simon Glass Signed-off-by: Tom Warren --- common/lcd.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) (limited to 'common/lcd.c') diff --git a/common/lcd.c b/common/lcd.c index b6be8002d20..37b03936f90 100644 --- a/common/lcd.c +++ b/common/lcd.c @@ -72,6 +72,10 @@ # endif #endif +#ifndef CONFIG_LCD_ALIGNMENT +#define CONFIG_LCD_ALIGNMENT PAGE_SIZE +#endif + DECLARE_GLOBAL_DATA_PTR; ulong lcd_setmem (ulong addr); @@ -326,6 +330,12 @@ static void test_pattern(void) /* ** GENERIC Initialization Routines */ /************************************************************************/ +int lcd_get_size(int *line_length) +{ + *line_length = (panel_info.vl_col * NBITS(panel_info.vl_bpix)) / 8; + return *line_length * panel_info.vl_row; +} + int drv_lcd_init (void) { struct stdio_dev lcddev; @@ -333,7 +343,7 @@ int drv_lcd_init (void) lcd_base = (void *)(gd->fb_base); - lcd_line_length = (panel_info.vl_col * NBITS (panel_info.vl_bpix)) / 8; + lcd_get_size(&lcd_line_length); lcd_init(lcd_base); /* LCD initialization */ @@ -445,15 +455,16 @@ static int lcd_init(void *lcdbase) ulong lcd_setmem(ulong addr) { ulong size; - int line_length = (panel_info.vl_col * NBITS(panel_info.vl_bpix)) / 8; + int line_length; debug("LCD panel info: %d x %d, %d bit/pix\n", panel_info.vl_col, panel_info.vl_row, NBITS(panel_info.vl_bpix)); - size = line_length * panel_info.vl_row; + size = lcd_get_size(&line_length); - /* Round up to nearest full page */ - size = (size + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1); + /* Round up to nearest full page, or MMU section if defined */ + size = ALIGN(size, CONFIG_LCD_ALIGNMENT); + addr = ALIGN(addr - CONFIG_LCD_ALIGNMENT + 1, CONFIG_LCD_ALIGNMENT); /* Allocate pages for the frame buffer. */ addr -= size; -- cgit v1.2.3 From 9a8efc4604b32221ea362ea41b38d714e4b4ab7a Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 30 Oct 2012 13:40:18 +0000 Subject: lcd: Add support for flushing LCD fb from dcache after update This provides an option for the LCD to flush the dcache after each update (puts, scroll or clear). Signed-off-by: Simon Glass Signed-off-by: Tom Warren --- common/lcd.c | 46 +++++++++++++++++++++++++++++++++++++++------- 1 file changed, 39 insertions(+), 7 deletions(-) (limited to 'common/lcd.c') diff --git a/common/lcd.c b/common/lcd.c index 37b03936f90..d2a3e910314 100644 --- a/common/lcd.c +++ b/common/lcd.c @@ -94,6 +94,9 @@ static void lcd_setbgcolor(int color); char lcd_is_enabled = 0; +static char lcd_flush_dcache; /* 1 to flush dcache after each lcd update */ + + #ifdef NOT_USED_SO_FAR static void lcd_getcolreg(ushort regno, ushort *red, ushort *green, ushort *blue); @@ -102,6 +105,28 @@ static int lcd_getfgcolor(void); /************************************************************************/ +/* Flush LCD activity to the caches */ +void lcd_sync(void) +{ + /* + * flush_dcache_range() is declared in common.h but it seems that some + * architectures do not actually implement it. Is there a way to find + * out whether it exists? For now, ARM is safe. + */ +#if defined(CONFIG_ARM) && !defined(CONFIG_SYS_DCACHE_OFF) + int line_length; + + if (lcd_flush_dcache) + flush_dcache_range((u32)lcd_base, + (u32)(lcd_base + lcd_get_size(&line_length))); +#endif +} + +void lcd_set_flush_dcache(int flush) +{ + lcd_flush_dcache = (flush != 0); +} + /*----------------------------------------------------------------------*/ static void console_scrollup(void) @@ -111,6 +136,7 @@ static void console_scrollup(void) /* Clear the last one */ memset(CONSOLE_ROW_LAST, COLOR_MASK(lcd_color_bg), CONSOLE_ROW_SIZE); + lcd_sync(); } /*----------------------------------------------------------------------*/ @@ -140,6 +166,8 @@ static inline void console_newline(void) /* Scroll everything up */ console_scrollup(); --console_row; + } else { + lcd_sync(); } } @@ -195,6 +223,7 @@ void lcd_puts(const char *s) while (*s) { lcd_putc(*s++); } + lcd_sync(); } /*----------------------------------------------------------------------*/ @@ -362,13 +391,6 @@ int drv_lcd_init (void) } /*----------------------------------------------------------------------*/ -static -int do_lcd_clear(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) -{ - lcd_clear(); - return 0; -} - void lcd_clear(void) { #if LCD_BPP == LCD_MONOCHROME @@ -410,6 +432,14 @@ void lcd_clear(void) console_col = 0; console_row = 0; + lcd_sync(); +} + +static int do_lcd_clear(cmd_tbl_t *cmdtp, int flag, int argc, + char *const argv[]) +{ + lcd_clear(); + return 0; } U_BOOT_CMD( @@ -621,6 +651,7 @@ void bitmap_plot(int x, int y) } WATCHDOG_RESET(); + lcd_sync(); } #else static inline void bitmap_plot(int x, int y) {} @@ -842,6 +873,7 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y) break; }; + lcd_sync(); return 0; } #endif -- cgit v1.2.3 From 0d89efef773318b241df7cb1295ac72742e6f848 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 17 Oct 2012 13:24:59 +0000 Subject: lcd: Add CONFIG_CONSOLE_SCROLL_LINES option to speed console When the cursor position gets to the end of the LCD console we normally scroll by one line. This adds an option to increase that value. Console scrolling is often slow, and if a large amount of output is being sent, increasing this option to 10 or so will speed things up considerably. Signed-off-by: Simon Glass Signed-off-by: Tom Warren --- common/lcd.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) (limited to 'common/lcd.c') diff --git a/common/lcd.c b/common/lcd.c index d2a3e910314..3017604734b 100644 --- a/common/lcd.c +++ b/common/lcd.c @@ -76,6 +76,11 @@ #define CONFIG_LCD_ALIGNMENT PAGE_SIZE #endif +/* By default we scroll by a single line */ +#ifndef CONFIG_CONSOLE_SCROLL_LINES +#define CONFIG_CONSOLE_SCROLL_LINES 1 +#endif + DECLARE_GLOBAL_DATA_PTR; ulong lcd_setmem (ulong addr); @@ -131,12 +136,20 @@ void lcd_set_flush_dcache(int flush) static void console_scrollup(void) { - /* Copy up rows ignoring the first one */ - memcpy(CONSOLE_ROW_FIRST, CONSOLE_ROW_SECOND, CONSOLE_SCROLL_SIZE); + const int rows = CONFIG_CONSOLE_SCROLL_LINES; + + /* Copy up rows ignoring those that will be overwritten */ + memcpy(CONSOLE_ROW_FIRST, + lcd_console_address + CONSOLE_ROW_SIZE * rows, + CONSOLE_SIZE - CONSOLE_ROW_SIZE * rows); + + /* Clear the last rows */ + memset(lcd_console_address + CONSOLE_SIZE - CONSOLE_ROW_SIZE * rows, + COLOR_MASK(lcd_color_bg), + CONSOLE_ROW_SIZE * rows); - /* Clear the last one */ - memset(CONSOLE_ROW_LAST, COLOR_MASK(lcd_color_bg), CONSOLE_ROW_SIZE); lcd_sync(); + console_row -= rows; } /*----------------------------------------------------------------------*/ @@ -165,7 +178,6 @@ static inline void console_newline(void) if (console_row >= CONSOLE_ROWS) { /* Scroll everything up */ console_scrollup(); - --console_row; } else { lcd_sync(); } -- cgit v1.2.3