added 2 changesets to branch 'refs/remotes/mmu_man-github/sam460ex' old head: aec8bf1b72a0ec30f3286d06dec76955ab402a24 new head: 74eeabe4a645ee37466160d824975cda4fe200b7 ---------------------------------------------------------------------------- 513f67f: U-Boot: don't dump the FDT nodes by default * only dump some header infos from the FDT by default, as dumping the complete tree can get quite verbose. 74eeabe: U-Boot: initialize the debug UART using FDT hints when possible * we first try to find 'serial', 'serial0' or 'serial1' in /aliases * extract the required properties from the found node and use them * fallback to the hardcoded UART from the board definition header [ François Revol <revol@xxxxxxx> ] ---------------------------------------------------------------------------- 4 files changed, 98 insertions(+), 6 deletions(-) src/system/boot/platform/u-boot/fdt_support.cpp | 5 +- src/system/boot/platform/u-boot/serial.cpp | 95 ++++++++++++++++++- src/system/boot/platform/u-boot/serial.h | 2 +- src/system/boot/platform/u-boot/start.cpp | 2 +- ############################################################################ Commit: 513f67f193896ab464a1f32c4adce76306afa170 Author: François Revol <revol@xxxxxxx> Date: Fri Aug 24 19:15:50 2012 UTC U-Boot: don't dump the FDT nodes by default * only dump some header infos from the FDT by default, as dumping the complete tree can get quite verbose. ---------------------------------------------------------------------------- diff --git a/src/system/boot/platform/u-boot/fdt_support.cpp b/src/system/boot/platform/u-boot/fdt_support.cpp index 3fba564..cd7583d 100644 --- a/src/system/boot/platform/u-boot/fdt_support.cpp +++ b/src/system/boot/platform/u-boot/fdt_support.cpp @@ -22,7 +22,8 @@ static const char *sTabTab = "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t"; #define DS "%.*s" #define DA depth - 1, sTabTab -#define FDT_DUMP_PROPS +//#define FDT_DUMP_NODES +//#define FDT_DUMP_PROPS //#define FDT_DUMP_PROP_VALUES @@ -79,6 +80,7 @@ void dump_fdt(const void *fdt) dprintf("fdt_size_dt_strings: %d\n", fdt_size_dt_strings(fdt)); dprintf("fdt_size_dt_struct: %d\n", fdt_size_dt_struct(fdt)); +#ifdef FDT_DUMP_NODES dprintf("fdt tree:\n"); while ((node = fdt_next_node(fdt, node, &depth)) >= 0) { @@ -103,6 +105,7 @@ void dump_fdt(const void *fdt) } #endif } +#endif } ############################################################################ Commit: 74eeabe4a645ee37466160d824975cda4fe200b7 Author: François Revol <revol@xxxxxxx> Date: Fri Aug 24 19:20:09 2012 UTC U-Boot: initialize the debug UART using FDT hints when possible * we first try to find 'serial', 'serial0' or 'serial1' in /aliases * extract the required properties from the found node and use them * fallback to the hardcoded UART from the board definition header ---------------------------------------------------------------------------- diff --git a/src/system/boot/platform/u-boot/serial.cpp b/src/system/boot/platform/u-boot/serial.cpp index 12c6357..27bbb81 100644 --- a/src/system/boot/platform/u-boot/serial.cpp +++ b/src/system/boot/platform/u-boot/serial.cpp @@ -17,6 +17,12 @@ #include <new> #include <string.h> +extern "C" { +#include <fdt.h> +#include <libfdt.h> +#include <libfdt_env.h> +}; + DebugUART* gUART; @@ -90,11 +96,94 @@ serial_cleanup(void) } +static void +serial_init_fdt(const void *fdt) +{ + const char *name; + const char *type; + int node; + int len; + phys_addr_t regs; + int32 clock = 0; + int32 speed = 0; + const void *prop; + + if (fdt == NULL) + return; + + name = fdt_get_alias(fdt, "serial"); + if (name == NULL) + name = fdt_get_alias(fdt, "serial0"); + if (name == NULL) + name = fdt_get_alias(fdt, "serial1"); + // TODO: else use /chosen linux,stdout-path + if (name == NULL) + return; + + node = fdt_path_offset(fdt, name); + //dprintf("serial: using '%s', node %d\n", name, node); + if (node < 0) + return; + + type = (const char *)fdt_getprop(fdt, node, "device_type", &len); + //dprintf("serial: type: '%s'\n", type); + if (type == NULL || strcmp(type, "serial")) + return; + + // determine the MMIO address + // TODO: ppc640 use 64bit addressing, but U-Boot seems to map it below 4G, + // and the FDT is not very clear. libfdt is also getting 64bit addr support. + // so FIXME someday. + prop = fdt_getprop(fdt, node, "virtual-reg", &len); + if (prop && len == 4) { + regs = fdt32_to_cpu(*(uint32_t *)prop); + //dprintf("serial: virtual-reg 0x%08llx\n", (int64)regs); + } else { + prop = fdt_getprop(fdt, node, "reg", &len); + if (prop && len >= 4) { + regs = fdt32_to_cpu(*(uint32_t *)prop); + //dprintf("serial: reg 0x%08llx\n", (int64)regs); + } else + return; + } + + // get the UART clock rate + prop = fdt_getprop(fdt, node, "clock-frequency", &len); + if (prop && len == 4) { + clock = fdt32_to_cpu(*(uint32_t *)prop); + //dprintf("serial: clock %ld\n", clock); + } + + // get current speed (XXX: not yet passed over) + prop = fdt_getprop(fdt, node, "current-speed", &len); + if (prop && len == 4) { + speed = fdt32_to_cpu(*(uint32_t *)prop); + //dprintf("serial: speed %ld\n", speed); + } + + if (fdt_node_check_compatible(fdt, node, "ns16550a") == 1 + || fdt_node_check_compatible(fdt, node, "ns16550") == 1) { + gUART = arch_get_uart_8250(regs, clock); + //dprintf("serial: using 8250\n"); + return; + } + +} + + extern "C" void -serial_init(void) +serial_init(const void *fdt) { - gUART = arch_get_uart_8250(BOARD_UART_DEBUG, BOARD_UART_CLOCK); - if (gUART == 0) + // first try with hints from the FDT + serial_init_fdt(fdt); + +#ifdef BOARD_UART_DEBUG + // fallback to hardcoded board UART + if (gUART == NULL) + gUART = arch_get_uart_8250(BOARD_UART_DEBUG, BOARD_UART_CLOCK); +#endif + + if (gUART == NULL) return; serial_enable(); diff --git a/src/system/boot/platform/u-boot/serial.h b/src/system/boot/platform/u-boot/serial.h index 5db0789..af09d8c 100644 --- a/src/system/boot/platform/u-boot/serial.h +++ b/src/system/boot/platform/u-boot/serial.h @@ -13,7 +13,7 @@ extern "C" { #endif -extern void serial_init(void); +extern void serial_init(const void *fdt); extern void serial_cleanup(void); extern void serial_puts(const char *string, size_t size); diff --git a/src/system/boot/platform/u-boot/start.cpp b/src/system/boot/platform/u-boot/start.cpp index a6ad586..c379aa1 100644 --- a/src/system/boot/platform/u-boot/start.cpp +++ b/src/system/boot/platform/u-boot/start.cpp @@ -167,7 +167,7 @@ start_raw(int argc, const char **argv) args.platform.boot_tgz_data = NULL; args.platform.boot_tgz_size = 0; - serial_init(); + serial_init(gFDT); console_init(); cpu_init();