]> git.kernelconcepts.de Git - karo-tx-uboot.git/commitdiff
fdt: karo: add support for LVDS selection via 'video_mode'
authorLothar Waßmann <LW@KARO-electronics.de>
Mon, 28 Oct 2013 14:57:28 +0000 (15:57 +0100)
committerLothar Waßmann <LW@KARO-electronics.de>
Mon, 28 Oct 2013 14:57:28 +0000 (15:57 +0100)
board/karo/common/fdt.c
board/karo/common/karo.h
board/karo/tx53/tx53.c
board/karo/tx6/tx6qdl.c

index 9c154eadb98f17504d9ec20d6effd8e4d58e75a8..1ab15fe2027915be6dc3811556bdfd251fb6f990 100644 (file)
@@ -70,7 +70,11 @@ void karo_fdt_move_fdt(void)
        if (fdt == NULL) {
                fdt = (void *)gd->fdt_blob;
                if (fdt == NULL) {
+#ifdef CONFIG_OF_EMBED
                        printf("Compiled in FDT not found\n");
+#else
+                       printf("No FDT found\n");
+#endif
                        return;
                }
                debug("Checking FDT header @ %p\n", fdt);
@@ -596,6 +600,75 @@ out:
        return ret;
 }
 
+char *karo_fdt_set_display(char *video_mode, const char *lcd_path,
+                       const char *lvds_path)
+{
+       char *vm;
+       int ret;
+       int off;
+       void *blob = (void *)gd->fdt_blob;
+
+       if (video_mode == NULL)
+               return NULL;
+
+       off = fdt_path_offset(blob, "/aliases");
+       ret = fdt_resize(blob);
+       if (ret < 0) {
+               printf("%s: Failed to resize FDT: %s\n",
+                       __func__, fdt_strerror(ret));
+       }
+       vm = strsep(&video_mode, ":");
+       if (off < 0) {
+               off = fdt_add_subnode(blob, off, "aliases");
+               if (off < 0) {
+                       printf("%s: Failed to create 'aliases' node: %s\n",
+                               __func__, fdt_strerror(off));
+                       return video_mode ?: vm;
+               }
+       }
+       if (video_mode != NULL) {
+               char display[strlen(lvds_path) + sizeof("/lvds-channel@x")];
+
+               strncpy(display, lvds_path, sizeof(display));
+               if (strcmp(vm, "LVDS") == 0 ||
+                       strcmp(vm, "LVDS0") == 0) {
+                       strncat(display, "/lvds-channel@0", sizeof(display));
+               } else if (strcmp(vm, "LVDS1") == 0) {
+                       strncat(display, "/lvds-channel@1", sizeof(display));
+               } else {
+                       printf("%s: Syntax error in video_mode\n",
+                               __func__);
+                       return video_mode;
+               }
+               ret = fdt_setprop_string(blob, off, "display", display);
+               debug("setprop_string(display='%s') returned %d\n", display, ret);
+       } else {
+               char display[strlen(lcd_path) + sizeof("/display@di0")];
+
+               snprintf(display, sizeof(display), "%s/display@di0", lcd_path);
+
+               ret = fdt_setprop_string(blob, off, "display",
+                                       display);
+
+               off = fdt_path_offset(blob, "lvds0");
+               if (off >= 0) {
+                       ret = fdt_set_node_status(blob, off,
+                                               FDT_STATUS_DISABLED, 0);
+               }
+               off = fdt_path_offset(blob, "lvds1");
+               if (off >= 0) {
+                       ret = fdt_set_node_status(blob, off,
+                                               FDT_STATUS_DISABLED, 0);
+               }
+               video_mode = vm;
+       }
+       if (ret) {
+               printf("%s: failed to set 'display' alias: %s\n",
+                       __func__, fdt_strerror(ret));
+       }
+       return video_mode;
+}
+
 int karo_fdt_update_fb_mode(void *blob, const char *name)
 {
        int off = fdt_path_offset(blob, "display");
index ba4ef467edcee8e416a7d53d4392415c40044aab..53a5ee9439acfac2f15c23125d1b455a2b3513e2 100644 (file)
@@ -31,6 +31,8 @@ int karo_fdt_get_fb_mode(void *blob, const char *name,
 int karo_fdt_update_fb_mode(void *blob, const char *name);
 int karo_fdt_create_fb_mode(void *blob, const char *name,
                        struct fb_videomode *mode);
+char *karo_fdt_set_display(char *video_mode, const char *lcd_path,
+                       const char *lvds_path);
 #else
 static inline void karo_fdt_remove_node(void *blob, const char *node)
 {
@@ -75,6 +77,11 @@ static inline int karo_fdt_create_fb_mode(void *blob,
 {
        return 0;
 }
+static inline char *karo_fdt_set_display(char *video_mode, const char *lcd_path,
+                                       const char *lvds_path)
+{
+       return video_mode;
+}
 #endif
 
 int karo_load_splashimage(int mode);
index 6ab338ffc9a473a07a4f2ec487bb67139222a3fe..4ed1764126f1c0f501aace01a23660c87f32adae 100644 (file)
@@ -712,6 +712,7 @@ static const struct gpio stk5_lcd_gpios[] = {
 void lcd_ctrl_init(void *lcdbase)
 {
        int color_depth = 24;
+       char *video_mode = getenv("video_mode");
        char *vm;
        unsigned long val;
        int refresh = 60;
@@ -736,12 +737,13 @@ void lcd_ctrl_init(void *lcdbase)
 
        karo_fdt_move_fdt();
 
-       vm = getenv("video_mode");
+       vm = karo_fdt_set_display(video_mode, "/soc", "/soc/aips/ldb");
        if (vm == NULL) {
                debug("Disabling LCD\n");
                lcd_enabled = 0;
                return;
        }
+       video_mode = vm;
        if (karo_fdt_get_fb_mode(working_fdt, vm, &fb_mode) == 0) {
                p = &fb_mode;
                debug("Using video mode from FDT\n");
@@ -888,14 +890,13 @@ void lcd_ctrl_init(void *lcdbase)
 
        if (p != &fb_mode) {
                int ret;
-               char *modename = getenv("video_mode");
 
                printf("Creating new display-timing node from '%s'\n",
-                       modename);
-               ret = karo_fdt_create_fb_mode(working_fdt, modename, p);
+                       video_mode);
+               ret = karo_fdt_create_fb_mode(working_fdt, video_mode, p);
                if (ret)
                        printf("Failed to create new display-timing node from '%s': %d\n",
-                               modename, ret);
+                               video_mode, ret);
        }
 
        gpio_request_array(stk5_lcd_gpios, ARRAY_SIZE(stk5_lcd_gpios));
@@ -1064,6 +1065,7 @@ void ft_board_setup(void *blob, bd_t *bd)
 {
        const char *baseboard = getenv("baseboard");
        int stk5_v5 = baseboard != NULL && (strcmp(baseboard, "stk5-v5") == 0);
+       char *video_mode = getenv("video_mode");
 
        fdt_fixup_mtdparts(blob, nodes, ARRAY_SIZE(nodes));
        fdt_fixup_ethernet(blob);
@@ -1072,6 +1074,7 @@ void ft_board_setup(void *blob, bd_t *bd)
        karo_fdt_fixup_usb_otg(blob, "fsl,imx-otg", "fsl,usbphy");
        karo_fdt_fixup_flexcan(blob, stk5_v5);
        tx53_fixup_rtc(blob);
-       karo_fdt_update_fb_mode(blob, getenv("video_mode"));
+       video_mode = karo_fdt_set_display(video_mode, "/soc", "/soc/aips/ldb");
+       karo_fdt_update_fb_mode(blob, video_mode);
 }
 #endif /* CONFIG_OF_BOARD_SETUP */
index 239032a697d9f0d4e6fae354fe94084cd5f361a0..59e0e023b4ce1d5318fa2a4a6dd739f5534cf09c 100644 (file)
@@ -812,6 +812,7 @@ static const struct gpio stk5_lcd_gpios[] = {
 void lcd_ctrl_init(void *lcdbase)
 {
        int color_depth = 24;
+       char *video_mode = getenv("video_mode");
        char *vm;
        unsigned long val;
        int refresh = 60;
@@ -830,17 +831,19 @@ void lcd_ctrl_init(void *lcdbase)
        if (tstc() || (wrsr & WRSR_TOUT)) {
                debug("Disabling LCD\n");
                lcd_enabled = 0;
+               setenv("splashimage", NULL);
                return;
        }
 
        karo_fdt_move_fdt();
 
-       vm = getenv("video_mode");
+       vm = karo_fdt_set_display(video_mode, "", "/soc/aips-bus/ldb");
        if (vm == NULL) {
                debug("Disabling LCD\n");
                lcd_enabled = 0;
                return;
        }
+       video_mode = vm;
        if (karo_fdt_get_fb_mode(working_fdt, vm, &fb_mode) == 0) {
                p = &fb_mode;
                debug("Using video mode from FDT\n");
@@ -987,14 +990,13 @@ void lcd_ctrl_init(void *lcdbase)
 
        if (p != &fb_mode) {
                int ret;
-               char *modename = getenv("video_mode");
 
                printf("Creating new display-timing node from '%s'\n",
-                       modename);
-               ret = karo_fdt_create_fb_mode(working_fdt, modename, p);
+                       video_mode);
+               ret = karo_fdt_create_fb_mode(working_fdt, video_mode, p);
                if (ret)
                        printf("Failed to create new display-timing node from '%s': %d\n",
-                               modename, ret);
+                               video_mode, ret);
        }
 
        gpio_request_array(stk5_lcd_gpios, ARRAY_SIZE(stk5_lcd_gpios));
@@ -1167,6 +1169,7 @@ void ft_board_setup(void *blob, bd_t *bd)
 {
        const char *baseboard = getenv("baseboard");
        int stk5_v5 = baseboard != NULL && (strcmp(baseboard, "stk5-v5") == 0);
+       char *video_mode = getenv("video_mode");
 
        karo_fdt_enable_node(blob, "stk5led", !stk5_v5);
 
@@ -1176,6 +1179,8 @@ void ft_board_setup(void *blob, bd_t *bd)
        karo_fdt_fixup_touchpanel(blob);
        karo_fdt_fixup_usb_otg(blob, "usbotg", "fsl,usbphy");
        karo_fdt_fixup_flexcan(blob, stk5_v5);
-       karo_fdt_update_fb_mode(blob, getenv("video_mode"));
+
+       video_mode = karo_fdt_set_display(video_mode, "", "/soc/aips-bus/ldb");
+       karo_fdt_update_fb_mode(blob, video_mode);
 }
 #endif /* CONFIG_OF_BOARD_SETUP */