X-Git-Url: https://git.karo-electronics.de/?a=blobdiff_plain;f=lib%2Ffdtdec.c;h=1808350a5707031afbab3dfaacfb73017bfea321;hb=28af5121f1c575d523ebf2226ed988c6c57fb336;hp=5bf8f29b13e92fbfcb9f0d83132e0e6ac987d0e2;hpb=6a608f20b987122a658e26978d76d2753654f5f2;p=karo-tx-uboot.git diff --git a/lib/fdtdec.c b/lib/fdtdec.c index 5bf8f29b13..1808350a57 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -9,6 +9,7 @@ #include #include #include +#include #include DECLARE_GLOBAL_DATA_PTR; @@ -29,6 +30,9 @@ static const char * const compat_names[COMPAT_COUNT] = { COMPAT(NVIDIA_TEGRA20_KBC, "nvidia,tegra20-kbc"), COMPAT(NVIDIA_TEGRA20_NAND, "nvidia,tegra20-nand"), COMPAT(NVIDIA_TEGRA20_PWM, "nvidia,tegra20-pwm"), + COMPAT(NVIDIA_TEGRA124_DC, "nvidia,tegra124-dc"), + COMPAT(NVIDIA_TEGRA124_SOR, "nvidia,tegra124-sor"), + COMPAT(NVIDIA_TEGRA124_PMC, "nvidia,tegra124-pmc"), COMPAT(NVIDIA_TEGRA20_DC, "nvidia,tegra20-dc"), COMPAT(NVIDIA_TEGRA124_SDMMC, "nvidia,tegra124-sdhci"), COMPAT(NVIDIA_TEGRA30_SDMMC, "nvidia,tegra30-sdhci"), @@ -42,10 +46,7 @@ static const char * const compat_names[COMPAT_COUNT] = { COMPAT(SAMSUNG_S3C2440_I2C, "samsung,s3c2440-i2c"), COMPAT(SAMSUNG_EXYNOS5_SOUND, "samsung,exynos-sound"), COMPAT(WOLFSON_WM8994_CODEC, "wolfson,wm8994-codec"), - COMPAT(GOOGLE_CROS_EC, "google,cros-ec"), COMPAT(GOOGLE_CROS_EC_KEYB, "google,cros-ec-keyb"), - COMPAT(SAMSUNG_EXYNOS_EHCI, "samsung,exynos-ehci"), - COMPAT(SAMSUNG_EXYNOS5_XHCI, "samsung,exynos5250-xhci"), COMPAT(SAMSUNG_EXYNOS_USB_PHY, "samsung,exynos-usb-phy"), COMPAT(SAMSUNG_EXYNOS5_USB3_PHY, "samsung,exynos5250-usb3-phy"), COMPAT(SAMSUNG_EXYNOS_TMU, "samsung,exynos-tmu"), @@ -55,19 +56,17 @@ static const char * const compat_names[COMPAT_COUNT] = { COMPAT(SAMSUNG_EXYNOS_DWMMC, "samsung,exynos-dwmmc"), COMPAT(SAMSUNG_EXYNOS_MMC, "samsung,exynos-mmc"), COMPAT(SAMSUNG_EXYNOS_SERIAL, "samsung,exynos4210-uart"), - COMPAT(MAXIM_MAX77686_PMIC, "maxim,max77686_pmic"), + COMPAT(MAXIM_MAX77686_PMIC, "maxim,max77686"), COMPAT(GENERIC_SPI_FLASH, "spi-flash"), COMPAT(MAXIM_98095_CODEC, "maxim,max98095-codec"), COMPAT(INFINEON_SLB9635_TPM, "infineon,slb9635-tpm"), - COMPAT(INFINEON_SLB9645_TPM, "infineon,slb9645-tpm"), + COMPAT(INFINEON_SLB9645_TPM, "infineon,slb9645tt"), COMPAT(SAMSUNG_EXYNOS5_I2C, "samsung,exynos5-hsi2c"), - COMPAT(SANDBOX_HOST_EMULATION, "sandbox,host-emulation"), COMPAT(SANDBOX_LCD_SDL, "sandbox,lcd-sdl"), COMPAT(TI_TPS65090, "ti,tps65090"), COMPAT(COMPAT_NXP_PTN3460, "nxp,ptn3460"), COMPAT(SAMSUNG_EXYNOS_SYSMMU, "samsung,sysmmu-v3.3"), COMPAT(PARADE_PS8625, "parade,ps8625"), - COMPAT(COMPAT_INTEL_LPC, "intel,lpc"), COMPAT(INTEL_MICROCODE, "intel,microcode"), COMPAT(MEMORY_SPD, "memory-spd"), COMPAT(INTEL_PANTHERPOINT_AHCI, "intel,pantherpoint-ahci"), @@ -75,6 +74,10 @@ static const char * const compat_names[COMPAT_COUNT] = { COMPAT(INTEL_GMA, "intel,gma"), COMPAT(AMS_AS3722, "ams,as3722"), COMPAT(INTEL_ICH_SPI, "intel,ich-spi"), + COMPAT(INTEL_QRK_MRC, "intel,quark-mrc"), + COMPAT(SOCIONEXT_XHCI, "socionext,uniphier-xhci"), + COMPAT(COMPAT_INTEL_PCH, "intel,bd82x6x"), + COMPAT(COMPAT_INTEL_IRQ_ROUTER, "intel,irq-router"), }; const char *fdtdec_get_compatible(enum fdt_compat_id id) @@ -158,8 +161,10 @@ int fdtdec_get_pci_addr(const void *blob, int node, enum fdt_pci_space type, } } - if (i == num) + if (i == num) { + ret = -ENXIO; goto fail; + } return 0; } else { @@ -563,9 +568,11 @@ int fdtdec_prepare_fdt(void) { if (!gd->fdt_blob || ((uintptr_t)gd->fdt_blob & 3) || fdt_check_header(gd->fdt_blob)) { - printf("No valid FDT found - please append one to U-Boot " - "binary, use u-boot-dtb.bin or define " - "CONFIG_OF_EMBED. For sandbox, use -d \n"); +#ifdef CONFIG_SPL_BUILD + puts("Missing DTB\n"); +#else + puts("No valid device tree binary found - please append one to U-Boot binary, use u-boot-dtb.bin or define CONFIG_OF_EMBED. For sandbox, use -d \n"); +#endif return -1; } return 0; @@ -916,7 +923,7 @@ int fdtdec_read_fmap_entry(const void *blob, int node, const char *name, return 0; } -static u64 fdtdec_get_number(const fdt32_t *ptr, unsigned int cells) +u64 fdtdec_get_number(const fdt32_t *ptr, unsigned int cells) { u64 number = 0; @@ -1033,4 +1040,126 @@ int fdtdec_decode_memory_region(const void *blob, int config_node, return 0; } + +static int decode_timing_property(const void *blob, int node, const char *name, + struct timing_entry *result) +{ + int length, ret = 0; + const u32 *prop; + + prop = fdt_getprop(blob, node, name, &length); + if (!prop) { + debug("%s: could not find property %s\n", + fdt_get_name(blob, node, NULL), name); + return length; + } + + if (length == sizeof(u32)) { + result->typ = fdtdec_get_int(blob, node, name, 0); + result->min = result->typ; + result->max = result->typ; + } else { + ret = fdtdec_get_int_array(blob, node, name, &result->min, 3); + } + + return ret; +} + +int fdtdec_decode_display_timing(const void *blob, int parent, int index, + struct display_timing *dt) +{ + int i, node, timings_node; + u32 val = 0; + int ret = 0; + + timings_node = fdt_subnode_offset(blob, parent, "display-timings"); + if (timings_node < 0) + return timings_node; + + for (i = 0, node = fdt_first_subnode(blob, timings_node); + node > 0 && i != index; + node = fdt_next_subnode(blob, node)) + i++; + + if (node < 0) + return node; + + memset(dt, 0, sizeof(*dt)); + + ret |= decode_timing_property(blob, node, "hback-porch", + &dt->hback_porch); + ret |= decode_timing_property(blob, node, "hfront-porch", + &dt->hfront_porch); + ret |= decode_timing_property(blob, node, "hactive", &dt->hactive); + ret |= decode_timing_property(blob, node, "hsync-len", &dt->hsync_len); + ret |= decode_timing_property(blob, node, "vback-porch", + &dt->vback_porch); + ret |= decode_timing_property(blob, node, "vfront-porch", + &dt->vfront_porch); + ret |= decode_timing_property(blob, node, "vactive", &dt->vactive); + ret |= decode_timing_property(blob, node, "vsync-len", &dt->vsync_len); + ret |= decode_timing_property(blob, node, "clock-frequency", + &dt->pixelclock); + + dt->flags = 0; + val = fdtdec_get_int(blob, node, "vsync-active", -1); + if (val != -1) { + dt->flags |= val ? DISPLAY_FLAGS_VSYNC_HIGH : + DISPLAY_FLAGS_VSYNC_LOW; + } + val = fdtdec_get_int(blob, node, "hsync-active", -1); + if (val != -1) { + dt->flags |= val ? DISPLAY_FLAGS_HSYNC_HIGH : + DISPLAY_FLAGS_HSYNC_LOW; + } + val = fdtdec_get_int(blob, node, "de-active", -1); + if (val != -1) { + dt->flags |= val ? DISPLAY_FLAGS_DE_HIGH : + DISPLAY_FLAGS_DE_LOW; + } + val = fdtdec_get_int(blob, node, "pixelclk-active", -1); + if (val != -1) { + dt->flags |= val ? DISPLAY_FLAGS_PIXDATA_POSEDGE : + DISPLAY_FLAGS_PIXDATA_NEGEDGE; + } + + if (fdtdec_get_bool(blob, node, "interlaced")) + dt->flags |= DISPLAY_FLAGS_INTERLACED; + if (fdtdec_get_bool(blob, node, "doublescan")) + dt->flags |= DISPLAY_FLAGS_DOUBLESCAN; + if (fdtdec_get_bool(blob, node, "doubleclk")) + dt->flags |= DISPLAY_FLAGS_DOUBLECLK; + + return 0; +} + +int fdtdec_setup(void) +{ +#ifdef CONFIG_OF_CONTROL +# ifdef CONFIG_OF_EMBED + /* Get a pointer to the FDT */ + gd->fdt_blob = __dtb_dt_begin; +# elif defined CONFIG_OF_SEPARATE +# ifdef CONFIG_SPL_BUILD + /* FDT is at end of BSS */ + gd->fdt_blob = (ulong *)&__bss_end; +# else + /* FDT is at end of image */ + gd->fdt_blob = (ulong *)&_end; +#endif +# elif defined(CONFIG_OF_HOSTFILE) + if (sandbox_read_fdt_from_file()) { + puts("Failed to read control FDT\n"); + return -1; + } +# endif +# ifndef CONFIG_SPL_BUILD + /* Allow the early environment to override the fdt address */ + gd->fdt_blob = (void *)getenv_ulong("fdtcontroladdr", 16, + (uintptr_t)gd->fdt_blob); +# endif #endif + return fdtdec_prepare_fdt(); +} + +#endif /* !USE_HOSTCC */