From 676d319ef5f450ca7845555f75de496b96cd688e Mon Sep 17 00:00:00 2001
From: Simon Glass <sjg@chromium.org>
Date: Wed, 17 Oct 2012 13:24:54 +0000
Subject: [PATCH] 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 <sjg@chromium.org>
Signed-off-by: Tom Warren <twarren@nvidia.com>
---
 README        | 10 ++++++++++
 common/lcd.c  | 21 ++++++++++++++++-----
 include/lcd.h |  3 +++
 3 files changed, 29 insertions(+), 5 deletions(-)

diff --git a/README b/README
index afdf591c62..5c03be7918 100644
--- a/README
+++ b/README
@@ -1469,6 +1469,16 @@ CBFS (Coreboot Filesystem) support
 		Normally display is black on white background; define
 		CONFIG_SYS_WHITE_ON_BLACK to get it inverted.
 
+
+		CONFIG_LCD_ALIGNMENT
+
+		Normally the LCD is page-aligned (tyically 4KB). If this is
+		defined then the LCD will be aligned to this value instead.
+		For ARM it is sometimes useful to use MMU_SECTION_SIZE
+		here, since it is cheaper to change data cache settings on
+		a per-section basis.
+
+
 - Splash Screen Support: CONFIG_SPLASH_SCREEN
 
 		If this option is set, the environment is checked for
diff --git a/common/lcd.c b/common/lcd.c
index b6be8002d2..37b03936f9 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;
diff --git a/include/lcd.h b/include/lcd.h
index 42070d7636..6a600eece4 100644
--- a/include/lcd.h
+++ b/include/lcd.h
@@ -297,6 +297,9 @@ int	lcd_display_bitmap(ulong bmp_image, int x, int y);
 /* Allow boards to customize the information displayed */
 void lcd_show_board_info(void);
 
+/* Return the size of the LCD frame buffer, and the line length */
+int lcd_get_size(int *line_length);
+
 /************************************************************************/
 /* ** BITMAP DISPLAY SUPPORT						*/
 /************************************************************************/
-- 
2.39.5