]> git.kernelconcepts.de Git - karo-tx-uboot.git/blobdiff - board/karo/common/fdt.c
karo: fdt: remove 'vbus-supply' from usbotg node when otg_mode=peripheral
[karo-tx-uboot.git] / board / karo / common / fdt.c
index 2322447986c1f3b7d873e9b6fabcfb805a660e38..387208c78e4e317e36ce96a4079121c39812337f 100644 (file)
@@ -48,50 +48,6 @@ static void karo_set_fdtsize(void *fdt)
        setenv_hex("fdtsize", fdt_totalsize(fdt));
 }
 
-static int karo_load_part(const char *part, void *addr, size_t len)
-{
-       int ret;
-       struct mtd_device *dev;
-       struct part_info *part_info;
-       u8 part_num;
-       size_t actual;
-
-       debug("Initializing mtd_parts\n");
-       ret = mtdparts_init();
-       if (ret)
-               return ret;
-
-       debug("Trying to find NAND partition '%s'\n", part);
-       ret = find_dev_and_part(part, &dev, &part_num, &part_info);
-       if (ret) {
-               printf("Failed to find flash partition '%s': %d\n",
-                       part, ret);
-
-               return ret;
-       }
-       debug("Found partition '%s': offset=%08x size=%08x\n",
-               part, part_info->offset, part_info->size);
-       if (part_info->size < len) {
-               printf("Warning: partition '%s' smaller than requested size: %u; truncating data to %u byte\n",
-                       part, len, part_info->size);
-               len = part_info->size;
-       }
-       debug("Reading NAND partition '%s' to %p\n", part, addr);
-       ret = nand_read_skip_bad(&nand_info[0], part_info->offset, &len,
-                               &actual, len, addr);
-       if (ret) {
-               printf("Failed to load partition '%s' to %p\n", part, addr);
-               return ret;
-       }
-       if (actual < len)
-               printf("Read only %u of %u bytes due to bad blocks\n",
-                       actual, len);
-
-       debug("Read %u byte from partition '%s' @ offset %08x\n",
-               len, part, part_info->offset);
-       return 0;
-}
-
 static void *karo_fdt_load_dtb(void)
 {
        int ret;
@@ -207,13 +163,11 @@ static void fdt_disable_tp_node(void *blob, const char *name)
 {
        int offs = fdt_node_offset_by_compatible(blob, -1, name);
 
-       if (offs < 0) {
-               debug("node '%s' not found: %s\n", name, fdt_strerror(offs));
-               return;
+       while (offs >= 0) {
+               debug("Disabling node '%s'\n", name);
+               fdt_set_node_status(blob, offs, FDT_STATUS_DISABLED, 0);
+               offs = fdt_node_offset_by_compatible(blob, offs, name);
        }
-
-       debug("Disabling node '%s'\n", name);
-       fdt_set_node_status(blob, offs, FDT_STATUS_DISABLED, 0);
 }
 
 void karo_fdt_fixup_touchpanel(void *blob, const char *panels[],
@@ -241,12 +195,39 @@ void karo_fdt_fixup_touchpanel(void *blob, const char *panels[],
        karo_set_fdtsize(blob);
 }
 
+static int karo_fdt_disable_node_phandle(void *blob, const char *parent,
+                                       const char *name)
+{
+       const uint32_t *ph;
+       int off;
+
+       off = fdt_path_offset(blob, parent);
+       if (off < 0) {
+               printf("Failed to find node '%s'\n", parent);
+               return off;
+       }
+
+       ph = fdt_getprop(blob, off, name, NULL);
+       if (ph == NULL) {
+               debug("Failed to find '%s' phandle in node '%s'\n", name,
+                       fdt_get_name(blob, off, NULL));
+               return -FDT_ERR_NOTFOUND;
+       }
+
+       off = fdt_node_offset_by_phandle(blob, fdt32_to_cpu(*ph));
+       if (off <= 0) {
+               printf("Failed to find '%s' node via phandle %04x\n",
+                       name, fdt32_to_cpu(*ph));
+               return -FDT_ERR_NOTFOUND;
+       }
+       return fdt_set_node_status(blob, off, FDT_STATUS_DISABLED, 0);
+}
+
 void karo_fdt_fixup_usb_otg(void *blob, const char *node, const char *phy)
 {
        const char *otg_mode = getenv("otg_mode");
        int off;
        int ret;
-       const uint32_t *ph;
        int disable_otg = 0;
        int disable_phy_pins = 1;
 
@@ -269,6 +250,7 @@ void karo_fdt_fixup_usb_otg(void *blob, const char *node, const char *phy)
        } else if (otg_mode && strcmp(otg_mode, "otg") == 0) {
                debug("Setting dr_mode to 'host'\n");
                ret = fdt_setprop_string(blob, off, "dr_mode", "otg");
+               disable_phy_pins = 0;
        } else {
                if (otg_mode && strcmp(otg_mode, "none") != 0)
                        printf("Invalid 'otg_mode' setting '%s'; disabling usbotg port\n",
@@ -280,30 +262,22 @@ void karo_fdt_fixup_usb_otg(void *blob, const char *node, const char *phy)
        if ((!disable_phy_pins && !disable_otg) || ret)
                goto out;
 
+       ret = karo_fdt_disable_node_phandle(blob, node, "vbus-supply");
+       if (ret)
+               goto out;
+
        if (disable_otg) {
+               debug("Disabling usbphy\n");
                ret = fdt_set_node_status(blob, off, FDT_STATUS_DISABLED, 0);
                if (ret)
                        goto out;
-       }
 
-       ph = fdt_getprop(blob, off, phy, NULL);
-       if (ph == NULL) {
-               printf("Failed to find '%s' phandle in node '%s'\n", phy,
-                       fdt_get_name(blob, off, NULL));
-               goto out;
-       }
-
-       off = fdt_node_offset_by_phandle(blob, fdt32_to_cpu(*ph));
-       if (off <= 0) {
-               printf("Failed to find '%s' node via phandle %04x\n",
-                       phy, fdt32_to_cpu(*ph));
-               goto out;
+               ret = karo_fdt_disable_node_phandle(blob, node, phy);
+       } else if (disable_phy_pins) {
+               debug("Removing 'vbus-supply' from usbotg node\n");
+               fdt_delprop(blob, off, "vbus-supply");
        }
 
-       if (disable_otg) {
-               debug("Disabling usbphy\n");
-               ret = fdt_set_node_status(blob, off, FDT_STATUS_DISABLED, 0);
-       }
 out:
        if (ret)
                printf("Failed to update usbotg: %s\n", fdt_strerror(ret));
@@ -366,27 +340,44 @@ static inline void karo_fdt_set_lcd_pins(void *blob, const char *name)
 
 void karo_fdt_fixup_flexcan(void *blob, int xcvr_present)
 {
+       int ret;
        const char *xcvr_status = "disabled";
+       const char *otg_mode = getenv("otg_mode");
 
-#ifndef CONFIG_SYS_LVDS_IF
        if (xcvr_present) {
                if (karo_fdt_flexcan_enabled(blob)) {
-                       karo_fdt_set_lcd_pins(blob, "lcdif_23bit_pins_a");
-                       xcvr_status = "okay";
-               } else {
+                       if (!is_lvds()) {
+                               debug("Changing LCD to use 23bits only\n");
+                               karo_fdt_set_lcd_pins(blob, "lcdif_23bit_pins_a");
+                               xcvr_status = NULL;
+                       }
+               } else if (!is_lvds()) {
+                       debug("Changing LCD to use 24bits\n");
                        karo_fdt_set_lcd_pins(blob, "lcdif_24bit_pins_a");
                }
        } else {
-               const char *otg_mode = getenv("otg_mode");
+               int off = fdt_path_offset(blob, "can0");
+
+               if (off >= 0)
+                       fdt_delprop(blob, off, "xceiver-supply");
+               off = fdt_path_offset(blob, "can1");
+               if (off >= 0)
+                       fdt_delprop(blob, off, "xceiver-supply");
+               if (!is_lvds())
+                       karo_fdt_set_lcd_pins(blob, "lcdif_24bit_pins_a");
+       }
 
-               if (otg_mode && (strcmp(otg_mode, "host") == 0))
-                       karo_fdt_enable_node(blob, "can1", 0);
+       if (otg_mode && strcmp(otg_mode, "host") == 0)
+               karo_fdt_enable_node(blob, "can1", 0);
 
-               karo_fdt_set_lcd_pins(blob, "lcdif_24bit_pins_a");
+       if (xcvr_status) {
+               debug("Disabling CAN XCVR\n");
+               ret = fdt_find_and_setprop(blob, "reg_can_xcvr", "status",
+                                       xcvr_status, strlen(xcvr_status) + 1, 1);
+               if (ret)
+                       printf("Failed to disable CAN transceiver switch: %s\n",
+                               fdt_strerror(ret));
        }
-#endif
-       fdt_find_and_setprop(blob, "reg_can_xcvr", "status",
-                       xcvr_status, strlen(xcvr_status) + 1, 1);
 }
 
 void karo_fdt_del_prop(void *blob, const char *compat, phys_addr_t offs,
@@ -748,6 +739,7 @@ int karo_fdt_update_fb_mode(void *blob, const char *name)
        return off;
 }
 
+#ifdef CONFIG_SYS_LVDS_IF
 int karo_fdt_get_lcd_bus_width(const void *blob, int default_width)
 {
        int off = fdt_path_offset(blob, "display");
@@ -800,3 +792,41 @@ u8 karo_fdt_get_lvds_channels(const void *blob)
        }
        return lvds_chan_mask;
 }
+#endif
+
+int karo_fdt_get_backlight_polarity(const void *blob)
+{
+#ifdef CONFIG_SYS_LVDS_IF
+       const char *backlight_node = "/backlight0";
+#else
+       const char *backlight_node = "/backlight";
+#endif
+       int off = fdt_path_offset(blob, "backlight"); /* first try alias */
+       const struct fdt_property *prop;
+       int len;
+
+       if (off < 0) {
+               /*
+                * if no 'backlight' alias exists try finding '/backlight0'
+                * or '/backlight' depending on LVDS or not
+                */
+               off = fdt_path_offset(blob, backlight_node);
+               if (off < 0) {
+                       printf("/backlight node not found in DT\n");
+                       return off;
+               }
+       }
+
+       prop = fdt_get_property(blob, off, "pwms", &len);
+       if (!prop)
+               printf("'pwms' property not found\n");
+       else
+               debug("'pwms' property has len %d\n", len);
+
+       len /= sizeof(u32);
+       if (prop && len > 3) {
+               const u32 *data = (const u32 *)prop->data;
+               return fdt32_to_cpu(data[3]) == 0;
+       }
+       return 0;
+}