]> git.kernelconcepts.de Git - karo-tx-uboot.git/blobdiff - common/lcd.c
Merge branch 'master' of git://git.denx.de/u-boot-i2c
[karo-tx-uboot.git] / common / lcd.c
index b98eea669692a977c5a7684e81b56e5328d8111b..8d5c63c29ef924166576d9d3793379429acfe0e4 100644 (file)
@@ -4,23 +4,7 @@
  * (C) Copyright 2001-2002
  * Wolfgang Denk, DENX Software Engineering -- wd@denx.de
  *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * 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
+ * SPDX-License-Identifier:    GPL-2.0+ 
  */
 
 /************************************************************************/
@@ -43,6 +27,8 @@
 #include <lcd.h>
 #include <watchdog.h>
 
+#include <splash.h>
+
 #if defined(CONFIG_CPU_PXA25X) || defined(CONFIG_CPU_PXA27X) || \
        defined(CONFIG_CPU_MONAHANS)
 #define CONFIG_CPU_PXA
 #include <atmel_lcdc.h>
 #endif
 
+#if defined(CONFIG_LCD_DT_SIMPLEFB)
+#include <libfdt.h>
+#endif
+
 /************************************************************************/
 /* ** FONT DATA                                                                */
 /************************************************************************/
@@ -493,6 +483,18 @@ static int lcd_init(void *lcdbase)
        debug("[LCD] Initializing LCD frambuffer at %p\n", lcdbase);
 
        lcd_ctrl_init(lcdbase);
+
+       /*
+        * lcd_ctrl_init() of some drivers (i.e. bcm2835 on rpi_b) ignores
+        * the 'lcdbase' argument and uses custom lcd base address
+        * by setting up gd->fb_base. Check for this condition and fixup
+        * 'lcd_base' address.
+        */
+       if ((unsigned long)lcdbase != gd->fb_base)
+               lcd_base = (void *)gd->fb_base;
+
+       debug("[LCD] Using LCD frambuffer at %p\n", lcd_base);
+
        lcd_get_size(&lcd_line_length);
        lcd_line_length = (panel_info.vl_col * NBITS(panel_info.vl_bpix)) / 8;
        lcd_is_enabled = 1;
@@ -1056,18 +1058,6 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y)
 }
 #endif
 
-#ifdef CONFIG_SPLASH_SCREEN_PREPARE
-static inline int splash_screen_prepare(void)
-{
-       return board_splash_screen_prepare();
-}
-#else
-static inline int splash_screen_prepare(void)
-{
-       return 0;
-}
-#endif
-
 static void *lcd_logo(void)
 {
 #ifdef CONFIG_SPLASH_SCREEN
@@ -1080,26 +1070,11 @@ static void *lcd_logo(void)
                do_splash = 0;
 
                if (splash_screen_prepare())
-                       return (void *)gd->fb_base;
+                       return (void *)lcd_base;
 
                addr = simple_strtoul (s, NULL, 16);
-#ifdef CONFIG_SPLASH_SCREEN_ALIGN
-               s = getenv("splashpos");
-               if (s != NULL) {
-                       if (s[0] == 'm')
-                               x = BMP_ALIGN_CENTER;
-                       else
-                               x = simple_strtol(s, NULL, 0);
-
-                       s = strchr(s + 1, ',');
-                       if (s != NULL) {
-                               if (s[1] == 'm')
-                                       y = BMP_ALIGN_CENTER;
-                               else
-                                       y = simple_strtol (s + 1, NULL, 0);
-                       }
-               }
-#endif /* CONFIG_SPLASH_SCREEN_ALIGN */
+
+               splash_get_pos(&x, &y);
 
                if (bmp_display(addr, x, y) == 0)
                        return (void *)lcd_base;
@@ -1170,3 +1145,86 @@ int lcd_get_screen_columns(void)
 {
        return CONSOLE_COLS;
 }
+
+#if defined(CONFIG_LCD_DT_SIMPLEFB)
+static int lcd_dt_simplefb_configure_node(void *blob, int off)
+{
+       u32 stride;
+       fdt32_t cells[2];
+       int ret;
+       static const char format[] =
+#if LCD_BPP == LCD_COLOR16
+               "r5g6b5";
+#else
+               "";
+#endif
+
+       if (!format[0])
+               return -1;
+
+       stride = panel_info.vl_col * 2;
+
+       cells[0] = cpu_to_fdt32(gd->fb_base);
+       cells[1] = cpu_to_fdt32(stride * panel_info.vl_row);
+       ret = fdt_setprop(blob, off, "reg", cells, sizeof(cells[0]) * 2);
+       if (ret < 0)
+               return -1;
+
+       cells[0] = cpu_to_fdt32(panel_info.vl_col);
+       ret = fdt_setprop(blob, off, "width", cells, sizeof(cells[0]));
+       if (ret < 0)
+               return -1;
+
+       cells[0] = cpu_to_fdt32(panel_info.vl_row);
+       ret = fdt_setprop(blob, off, "height", cells, sizeof(cells[0]));
+       if (ret < 0)
+               return -1;
+
+       cells[0] = cpu_to_fdt32(stride);
+       ret = fdt_setprop(blob, off, "stride", cells, sizeof(cells[0]));
+       if (ret < 0)
+               return -1;
+
+       ret = fdt_setprop(blob, off, "format", format, strlen(format) + 1);
+       if (ret < 0)
+               return -1;
+
+       ret = fdt_delprop(blob, off, "status");
+       if (ret < 0)
+               return -1;
+
+       return 0;
+}
+
+int lcd_dt_simplefb_add_node(void *blob)
+{
+       static const char compat[] = "simple-framebuffer";
+       static const char disabled[] = "disabled";
+       int off, ret;
+
+       off = fdt_add_subnode(blob, 0, "framebuffer");
+       if (off < 0)
+               return -1;
+
+       ret = fdt_setprop(blob, off, "status", disabled, sizeof(disabled));
+       if (ret < 0)
+               return -1;
+
+       ret = fdt_setprop(blob, off, "compatible", compat, sizeof(compat));
+       if (ret < 0)
+               return -1;
+
+       return lcd_dt_simplefb_configure_node(blob, off);
+}
+
+int lcd_dt_simplefb_enable_existing_node(void *blob)
+{
+       int off;
+
+       off = fdt_node_offset_by_compatible(blob, -1, "simple-framebuffer");
+       if (off < 0)
+               return -1;
+
+       return lcd_dt_simplefb_configure_node(blob, off);
+}
+#endif