X-Git-Url: https://git.kernelconcepts.de/?p=karo-tx-uboot.git;a=blobdiff_plain;f=board%2Fkaro%2Fcommon%2Ffdt.c;h=d43a1170fc27a27748b55eadb131dcc7ec8df03d;hp=387208c78e4e317e36ce96a4079121c39812337f;hb=b613e722f29c16b73805731b93c405b391f34708;hpb=cae0d09651975e122d2b4c66779adc77b8179432 diff --git a/board/karo/common/fdt.c b/board/karo/common/fdt.c index 387208c78e..d43a1170fc 100644 --- a/board/karo/common/fdt.c +++ b/board/karo/common/fdt.c @@ -1,5 +1,5 @@ /* - * (C) Copyright 2012,2013 Lothar Waßmann + * (C) Copyright 2012-2014 Lothar Waßmann * * 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); } @@ -223,13 +227,14 @@ static int karo_fdt_disable_node_phandle(void *blob, const char *parent, 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) +void karo_fdt_fixup_usb_otg(void *blob, const char *node, const char *phy, + const char *phy_supply) { const char *otg_mode = getenv("otg_mode"); 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 : ""); @@ -239,20 +244,19 @@ void karo_fdt_fixup_usb_otg(void *blob, const char *node, const char *phy) return; } - if (otg_mode && (strcmp(otg_mode, "device") == 0 || - strcmp(otg_mode, "gadget") == 0)) { + if (otg_mode && (strcasecmp(otg_mode, "device") == 0 || + strcasecmp(otg_mode, "gadget") == 0)) { debug("Setting dr_mode to 'peripheral'\n"); ret = fdt_setprop_string(blob, off, "dr_mode", "peripheral"); - } else if (otg_mode && strcmp(otg_mode, "host") == 0) { + 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 && strcmp(otg_mode, "otg") == 0) { - debug("Setting dr_mode to 'host'\n"); + } 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 && strcmp(otg_mode, "none") != 0) + if (otg_mode && strcasecmp(otg_mode, "none") != 0) printf("Invalid 'otg_mode' setting '%s'; disabling usbotg port\n", otg_mode); disable_otg = 1; @@ -262,24 +266,57 @@ 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) + ret = karo_fdt_disable_node_phandle(blob, node, phy_supply); + 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, "vbus-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); @@ -367,7 +404,7 @@ void karo_fdt_fixup_flexcan(void *blob, int xcvr_present) karo_fdt_set_lcd_pins(blob, "lcdif_24bit_pins_a"); } - if (otg_mode && strcmp(otg_mode, "host") == 0) + if (otg_mode && strcasecmp(otg_mode, "host") == 0) karo_fdt_enable_node(blob, "can1", 0); if (xcvr_status) { @@ -380,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); } @@ -545,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) { @@ -709,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) { @@ -812,7 +836,7 @@ int karo_fdt_get_backlight_polarity(const void *blob) */ off = fdt_path_offset(blob, backlight_node); if (off < 0) { - printf("/backlight node not found in DT\n"); + printf("%s node not found in DT\n", backlight_node); return off; } }