]> git.kernelconcepts.de Git - karo-tx-uboot.git/blobdiff - board/karo/common/fdt.c
karo: tx6: don't write u-boot image with WITH_DROP_FFS
[karo-tx-uboot.git] / board / karo / common / fdt.c
index 1b87a6ffcba5f54f94c5bb1ab077d450a7eca6cb..d43a1170fc27a27748b55eadb131dcc7ec8df03d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * (C) Copyright 2012,2013 Lothar Waßmann <LW@KARO-electronics.de>
+ * (C) Copyright 2012-2014 Lothar Waßmann <LW@KARO-electronics.de>
  *
  * See file CREDITS for list of people who contributed to this
  * project.
@@ -51,7 +51,11 @@ static void karo_set_fdtsize(void *fdt)
 static void *karo_fdt_load_dtb(void)
 {
        int ret;
-       void *fdt = (void *)getenv_ulong("fdtaddr", 16, CONFIG_SYS_FDT_ADDR);
+       void *fdt;
+
+       if (getenv("fdtaddr") == NULL)
+               setenv_hex("fdtaddr", CONFIG_SYS_FDT_ADDR);
+       fdt = (void *)getenv_ulong("fdtaddr", 16, CONFIG_SYS_FDT_ADDR);
 
        if (had_ctrlc()) {
                printf("aborting DTB load\n");
@@ -119,7 +123,7 @@ void karo_fdt_move_fdt(void)
                        fdt_addr, fdt_addr + fdt_totalsize(fdt) - 1);
                memmove((void *)fdt_addr, fdt, fdt_totalsize(fdt));
        }
-       set_working_fdt_addr((void *)fdt_addr);
+       set_working_fdt_addr(fdt_addr);
        gd->fdt_blob = fdt;
        karo_set_fdtsize(fdt);
 }
@@ -230,7 +234,7 @@ void karo_fdt_fixup_usb_otg(void *blob, const char *node, const char *phy,
        int off;
        int ret;
        int disable_otg = 0;
-       int disable_phy_pins = 1;
+       int disable_phy_pins = 0;
 
        debug("OTG mode is '%s'\n", otg_mode ? otg_mode : "<UNSET>");
 
@@ -244,14 +248,13 @@ void karo_fdt_fixup_usb_otg(void *blob, const char *node, const char *phy,
                                strcasecmp(otg_mode, "gadget") == 0)) {
                debug("Setting dr_mode to 'peripheral'\n");
                ret = fdt_setprop_string(blob, off, "dr_mode", "peripheral");
+               disable_phy_pins = 1;
        } else if (otg_mode && strcasecmp(otg_mode, "host") == 0) {
                debug("Setting dr_mode to 'host'\n");
                ret = fdt_setprop_string(blob, off, "dr_mode", "host");
-               disable_phy_pins = 0;
        } else if (otg_mode && strcasecmp(otg_mode, "otg") == 0) {
                debug("Setting dr_mode to 'otg'\n");
                ret = fdt_setprop_string(blob, off, "dr_mode", "otg");
-               disable_phy_pins = 0;
        } else {
                if (otg_mode && strcasecmp(otg_mode, "none") != 0)
                        printf("Invalid 'otg_mode' setting '%s'; disabling usbotg port\n",
@@ -264,23 +267,56 @@ void karo_fdt_fixup_usb_otg(void *blob, const char *node, const char *phy,
                goto out;
 
        ret = karo_fdt_disable_node_phandle(blob, node, phy_supply);
-       if (ret)
+       if (ret && ret == -FDT_ERR_NOTFOUND) {
+               const uint32_t *ph;
+
+               ph = fdt_getprop(blob, off, phy, NULL);
+               if (ph == NULL) {
+                       printf("Failed to find '%s' phandle in node '%s'\n",
+                               phy, node);
+                       ret = -FDT_ERR_NOTFOUND;
+                       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));
+                       ret = off;
+                       goto out;
+               }
+               ph = fdt_getprop(blob, off, phy_supply, NULL);
+               if (ph == NULL) {
+                       debug("Failed to find '%s' phandle in node '%s'\n",
+                               phy_supply, fdt_get_name(blob, off, NULL));
+                       ret = -FDT_ERR_NOTFOUND;
+                       goto disable_otg;
+               }
+               ret = fdt_node_offset_by_phandle(blob, fdt32_to_cpu(*ph));
+               if (ret > 0) {
+                       debug("Disabling node %s via phandle %s:%s\n",
+                               fdt_get_name(blob, ret, NULL),
+                               fdt_get_name(blob, off, NULL), phy_supply);
+                       ret = fdt_set_node_status(blob, ret,
+                                               FDT_STATUS_DISABLED, 0);
+               }
+       }
+       if (ret && ret != -FDT_ERR_NOTFOUND)
                goto out;
 
+disable_otg:
        if (disable_otg) {
-               debug("Disabling usbphy\n");
+               debug("Disabling '%s'\n", fdt_get_name(blob, off, NULL));
                ret = fdt_set_node_status(blob, off, FDT_STATUS_DISABLED, 0);
-               if (ret)
-                       goto out;
-
-               ret = karo_fdt_disable_node_phandle(blob, node, phy);
+               if (ret > 0)
+                       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, phy_supply);
+               debug("Removing '%s' from node '%s'\n", phy_supply,
+                       fdt_get_name(blob, off, NULL));
+               ret = fdt_delprop(blob, off, phy_supply);
        }
 
 out:
-       if (ret)
+       if (ret && ret != -FDT_ERR_NOTFOUND)
                printf("Failed to update usbotg: %s\n", fdt_strerror(ret));
        else
                debug("node '%s' updated\n", node);
@@ -381,37 +417,28 @@ void karo_fdt_fixup_flexcan(void *blob, int xcvr_present)
        }
 }
 
-void karo_fdt_del_prop(void *blob, const char *compat, phys_addr_t offs,
-                       const char *prop)
+void karo_fdt_del_prop(void *blob, const char *compat, u32 offs,
+                       const char *propname)
 {
-       int ret;
-       int offset;
-       const uint32_t *phandle;
-       uint32_t ph = 0;
-
-       offset = fdt_node_offset_by_compat_reg(blob, compat, offs);
-       if (offset <= 0)
-               return;
-
-       phandle = fdt_getprop(blob, offset, prop, NULL);
-       if (phandle) {
-               ph = fdt32_to_cpu(*phandle);
-       }
+       int offset = -1;
+       const fdt32_t *reg = NULL;
 
-       debug("Removing property '%s' from node %s@%08lx\n", prop, compat, offs);
-       ret = fdt_delprop(blob, offset, prop);
-       if (ret == 0)
-               karo_set_fdtsize(blob);
+       while (1) {
+               offset = fdt_node_offset_by_compatible(blob, offset, compat);
+               if (offset <= 0)
+                       return;
 
-       if (!ph)
-               return;
+               reg = fdt_getprop(blob, offset, "reg", NULL);
+               if (reg == NULL)
+                       return;
 
-       offset = fdt_node_offset_by_phandle(blob, ph);
-       if (offset <= 0)
-               return;
+               if (fdt32_to_cpu(*reg) == offs)
+                       break;
+       }
+       debug("Removing property '%s' from node %s@%x\n",
+               propname, compat, offs);
+       fdt_delprop(blob, offset, propname);
 
-       debug("Removing node @ %08x\n", offset);
-       fdt_del_node(blob, offset);
        karo_set_fdtsize(blob);
 }
 
@@ -546,8 +573,6 @@ int karo_fdt_get_fb_mode(void *blob, const char *name, struct fb_videomode *fb_m
                                fdt_get_name(blob, off, NULL), d);
                        continue;
                }
-               debug("parsing subnode @ %04x %s depth %d\n", off,
-                       fdt_get_name(blob, off, NULL), d);
 
                n = fdt_getprop(blob, off, "panel-name", &len);
                if (!n) {
@@ -710,8 +735,6 @@ int karo_fdt_update_fb_mode(void *blob, const char *name)
                                fdt_get_name(blob, off, NULL), d);
                        continue;
                }
-               debug("parsing subnode @ %04x %s depth %d\n", off,
-                       fdt_get_name(blob, off, NULL), d);
 
                n = fdt_getprop(blob, off, "panel-name", &len);
                if (!n) {