diff mbox

[U-Boot,v2,08/11] video: cfb_console: flush dcache for frame buffer in DRAM

Message ID 1335634011-9104-9-git-send-email-pali.rohar@gmail.com
State Superseded
Delegated to: Anatolij Gustschin
Headers show

Commit Message

Pali Rohár April 28, 2012, 5:26 p.m. UTC
From: Anatolij Gustschin <agust@denx.de>

Data cache flushing is required for frame buffer in RAM to fix the
distorted console text output. Currently this text distortion is
observed with cfb on beageboard and N900 when running with data
cache enabled.

Reported-by: Pali Rohár <pali.rohar@gmail.com>
Tested-by: Pali Rohár <pali.rohar@gmail.com>
Signed-off-by: Anatolij Gustschin <agust@denx.de>
---
Changes since original version:
   - Rebased on Nokia RX-51 patch series
   - Call flush_cache in console_clear too

 drivers/video/cfb_console.c |   37 +++++++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)
diff mbox

Patch

diff --git a/drivers/video/cfb_console.c b/drivers/video/cfb_console.c
index dae2178..b8416d9 100644
--- a/drivers/video/cfb_console.c
+++ b/drivers/video/cfb_console.c
@@ -360,6 +360,8 @@  void console_cursor(int state);
 extern void video_get_info_str(int line_number,	char *info);
 #endif
 
+DECLARE_GLOBAL_DATA_PTR;
+
 /* Locals */
 static GraphicDevice *pGD;	/* Pointer to Graphic array */
 
@@ -382,6 +384,8 @@  static int ansi_buf_size;
 static int ansi_colors_need_revert;
 static int ansi_cursor_hidden;
 
+static int cfb_do_flush_cache;
+
 static const int video_font_draw_table8[] = {
 	0x00000000, 0x000000ff, 0x0000ff00, 0x0000ffff,
 	0x00ff0000, 0x00ff00ff, 0x00ffff00, 0x00ffffff,
@@ -558,6 +562,8 @@  static void video_drawchars(int xx, int yy, unsigned char *s, int count)
 					SWAP32((video_font_draw_table32
 						[bits & 15][3] & eorx) ^ bgx);
 			}
+			if (cfb_do_flush_cache)
+				flush_cache((ulong)dest0, 32);
 			dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE;
 			s++;
 		}
@@ -634,6 +640,8 @@  static void video_invertchar(int xx, int yy)
 		for (x = firstx; x < lastx; x++) {
 			u8 *dest = (u8 *)(video_fb_address) + x + y;
 			*dest = ~*dest;
+			if (cfb_do_flush_cache)
+				flush_cache((ulong)dest, 4);
 		}
 	}
 }
@@ -709,6 +717,8 @@  static void console_clear(void)
 #else
 	memsetl(CONSOLE_ROW_FIRST, CONSOLE_SIZE, bgx);
 #endif
+	if (cfb_do_flush_cache)
+		flush_cache((ulong)CONSOLE_ROW_FIRST, CONSOLE_SIZE);
 }
 
 static void console_clear_line(int line, int begin, int end)
@@ -745,6 +755,8 @@  static void console_clear_line(int line, int begin, int end)
 				bgx			/* fill color */
 				);
 #endif
+	if (cfb_do_flush_cache)
+		flush_cache((ulong)CONSOLE_ROW_FIRST, CONSOLE_SIZE);
 }
 
 static void console_scrollup(void)
@@ -1972,6 +1984,29 @@  static void *video_logo(void)
 }
 #endif
 
+static int cfb_fb_is_in_dram(void)
+{
+	bd_t *bd = gd->bd;
+	ulong start, end;
+	int i;
+
+	for (i = 0; i < CONFIG_NR_DRAM_BANKS; ++i) {
+#if defined(CONFIG_ARM) || defined(CONFIG_AVR32) || defined(COFNIG_NDS32) || \
+defined(CONFIG_SANDBOX) || defined(CONFIG_X86)
+		start = bd->bi_dram[i].start;
+		end = bd->bi_dram[i].start + bd->bi_dram[i].size - 1;
+#else
+		start = bd->bi_memstart;
+		end = bd->bi_memsize;
+#endif
+
+		if ((ulong)video_fb_address >= start &&
+		    (ulong)video_fb_address < end)
+			return 1;
+	}
+	return 0;
+}
+
 static int video_init(void)
 {
 	unsigned char color8;
@@ -1985,6 +2020,8 @@  static int video_init(void)
 	video_init_hw_cursor(VIDEO_FONT_WIDTH, VIDEO_FONT_HEIGHT);
 #endif
 
+	cfb_do_flush_cache = cfb_fb_is_in_dram() && dcache_status();
+
 	/* Init drawing pats */
 	switch (VIDEO_DATA_FORMAT) {
 	case GDF__8BIT_INDEX: