]> git.kernelconcepts.de Git - karo-tx-uboot.git/blobdiff - common/lcd.c
Add a 'fake' go command to the bootm command
[karo-tx-uboot.git] / common / lcd.c
index 195f1de617c07a508f579c70b5df57e53e013562..3a60484eea615a4f20bd78109f738de26478c88f 100644 (file)
 #include <atmel_lcdc.h>
 #endif
 
+#if defined(CONFIG_LCD_DT_SIMPLEFB)
+#include <libfdt.h>
+#endif
+
 /************************************************************************/
 /* ** FONT DATA                                                                */
 /************************************************************************/
@@ -411,8 +415,6 @@ int drv_lcd_init(void)
 
        lcd_base = (void *) gd->fb_base;
 
-       lcd_get_size(&lcd_line_length);
-
        lcd_init(lcd_base);             /* LCD initialization */
 
        /* Device initialization */
@@ -495,6 +497,20 @@ 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;
        lcd_clear();
        lcd_enable();
@@ -1170,3 +1186,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;
+       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)
+{
+       const char compat[] = "simple-framebuffer";
+       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