summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.travis.yml6
-rw-r--r--MAINTAINERS1
-rw-r--r--Makefile10
-rw-r--r--arch/arm/Kconfig1
-rw-r--r--arch/arm/cpu/armv8/fsl-layerscape/soc.c8
-rw-r--r--arch/arm/dts/Makefile3
-rw-r--r--arch/arm/dts/am3517-evm-u-boot.dtsi12
-rw-r--r--arch/arm/dts/am3517-evm.dts61
-rw-r--r--arch/arm/dts/am3517-u-boot.dtsi10
-rw-r--r--arch/arm/dts/am3517.dtsi107
-rw-r--r--arch/arm/dts/am35xx-clocks.dtsi128
-rw-r--r--arch/arm/dts/da850-evm-u-boot.dtsi23
-rw-r--r--arch/arm/dts/da850-evm.dts304
-rw-r--r--arch/arm/dts/da850.dtsi581
-rw-r--r--arch/arm/dts/fsl-ls2081a-rdb.dts4
-rw-r--r--arch/arm/dts/omap3.dtsi4
-rw-r--r--arch/arm/dts/omap5-u-boot.dtsi20
-rw-r--r--arch/arm/dts/rk3288-vyasa.dts327
-rw-r--r--arch/arm/dts/rk3368-lion-u-boot.dtsi10
-rw-r--r--arch/arm/dts/rk3399-puma.dtsi12
-rw-r--r--arch/arm/dts/rv1108-evb.dts22
-rw-r--r--arch/arm/dts/rv1108.dtsi24
-rw-r--r--arch/arm/dts/stih407-family.dtsi3
-rw-r--r--arch/arm/dts/stih410.dtsi11
-rw-r--r--arch/arm/dts/stm32h7-u-boot.dtsi88
-rw-r--r--arch/arm/dts/stm32h743-pinctrl.dtsi249
-rw-r--r--arch/arm/dts/stm32h743.dtsi129
-rw-r--r--arch/arm/dts/stm32h743i-disco.dts100
-rw-r--r--arch/arm/dts/stm32h743i-eval.dts100
-rw-r--r--arch/arm/dts/tps6507x.dtsi47
-rw-r--r--arch/arm/include/asm/arch-fsl-layerscape/cpu.h10
-rw-r--r--arch/arm/include/asm/arch-mx6/sys_proto.h7
-rw-r--r--arch/arm/include/asm/arch-mx7/clock.h6
-rw-r--r--arch/arm/include/asm/arch-rockchip/grf_rk322x.h32
-rw-r--r--arch/arm/include/asm/arch-stih410/sys_proto.h11
-rw-r--r--arch/arm/include/asm/arch-stm32h7/gpio.h126
-rw-r--r--arch/arm/include/asm/arch-stm32h7/stm32.h21
-rw-r--r--arch/arm/mach-imx/mx7/clock.c6
-rw-r--r--arch/arm/mach-imx/spl.c22
-rw-r--r--arch/arm/mach-mvebu/cpu.c30
-rw-r--r--arch/arm/mach-mvebu/dram.c51
-rw-r--r--arch/arm/mach-mvebu/include/mach/config.h3
-rw-r--r--arch/arm/mach-mvebu/include/mach/cpu.h1
-rw-r--r--arch/arm/mach-mvebu/include/mach/soc.h4
-rw-r--r--arch/arm/mach-mvebu/spl.c3
-rw-r--r--arch/arm/mach-omap2/am33xx/mux.c14
-rw-r--r--arch/arm/mach-omap2/omap3/Kconfig5
-rw-r--r--arch/arm/mach-omap2/sec-common.c6
-rw-r--r--arch/arm/mach-rockchip/rk322x-board.c23
-rw-r--r--arch/arm/mach-rockchip/rk3288/Kconfig11
-rw-r--r--arch/arm/mach-rockchip/rk3399-board-spl.c34
-rw-r--r--arch/arm/mach-rockchip/rk3399/sdram_rk3399.c2
-rw-r--r--arch/arm/mach-socfpga/misc_gen5.c2
-rw-r--r--arch/arm/mach-stm32/Kconfig17
-rw-r--r--arch/arm/mach-stm32/Makefile1
-rw-r--r--arch/arm/mach-stm32/stm32h7/Kconfig12
-rw-r--r--arch/arm/mach-stm32/stm32h7/Makefile8
-rw-r--r--arch/arm/mach-stm32/stm32h7/soc.c59
-rw-r--r--arch/arm/mach-uniphier/Kconfig21
-rw-r--r--arch/arm/mach-uniphier/clk/clk-ld11.c2
-rw-r--r--arch/arm/mach-uniphier/clk/clk-ld20.c12
-rw-r--r--arch/arm/mach-uniphier/clk/clk-pxs3.c12
-rw-r--r--arch/arm/mach-uniphier/sc64-regs.h18
-rw-r--r--arch/nds32/cpu/n1213/start.S29
-rw-r--r--arch/nds32/dts/ae3xx.dts23
-rw-r--r--arch/nds32/include/asm/bootm.h2
-rw-r--r--arch/nds32/include/asm/io.h33
-rw-r--r--arch/nds32/lib/bootm.c1
-rw-r--r--board/AndesTech/adp-ae3xx/adp-ae3xx.c1
-rw-r--r--board/amarula/vyasa-rk3288/Kconfig12
-rw-r--r--board/amarula/vyasa-rk3288/MAINTAINERS6
-rw-r--r--board/amarula/vyasa-rk3288/Makefile7
-rw-r--r--board/amarula/vyasa-rk3288/vyasa-rk3288.c7
-rw-r--r--board/bachmann/ot1200/ot1200_spl.c6
-rw-r--r--board/compulab/cm_fx6/spl.c3
-rw-r--r--board/davinci/da8xxevm/Kconfig2
-rw-r--r--board/davinci/da8xxevm/da850evm.c3
-rw-r--r--board/engicam/common/spl.c6
-rw-r--r--board/freescale/ls2080ardb/ls2080ardb.c12
-rw-r--r--board/freescale/mx7dsabresd/mx7dsabresd.c2
-rw-r--r--board/gateworks/gw_ventana/gw_ventana_spl.c3
-rw-r--r--board/ge/bx50v3/Makefile2
-rw-r--r--board/ge/bx50v3/bx50v3.c109
-rw-r--r--board/ge/bx50v3/vpd_reader.c228
-rw-r--r--board/ge/bx50v3/vpd_reader.h25
-rw-r--r--board/kosagi/novena/novena_spl.c6
-rw-r--r--board/liebherr/mccmon6/spl.c6
-rw-r--r--board/logicpd/am3517evm/am3517evm.c71
-rw-r--r--board/solidrun/clearfog/README20
-rw-r--r--board/solidrun/mx6cuboxi/mx6cuboxi.c35
-rw-r--r--board/st/stih410-b2260/board.c42
-rw-r--r--board/st/stm32h743-disco/Kconfig19
-rw-r--r--board/st/stm32h743-disco/MAINTAINERS7
-rw-r--r--board/st/stm32h743-disco/Makefile8
-rw-r--r--board/st/stm32h743-disco/stm32h743-disco.c56
-rw-r--r--board/st/stm32h743-eval/Kconfig19
-rw-r--r--board/st/stm32h743-eval/MAINTAINERS6
-rw-r--r--board/st/stm32h743-eval/Makefile8
-rw-r--r--board/st/stm32h743-eval/stm32h743-eval.c56
-rw-r--r--board/technexion/pico-imx7d/README17
-rw-r--r--board/technexion/pico-imx7d/pico-imx7d.c2
-rw-r--r--board/theadorable/MAINTAINERS1
-rw-r--r--board/theobroma-systems/lion_rk3368/README24
-rw-r--r--board/theobroma-systems/puma_rk3399/README51
-rw-r--r--board/theobroma-systems/puma_rk3399/puma-rk3399.c2
-rw-r--r--board/toradex/apalis_imx6/apalis_imx6.c13
-rw-r--r--board/toradex/colibri_imx6/colibri_imx6.c13
-rw-r--r--board/toradex/colibri_imx7/colibri_imx7.c2
-rw-r--r--board/udoo/udoo_spl.c6
-rw-r--r--board/wandboard/spl.c6
-rw-r--r--cmd/gpt.c3
-rw-r--r--common/Makefile2
-rw-r--r--common/spl/Kconfig1
-rw-r--r--common/spl/spl.c14
-rw-r--r--common/spl/spl_fit.c5
-rw-r--r--common/spl/spl_mmc.c5
-rw-r--r--common/usb_storage.c64
-rw-r--r--configs/Cyrus_P5020_defconfig1
-rw-r--r--configs/Cyrus_P5040_defconfig1
-rw-r--r--configs/MPC8610HPCD_defconfig1
-rw-r--r--configs/MPC8641HPCN_36BIT_defconfig1
-rw-r--r--configs/MPC8641HPCN_defconfig1
-rw-r--r--configs/adp-ae3xx_defconfig10
-rw-r--r--configs/am335x_baltos_defconfig2
-rw-r--r--configs/am335x_boneblack_defconfig2
-rw-r--r--configs/am335x_boneblack_vboot_defconfig2
-rw-r--r--configs/am335x_evm_defconfig2
-rw-r--r--configs/am335x_evm_nor_defconfig2
-rw-r--r--configs/am335x_evm_spiboot_defconfig2
-rw-r--r--configs/am335x_evm_usbspl_defconfig2
-rw-r--r--configs/am335x_hs_evm_defconfig2
-rw-r--r--configs/am335x_hs_evm_uart_defconfig67
-rw-r--r--configs/am335x_igep003x_defconfig2
-rw-r--r--configs/am335x_shc_defconfig2
-rw-r--r--configs/am335x_shc_ict_defconfig2
-rw-r--r--configs/am335x_shc_netboot_defconfig2
-rw-r--r--configs/am335x_shc_prompt_defconfig2
-rw-r--r--configs/am335x_shc_sdboot_defconfig2
-rw-r--r--configs/am335x_shc_sdboot_prompt_defconfig2
-rw-r--r--configs/am335x_sl50_defconfig2
-rw-r--r--configs/am3517_evm_defconfig6
-rw-r--r--configs/am43xx_evm_defconfig2
-rw-r--r--configs/am43xx_evm_usbhost_boot_defconfig2
-rw-r--r--configs/am43xx_hs_evm_defconfig2
-rw-r--r--configs/am57xx_evm_defconfig2
-rw-r--r--configs/am57xx_hs_evm_defconfig2
-rw-r--r--configs/apalis_imx6_defconfig1
-rw-r--r--configs/apalis_imx6_nospl_com_defconfig1
-rw-r--r--configs/apalis_imx6_nospl_it_defconfig1
-rw-r--r--configs/chiliboard_defconfig2
-rw-r--r--configs/clearfog_defconfig2
-rw-r--r--configs/colibri_imx6_defconfig1
-rw-r--r--configs/colibri_imx6_nospl_defconfig1
-rw-r--r--configs/controlcenterdc_defconfig2
-rw-r--r--configs/da850_am18xxevm_defconfig16
-rw-r--r--configs/da850evm_defconfig15
-rw-r--r--configs/da850evm_direct_nor_defconfig10
-rw-r--r--configs/db-88f6820-amc_defconfig2
-rw-r--r--configs/db-88f6820-gp_defconfig2
-rw-r--r--configs/db-mv784mp-gp_defconfig2
-rw-r--r--configs/dra7xx_evm_defconfig2
-rw-r--r--configs/dra7xx_hs_evm_defconfig2
-rw-r--r--configs/ds414_defconfig2
-rw-r--r--configs/evb-rv1108_defconfig21
-rw-r--r--configs/firefly-rk3288_defconfig1
-rw-r--r--configs/lion-rk3368_defconfig7
-rw-r--r--configs/ls1043ardb_sdcard_defconfig1
-rw-r--r--configs/ls1046ardb_sdcard_defconfig1
-rw-r--r--configs/maxbcm_defconfig2
-rw-r--r--configs/mx6cuboxi_defconfig1
-rw-r--r--configs/mx6sabresd_defconfig4
-rw-r--r--configs/omap3_evm_defconfig2
-rw-r--r--configs/omap3_logic_defconfig2
-rw-r--r--configs/omap3_overo_defconfig2
-rw-r--r--configs/puma-rk3399_defconfig1
-rw-r--r--configs/rpi_2_defconfig1
-rw-r--r--configs/rpi_3_32b_defconfig1
-rw-r--r--configs/rpi_3_defconfig1
-rw-r--r--configs/rpi_defconfig1
-rw-r--r--configs/sandbox_defconfig1
-rw-r--r--configs/sandbox_flattree_defconfig1
-rw-r--r--configs/sandbox_noblk_defconfig1
-rw-r--r--configs/sandbox_spl_defconfig1
-rw-r--r--configs/seaboard_defconfig1
-rw-r--r--configs/sheep-rk3368_defconfig2
-rw-r--r--configs/socfpga_de0_nano_soc_defconfig3
-rw-r--r--configs/stih410-b2260_defconfig39
-rw-r--r--configs/stm32h743-disco_defconfig30
-rw-r--r--configs/stm32h743-eval_defconfig30
-rw-r--r--configs/theadorable_debug_defconfig2
-rw-r--r--configs/theadorable_defconfig54
-rw-r--r--configs/ti816x_evm_defconfig2
-rw-r--r--configs/turris_omnia_defconfig2
-rw-r--r--configs/uniphier_pro4_defconfig49
-rw-r--r--configs/uniphier_v7_defconfig (renamed from configs/uniphier_pxs2_ld6b_defconfig)4
-rw-r--r--configs/ventana_defconfig1
-rw-r--r--configs/vyasa-rk3288_defconfig63
-rw-r--r--doc/README.uniphier33
-rw-r--r--doc/device-tree-bindings/clock/st,stm32h7-rcc.txt152
-rw-r--r--doc/device-tree-bindings/phy/phy-stih407-usb.txt24
-rw-r--r--doc/device-tree-bindings/reset/st,stm32-rcc.txt6
-rw-r--r--doc/device-tree-bindings/usb/dwc3-st.txt60
-rw-r--r--drivers/clk/Makefile1
-rw-r--r--drivers/clk/clk_stm32f7.c13
-rw-r--r--drivers/clk/clk_stm32h7.c802
-rw-r--r--drivers/clk/rockchip/clk_rk3368.c2
-rw-r--r--drivers/clk/rockchip/clk_rk3399.c19
-rw-r--r--drivers/core/read.c18
-rw-r--r--drivers/gpio/rk_gpio.c3
-rw-r--r--drivers/i2c/rk_i2c.c2
-rw-r--r--drivers/misc/Kconfig9
-rw-r--r--drivers/misc/Makefile1
-rw-r--r--drivers/misc/rockchip-efuse.c2
-rw-r--r--drivers/misc/stm32_rcc.c45
-rw-r--r--drivers/mmc/Kconfig16
-rw-r--r--drivers/mmc/Makefile1
-rw-r--r--drivers/mmc/rockchip_dw_mmc.c2
-rw-r--r--drivers/mmc/rockchip_sdhci.c5
-rw-r--r--drivers/mmc/sdhci-cadence.c51
-rw-r--r--drivers/mmc/sti_sdhci.c62
-rw-r--r--drivers/mmc/stm32_sdmmc2.c608
-rw-r--r--drivers/mmc/uniphier-sd.c253
-rw-r--r--drivers/mtd/cfi_flash.c25
-rw-r--r--drivers/mtd/nand/denali.c27
-rw-r--r--drivers/mtd/nand/denali.h7
-rw-r--r--drivers/mtd/nand/denali_dt.c30
-rw-r--r--drivers/mtd/spi/spi_flash_ids.c6
-rw-r--r--drivers/net/Kconfig8
-rw-r--r--drivers/net/designware.c11
-rw-r--r--drivers/net/ftmac100.c12
-rw-r--r--drivers/net/phy/micrel_ksz90x1.c5
-rw-r--r--drivers/pci/Kconfig1
-rw-r--r--drivers/pci/pci_tegra.c2
-rw-r--r--drivers/pci/pcie_layerscape.h1
-rw-r--r--drivers/pci/pcie_layerscape_fixup.c19
-rw-r--r--drivers/pci/pcie_xilinx.c6
-rw-r--r--drivers/phy/Kconfig8
-rw-r--r--drivers/phy/Makefile1
-rw-r--r--drivers/phy/sti_usb_phy.c181
-rw-r--r--drivers/pinctrl/pinctrl_stm32.c1
-rw-r--r--drivers/pinctrl/rockchip/pinctrl_rk3368.c3
-rw-r--r--drivers/power/pmic/rk8xx.c2
-rw-r--r--drivers/power/regulator/Kconfig13
-rw-r--r--drivers/power/regulator/Makefile1
-rw-r--r--drivers/power/regulator/pbias_regulator.c301
-rw-r--r--drivers/ram/rockchip/dmc-rk3368.c11
-rw-r--r--drivers/reset/Kconfig7
-rw-r--r--drivers/reset/Makefile1
-rw-r--r--drivers/reset/stm32-reset.c80
-rw-r--r--drivers/serial/Kconfig7
-rw-r--r--drivers/serial/serial_stm32x7.c2
-rw-r--r--drivers/spi/Kconfig7
-rw-r--r--drivers/spi/Makefile1
-rw-r--r--drivers/spi/davinci_spi.c1
-rw-r--r--drivers/spi/fsl_qspi.c46
-rw-r--r--drivers/spi/fsl_qspi.h4
-rw-r--r--drivers/spi/mxc_spi.c181
-rw-r--r--drivers/spi/nds_ae3xx_spi.c499
-rw-r--r--drivers/spi/rk_spi.c2
-rw-r--r--drivers/sysreset/Makefile1
-rw-r--r--drivers/timer/rockchip_timer.c78
-rw-r--r--drivers/timer/timer-uclass.c52
-rw-r--r--drivers/usb/Kconfig2
-rw-r--r--drivers/usb/gadget/dwc2_udc_otg_xfer_dma.c3
-rw-r--r--drivers/usb/host/Kconfig9
-rw-r--r--drivers/usb/host/Makefile1
-rw-r--r--drivers/usb/host/dwc2.c2
-rw-r--r--drivers/usb/host/dwc3-sti-glue.c257
-rw-r--r--drivers/usb/host/ehci-generic.c2
-rw-r--r--drivers/usb/host/ehci-hcd.c12
-rw-r--r--drivers/usb/host/usb-uclass.c11
-rw-r--r--drivers/usb/host/xhci-rockchip.c4
-rw-r--r--drivers/usb/host/xhci.c15
-rw-r--r--drivers/usb/host/xhci.h4
-rw-r--r--drivers/video/Kconfig41
-rw-r--r--drivers/video/Makefile8
-rw-r--r--drivers/video/backlight_gpio.c74
-rw-r--r--drivers/video/cfb_console.c3
-rw-r--r--drivers/video/simplefb.c73
-rw-r--r--drivers/video/stm32/Kconfig44
-rw-r--r--drivers/video/stm32/Makefile10
-rw-r--r--drivers/video/stm32/stm32_ltdc.c406
-rw-r--r--drivers/video/video-uclass.c4
-rw-r--r--dts/Kconfig13
-rw-r--r--fs/fat/fat.c14
-rw-r--r--include/configs/adp-ae3xx.h18
-rw-r--r--include/configs/adp-ag101p.h3
-rw-r--r--include/configs/am3517_evm.h14
-rw-r--r--include/configs/am43xx_evm.h5
-rw-r--r--include/configs/am57xx_evm.h3
-rw-r--r--include/configs/da850evm.h57
-rw-r--r--include/configs/dra7xx_evm.h3
-rw-r--r--include/configs/ge_bx50v3.h15
-rw-r--r--include/configs/k2g_evm.h2
-rw-r--r--include/configs/ls1043a_common.h2
-rw-r--r--include/configs/ls2080ardb.h8
-rw-r--r--include/configs/mvebu_armada-37xx.h1
-rw-r--r--include/configs/mx6cuboxi.h4
-rw-r--r--include/configs/rk3368_common.h1
-rw-r--r--include/configs/rv1108_common.h3
-rw-r--r--include/configs/socfpga_common.h2
-rw-r--r--include/configs/stih410-b2260.h15
-rw-r--r--include/configs/stm32h743-disco.h51
-rw-r--r--include/configs/stm32h743-eval.h51
-rw-r--r--include/configs/ti_armv7_keystone2.h2
-rw-r--r--include/configs/vyasa-rk3288.h23
-rw-r--r--include/dm/read.h51
-rw-r--r--include/dt-bindings/clock/stm32h7-clks.h167
-rw-r--r--include/dt-bindings/memory/stm32-sdram.h7
-rw-r--r--include/dt-bindings/mfd/stm32h7-rcc.h138
-rw-r--r--include/dt-bindings/pinctrl/stm32h7-pinfunc.h1612
-rw-r--r--include/dwc3-sti-glue.h41
-rw-r--r--include/environment/ti/boot.h13
-rw-r--r--include/flash.h5
-rw-r--r--include/mtd/cfi_flash.h1
-rw-r--r--include/usb.h22
-rw-r--r--include/usb/ehci-ci.h2
-rw-r--r--net/tftp.c2
-rw-r--r--scripts/Kbuild.include5
-rw-r--r--scripts/Makefile1
-rw-r--r--scripts/Makefile.extrawarn16
-rw-r--r--scripts/config_whitelist.txt1
-rwxr-xr-xscripts/dtc-version.sh7
-rw-r--r--scripts/dtc/Makefile31
-rw-r--r--scripts/dtc/Makefile.dtc18
-rw-r--r--scripts/dtc/checks.c1076
-rw-r--r--scripts/dtc/data.c269
-rw-r--r--scripts/dtc/dtc-lexer.l306
-rw-r--r--scripts/dtc/dtc-lexer.lex.c_shipped2255
-rw-r--r--scripts/dtc/dtc-parser.tab.c_shipped2301
-rw-r--r--scripts/dtc/dtc-parser.tab.h_shipped123
-rw-r--r--scripts/dtc/dtc-parser.y519
-rw-r--r--scripts/dtc/dtc.c365
-rw-r--r--scripts/dtc/dtc.h290
-rw-r--r--scripts/dtc/flattree.c940
-rw-r--r--scripts/dtc/fstree.c90
-rw-r--r--scripts/dtc/libfdt/Makefile.libfdt11
-rw-r--r--scripts/dtc/libfdt/fdt.c251
-rw-r--r--scripts/dtc/libfdt/fdt.h111
-rw-r--r--scripts/dtc/libfdt/fdt_empty_tree.c83
-rw-r--r--scripts/dtc/libfdt/fdt_ro.c703
-rw-r--r--scripts/dtc/libfdt/fdt_rw.c505
-rw-r--r--scripts/dtc/libfdt/fdt_strerror.c102
-rw-r--r--scripts/dtc/libfdt/fdt_sw.c300
-rw-r--r--scripts/dtc/libfdt/fdt_wip.c139
-rw-r--r--scripts/dtc/libfdt/libfdt.h1899
-rw-r--r--scripts/dtc/libfdt/libfdt_env.h112
-rw-r--r--scripts/dtc/libfdt/libfdt_internal.h95
-rw-r--r--scripts/dtc/livetree.c981
-rw-r--r--scripts/dtc/srcpos.c302
-rw-r--r--scripts/dtc/srcpos.h117
-rw-r--r--scripts/dtc/treesource.c284
-rwxr-xr-xscripts/dtc/update-dtc-source.sh81
-rw-r--r--scripts/dtc/util.c474
-rw-r--r--scripts/dtc/util.h263
-rw-r--r--scripts/dtc/version_gen.h1
-rw-r--r--scripts/spelling.txt1217
-rw-r--r--test/py/README.md7
-rw-r--r--test/py/conftest.py35
-rw-r--r--test/py/multiplexed_log.py8
-rw-r--r--test/py/tests/test_dfu.py1
-rwxr-xr-xtest/py/tests/test_fit.py1
-rw-r--r--test/py/tests/test_gpt.py13
-rw-r--r--test/py/tests/test_vboot.py4
-rw-r--r--tools/Makefile2
-rw-r--r--tools/buildman/kconfiglib.py333
-rwxr-xr-xtools/moveconfig.py2
367 files changed, 27912 insertions, 973 deletions
diff --git a/.travis.yml b/.travis.yml
index b81d733695..00b2a73a5e 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -26,11 +26,9 @@ addons:
- grub-efi-ia32-bin
- rpm2cpio
- wget
+ - device-tree-compiler
install:
- # install latest device tree compiler
- - git clone --depth=1 git://git.kernel.org/pub/scm/utils/dtc/dtc.git /tmp/dtc
- - make -j4 -C /tmp/dtc
# Clone uboot-test-hooks
- git clone --depth=1 git://github.com/swarren/uboot-test-hooks.git /tmp/uboot-test-hooks
- ln -s travis-ci /tmp/uboot-test-hooks/bin/`hostname`
@@ -51,7 +49,7 @@ install:
env:
global:
- - PATH=/tmp/dtc:/tmp/qemu-install/bin:/tmp/uboot-test-hooks/bin:/usr/bin:/bin
+ - PATH=/tmp/qemu-install/bin:/tmp/uboot-test-hooks/bin:/usr/bin:/bin
- PYTHONPATH=/tmp/uboot-test-hooks/py/travis-ci
- BUILD_DIR=build
- HOSTCC="cc"
diff --git a/MAINTAINERS b/MAINTAINERS
index 0b7b2bbeb2..b167b028ec 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -420,6 +420,7 @@ F: arch/arm/mach-omap2/omap5/sec-fxns.c
F: arch/arm/mach-omap2/sec-common.c
F: arch/arm/mach-omap2/config_secure.mk
F: configs/am335x_hs_evm_defconfig
+F: configs/am335x_hs_evm_uart_defconfig
F: configs/am43xx_hs_evm_defconfig
F: configs/am57xx_hs_evm_defconfig
F: configs/dra7xx_hs_evm_defconfig
diff --git a/Makefile b/Makefile
index 8250b3409a..b7d5cbb3f9 100644
--- a/Makefile
+++ b/Makefile
@@ -349,7 +349,7 @@ OBJDUMP = $(CROSS_COMPILE)objdump
AWK = awk
PERL = perl
PYTHON ?= python
-DTC ?= dtc
+DTC ?= $(objtree)/scripts/dtc/dtc
CHECK = sparse
CHECKFLAGS := -D__linux__ -Dlinux -D__STDC__ -Dunix -D__unix__ \
@@ -872,7 +872,7 @@ endif
PHONY += dtbs
dtbs: dts/dt.dtb
@:
-dts/dt.dtb: checkdtc u-boot
+dts/dt.dtb: u-boot
$(Q)$(MAKE) $(build)=dts dtbs
quiet_cmd_copy = COPY $@
@@ -1447,12 +1447,6 @@ SYSTEM_MAP = \
System.map: u-boot
@$(call SYSTEM_MAP,$<) > $@
-checkdtc:
- @if test $(call dtc-version) -lt 0104; then \
- echo '*** Your dtc is too old, please upgrade to dtc 1.4 or newer'; \
- false; \
- fi
-
#########################################################################
# ARM relocations should all be R_ARM_RELATIVE (32-bit) or
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index bb64b9c160..fca23b4e64 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -588,6 +588,7 @@ config ARCH_OMAP2PLUS
bool "TI OMAP2+"
select CPU_V7
select SPL_BOARD_INIT if SPL
+ select SPL_STACK_R if SPL
select SUPPORT_SPL
imply FIT
diff --git a/arch/arm/cpu/armv8/fsl-layerscape/soc.c b/arch/arm/cpu/armv8/fsl-layerscape/soc.c
index 6698c0467d..a90ee0afd7 100644
--- a/arch/arm/cpu/armv8/fsl-layerscape/soc.c
+++ b/arch/arm/cpu/armv8/fsl-layerscape/soc.c
@@ -260,8 +260,8 @@ static void erratum_rcw_src(void)
#ifdef CONFIG_SYS_FSL_ERRATUM_A009203
static void erratum_a009203(void)
{
- u8 __iomem *ptr;
#ifdef CONFIG_SYS_I2C
+ u8 __iomem *ptr;
#ifdef I2C1_BASE_ADDR
ptr = (u8 __iomem *)(I2C1_BASE_ADDR + I2C_DEBUG_REG);
@@ -297,7 +297,9 @@ void bypass_smmu(void)
void fsl_lsch3_early_init_f(void)
{
erratum_rcw_src();
+#ifdef CONFIG_FSL_IFC
init_early_memctl_regs(); /* tighten IFC timing */
+#endif
#ifdef CONFIG_SYS_FSL_ERRATUM_A009203
erratum_a009203();
#endif
@@ -323,11 +325,14 @@ int sata_init(void)
{
struct ccsr_ahci __iomem *ccsr_ahci;
+#ifdef CONFIG_SYS_SATA2
ccsr_ahci = (void *)CONFIG_SYS_SATA2;
out_le32(&ccsr_ahci->ppcfg, AHCI_PORT_PHY_1_CFG);
out_le32(&ccsr_ahci->ptc, AHCI_PORT_TRANS_CFG);
out_le32(&ccsr_ahci->axicc, AHCI_PORT_AXICC_CFG);
+#endif
+#ifdef CONFIG_SYS_SATA1
ccsr_ahci = (void *)CONFIG_SYS_SATA1;
out_le32(&ccsr_ahci->ppcfg, AHCI_PORT_PHY_1_CFG);
out_le32(&ccsr_ahci->ptc, AHCI_PORT_TRANS_CFG);
@@ -335,6 +340,7 @@ int sata_init(void)
ahci_init((void __iomem *)CONFIG_SYS_SATA1);
scsi_scan(false);
+#endif
return 0;
}
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 85ce68789a..7c062f0cad 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -41,6 +41,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += \
rk3288-veyron-jerry.dtb \
rk3288-veyron-mickey.dtb \
rk3288-veyron-minnie.dtb \
+ rk3288-vyasa.dtb \
rk3328-evb.dtb \
rk3368-lion.dtb \
rk3368-sheep.dtb \
@@ -205,6 +206,8 @@ dtb-$(CONFIG_ARCH_SNAPDRAGON) += dragonboard410c.dtb
dtb-$(CONFIG_STM32F7) += stm32f746-disco.dtb \
stm32f769-disco.dtb
+dtb-$(CONFIG_STM32H7) += stm32h743i-disco.dtb \
+ stm32h743i-eval.dtb
dtb-$(CONFIG_MACH_SUN4I) += \
sun4i-a10-a1000.dtb \
diff --git a/arch/arm/dts/am3517-evm-u-boot.dtsi b/arch/arm/dts/am3517-evm-u-boot.dtsi
new file mode 100644
index 0000000000..24a67dbd1e
--- /dev/null
+++ b/arch/arm/dts/am3517-evm-u-boot.dtsi
@@ -0,0 +1,12 @@
+/*
+ * Copyright (C) 2017
+ * Logic PD - http://www.logicpd.com
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+/ {
+ chosen {
+ stdout-path = &uart3;
+ };
+};
diff --git a/arch/arm/dts/am3517-evm.dts b/arch/arm/dts/am3517-evm.dts
new file mode 100644
index 0000000000..0e4a125f78
--- /dev/null
+++ b/arch/arm/dts/am3517-evm.dts
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+/dts-v1/;
+
+#include "am3517.dtsi"
+
+/ {
+ model = "TI AM3517 EVM (AM3517/05 TMDSEVM3517)";
+ compatible = "ti,am3517-evm", "ti,am3517", "ti,omap3";
+
+ memory@80000000 {
+ device_type = "memory";
+ reg = <0x80000000 0x10000000>; /* 256 MB */
+ };
+
+ vmmc_fixed: vmmc {
+ compatible = "regulator-fixed";
+ regulator-name = "vmmc_fixed";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+};
+
+&davinci_emac {
+ status = "okay";
+};
+
+&davinci_mdio {
+ status = "okay";
+};
+
+&i2c1 {
+ clock-frequency = <400000>;
+};
+
+&i2c2 {
+ clock-frequency = <400000>;
+};
+
+&i2c3 {
+ clock-frequency = <400000>;
+};
+
+&mmc1 {
+ vmmc-supply = <&vmmc_fixed>;
+ bus-width = <4>;
+};
+
+&mmc2 {
+ status = "disabled";
+};
+
+&mmc3 {
+ status = "disabled";
+};
+
diff --git a/arch/arm/dts/am3517-u-boot.dtsi b/arch/arm/dts/am3517-u-boot.dtsi
new file mode 100644
index 0000000000..219005210d
--- /dev/null
+++ b/arch/arm/dts/am3517-u-boot.dtsi
@@ -0,0 +1,10 @@
+/*
+ * Copyright (C) 2017
+ * Logic PD - http://www.logicpd.com
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+&uart4 {
+ reg-shift = <2>;
+};
diff --git a/arch/arm/dts/am3517.dtsi b/arch/arm/dts/am3517.dtsi
new file mode 100644
index 0000000000..00da3f2c40
--- /dev/null
+++ b/arch/arm/dts/am3517.dtsi
@@ -0,0 +1,107 @@
+/*
+ * Device Tree Source for am3517 SoC
+ *
+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#include "omap3.dtsi"
+
+/ {
+ aliases {
+ serial3 = &uart4;
+ can = &hecc;
+ };
+
+ ocp@68000000 {
+ am35x_otg_hs: am35x_otg_hs@5c040000 {
+ compatible = "ti,omap3-musb";
+ ti,hwmods = "am35x_otg_hs";
+ status = "disabled";
+ reg = <0x5c040000 0x1000>;
+ interrupts = <71>;
+ interrupt-names = "mc";
+ };
+
+ davinci_emac: ethernet@0x5c000000 {
+ compatible = "ti,am3517-emac";
+ ti,hwmods = "davinci_emac";
+ status = "disabled";
+ reg = <0x5c000000 0x30000>;
+ interrupts = <67 68 69 70>;
+ syscon = <&scm_conf>;
+ ti,davinci-ctrl-reg-offset = <0x10000>;
+ ti,davinci-ctrl-mod-reg-offset = <0>;
+ ti,davinci-ctrl-ram-offset = <0x20000>;
+ ti,davinci-ctrl-ram-size = <0x2000>;
+ ti,davinci-rmii-en = /bits/ 8 <1>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ };
+
+ davinci_mdio: ethernet@0x5c030000 {
+ compatible = "ti,davinci_mdio";
+ ti,hwmods = "davinci_mdio";
+ status = "disabled";
+ reg = <0x5c030000 0x1000>;
+ bus_freq = <1000000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ uart4: serial@4809e000 {
+ compatible = "ti,omap3-uart";
+ ti,hwmods = "uart4";
+ status = "disabled";
+ reg = <0x4809e000 0x400>;
+ interrupts = <84>;
+ dmas = <&sdma 55 &sdma 54>;
+ dma-names = "tx", "rx";
+ clock-frequency = <48000000>;
+ };
+
+ omap3_pmx_core2: pinmux@480025d8 {
+ compatible = "ti,omap3-padconf", "pinctrl-single";
+ reg = <0x480025d8 0x24>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #pinctrl-cells = <1>;
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ pinctrl-single,register-width = <16>;
+ pinctrl-single,function-mask = <0xff1f>;
+ };
+
+ hecc: can@5c050000 {
+ compatible = "ti,am3517-hecc";
+ status = "disabled";
+ reg = <0x5c050000 0x80>,
+ <0x5c053000 0x180>,
+ <0x5c052000 0x200>;
+ reg-names = "hecc", "hecc-ram", "mbx";
+ interrupts = <24>;
+ clocks = <&hecc_ck>;
+ };
+ };
+};
+
+&iva {
+ status = "disabled";
+};
+
+&mailbox {
+ status = "disabled";
+};
+
+&mmu_isp {
+ status = "disabled";
+};
+
+&smartreflex_mpu_iva {
+ status = "disabled";
+};
+
+/include/ "am35xx-clocks.dtsi"
+/include/ "omap36xx-am35xx-omap3430es2plus-clocks.dtsi"
diff --git a/arch/arm/dts/am35xx-clocks.dtsi b/arch/arm/dts/am35xx-clocks.dtsi
new file mode 100644
index 0000000000..00dd1f091b
--- /dev/null
+++ b/arch/arm/dts/am35xx-clocks.dtsi
@@ -0,0 +1,128 @@
+/*
+ * Device Tree Source for OMAP3 clock data
+ *
+ * Copyright (C) 2013 Texas Instruments, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+&scm_clocks {
+ emac_ick: emac_ick@32c {
+ #clock-cells = <0>;
+ compatible = "ti,am35xx-gate-clock";
+ clocks = <&ipss_ick>;
+ reg = <0x032c>;
+ ti,bit-shift = <1>;
+ };
+
+ emac_fck: emac_fck@32c {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&rmii_ck>;
+ reg = <0x032c>;
+ ti,bit-shift = <9>;
+ };
+
+ vpfe_ick: vpfe_ick@32c {
+ #clock-cells = <0>;
+ compatible = "ti,am35xx-gate-clock";
+ clocks = <&ipss_ick>;
+ reg = <0x032c>;
+ ti,bit-shift = <2>;
+ };
+
+ vpfe_fck: vpfe_fck@32c {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&pclk_ck>;
+ reg = <0x032c>;
+ ti,bit-shift = <10>;
+ };
+
+ hsotgusb_ick_am35xx: hsotgusb_ick_am35xx@32c {
+ #clock-cells = <0>;
+ compatible = "ti,am35xx-gate-clock";
+ clocks = <&ipss_ick>;
+ reg = <0x032c>;
+ ti,bit-shift = <0>;
+ };
+
+ hsotgusb_fck_am35xx: hsotgusb_fck_am35xx@32c {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&sys_ck>;
+ reg = <0x032c>;
+ ti,bit-shift = <8>;
+ };
+
+ hecc_ck: hecc_ck@32c {
+ #clock-cells = <0>;
+ compatible = "ti,am35xx-gate-clock";
+ clocks = <&sys_ck>;
+ reg = <0x032c>;
+ ti,bit-shift = <3>;
+ };
+};
+&cm_clocks {
+ ipss_ick: ipss_ick@a10 {
+ #clock-cells = <0>;
+ compatible = "ti,am35xx-interface-clock";
+ clocks = <&core_l3_ick>;
+ reg = <0x0a10>;
+ ti,bit-shift = <4>;
+ };
+
+ rmii_ck: rmii_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <50000000>;
+ };
+
+ pclk_ck: pclk_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <27000000>;
+ };
+
+ uart4_ick_am35xx: uart4_ick_am35xx@a10 {
+ #clock-cells = <0>;
+ compatible = "ti,omap3-interface-clock";
+ clocks = <&core_l4_ick>;
+ reg = <0x0a10>;
+ ti,bit-shift = <23>;
+ };
+
+ uart4_fck_am35xx: uart4_fck_am35xx@a00 {
+ #clock-cells = <0>;
+ compatible = "ti,wait-gate-clock";
+ clocks = <&core_48m_fck>;
+ reg = <0x0a00>;
+ ti,bit-shift = <23>;
+ };
+};
+
+&cm_clockdomains {
+ core_l3_clkdm: core_l3_clkdm {
+ compatible = "ti,clockdomain";
+ clocks = <&sdrc_ick>, <&ipss_ick>, <&emac_ick>, <&vpfe_ick>,
+ <&hsotgusb_ick_am35xx>, <&hsotgusb_fck_am35xx>,
+ <&hecc_ck>;
+ };
+
+ core_l4_clkdm: core_l4_clkdm {
+ compatible = "ti,clockdomain";
+ clocks = <&cpefuse_fck>, <&ts_fck>, <&usbtll_fck>,
+ <&usbtll_ick>, <&mmchs3_ick>, <&mmchs3_fck>,
+ <&mmchs2_fck>, <&mmchs1_fck>, <&i2c3_fck>, <&i2c2_fck>,
+ <&i2c1_fck>, <&mcspi4_fck>, <&mcspi3_fck>,
+ <&mcspi2_fck>, <&mcspi1_fck>, <&uart2_fck>,
+ <&uart1_fck>, <&hdq_fck>, <&mmchs2_ick>, <&mmchs1_ick>,
+ <&hdq_ick>, <&mcspi4_ick>, <&mcspi3_ick>,
+ <&mcspi2_ick>, <&mcspi1_ick>, <&i2c3_ick>, <&i2c2_ick>,
+ <&i2c1_ick>, <&uart2_ick>, <&uart1_ick>, <&gpt11_ick>,
+ <&gpt10_ick>, <&mcbsp5_ick>, <&mcbsp1_ick>,
+ <&omapctrl_ick>, <&aes2_ick>, <&sha12_ick>,
+ <&uart4_ick_am35xx>, <&uart4_fck_am35xx>;
+ };
+};
diff --git a/arch/arm/dts/da850-evm-u-boot.dtsi b/arch/arm/dts/da850-evm-u-boot.dtsi
new file mode 100644
index 0000000000..5cc5a81f6f
--- /dev/null
+++ b/arch/arm/dts/da850-evm-u-boot.dtsi
@@ -0,0 +1,23 @@
+/*
+ * da850-evm U-Boot Additions
+ *
+ * Copyright (C) 2017 Logic PD, Inc.
+ * Copyright (C) Adam Ford
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+/ {
+ chosen {
+ stdout-path = &serial2;
+ };
+
+ aliases {
+ i2c0 = &i2c0;
+ spi0 = &spi1;
+ };
+};
+
+&flash {
+ compatible = "m25p64", "spi-flash";
+};
diff --git a/arch/arm/dts/da850-evm.dts b/arch/arm/dts/da850-evm.dts
new file mode 100644
index 0000000000..67e72bc72e
--- /dev/null
+++ b/arch/arm/dts/da850-evm.dts
@@ -0,0 +1,304 @@
+/*
+ * Device Tree for DA850 EVM board
+ *
+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, version 2.
+ */
+/dts-v1/;
+#include "da850.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+ compatible = "ti,da850-evm", "ti,da850";
+ model = "DA850/AM1808/OMAP-L138 EVM";
+
+ soc@1c00000 {
+ pmx_core: pinmux@14120 {
+ status = "okay";
+
+ mcasp0_pins: pinmux_mcasp0_pins {
+ pinctrl-single,bits = <
+ /*
+ * AHCLKX, ACLKX, AFSX, AHCLKR, ACLKR,
+ * AFSR, AMUTE
+ */
+ 0x00 0x11111111 0xffffffff
+ /* AXR11, AXR12 */
+ 0x04 0x00011000 0x000ff000
+ >;
+ };
+ nand_pins: nand_pins {
+ pinctrl-single,bits = <
+ /* EMA_WAIT[0], EMA_OE, EMA_WE, EMA_CS[4], EMA_CS[3] */
+ 0x1c 0x10110110 0xf0ff0ff0
+ /*
+ * EMA_D[0], EMA_D[1], EMA_D[2],
+ * EMA_D[3], EMA_D[4], EMA_D[5],
+ * EMA_D[6], EMA_D[7]
+ */
+ 0x24 0x11111111 0xffffffff
+ /* EMA_A[1], EMA_A[2] */
+ 0x30 0x01100000 0x0ff00000
+ >;
+ };
+ };
+ serial0: serial@42000 {
+ status = "okay";
+ };
+ serial1: serial@10c000 {
+ status = "okay";
+ };
+ serial2: serial@10d000 {
+ status = "okay";
+ };
+ rtc0: rtc@23000 {
+ status = "okay";
+ };
+ i2c0: i2c@22000 {
+ status = "okay";
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins>;
+
+ tps: tps@48 {
+ reg = <0x48>;
+ };
+ tlv320aic3106: tlv320aic3106@18 {
+ #sound-dai-cells = <0>;
+ compatible = "ti,tlv320aic3106";
+ reg = <0x18>;
+ status = "okay";
+
+ /* Regulators */
+ IOVDD-supply = <&vdcdc2_reg>;
+ /* Derived from VBAT: Baseboard 3.3V / 1.8V */
+ AVDD-supply = <&vbat>;
+ DRVDD-supply = <&vbat>;
+ DVDD-supply = <&vbat>;
+ };
+ tca6416: gpio@20 {
+ compatible = "ti,tca6416";
+ reg = <0x20>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+ };
+ wdt: wdt@21000 {
+ status = "okay";
+ };
+ mmc0: mmc@40000 {
+ max-frequency = <50000000>;
+ bus-width = <4>;
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins>;
+ };
+ spi1: spi@30e000 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi1_pins &spi1_cs0_pin>;
+ flash: m25p80@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "m25p64";
+ spi-max-frequency = <30000000>;
+ m25p,fast-read;
+ reg = <0>;
+ partition@0 {
+ label = "U-Boot-SPL";
+ reg = <0x00000000 0x00010000>;
+ read-only;
+ };
+ partition@1 {
+ label = "U-Boot";
+ reg = <0x00010000 0x00080000>;
+ read-only;
+ };
+ partition@2 {
+ label = "U-Boot-Env";
+ reg = <0x00090000 0x00010000>;
+ read-only;
+ };
+ partition@3 {
+ label = "Kernel";
+ reg = <0x000a0000 0x00280000>;
+ };
+ partition@4 {
+ label = "Filesystem";
+ reg = <0x00320000 0x00400000>;
+ };
+ partition@5 {
+ label = "MAC-Address";
+ reg = <0x007f0000 0x00010000>;
+ read-only;
+ };
+ };
+ };
+ mdio: mdio@224000 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&mdio_pins>;
+ bus_freq = <2200000>;
+ };
+ eth0: ethernet@220000 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&mii_pins>;
+ };
+ gpio: gpio@226000 {
+ status = "okay";
+ };
+ };
+ vbat: fixedregulator0 {
+ compatible = "regulator-fixed";
+ regulator-name = "vbat";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-boot-on;
+ };
+
+ sound {
+ compatible = "simple-audio-card";
+ simple-audio-card,name = "DA850/OMAP-L138 EVM";
+ simple-audio-card,widgets =
+ "Line", "Line In",
+ "Line", "Line Out";
+ simple-audio-card,routing =
+ "LINE1L", "Line In",
+ "LINE1R", "Line In",
+ "Line Out", "LLOUT",
+ "Line Out", "RLOUT";
+ simple-audio-card,format = "dsp_b";
+ simple-audio-card,bitclock-master = <&link0_codec>;
+ simple-audio-card,frame-master = <&link0_codec>;
+ simple-audio-card,bitclock-inversion;
+
+ simple-audio-card,cpu {
+ sound-dai = <&mcasp0>;
+ system-clock-frequency = <24576000>;
+ };
+
+ link0_codec: simple-audio-card,codec {
+ sound-dai = <&tlv320aic3106>;
+ system-clock-frequency = <24576000>;
+ };
+ };
+};
+
+/include/ "tps6507x.dtsi"
+
+&tps {
+ vdcdc1_2-supply = <&vbat>;
+ vdcdc3-supply = <&vbat>;
+ vldo1_2-supply = <&vbat>;
+
+ regulators {
+ vdcdc1_reg: regulator@0 {
+ regulator-name = "VDCDC1_3.3V";
+ regulator-min-microvolt = <3150000>;
+ regulator-max-microvolt = <3450000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ vdcdc2_reg: regulator@1 {
+ regulator-name = "VDCDC2_3.3V";
+ regulator-min-microvolt = <1710000>;
+ regulator-max-microvolt = <3450000>;
+ regulator-always-on;
+ regulator-boot-on;
+ ti,defdcdc_default = <1>;
+ };
+
+ vdcdc3_reg: regulator@2 {
+ regulator-name = "VDCDC3_1.2V";
+ regulator-min-microvolt = <950000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-always-on;
+ regulator-boot-on;
+ ti,defdcdc_default = <1>;
+ };
+
+ ldo1_reg: regulator@3 {
+ regulator-name = "LDO1_1.8V";
+ regulator-min-microvolt = <1710000>;
+ regulator-max-microvolt = <1890000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ ldo2_reg: regulator@4 {
+ regulator-name = "LDO2_1.2V";
+ regulator-min-microvolt = <1140000>;
+ regulator-max-microvolt = <1320000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+ };
+};
+
+&mcasp0 {
+ #sound-dai-cells = <0>;
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&mcasp0_pins>;
+
+ op-mode = <0>; /* MCASP_IIS_MODE */
+ tdm-slots = <2>;
+ /* 4 serializer */
+ serial-dir = < /* 0: INACTIVE, 1: TX, 2: RX */
+ 0 0 0 0
+ 0 0 0 0
+ 0 0 0 1
+ 2 0 0 0
+ >;
+ tx-num-evt = <32>;
+ rx-num-evt = <32>;
+};
+
+&edma0 {
+ ti,edma-reserved-slot-ranges = <32 50>;
+};
+
+&edma1 {
+ ti,edma-reserved-slot-ranges = <32 90>;
+};
+
+&aemif {
+ pinctrl-names = "default";
+ pinctrl-0 = <&nand_pins>;
+ status = "ok";
+ cs3 {
+ #address-cells = <2>;
+ #size-cells = <1>;
+ clock-ranges;
+ ranges;
+
+ ti,cs-chipselect = <3>;
+
+ nand@2000000,0 {
+ compatible = "ti,davinci-nand";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0 0x02000000 0x02000000
+ 1 0x00000000 0x00008000>;
+
+ ti,davinci-chipselect = <1>;
+ ti,davinci-mask-ale = <0>;
+ ti,davinci-mask-cle = <0>;
+ ti,davinci-mask-chipsel = <0>;
+ ti,davinci-ecc-mode = "hw";
+ ti,davinci-ecc-bits = <4>;
+ ti,davinci-nand-use-bbt;
+ };
+ };
+};
+
+&vpif {
+ pinctrl-names = "default";
+ pinctrl-0 = <&vpif_capture_pins>, <&vpif_display_pins>;
+ status = "okay";
+};
diff --git a/arch/arm/dts/da850.dtsi b/arch/arm/dts/da850.dtsi
new file mode 100644
index 0000000000..02e2f8f258
--- /dev/null
+++ b/arch/arm/dts/da850.dtsi
@@ -0,0 +1,581 @@
+/*
+ * Copyright 2012 DENX Software Engineering GmbH
+ * Heiko Schocher <hs@denx.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+#include "skeleton.dtsi"
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+ arm {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ intc: interrupt-controller@fffee000 {
+ compatible = "ti,cp-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ ti,intc-size = <101>;
+ reg = <0xfffee000 0x2000>;
+ };
+ };
+
+ aliases {
+ spi0 = &spi0;
+ };
+
+ soc@1c00000 {
+ compatible = "simple-bus";
+ model = "da850";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x0 0x01c00000 0x400000>;
+ interrupt-parent = <&intc>;
+
+ pmx_core: pinmux@14120 {
+ compatible = "pinctrl-single";
+ reg = <0x14120 0x50>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #pinctrl-cells = <2>;
+ pinctrl-single,bit-per-mux;
+ pinctrl-single,register-width = <32>;
+ pinctrl-single,function-mask = <0xf>;
+ status = "disabled";
+
+ serial0_rtscts_pins: pinmux_serial0_rtscts_pins {
+ pinctrl-single,bits = <
+ /* UART0_RTS UART0_CTS */
+ 0x0c 0x22000000 0xff000000
+ >;
+ };
+ serial0_rxtx_pins: pinmux_serial0_rxtx_pins {
+ pinctrl-single,bits = <
+ /* UART0_TXD UART0_RXD */
+ 0x0c 0x00220000 0x00ff0000
+ >;
+ };
+ serial1_rtscts_pins: pinmux_serial1_rtscts_pins {
+ pinctrl-single,bits = <
+ /* UART1_CTS UART1_RTS */
+ 0x00 0x00440000 0x00ff0000
+ >;
+ };
+ serial1_rxtx_pins: pinmux_serial1_rxtx_pins {
+ pinctrl-single,bits = <
+ /* UART1_TXD UART1_RXD */
+ 0x10 0x22000000 0xff000000
+ >;
+ };
+ serial2_rtscts_pins: pinmux_serial2_rtscts_pins {
+ pinctrl-single,bits = <
+ /* UART2_CTS UART2_RTS */
+ 0x00 0x44000000 0xff000000
+ >;
+ };
+ serial2_rxtx_pins: pinmux_serial2_rxtx_pins {
+ pinctrl-single,bits = <
+ /* UART2_TXD UART2_RXD */
+ 0x10 0x00220000 0x00ff0000
+ >;
+ };
+ i2c0_pins: pinmux_i2c0_pins {
+ pinctrl-single,bits = <
+ /* I2C0_SDA,I2C0_SCL */
+ 0x10 0x00002200 0x0000ff00
+ >;
+ };
+ i2c1_pins: pinmux_i2c1_pins {
+ pinctrl-single,bits = <
+ /* I2C1_SDA, I2C1_SCL */
+ 0x10 0x00440000 0x00ff0000
+ >;
+ };
+ mmc0_pins: pinmux_mmc_pins {
+ pinctrl-single,bits = <
+ /* MMCSD0_DAT[3] MMCSD0_DAT[2]
+ * MMCSD0_DAT[1] MMCSD0_DAT[0]
+ * MMCSD0_CMD MMCSD0_CLK
+ */
+ 0x28 0x00222222 0x00ffffff
+ >;
+ };
+ ehrpwm0a_pins: pinmux_ehrpwm0a_pins {
+ pinctrl-single,bits = <
+ /* EPWM0A */
+ 0xc 0x00000002 0x0000000f
+ >;
+ };
+ ehrpwm0b_pins: pinmux_ehrpwm0b_pins {
+ pinctrl-single,bits = <
+ /* EPWM0B */
+ 0xc 0x00000020 0x000000f0
+ >;
+ };
+ ehrpwm1a_pins: pinmux_ehrpwm1a_pins {
+ pinctrl-single,bits = <
+ /* EPWM1A */
+ 0x14 0x00000002 0x0000000f
+ >;
+ };
+ ehrpwm1b_pins: pinmux_ehrpwm1b_pins {
+ pinctrl-single,bits = <
+ /* EPWM1B */
+ 0x14 0x00000020 0x000000f0
+ >;
+ };
+ ecap0_pins: pinmux_ecap0_pins {
+ pinctrl-single,bits = <
+ /* ECAP0_APWM0 */
+ 0x8 0x20000000 0xf0000000
+ >;
+ };
+ ecap1_pins: pinmux_ecap1_pins {
+ pinctrl-single,bits = <
+ /* ECAP1_APWM1 */
+ 0x4 0x40000000 0xf0000000
+ >;
+ };
+ ecap2_pins: pinmux_ecap2_pins {
+ pinctrl-single,bits = <
+ /* ECAP2_APWM2 */
+ 0x4 0x00000004 0x0000000f
+ >;
+ };
+ spi0_pins: pinmux_spi0_pins {
+ pinctrl-single,bits = <
+ /* SIMO, SOMI, CLK */
+ 0xc 0x00001101 0x0000ff0f
+ >;
+ };
+ spi0_cs0_pin: pinmux_spi0_cs0 {
+ pinctrl-single,bits = <
+ /* CS0 */
+ 0x10 0x00000010 0x000000f0
+ >;
+ };
+ spi0_cs3_pin: pinmux_spi0_cs3_pin {
+ pinctrl-single,bits = <
+ /* CS3 */
+ 0xc 0x01000000 0x0f000000
+ >;
+ };
+ spi1_pins: pinmux_spi1_pins {
+ pinctrl-single,bits = <
+ /* SIMO, SOMI, CLK */
+ 0x14 0x00110100 0x00ff0f00
+ >;
+ };
+ spi1_cs0_pin: pinmux_spi1_cs0 {
+ pinctrl-single,bits = <
+ /* CS0 */
+ 0x14 0x00000010 0x000000f0
+ >;
+ };
+ mdio_pins: pinmux_mdio_pins {
+ pinctrl-single,bits = <
+ /* MDIO_CLK, MDIO_D */
+ 0x10 0x00000088 0x000000ff
+ >;
+ };
+ mii_pins: pinmux_mii_pins {
+ pinctrl-single,bits = <
+ /*
+ * MII_TXEN, MII_TXCLK, MII_COL
+ * MII_TXD_3, MII_TXD_2, MII_TXD_1
+ * MII_TXD_0
+ */
+ 0x8 0x88888880 0xfffffff0
+ /*
+ * MII_RXER, MII_CRS, MII_RXCLK
+ * MII_RXDV, MII_RXD_3, MII_RXD_2
+ * MII_RXD_1, MII_RXD_0
+ */
+ 0xc 0x88888888 0xffffffff
+ >;
+ };
+ lcd_pins: pinmux_lcd_pins {
+ pinctrl-single,bits = <
+ /*
+ * LCD_D[2], LCD_D[3], LCD_D[4], LCD_D[5],
+ * LCD_D[6], LCD_D[7]
+ */
+ 0x40 0x22222200 0xffffff00
+ /*
+ * LCD_D[10], LCD_D[11], LCD_D[12], LCD_D[13],
+ * LCD_D[14], LCD_D[15], LCD_D[0], LCD_D[1]
+ */
+ 0x44 0x22222222 0xffffffff
+ /* LCD_D[8], LCD_D[9] */
+ 0x48 0x00000022 0x000000ff
+
+ /* LCD_PCLK */
+ 0x48 0x02000000 0x0f000000
+ /* LCD_AC_ENB_CS, LCD_VSYNC, LCD_HSYNC */
+ 0x4c 0x02000022 0x0f0000ff
+ >;
+ };
+ vpif_capture_pins: vpif_capture_pins {
+ pinctrl-single,bits = <
+ /* VP_DIN[2..7], VP_CLKIN1, VP_CLKIN0 */
+ 0x38 0x11111111 0xffffffff
+ /* VP_DIN[10..15,0..1] */
+ 0x3c 0x11111111 0xffffffff
+ /* VP_DIN[8..9] */
+ 0x40 0x00000011 0x000000ff
+ >;
+ };
+ vpif_display_pins: vpif_display_pins {
+ pinctrl-single,bits = <
+ /* VP_DOUT[2..7] */
+ 0x40 0x11111100 0xffffff00
+ /* VP_DOUT[10..15,0..1] */
+ 0x44 0x11111111 0xffffffff
+ /* VP_DOUT[8..9] */
+ 0x48 0x00000011 0x000000ff
+ /*
+ * VP_CLKOUT3, VP_CLKIN3,
+ * VP_CLKOUT2, VP_CLKIN2
+ */
+ 0x4c 0x00111100 0x00ffff00
+ >;
+ };
+ };
+ prictrl: priority-controller@14110 {
+ compatible = "ti,da850-mstpri";
+ reg = <0x14110 0x0c>;
+ status = "disabled";
+ };
+ cfgchip: chip-controller@1417c {
+ compatible = "ti,da830-cfgchip", "syscon", "simple-mfd";
+ reg = <0x1417c 0x14>;
+
+ usb_phy: usb-phy {
+ compatible = "ti,da830-usb-phy";
+ #phy-cells = <1>;
+ status = "disabled";
+ };
+ };
+ edma0: edma@0 {
+ compatible = "ti,edma3-tpcc";
+ /* eDMA3 CC0: 0x01c0 0000 - 0x01c0 7fff */
+ reg = <0x0 0x8000>;
+ reg-names = "edma3_cc";
+ interrupts = <11 12>;
+ interrupt-names = "edma3_ccint", "edma3_ccerrint";
+ #dma-cells = <2>;
+
+ ti,tptcs = <&edma0_tptc0 7>, <&edma0_tptc1 0>;
+ };
+ edma0_tptc0: tptc@8000 {
+ compatible = "ti,edma3-tptc";
+ reg = <0x8000 0x400>;
+ interrupts = <13>;
+ interrupt-names = "edm3_tcerrint";
+ };
+ edma0_tptc1: tptc@8400 {
+ compatible = "ti,edma3-tptc";
+ reg = <0x8400 0x400>;
+ interrupts = <32>;
+ interrupt-names = "edm3_tcerrint";
+ };
+ edma1: edma@230000 {
+ compatible = "ti,edma3-tpcc";
+ /* eDMA3 CC1: 0x01e3 0000 - 0x01e3 7fff */
+ reg = <0x230000 0x8000>;
+ reg-names = "edma3_cc";
+ interrupts = <93 94>;
+ interrupt-names = "edma3_ccint", "edma3_ccerrint";
+ #dma-cells = <2>;
+
+ ti,tptcs = <&edma1_tptc0 7>;
+ };
+ edma1_tptc0: tptc@238000 {
+ compatible = "ti,edma3-tptc";
+ reg = <0x238000 0x400>;
+ interrupts = <95>;
+ interrupt-names = "edm3_tcerrint";
+ };
+ serial0: serial@42000 {
+ compatible = "ti,da830-uart", "ns16550a";
+ reg = <0x42000 0x100>;
+ reg-io-width = <4>;
+ reg-shift = <2>;
+ interrupts = <25>;
+ status = "disabled";
+ };
+ serial1: serial@10c000 {
+ compatible = "ti,da830-uart", "ns16550a";
+ reg = <0x10c000 0x100>;
+ reg-io-width = <4>;
+ reg-shift = <2>;
+ interrupts = <53>;
+ status = "disabled";
+ };
+ serial2: serial@10d000 {
+ compatible = "ti,da830-uart", "ns16550a";
+ reg = <0x10d000 0x100>;
+ reg-io-width = <4>;
+ reg-shift = <2>;
+ interrupts = <61>;
+ status = "disabled";
+ };
+ rtc0: rtc@23000 {
+ compatible = "ti,da830-rtc";
+ reg = <0x23000 0x1000>;
+ interrupts = <19
+ 19>;
+ status = "disabled";
+ };
+ i2c0: i2c@22000 {
+ compatible = "ti,davinci-i2c";
+ reg = <0x22000 0x1000>;
+ interrupts = <15>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+ i2c1: i2c@228000 {
+ compatible = "ti,davinci-i2c";
+ reg = <0x228000 0x1000>;
+ interrupts = <51>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+ wdt: wdt@21000 {
+ compatible = "ti,davinci-wdt";
+ reg = <0x21000 0x1000>;
+ status = "disabled";
+ };
+ mmc0: mmc@40000 {
+ compatible = "ti,da830-mmc";
+ reg = <0x40000 0x1000>;
+ cap-sd-highspeed;
+ cap-mmc-highspeed;
+ interrupts = <16>;
+ dmas = <&edma0 16 0>, <&edma0 17 0>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+ vpif: video@217000 {
+ compatible = "ti,da850-vpif";
+ reg = <0x217000 0x1000>;
+ interrupts = <92>;
+ status = "disabled";
+
+ /* VPIF capture port */
+ port@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ /* VPIF display port */
+ port@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+ mmc1: mmc@21b000 {
+ compatible = "ti,da830-mmc";
+ reg = <0x21b000 0x1000>;
+ cap-sd-highspeed;
+ cap-mmc-highspeed;
+ interrupts = <72>;
+ dmas = <&edma1 28 0>, <&edma1 29 0>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+ ehrpwm0: pwm@300000 {
+ compatible = "ti,da850-ehrpwm", "ti,am3352-ehrpwm",
+ "ti,am33xx-ehrpwm";
+ #pwm-cells = <3>;
+ reg = <0x300000 0x2000>;
+ status = "disabled";
+ };
+ ehrpwm1: pwm@302000 {
+ compatible = "ti,da850-ehrpwm", "ti,am3352-ehrpwm",
+ "ti,am33xx-ehrpwm";
+ #pwm-cells = <3>;
+ reg = <0x302000 0x2000>;
+ status = "disabled";
+ };
+ ecap0: ecap@306000 {
+ compatible = "ti,da850-ecap", "ti,am3352-ecap",
+ "ti,am33xx-ecap";
+ #pwm-cells = <3>;
+ reg = <0x306000 0x80>;
+ status = "disabled";
+ };
+ ecap1: ecap@307000 {
+ compatible = "ti,da850-ecap", "ti,am3352-ecap",
+ "ti,am33xx-ecap";
+ #pwm-cells = <3>;
+ reg = <0x307000 0x80>;
+ status = "disabled";
+ };
+ ecap2: ecap@308000 {
+ compatible = "ti,da850-ecap", "ti,am3352-ecap",
+ "ti,am33xx-ecap";
+ #pwm-cells = <3>;
+ reg = <0x308000 0x80>;
+ status = "disabled";
+ };
+ spi0: spi@41000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "ti,da830-spi";
+ reg = <0x41000 0x1000>;
+ num-cs = <6>;
+ ti,davinci-spi-intr-line = <1>;
+ interrupts = <20>;
+ dmas = <&edma0 14 0>, <&edma0 15 0>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+ spi1: spi@30e000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "ti,da830-spi";
+ reg = <0x30e000 0x1000>;
+ num-cs = <4>;
+ ti,davinci-spi-intr-line = <1>;
+ interrupts = <56>;
+ dmas = <&edma0 18 0>, <&edma0 19 0>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+ usb0: usb@200000 {
+ compatible = "ti,da830-musb";
+ reg = <0x200000 0x1000>;
+ ranges;
+ interrupts = <58>;
+ interrupt-names = "mc";
+ dr_mode = "otg";
+ phys = <&usb_phy 0>;
+ phy-names = "usb-phy";
+ status = "disabled";
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ dmas = <&cppi41dma 0 0 &cppi41dma 1 0
+ &cppi41dma 2 0 &cppi41dma 3 0
+ &cppi41dma 0 1 &cppi41dma 1 1
+ &cppi41dma 2 1 &cppi41dma 3 1>;
+ dma-names =
+ "rx1", "rx2", "rx3", "rx4",
+ "tx1", "tx2", "tx3", "tx4";
+
+ cppi41dma: dma-controller@201000 {
+ compatible = "ti,da830-cppi41";
+ reg = <0x201000 0x1000
+ 0x202000 0x1000
+ 0x204000 0x4000>;
+ reg-names = "controller",
+ "scheduler", "queuemgr";
+ interrupts = <58>;
+ #dma-cells = <2>;
+ #dma-channels = <4>;
+ status = "okay";
+ };
+ };
+ sata: sata@218000 {
+ compatible = "ti,da850-ahci";
+ reg = <0x218000 0x2000>, <0x22c018 0x4>;
+ interrupts = <67>;
+ status = "disabled";
+ };
+ mdio: mdio@224000 {
+ compatible = "ti,davinci_mdio";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x224000 0x1000>;
+ status = "disabled";
+ };
+ eth0: ethernet@220000 {
+ compatible = "ti,davinci-dm6467-emac";
+ reg = <0x220000 0x4000>;
+ ti,davinci-ctrl-reg-offset = <0x3000>;
+ ti,davinci-ctrl-mod-reg-offset = <0x2000>;
+ ti,davinci-ctrl-ram-offset = <0>;
+ ti,davinci-ctrl-ram-size = <0x2000>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ interrupts = <33
+ 34
+ 35
+ 36
+ >;
+ status = "disabled";
+ };
+ usb1: usb@225000 {
+ compatible = "ti,da830-ohci";
+ reg = <0x225000 0x1000>;
+ interrupts = <59>;
+ phys = <&usb_phy 1>;
+ phy-names = "usb-phy";
+ status = "disabled";
+ };
+ gpio: gpio@226000 {
+ compatible = "ti,dm6441-gpio";
+ gpio-controller;
+ #gpio-cells = <2>;
+ reg = <0x226000 0x1000>;
+ interrupts = <42 IRQ_TYPE_EDGE_BOTH
+ 43 IRQ_TYPE_EDGE_BOTH 44 IRQ_TYPE_EDGE_BOTH
+ 45 IRQ_TYPE_EDGE_BOTH 46 IRQ_TYPE_EDGE_BOTH
+ 47 IRQ_TYPE_EDGE_BOTH 48 IRQ_TYPE_EDGE_BOTH
+ 49 IRQ_TYPE_EDGE_BOTH 50 IRQ_TYPE_EDGE_BOTH>;
+ ti,ngpio = <144>;
+ ti,davinci-gpio-unbanked = <0>;
+ status = "disabled";
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+ pinconf: pin-controller@22c00c {
+ compatible = "ti,da850-pupd";
+ reg = <0x22c00c 0x8>;
+ status = "disabled";
+ };
+
+ mcasp0: mcasp@100000 {
+ compatible = "ti,da830-mcasp-audio";
+ reg = <0x100000 0x2000>,
+ <0x102000 0x400000>;
+ reg-names = "mpu", "dat";
+ interrupts = <54>;
+ interrupt-names = "common";
+ status = "disabled";
+ dmas = <&edma0 1 1>,
+ <&edma0 0 1>;
+ dma-names = "tx", "rx";
+ };
+
+ lcdc: display@213000 {
+ compatible = "ti,da850-tilcdc";
+ reg = <0x213000 0x1000>;
+ interrupts = <52>;
+ max-pixelclock = <37500>;
+ status = "disabled";
+ };
+ };
+ aemif: aemif@68000000 {
+ compatible = "ti,da850-aemif";
+ #address-cells = <2>;
+ #size-cells = <1>;
+
+ reg = <0x68000000 0x00008000>;
+ ranges = <0 0 0x60000000 0x08000000
+ 1 0 0x68000000 0x00008000>;
+ status = "disabled";
+ };
+ memctrl: memory-controller@b0000000 {
+ compatible = "ti,da850-ddr-controller";
+ reg = <0xb0000000 0xe8>;
+ status = "disabled";
+ };
+};
diff --git a/arch/arm/dts/fsl-ls2081a-rdb.dts b/arch/arm/dts/fsl-ls2081a-rdb.dts
index 6489362fc0..aa4aa68c9c 100644
--- a/arch/arm/dts/fsl-ls2081a-rdb.dts
+++ b/arch/arm/dts/fsl-ls2081a-rdb.dts
@@ -41,7 +41,7 @@
bus-num = <0>;
status = "okay";
- qflash0: n25q512a@0 {
+ qflash0: s25fs512s@0 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "spi-flash";
@@ -49,7 +49,7 @@
reg = <0>;
};
- qflash1: n25q512a@1 {
+ qflash1: s25fs512s@1 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "spi-flash";
diff --git a/arch/arm/dts/omap3.dtsi b/arch/arm/dts/omap3.dtsi
index e6f9c9a6dd..56c94729bb 100644
--- a/arch/arm/dts/omap3.dtsi
+++ b/arch/arm/dts/omap3.dtsi
@@ -716,14 +716,12 @@
usbhsohci: ohci@48064400 {
compatible = "ti,ohci-omap3";
reg = <0x48064400 0x400>;
- interrupt-parent = <&intc>;
interrupts = <76>;
};
usbhsehci: ehci@48064800 {
compatible = "ti,ehci-omap";
reg = <0x48064800 0x400>;
- interrupt-parent = <&intc>;
interrupts = <77>;
};
};
@@ -834,7 +832,6 @@
reg-names = "tx",
"rx";
- interrupt-parent = <&intc>;
interrupts = <67>,
<68>;
};
@@ -847,7 +844,6 @@
reg-names = "tx",
"rx";
- interrupt-parent = <&intc>;
interrupts = <69>,
<70>;
};
diff --git a/arch/arm/dts/omap5-u-boot.dtsi b/arch/arm/dts/omap5-u-boot.dtsi
index 2eeed6f4a0..fdaa69297c 100644
--- a/arch/arm/dts/omap5-u-boot.dtsi
+++ b/arch/arm/dts/omap5-u-boot.dtsi
@@ -60,10 +60,30 @@
};
};
+&gpio1 {
+ u-boot,dm-spl;
+};
+
&gpio2 {
u-boot,dm-spl;
};
+&gpio3 {
+ u-boot,dm-spl;
+};
+
+&gpio4 {
+ u-boot,dm-spl;
+};
+
+&gpio5 {
+ u-boot,dm-spl;
+};
+
+&gpio6 {
+ u-boot,dm-spl;
+};
+
&gpio7 {
u-boot,dm-spl;
};
diff --git a/arch/arm/dts/rk3288-vyasa.dts b/arch/arm/dts/rk3288-vyasa.dts
new file mode 100644
index 0000000000..93a9c5ee09
--- /dev/null
+++ b/arch/arm/dts/rk3288-vyasa.dts
@@ -0,0 +1,327 @@
+/*
+ * Copyright (C) 2017 Jagan Teki <jagan@amarulasolutions.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "rk3288.dtsi"
+
+/ {
+ model = "Amarula Vyasa-RK3288";
+ compatible = "amarula,vyasa-rk3288", "rockchip,rk3288";
+
+ chosen {
+ stdout-path = &uart2;
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0 0x80000000>;
+ };
+
+ vcc_sd: sdmmc-regulator {
+ compatible = "regulator-fixed";
+ gpio = <&gpio7 RK_PB3 GPIO_ACTIVE_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc_pwr>;
+ regulator-name = "vcc_sd";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ startup-delay-us = <100000>;
+ vin-supply = <&vcc_io>;
+ };
+
+ vcc_sys: vsys-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc_sys";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+};
+
+&dmc {
+ rockchip,pctl-timing = <0x29a 0xc8 0x1f8 0x42 0x4e 0x4 0xea 0xa
+ 0x5 0x0 0xa 0x7 0x19 0x24 0xa 0x7
+ 0x5 0xa 0x5 0x200 0x5 0x10 0x40 0x0
+ 0x1 0x7 0x7 0x4 0xc 0x43 0x100 0x0
+ 0x5 0x0>;
+ rockchip,phy-timing = <0x48f9aab4 0xea0910 0x1002c200
+ 0xa60 0x40 0x10 0x0>;
+ /* Add a dummy value to cause of-platdata think this is bytes */
+ rockchip,sdram-params = <0x30B25564 0x627 3 666000000 3 9 1>;
+};
+
+&cpu0 {
+ cpu0-supply = <&vdd_cpu>;
+};
+
+&i2c0 {
+ clock-frequency = <400000>;
+ status = "okay";
+
+ rk808: pmic@1b {
+ compatible = "rockchip,rk808";
+ reg = <0x1b>;
+ interrupt-parent = <&gpio0>;
+ interrupts = <RK_PA4 IRQ_TYPE_LEVEL_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pmic_int &global_pwroff>;
+ wakeup-source;
+ rockchip,system-power-controller;
+ #clock-cells = <1>;
+ clock-output-names = "xin32k", "rk808-clkout2";
+
+ vcc1-supply = <&vcc_sys>;
+ vcc2-supply = <&vcc_sys>;
+ vcc3-supply = <&vcc_sys>;
+ vcc4-supply = <&vcc_sys>;
+ vcc6-supply = <&vcc_sys>;
+ vcc7-supply = <&vcc_sys>;
+ vcc8-supply = <&vcc_io>;
+ vcc9-supply = <&vcc_sys>;
+ vcc10-supply = <&vcc_sys>;
+ vcc11-supply = <&vcc_sys>;
+ vcc12-supply = <&vcc_io>;
+
+ regulators {
+ vdd_cpu: vdd_log: DCDC_REG1 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-name = "vdd_log";
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_gpu: DCDC_REG2 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <1250000>;
+ regulator-name = "vdd_gpu";
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1000000>;
+ };
+ };
+
+ vcc_ddr: DCDC_REG3 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-name = "vcc_ddr";
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+
+ vcc_io: DCDC_REG4 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vcc_io";
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <3300000>;
+ };
+ };
+
+ vcca_tp: LDO_REG1 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vcc_tp";
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <3300000>;
+ };
+ };
+
+ vcc_codec: LDO_REG2 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vcc_codec";
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_10: LDO_REG3 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-name = "vdd_10";
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1000000>;
+ };
+ };
+
+ vcc_gps: LDO_REG4 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "vcc_gps";
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ vccio_sd: LDO_REG5 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vccio_sd";
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <3300000>;
+ };
+ };
+
+ vcc10_lcd: LDO_REG6 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-name = "vcc10_lcd";
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ vcc_18: LDO_REG7 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "vcc_18";
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ vcc18_lcd: LDO_REG8 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "vcc18_lcd";
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ vcc33_sd: SWITCH_REG1 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vcc33_sd";
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+
+ vcc_lan: SWITCH_REG2 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vcc_lan";
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+ };
+ };
+};
+
+&sdmmc {
+ u-boot,dm-pre-reloc;
+ status = "okay";
+
+ bus-width = <4>;
+ cap-mmc-highspeed;
+ cap-sd-highspeed;
+ card-detect-delay = <200>;
+ disable-wp;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc_clk>, <&sdmmc_cmd>, <&sdmmc_cd>, <&sdmmc_bus4>;
+ vmmc-supply = <&vcc_sd>;
+ vqmmc-supply = <&vccio_sd>;
+};
+
+&uart2 {
+ u-boot,dm-pre-reloc;
+ status = "okay";
+};
+
+&wdt {
+ status = "okay";
+};
+
+&pinctrl {
+ u-boot,dm-pre-reloc;
+ pmic {
+ pmic_int: pmic-int {
+ rockchip,pins = <RK_GPIO0 4 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
+
+ sdmmc {
+ sdmmc_pwr: sdmmc-pwr {
+ rockchip,pins = <7 11 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+};
diff --git a/arch/arm/dts/rk3368-lion-u-boot.dtsi b/arch/arm/dts/rk3368-lion-u-boot.dtsi
index 6052e8a8d3..a9b7f81c62 100644
--- a/arch/arm/dts/rk3368-lion-u-boot.dtsi
+++ b/arch/arm/dts/rk3368-lion-u-boot.dtsi
@@ -13,6 +13,7 @@
chosen {
stdout-path = "serial0:115200n8";
u-boot,spl-boot-order = &emmc, &sdmmc;
+ tick-timer = "/timer@ff810000";
};
};
@@ -70,24 +71,25 @@
};
&emmc {
- u-boot,dm-pre-reloc;
+ u-boot,dm-spl;
};
&sdmmc {
- u-boot,dm-pre-reloc;
+ u-boot,dm-spl;
};
&spi1 {
- u-boot,dm-pre-reloc;
+ u-boot,dm-spl;
spiflash: w25q32dw@0 {
- u-boot,dm-pre-reloc;
+ u-boot,dm-spl;
};
};
&timer0 {
u-boot,dm-pre-reloc;
clock-frequency = <24000000>;
+ status = "okay";
};
diff --git a/arch/arm/dts/rk3399-puma.dtsi b/arch/arm/dts/rk3399-puma.dtsi
index dd1baea704..a04878e223 100644
--- a/arch/arm/dts/rk3399-puma.dtsi
+++ b/arch/arm/dts/rk3399-puma.dtsi
@@ -89,6 +89,17 @@
};
};
+ usbhub_enable: usbhub_enable {
+ compatible = "regulator-fixed";
+ regulator-name = "usbhub_enable";
+ enable-active-low;
+ gpio = <&gpio4 3 GPIO_ACTIVE_HIGH>;
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
vccadc_ref: vccadc-ref {
compatible = "regulator-fixed";
regulator-name = "vcc1v8_sys";
@@ -514,7 +525,6 @@
};
&dwc3_typec1 {
- rockchip,vbus-gpio = <&gpio4 3 GPIO_ACTIVE_LOW>;
status = "okay";
};
diff --git a/arch/arm/dts/rv1108-evb.dts b/arch/arm/dts/rv1108-evb.dts
index 0128dd8b1d..2b221b6d61 100644
--- a/arch/arm/dts/rv1108-evb.dts
+++ b/arch/arm/dts/rv1108-evb.dts
@@ -20,6 +20,15 @@
chosen {
stdout-path = "serial2:1500000n8";
};
+
+ vcc5v0_otg: vcc5v0-otg-drv {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ regulator-name = "vcc5v0_otg";
+ gpio = <&gpio0 RK_PB0 GPIO_ACTIVE_HIGH>;
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ };
};
&gmac {
@@ -52,3 +61,16 @@
&uart2 {
status = "okay";
};
+
+&usb20_otg {
+ vbus-supply = <&vcc5v0_otg>;
+ status = "okay";
+};
+
+&usb_host_ehci {
+ status = "okay";
+};
+
+&usb_host_ohci {
+ status = "okay";
+};
diff --git a/arch/arm/dts/rv1108.dtsi b/arch/arm/dts/rv1108.dtsi
index 77ca24e7f3..3153dfe658 100644
--- a/arch/arm/dts/rv1108.dtsi
+++ b/arch/arm/dts/rv1108.dtsi
@@ -175,6 +175,30 @@
status = "disabled";
};
+ usb_host_ehci: usb@30140000 {
+ compatible = "generic-ehci";
+ reg = <0x30140000 0x20000>;
+ interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ usb_host_ohci: usb@30160000 {
+ compatible = "generic-ohci";
+ reg = <0x30160000 0x20000>;
+ interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ usb20_otg: usb@30180000 {
+ compatible = "rockchip,rv1108-usb", "rockchip,rk3288-usb",
+ "snps,dwc2";
+ reg = <0x30180000 0x40000>;
+ interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>;
+ hnp-srp-disable;
+ dr_mode = "otg";
+ status = "disabled";
+ };
+
sfc: sfc@301c0000 {
compatible = "rockchip,sfc";
reg = <0x301c0000 0x200>;
diff --git a/arch/arm/dts/stih407-family.dtsi b/arch/arm/dts/stih407-family.dtsi
index af66b53471..6c6de58029 100644
--- a/arch/arm/dts/stih407-family.dtsi
+++ b/arch/arm/dts/stih407-family.dtsi
@@ -563,6 +563,7 @@
clocks = <&clk_s_c0_flexgen CLK_MMC_1>,
<&clk_s_c0_flexgen CLK_RX_ICN_HVA>;
resets = <&softreset STIH407_MMC1_SOFTRESET>;
+ reset-names = "softreset";
bus-width = <4>;
};
@@ -654,7 +655,7 @@
compatible = "snps,dwc3";
reg = <0x09900000 0x100000>;
interrupts = <GIC_SPI 155 IRQ_TYPE_NONE>;
- dr_mode = "host";
+ dr_mode = "peripheral";
phy-names = "usb2-phy", "usb3-phy";
phys = <&usb2_picophy0>,
<&phy_port2 PHY_TYPE_USB3>;
diff --git a/arch/arm/dts/stih410.dtsi b/arch/arm/dts/stih410.dtsi
index f118a9e51c..b59b110989 100644
--- a/arch/arm/dts/stih410.dtsi
+++ b/arch/arm/dts/stih410.dtsi
@@ -83,7 +83,7 @@
};
ohci0: usb@9a03c00 {
- compatible = "st,st-ohci-300x";
+ compatible = "generic-ohci";
reg = <0x9a03c00 0x100>;
interrupts = <GIC_SPI 180 IRQ_TYPE_NONE>;
clocks = <&clk_s_c0_flexgen CLK_TX_ICN_DISP_0>,
@@ -91,6 +91,7 @@
resets = <&powerdown STIH407_USB2_PORT0_POWERDOWN>,
<&softreset STIH407_USB2_PORT0_SOFTRESET>;
reset-names = "power", "softreset";
+
phys = <&usb2_picophy1>;
phy-names = "usb";
@@ -98,7 +99,7 @@
};
ehci0: usb@9a03e00 {
- compatible = "st,st-ehci-300x";
+ compatible = "generic-ehci";
reg = <0x9a03e00 0x100>;
interrupts = <GIC_SPI 151 IRQ_TYPE_NONE>;
pinctrl-names = "default";
@@ -115,7 +116,7 @@
};
ohci1: usb@9a83c00 {
- compatible = "st,st-ohci-300x";
+ compatible = "generic-ohci";
reg = <0x9a83c00 0x100>;
interrupts = <GIC_SPI 181 IRQ_TYPE_NONE>;
clocks = <&clk_s_c0_flexgen CLK_TX_ICN_DISP_0>,
@@ -123,6 +124,7 @@
resets = <&powerdown STIH407_USB2_PORT1_POWERDOWN>,
<&softreset STIH407_USB2_PORT1_SOFTRESET>;
reset-names = "power", "softreset";
+
phys = <&usb2_picophy2>;
phy-names = "usb";
@@ -130,7 +132,7 @@
};
ehci1: usb@9a83e00 {
- compatible = "st,st-ehci-300x";
+ compatible = "generic-ehci";
reg = <0x9a83e00 0x100>;
interrupts = <GIC_SPI 153 IRQ_TYPE_NONE>;
pinctrl-names = "default";
@@ -140,6 +142,7 @@
resets = <&powerdown STIH407_USB2_PORT1_POWERDOWN>,
<&softreset STIH407_USB2_PORT1_SOFTRESET>;
reset-names = "power", "softreset";
+
phys = <&usb2_picophy2>;
phy-names = "usb";
diff --git a/arch/arm/dts/stm32h7-u-boot.dtsi b/arch/arm/dts/stm32h7-u-boot.dtsi
new file mode 100644
index 0000000000..2525035da1
--- /dev/null
+++ b/arch/arm/dts/stm32h7-u-boot.dtsi
@@ -0,0 +1,88 @@
+/{
+ clocks {
+ u-boot,dm-pre-reloc;
+ };
+
+ soc {
+ u-boot,dm-pre-reloc;
+ pin-controller {
+ u-boot,dm-pre-reloc;
+ };
+ };
+};
+
+&clk_hse {
+ u-boot,dm-pre-reloc;
+};
+
+&clk_lse {
+ u-boot,dm-pre-reloc;
+};
+
+&clk_i2s {
+ u-boot,dm-pre-reloc;
+};
+
+&pwrcfg {
+ u-boot,dm-pre-reloc;
+};
+
+&rcc {
+ u-boot,dm-pre-reloc;
+};
+
+&fmc {
+ u-boot,dm-pre-reloc;
+};
+
+&clk_hsi {
+ u-boot,dm-pre-reloc;
+};
+
+&clk_csi {
+ u-boot,dm-pre-reloc;
+};
+
+&gpioa {
+ u-boot,dm-pre-reloc;
+};
+
+&gpiob {
+ u-boot,dm-pre-reloc;
+};
+
+&gpioc {
+ u-boot,dm-pre-reloc;
+};
+
+&gpiod {
+ u-boot,dm-pre-reloc;
+};
+
+&gpioe {
+ u-boot,dm-pre-reloc;
+};
+
+&gpiof {
+ u-boot,dm-pre-reloc;
+};
+
+&gpiog {
+ u-boot,dm-pre-reloc;
+};
+
+&gpioh {
+ u-boot,dm-pre-reloc;
+};
+
+&gpioi {
+ u-boot,dm-pre-reloc;
+};
+
+&gpioj {
+ u-boot,dm-pre-reloc;
+};
+
+&gpiok {
+ u-boot,dm-pre-reloc;
+};
diff --git a/arch/arm/dts/stm32h743-pinctrl.dtsi b/arch/arm/dts/stm32h743-pinctrl.dtsi
new file mode 100644
index 0000000000..d3e11d53ab
--- /dev/null
+++ b/arch/arm/dts/stm32h743-pinctrl.dtsi
@@ -0,0 +1,249 @@
+/*
+ * Copyright 2017 - Alexandre Torgue <alexandre.torgue@st.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <dt-bindings/pinctrl/stm32h7-pinfunc.h>
+
+/ {
+ soc {
+ pin-controller {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "st,stm32h743-pinctrl";
+ ranges = <0 0x58020000 0x3000>;
+ pins-are-numbered;
+
+ gpioa: gpio@58020000 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ compatible = "st,stm32-gpio";
+ reg = <0x0 0x400>;
+ clocks = <&rcc GPIOA_CK>;
+ st,bank-name = "GPIOA";
+ };
+
+ gpiob: gpio@58020400 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ compatible = "st,stm32-gpio";
+ reg = <0x400 0x400>;
+ clocks = <&rcc GPIOB_CK>;
+ st,bank-name = "GPIOB";
+ };
+
+ gpioc: gpio@58020800 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ compatible = "st,stm32-gpio";
+ reg = <0x800 0x400>;
+ clocks = <&rcc GPIOC_CK>;
+ st,bank-name = "GPIOC";
+ };
+
+ gpiod: gpio@58020c00 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ compatible = "st,stm32-gpio";
+ reg = <0xc00 0x400>;
+ clocks = <&rcc GPIOD_CK>;
+ st,bank-name = "GPIOD";
+ };
+
+ gpioe: gpio@58021000 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ compatible = "st,stm32-gpio";
+ reg = <0x1000 0x400>;
+ clocks = <&rcc GPIOE_CK>;
+ st,bank-name = "GPIOE";
+ };
+
+ gpiof: gpio@58021400 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ compatible = "st,stm32-gpio";
+ reg = <0x1400 0x400>;
+ clocks = <&rcc GPIOF_CK>;
+ st,bank-name = "GPIOF";
+ };
+
+ gpiog: gpio@58021800 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ compatible = "st,stm32-gpio";
+ reg = <0x1800 0x400>;
+ clocks = <&rcc GPIOG_CK>;
+ st,bank-name = "GPIOG";
+ };
+
+ gpioh: gpio@58021c00 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ compatible = "st,stm32-gpio";
+ reg = <0x1c00 0x400>;
+ clocks = <&rcc GPIOH_CK>;
+ st,bank-name = "GPIOH";
+ };
+
+ gpioi: gpio@58022000 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ compatible = "st,stm32-gpio";
+ reg = <0x2000 0x400>;
+ clocks = <&rcc GPIOI_CK>;
+ st,bank-name = "GPIOI";
+ };
+
+ gpioj: gpio@58022400 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ compatible = "st,stm32-gpio";
+ reg = <0x2400 0x400>;
+ clocks = <&rcc GPIOJ_CK>;
+ st,bank-name = "GPIOJ";
+ };
+
+ gpiok: gpio@58022800 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ compatible = "st,stm32-gpio";
+ reg = <0x2800 0x400>;
+ clocks = <&rcc GPIOK_CK>;
+ st,bank-name = "GPIOK";
+ };
+
+ usart1_pins: usart1@0 {
+ pins1 {
+ pinmux = <STM32H7_PB14_FUNC_USART1_TX>;
+ bias-disable;
+ drive-push-pull;
+ slew-rate = <0>;
+ };
+ pins2 {
+ pinmux = <STM32H7_PB15_FUNC_USART1_RX>;
+ bias-disable;
+ };
+ };
+
+ usart2_pins: usart2@0 {
+ pins1 {
+ pinmux = <STM32H7_PD5_FUNC_USART2_TX>;
+ bias-disable;
+ drive-push-pull;
+ slew-rate = <0>;
+ };
+ pins2 {
+ pinmux = <STM32H7_PD6_FUNC_USART2_RX>;
+ bias-disable;
+ };
+ };
+
+ fmc_pins: fmc@0 {
+ pins {
+ pinmux = <STM32H7_PD0_FUNC_FMC_D2_FMC_DA2>,
+ <STM32H7_PD1_FUNC_FMC_D3_FMC_DA3>,
+ <STM32H7_PD8_FUNC_FMC_D13_FMC_DA13>,
+ <STM32H7_PD9_FUNC_FMC_D14_FMC_DA14>,
+ <STM32H7_PD10_FUNC_FMC_D15_FMC_DA15>,
+ <STM32H7_PD14_FUNC_FMC_D0_FMC_DA0>,
+ <STM32H7_PD15_FUNC_FMC_D1_FMC_DA1>,
+
+ <STM32H7_PE0_FUNC_FMC_NBL0>,
+ <STM32H7_PE1_FUNC_FMC_NBL1>,
+ <STM32H7_PE7_FUNC_FMC_D4_FMC_DA4>,
+ <STM32H7_PE8_FUNC_FMC_D5_FMC_DA5>,
+ <STM32H7_PE9_FUNC_FMC_D6_FMC_DA6>,
+ <STM32H7_PE10_FUNC_FMC_D7_FMC_DA7>,
+ <STM32H7_PE11_FUNC_FMC_D8_FMC_DA8>,
+ <STM32H7_PE12_FUNC_FMC_D9_FMC_DA9>,
+ <STM32H7_PE13_FUNC_FMC_D10_FMC_DA10>,
+ <STM32H7_PE14_FUNC_FMC_D11_FMC_DA11>,
+ <STM32H7_PE15_FUNC_FMC_D12_FMC_DA12>,
+
+ <STM32H7_PF0_FUNC_FMC_A0>,
+ <STM32H7_PF1_FUNC_FMC_A1>,
+ <STM32H7_PF2_FUNC_FMC_A2>,
+ <STM32H7_PF3_FUNC_FMC_A3>,
+ <STM32H7_PF4_FUNC_FMC_A4>,
+ <STM32H7_PF5_FUNC_FMC_A5>,
+ <STM32H7_PF11_FUNC_FMC_SDNRAS>,
+ <STM32H7_PF12_FUNC_FMC_A6>,
+ <STM32H7_PF13_FUNC_FMC_A7>,
+ <STM32H7_PF14_FUNC_FMC_A8>,
+ <STM32H7_PF15_FUNC_FMC_A9>,
+
+ <STM32H7_PG0_FUNC_FMC_A10>,
+ <STM32H7_PG1_FUNC_FMC_A11>,
+ <STM32H7_PG2_FUNC_FMC_A12>,
+ <STM32H7_PG4_FUNC_FMC_A14_FMC_BA0>,
+ <STM32H7_PG5_FUNC_FMC_A15_FMC_BA1>,
+ <STM32H7_PG8_FUNC_FMC_SDCLK>,
+ <STM32H7_PG15_FUNC_FMC_SDNCAS>,
+
+ <STM32H7_PH5_FUNC_FMC_SDNWE>,
+ <STM32H7_PH6_FUNC_FMC_SDNE1>,
+ <STM32H7_PH7_FUNC_FMC_SDCKE1>,
+ <STM32H7_PH8_FUNC_FMC_D16>,
+ <STM32H7_PH9_FUNC_FMC_D17>,
+ <STM32H7_PH10_FUNC_FMC_D18>,
+ <STM32H7_PH11_FUNC_FMC_D19>,
+ <STM32H7_PH12_FUNC_FMC_D20>,
+ <STM32H7_PH13_FUNC_FMC_D21>,
+ <STM32H7_PH14_FUNC_FMC_D22>,
+ <STM32H7_PH15_FUNC_FMC_D23>,
+
+ <STM32H7_PI0_FUNC_FMC_D24>,
+ <STM32H7_PI1_FUNC_FMC_D25>,
+ <STM32H7_PI2_FUNC_FMC_D26>,
+ <STM32H7_PI3_FUNC_FMC_D27>,
+ <STM32H7_PI4_FUNC_FMC_NBL2>,
+ <STM32H7_PI5_FUNC_FMC_NBL3>,
+ <STM32H7_PI6_FUNC_FMC_D28>,
+ <STM32H7_PI7_FUNC_FMC_D29>,
+ <STM32H7_PI9_FUNC_FMC_D30>,
+ <STM32H7_PI10_FUNC_FMC_D31>;
+
+ slew-rate = <3>;
+ };
+ };
+ };
+ };
+};
diff --git a/arch/arm/dts/stm32h743.dtsi b/arch/arm/dts/stm32h743.dtsi
new file mode 100644
index 0000000000..16e93089d7
--- /dev/null
+++ b/arch/arm/dts/stm32h743.dtsi
@@ -0,0 +1,129 @@
+/*
+ * Copyright 2017 - Alexandre Torgue <alexandre.torgue@st.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "skeleton.dtsi"
+#include "armv7-m.dtsi"
+#include <dt-bindings/clock/stm32h7-clks.h>
+
+/ {
+ clocks {
+ clk_hse: clk-hse {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <25000000>;
+ };
+
+ clk_lse: clk-lse {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <32768>;
+ };
+
+ clk_i2s: i2s_ckin {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <0>;
+ };
+ };
+
+ soc {
+ rcc: rcc@58024400 {
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ compatible = "st,stm32h743-rcc", "st,stm32-rcc";
+ reg = <0x58024400 0x400>;
+ clocks = <&clk_hse>, <&clk_lse>, <&clk_i2s>, <&clk_hsi>, <&clk_csi>;
+ st,syscfg = <&pwrcfg>;
+ };
+
+ usart1: serial@40011000 {
+ compatible = "st,stm32h7-usart", "st,stm32h7-uart";
+ reg = <0x40011000 0x400>;
+ interrupts = <37>;
+ status = "disabled";
+ clocks = <&rcc USART1_CK>;
+ };
+
+ usart2: serial@40004400 {
+ compatible = "st,stm32h7-usart", "st,stm32h7-uart";
+ reg = <0x40004400 0x400>;
+ interrupts = <38>;
+ status = "disabled";
+ clocks = <&rcc USART2_CK>;
+ };
+
+ timer5: timer@40000c00 {
+ compatible = "st,stm32-timer";
+ reg = <0x40000c00 0x400>;
+ interrupts = <50>;
+ clocks = <&rcc TIM5_CK>;
+ };
+
+ pwrcfg: power-config@58024800 {
+ compatible = "syscon";
+ reg = <0x58024800 0x400>;
+ };
+
+ fmc: fmc@52004000 {
+ compatible = "st,stm32h7-fmc";
+ reg = <0x52004000 0x1000>;
+ clocks = <&rcc FMC_CK>;
+ };
+
+ clk_hsi: clk-hsi {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <64000000>;
+ };
+
+ clk_csi: clk-csi {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <4000000>;
+ };
+ };
+};
+
+&systick {
+ clock-frequency = <250000000>;
+ status = "okay";
+};
diff --git a/arch/arm/dts/stm32h743i-disco.dts b/arch/arm/dts/stm32h743i-disco.dts
new file mode 100644
index 0000000000..bef7e90f20
--- /dev/null
+++ b/arch/arm/dts/stm32h743i-disco.dts
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2017 - Patrice Chotard <patrice.chotard@st.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "stm32h743.dtsi"
+#include "stm32h743-pinctrl.dtsi"
+#include <dt-bindings/memory/stm32-sdram.h>
+
+/ {
+ model = "STMicroelectronics STM32H743i-Discovery board";
+ compatible = "st,stm32h743i-disco", "st,stm32h743";
+
+ chosen {
+ bootargs = "root=/dev/ram";
+ stdout-path = "serial0:115200n8";
+ };
+
+ memory {
+ reg = <0xd0000000 0x2000000>;
+ };
+
+ aliases {
+ serial0 = &usart2;
+ gpio0 = &gpioa;
+ gpio1 = &gpiob;
+ gpio2 = &gpioc;
+ gpio3 = &gpiod;
+ gpio4 = &gpioe;
+ gpio5 = &gpiof;
+ gpio6 = &gpiog;
+ gpio7 = &gpioh;
+ gpio8 = &gpioi;
+ gpio9 = &gpioj;
+ gpio10 = &gpiok;
+ };
+};
+
+&usart2 {
+ pinctrl-0 = <&usart2_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&fmc {
+ pinctrl-0 = <&fmc_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+
+ /*
+ * Memory configuration from sdram datasheet IS42S32800G-6BLI
+ * firsct bank is bank@0
+ * second bank is bank@1
+ */
+ bank1: bank@1 {
+ st,sdram-control = /bits/ 8 <NO_COL_9 NO_ROW_12 MWIDTH_32 BANKS_4
+ CAS_2 SDCLK_3 RD_BURST_EN RD_PIPE_DL_0>;
+ st,sdram-timing = /bits/ 8 <TMRD_1 TXSR_1 TRAS_1 TRC_6 TRP_2
+ TWR_1 TRCD_1>;
+ st,sdram-refcount = <1539>;
+ };
+};
diff --git a/arch/arm/dts/stm32h743i-eval.dts b/arch/arm/dts/stm32h743i-eval.dts
new file mode 100644
index 0000000000..0e01ce51ab
--- /dev/null
+++ b/arch/arm/dts/stm32h743i-eval.dts
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2017 - Alexandre Torgue <alexandre.torgue@st.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "stm32h743.dtsi"
+#include "stm32h743-pinctrl.dtsi"
+#include <dt-bindings/memory/stm32-sdram.h>
+
+/ {
+ model = "STMicroelectronics STM32H743i-EVAL board";
+ compatible = "st,stm32h743i-eval", "st,stm32h743";
+
+ chosen {
+ bootargs = "root=/dev/ram";
+ stdout-path = "serial0:115200n8";
+ };
+
+ memory {
+ reg = <0xd0000000 0x2000000>;
+ };
+
+ aliases {
+ serial0 = &usart1;
+ gpio0 = &gpioa;
+ gpio1 = &gpiob;
+ gpio2 = &gpioc;
+ gpio3 = &gpiod;
+ gpio4 = &gpioe;
+ gpio5 = &gpiof;
+ gpio6 = &gpiog;
+ gpio7 = &gpioh;
+ gpio8 = &gpioi;
+ gpio9 = &gpioj;
+ gpio10 = &gpiok;
+ };
+};
+
+&usart1 {
+ pinctrl-0 = <&usart1_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&fmc {
+ pinctrl-0 = <&fmc_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+
+ /*
+ * Memory configuration from sdram datasheet IS42S32800G-6BLI
+ * firsct bank is bank@0
+ * second bank is bank@1
+ */
+ bank2: bank@1 {
+ st,sdram-control = /bits/ 8 <NO_COL_9 NO_ROW_12 MWIDTH_32 BANKS_4
+ CAS_2 SDCLK_3 RD_BURST_EN RD_PIPE_DL_0>;
+ st,sdram-timing = /bits/ 8 <TMRD_1 TXSR_1 TRAS_1 TRC_6 TRP_2
+ TWR_1 TRCD_1>;
+ st,sdram-refcount = <1539>;
+ };
+};
diff --git a/arch/arm/dts/tps6507x.dtsi b/arch/arm/dts/tps6507x.dtsi
new file mode 100644
index 0000000000..4c326e591e
--- /dev/null
+++ b/arch/arm/dts/tps6507x.dtsi
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*
+ * Integrated Power Management Chip
+ * http://www.ti.com/lit/ds/symlink/tps65070.pdf
+ */
+
+&tps {
+ compatible = "ti,tps6507x";
+
+ regulators {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ vdcdc1_reg: regulator@0 {
+ reg = <0>;
+ regulator-compatible = "VDCDC1";
+ };
+
+ vdcdc2_reg: regulator@1 {
+ reg = <1>;
+ regulator-compatible = "VDCDC2";
+ };
+
+ vdcdc3_reg: regulator@2 {
+ reg = <2>;
+ regulator-compatible = "VDCDC3";
+ };
+
+ ldo1_reg: regulator@3 {
+ reg = <3>;
+ regulator-compatible = "LDO1";
+ };
+
+ ldo2_reg: regulator@4 {
+ reg = <4>;
+ regulator-compatible = "LDO2";
+ };
+
+ };
+};
diff --git a/arch/arm/include/asm/arch-fsl-layerscape/cpu.h b/arch/arm/include/asm/arch-fsl-layerscape/cpu.h
index a0dac86bab..4d7992465a 100644
--- a/arch/arm/include/asm/arch-fsl-layerscape/cpu.h
+++ b/arch/arm/include/asm/arch-fsl-layerscape/cpu.h
@@ -106,6 +106,7 @@ static struct mm_region early_map[] = {
{ CONFIG_SYS_FSL_QSPI_BASE1, CONFIG_SYS_FSL_QSPI_BASE1,
CONFIG_SYS_FSL_QSPI_SIZE1,
PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_NON_SHARE},
+#ifdef CONFIG_FSL_IFC
/* For IFC Region #1, only the first 4MB is cache-enabled */
{ CONFIG_SYS_FSL_IFC_BASE1, CONFIG_SYS_FSL_IFC_BASE1,
CONFIG_SYS_FSL_IFC_SIZE1_1,
@@ -120,6 +121,7 @@ static struct mm_region early_map[] = {
CONFIG_SYS_FSL_IFC_SIZE1,
PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE
},
+#endif
{ CONFIG_SYS_FSL_DRAM_BASE1, CONFIG_SYS_FSL_DRAM_BASE1,
CONFIG_SYS_FSL_DRAM_SIZE1,
#if defined(CONFIG_SPL) && !defined(CONFIG_SPL_BUILD)
@@ -129,11 +131,13 @@ static struct mm_region early_map[] = {
#endif
PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS
},
+#ifdef CONFIG_FSL_IFC
/* Map IFC region #2 up to CONFIG_SYS_FLASH_BASE for NAND boot */
{ CONFIG_SYS_FSL_IFC_BASE2, CONFIG_SYS_FSL_IFC_BASE2,
CONFIG_SYS_FLASH_BASE - CONFIG_SYS_FSL_IFC_BASE2,
PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE
},
+#endif
{ CONFIG_SYS_FSL_DCSR_BASE, CONFIG_SYS_FSL_DCSR_BASE,
CONFIG_SYS_FSL_DCSR_SIZE,
PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
@@ -163,10 +167,12 @@ static struct mm_region early_map[] = {
CONFIG_SYS_FSL_QSPI_SIZE,
PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE
},
+#ifdef CONFIG_FSL_IFC
{ CONFIG_SYS_FSL_IFC_BASE, CONFIG_SYS_FSL_IFC_BASE,
CONFIG_SYS_FSL_IFC_SIZE,
PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE
},
+#endif
{ CONFIG_SYS_FSL_DRAM_BASE1, CONFIG_SYS_FSL_DRAM_BASE1,
CONFIG_SYS_FSL_DRAM_SIZE1,
#if defined(CONFIG_SPL) && !defined(CONFIG_SPL_BUILD)
@@ -211,11 +217,13 @@ static struct mm_region final_map[] = {
PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
},
+#ifdef CONFIG_FSL_IFC
{ CONFIG_SYS_FSL_IFC_BASE2, CONFIG_SYS_FSL_IFC_BASE2,
CONFIG_SYS_FSL_IFC_SIZE2,
PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
},
+#endif
{ CONFIG_SYS_FSL_DCSR_BASE, CONFIG_SYS_FSL_DCSR_BASE,
CONFIG_SYS_FSL_DCSR_SIZE,
PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
@@ -310,10 +318,12 @@ static struct mm_region final_map[] = {
PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
},
+#ifdef CONFIG_FSL_IFC
{ CONFIG_SYS_FSL_IFC_BASE, CONFIG_SYS_FSL_IFC_BASE,
CONFIG_SYS_FSL_IFC_SIZE,
PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE
},
+#endif
{ CONFIG_SYS_FSL_DRAM_BASE1, CONFIG_SYS_FSL_DRAM_BASE1,
CONFIG_SYS_FSL_DRAM_SIZE1,
PTE_BLOCK_MEMTYPE(MT_NORMAL) |
diff --git a/arch/arm/include/asm/arch-mx6/sys_proto.h b/arch/arm/include/asm/arch-mx6/sys_proto.h
index 14f5d948c9..ba73943260 100644
--- a/arch/arm/include/asm/arch-mx6/sys_proto.h
+++ b/arch/arm/include/asm/arch-mx6/sys_proto.h
@@ -6,3 +6,10 @@
*/
#include <asm/mach-imx/sys_proto.h>
+
+#define USBPHY_PWD 0x00000000
+
+#define USBPHY_PWD_RXPWDRX (1 << 20) /* receiver block power down */
+
+#define is_usbotg_phy_active(void) (!(readl(USB_PHY0_BASE_ADDR + USBPHY_PWD) & \
+ USBPHY_PWD_RXPWDRX))
diff --git a/arch/arm/include/asm/arch-mx7/clock.h b/arch/arm/include/asm/arch-mx7/clock.h
index 688d2361df..3b115ad57c 100644
--- a/arch/arm/include/asm/arch-mx7/clock.h
+++ b/arch/arm/include/asm/arch-mx7/clock.h
@@ -318,9 +318,9 @@ struct clk_root_map {
};
enum enet_freq {
- ENET_25MHz,
- ENET_50MHz,
- ENET_125MHz,
+ ENET_25MHZ,
+ ENET_50MHZ,
+ ENET_125MHZ,
};
u32 get_root_clk(enum clk_root_index clock_id);
diff --git a/arch/arm/include/asm/arch-rockchip/grf_rk322x.h b/arch/arm/include/asm/arch-rockchip/grf_rk322x.h
index 26071c8ec8..c0c0d84cf1 100644
--- a/arch/arm/include/asm/arch-rockchip/grf_rk322x.h
+++ b/arch/arm/include/asm/arch-rockchip/grf_rk322x.h
@@ -54,6 +54,32 @@ struct rk322x_grf {
unsigned int os_reg[8];
unsigned int reserved9[(0x604 - 0x5e4) / 4 - 1];
unsigned int ddrc_stat;
+ unsigned int reserved10[(0x680 - 0x604) / 4 - 1];
+ unsigned int sig_detect_con[2];
+ unsigned int reserved11[(0x690 - 0x684) / 4 - 1];
+ unsigned int sig_detect_status[2];
+ unsigned int reserved12[(0x6a0 - 0x694) / 4 - 1];
+ unsigned int sig_detect_clr[2];
+ unsigned int reserved13[(0x6b0 - 0x6a4) / 4 - 1];
+ unsigned int emmc_det;
+ unsigned int reserved14[(0x700 - 0x6b0) / 4 - 1];
+ unsigned int host0_con[3];
+ unsigned int reserved15;
+ unsigned int host1_con[3];
+ unsigned int reserved16;
+ unsigned int host2_con[3];
+ unsigned int reserved17[(0x760 - 0x728) / 4 - 1];
+ unsigned int usbphy0_con[27];
+ unsigned int reserved18[(0x800 - 0x7c8) / 4 - 1];
+ unsigned int usbphy1_con[27];
+ unsigned int reserved19[(0x880 - 0x868) / 4 - 1];
+ unsigned int otg_con0;
+ unsigned int uoc_status0;
+ unsigned int reserved20[(0x900 - 0x884) / 4 - 1];
+ unsigned int mac_con[2];
+ unsigned int reserved21[(0xb00 - 0x904) / 4 - 1];
+ unsigned int macphy_con[4];
+ unsigned int macphy_status;
};
check_member(rk322x_grf, ddrc_stat, 0x604);
@@ -516,4 +542,10 @@ enum {
CON_IOMUX_PWM0SEL_SHIFT = 0,
CON_IOMUX_PWM0SEL_MASK = 1 << CON_IOMUX_PWM0SEL_SHIFT,
};
+
+/* GRF_MACPHY_CON0 */
+enum {
+ MACPHY_CFG_ENABLE_SHIFT = 0,
+ MACPHY_CFG_ENABLE_MASK = 1 << MACPHY_CFG_ENABLE_SHIFT,
+};
#endif
diff --git a/arch/arm/include/asm/arch-stih410/sys_proto.h b/arch/arm/include/asm/arch-stih410/sys_proto.h
new file mode 100644
index 0000000000..5c40d3b0a4
--- /dev/null
+++ b/arch/arm/include/asm/arch-stih410/sys_proto.h
@@ -0,0 +1,11 @@
+/*
+ * Copyright (c) 2017
+ * Patrice Chotard <patrice.chotard@st.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _ASM_ARCH_SYS_PROTO_H
+#define _ASM_ARCH_SYS_PROTO_H
+
+#endif /* _ASM_ARCH_SYS_PROTO_H */
diff --git a/arch/arm/include/asm/arch-stm32h7/gpio.h b/arch/arm/include/asm/arch-stm32h7/gpio.h
new file mode 100644
index 0000000000..450784cb21
--- /dev/null
+++ b/arch/arm/include/asm/arch-stm32h7/gpio.h
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) STMicroelectronics SA 2017
+ * Author(s): Patrice CHOTARD, <patrice.chotard@st.com> for STMicroelectronics.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _STM32_GPIO_H_
+#define _STM32_GPIO_H_
+#include <asm/gpio.h>
+
+enum stm32_gpio_port {
+ STM32_GPIO_PORT_A = 0,
+ STM32_GPIO_PORT_B,
+ STM32_GPIO_PORT_C,
+ STM32_GPIO_PORT_D,
+ STM32_GPIO_PORT_E,
+ STM32_GPIO_PORT_F,
+ STM32_GPIO_PORT_G,
+ STM32_GPIO_PORT_H,
+ STM32_GPIO_PORT_I
+};
+
+enum stm32_gpio_pin {
+ STM32_GPIO_PIN_0 = 0,
+ STM32_GPIO_PIN_1,
+ STM32_GPIO_PIN_2,
+ STM32_GPIO_PIN_3,
+ STM32_GPIO_PIN_4,
+ STM32_GPIO_PIN_5,
+ STM32_GPIO_PIN_6,
+ STM32_GPIO_PIN_7,
+ STM32_GPIO_PIN_8,
+ STM32_GPIO_PIN_9,
+ STM32_GPIO_PIN_10,
+ STM32_GPIO_PIN_11,
+ STM32_GPIO_PIN_12,
+ STM32_GPIO_PIN_13,
+ STM32_GPIO_PIN_14,
+ STM32_GPIO_PIN_15
+};
+
+enum stm32_gpio_mode {
+ STM32_GPIO_MODE_IN = 0,
+ STM32_GPIO_MODE_OUT,
+ STM32_GPIO_MODE_AF,
+ STM32_GPIO_MODE_AN
+};
+
+enum stm32_gpio_otype {
+ STM32_GPIO_OTYPE_PP = 0,
+ STM32_GPIO_OTYPE_OD
+};
+
+enum stm32_gpio_speed {
+ STM32_GPIO_SPEED_2M = 0,
+ STM32_GPIO_SPEED_25M,
+ STM32_GPIO_SPEED_50M,
+ STM32_GPIO_SPEED_100M
+};
+
+enum stm32_gpio_pupd {
+ STM32_GPIO_PUPD_NO = 0,
+ STM32_GPIO_PUPD_UP,
+ STM32_GPIO_PUPD_DOWN
+};
+
+enum stm32_gpio_af {
+ STM32_GPIO_AF0 = 0,
+ STM32_GPIO_AF1,
+ STM32_GPIO_AF2,
+ STM32_GPIO_AF3,
+ STM32_GPIO_AF4,
+ STM32_GPIO_AF5,
+ STM32_GPIO_AF6,
+ STM32_GPIO_AF7,
+ STM32_GPIO_AF8,
+ STM32_GPIO_AF9,
+ STM32_GPIO_AF10,
+ STM32_GPIO_AF11,
+ STM32_GPIO_AF12,
+ STM32_GPIO_AF13,
+ STM32_GPIO_AF14,
+ STM32_GPIO_AF15
+};
+
+struct stm32_gpio_dsc {
+ enum stm32_gpio_port port;
+ enum stm32_gpio_pin pin;
+};
+
+struct stm32_gpio_ctl {
+ enum stm32_gpio_mode mode;
+ enum stm32_gpio_otype otype;
+ enum stm32_gpio_speed speed;
+ enum stm32_gpio_pupd pupd;
+ enum stm32_gpio_af af;
+};
+
+struct stm32_gpio_regs {
+ u32 moder; /* GPIO port mode */
+ u32 otyper; /* GPIO port output type */
+ u32 ospeedr; /* GPIO port output speed */
+ u32 pupdr; /* GPIO port pull-up/pull-down */
+ u32 idr; /* GPIO port input data */
+ u32 odr; /* GPIO port output data */
+ u32 bsrr; /* GPIO port bit set/reset */
+ u32 lckr; /* GPIO port configuration lock */
+ u32 afr[2]; /* GPIO alternate function */
+};
+
+struct stm32_gpio_priv {
+ struct stm32_gpio_regs *regs;
+};
+
+static inline unsigned stm32_gpio_to_port(unsigned gpio)
+{
+ return gpio / 16;
+}
+
+static inline unsigned stm32_gpio_to_pin(unsigned gpio)
+{
+ return gpio % 16;
+}
+
+#endif /* _STM32_GPIO_H_ */
diff --git a/arch/arm/include/asm/arch-stm32h7/stm32.h b/arch/arm/include/asm/arch-stm32h7/stm32.h
new file mode 100644
index 0000000000..9ff1f13735
--- /dev/null
+++ b/arch/arm/include/asm/arch-stm32h7/stm32.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) STMicroelectronics SA 2017
+ * Author(s): Patrice CHOTARD, <patrice.chotard@st.com> for STMicroelectronics.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _ASM_ARCH_HARDWARE_H
+#define _ASM_ARCH_HARDWARE_H
+
+/*
+ * This empty files is needed to not break compilation
+ * Some common drivers to STM32F4/F7 and H7 include a stm32.h file
+ * Some cleanup need to be done to communalize all the following
+ * stm32.h files:
+ *
+ * arch/arm/include/asm/arch-stm32f1/stm32.h
+ * arch/arm/include/asm/arch-stm32f4/stm32.h
+ * arch/arm/include/asm/arch-stm32f7/stm32.h
+ */
+#endif /* _ASM_ARCH_HARDWARE_H */
diff --git a/arch/arm/mach-imx/mx7/clock.c b/arch/arm/mach-imx/mx7/clock.c
index 2cfde46a55..8150faa1a3 100644
--- a/arch/arm/mach-imx/mx7/clock.c
+++ b/arch/arm/mach-imx/mx7/clock.c
@@ -966,15 +966,15 @@ int set_clk_enet(enum enet_freq type)
clock_enable(CCGR_ENET2, 0);
switch (type) {
- case ENET_125MHz:
+ case ENET_125MHZ:
enet1_ref = ENET1_REF_CLK_ROOT_FROM_PLL_ENET_MAIN_125M_CLK;
enet2_ref = ENET2_REF_CLK_ROOT_FROM_PLL_ENET_MAIN_125M_CLK;
break;
- case ENET_50MHz:
+ case ENET_50MHZ:
enet1_ref = ENET1_REF_CLK_ROOT_FROM_PLL_ENET_MAIN_50M_CLK;
enet2_ref = ENET2_REF_CLK_ROOT_FROM_PLL_ENET_MAIN_50M_CLK;
break;
- case ENET_25MHz:
+ case ENET_25MHZ:
enet1_ref = ENET1_REF_CLK_ROOT_FROM_PLL_ENET_MAIN_25M_CLK;
enet2_ref = ENET2_REF_CLK_ROOT_FROM_PLL_ENET_MAIN_25M_CLK;
break;
diff --git a/arch/arm/mach-imx/spl.c b/arch/arm/mach-imx/spl.c
index 258578ac25..5944f99482 100644
--- a/arch/arm/mach-imx/spl.c
+++ b/arch/arm/mach-imx/spl.c
@@ -14,6 +14,7 @@
#include <asm/spl.h>
#include <spl.h>
#include <asm/mach-imx/hab.h>
+#include <g_dnl.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -31,6 +32,18 @@ u32 spl_boot_device(void)
if (((bmode >> 24) & 0x03) == 0x01) /* Serial Downloader */
return BOOT_DEVICE_BOARD;
+ /*
+ * The above method does not detect that the boot ROM used
+ * serial downloader in case the boot ROM decided to use the
+ * serial downloader as a fall back (primary boot source failed).
+ *
+ * Infer that the boot ROM used the USB serial downloader by
+ * checking whether the USB PHY is currently active... This
+ * assumes that SPL did not (yet) initialize the USB PHY...
+ */
+ if (is_usbotg_phy_active())
+ return BOOT_DEVICE_BOARD;
+
/* BOOT_CFG1[7:4] - see IMX6DQRM Table 8-8 */
switch ((reg & IMX6_BMODE_MASK) >> IMX6_BMODE_SHIFT) {
/* EIM: See 8.5.1, Table 8-9 */
@@ -82,6 +95,15 @@ u32 spl_boot_device(void)
}
return BOOT_DEVICE_NONE;
}
+
+#ifdef CONFIG_SPL_USB_GADGET_SUPPORT
+int g_dnl_bind_fixup(struct usb_device_descriptor *dev, const char *name)
+{
+ put_unaligned(CONFIG_G_DNL_PRODUCT_NUM + 0xfff, &dev->idProduct);
+
+ return 0;
+}
+#endif
#endif
#if defined(CONFIG_SPL_MMC_SUPPORT)
diff --git a/arch/arm/mach-mvebu/cpu.c b/arch/arm/mach-mvebu/cpu.c
index 14457317ce..74a63dd656 100644
--- a/arch/arm/mach-mvebu/cpu.c
+++ b/arch/arm/mach-mvebu/cpu.c
@@ -62,6 +62,11 @@ int mvebu_soc_family(void)
case SOC_88F6820_ID:
case SOC_88F6828_ID:
return MVEBU_SOC_A38X;
+
+ case SOC_98DX3236_ID:
+ case SOC_98DX3336_ID:
+ case SOC_98DX4251_ID:
+ return MVEBU_SOC_MSYS;
}
return MVEBU_SOC_UNKNOWN;
@@ -107,13 +112,15 @@ static const struct sar_freq_modes sar_freq_tab[] = {
#elif defined(CONFIG_ARMADA_38X)
/* SAR frequency values for Armada 38x */
static const struct sar_freq_modes sar_freq_tab[] = {
- { 0x0, 0x0, 666, 333, 333 },
- { 0x2, 0x0, 800, 400, 400 },
- { 0x4, 0x0, 1066, 533, 533 },
- { 0x6, 0x0, 1200, 600, 600 },
- { 0x8, 0x0, 1332, 666, 666 },
- { 0xc, 0x0, 1600, 800, 800 },
- { 0xff, 0xff, 0, 0, 0 } /* 0xff marks end of array */
+ { 0x0, 0x0, 666, 333, 333 },
+ { 0x2, 0x0, 800, 400, 400 },
+ { 0x4, 0x0, 1066, 533, 533 },
+ { 0x6, 0x0, 1200, 600, 600 },
+ { 0x8, 0x0, 1332, 666, 666 },
+ { 0xc, 0x0, 1600, 800, 800 },
+ { 0x10, 0x0, 1866, 933, 933 },
+ { 0x13, 0x0, 2000, 1000, 933 },
+ { 0xff, 0xff, 0, 0, 0 } /* 0xff marks end of array */
};
#else
/* SAR frequency values for Armada XP */
@@ -208,6 +215,15 @@ int print_cpuinfo(void)
case SOC_88F6828_ID:
puts("MV88F6828-");
break;
+ case SOC_98DX3236_ID:
+ puts("98DX3236-");
+ break;
+ case SOC_98DX3336_ID:
+ puts("98DX3336-");
+ break;
+ case SOC_98DX4251_ID:
+ puts("98DX4251-");
+ break;
default:
puts("Unknown-");
break;
diff --git a/arch/arm/mach-mvebu/dram.c b/arch/arm/mach-mvebu/dram.c
index e3f304c366..e634905618 100644
--- a/arch/arm/mach-mvebu/dram.c
+++ b/arch/arm/mach-mvebu/dram.c
@@ -179,11 +179,11 @@ static void dram_ecc_scrubbing(void)
reg_write(REG_SDRAM_CONFIG_ADDR, temp);
for (cs = 0; cs < CONFIG_NR_DRAM_BANKS; cs++) {
- size = mvebu_sdram_bs(cs) - 1;
+ size = mvebu_sdram_bs(cs);
if (size == 0)
continue;
- total = (u64)size + 1;
+ total = (u64)size;
total_mem += (u32)(total / (1 << 30));
start_addr = 0;
mv_xor_init2(cs);
@@ -194,7 +194,7 @@ static void dram_ecc_scrubbing(void)
size -= start_addr;
}
- mv_xor_mem_init(SCRB_XOR_CHAN, start_addr, size,
+ mv_xor_mem_init(SCRB_XOR_CHAN, start_addr, size - 1,
SCRUB_MAGIC, SCRUB_MAGIC);
/* Wait for previous transfer completion */
@@ -216,6 +216,35 @@ static int ecc_enabled(void)
return 0;
}
+
+/* Return the width of the DRAM bus, or 0 for unknown. */
+static int bus_width(void)
+{
+ int full_width = 0;
+
+ if (reg_read(REG_SDRAM_CONFIG_ADDR) & (1 << REG_SDRAM_CONFIG_WIDTH_OFFS))
+ full_width = 1;
+
+ switch (mvebu_soc_family()) {
+ case MVEBU_SOC_AXP:
+ return full_width ? 64 : 32;
+ break;
+ case MVEBU_SOC_A375:
+ case MVEBU_SOC_A38X:
+ case MVEBU_SOC_MSYS:
+ return full_width ? 32 : 16;
+ default:
+ return 0;
+ }
+}
+
+static int cycle_mode(void)
+{
+ int val = reg_read(REG_DUNIT_CTRL_LOW_ADDR);
+
+ return (val >> REG_DUNIT_CTRL_LOW_2T_OFFS) & REG_DUNIT_CTRL_LOW_2T_MASK;
+}
+
#else
static void dram_ecc_scrubbing(void)
{
@@ -295,10 +324,26 @@ int dram_init_banksize(void)
void board_add_ram_info(int use_default)
{
struct sar_freq_modes sar_freq;
+ int mode;
+ int width;
get_sar_freq(&sar_freq);
printf(" (%d MHz, ", sar_freq.d_clk);
+ width = bus_width();
+ if (width)
+ printf("%d-bit, ", width);
+
+ mode = cycle_mode();
+ /* Mode 0 = Single cycle
+ * Mode 1 = Two cycles (2T)
+ * Mode 2 = Three cycles (3T)
+ */
+ if (mode == 1)
+ printf("2T, ");
+ if (mode == 2)
+ printf("3T, ");
+
if (ecc_enabled())
printf("ECC");
else
diff --git a/arch/arm/mach-mvebu/include/mach/config.h b/arch/arm/mach-mvebu/include/mach/config.h
index 2dc9b1dea3..cfd0952470 100644
--- a/arch/arm/mach-mvebu/include/mach/config.h
+++ b/arch/arm/mach-mvebu/include/mach/config.h
@@ -76,9 +76,6 @@
*/
#ifdef CONFIG_CMD_NET
#define CONFIG_MII /* expose smi ove miiphy interface */
-#if !defined(CONFIG_ARMADA_375)
-#define CONFIG_MVNETA /* Enable Marvell Gbe Controller Driver */
-#endif
#define CONFIG_ENV_OVERWRITE /* ethaddr can be reprogrammed */
#define CONFIG_ARP_TIMEOUT 200
#define CONFIG_NET_RETRY_COUNT 50
diff --git a/arch/arm/mach-mvebu/include/mach/cpu.h b/arch/arm/mach-mvebu/include/mach/cpu.h
index d241eea956..b67b77ae0d 100644
--- a/arch/arm/mach-mvebu/include/mach/cpu.h
+++ b/arch/arm/mach-mvebu/include/mach/cpu.h
@@ -65,6 +65,7 @@ enum {
MVEBU_SOC_AXP,
MVEBU_SOC_A375,
MVEBU_SOC_A38X,
+ MVEBU_SOC_MSYS,
MVEBU_SOC_UNKNOWN,
};
diff --git a/arch/arm/mach-mvebu/include/mach/soc.h b/arch/arm/mach-mvebu/include/mach/soc.h
index 0900e4008c..1d302761f0 100644
--- a/arch/arm/mach-mvebu/include/mach/soc.h
+++ b/arch/arm/mach-mvebu/include/mach/soc.h
@@ -18,6 +18,9 @@
#define SOC_88F6810_ID 0x6810
#define SOC_88F6820_ID 0x6820
#define SOC_88F6828_ID 0x6828
+#define SOC_98DX3236_ID 0xf410
+#define SOC_98DX3336_ID 0xf400
+#define SOC_98DX4251_ID 0xfc00
/* A375 revisions */
#define MV_88F67XX_A0_ID 0x3
@@ -139,6 +142,7 @@
#define BOOT_DEV_SEL_MASK (0x3f << BOOT_DEV_SEL_OFFS)
#define BOOT_FROM_UART 0x28
+#define BOOT_FROM_UART_ALT 0x3f
#define BOOT_FROM_SPI 0x32
#define BOOT_FROM_MMC 0x30
#define BOOT_FROM_MMC_ALT 0x31
diff --git a/arch/arm/mach-mvebu/spl.c b/arch/arm/mach-mvebu/spl.c
index 3cf02a54ce..a72a769f7c 100644
--- a/arch/arm/mach-mvebu/spl.c
+++ b/arch/arm/mach-mvebu/spl.c
@@ -42,6 +42,9 @@ static u32 get_boot_device(void)
return BOOT_DEVICE_MMC1;
#endif
case BOOT_FROM_UART:
+#ifdef BOOT_FROM_UART_ALT
+ case BOOT_FROM_UART_ALT:
+#endif
return BOOT_DEVICE_UART;
case BOOT_FROM_SPI:
default:
diff --git a/arch/arm/mach-omap2/am33xx/mux.c b/arch/arm/mach-omap2/am33xx/mux.c
index 2ded47228d..aad3ec8556 100644
--- a/arch/arm/mach-omap2/am33xx/mux.c
+++ b/arch/arm/mach-omap2/am33xx/mux.c
@@ -31,3 +31,17 @@ void configure_module_pin_mux(struct module_pin_mux *mod_pin_mux)
for (i = 0; mod_pin_mux[i].reg_offset != -1; i++)
MUX_CFG(mod_pin_mux[i].val, mod_pin_mux[i].reg_offset);
}
+
+/*
+ * provide a default over-writable definition
+*/
+void __weak set_uart_mux_conf(void)
+{
+}
+
+/*
+* provide a default over-writable definition
+*/
+void __weak set_mux_conf_regs(void)
+{
+}
diff --git a/arch/arm/mach-omap2/omap3/Kconfig b/arch/arm/mach-omap2/omap3/Kconfig
index 11f5f058b9..4dbf9a27da 100644
--- a/arch/arm/mach-omap2/omap3/Kconfig
+++ b/arch/arm/mach-omap2/omap3/Kconfig
@@ -22,6 +22,11 @@ choice
config TARGET_AM3517_EVM
bool "AM3517 EVM"
+ select DM
+ select DM_SERIAL
+ select DM_GPIO
+ select DM_I2C
+ select DM_MMC
config TARGET_MT_VENTOUX
bool "TeeJet Mt.Ventoux"
diff --git a/arch/arm/mach-omap2/sec-common.c b/arch/arm/mach-omap2/sec-common.c
index 52e1785b4a..2630e7d316 100644
--- a/arch/arm/mach-omap2/sec-common.c
+++ b/arch/arm/mach-omap2/sec-common.c
@@ -41,6 +41,9 @@
#define PPA_SERV_HAL_SETUP_EMIF_FW_REGION (PPA_HAL_SERVICES_START_INDEX + 26)
#define PPA_SERV_HAL_LOCK_EMIF_FW (PPA_HAL_SERVICES_START_INDEX + 27)
+/* Offset of header size if image is signed as ISW */
+#define HEADER_SIZE_OFFSET (0x6D)
+
int tee_loaded = 0;
/* Argument for PPA_SERV_HAL_TEE_LOAD_MASTER */
@@ -125,6 +128,9 @@ int secure_boot_verify_image(void **image, size_t *size)
}
*size = sig_addr - cert_addr; /* Subtract out the signature size */
+ /* Subtract header if present */
+ if (strncmp((char *)sig_addr, "CERT_ISW_", 9) == 0)
+ *size = ((u32 *)*image)[HEADER_SIZE_OFFSET];
cert_size = *size;
/* Check if image load address is 32-bit aligned */
diff --git a/arch/arm/mach-rockchip/rk322x-board.c b/arch/arm/mach-rockchip/rk322x-board.c
index c0ac2e9b56..dcd8cf805f 100644
--- a/arch/arm/mach-rockchip/rk322x-board.c
+++ b/arch/arm/mach-rockchip/rk322x-board.c
@@ -7,6 +7,7 @@
#include <clk.h>
#include <dm.h>
#include <ram.h>
+#include <syscon.h>
#include <asm/io.h>
#include <asm/arch/clock.h>
#include <asm/arch/periph.h>
@@ -67,6 +68,14 @@ int board_init(void)
CON_IOMUX_UART2SEL_MASK,
CON_IOMUX_UART2SEL_21 << CON_IOMUX_UART2SEL_SHIFT);
+ /*
+ * The integrated macphy is enabled by default, disable it
+ * for saving power consuming.
+ */
+ rk_clrsetreg(&grf->macphy_con[0],
+ MACPHY_CFG_ENABLE_MASK,
+ 0 << MACPHY_CFG_ENABLE_SHIFT);
+
return 0;
}
@@ -136,3 +145,17 @@ int board_usb_cleanup(int index, enum usb_init_type init)
return 0;
}
#endif
+
+#if defined(CONFIG_USB_FUNCTION_FASTBOOT)
+int fb_set_reboot_flag(void)
+{
+ struct rk322x_grf *grf;
+
+ printf("Setting reboot to fastboot flag ...\n");
+ grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
+ /* Set boot mode to fastboot */
+ writel(BOOT_FASTBOOT, &grf->os_reg[0]);
+
+ return 0;
+}
+#endif
diff --git a/arch/arm/mach-rockchip/rk3288/Kconfig b/arch/arm/mach-rockchip/rk3288/Kconfig
index 53cc9a0dcd..4ad2940069 100644
--- a/arch/arm/mach-rockchip/rk3288/Kconfig
+++ b/arch/arm/mach-rockchip/rk3288/Kconfig
@@ -84,6 +84,15 @@ config TARGET_POPMETAL_RK3288
2GB DDR3. Expansion connectors provide access to I2C, SPI, UART,
GPIOs and display interface.
+config TARGET_VYASA_RK3288
+ bool "Vyasa-RK3288"
+ select BOARD_LATE_INIT
+ help
+ Vyasa is a RK3288-based development board with 2 USB ports,
+ HDMI, VGA, micro-SD card, audio, WiFi and Gigabit Ethernet, It
+ also includes on-board eMMC and 2GB of SDRAM. Expansion connectors
+ provide access to display pins, I2C, SPI, UART and GPIOs.
+
config TARGET_ROCK2
bool "Radxa Rock 2"
select BOARD_LATE_INIT
@@ -129,6 +138,8 @@ config SPL_LIBGENERIC_SUPPORT
config SPL_SERIAL_SUPPORT
default y
+source "board/amarula/vyasa-rk3288/Kconfig"
+
source "board/chipspark/popmetal_rk3288/Kconfig"
source "board/firefly/firefly-rk3288/Kconfig"
diff --git a/arch/arm/mach-rockchip/rk3399-board-spl.c b/arch/arm/mach-rockchip/rk3399-board-spl.c
index d6bf74f7ad..3406156447 100644
--- a/arch/arm/mach-rockchip/rk3399-board-spl.c
+++ b/arch/arm/mach-rockchip/rk3399-board-spl.c
@@ -5,19 +5,17 @@
*/
#include <common.h>
-#include <debug_uart.h>
-#include <dm.h>
-#include <ram.h>
-#include <spl.h>
-#include <asm/gpio.h>
-#include <asm/io.h>
#include <asm/arch/clock.h>
+#include <asm/arch/grf_rk3399.h>
#include <asm/arch/hardware.h>
#include <asm/arch/periph.h>
-#include <asm/arch/sdram.h>
-#include <asm/arch/timer.h>
+#include <asm/io.h>
+#include <debug_uart.h>
+#include <dm.h>
#include <dm/pinctrl.h>
-#include <power/regulator.h>
+#include <ram.h>
+#include <spl.h>
+#include <syscon.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -53,7 +51,6 @@ void secure_timer_init(void)
void board_debug_uart_init(void)
{
-#include <asm/arch/grf_rk3399.h>
#define GRF_BASE 0xff770000
struct rk3399_grf_regs * const grf = (void *)GRF_BASE;
@@ -80,13 +77,12 @@ void board_debug_uart_init(void)
#endif
}
-#define GRF_EMMCCORE_CON11 0xff77f02c
-#define SGRF_DDR_RGN_CON16 0xff330040
-#define SGRF_SLV_SECURE_CON4 0xff33e3d0
void board_init_f(ulong dummy)
{
struct udevice *pinctrl;
struct udevice *dev;
+ struct rk3399_pmusgrf_regs *sgrf;
+ struct rk3399_grf_regs *grf;
int ret;
#define EARLY_UART
@@ -103,9 +99,6 @@ void board_init_f(ulong dummy)
printascii("U-Boot SPL board init");
#endif
- /* Emmc clock generator: disable the clock multipilier */
- rk_clrreg(GRF_EMMCCORE_CON11, 0x0ff);
-
ret = spl_early_init();
if (ret) {
debug("spl_early_init() failed: %d\n", ret);
@@ -121,8 +114,13 @@ void board_init_f(ulong dummy)
* driver, which tries to DMA from/to the stack (likely)
* located in this range.
*/
- rk_clrsetreg(SGRF_DDR_RGN_CON16, 0x1FF, 0);
- rk_clrreg(SGRF_SLV_SECURE_CON4, 0x2000);
+ sgrf = syscon_get_first_range(ROCKCHIP_SYSCON_PMUSGRF);
+ rk_clrsetreg(&sgrf->ddr_rgn_con[16], 0x1ff, 0);
+ rk_clrreg(&sgrf->slv_secure_con4, 0x2000);
+
+ /* eMMC clock generator: disable the clock multipilier */
+ grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
+ rk_clrreg(&grf->emmccore_con[11], 0x0ff);
secure_timer_init();
diff --git a/arch/arm/mach-rockchip/rk3399/sdram_rk3399.c b/arch/arm/mach-rockchip/rk3399/sdram_rk3399.c
index 63342ab5c9..5ed4b03837 100644
--- a/arch/arm/mach-rockchip/rk3399/sdram_rk3399.c
+++ b/arch/arm/mach-rockchip/rk3399/sdram_rk3399.c
@@ -1115,7 +1115,7 @@ static int conv_of_platdata(struct udevice *dev)
int ret;
ret = regmap_init_mem_platdata(dev, dtplat->reg,
- ARRAY_SIZE(dtplat->reg) / 4,
+ ARRAY_SIZE(dtplat->reg) / 2,
&plat->map);
if (ret)
return ret;
diff --git a/arch/arm/mach-socfpga/misc_gen5.c b/arch/arm/mach-socfpga/misc_gen5.c
index 2f1da740fb..91ddb79f73 100644
--- a/arch/arm/mach-socfpga/misc_gen5.c
+++ b/arch/arm/mach-socfpga/misc_gen5.c
@@ -144,7 +144,7 @@ static const struct {
const u16 pn;
const char *name;
const char *var;
-} const socfpga_fpga_model[] = {
+} socfpga_fpga_model[] = {
/* Cyclone V E */
{ 0x2b15, "Cyclone V, E/A2", "cv_e_a2" },
{ 0x2b05, "Cyclone V, E/A4", "cv_e_a4" },
diff --git a/arch/arm/mach-stm32/Kconfig b/arch/arm/mach-stm32/Kconfig
index 947ce5f1ce..b618b60795 100644
--- a/arch/arm/mach-stm32/Kconfig
+++ b/arch/arm/mach-stm32/Kconfig
@@ -25,7 +25,24 @@ config STM32F7
select SPL_SYS_MALLOC_SIMPLE
select SPL_XIP_SUPPORT
+config STM32H7
+ bool "stm32h7 family"
+ select CLK
+ select DM_GPIO
+ select DM_RESET
+ select MISC
+ select PINCTRL
+ select PINCTRL_STM32
+ select RAM
+ select REGMAP
+ select STM32_SDRAM
+ select STM32_RCC
+ select STM32_RESET
+ select STM32X7_SERIAL
+ select SYSCON
+
source "arch/arm/mach-stm32/stm32f4/Kconfig"
source "arch/arm/mach-stm32/stm32f7/Kconfig"
+source "arch/arm/mach-stm32/stm32h7/Kconfig"
endif
diff --git a/arch/arm/mach-stm32/Makefile b/arch/arm/mach-stm32/Makefile
index 6b7694471f..0f5ac37168 100644
--- a/arch/arm/mach-stm32/Makefile
+++ b/arch/arm/mach-stm32/Makefile
@@ -7,3 +7,4 @@
obj-$(CONFIG_STM32F4) += stm32f4/
obj-$(CONFIG_STM32F7) += stm32f7/
+obj-$(CONFIG_STM32H7) += stm32h7/
diff --git a/arch/arm/mach-stm32/stm32h7/Kconfig b/arch/arm/mach-stm32/stm32h7/Kconfig
new file mode 100644
index 0000000000..55e6217950
--- /dev/null
+++ b/arch/arm/mach-stm32/stm32h7/Kconfig
@@ -0,0 +1,12 @@
+if STM32H7
+
+config TARGET_STM32H743_DISCO
+ bool "STM32H743 Discovery board"
+
+config TARGET_STM32H743_EVAL
+ bool "STM32H743 Evaluation board"
+
+source "board/st/stm32h743-eval/Kconfig"
+source "board/st/stm32h743-disco/Kconfig"
+
+endif
diff --git a/arch/arm/mach-stm32/stm32h7/Makefile b/arch/arm/mach-stm32/stm32h7/Makefile
new file mode 100644
index 0000000000..97f92f74ca
--- /dev/null
+++ b/arch/arm/mach-stm32/stm32h7/Makefile
@@ -0,0 +1,8 @@
+#
+# Copyright (c) 2017
+# Patrice Chotard <patrice.chotard@st.com>
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+obj-y += soc.o
diff --git a/arch/arm/mach-stm32/stm32h7/soc.c b/arch/arm/mach-stm32/stm32h7/soc.c
new file mode 100644
index 0000000000..a65fab6d2e
--- /dev/null
+++ b/arch/arm/mach-stm32/stm32h7/soc.c
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) STMicroelectronics SA 2017
+ * Author(s): Patrice CHOTARD, <patrice.chotard@st.com> for STMicroelectronics.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/armv7m_mpu.h>
+
+u32 get_cpu_rev(void)
+{
+ return 0;
+}
+
+int arch_cpu_init(void)
+{
+ int i;
+
+ struct mpu_region_config stm32_region_config[] = {
+ /*
+ * Make all 4GB cacheable & executable. We are overriding it
+ * with next region for any requirement. e.g. below region1,
+ * 2 etc.
+ * In other words, the area not coming in following
+ * regions configuration is the one configured here in region_0
+ * (cacheable & executable).
+ */
+ { 0x00000000, REGION_0, XN_DIS, PRIV_RW_USR_RW,
+ O_I_WB_RD_WR_ALLOC, REGION_4GB },
+
+ /* Code area, executable & strongly ordered */
+ { 0xD0000000, REGION_1, XN_EN, PRIV_RW_USR_RW,
+ STRONG_ORDER, REGION_8MB },
+
+ /* Device area in all H7 : Not executable */
+ { 0x40000000, REGION_2, XN_EN, PRIV_RW_USR_RW,
+ DEVICE_NON_SHARED, REGION_512MB },
+
+ /*
+ * Armv7m fixed configuration: strongly ordered & not
+ * executable, not cacheable
+ */
+ { 0xE0000000, REGION_4, XN_EN, PRIV_RW_USR_RW,
+ STRONG_ORDER, REGION_512MB },
+ };
+
+ disable_mpu();
+ for (i = 0; i < ARRAY_SIZE(stm32_region_config); i++)
+ mpu_config(&stm32_region_config[i]);
+ enable_mpu();
+
+ return 0;
+}
+
+void s_init(void)
+{
+}
diff --git a/arch/arm/mach-uniphier/Kconfig b/arch/arm/mach-uniphier/Kconfig
index ee22112412..c8b5ab4d32 100644
--- a/arch/arm/mach-uniphier/Kconfig
+++ b/arch/arm/mach-uniphier/Kconfig
@@ -12,18 +12,14 @@ config ARCH_UNIPHIER_32BIT
choice
prompt "UniPhier SoC select"
- default ARCH_UNIPHIER_PRO4
+ default ARCH_UNIPHIER_V8_MULTI
config ARCH_UNIPHIER_LD4_SLD8
bool "UniPhier LD4/sLD8 SoCs"
select ARCH_UNIPHIER_32BIT
-config ARCH_UNIPHIER_PRO4
- bool "UniPhier Pro4 SoC"
- select ARCH_UNIPHIER_32BIT
-
-config ARCH_UNIPHIER_PRO5_PXS2_LD6B
- bool "UniPhier Pro5/PXs2/LD6b SoCs"
+config ARCH_UNIPHIER_V7_MULTI
+ bool "UniPhier Pro4/Pro5/PXs2/LD6b SoCs"
select ARCH_UNIPHIER_32BIT
config ARCH_UNIPHIER_V8_MULTI
@@ -44,19 +40,24 @@ config ARCH_UNIPHIER_SLD8
depends on ARCH_UNIPHIER_LD4_SLD8
default y
+config ARCH_UNIPHIER_PRO4
+ bool "Enable UniPhier Pro4 SoC support"
+ depends on ARCH_UNIPHIER_V7_MULTI
+ default y
+
config ARCH_UNIPHIER_PRO5
bool "Enable UniPhier Pro5 SoC support"
- depends on ARCH_UNIPHIER_PRO5_PXS2_LD6B
+ depends on ARCH_UNIPHIER_V7_MULTI
default y
config ARCH_UNIPHIER_PXS2
bool "Enable UniPhier Pxs2 SoC support"
- depends on ARCH_UNIPHIER_PRO5_PXS2_LD6B
+ depends on ARCH_UNIPHIER_V7_MULTI
default y
config ARCH_UNIPHIER_LD6B
bool "Enable UniPhier LD6b SoC support"
- depends on ARCH_UNIPHIER_PRO5_PXS2_LD6B
+ depends on ARCH_UNIPHIER_V7_MULTI
default y
config ARCH_UNIPHIER_LD11
diff --git a/arch/arm/mach-uniphier/clk/clk-ld11.c b/arch/arm/mach-uniphier/clk/clk-ld11.c
index 0266e7e66b..a4b7419e54 100644
--- a/arch/arm/mach-uniphier/clk/clk-ld11.c
+++ b/arch/arm/mach-uniphier/clk/clk-ld11.c
@@ -40,7 +40,7 @@ void uniphier_ld11_clk_init(void)
int ch;
tmp = readl(SC_CLKCTRL4);
- tmp |= SC_CLKCTRL4_MIO | SC_CLKCTRL4_STDMAC;
+ tmp |= BIT(10) | BIT(8); /* MIO, STDMAC */
writel(tmp, SC_CLKCTRL4);
for (ch = 0; ch < 3; ch++) {
diff --git a/arch/arm/mach-uniphier/clk/clk-ld20.c b/arch/arm/mach-uniphier/clk/clk-ld20.c
index 5bb560cafe..f79fb38535 100644
--- a/arch/arm/mach-uniphier/clk/clk-ld20.c
+++ b/arch/arm/mach-uniphier/clk/clk-ld20.c
@@ -4,14 +4,26 @@
* SPDX-License-Identifier: GPL-2.0+
*/
+#include <linux/bitops.h>
#include <linux/io.h>
#include "../init.h"
+#include "../sc64-regs.h"
#define SDCTRL_EMMC_HW_RESET 0x59810280
void uniphier_ld20_clk_init(void)
{
+ u32 tmp;
+
+ tmp = readl(SC_RSTCTRL6);
+ tmp |= BIT(8); /* Mali */
+ writel(tmp, SC_RSTCTRL6);
+
+ tmp = readl(SC_CLKCTRL6);
+ tmp |= BIT(8); /* Mali */
+ writel(tmp, SC_CLKCTRL6);
+
/* TODO: use "mmc-pwrseq-emmc" */
writel(1, SDCTRL_EMMC_HW_RESET);
}
diff --git a/arch/arm/mach-uniphier/clk/clk-pxs3.c b/arch/arm/mach-uniphier/clk/clk-pxs3.c
index 2dee857a18..3b9cc626f1 100644
--- a/arch/arm/mach-uniphier/clk/clk-pxs3.c
+++ b/arch/arm/mach-uniphier/clk/clk-pxs3.c
@@ -4,14 +4,26 @@
* SPDX-License-Identifier: GPL-2.0+
*/
+#include <linux/bitops.h>
#include <linux/io.h>
#include "../init.h"
+#include "../sc64-regs.h"
#define SDCTRL_EMMC_HW_RESET 0x59810280
void uniphier_pxs3_clk_init(void)
{
+ u32 tmp;
+
+ tmp = readl(SC_RSTCTRL6);
+ tmp |= BIT(8); /* Mali */
+ writel(tmp, SC_RSTCTRL6);
+
+ tmp = readl(SC_CLKCTRL6);
+ tmp |= BIT(8); /* Mali */
+ writel(tmp, SC_CLKCTRL6);
+
/* TODO: use "mmc-pwrseq-emmc" */
writel(1, SDCTRL_EMMC_HW_RESET);
}
diff --git a/arch/arm/mach-uniphier/sc64-regs.h b/arch/arm/mach-uniphier/sc64-regs.h
index d0a51f239c..80efb4e4e3 100644
--- a/arch/arm/mach-uniphier/sc64-regs.h
+++ b/arch/arm/mach-uniphier/sc64-regs.h
@@ -15,34 +15,16 @@
#define SC_RSTCTRL (SC_BASE_ADDR | 0x2000)
#define SC_RSTCTRL3 (SC_BASE_ADDR | 0x2008)
#define SC_RSTCTRL4 (SC_BASE_ADDR | 0x200c)
-#define SC_RSTCTRL4_ETHER (1 << 6)
-#define SC_RSTCTRL4_NAND (1 << 0)
#define SC_RSTCTRL5 (SC_BASE_ADDR | 0x2010)
#define SC_RSTCTRL6 (SC_BASE_ADDR | 0x2014)
#define SC_RSTCTRL7 (SC_BASE_ADDR | 0x2018)
-#define SC_RSTCTRL7_UMCSB (1 << 16)
-#define SC_RSTCTRL7_UMCA2 (1 << 10)
-#define SC_RSTCTRL7_UMCA1 (1 << 9)
-#define SC_RSTCTRL7_UMCA0 (1 << 8)
-#define SC_RSTCTRL7_UMC32 (1 << 2)
-#define SC_RSTCTRL7_UMC31 (1 << 1)
-#define SC_RSTCTRL7_UMC30 (1 << 0)
#define SC_CLKCTRL (SC_BASE_ADDR | 0x2100)
#define SC_CLKCTRL3 (SC_BASE_ADDR | 0x2108)
#define SC_CLKCTRL4 (SC_BASE_ADDR | 0x210c)
-#define SC_CLKCTRL4_MIO (1 << 10)
-#define SC_CLKCTRL4_STDMAC (1 << 8)
-#define SC_CLKCTRL4_PERI (1 << 7)
-#define SC_CLKCTRL4_ETHER (1 << 6)
-#define SC_CLKCTRL4_NAND (1 << 0)
#define SC_CLKCTRL5 (SC_BASE_ADDR | 0x2110)
#define SC_CLKCTRL6 (SC_BASE_ADDR | 0x2114)
#define SC_CLKCTRL7 (SC_BASE_ADDR | 0x2118)
-#define SC_CLKCTRL7_UMCSB (1 << 16)
-#define SC_CLKCTRL7_UMC32 (1 << 2)
-#define SC_CLKCTRL7_UMC31 (1 << 1)
-#define SC_CLKCTRL7_UMC30 (1 << 0)
#define SC_CA72_GEARST (SC_BASE_ADDR | 0x8000)
#define SC_CA72_GEARSET (SC_BASE_ADDR | 0x8004)
diff --git a/arch/nds32/cpu/n1213/start.S b/arch/nds32/cpu/n1213/start.S
index f9f999902c..0d98d03fc3 100644
--- a/arch/nds32/cpu/n1213/start.S
+++ b/arch/nds32/cpu/n1213/start.S
@@ -119,19 +119,46 @@ set_ivb:
/* set IVIC, vector size: 4 bytes, base: 0x0 */
mtsr $r0, $ivb
/*
- * MMU_CTL NTC0 Cacheable/Write-Back
+ * MMU_CTL NTC0 Non-cacheable
*/
+ li $r0, ~0x6
+ mfsr $r1, $mr0
+ and $r1, $r1, $r0
+ mtsr $r1, $mr0
+
li $r0, ~0x3
mfsr $r1, $mr8
and $r1, $r1, $r0
mtsr $r1, $mr8
#if (!defined(CONFIG_SYS_ICACHE_OFF) || !defined(CONFIG_SYS_DCACHE_OFF))
+/*
+ * MMU_CTL NTC0 Cacheable/Write-Back
+ */
li $r0, 0x4
mfsr $r1, $mr0
or $r1, $r1, $r0
mtsr $r1, $mr0
#endif
+#ifndef CONFIG_SYS_DCACHE_OFF
+#ifdef CONFIG_ARCH_MAP_SYSMEM
+/*
+ * MMU_CTL NTC1 Non-cacheable
+ */
+ li $r0, ~0x18
+ mfsr $r1, $mr0
+ and $r1, $r1, $r0
+ mtsr $r1, $mr0
+/*
+ * MMU_CTL NTM1 mapping for partition 0
+ */
+ li $r0, ~0x6000
+ mfsr $r1, $mr0
+ and $r1, $r1, $r0
+ mtsr $r1, $mr0
+#endif
+#endif
+
#if !defined(CONFIG_SYS_ICACHE_OFF)
li $r0, 0x1
mfsr $r1, $mr8
diff --git a/arch/nds32/dts/ae3xx.dts b/arch/nds32/dts/ae3xx.dts
index 4221e4bf9a..fbe6d74437 100644
--- a/arch/nds32/dts/ae3xx.dts
+++ b/arch/nds32/dts/ae3xx.dts
@@ -8,6 +8,7 @@
aliases {
uart0 = &serial0;
ethernet0 = &mac0;
+ spi0 = &spi;
} ;
chosen {
@@ -22,6 +23,12 @@
reg = <0x00000000 0x40000000>;
};
+ spiclk: virt_100mhz {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <100000000>;
+ };
+
cpus {
#address-cells = <1>;
#size-cells = <0>;
@@ -69,4 +76,20 @@
device-width = <1>;
};
+ spi: spi@f0b00000 {
+ compatible = "andestech,atcspi200";
+ reg = <0xf0b00000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ num-cs = <1>;
+ clocks = <&spiclk>;
+ interrupts = <3 4>;
+ flash@0 {
+ compatible = "spi-flash";
+ spi-max-frequency = <50000000>;
+ reg = <0>;
+ spi-cpol;
+ spi-cpha;
+ };
+ };
};
diff --git a/arch/nds32/include/asm/bootm.h b/arch/nds32/include/asm/bootm.h
index 6b10c078df..2e2fe01f0e 100644
--- a/arch/nds32/include/asm/bootm.h
+++ b/arch/nds32/include/asm/bootm.h
@@ -11,6 +11,8 @@
#ifndef NDS32_BOOTM_H
#define NDS32_BOOTM_H
+#include <asm/setup.h>
+
extern void udc_disconnect(void);
#if defined(CONFIG_SETUP_MEMORY_TAGS) || \
diff --git a/arch/nds32/include/asm/io.h b/arch/nds32/include/asm/io.h
index b2c4d0ef8c..25ef9a46c6 100644
--- a/arch/nds32/include/asm/io.h
+++ b/arch/nds32/include/asm/io.h
@@ -48,6 +48,27 @@ static inline void sync(void)
#define MAP_WRBACK (0)
#define MAP_WRTHROUGH (0)
+#ifdef CONFIG_ARCH_MAP_SYSMEM
+static inline void *map_sysmem(phys_addr_t paddr, unsigned long len)
+{
+ if(paddr <PHYS_SDRAM_0_SIZE + PHYS_SDRAM_1_SIZE)
+ paddr = paddr | 0x40000000;
+ return (void *)(uintptr_t)paddr;
+}
+
+static inline void *unmap_sysmem(const void *vaddr)
+{
+ phys_addr_t paddr = (phys_addr_t)vaddr;
+ paddr = paddr & ~0x40000000;
+ return (void *)(uintptr_t)paddr;
+}
+
+static inline phys_addr_t map_to_sysmem(const void *ptr)
+{
+ return (phys_addr_t)(uintptr_t)ptr;
+}
+#endif
+
static inline void *
map_physmem(phys_addr_t paddr, unsigned long len, unsigned long flags)
{
@@ -104,26 +125,26 @@ extern void __raw_readsl(unsigned int addr, void *data, int longlen);
#define __iormb() dmb()
#define __iowmb() dmb()
-static inline void writeb(unsigned char val, unsigned char *addr)
+static inline void writeb(u8 val, volatile void __iomem *addr)
{
__iowmb();
__arch_putb(val, addr);
}
-static inline void writew(unsigned short val, unsigned short *addr)
+static inline void writew(u16 val, volatile void __iomem *addr)
{
__iowmb();
__arch_putw(val, addr);
}
-static inline void writel(unsigned int val, unsigned int *addr)
+static inline void writel(u32 val, volatile void __iomem *addr)
{
__iowmb();
__arch_putl(val, addr);
}
-static inline unsigned char readb(unsigned char *addr)
+static inline u8 readb(const volatile void __iomem *addr)
{
u8 val;
@@ -132,7 +153,7 @@ static inline unsigned char readb(unsigned char *addr)
return val;
}
-static inline unsigned short readw(unsigned short *addr)
+static inline u16 readw(const volatile void __iomem *addr)
{
u16 val;
@@ -141,7 +162,7 @@ static inline unsigned short readw(unsigned short *addr)
return val;
}
-static inline unsigned int readl(unsigned int *addr)
+static inline u32 readl(const volatile void __iomem *addr)
{
u32 val;
diff --git a/arch/nds32/lib/bootm.c b/arch/nds32/lib/bootm.c
index e834329e0b..42b15dfcbf 100644
--- a/arch/nds32/lib/bootm.c
+++ b/arch/nds32/lib/bootm.c
@@ -12,7 +12,6 @@
#include <u-boot/zlib.h>
#include <asm/byteorder.h>
#include <asm/bootm.h>
-#include <asm/setup.h>
DECLARE_GLOBAL_DATA_PTR;
diff --git a/board/AndesTech/adp-ae3xx/adp-ae3xx.c b/board/AndesTech/adp-ae3xx/adp-ae3xx.c
index 98ed4d9589..8cffb6ba8b 100644
--- a/board/AndesTech/adp-ae3xx/adp-ae3xx.c
+++ b/board/AndesTech/adp-ae3xx/adp-ae3xx.c
@@ -6,6 +6,7 @@
* SPDX-License-Identifier: GPL-2.0+
*/
+#include <asm/mach-types.h>
#include <common.h>
#if defined(CONFIG_FTMAC100) && !defined(CONFIG_DM_ETH)
#include <netdev.h>
diff --git a/board/amarula/vyasa-rk3288/Kconfig b/board/amarula/vyasa-rk3288/Kconfig
new file mode 100644
index 0000000000..8b8c30835e
--- /dev/null
+++ b/board/amarula/vyasa-rk3288/Kconfig
@@ -0,0 +1,12 @@
+if TARGET_VYASA_RK3288
+
+config SYS_BOARD
+ default "vyasa-rk3288"
+
+config SYS_VENDOR
+ default "amarula"
+
+config SYS_CONFIG_NAME
+ default "vyasa-rk3288"
+
+endif
diff --git a/board/amarula/vyasa-rk3288/MAINTAINERS b/board/amarula/vyasa-rk3288/MAINTAINERS
new file mode 100644
index 0000000000..10397fcb4b
--- /dev/null
+++ b/board/amarula/vyasa-rk3288/MAINTAINERS
@@ -0,0 +1,6 @@
+VYASA RK3288
+M: Jagan Teki <jagan@amarulasolutions.com>
+S: Maintained
+F: board/amarula/vyasa-rk3288
+F: include/configs/vyasa-rk3288.h
+F: configs/vyasa-rk3288_defconfig
diff --git a/board/amarula/vyasa-rk3288/Makefile b/board/amarula/vyasa-rk3288/Makefile
new file mode 100644
index 0000000000..7c0d5c0316
--- /dev/null
+++ b/board/amarula/vyasa-rk3288/Makefile
@@ -0,0 +1,7 @@
+#
+# Copyright (C) 2017 Amarula Solutions
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+obj-y += vyasa-rk3288.o
diff --git a/board/amarula/vyasa-rk3288/vyasa-rk3288.c b/board/amarula/vyasa-rk3288/vyasa-rk3288.c
new file mode 100644
index 0000000000..ceee42c16e
--- /dev/null
+++ b/board/amarula/vyasa-rk3288/vyasa-rk3288.c
@@ -0,0 +1,7 @@
+/*
+ * Copyright (C) 2017 Amarula Solutions
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
diff --git a/board/bachmann/ot1200/ot1200_spl.c b/board/bachmann/ot1200/ot1200_spl.c
index 9d28da4ba4..f3dff95710 100644
--- a/board/bachmann/ot1200/ot1200_spl.c
+++ b/board/bachmann/ot1200/ot1200_spl.c
@@ -151,10 +151,4 @@ void board_init_f(ulong dummy)
/* configure MMDC for SDRAM width/size and per-model calibration */
ot1200_spl_dram_init();
-
- /* Clear the BSS. */
- memset(__bss_start, 0, __bss_end - __bss_start);
-
- /* load/boot image from boot device */
- board_init_r(NULL, 0);
}
diff --git a/board/compulab/cm_fx6/spl.c b/board/compulab/cm_fx6/spl.c
index bba977ff8e..56aac60239 100644
--- a/board/compulab/cm_fx6/spl.c
+++ b/board/compulab/cm_fx6/spl.c
@@ -336,9 +336,6 @@ void board_init_f(ulong dummy)
puts("!!!ERROR!!! DRAM detection failed!!!\n");
hang();
}
-
- memset(__bss_start, 0, __bss_end - __bss_start);
- board_init_r(NULL, 0);
}
void board_boot_order(u32 *spl_boot_list)
diff --git a/board/davinci/da8xxevm/Kconfig b/board/davinci/da8xxevm/Kconfig
index bb1188b4ea..e0df97ca0e 100644
--- a/board/davinci/da8xxevm/Kconfig
+++ b/board/davinci/da8xxevm/Kconfig
@@ -33,6 +33,8 @@ config MAC_ADDR_IN_EEPROM
endif
+source "board/ti/common/Kconfig"
+
endif
if TARGET_OMAPL138_LCDK
diff --git a/board/davinci/da8xxevm/da850evm.c b/board/davinci/da8xxevm/da850evm.c
index 516d86df50..83c9f2940f 100644
--- a/board/davinci/da8xxevm/da850evm.c
+++ b/board/davinci/da8xxevm/da850evm.c
@@ -60,7 +60,7 @@ static int get_mac_addr(u8 *addr)
return -1;
}
- ret = spi_flash_read(flash, CFG_MAC_ADDR_OFFSET, 6, addr);
+ ret = spi_flash_read(flash, (CFG_MAC_ADDR_OFFSET) + 1, 7, addr);
if (ret) {
printf("Error - unable to read MAC address from SPI flash.\n");
return -1;
@@ -140,6 +140,7 @@ int misc_init_r(void)
uchar buff[6];
spi_mac_read = get_mac_addr(buff);
+ buff[0] = 0;
/*
* MAC address not present in the environment
diff --git a/board/engicam/common/spl.c b/board/engicam/common/spl.c
index 6964c131d9..8711418fb4 100644
--- a/board/engicam/common/spl.c
+++ b/board/engicam/common/spl.c
@@ -384,10 +384,4 @@ void board_init_f(ulong dummy)
/* DDR initialization */
spl_dram_init();
-
- /* Clear the BSS. */
- memset(__bss_start, 0, __bss_end - __bss_start);
-
- /* load/boot image from boot device */
- board_init_r(NULL, 0);
}
diff --git a/board/freescale/ls2080ardb/ls2080ardb.c b/board/freescale/ls2080ardb/ls2080ardb.c
index 666562d106..827bfad521 100644
--- a/board/freescale/ls2080ardb/ls2080ardb.c
+++ b/board/freescale/ls2080ardb/ls2080ardb.c
@@ -251,6 +251,8 @@ int misc_init_r(void)
char *env_hwconfig;
u32 __iomem *dcfg_ccsr = (u32 __iomem *)DCFG_BASE;
u32 val;
+ struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
+ u32 svr = gur_in32(&gur->svr);
val = in_le32(dcfg_ccsr + DCFG_RCWSR13 / 4);
@@ -278,6 +280,16 @@ int misc_init_r(void)
if (adjust_vdd(0))
printf("Warning: Adjusting core voltage failed.\n");
+ /*
+ * Default value of board env is based on filename which is
+ * ls2080ardb. Modify board env for other supported SoCs
+ */
+ if ((SVR_SOC_VER(svr) == SVR_LS2088A) ||
+ (SVR_SOC_VER(svr) == SVR_LS2048A))
+ env_set("board", "ls2088ardb");
+ else if ((SVR_SOC_VER(svr) == SVR_LS2081A) ||
+ (SVR_SOC_VER(svr) == SVR_LS2041A))
+ env_set("board", "ls2081ardb");
return 0;
}
diff --git a/board/freescale/mx7dsabresd/mx7dsabresd.c b/board/freescale/mx7dsabresd/mx7dsabresd.c
index a681ecef3a..5819b1825d 100644
--- a/board/freescale/mx7dsabresd/mx7dsabresd.c
+++ b/board/freescale/mx7dsabresd/mx7dsabresd.c
@@ -260,7 +260,7 @@ static int setup_fec(void)
(IOMUXC_GPR_GPR1_GPR_ENET1_TX_CLK_SEL_MASK |
IOMUXC_GPR_GPR1_GPR_ENET1_CLK_DIR_MASK), 0);
- return set_clk_enet(ENET_125MHz);
+ return set_clk_enet(ENET_125MHZ);
}
diff --git a/board/gateworks/gw_ventana/gw_ventana_spl.c b/board/gateworks/gw_ventana/gw_ventana_spl.c
index c2e370ba0b..bdbe5e7027 100644
--- a/board/gateworks/gw_ventana/gw_ventana_spl.c
+++ b/board/gateworks/gw_ventana/gw_ventana_spl.c
@@ -626,9 +626,6 @@ void board_init_f(ulong dummy)
spl_dram_init(8 << ventana_info.sdram_width,
16 << ventana_info.sdram_size,
board_model);
-
- /* Clear the BSS. */
- memset(__bss_start, 0, __bss_end - __bss_start);
}
void board_boot_order(u32 *spl_boot_list)
diff --git a/board/ge/bx50v3/Makefile b/board/ge/bx50v3/Makefile
index bcd149f5b0..2fff27bc77 100644
--- a/board/ge/bx50v3/Makefile
+++ b/board/ge/bx50v3/Makefile
@@ -5,4 +5,4 @@
# SPDX-License-Identifier: GPL-2.0+
#
-obj-y := bx50v3.o
+obj-y := bx50v3.o vpd_reader.o
diff --git a/board/ge/bx50v3/bx50v3.c b/board/ge/bx50v3/bx50v3.c
index b25c634bb5..c7df4ce847 100644
--- a/board/ge/bx50v3/bx50v3.c
+++ b/board/ge/bx50v3/bx50v3.c
@@ -26,8 +26,19 @@
#include <asm/arch/sys_proto.h>
#include <i2c.h>
#include <pwm.h>
+#include <stdlib.h>
+#include "vpd_reader.h"
DECLARE_GLOBAL_DATA_PTR;
+#ifndef CONFIG_SYS_I2C_EEPROM_ADDR
+# define CONFIG_SYS_I2C_EEPROM_ADDR 0x50
+# define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 1
+#endif
+
+#ifndef CONFIG_SYS_I2C_EEPROM_BUS
+#define CONFIG_SYS_I2C_EEPROM_BUS 2
+#endif
+
#define NC_PAD_CTRL (PAD_CTL_PUS_100K_UP | \
PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | \
PAD_CTL_HYS)
@@ -528,6 +539,102 @@ int overwrite_console(void)
return 1;
}
+#define VPD_TYPE_INVALID 0x00
+#define VPD_BLOCK_NETWORK 0x20
+#define VPD_BLOCK_HWID 0x44
+#define VPD_PRODUCT_B850 1
+#define VPD_PRODUCT_B650 2
+#define VPD_PRODUCT_B450 3
+
+struct vpd_cache {
+ uint8_t product_id;
+ uint8_t macbits;
+ unsigned char mac1[6];
+};
+
+/*
+ * Extracts MAC and product information from the VPD.
+ */
+static int vpd_callback(
+ void *userdata,
+ uint8_t id,
+ uint8_t version,
+ uint8_t type,
+ size_t size,
+ uint8_t const *data)
+{
+ struct vpd_cache *vpd = (struct vpd_cache *)userdata;
+
+ if ( id == VPD_BLOCK_HWID
+ && version == 1
+ && type != VPD_TYPE_INVALID
+ && size >= 1) {
+ vpd->product_id = data[0];
+
+ } else if ( id == VPD_BLOCK_NETWORK
+ && version == 1
+ && type != VPD_TYPE_INVALID
+ && size >= 6) {
+ vpd->macbits |= 1;
+ memcpy(vpd->mac1, data, 6);
+ }
+
+ return 0;
+}
+
+static void set_eth0_mac_address(unsigned char * mac)
+{
+ uint32_t *ENET_TCR = (uint32_t*)0x21880c4;
+ uint32_t *ENET_PALR = (uint32_t*)0x21880e4;
+ uint32_t *ENET_PAUR = (uint32_t*)0x21880e8;
+
+ *ENET_TCR |= 0x100; /* ADDINS */
+ *ENET_PALR |= (mac[0] << 24) | (mac[1] << 16) | (mac[2] << 8) | mac[3];
+ *ENET_PAUR |= (mac[4] << 24) | (mac[5] << 16);
+}
+
+static void process_vpd(struct vpd_cache *vpd)
+{
+ if ( vpd->product_id == VPD_PRODUCT_B850
+ || vpd->product_id == VPD_PRODUCT_B650
+ || vpd->product_id == VPD_PRODUCT_B450) {
+ if (vpd->macbits & 1) {
+ set_eth0_mac_address(vpd->mac1);
+ }
+ }
+}
+
+static int read_vpd(uint eeprom_bus)
+{
+ struct vpd_cache vpd;
+ int res;
+ int size = 1024;
+ uint8_t *data;
+ unsigned int current_i2c_bus = i2c_get_bus_num();
+
+ res = i2c_set_bus_num(eeprom_bus);
+ if (res < 0)
+ return res;
+
+ data = (uint8_t *)malloc(size);
+ if (!data)
+ return -ENOMEM;
+
+ res = i2c_read(CONFIG_SYS_I2C_EEPROM_ADDR, 0,
+ CONFIG_SYS_I2C_EEPROM_ADDR_LEN, data, size);
+
+ if (res == 0) {
+ memset(&vpd, 0, sizeof(vpd));
+ vpd_reader(size, data, &vpd, vpd_callback);
+ process_vpd(&vpd);
+ }
+
+ free(data);
+
+ i2c_set_bus_num(current_i2c_bus);
+ return res;
+}
+
int board_eth_init(bd_t *bis)
{
setup_iomux_enet();
@@ -586,6 +693,8 @@ int board_init(void)
setup_i2c(2, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info2);
setup_i2c(3, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info3);
+ read_vpd(CONFIG_SYS_I2C_EEPROM_BUS);
+
return 0;
}
diff --git a/board/ge/bx50v3/vpd_reader.c b/board/ge/bx50v3/vpd_reader.c
new file mode 100644
index 0000000000..98da893d2c
--- /dev/null
+++ b/board/ge/bx50v3/vpd_reader.c
@@ -0,0 +1,228 @@
+/*
+ * Copyright 2016 General Electric Company
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include "vpd_reader.h"
+
+#include <linux/bch.h>
+#include <stdlib.h>
+
+
+/* BCH configuration */
+
+const struct {
+ int header_ecc_capability_bits;
+ int data_ecc_capability_bits;
+ unsigned int prim_poly;
+ struct {
+ int min;
+ int max;
+ } galois_field_order;
+} bch_configuration = {
+ .header_ecc_capability_bits = 4,
+ .data_ecc_capability_bits = 16,
+ .prim_poly = 0,
+ .galois_field_order = {
+ .min = 5,
+ .max = 15,
+ },
+};
+
+static int calculate_galois_field_order(size_t source_length)
+{
+ int gfo = bch_configuration.galois_field_order.min;
+
+ for (; gfo < bch_configuration.galois_field_order.max &&
+ ((((1 << gfo) - 1) - ((int)source_length * 8)) < 0);
+ gfo++) {
+ }
+
+ if (gfo == bch_configuration.galois_field_order.max) {
+ return -1;
+ }
+
+ return gfo + 1;
+}
+
+static int verify_bch(int ecc_bits, unsigned int prim_poly,
+ uint8_t * data, size_t data_length,
+ const uint8_t * ecc, size_t ecc_length)
+{
+ int gfo = calculate_galois_field_order(data_length);
+ if (gfo < 0) {
+ return -1;
+ }
+
+ struct bch_control * bch = init_bch(gfo, ecc_bits, prim_poly);
+ if (!bch) {
+ return -1;
+ }
+
+ if (bch->ecc_bytes != ecc_length) {
+ free_bch(bch);
+ return -1;
+ }
+
+ unsigned * errloc = (unsigned *)calloc(data_length, sizeof(unsigned));
+ int errors = decode_bch(
+ bch, data, data_length, ecc, NULL, NULL, errloc);
+ free_bch(bch);
+ if (errors < 0) {
+ free(errloc);
+ return -1;
+ }
+
+ if (errors > 0) {
+ for (int n = 0; n < errors; n++) {
+ if (errloc[n] >= 8 * data_length) {
+ /* n-th error located in ecc (no need for data correction) */
+ } else {
+ /* n-th error located in data */
+ data[errloc[n] / 8] ^= 1 << (errloc[n] % 8);
+ }
+ }
+ }
+
+ free(errloc);
+ return 0;
+}
+
+
+static const int ID = 0;
+static const int LEN = 1;
+static const int VER = 2;
+static const int TYP = 3;
+static const int BLOCK_SIZE = 4;
+
+static const uint8_t HEADER_BLOCK_ID = 0x00;
+static const uint8_t HEADER_BLOCK_LEN = 18;
+static const uint32_t HEADER_BLOCK_MAGIC = 0xca53ca53;
+static const size_t HEADER_BLOCK_VERIFY_LEN = 14;
+static const size_t HEADER_BLOCK_ECC_OFF = 14;
+static const size_t HEADER_BLOCK_ECC_LEN = 4;
+
+static const uint8_t ECC_BLOCK_ID = 0xFF;
+
+int vpd_reader(
+ size_t size,
+ uint8_t * data,
+ void * userdata,
+ int (*fn)(
+ void * userdata,
+ uint8_t id,
+ uint8_t version,
+ uint8_t type,
+ size_t size,
+ uint8_t const * data))
+{
+ if ( size < HEADER_BLOCK_LEN
+ || data == NULL
+ || fn == NULL) {
+ return -EINVAL;
+ }
+
+ /*
+ * +--------------------+--------------------+--//--+--------------------+
+ * | header block | data block | ... | ecc block |
+ * +--------------------+--------------------+--//--+--------------------+
+ * : : :
+ * +------+-------+-----+ +------+-------------+
+ * | id | magic | ecc | | ... | ecc |
+ * | len | off | | +------+-------------+
+ * | ver | size | | :
+ * | type | | | :
+ * +------+-------+-----+ :
+ * : : : :
+ * <----- [1] ----> <----------- [2] ----------->
+ *
+ * Repair (if necessary) the contents of header block [1] by using a
+ * 4 byte ECC located at the end of the header block. A successful
+ * return value means that we can trust the header.
+ */
+ int ret = verify_bch(
+ bch_configuration.header_ecc_capability_bits,
+ bch_configuration.prim_poly,
+ data,
+ HEADER_BLOCK_VERIFY_LEN,
+ &data[HEADER_BLOCK_ECC_OFF],
+ HEADER_BLOCK_ECC_LEN);
+ if (ret < 0) {
+ return ret;
+ }
+
+ /* Validate header block { id, length, version, type }. */
+ if ( data[ID] != HEADER_BLOCK_ID
+ || data[LEN] != HEADER_BLOCK_LEN
+ || data[VER] != 0
+ || data[TYP] != 0
+ || ntohl(*(uint32_t *)(&data[4])) != HEADER_BLOCK_MAGIC) {
+ return -EINVAL;
+ }
+
+ uint32_t offset = ntohl(*(uint32_t *)(&data[8]));
+ uint16_t size_bits = ntohs(*(uint16_t *)(&data[12]));
+
+ /* Check that ECC header fits. */
+ if (offset + 3 >= size) {
+ return -EINVAL;
+ }
+
+ /* Validate ECC block. */
+ uint8_t * ecc = &data[offset];
+ if ( ecc[ID] != ECC_BLOCK_ID
+ || ecc[LEN] < BLOCK_SIZE
+ || ecc[LEN] + offset > size
+ || ecc[LEN] - BLOCK_SIZE != size_bits / 8
+ || ecc[VER] != 1
+ || ecc[TYP] != 1) {
+ return -EINVAL;
+ }
+
+ /*
+ * Use the header block to locate the ECC block and verify the data
+ * blocks [2] against the ecc block ECC.
+ */
+ ret = verify_bch(
+ bch_configuration.data_ecc_capability_bits,
+ bch_configuration.prim_poly,
+ &data[data[LEN]],
+ offset - data[LEN],
+ &data[offset + BLOCK_SIZE],
+ ecc[LEN] - BLOCK_SIZE);
+ if (ret < 0) {
+ return ret;
+ }
+
+ /* Stop after ECC. Ignore possible zero padding. */
+ size = offset;
+
+ for (;;) {
+ /* Move to next block. */
+ size -= data[LEN];
+ data += data[LEN];
+
+ if (size == 0) {
+ /* Finished iterating through blocks. */
+ return 0;
+ }
+
+ if ( size < BLOCK_SIZE
+ || data[LEN] < BLOCK_SIZE) {
+ /* Not enough data for a header, or short header. */
+ return -EINVAL;
+ }
+
+ ret = fn(
+ userdata,
+ data[ID],
+ data[VER],
+ data[TYP],
+ data[LEN] - BLOCK_SIZE,
+ &data[BLOCK_SIZE]);
+ if (ret) {
+ return ret;
+ }
+ }
+}
diff --git a/board/ge/bx50v3/vpd_reader.h b/board/ge/bx50v3/vpd_reader.h
new file mode 100644
index 0000000000..efa172a915
--- /dev/null
+++ b/board/ge/bx50v3/vpd_reader.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2016 General Electric Company
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include "common.h"
+
+/*
+ * Read VPD from given data, verify content, and call callback
+ * for each vital product data block.
+ *
+ * Returns Non-zero on error. Negative numbers encode errno.
+ */
+int vpd_reader(
+ size_t size,
+ uint8_t * data,
+ void * userdata,
+ int (*fn)(
+ void * userdata,
+ uint8_t id,
+ uint8_t version,
+ uint8_t type,
+ size_t size,
+ uint8_t const * data));
diff --git a/board/kosagi/novena/novena_spl.c b/board/kosagi/novena/novena_spl.c
index 512f06da76..b4a68da88f 100644
--- a/board/kosagi/novena/novena_spl.c
+++ b/board/kosagi/novena/novena_spl.c
@@ -596,10 +596,4 @@ void board_init_f(ulong dummy)
udelay(100);
mmdc_do_write_level_calibration(&novena_ddr_info);
mmdc_do_dqs_calibration(&novena_ddr_info);
-
- /* Clear the BSS. */
- memset(__bss_start, 0, __bss_end - __bss_start);
-
- /* load/boot image from boot device */
- board_init_r(NULL, 0);
}
diff --git a/board/liebherr/mccmon6/spl.c b/board/liebherr/mccmon6/spl.c
index a2f804db8f..196da46df9 100644
--- a/board/liebherr/mccmon6/spl.c
+++ b/board/liebherr/mccmon6/spl.c
@@ -296,11 +296,5 @@ void board_init_f(ulong dummy)
/* DDR initialization */
spl_dram_init();
-
- /* Clear the BSS. */
- memset(__bss_start, 0, __bss_end - __bss_start);
-
- /* load/boot image from boot device */
- board_init_r(NULL, 0);
}
#endif
diff --git a/board/logicpd/am3517evm/am3517evm.c b/board/logicpd/am3517evm/am3517evm.c
index c18a5a3140..29f136a530 100644
--- a/board/logicpd/am3517evm/am3517evm.c
+++ b/board/logicpd/am3517evm/am3517evm.c
@@ -12,6 +12,8 @@
*/
#include <common.h>
+#include <dm.h>
+#include <ns16550.h>
#include <asm/io.h>
#include <asm/omap_musb.h>
#include <asm/arch/am35x_def.h>
@@ -34,6 +36,22 @@ DECLARE_GLOBAL_DATA_PTR;
#define AM3517_IP_SW_RESET 0x48002598
#define CPGMACSS_SW_RST (1 << 1)
+#define PHY_GPIO 30
+
+/* This is only needed until SPL gets OF support */
+#ifdef CONFIG_SPL_BUILD
+static const struct ns16550_platdata am3517_serial = {
+ .base = OMAP34XX_UART3,
+ .reg_shift = 2,
+ .clock = V_NS16550_CLK,
+ .fcr = UART_FCR_DEFVAL,
+};
+
+U_BOOT_DEVICE(am3517_uart) = {
+ "ns16550_serial",
+ &am3517_serial
+};
+#endif
/*
* Routine: board_init
@@ -113,30 +131,35 @@ int misc_init_r(void)
am3517_evm_musb_init();
- /* activate PHY reset */
- gpio_direction_output(30, 0);
- gpio_set_value(30, 0);
-
- ctr = 0;
- do {
- udelay(1000);
- ctr++;
- } while (ctr < 300);
-
- /* deactivate PHY reset */
- gpio_set_value(30, 1);
-
- /* allow the PHY to stabilize and settle down */
- ctr = 0;
- do {
- udelay(1000);
- ctr++;
- } while (ctr < 300);
-
- /* ensure that the module is out of reset */
- reset = readl(AM3517_IP_SW_RESET);
- reset &= (~CPGMACSS_SW_RST);
- writel(reset,AM3517_IP_SW_RESET);
+ if (gpio_request(PHY_GPIO, "gpio_30") == 0) {
+ /* activate PHY reset */
+ gpio_direction_output(PHY_GPIO, 0);
+ gpio_set_value(PHY_GPIO, 0);
+
+ ctr = 0;
+ do {
+ udelay(1000);
+ ctr++;
+ } while (ctr < 300);
+
+ /* deactivate PHY reset */
+ gpio_set_value(PHY_GPIO, 1);
+
+ /* allow the PHY to stabilize and settle down */
+ ctr = 0;
+ do {
+ udelay(1000);
+ ctr++;
+ } while (ctr < 300);
+
+ /* ensure that the module is out of reset */
+ reset = readl(AM3517_IP_SW_RESET);
+ reset &= (~CPGMACSS_SW_RST);
+ writel(reset, AM3517_IP_SW_RESET);
+
+ /* Free requested GPIO */
+ gpio_free(PHY_GPIO);
+ }
return 0;
}
diff --git a/board/solidrun/clearfog/README b/board/solidrun/clearfog/README
index 2cfa5bfc86..ef1e3bf426 100644
--- a/board/solidrun/clearfog/README
+++ b/board/solidrun/clearfog/README
@@ -16,3 +16,23 @@ $ sudo dd if=u-boot-spl.kwb of=/dev/sdX bs=512 seek=1
Please use the correct device node for your setup instead
of "/dev/sdX" here!
+
+Boot from UART:
+---------------
+
+Connect the on-board micro-USB (CF Pro: CON11, CF Base: CON5)
+to your host.
+
+Set the SW1 DIP switches to UART boot (0: OFF, 1: ON):
+
+ ClearFog Base: 01001
+ ClearFog Pro: 11110
+
+Run the following command to initiate U-Boot download:
+
+ ./tools/kwboot -b u-boot-spl.kwb /dev/ttyUSBX
+
+Use the correct UART device node for /dev/ttyUSBX.
+
+When download finishes start your favorite terminal emulator
+on /dev/ttyUSBX.
diff --git a/board/solidrun/mx6cuboxi/mx6cuboxi.c b/board/solidrun/mx6cuboxi/mx6cuboxi.c
index 986abc5772..1e4da4a6b1 100644
--- a/board/solidrun/mx6cuboxi/mx6cuboxi.c
+++ b/board/solidrun/mx6cuboxi/mx6cuboxi.c
@@ -349,6 +349,7 @@ static bool is_hummingboard(void)
* Machine selection -
* Machine val1, val2
* -------------------------
+ * HB2 x x
* HB rev 3.x x 0
* CBi 0 1
* HB 1 1
@@ -362,9 +363,37 @@ static bool is_hummingboard(void)
return true;
}
+static bool is_hummingboard2(void)
+{
+ int val1;
+
+ SETUP_IOMUX_PADS(hb_cbi_sense);
+
+ gpio_direction_input(IMX_GPIO_NR(2, 8));
+
+ val1 = gpio_get_value(IMX_GPIO_NR(2, 8));
+
+ /*
+ * Machine selection -
+ * Machine val1
+ * -------------------
+ * HB2 0
+ * HB rev 3.x x
+ * CBi x
+ * HB x
+ */
+
+ if (val1 == 0)
+ return true;
+ else
+ return false;
+}
+
int checkboard(void)
{
- if (is_hummingboard())
+ if (is_hummingboard2())
+ puts("Board: MX6 Hummingboard2\n");
+ else if (is_hummingboard())
puts("Board: MX6 Hummingboard\n");
else
puts("Board: MX6 Cubox-i\n");
@@ -375,7 +404,9 @@ int checkboard(void)
int board_late_init(void)
{
#ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
- if (is_hummingboard())
+ if (is_hummingboard2())
+ env_set("board_name", "HUMMINGBOARD2");
+ else if (is_hummingboard())
env_set("board_name", "HUMMINGBOARD");
else
env_set("board_name", "CUBOXI");
diff --git a/board/st/stih410-b2260/board.c b/board/st/stih410-b2260/board.c
index 92b0695593..d6cbbb866a 100644
--- a/board/st/stih410-b2260/board.c
+++ b/board/st/stih410-b2260/board.c
@@ -7,6 +7,10 @@
*/
#include <common.h>
+#include <linux/usb/otg.h>
+#include <dwc3-sti-glue.h>
+#include <dwc3-uboot.h>
+#include <usb.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -36,3 +40,41 @@ int board_init(void)
{
return 0;
}
+
+#ifdef CONFIG_USB_DWC3
+static struct dwc3_device dwc3_device_data = {
+ .maximum_speed = USB_SPEED_HIGH,
+ .dr_mode = USB_DR_MODE_PERIPHERAL,
+ .index = 0,
+};
+
+int usb_gadget_handle_interrupts(int index)
+{
+ dwc3_uboot_handle_interrupt(index);
+ return 0;
+}
+
+int board_usb_init(int index, enum usb_init_type init)
+{
+ int node;
+ const void *blob = gd->fdt_blob;
+
+ /* find the snps,dwc3 node */
+ node = fdt_node_offset_by_compatible(blob, -1, "snps,dwc3");
+
+ dwc3_device_data.base = fdtdec_get_addr(blob, node, "reg");
+
+ return dwc3_uboot_init(&dwc3_device_data);
+}
+
+int board_usb_cleanup(int index, enum usb_init_type init)
+{
+ dwc3_uboot_exit(index);
+ return 0;
+}
+
+int g_dnl_board_usb_cable_connected(void)
+{
+ return 1;
+}
+#endif
diff --git a/board/st/stm32h743-disco/Kconfig b/board/st/stm32h743-disco/Kconfig
new file mode 100644
index 0000000000..7d6ec1d958
--- /dev/null
+++ b/board/st/stm32h743-disco/Kconfig
@@ -0,0 +1,19 @@
+if TARGET_STM32H743_DISCO
+
+config SYS_BOARD
+ string
+ default "stm32h743-disco"
+
+config SYS_VENDOR
+ string
+ default "st"
+
+config SYS_SOC
+ string
+ default "stm32h7"
+
+config SYS_CONFIG_NAME
+ string
+ default "stm32h743-disco"
+
+endif
diff --git a/board/st/stm32h743-disco/MAINTAINERS b/board/st/stm32h743-disco/MAINTAINERS
new file mode 100644
index 0000000000..e5e0b5a6f2
--- /dev/null
+++ b/board/st/stm32h743-disco/MAINTAINERS
@@ -0,0 +1,7 @@
+STM32H743 DISCOVERY BOARD
+M: Patrice Chotard <patrice.chotard@st.com>
+S: Maintained
+F: board/st/stm32h743-disco
+F: include/configs/stm32h743-disco.h
+F: configs/stm32h743-disco_defconfig
+F: arch/arm/dts/stm32h7*
diff --git a/board/st/stm32h743-disco/Makefile b/board/st/stm32h743-disco/Makefile
new file mode 100644
index 0000000000..778fe1c97f
--- /dev/null
+++ b/board/st/stm32h743-disco/Makefile
@@ -0,0 +1,8 @@
+#
+# Copyright (C) STMicroelectronics SA 2017
+# Author(s): Patrice CHOTARD, <patrice.chotard@st.com> for STMicroelectronics.#
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+obj-y := stm32h743-disco.o
diff --git a/board/st/stm32h743-disco/stm32h743-disco.c b/board/st/stm32h743-disco/stm32h743-disco.c
new file mode 100644
index 0000000000..625b3a077b
--- /dev/null
+++ b/board/st/stm32h743-disco/stm32h743-disco.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) STMicroelectronics SA 2017
+ * Author(s): Patrice CHOTARD, <patrice.chotard@st.com> for STMicroelectronics.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int dram_init(void)
+{
+ struct udevice *dev;
+ int ret;
+
+ ret = uclass_get_device(UCLASS_RAM, 0, &dev);
+ if (ret) {
+ debug("DRAM init failed: %d\n", ret);
+ return ret;
+ }
+
+ if (fdtdec_setup_memory_size() != 0)
+ ret = -EINVAL;
+
+ return ret;
+}
+
+int dram_init_banksize(void)
+{
+ fdtdec_setup_memory_banksize();
+
+ return 0;
+}
+
+int board_early_init_f(void)
+{
+ return 0;
+}
+
+u32 get_board_rev(void)
+{
+ return 0;
+}
+
+int board_late_init(void)
+{
+ return 0;
+}
+
+int board_init(void)
+{
+ gd->bd->bi_boot_params = gd->bd->bi_dram[0].start + 0x100;
+ return 0;
+}
diff --git a/board/st/stm32h743-eval/Kconfig b/board/st/stm32h743-eval/Kconfig
new file mode 100644
index 0000000000..ea879b13c8
--- /dev/null
+++ b/board/st/stm32h743-eval/Kconfig
@@ -0,0 +1,19 @@
+if TARGET_STM32H743_EVAL
+
+config SYS_BOARD
+ string
+ default "stm32h743-eval"
+
+config SYS_VENDOR
+ string
+ default "st"
+
+config SYS_SOC
+ string
+ default "stm32h7"
+
+config SYS_CONFIG_NAME
+ string
+ default "stm32h743-eval"
+
+endif
diff --git a/board/st/stm32h743-eval/MAINTAINERS b/board/st/stm32h743-eval/MAINTAINERS
new file mode 100644
index 0000000000..3029c56023
--- /dev/null
+++ b/board/st/stm32h743-eval/MAINTAINERS
@@ -0,0 +1,6 @@
+STM32H743 EVALUATION BOARD
+M: Patrice Chotard <patrice.chotard@st.com>
+S: Maintained
+F: board/st/stm32h743-eval
+F: include/configs/stm32h743-eval.h
+F: configs/stm32h743-eval_defconfig
diff --git a/board/st/stm32h743-eval/Makefile b/board/st/stm32h743-eval/Makefile
new file mode 100644
index 0000000000..4f25b2d96b
--- /dev/null
+++ b/board/st/stm32h743-eval/Makefile
@@ -0,0 +1,8 @@
+#
+# (C) Copyright 2017
+# Patrice Chotard, <patrice.chotard@st.com>
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+obj-y := stm32h743-eval.o
diff --git a/board/st/stm32h743-eval/stm32h743-eval.c b/board/st/stm32h743-eval/stm32h743-eval.c
new file mode 100644
index 0000000000..625b3a077b
--- /dev/null
+++ b/board/st/stm32h743-eval/stm32h743-eval.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) STMicroelectronics SA 2017
+ * Author(s): Patrice CHOTARD, <patrice.chotard@st.com> for STMicroelectronics.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int dram_init(void)
+{
+ struct udevice *dev;
+ int ret;
+
+ ret = uclass_get_device(UCLASS_RAM, 0, &dev);
+ if (ret) {
+ debug("DRAM init failed: %d\n", ret);
+ return ret;
+ }
+
+ if (fdtdec_setup_memory_size() != 0)
+ ret = -EINVAL;
+
+ return ret;
+}
+
+int dram_init_banksize(void)
+{
+ fdtdec_setup_memory_banksize();
+
+ return 0;
+}
+
+int board_early_init_f(void)
+{
+ return 0;
+}
+
+u32 get_board_rev(void)
+{
+ return 0;
+}
+
+int board_late_init(void)
+{
+ return 0;
+}
+
+int board_init(void)
+{
+ gd->bd->bi_boot_params = gd->bd->bi_dram[0].start + 0x100;
+ return 0;
+}
diff --git a/board/technexion/pico-imx7d/README b/board/technexion/pico-imx7d/README
index a2805ee080..8af4effa78 100644
--- a/board/technexion/pico-imx7d/README
+++ b/board/technexion/pico-imx7d/README
@@ -47,3 +47,20 @@ Remove power from the pico board.
Put pico board into normal boot mode.
Power up the board and the new updated U-Boot should boot from eMMC.
+
+Building U-Boot to boot with NXP 4.1 kernel:
+
+The NXP 4.1 kernel boots only in secure boot mode on mx7.
+
+Follow the next steps to enable secure boot:
+
+$ make mrproper
+$ make pico-imx7d_defconfig
+$ make menuconfig
+ -> ARM architecture
+ -> [*] Enable support for booting in non-secure mode
+ -> [*] Boot in secure mode by default
+ -> Exit
+$ make
+
+Flash u-boot.imx using the imx_usb_loader tool.
diff --git a/board/technexion/pico-imx7d/pico-imx7d.c b/board/technexion/pico-imx7d/pico-imx7d.c
index b4c9be7378..67bab51dfd 100644
--- a/board/technexion/pico-imx7d/pico-imx7d.c
+++ b/board/technexion/pico-imx7d/pico-imx7d.c
@@ -182,7 +182,7 @@ static int setup_fec(void)
(IOMUXC_GPR_GPR1_GPR_ENET1_TX_CLK_SEL_MASK |
IOMUXC_GPR_GPR1_GPR_ENET1_CLK_DIR_MASK), 0);
- return set_clk_enet(ENET_125MHz);
+ return set_clk_enet(ENET_125MHZ);
}
int board_phy_config(struct phy_device *phydev)
diff --git a/board/theadorable/MAINTAINERS b/board/theadorable/MAINTAINERS
index 5ae6b6487c..1e8df93d37 100644
--- a/board/theadorable/MAINTAINERS
+++ b/board/theadorable/MAINTAINERS
@@ -4,4 +4,3 @@ S: Maintained
F: board/theadorable/
F: include/configs/theadorable.h
F: configs/theadorable_debug_defconfig
-F: configs/theadorable_defconfig
diff --git a/board/theobroma-systems/lion_rk3368/README b/board/theobroma-systems/lion_rk3368/README
index 47304fcba6..83e4332984 100644
--- a/board/theobroma-systems/lion_rk3368/README
+++ b/board/theobroma-systems/lion_rk3368/README
@@ -26,12 +26,32 @@ Build the full U-Boot and a FIT image including the ATF
> make CROSS_COMPILE=aarch64-unknown-elf- ARCH=arm u-boot.itb
-Write to a SD-card
-==================
+Flash the image
+===============
+
+Copy the SPL to offset 32k and the FIT image containing the payloads
+(U-Boot proper, ATF, devicetree) to offset 256k card.
+
+SD-Card
+-------
> dd if=spl-3368.img of=/dev/sdb seek=64
> dd if=u-boot.itb of=/dev/sdb seek=512
+eMMC
+----
+
+rkdeveloptool allows to flash the on-board eMMC via the USB OTG interface with
+help of the Rockchip loader binary.
+
+ > git clone https://github.com/rockchip-linux/rkdeveloptool
+ > cd rkdeveloptool
+ > autoreconf -i && && ./configure && make
+ > git clone https://github.com/rockchip-linux/rkbin.git
+ > ./rkdeveloptool db rkbin/rk33/rk3368_loader_v2.00.256.bin
+ > ./rkdeveloptool wl 64 ../spl.img
+ > ./rkdeveloptool wl 512 ../u-boot.itb
+
If everything went according to plan, you should see the following
output on UART0:
diff --git a/board/theobroma-systems/puma_rk3399/README b/board/theobroma-systems/puma_rk3399/README
index 214281a329..f67dfb451f 100644
--- a/board/theobroma-systems/puma_rk3399/README
+++ b/board/theobroma-systems/puma_rk3399/README
@@ -55,18 +55,53 @@ Compile the U-Boot
Package the image
=================
- > tools/mkimage -n rk3399 -T rksd -d spl/u-boot-spl.bin spl.img
- > make CROSS_COMPILE=aarch64-linux-gnu- u-boot.itb
+Creating a SPL image for SD-Card/eMMC
+ > tools/mkimage -n rk3399 -T rksd -d spl/u-boot-spl.bin spl_mmc.img
+Creating a SPL image for SPI-NOR
+ > tools/mkimage -n rk3399 -T rkspi -d spl/u-boot-spl.bin spl_nor.img
+Create the FIT image containing U-Boot proper, ATF, M0 Firmware, devicetree
+ > make CROSS_COMPILE=aarch64-linux-gnu- u-boot.itb
Flash the image
===============
-Copy the SPL to offset 32k and the FIT image containing the payloads
-(U-Boot proper, ATF, M0 Firmware, devicetree) to offset 256k on a SD
-card.
+Copy the SPL to offset 32k for SD/eMMC, offset 0 for NOR-Flash and the FIT
+image to offset 256k card.
- > dd if=spl.img of=/dev/sdb seek=64
+SD-Card
+-------
+
+ > dd if=spl_mmc.img of=/dev/sdb seek=64
> dd if=u-boot.itb of=/dev/sdb seek=512
-After powering up the board (with the inserted SD card), you should see
-a U-Boot console on UART0 (115200n8).
+eMMC
+----
+
+rkdeveloptool allows to flash the on-board eMMC via the USB OTG interface with
+help of the Rockchip loader binary.
+
+ > git clone https://github.com/rockchip-linux/rkdeveloptool
+ > cd rkdeveloptool
+ > autoreconf -i && ./configure && make
+ > git clone https://github.com/rockchip-linux/rkbin.git
+ > ./rkdeveloptool db rkbin/rk33/rk3399_loader_v1.08.106.bin
+ > ./rkdeveloptool wl 64 ../spl_mmc.img
+ > ./rkdeveloptool wl 512 ../u-boot.itb
+
+NOR-Flash
+---------
+
+Writing the SPI NOR Flash requires a running U-Boot. For the sake of simplicity
+we assume you have a SD-Card with a partition containing the required files
+ready.
+
+ > load mmc 1:1 ${kernel_addr_r} spl_nor.img
+ > sf probe
+ > sf erase 0 +$filesize
+ > sf write $kernel_addr_r 0 ${filesize}
+ > load mmc 1:1 ${kernel_addr_r} u-boot.itb
+ > sf erase 0x40000 +$filesize
+ > sf write $kernel_addr_r 0x40000 ${filesize}
+
+
+Reboot the system and you should see a U-Boot console on UART0 (115200n8).
diff --git a/board/theobroma-systems/puma_rk3399/puma-rk3399.c b/board/theobroma-systems/puma_rk3399/puma-rk3399.c
index c6f8eed0c9..45d56cd99e 100644
--- a/board/theobroma-systems/puma_rk3399/puma-rk3399.c
+++ b/board/theobroma-systems/puma_rk3399/puma-rk3399.c
@@ -107,7 +107,7 @@ static void setup_serial(void)
u8 low[cpuid_length/2], high[cpuid_length/2];
char cpuid_str[cpuid_length * 2 + 1];
u64 serialno;
- char serialno_str[16];
+ char serialno_str[17];
/* retrieve the device */
ret = uclass_get_device_by_driver(UCLASS_MISC,
diff --git a/board/toradex/apalis_imx6/apalis_imx6.c b/board/toradex/apalis_imx6/apalis_imx6.c
index ebc6c12cbc..628a61dae0 100644
--- a/board/toradex/apalis_imx6/apalis_imx6.c
+++ b/board/toradex/apalis_imx6/apalis_imx6.c
@@ -29,7 +29,6 @@
#include <dm/platform_data/serial_mxc.h>
#include <dm/platdata.h>
#include <fsl_esdhc.h>
-#include <g_dnl.h>
#include <i2c.h>
#include <imx_thermal.h>
#include <linux/errno.h>
@@ -1224,18 +1223,6 @@ void reset_cpu(ulong addr)
{
}
-#ifdef CONFIG_SPL_USB_GADGET_SUPPORT
-int g_dnl_bind_fixup(struct usb_device_descriptor *dev, const char *name)
-{
- unsigned short usb_pid;
-
- usb_pid = TORADEX_USB_PRODUCT_NUM_OFFSET + 0xfff;
- put_unaligned(usb_pid, &dev->idProduct);
-
- return 0;
-}
-#endif
-
#endif
static struct mxc_serial_platdata mxc_serial_plat = {
diff --git a/board/toradex/colibri_imx6/colibri_imx6.c b/board/toradex/colibri_imx6/colibri_imx6.c
index 669d9123ca..756e3f39df 100644
--- a/board/toradex/colibri_imx6/colibri_imx6.c
+++ b/board/toradex/colibri_imx6/colibri_imx6.c
@@ -28,7 +28,6 @@
#include <dm/platform_data/serial_mxc.h>
#include <dm/platdata.h>
#include <fsl_esdhc.h>
-#include <g_dnl.h>
#include <i2c.h>
#include <imx_thermal.h>
#include <linux/errno.h>
@@ -1108,18 +1107,6 @@ void reset_cpu(ulong addr)
{
}
-#ifdef CONFIG_SPL_USB_GADGET_SUPPORT
-int g_dnl_bind_fixup(struct usb_device_descriptor *dev, const char *name)
-{
- unsigned short usb_pid;
-
- usb_pid = TORADEX_USB_PRODUCT_NUM_OFFSET + 0xfff;
- put_unaligned(usb_pid, &dev->idProduct);
-
- return 0;
-}
-#endif
-
#endif
static struct mxc_serial_platdata mxc_serial_plat = {
diff --git a/board/toradex/colibri_imx7/colibri_imx7.c b/board/toradex/colibri_imx7/colibri_imx7.c
index 5cb14b43de..13b2b5785b 100644
--- a/board/toradex/colibri_imx7/colibri_imx7.c
+++ b/board/toradex/colibri_imx7/colibri_imx7.c
@@ -280,7 +280,7 @@ static int setup_fec(void)
IOMUXC_GPR_GPR1_GPR_ENET1_TX_CLK_SEL_MASK);
#endif
- return set_clk_enet(ENET_50MHz);
+ return set_clk_enet(ENET_50MHZ);
}
int board_phy_config(struct phy_device *phydev)
diff --git a/board/udoo/udoo_spl.c b/board/udoo/udoo_spl.c
index 3645969e43..694055bd2e 100644
--- a/board/udoo/udoo_spl.c
+++ b/board/udoo/udoo_spl.c
@@ -252,11 +252,5 @@ void board_init_f(ulong dummy)
/* DDR initialization */
spl_dram_init();
-
- /* Clear the BSS. */
- memset(__bss_start, 0, __bss_end - __bss_start);
-
- /* load/boot image from boot device */
- board_init_r(NULL, 0);
}
#endif
diff --git a/board/wandboard/spl.c b/board/wandboard/spl.c
index 99a02865ec..00c75d0682 100644
--- a/board/wandboard/spl.c
+++ b/board/wandboard/spl.c
@@ -300,11 +300,5 @@ void board_init_f(ulong dummy)
/* DDR initialization */
spl_dram_init();
-
- /* Clear the BSS. */
- memset(__bss_start, 0, __bss_end - __bss_start);
-
- /* load/boot image from boot device */
- board_init_r(NULL, 0);
}
#endif
diff --git a/cmd/gpt.c b/cmd/gpt.c
index 638aa19826..d4406e3120 100644
--- a/cmd/gpt.c
+++ b/cmd/gpt.c
@@ -190,10 +190,9 @@ static void del_gpt_info(void)
static struct disk_part *allocate_disk_part(disk_partition_t *info, int partnum)
{
struct disk_part *newpart;
- newpart = malloc(sizeof(*newpart));
+ newpart = calloc(1, sizeof(struct disk_part));
if (!newpart)
return ERR_PTR(-ENOMEM);
- memset(newpart, '\0', sizeof(newpart));
newpart->gpt_part_info.start = info->start;
newpart->gpt_part_info.size = info->size;
diff --git a/common/Makefile b/common/Makefile
index 1b56cf9a70..801ea3191f 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -63,7 +63,7 @@ obj-$(CONFIG_CMDLINE) += cli_readline.o cli_simple.o
endif # !CONFIG_SPL_BUILD
-obj-$(CONFIG_$(SPL_)BOOTSTAGE) += bootstage.o
+obj-$(CONFIG_$(SPL_TPL_)BOOTSTAGE) += bootstage.o
ifdef CONFIG_SPL_BUILD
obj-$(CONFIG_SPL_DFU_SUPPORT) += dfu.o
diff --git a/common/spl/Kconfig b/common/spl/Kconfig
index b05ec21ed6..0bd8370337 100644
--- a/common/spl/Kconfig
+++ b/common/spl/Kconfig
@@ -94,6 +94,7 @@ config SPL_STACK_R
config SPL_STACK_R_ADDR
depends on SPL_STACK_R
hex "SDRAM location for SPL stack"
+ default 0x82000000 if ARCH_OMAP2PLUS
help
Specify the address in SDRAM for the SPL stack. This will be set up
before board_init_r() is called.
diff --git a/common/spl/spl.c b/common/spl/spl.c
index ce9819e4db..4afbe97fc1 100644
--- a/common/spl/spl.c
+++ b/common/spl/spl.c
@@ -424,13 +424,6 @@ void board_init_r(gd_t *dummy1, ulong dummy2)
debug("SPL malloc() used %#lx bytes (%ld KB)\n", gd->malloc_ptr,
gd->malloc_ptr / 1024);
#endif
-
- if (CONFIG_IS_ENABLED(ATF_SUPPORT)) {
- debug("loaded - jumping to U-Boot via ATF BL31.\n");
- bl31_entry();
- }
-
- debug("loaded - jumping to U-Boot...\n");
#ifdef CONFIG_BOOTSTAGE_STASH
int ret;
@@ -440,6 +433,13 @@ void board_init_r(gd_t *dummy1, ulong dummy2)
if (ret)
debug("Failed to stash bootstage: err=%d\n", ret);
#endif
+
+ if (CONFIG_IS_ENABLED(ATF_SUPPORT)) {
+ debug("loaded - jumping to U-Boot via ATF BL31.\n");
+ bl31_entry();
+ }
+
+ debug("loaded - jumping to U-Boot...\n");
spl_board_prepare_for_boot();
jump_to_image_no_args(&spl_image);
}
diff --git a/common/spl/spl_fit.c b/common/spl/spl_fit.c
index 49ccf1c17b..32d9ee5901 100644
--- a/common/spl/spl_fit.c
+++ b/common/spl/spl_fit.c
@@ -135,6 +135,7 @@ static int spl_load_fit_image(struct spl_load_info *info, ulong sector,
int offset;
size_t length;
int len;
+ ulong size;
ulong load_addr, load_ptr;
void *src;
ulong overhead;
@@ -197,11 +198,13 @@ static int spl_load_fit_image(struct spl_load_info *info, ulong sector,
IS_ENABLED(CONFIG_SPL_GZIP) &&
image_comp == IH_COMP_GZIP &&
type == IH_TYPE_KERNEL) {
+ size = length;
if (gunzip((void *)load_addr, CONFIG_SYS_BOOTM_LEN,
- src, &length)) {
+ src, &size)) {
puts("Uncompressing error\n");
return -EIO;
}
+ length = size;
} else {
memcpy((void *)load_addr, src, length);
}
diff --git a/common/spl/spl_mmc.c b/common/spl/spl_mmc.c
index b2cccc6c6e..b57e0b04e4 100644
--- a/common/spl/spl_mmc.c
+++ b/common/spl/spl_mmc.c
@@ -52,8 +52,9 @@ static ulong h_spl_load_read(struct spl_load_info *load, ulong sector,
return blk_dread(mmc_get_blk_desc(mmc), sector, count, buf);
}
-static int mmc_load_image_raw_sector(struct spl_image_info *spl_image,
- struct mmc *mmc, unsigned long sector)
+static __maybe_unused
+int mmc_load_image_raw_sector(struct spl_image_info *spl_image,
+ struct mmc *mmc, unsigned long sector)
{
unsigned long count;
struct image_header *header;
diff --git a/common/usb_storage.c b/common/usb_storage.c
index df0b057308..a57570b73f 100644
--- a/common/usb_storage.c
+++ b/common/usb_storage.c
@@ -98,19 +98,9 @@ struct us_data {
struct scsi_cmd *srb; /* current srb */
trans_reset transport_reset; /* reset routine */
trans_cmnd transport; /* transport routine */
+ unsigned short max_xfer_blk; /* maximum transfer blocks */
};
-#ifdef CONFIG_USB_EHCI_HCD
-/*
- * The U-Boot EHCI driver can handle any transfer length as long as there is
- * enough free heap space left, but the SCSI READ(10) and WRITE(10) commands are
- * limited to 65535 blocks.
- */
-#define USB_MAX_XFER_BLK 65535
-#else
-#define USB_MAX_XFER_BLK 20
-#endif
-
#ifndef CONFIG_BLK
static struct us_data usb_stor[USB_MAX_STOR_DEV];
#endif
@@ -949,6 +939,38 @@ do_retry:
return USB_STOR_TRANSPORT_FAILED;
}
+static void usb_stor_set_max_xfer_blk(struct usb_device *udev,
+ struct us_data *us)
+{
+ unsigned short blk;
+ size_t __maybe_unused size;
+ int __maybe_unused ret;
+
+#ifndef CONFIG_DM_USB
+#ifdef CONFIG_USB_EHCI_HCD
+ /*
+ * The U-Boot EHCI driver can handle any transfer length as long as
+ * there is enough free heap space left, but the SCSI READ(10) and
+ * WRITE(10) commands are limited to 65535 blocks.
+ */
+ blk = USHRT_MAX;
+#else
+ blk = 20;
+#endif
+#else
+ ret = usb_get_max_xfer_size(udev, (size_t *)&size);
+ if (ret < 0) {
+ /* unimplemented, let's use default 20 */
+ blk = 20;
+ } else {
+ if (size > USHRT_MAX * 512)
+ blk = USHRT_MAX;
+ blk = size / 512;
+ }
+#endif
+
+ us->max_xfer_blk = blk;
+}
static int usb_inquiry(struct scsi_cmd *srb, struct us_data *ss)
{
@@ -1150,12 +1172,12 @@ static unsigned long usb_stor_read(struct blk_desc *block_dev, lbaint_t blknr,
/* XXX need some comment here */
retry = 2;
srb->pdata = (unsigned char *)buf_addr;
- if (blks > USB_MAX_XFER_BLK)
- smallblks = USB_MAX_XFER_BLK;
+ if (blks > ss->max_xfer_blk)
+ smallblks = ss->max_xfer_blk;
else
smallblks = (unsigned short) blks;
retry_it:
- if (smallblks == USB_MAX_XFER_BLK)
+ if (smallblks == ss->max_xfer_blk)
usb_show_progress();
srb->datalen = block_dev->blksz * smallblks;
srb->pdata = (unsigned char *)buf_addr;
@@ -1178,7 +1200,7 @@ retry_it:
start, smallblks, buf_addr);
usb_disable_asynch(0); /* asynch transfer allowed */
- if (blkcnt >= USB_MAX_XFER_BLK)
+ if (blkcnt >= ss->max_xfer_blk)
debug("\n");
return blkcnt;
}
@@ -1236,12 +1258,12 @@ static unsigned long usb_stor_write(struct blk_desc *block_dev, lbaint_t blknr,
*/
retry = 2;
srb->pdata = (unsigned char *)buf_addr;
- if (blks > USB_MAX_XFER_BLK)
- smallblks = USB_MAX_XFER_BLK;
+ if (blks > ss->max_xfer_blk)
+ smallblks = ss->max_xfer_blk;
else
smallblks = (unsigned short) blks;
retry_it:
- if (smallblks == USB_MAX_XFER_BLK)
+ if (smallblks == ss->max_xfer_blk)
usb_show_progress();
srb->datalen = block_dev->blksz * smallblks;
srb->pdata = (unsigned char *)buf_addr;
@@ -1263,7 +1285,7 @@ retry_it:
PRIxPTR "\n", start, smallblks, buf_addr);
usb_disable_asynch(0); /* asynch transfer allowed */
- if (blkcnt >= USB_MAX_XFER_BLK)
+ if (blkcnt >= ss->max_xfer_blk)
debug("\n");
return blkcnt;
@@ -1384,6 +1406,10 @@ int usb_storage_probe(struct usb_device *dev, unsigned int ifnum,
ss->irqmaxp = usb_maxpacket(dev, ss->irqpipe);
dev->irq_handle = usb_stor_irq;
}
+
+ /* Set the maximum transfer size per host controller setting */
+ usb_stor_set_max_xfer_blk(dev, ss);
+
dev->privptr = (void *)ss;
return 1;
}
diff --git a/configs/Cyrus_P5020_defconfig b/configs/Cyrus_P5020_defconfig
index 82da854386..37f78a4811 100644
--- a/configs/Cyrus_P5020_defconfig
+++ b/configs/Cyrus_P5020_defconfig
@@ -34,5 +34,4 @@ CONFIG_FSL_ESPI=y
CONFIG_USB=y
CONFIG_USB_STORAGE=y
CONFIG_USB_KEYBOARD=y
-CONFIG_SYS_USB_EVENT_POLL=y
CONFIG_OF_LIBFDT=y
diff --git a/configs/Cyrus_P5040_defconfig b/configs/Cyrus_P5040_defconfig
index 0fc9a07548..d33b514ee0 100644
--- a/configs/Cyrus_P5040_defconfig
+++ b/configs/Cyrus_P5040_defconfig
@@ -34,5 +34,4 @@ CONFIG_FSL_ESPI=y
CONFIG_USB=y
CONFIG_USB_STORAGE=y
CONFIG_USB_KEYBOARD=y
-CONFIG_SYS_USB_EVENT_POLL=y
CONFIG_OF_LIBFDT=y
diff --git a/configs/MPC8610HPCD_defconfig b/configs/MPC8610HPCD_defconfig
index fde837c011..c71d5b18e1 100644
--- a/configs/MPC8610HPCD_defconfig
+++ b/configs/MPC8610HPCD_defconfig
@@ -22,5 +22,4 @@ CONFIG_SCSI=y
CONFIG_SYS_NS16550=y
CONFIG_USB=y
CONFIG_USB_KEYBOARD=y
-CONFIG_SYS_USB_EVENT_POLL=y
CONFIG_OF_LIBFDT=y
diff --git a/configs/MPC8641HPCN_36BIT_defconfig b/configs/MPC8641HPCN_36BIT_defconfig
index 7318e723a8..9949e8b699 100644
--- a/configs/MPC8641HPCN_36BIT_defconfig
+++ b/configs/MPC8641HPCN_36BIT_defconfig
@@ -21,5 +21,4 @@ CONFIG_PHYLIB=y
CONFIG_SYS_NS16550=y
CONFIG_USB=y
CONFIG_USB_KEYBOARD=y
-CONFIG_SYS_USB_EVENT_POLL=y
CONFIG_OF_LIBFDT=y
diff --git a/configs/MPC8641HPCN_defconfig b/configs/MPC8641HPCN_defconfig
index def36e4171..c8440d2584 100644
--- a/configs/MPC8641HPCN_defconfig
+++ b/configs/MPC8641HPCN_defconfig
@@ -21,5 +21,4 @@ CONFIG_PHYLIB=y
CONFIG_SYS_NS16550=y
CONFIG_USB=y
CONFIG_USB_KEYBOARD=y
-CONFIG_SYS_USB_EVENT_POLL=y
CONFIG_OF_LIBFDT=y
diff --git a/configs/adp-ae3xx_defconfig b/configs/adp-ae3xx_defconfig
index 9e1e5ecb47..c1053958c4 100644
--- a/configs/adp-ae3xx_defconfig
+++ b/configs/adp-ae3xx_defconfig
@@ -5,6 +5,8 @@ CONFIG_FIT=y
CONFIG_BOOTDELAY=3
CONFIG_SYS_PROMPT="NDS32 # "
CONFIG_CMD_MMC=y
+CONFIG_CMD_SF=y
+CONFIG_CMD_SF_TEST=y
# CONFIG_CMD_SETEXPR is not set
CONFIG_CMD_DHCP=y
CONFIG_CMD_PING=y
@@ -13,17 +15,23 @@ CONFIG_CMD_DATE=y
CONFIG_CMD_EXT2=y
CONFIG_CMD_FAT=y
CONFIG_OF_CONTROL=y
-CONFIG_ENV_IS_IN_FLASH=y
+CONFIG_ENV_IS_IN_SPI_FLASH=y
CONFIG_NET_RANDOM_ETHADDR=y
CONFIG_DM=y
+CONFIG_CLK=y
CONFIG_MMC=y
CONFIG_MTD=y
CONFIG_MTD_NOR_FLASH=y
CONFIG_CFI_FLASH=y
+CONFIG_DM_SPI_FLASH=y
+CONFIG_SPI_FLASH=y
+CONFIG_SPI_FLASH_MACRONIX=y
CONFIG_DM_ETH=y
CONFIG_FTMAC100=y
CONFIG_BAUDRATE=38400
CONFIG_DM_SERIAL=y
CONFIG_SYS_NS16550=y
+CONFIG_DM_SPI=y
+CONFIG_NDS_AE3XX_SPI=y
CONFIG_TIMER=y
CONFIG_AE3XX_TIMER=y
diff --git a/configs/am335x_baltos_defconfig b/configs/am335x_baltos_defconfig
index eb8338f0f1..2842694dbc 100644
--- a/configs/am335x_baltos_defconfig
+++ b/configs/am335x_baltos_defconfig
@@ -10,7 +10,6 @@ CONFIG_SPL_SERIAL_SUPPORT=y
CONFIG_SPL_LIBDISK_SUPPORT=y
CONFIG_SPL_NAND_SUPPORT=y
CONFIG_SPL_WATCHDOG_SUPPORT=y
-CONFIG_SPL_STACK_R_ADDR=0x82000000
CONFIG_SPL_FAT_SUPPORT=y
CONFIG_FIT_VERBOSE=y
CONFIG_OF_BOARD_SETUP=y
@@ -18,7 +17,6 @@ CONFIG_SYS_CONSOLE_INFO_QUIET=y
CONFIG_VERSION_VARIABLE=y
CONFIG_ARCH_MISC_INIT=y
CONFIG_SPL=y
-CONFIG_SPL_STACK_R=y
CONFIG_SPL_EXT_SUPPORT=y
CONFIG_SPL_I2C_SUPPORT=y
CONFIG_SPL_MTD_SUPPORT=y
diff --git a/configs/am335x_boneblack_defconfig b/configs/am335x_boneblack_defconfig
index b8526fc15e..2fc25fbaab 100644
--- a/configs/am335x_boneblack_defconfig
+++ b/configs/am335x_boneblack_defconfig
@@ -3,14 +3,12 @@ CONFIG_ARCH_OMAP2PLUS=y
CONFIG_TI_COMMON_CMD_OPTIONS=y
CONFIG_AM33XX=y
# CONFIG_SPL_NAND_SUPPORT is not set
-CONFIG_SPL_STACK_R_ADDR=0x82000000
CONFIG_DISTRO_DEFAULTS=y
CONFIG_SYS_EXTRA_OPTIONS="EMMC_BOOT"
CONFIG_SYS_CONSOLE_INFO_QUIET=y
CONFIG_VERSION_VARIABLE=y
CONFIG_ARCH_MISC_INIT=y
CONFIG_SPL=y
-CONFIG_SPL_STACK_R=y
CONFIG_SPL_MUSB_NEW_SUPPORT=y
CONFIG_SPL_OS_BOOT=y
CONFIG_AUTOBOOT_KEYED=y
diff --git a/configs/am335x_boneblack_vboot_defconfig b/configs/am335x_boneblack_vboot_defconfig
index 0a239bb733..e8bcb6d0c8 100644
--- a/configs/am335x_boneblack_vboot_defconfig
+++ b/configs/am335x_boneblack_vboot_defconfig
@@ -3,7 +3,6 @@ CONFIG_ARCH_OMAP2PLUS=y
CONFIG_TI_COMMON_CMD_OPTIONS=y
CONFIG_AM33XX=y
# CONFIG_SPL_NAND_SUPPORT is not set
-CONFIG_SPL_STACK_R_ADDR=0x82000000
CONFIG_DEFAULT_DEVICE_TREE="am335x-boneblack"
CONFIG_DISTRO_DEFAULTS=y
CONFIG_FIT_SIGNATURE=y
@@ -13,7 +12,6 @@ CONFIG_SYS_CONSOLE_INFO_QUIET=y
CONFIG_VERSION_VARIABLE=y
CONFIG_ARCH_MISC_INIT=y
CONFIG_SPL=y
-CONFIG_SPL_STACK_R=y
CONFIG_SPL_MUSB_NEW_SUPPORT=y
CONFIG_SPL_OS_BOOT=y
CONFIG_AUTOBOOT_KEYED=y
diff --git a/configs/am335x_evm_defconfig b/configs/am335x_evm_defconfig
index 00c1af4344..b6a7cf0e5c 100644
--- a/configs/am335x_evm_defconfig
+++ b/configs/am335x_evm_defconfig
@@ -2,7 +2,6 @@ CONFIG_ARM=y
CONFIG_ARCH_OMAP2PLUS=y
CONFIG_TI_COMMON_CMD_OPTIONS=y
CONFIG_AM33XX=y
-CONFIG_SPL_STACK_R_ADDR=0x82000000
CONFIG_DEFAULT_DEVICE_TREE="am335x-evm"
CONFIG_DISTRO_DEFAULTS=y
CONFIG_SPL_LOAD_FIT=y
@@ -10,7 +9,6 @@ CONFIG_SYS_CONSOLE_INFO_QUIET=y
CONFIG_VERSION_VARIABLE=y
CONFIG_ARCH_MISC_INIT=y
CONFIG_SPL=y
-CONFIG_SPL_STACK_R=y
CONFIG_SPL_MTD_SUPPORT=y
CONFIG_SPL_MUSB_NEW_SUPPORT=y
CONFIG_SPL_OS_BOOT=y
diff --git a/configs/am335x_evm_nor_defconfig b/configs/am335x_evm_nor_defconfig
index 9f08edff4c..e2fc822c2f 100644
--- a/configs/am335x_evm_nor_defconfig
+++ b/configs/am335x_evm_nor_defconfig
@@ -3,13 +3,11 @@ CONFIG_ARCH_OMAP2PLUS=y
CONFIG_TI_COMMON_CMD_OPTIONS=y
CONFIG_AM33XX=y
CONFIG_NOR=y
-CONFIG_SPL_STACK_R_ADDR=0x82000000
CONFIG_DISTRO_DEFAULTS=y
CONFIG_SYS_CONSOLE_INFO_QUIET=y
CONFIG_VERSION_VARIABLE=y
CONFIG_ARCH_MISC_INIT=y
CONFIG_SPL=y
-CONFIG_SPL_STACK_R=y
CONFIG_SPL_MTD_SUPPORT=y
CONFIG_SPL_MUSB_NEW_SUPPORT=y
CONFIG_SPL_OS_BOOT=y
diff --git a/configs/am335x_evm_spiboot_defconfig b/configs/am335x_evm_spiboot_defconfig
index 501fb2b90f..a53e5aee83 100644
--- a/configs/am335x_evm_spiboot_defconfig
+++ b/configs/am335x_evm_spiboot_defconfig
@@ -5,7 +5,6 @@ CONFIG_AM33XX=y
# CONFIG_SPL_NAND_SUPPORT is not set
CONFIG_SPL_SPI_FLASH_SUPPORT=y
CONFIG_SPL_SPI_SUPPORT=y
-CONFIG_SPL_STACK_R_ADDR=0x82000000
CONFIG_DISTRO_DEFAULTS=y
CONFIG_SYS_EXTRA_OPTIONS="SPI_BOOT"
CONFIG_SPI_BOOT=y
@@ -13,7 +12,6 @@ CONFIG_SYS_CONSOLE_INFO_QUIET=y
CONFIG_VERSION_VARIABLE=y
CONFIG_ARCH_MISC_INIT=y
CONFIG_SPL=y
-CONFIG_SPL_STACK_R=y
CONFIG_SPL_MUSB_NEW_SUPPORT=y
CONFIG_FASTBOOT=y
CONFIG_USB_FUNCTION_FASTBOOT=y
diff --git a/configs/am335x_evm_usbspl_defconfig b/configs/am335x_evm_usbspl_defconfig
index 7c351382d9..7b003ee777 100644
--- a/configs/am335x_evm_usbspl_defconfig
+++ b/configs/am335x_evm_usbspl_defconfig
@@ -3,14 +3,12 @@ CONFIG_ARCH_OMAP2PLUS=y
CONFIG_TI_COMMON_CMD_OPTIONS=y
CONFIG_AM33XX=y
# CONFIG_SPL_NAND_SUPPORT is not set
-CONFIG_SPL_STACK_R_ADDR=0x82000000
CONFIG_DISTRO_DEFAULTS=y
# CONFIG_ANDROID_BOOT_IMAGE is not set
CONFIG_SYS_CONSOLE_INFO_QUIET=y
CONFIG_VERSION_VARIABLE=y
CONFIG_ARCH_MISC_INIT=y
CONFIG_SPL=y
-CONFIG_SPL_STACK_R=y
CONFIG_SPL_MUSB_NEW_SUPPORT=y
CONFIG_SPL_NET_SUPPORT=y
CONFIG_SPL_OS_BOOT=y
diff --git a/configs/am335x_hs_evm_defconfig b/configs/am335x_hs_evm_defconfig
index acdd56b435..af5233c5fc 100644
--- a/configs/am335x_hs_evm_defconfig
+++ b/configs/am335x_hs_evm_defconfig
@@ -5,7 +5,6 @@ CONFIG_AM33XX=y
CONFIG_TI_SECURE_DEVICE=y
CONFIG_ISW_ENTRY_ADDR=0x40300350
# CONFIG_SPL_NAND_SUPPORT is not set
-CONFIG_SPL_STACK_R_ADDR=0x82000000
CONFIG_DEFAULT_DEVICE_TREE="am335x-evm"
CONFIG_DISTRO_DEFAULTS=y
CONFIG_ANDROID_BOOT_IMAGE=y
@@ -16,7 +15,6 @@ CONFIG_SYS_CONSOLE_INFO_QUIET=y
CONFIG_VERSION_VARIABLE=y
CONFIG_ARCH_MISC_INIT=y
CONFIG_SPL=y
-CONFIG_SPL_STACK_R=y
# CONFIG_SPL_ENV_SUPPORT is not set
# CONFIG_SPL_EXT_SUPPORT is not set
CONFIG_SPL_MTD_SUPPORT=y
diff --git a/configs/am335x_hs_evm_uart_defconfig b/configs/am335x_hs_evm_uart_defconfig
new file mode 100644
index 0000000000..1c453fb23a
--- /dev/null
+++ b/configs/am335x_hs_evm_uart_defconfig
@@ -0,0 +1,67 @@
+CONFIG_ARM=y
+CONFIG_ARCH_OMAP2PLUS=y
+CONFIG_TI_COMMON_CMD_OPTIONS=y
+CONFIG_AM33XX=y
+# CONFIG_SPL_FAT_SUPPORT is not set
+# CONFIG_SPL_LIBDISK_SUPPORT is not set
+# CONFIG_SPL_MMC_SUPPORT is not set
+# CONFIG_SPL_NAND_SUPPORT is not set
+CONFIG_TI_SECURE_DEVICE=y
+CONFIG_ISW_ENTRY_ADDR=0x40301950
+CONFIG_SPL_STACK_R_ADDR=0x82000000
+CONFIG_DEFAULT_DEVICE_TREE="am335x-evm"
+CONFIG_DISTRO_DEFAULTS=y
+CONFIG_FIT_IMAGE_POST_PROCESS=y
+CONFIG_SPL_LOAD_FIT=y
+CONFIG_SPL_FIT_IMAGE_POST_PROCESS=y
+CONFIG_SYS_CONSOLE_INFO_QUIET=y
+CONFIG_VERSION_VARIABLE=y
+CONFIG_ARCH_MISC_INIT=y
+CONFIG_SPL=y
+CONFIG_SPL_SYS_MALLOC_SIMPLE=y
+CONFIG_SPL_STACK_R=y
+# CONFIG_SPL_ENV_SUPPORT is not set
+# CONFIG_SPL_EXT_SUPPORT is not set
+CONFIG_SPL_MTD_SUPPORT=y
+# CONFIG_SPL_YMODEM_SUPPORT is not set
+# CONFIG_CMD_IMLS is not set
+# CONFIG_CMD_FLASH is not set
+CONFIG_CMD_NAND=y
+# CONFIG_CMD_SETEXPR is not set
+CONFIG_CMD_MTDPARTS=y
+# CONFIG_SPL_EFI_PARTITION is not set
+CONFIG_OF_CONTROL=y
+CONFIG_OF_LIST="am335x-evm am335x-bone am335x-boneblack am335x-evmsk am335x-bonegreen am335x-icev2"
+# CONFIG_BLK is not set
+CONFIG_DFU_MMC=y
+CONFIG_DFU_NAND=y
+CONFIG_DFU_RAM=y
+CONFIG_DM_I2C=y
+CONFIG_MISC=y
+CONFIG_DM_MMC=y
+CONFIG_MMC_OMAP_HS=y
+CONFIG_NAND=y
+CONFIG_SPI_FLASH=y
+CONFIG_SPI_FLASH_WINBOND=y
+CONFIG_PHYLIB=y
+CONFIG_DM_ETH=y
+CONFIG_PHY_GIGE=y
+CONFIG_SYS_NS16550=y
+CONFIG_OMAP3_SPI=y
+CONFIG_TIMER=y
+CONFIG_OMAP_TIMER=y
+CONFIG_USB=y
+CONFIG_DM_USB=y
+CONFIG_USB_MUSB_HOST=y
+CONFIG_USB_MUSB_GADGET=y
+CONFIG_USB_MUSB_TI=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_GADGET_DOWNLOAD=y
+CONFIG_G_DNL_MANUFACTURER="Texas Instruments"
+CONFIG_G_DNL_VENDOR_NUM=0x0451
+CONFIG_G_DNL_PRODUCT_NUM=0xd022
+CONFIG_USE_TINY_PRINTF=y
+CONFIG_RSA=y
+CONFIG_LZO=y
+CONFIG_OF_LIBFDT_OVERLAY=y
diff --git a/configs/am335x_igep003x_defconfig b/configs/am335x_igep003x_defconfig
index 1b03c334b4..f344a7367d 100644
--- a/configs/am335x_igep003x_defconfig
+++ b/configs/am335x_igep003x_defconfig
@@ -11,14 +11,12 @@ CONFIG_SPL_SERIAL_SUPPORT=y
CONFIG_SPL_LIBDISK_SUPPORT=y
CONFIG_SPL_NAND_SUPPORT=y
CONFIG_SPL_WATCHDOG_SUPPORT=y
-CONFIG_SPL_STACK_R_ADDR=0x82000000
CONFIG_SPL_FAT_SUPPORT=y
CONFIG_OF_BOARD_SETUP=y
CONFIG_SYS_EXTRA_OPTIONS="MACH_TYPE=MACH_TYPE_IGEP0033"
CONFIG_SYS_CONSOLE_INFO_QUIET=y
CONFIG_VERSION_VARIABLE=y
CONFIG_SPL=y
-CONFIG_SPL_STACK_R=y
CONFIG_SPL_EXT_SUPPORT=y
CONFIG_SPL_I2C_SUPPORT=y
CONFIG_SPL_MTD_SUPPORT=y
diff --git a/configs/am335x_shc_defconfig b/configs/am335x_shc_defconfig
index c63e388ff5..0b29290cf5 100644
--- a/configs/am335x_shc_defconfig
+++ b/configs/am335x_shc_defconfig
@@ -9,13 +9,11 @@ CONFIG_SPL_MMC_SUPPORT=y
CONFIG_SPL_SERIAL_SUPPORT=y
CONFIG_SPL_LIBDISK_SUPPORT=y
CONFIG_SPL_WATCHDOG_SUPPORT=y
-CONFIG_SPL_STACK_R_ADDR=0x82000000
CONFIG_SPL_FAT_SUPPORT=y
CONFIG_SERIES=y
CONFIG_SYS_CONSOLE_INFO_QUIET=y
CONFIG_VERSION_VARIABLE=y
CONFIG_SPL=y
-CONFIG_SPL_STACK_R=y
CONFIG_SPL_EXT_SUPPORT=y
CONFIG_SPL_I2C_SUPPORT=y
CONFIG_SPL_OS_BOOT=y
diff --git a/configs/am335x_shc_ict_defconfig b/configs/am335x_shc_ict_defconfig
index 1bcf683e35..73e0d2857f 100644
--- a/configs/am335x_shc_ict_defconfig
+++ b/configs/am335x_shc_ict_defconfig
@@ -9,14 +9,12 @@ CONFIG_SPL_MMC_SUPPORT=y
CONFIG_SPL_SERIAL_SUPPORT=y
CONFIG_SPL_LIBDISK_SUPPORT=y
CONFIG_SPL_WATCHDOG_SUPPORT=y
-CONFIG_SPL_STACK_R_ADDR=0x82000000
CONFIG_SPL_FAT_SUPPORT=y
CONFIG_SHC_ICT=y
CONFIG_SERIES=y
CONFIG_SYS_CONSOLE_INFO_QUIET=y
CONFIG_VERSION_VARIABLE=y
CONFIG_SPL=y
-CONFIG_SPL_STACK_R=y
CONFIG_SPL_EXT_SUPPORT=y
CONFIG_SPL_I2C_SUPPORT=y
CONFIG_SPL_OS_BOOT=y
diff --git a/configs/am335x_shc_netboot_defconfig b/configs/am335x_shc_netboot_defconfig
index 9528a8cd5c..c4f2f55d05 100644
--- a/configs/am335x_shc_netboot_defconfig
+++ b/configs/am335x_shc_netboot_defconfig
@@ -9,14 +9,12 @@ CONFIG_SPL_MMC_SUPPORT=y
CONFIG_SPL_SERIAL_SUPPORT=y
CONFIG_SPL_LIBDISK_SUPPORT=y
CONFIG_SPL_WATCHDOG_SUPPORT=y
-CONFIG_SPL_STACK_R_ADDR=0x82000000
CONFIG_SPL_FAT_SUPPORT=y
CONFIG_SHC_NETBOOT=y
CONFIG_SERIES=y
CONFIG_SYS_CONSOLE_INFO_QUIET=y
CONFIG_VERSION_VARIABLE=y
CONFIG_SPL=y
-CONFIG_SPL_STACK_R=y
CONFIG_SPL_ENV_SUPPORT=y
CONFIG_SPL_EXT_SUPPORT=y
CONFIG_SPL_I2C_SUPPORT=y
diff --git a/configs/am335x_shc_prompt_defconfig b/configs/am335x_shc_prompt_defconfig
index 8519282ecf..4eac21b4eb 100644
--- a/configs/am335x_shc_prompt_defconfig
+++ b/configs/am335x_shc_prompt_defconfig
@@ -9,13 +9,11 @@ CONFIG_SPL_MMC_SUPPORT=y
CONFIG_SPL_SERIAL_SUPPORT=y
CONFIG_SPL_LIBDISK_SUPPORT=y
CONFIG_SPL_WATCHDOG_SUPPORT=y
-CONFIG_SPL_STACK_R_ADDR=0x82000000
CONFIG_SPL_FAT_SUPPORT=y
CONFIG_SERIES=y
CONFIG_SYS_CONSOLE_INFO_QUIET=y
CONFIG_VERSION_VARIABLE=y
CONFIG_SPL=y
-CONFIG_SPL_STACK_R=y
CONFIG_SPL_EXT_SUPPORT=y
CONFIG_SPL_I2C_SUPPORT=y
CONFIG_SPL_OS_BOOT=y
diff --git a/configs/am335x_shc_sdboot_defconfig b/configs/am335x_shc_sdboot_defconfig
index b00d6f6b22..e3a37db04a 100644
--- a/configs/am335x_shc_sdboot_defconfig
+++ b/configs/am335x_shc_sdboot_defconfig
@@ -9,14 +9,12 @@ CONFIG_SPL_MMC_SUPPORT=y
CONFIG_SPL_SERIAL_SUPPORT=y
CONFIG_SPL_LIBDISK_SUPPORT=y
CONFIG_SPL_WATCHDOG_SUPPORT=y
-CONFIG_SPL_STACK_R_ADDR=0x82000000
CONFIG_SPL_FAT_SUPPORT=y
CONFIG_SHC_SDBOOT=y
CONFIG_SERIES=y
CONFIG_SYS_CONSOLE_INFO_QUIET=y
CONFIG_VERSION_VARIABLE=y
CONFIG_SPL=y
-CONFIG_SPL_STACK_R=y
CONFIG_SPL_EXT_SUPPORT=y
CONFIG_SPL_I2C_SUPPORT=y
CONFIG_SPL_OS_BOOT=y
diff --git a/configs/am335x_shc_sdboot_prompt_defconfig b/configs/am335x_shc_sdboot_prompt_defconfig
index b00d6f6b22..e3a37db04a 100644
--- a/configs/am335x_shc_sdboot_prompt_defconfig
+++ b/configs/am335x_shc_sdboot_prompt_defconfig
@@ -9,14 +9,12 @@ CONFIG_SPL_MMC_SUPPORT=y
CONFIG_SPL_SERIAL_SUPPORT=y
CONFIG_SPL_LIBDISK_SUPPORT=y
CONFIG_SPL_WATCHDOG_SUPPORT=y
-CONFIG_SPL_STACK_R_ADDR=0x82000000
CONFIG_SPL_FAT_SUPPORT=y
CONFIG_SHC_SDBOOT=y
CONFIG_SERIES=y
CONFIG_SYS_CONSOLE_INFO_QUIET=y
CONFIG_VERSION_VARIABLE=y
CONFIG_SPL=y
-CONFIG_SPL_STACK_R=y
CONFIG_SPL_EXT_SUPPORT=y
CONFIG_SPL_I2C_SUPPORT=y
CONFIG_SPL_OS_BOOT=y
diff --git a/configs/am335x_sl50_defconfig b/configs/am335x_sl50_defconfig
index 3fa5d5e5cc..e9ca0d640f 100644
--- a/configs/am335x_sl50_defconfig
+++ b/configs/am335x_sl50_defconfig
@@ -9,14 +9,12 @@ CONFIG_SPL_MMC_SUPPORT=y
CONFIG_SPL_SERIAL_SUPPORT=y
CONFIG_SPL_LIBDISK_SUPPORT=y
CONFIG_SPL_WATCHDOG_SUPPORT=y
-CONFIG_SPL_STACK_R_ADDR=0x82000000
CONFIG_SPL_FAT_SUPPORT=y
CONFIG_DISTRO_DEFAULTS=y
CONFIG_SYS_EXTRA_OPTIONS="EMMC_BOOT"
CONFIG_SYS_CONSOLE_INFO_QUIET=y
CONFIG_VERSION_VARIABLE=y
CONFIG_SPL=y
-CONFIG_SPL_STACK_R=y
CONFIG_SPL_ENV_SUPPORT=y
CONFIG_SPL_EXT_SUPPORT=y
CONFIG_SPL_I2C_SUPPORT=y
diff --git a/configs/am3517_evm_defconfig b/configs/am3517_evm_defconfig
index 920c61c391..8ab018656d 100644
--- a/configs/am3517_evm_defconfig
+++ b/configs/am3517_evm_defconfig
@@ -4,11 +4,14 @@ CONFIG_ARCH_OMAP2PLUS=y
CONFIG_SYS_TEXT_BASE=0x80100000
CONFIG_TI_COMMON_CMD_OPTIONS=y
# CONFIG_SPL_GPIO_SUPPORT is not set
+CONFIG_SYS_MALLOC_F_LEN=0x2000
CONFIG_TARGET_AM3517_EVM=y
CONFIG_EMIF4=y
+CONFIG_DEFAULT_DEVICE_TREE="am3517-evm"
CONFIG_BOOTDELAY=10
CONFIG_VERSION_VARIABLE=y
CONFIG_SPL=y
+CONFIG_SPL_SYS_MALLOC_SIMPLE=y
# CONFIG_SPL_EXT_SUPPORT is not set
CONFIG_SPL_MTD_SUPPORT=y
CONFIG_HUSH_PARSER=y
@@ -27,13 +30,12 @@ CONFIG_CMD_CACHE=y
# CONFIG_CMD_TIME is not set
CONFIG_CMD_UBI=y
CONFIG_SPL_PARTITION_UUIDS=y
+CONFIG_OF_CONTROL=y
CONFIG_ENV_IS_IN_NAND=y
CONFIG_MMC_OMAP_HS=y
CONFIG_NAND=y
CONFIG_SYS_NS16550=y
CONFIG_USB=y
CONFIG_USB_MUSB_HOST=y
-CONFIG_USB_STORAGE=y
# CONFIG_FAT_WRITE is not set
CONFIG_BCH=y
-CONFIG_OF_LIBFDT=y
diff --git a/configs/am43xx_evm_defconfig b/configs/am43xx_evm_defconfig
index 15c25d39f1..352ae16a9e 100644
--- a/configs/am43xx_evm_defconfig
+++ b/configs/am43xx_evm_defconfig
@@ -3,14 +3,12 @@ CONFIG_ARCH_OMAP2PLUS=y
CONFIG_TI_COMMON_CMD_OPTIONS=y
CONFIG_SYS_MALLOC_F_LEN=0x2000
CONFIG_AM43XX=y
-CONFIG_SPL_STACK_R_ADDR=0x82000000
CONFIG_DEFAULT_DEVICE_TREE="am437x-gp-evm"
CONFIG_SPL_LOAD_FIT=y
CONFIG_SYS_EXTRA_OPTIONS="CONS_INDEX=1"
CONFIG_SYS_CONSOLE_INFO_QUIET=y
CONFIG_VERSION_VARIABLE=y
CONFIG_SPL=y
-CONFIG_SPL_STACK_R=y
CONFIG_SPL_MTD_SUPPORT=y
CONFIG_SPL_OS_BOOT=y
CONFIG_HUSH_PARSER=y
diff --git a/configs/am43xx_evm_usbhost_boot_defconfig b/configs/am43xx_evm_usbhost_boot_defconfig
index 0bed335722..1a4856ca9e 100644
--- a/configs/am43xx_evm_usbhost_boot_defconfig
+++ b/configs/am43xx_evm_usbhost_boot_defconfig
@@ -3,14 +3,12 @@ CONFIG_ARCH_OMAP2PLUS=y
CONFIG_SYS_MALLOC_F_LEN=0x2000
CONFIG_AM43XX=y
CONFIG_ISW_ENTRY_ADDR=0x40300350
-CONFIG_SPL_STACK_R_ADDR=0x82000000
CONFIG_DEFAULT_DEVICE_TREE="am437x-gp-evm"
CONFIG_SPL_LOAD_FIT=y
CONFIG_SYS_EXTRA_OPTIONS="SERIAL1,CONS_INDEX=1"
CONFIG_SYS_CONSOLE_INFO_QUIET=y
CONFIG_VERSION_VARIABLE=y
CONFIG_SPL=y
-CONFIG_SPL_STACK_R=y
CONFIG_SPL_MTD_SUPPORT=y
CONFIG_SPL_OS_BOOT=y
CONFIG_SPL_USB_HOST_SUPPORT=y
diff --git a/configs/am43xx_hs_evm_defconfig b/configs/am43xx_hs_evm_defconfig
index a4d23e10b6..9b2b1d7196 100644
--- a/configs/am43xx_hs_evm_defconfig
+++ b/configs/am43xx_hs_evm_defconfig
@@ -8,7 +8,6 @@ CONFIG_TI_SECURE_EMIF_REGION_START=0xbdb00000
CONFIG_TI_SECURE_EMIF_TOTAL_REGION_SIZE=0x02000000
CONFIG_TI_SECURE_EMIF_PROTECTED_REGION_SIZE=0x01c00000
CONFIG_ISW_ENTRY_ADDR=0x403018e0
-CONFIG_SPL_STACK_R_ADDR=0x82000000
CONFIG_DEFAULT_DEVICE_TREE="am437x-gp-evm"
CONFIG_FIT_IMAGE_POST_PROCESS=y
CONFIG_SPL_LOAD_FIT=y
@@ -18,7 +17,6 @@ CONFIG_SYS_EXTRA_OPTIONS="CONS_INDEX=1"
CONFIG_SYS_CONSOLE_INFO_QUIET=y
CONFIG_VERSION_VARIABLE=y
CONFIG_SPL=y
-CONFIG_SPL_STACK_R=y
CONFIG_SPL_ETH_SUPPORT=y
CONFIG_SPL_MTD_SUPPORT=y
CONFIG_SPL_NET_SUPPORT=y
diff --git a/configs/am57xx_evm_defconfig b/configs/am57xx_evm_defconfig
index 0e4679abed..0c9daed5f5 100644
--- a/configs/am57xx_evm_defconfig
+++ b/configs/am57xx_evm_defconfig
@@ -7,7 +7,6 @@ CONFIG_TARGET_AM57XX_EVM=y
# CONFIG_SPL_NAND_SUPPORT is not set
CONFIG_SPL_SPI_FLASH_SUPPORT=y
CONFIG_SPL_SPI_SUPPORT=y
-CONFIG_SPL_STACK_R_ADDR=0x82000000
CONFIG_ARMV7_LPAE=y
CONFIG_DEFAULT_DEVICE_TREE="am572x-idk"
CONFIG_SPL_LOAD_FIT=y
@@ -19,7 +18,6 @@ CONFIG_VERSION_VARIABLE=y
CONFIG_BOARD_EARLY_INIT_F=y
CONFIG_SPL=y
CONFIG_SPL_SYS_MALLOC_SIMPLE=y
-CONFIG_SPL_STACK_R=y
CONFIG_SPL_SEPARATE_BSS=y
CONFIG_SPL_DMA_SUPPORT=y
CONFIG_SPL_OS_BOOT=y
diff --git a/configs/am57xx_hs_evm_defconfig b/configs/am57xx_hs_evm_defconfig
index e7638b88c2..b527e18463 100644
--- a/configs/am57xx_hs_evm_defconfig
+++ b/configs/am57xx_hs_evm_defconfig
@@ -11,7 +11,6 @@ CONFIG_TARGET_AM57XX_EVM=y
# CONFIG_SPL_NAND_SUPPORT is not set
CONFIG_SPL_SPI_FLASH_SUPPORT=y
CONFIG_SPL_SPI_SUPPORT=y
-CONFIG_SPL_STACK_R_ADDR=0x82000000
CONFIG_ARMV7_LPAE=y
CONFIG_DEFAULT_DEVICE_TREE="am57xx-beagle-x15"
CONFIG_FIT_IMAGE_POST_PROCESS=y
@@ -25,7 +24,6 @@ CONFIG_VERSION_VARIABLE=y
CONFIG_BOARD_EARLY_INIT_F=y
CONFIG_SPL=y
CONFIG_SPL_SYS_MALLOC_SIMPLE=y
-CONFIG_SPL_STACK_R=y
CONFIG_SPL_SEPARATE_BSS=y
CONFIG_SPL_DMA_SUPPORT=y
CONFIG_HUSH_PARSER=y
diff --git a/configs/apalis_imx6_defconfig b/configs/apalis_imx6_defconfig
index b2284acc34..13f2a3b849 100644
--- a/configs/apalis_imx6_defconfig
+++ b/configs/apalis_imx6_defconfig
@@ -54,7 +54,6 @@ CONFIG_NETDEVICES=y
CONFIG_USB=y
CONFIG_USB_STORAGE=y
CONFIG_USB_KEYBOARD=y
-CONFIG_SYS_USB_EVENT_POLL=y
CONFIG_USB_GADGET=y
CONFIG_CI_UDC=y
CONFIG_USB_GADGET_DOWNLOAD=y
diff --git a/configs/apalis_imx6_nospl_com_defconfig b/configs/apalis_imx6_nospl_com_defconfig
index 239605dadf..7165749cfb 100644
--- a/configs/apalis_imx6_nospl_com_defconfig
+++ b/configs/apalis_imx6_nospl_com_defconfig
@@ -43,7 +43,6 @@ CONFIG_NETDEVICES=y
CONFIG_USB=y
CONFIG_USB_STORAGE=y
CONFIG_USB_KEYBOARD=y
-CONFIG_SYS_USB_EVENT_POLL=y
CONFIG_USB_GADGET=y
CONFIG_CI_UDC=y
CONFIG_USB_GADGET_DOWNLOAD=y
diff --git a/configs/apalis_imx6_nospl_it_defconfig b/configs/apalis_imx6_nospl_it_defconfig
index 1bc05d7266..0ad7674ee5 100644
--- a/configs/apalis_imx6_nospl_it_defconfig
+++ b/configs/apalis_imx6_nospl_it_defconfig
@@ -43,7 +43,6 @@ CONFIG_NETDEVICES=y
CONFIG_USB=y
CONFIG_USB_STORAGE=y
CONFIG_USB_KEYBOARD=y
-CONFIG_SYS_USB_EVENT_POLL=y
CONFIG_USB_GADGET=y
CONFIG_CI_UDC=y
CONFIG_USB_GADGET_DOWNLOAD=y
diff --git a/configs/chiliboard_defconfig b/configs/chiliboard_defconfig
index ea729b0155..d0f6f5fa11 100644
--- a/configs/chiliboard_defconfig
+++ b/configs/chiliboard_defconfig
@@ -9,12 +9,10 @@ CONFIG_SPL_SERIAL_SUPPORT=y
CONFIG_SPL_LIBDISK_SUPPORT=y
CONFIG_SPL_NAND_SUPPORT=y
CONFIG_SPL_WATCHDOG_SUPPORT=y
-CONFIG_SPL_STACK_R_ADDR=0x82000000
CONFIG_SPL_FAT_SUPPORT=y
CONFIG_BOOTDELAY=1
CONFIG_SYS_CONSOLE_INFO_QUIET=y
CONFIG_SPL=y
-CONFIG_SPL_STACK_R=y
CONFIG_SPL_I2C_SUPPORT=y
CONFIG_SPL_POWER_SUPPORT=y
CONFIG_HUSH_PARSER=y
diff --git a/configs/clearfog_defconfig b/configs/clearfog_defconfig
index 580eaf3e57..5eceacf491 100644
--- a/configs/clearfog_defconfig
+++ b/configs/clearfog_defconfig
@@ -35,8 +35,8 @@ CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_SDMA=y
CONFIG_MMC_SDHCI_MV=y
CONFIG_SPI_FLASH=y
-CONFIG_PHYLIB=y
CONFIG_PHY_GIGE=y
+CONFIG_MVNETA=y
CONFIG_PCI=y
CONFIG_DEBUG_UART_BASE=0xd0012000
CONFIG_DEBUG_UART_CLOCK=250000000
diff --git a/configs/colibri_imx6_defconfig b/configs/colibri_imx6_defconfig
index 7d1e709d4c..7e100869a4 100644
--- a/configs/colibri_imx6_defconfig
+++ b/configs/colibri_imx6_defconfig
@@ -52,7 +52,6 @@ CONFIG_PHY_MICREL=y
CONFIG_USB=y
CONFIG_USB_STORAGE=y
CONFIG_USB_KEYBOARD=y
-CONFIG_SYS_USB_EVENT_POLL=y
CONFIG_USB_GADGET=y
CONFIG_CI_UDC=y
CONFIG_USB_GADGET_DOWNLOAD=y
diff --git a/configs/colibri_imx6_nospl_defconfig b/configs/colibri_imx6_nospl_defconfig
index 6877993088..ba4b2dd9d4 100644
--- a/configs/colibri_imx6_nospl_defconfig
+++ b/configs/colibri_imx6_nospl_defconfig
@@ -41,7 +41,6 @@ CONFIG_PHY_MICREL=y
CONFIG_USB=y
CONFIG_USB_STORAGE=y
CONFIG_USB_KEYBOARD=y
-CONFIG_SYS_USB_EVENT_POLL=y
CONFIG_USB_GADGET=y
CONFIG_CI_UDC=y
CONFIG_USB_GADGET_DOWNLOAD=y
diff --git a/configs/controlcenterdc_defconfig b/configs/controlcenterdc_defconfig
index 836e00b2b5..04f622a574 100644
--- a/configs/controlcenterdc_defconfig
+++ b/configs/controlcenterdc_defconfig
@@ -46,8 +46,8 @@ CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_MV=y
CONFIG_SPI_FLASH=y
CONFIG_SPI_FLASH_STMICRO=y
-CONFIG_PHYLIB=y
CONFIG_PHY_GIGE=y
+CONFIG_MVNETA=y
CONFIG_SCSI=y
CONFIG_DEBUG_UART_BASE=0xd0012000
CONFIG_DEBUG_UART_CLOCK=250000000
diff --git a/configs/da850_am18xxevm_defconfig b/configs/da850_am18xxevm_defconfig
index 27370e7c0c..0c60fef098 100644
--- a/configs/da850_am18xxevm_defconfig
+++ b/configs/da850_am18xxevm_defconfig
@@ -1,17 +1,16 @@
CONFIG_ARM=y
CONFIG_ARCH_DAVINCI=y
CONFIG_TARGET_DA850EVM=y
-CONFIG_TI_COMMON_CMD_OPTIONS=y
CONFIG_MAC_ADDR_IN_EEPROM=y
+CONFIG_TI_COMMON_CMD_OPTIONS=y
CONFIG_SPL_LIBCOMMON_SUPPORT=y
CONFIG_SPL_LIBGENERIC_SUPPORT=y
CONFIG_SPL_SERIAL_SUPPORT=y
CONFIG_SPL_SPI_FLASH_SUPPORT=y
CONFIG_SPL_SPI_SUPPORT=y
+CONFIG_DEFAULT_DEVICE_TREE="da850-evm"
CONFIG_SYS_EXTRA_OPTIONS="DA850_AM18X_EVM,SYS_I2C_EEPROM_ADDR_LEN=2,SYS_I2C_EEPROM_ADDR=0x50"
CONFIG_BOOTDELAY=3
-CONFIG_USE_BOOTARGS=y
-CONFIG_BOOTARGS="mem=32M console=ttyS2,115200n8 root=/dev/mtdblock2 rw noinitrd ip=dhcp"
CONFIG_VERSION_VARIABLE=y
# CONFIG_DISPLAY_CPUINFO is not set
# CONFIG_DISPLAY_BOARDINFO is not set
@@ -19,24 +18,29 @@ CONFIG_BOARD_EARLY_INIT_F=y
CONFIG_SPL=y
CONFIG_SPL_BOARD_INIT=y
CONFIG_HUSH_PARSER=y
-# CONFIG_CMD_BOOTZ is not set
+CONFIG_SYS_PROMPT="U-Boot > "
# CONFIG_CMD_IMLS is not set
CONFIG_CRC32_VERIFY=y
# CONFIG_CMD_EEPROM is not set
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_GPIO is not set
# CONFIG_CMD_GPT is not set
-# CONFIG_CMD_I2C is not set
# CONFIG_CMD_PART is not set
# CONFIG_CMD_SETEXPR is not set
# CONFIG_CMD_TIME is not set
# CONFIG_CMD_EXT4 is not set
# CONFIG_CMD_FS_GENERIC is not set
CONFIG_CMD_DIAG=y
+CONFIG_OF_CONTROL=y
CONFIG_ENV_IS_IN_SPI_FLASH=y
+CONFIG_DM=y
+CONFIG_DM_I2C=y
+CONFIG_DM_I2C_COMPAT=y
+CONFIG_DM_SPI_FLASH=y
CONFIG_SPI_FLASH=y
CONFIG_SPI_FLASH_STMICRO=y
CONFIG_SPI_FLASH_WINBOND=y
+CONFIG_DM_SERIAL=y
CONFIG_SYS_NS16550=y
+CONFIG_DM_SPI=y
# CONFIG_FAT_WRITE is not set
-CONFIG_OF_LIBFDT=y
diff --git a/configs/da850evm_defconfig b/configs/da850evm_defconfig
index bfa5ea1c4b..d6eb4a5ba2 100644
--- a/configs/da850evm_defconfig
+++ b/configs/da850evm_defconfig
@@ -7,9 +7,9 @@ CONFIG_SPL_LIBGENERIC_SUPPORT=y
CONFIG_SPL_SERIAL_SUPPORT=y
CONFIG_SPL_SPI_FLASH_SUPPORT=y
CONFIG_SPL_SPI_SUPPORT=y
+CONFIG_DEFAULT_DEVICE_TREE="da850-evm"
+CONFIG_SYS_EXTRA_OPTIONS="MAC_ADDR_IN_SPIFLASH"
CONFIG_BOOTDELAY=3
-CONFIG_USE_BOOTARGS=y
-CONFIG_BOOTARGS="mem=32M console=ttyS2,115200n8 root=/dev/mtdblock2 rw noinitrd ip=dhcp"
CONFIG_VERSION_VARIABLE=y
# CONFIG_DISPLAY_CPUINFO is not set
# CONFIG_DISPLAY_BOARDINFO is not set
@@ -24,17 +24,24 @@ CONFIG_CRC32_VERIFY=y
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_GPIO is not set
# CONFIG_CMD_GPT is not set
-# CONFIG_CMD_I2C is not set
# CONFIG_CMD_PART is not set
# CONFIG_CMD_SETEXPR is not set
# CONFIG_CMD_TIME is not set
# CONFIG_CMD_EXT4 is not set
# CONFIG_CMD_FS_GENERIC is not set
+CONFIG_CMD_MTDPARTS=y
CONFIG_CMD_DIAG=y
+CONFIG_OF_CONTROL=y
CONFIG_ENV_IS_IN_SPI_FLASH=y
+CONFIG_DM=y
+CONFIG_DM_I2C=y
+CONFIG_DM_I2C_COMPAT=y
+CONFIG_DM_SPI_FLASH=y
CONFIG_SPI_FLASH=y
CONFIG_SPI_FLASH_STMICRO=y
CONFIG_SPI_FLASH_WINBOND=y
+CONFIG_SPI_FLASH_MTD=y
+CONFIG_DM_SERIAL=y
CONFIG_SYS_NS16550=y
+CONFIG_DM_SPI=y
# CONFIG_FAT_WRITE is not set
-CONFIG_OF_LIBFDT=y
diff --git a/configs/da850evm_direct_nor_defconfig b/configs/da850evm_direct_nor_defconfig
index 24ab89224d..3c8e7ad15a 100644
--- a/configs/da850evm_direct_nor_defconfig
+++ b/configs/da850evm_direct_nor_defconfig
@@ -2,6 +2,8 @@ CONFIG_ARM=y
CONFIG_ARCH_DAVINCI=y
CONFIG_TARGET_DA850EVM=y
CONFIG_TI_COMMON_CMD_OPTIONS=y
+CONFIG_DEFAULT_DEVICE_TREE="da850-evm"
+# CONFIG_SYS_MALLOC_F is not set
CONFIG_SYS_EXTRA_OPTIONS="USE_NOR,DIRECT_NOR_BOOT"
CONFIG_BOOTDELAY=3
CONFIG_USE_BOOTARGS=y
@@ -17,7 +19,6 @@ CONFIG_CRC32_VERIFY=y
# CONFIG_CMD_EEPROM is not set
# CONFIG_CMD_GPIO is not set
# CONFIG_CMD_GPT is not set
-# CONFIG_CMD_I2C is not set
# CONFIG_CMD_MMC is not set
# CONFIG_CMD_PART is not set
# CONFIG_CMD_SPI is not set
@@ -28,11 +29,16 @@ CONFIG_CRC32_VERIFY=y
# CONFIG_CMD_FAT is not set
# CONFIG_CMD_FS_GENERIC is not set
CONFIG_CMD_DIAG=y
+CONFIG_OF_CONTROL=y
CONFIG_ENV_IS_IN_FLASH=y
+CONFIG_DM=y
+CONFIG_DM_I2C=y
+CONFIG_DM_I2C_COMPAT=y
# CONFIG_MMC is not set
CONFIG_MTD_NOR_FLASH=y
+CONFIG_DM_SPI_FLASH=y
CONFIG_SPI_FLASH=y
CONFIG_SPI_FLASH_STMICRO=y
CONFIG_SPI_FLASH_WINBOND=y
CONFIG_SYS_NS16550=y
-CONFIG_OF_LIBFDT=y
+CONFIG_DM_SPI=y
diff --git a/configs/db-88f6820-amc_defconfig b/configs/db-88f6820-amc_defconfig
index 3074994ec6..e73d883cbe 100644
--- a/configs/db-88f6820-amc_defconfig
+++ b/configs/db-88f6820-amc_defconfig
@@ -47,8 +47,8 @@ CONFIG_SPI_FLASH=y
CONFIG_SPI_FLASH_BAR=y
CONFIG_SPI_FLASH_MACRONIX=y
CONFIG_SPI_FLASH_STMICRO=y
-CONFIG_PHYLIB=y
CONFIG_PHY_GIGE=y
+CONFIG_MVNETA=y
CONFIG_PCI=y
CONFIG_DEBUG_UART_BASE=0xd0012000
CONFIG_DEBUG_UART_CLOCK=200000000
diff --git a/configs/db-88f6820-gp_defconfig b/configs/db-88f6820-gp_defconfig
index 9d1771d292..d63992573c 100644
--- a/configs/db-88f6820-gp_defconfig
+++ b/configs/db-88f6820-gp_defconfig
@@ -45,8 +45,8 @@ CONFIG_MMC_SDHCI_MV=y
CONFIG_SPI_FLASH=y
CONFIG_SPI_FLASH_MACRONIX=y
CONFIG_SPI_FLASH_STMICRO=y
-CONFIG_PHYLIB=y
CONFIG_PHY_GIGE=y
+CONFIG_MVNETA=y
CONFIG_PCI=y
CONFIG_SCSI=y
CONFIG_DEBUG_UART_BASE=0xd0012000
diff --git a/configs/db-mv784mp-gp_defconfig b/configs/db-mv784mp-gp_defconfig
index 9458f8c438..03035d1e36 100644
--- a/configs/db-mv784mp-gp_defconfig
+++ b/configs/db-mv784mp-gp_defconfig
@@ -44,8 +44,8 @@ CONFIG_NAND_PXA3XX=y
CONFIG_SPI_FLASH=y
CONFIG_SPI_FLASH_MACRONIX=y
CONFIG_SPI_FLASH_STMICRO=y
-CONFIG_PHYLIB=y
CONFIG_PHY_GIGE=y
+CONFIG_MVNETA=y
CONFIG_PCI=y
CONFIG_DEBUG_UART_BASE=0xd0012000
CONFIG_DEBUG_UART_CLOCK=250000000
diff --git a/configs/dra7xx_evm_defconfig b/configs/dra7xx_evm_defconfig
index 53903bf730..215fc61dc6 100644
--- a/configs/dra7xx_evm_defconfig
+++ b/configs/dra7xx_evm_defconfig
@@ -7,7 +7,6 @@ CONFIG_TARGET_DRA7XX_EVM=y
# CONFIG_SPL_NAND_SUPPORT is not set
CONFIG_SPL_SPI_FLASH_SUPPORT=y
CONFIG_SPL_SPI_SUPPORT=y
-CONFIG_SPL_STACK_R_ADDR=0x82000000
CONFIG_ARMV7_LPAE=y
CONFIG_DEFAULT_DEVICE_TREE="dra7-evm"
CONFIG_SPL_LOAD_FIT=y
@@ -19,7 +18,6 @@ CONFIG_VERSION_VARIABLE=y
CONFIG_BOARD_EARLY_INIT_F=y
CONFIG_SPL=y
CONFIG_SPL_SYS_MALLOC_SIMPLE=y
-CONFIG_SPL_STACK_R=y
CONFIG_SPL_SEPARATE_BSS=y
CONFIG_SPL_DMA_SUPPORT=y
CONFIG_SPL_OS_BOOT=y
diff --git a/configs/dra7xx_hs_evm_defconfig b/configs/dra7xx_hs_evm_defconfig
index 06d8834119..c88229cead 100644
--- a/configs/dra7xx_hs_evm_defconfig
+++ b/configs/dra7xx_hs_evm_defconfig
@@ -11,7 +11,6 @@ CONFIG_TARGET_DRA7XX_EVM=y
# CONFIG_SPL_NAND_SUPPORT is not set
CONFIG_SPL_SPI_FLASH_SUPPORT=y
CONFIG_SPL_SPI_SUPPORT=y
-CONFIG_SPL_STACK_R_ADDR=0x82000000
CONFIG_ARMV7_LPAE=y
CONFIG_DEFAULT_DEVICE_TREE="dra7-evm"
CONFIG_FIT_IMAGE_POST_PROCESS=y
@@ -25,7 +24,6 @@ CONFIG_VERSION_VARIABLE=y
CONFIG_BOARD_EARLY_INIT_F=y
CONFIG_SPL=y
CONFIG_SPL_SYS_MALLOC_SIMPLE=y
-CONFIG_SPL_STACK_R=y
CONFIG_SPL_SEPARATE_BSS=y
CONFIG_SPL_DMA_SUPPORT=y
CONFIG_HUSH_PARSER=y
diff --git a/configs/ds414_defconfig b/configs/ds414_defconfig
index 96bdbeb0ea..f05ddd0de8 100644
--- a/configs/ds414_defconfig
+++ b/configs/ds414_defconfig
@@ -38,8 +38,8 @@ CONFIG_SPL_OF_TRANSLATE=y
CONFIG_SPI_FLASH=y
CONFIG_SPI_FLASH_BAR=y
CONFIG_SPI_FLASH_STMICRO=y
-CONFIG_PHYLIB=y
CONFIG_PHY_GIGE=y
+CONFIG_MVNETA=y
CONFIG_PCI=y
CONFIG_DEBUG_UART_BASE=0xd0012000
CONFIG_DEBUG_UART_CLOCK=250000000
diff --git a/configs/evb-rv1108_defconfig b/configs/evb-rv1108_defconfig
index ab4276ac8c..7036f433ee 100644
--- a/configs/evb-rv1108_defconfig
+++ b/configs/evb-rv1108_defconfig
@@ -5,8 +5,16 @@ CONFIG_TARGET_EVB_RV1108=y
CONFIG_DEFAULT_DEVICE_TREE="rv1108-evb"
CONFIG_DEBUG_UART=y
# CONFIG_DISPLAY_CPUINFO is not set
+CONFIG_FASTBOOT=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
+CONFIG_CMD_FASTBOOT=y
+CONFIG_FASTBOOT_BUF_ADDR=0x62000000
+CONFIG_FASTBOOT_BUF_SIZE=0x08000000
+CONFIG_FASTBOOT_FLASH=y
+CONFIG_FASTBOOT_FLASH_MMC_DEV=1
# CONFIG_CMD_IMLS is not set
CONFIG_CMD_SF=y
+CONFIG_CMD_USB=y
# CONFIG_CMD_SETEXPR is not set
CONFIG_CMD_CACHE=y
CONFIG_CMD_TIME=y
@@ -26,6 +34,7 @@ CONFIG_ETH_DESIGNWARE=y
CONFIG_GMAC_ROCKCHIP=y
CONFIG_PINCTRL=y
CONFIG_PINCTRL_ROCKCHIP_RV1108=y
+CONFIG_DM_REGULATOR_FIXED=y
CONFIG_BAUDRATE=1500000
# CONFIG_SPL_SERIAL_PRESENT is not set
CONFIG_DEBUG_UART_BASE=0x10210000
@@ -33,4 +42,16 @@ CONFIG_DEBUG_UART_CLOCK=24000000
CONFIG_DEBUG_UART_SHIFT=2
CONFIG_SYSRESET=y
CONFIG_USB=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_GENERIC=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_OHCI_GENERIC=y
+CONFIG_USB_DWC2=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_GADGET_DWC2_OTG=y
+CONFIG_USB_GADGET_DOWNLOAD=y
+CONFIG_G_DNL_MANUFACTURER="Rockchip"
+CONFIG_G_DNL_VENDOR_NUM=0x2207
+CONFIG_G_DNL_PRODUCT_NUM=0x110a
CONFIG_ERRNO_STR=y
diff --git a/configs/firefly-rk3288_defconfig b/configs/firefly-rk3288_defconfig
index 82da6016e6..178c879e26 100644
--- a/configs/firefly-rk3288_defconfig
+++ b/configs/firefly-rk3288_defconfig
@@ -73,7 +73,6 @@ CONFIG_USB=y
CONFIG_USB_DWC2=y
CONFIG_USB_STORAGE=y
CONFIG_USB_KEYBOARD=y
-CONFIG_SYS_USB_EVENT_POLL=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_DWC2_OTG=y
CONFIG_USB_GADGET_DOWNLOAD=y
diff --git a/configs/lion-rk3368_defconfig b/configs/lion-rk3368_defconfig
index 45a12a8b27..c7ee7b3f97 100644
--- a/configs/lion-rk3368_defconfig
+++ b/configs/lion-rk3368_defconfig
@@ -19,6 +19,11 @@ CONFIG_FIT=y
CONFIG_FIT_VERBOSE=y
CONFIG_SPL_LOAD_FIT=y
CONFIG_SPL_FIT_SOURCE="board/theobroma-systems/lion_rk3368/fit_spl_atf.its"
+CONFIG_BOOTSTAGE=y
+CONFIG_SPL_BOOTSTAGE=y
+CONFIG_BOOTSTAGE_REPORT=y
+CONFIG_BOOTSTAGE_FDT=y
+CONFIG_ENV_IS_IN_MMC=y
# CONFIG_DISPLAY_CPUINFO is not set
CONFIG_ARCH_EARLY_INIT_R=y
CONFIG_SPL=y
@@ -37,10 +42,12 @@ CONFIG_TPL_DRIVERS_MISC_SUPPORT=y
CONFIG_CMD_GPIO=y
CONFIG_CMD_MMC=y
CONFIG_CMD_SF=y
+CONFIG_CMD_BOOTSTAGE=y
CONFIG_CMD_REGULATOR=y
CONFIG_CMD_MTDPARTS=y
CONFIG_SPL_OF_CONTROL=y
CONFIG_TPL_OF_CONTROL=y
+CONFIG_OF_LIVE=y
CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names interrupt-parent"
CONFIG_TPL_OF_PLATDATA=y
CONFIG_ENV_IS_IN_MMC=y
diff --git a/configs/ls1043ardb_sdcard_defconfig b/configs/ls1043ardb_sdcard_defconfig
index efdaaa3d69..f6ea06bfb0 100644
--- a/configs/ls1043ardb_sdcard_defconfig
+++ b/configs/ls1043ardb_sdcard_defconfig
@@ -3,7 +3,6 @@ CONFIG_TARGET_LS1043ARDB=y
CONFIG_SPL_LIBCOMMON_SUPPORT=y
CONFIG_SPL_LIBGENERIC_SUPPORT=y
CONFIG_FSL_LS_PPA=y
-CONFIG_SPL_FSL_LS_PPA=y
CONFIG_SPL_MMC_SUPPORT=y
CONFIG_SPL_SERIAL_SUPPORT=y
CONFIG_SPL_DRIVERS_MISC_SUPPORT=y
diff --git a/configs/ls1046ardb_sdcard_defconfig b/configs/ls1046ardb_sdcard_defconfig
index 600990ea60..1d7ed3b23a 100644
--- a/configs/ls1046ardb_sdcard_defconfig
+++ b/configs/ls1046ardb_sdcard_defconfig
@@ -1,7 +1,6 @@
CONFIG_ARM=y
CONFIG_TARGET_LS1046ARDB=y
CONFIG_FSL_LS_PPA=y
-CONFIG_SPL_FSL_LS_PPA=y
CONFIG_DEFAULT_DEVICE_TREE="fsl-ls1046a-rdb"
CONFIG_DISTRO_DEFAULTS=y
CONFIG_FIT_VERBOSE=y
diff --git a/configs/maxbcm_defconfig b/configs/maxbcm_defconfig
index 131d5e1d8e..5efaff3b28 100644
--- a/configs/maxbcm_defconfig
+++ b/configs/maxbcm_defconfig
@@ -32,8 +32,8 @@ CONFIG_SPI_FLASH_BAR=y
CONFIG_SPI_FLASH_MACRONIX=y
CONFIG_SPI_FLASH_SPANSION=y
CONFIG_SPI_FLASH_STMICRO=y
-CONFIG_PHYLIB=y
CONFIG_PHY_GIGE=y
+CONFIG_MVNETA=y
CONFIG_DEBUG_UART_BASE=0xd0012000
CONFIG_DEBUG_UART_CLOCK=250000000
CONFIG_DEBUG_UART_SHIFT=2
diff --git a/configs/mx6cuboxi_defconfig b/configs/mx6cuboxi_defconfig
index 5490e3546b..27171fbddf 100644
--- a/configs/mx6cuboxi_defconfig
+++ b/configs/mx6cuboxi_defconfig
@@ -34,6 +34,5 @@ CONFIG_DM_THERMAL=y
CONFIG_USB=y
CONFIG_USB_STORAGE=y
CONFIG_USB_KEYBOARD=y
-CONFIG_SYS_USB_EVENT_POLL=y
# CONFIG_VIDEO_SW_CURSOR is not set
CONFIG_OF_LIBFDT=y
diff --git a/configs/mx6sabresd_defconfig b/configs/mx6sabresd_defconfig
index 0e49e69c8c..ad5d448539 100644
--- a/configs/mx6sabresd_defconfig
+++ b/configs/mx6sabresd_defconfig
@@ -18,6 +18,9 @@ CONFIG_SPL=y
CONFIG_SPL_EXT_SUPPORT=y
CONFIG_SPL_I2C_SUPPORT=y
CONFIG_SPL_OS_BOOT=y
+CONFIG_SPL_USB_HOST_SUPPORT=y
+CONFIG_SPL_USB_GADGET_SUPPORT=y
+CONFIG_SPL_USB_SDP_SUPPORT=y
CONFIG_HUSH_PARSER=y
CONFIG_CMD_BOOTZ=y
# CONFIG_CMD_IMLS is not set
@@ -31,6 +34,7 @@ CONFIG_CMD_PART=y
CONFIG_CMD_PCI=y
CONFIG_CMD_SF=y
CONFIG_CMD_USB=y
+CONFIG_CMD_USB_SDP=y
CONFIG_CMD_DHCP=y
CONFIG_CMD_MII=y
CONFIG_CMD_PING=y
diff --git a/configs/omap3_evm_defconfig b/configs/omap3_evm_defconfig
index 962ffa0729..bae67de718 100644
--- a/configs/omap3_evm_defconfig
+++ b/configs/omap3_evm_defconfig
@@ -5,7 +5,6 @@ CONFIG_SYS_TEXT_BASE=0x80100000
CONFIG_SYS_MALLOC_F_LEN=0x2000
CONFIG_SYS_MPUCLK=720
CONFIG_TARGET_OMAP3_EVM=y
-CONFIG_SPL_STACK_R_ADDR=0x82000000
CONFIG_DISTRO_DEFAULTS=y
CONFIG_BOOTDELAY=3
CONFIG_SYS_CONSOLE_INFO_QUIET=y
@@ -13,7 +12,6 @@ CONFIG_DEFAULT_FDT_FILE="omap3-evm.dtb"
CONFIG_VERSION_VARIABLE=y
CONFIG_SPL=y
CONFIG_SPL_SYS_MALLOC_SIMPLE=y
-CONFIG_SPL_STACK_R=y
# CONFIG_SPL_EXT_SUPPORT is not set
CONFIG_SPL_MTD_SUPPORT=y
CONFIG_SYS_PROMPT="OMAP3_EVM # "
diff --git a/configs/omap3_logic_defconfig b/configs/omap3_logic_defconfig
index b8f25883d8..adffcd981c 100644
--- a/configs/omap3_logic_defconfig
+++ b/configs/omap3_logic_defconfig
@@ -3,13 +3,11 @@ CONFIG_ARCH_OMAP2PLUS=y
CONFIG_TI_COMMON_CMD_OPTIONS=y
CONFIG_SYS_MALLOC_F_LEN=0x2000
CONFIG_TARGET_OMAP3_LOGIC=y
-CONFIG_SPL_STACK_R_ADDR=0x82000000
CONFIG_DEFAULT_DEVICE_TREE="logicpd-torpedo-37xx-devkit"
CONFIG_SYS_CONSOLE_INFO_QUIET=y
CONFIG_VERSION_VARIABLE=y
CONFIG_SPL=y
CONFIG_SPL_SYS_MALLOC_SIMPLE=y
-CONFIG_SPL_STACK_R=y
CONFIG_SPL_MTD_SUPPORT=y
CONFIG_SPL_OS_BOOT=y
CONFIG_HUSH_PARSER=y
diff --git a/configs/omap3_overo_defconfig b/configs/omap3_overo_defconfig
index 5d1cbe993a..4043c42e4b 100644
--- a/configs/omap3_overo_defconfig
+++ b/configs/omap3_overo_defconfig
@@ -2,12 +2,10 @@ CONFIG_ARM=y
CONFIG_ARCH_OMAP2PLUS=y
CONFIG_SYS_MALLOC_F_LEN=0x2000
CONFIG_TARGET_OMAP3_OVERO=y
-CONFIG_SPL_STACK_R_ADDR=0x82000000
CONFIG_SYS_CONSOLE_INFO_QUIET=y
CONFIG_VERSION_VARIABLE=y
CONFIG_SPL=y
CONFIG_SPL_SYS_MALLOC_SIMPLE=y
-CONFIG_SPL_STACK_R=y
CONFIG_SPL_MTD_SUPPORT=y
CONFIG_SPL_OS_BOOT=y
CONFIG_HUSH_PARSER=y
diff --git a/configs/puma-rk3399_defconfig b/configs/puma-rk3399_defconfig
index 1badf80beb..2ab2516c01 100644
--- a/configs/puma-rk3399_defconfig
+++ b/configs/puma-rk3399_defconfig
@@ -35,6 +35,7 @@ CONFIG_CMD_TIME=y
CONFIG_CMD_PMIC=y
CONFIG_CMD_REGULATOR=y
CONFIG_SPL_OF_CONTROL=y
+CONFIG_OF_LIVE=y
CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents"
CONFIG_ENV_IS_IN_MMC=y
CONFIG_REGMAP=y
diff --git a/configs/rpi_2_defconfig b/configs/rpi_2_defconfig
index 2345697701..03705975bf 100644
--- a/configs/rpi_2_defconfig
+++ b/configs/rpi_2_defconfig
@@ -26,7 +26,6 @@ CONFIG_DM_USB=y
CONFIG_USB_DWC2=y
CONFIG_USB_STORAGE=y
CONFIG_USB_KEYBOARD=y
-CONFIG_SYS_USB_EVENT_POLL=y
CONFIG_USB_HOST_ETHER=y
CONFIG_USB_ETHER_SMSC95XX=y
CONFIG_DM_VIDEO=y
diff --git a/configs/rpi_3_32b_defconfig b/configs/rpi_3_32b_defconfig
index bb56a9e4e1..31d67ccdc9 100644
--- a/configs/rpi_3_32b_defconfig
+++ b/configs/rpi_3_32b_defconfig
@@ -28,7 +28,6 @@ CONFIG_DM_USB=y
CONFIG_USB_DWC2=y
CONFIG_USB_STORAGE=y
CONFIG_USB_KEYBOARD=y
-CONFIG_SYS_USB_EVENT_POLL=y
CONFIG_USB_HOST_ETHER=y
CONFIG_USB_ETHER_SMSC95XX=y
CONFIG_DM_VIDEO=y
diff --git a/configs/rpi_3_defconfig b/configs/rpi_3_defconfig
index 6edacd69a2..1ac3a96e25 100644
--- a/configs/rpi_3_defconfig
+++ b/configs/rpi_3_defconfig
@@ -28,7 +28,6 @@ CONFIG_DM_USB=y
CONFIG_USB_DWC2=y
CONFIG_USB_STORAGE=y
CONFIG_USB_KEYBOARD=y
-CONFIG_SYS_USB_EVENT_POLL=y
CONFIG_USB_HOST_ETHER=y
CONFIG_USB_ETHER_SMSC95XX=y
CONFIG_DM_VIDEO=y
diff --git a/configs/rpi_defconfig b/configs/rpi_defconfig
index 2e81966c14..87e88223ee 100644
--- a/configs/rpi_defconfig
+++ b/configs/rpi_defconfig
@@ -26,7 +26,6 @@ CONFIG_DM_USB=y
CONFIG_USB_DWC2=y
CONFIG_USB_STORAGE=y
CONFIG_USB_KEYBOARD=y
-CONFIG_SYS_USB_EVENT_POLL=y
CONFIG_USB_HOST_ETHER=y
CONFIG_USB_ETHER_SMSC95XX=y
CONFIG_DM_VIDEO=y
diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index 310b8acc29..632e0aa0ee 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -175,7 +175,6 @@ CONFIG_DM_USB=y
CONFIG_USB_EMUL=y
CONFIG_USB_STORAGE=y
CONFIG_USB_KEYBOARD=y
-CONFIG_SYS_USB_EVENT_POLL=y
CONFIG_DM_VIDEO=y
CONFIG_CONSOLE_ROTATION=y
CONFIG_CONSOLE_TRUETYPE=y
diff --git a/configs/sandbox_flattree_defconfig b/configs/sandbox_flattree_defconfig
index 50ea35e64b..b1a341551f 100644
--- a/configs/sandbox_flattree_defconfig
+++ b/configs/sandbox_flattree_defconfig
@@ -160,7 +160,6 @@ CONFIG_DM_USB=y
CONFIG_USB_EMUL=y
CONFIG_USB_STORAGE=y
CONFIG_USB_KEYBOARD=y
-CONFIG_SYS_USB_EVENT_POLL=y
CONFIG_DM_VIDEO=y
CONFIG_CONSOLE_ROTATION=y
CONFIG_CONSOLE_TRUETYPE=y
diff --git a/configs/sandbox_noblk_defconfig b/configs/sandbox_noblk_defconfig
index 693c14bc60..39101741b1 100644
--- a/configs/sandbox_noblk_defconfig
+++ b/configs/sandbox_noblk_defconfig
@@ -168,7 +168,6 @@ CONFIG_DM_USB=y
CONFIG_USB_EMUL=y
CONFIG_USB_STORAGE=y
CONFIG_USB_KEYBOARD=y
-CONFIG_SYS_USB_EVENT_POLL=y
CONFIG_DM_VIDEO=y
CONFIG_CONSOLE_ROTATION=y
CONFIG_CONSOLE_TRUETYPE=y
diff --git a/configs/sandbox_spl_defconfig b/configs/sandbox_spl_defconfig
index db9129456b..7f03c6ed03 100644
--- a/configs/sandbox_spl_defconfig
+++ b/configs/sandbox_spl_defconfig
@@ -178,7 +178,6 @@ CONFIG_DM_USB=y
CONFIG_USB_EMUL=y
CONFIG_USB_STORAGE=y
CONFIG_USB_KEYBOARD=y
-CONFIG_SYS_USB_EVENT_POLL=y
CONFIG_DM_VIDEO=y
CONFIG_CONSOLE_ROTATION=y
CONFIG_CONSOLE_TRUETYPE=y
diff --git a/configs/seaboard_defconfig b/configs/seaboard_defconfig
index ea4546bce4..810cfaa498 100644
--- a/configs/seaboard_defconfig
+++ b/configs/seaboard_defconfig
@@ -36,7 +36,6 @@ CONFIG_USB_ULPI_VIEWPORT=y
CONFIG_USB_ULPI=y
CONFIG_USB_STORAGE=y
CONFIG_USB_KEYBOARD=y
-CONFIG_SYS_USB_EVENT_POLL=y
CONFIG_USB_HOST_ETHER=y
CONFIG_USB_ETHER_ASIX=y
CONFIG_DM_VIDEO=y
diff --git a/configs/sheep-rk3368_defconfig b/configs/sheep-rk3368_defconfig
index b862a14751..a7991afae2 100644
--- a/configs/sheep-rk3368_defconfig
+++ b/configs/sheep-rk3368_defconfig
@@ -2,6 +2,7 @@ CONFIG_ARM=y
CONFIG_ARCH_ROCKCHIP=y
CONFIG_SYS_MALLOC_F_LEN=0x1000
CONFIG_ROCKCHIP_RK3368=y
+CONFIG_TARGET_SHEEP=y
CONFIG_DEFAULT_DEVICE_TREE="rk3368-sheep"
CONFIG_DEBUG_UART=y
CONFIG_ANDROID_BOOT_IMAGE=y
@@ -14,6 +15,7 @@ CONFIG_CLK=y
CONFIG_MMC_DW=y
CONFIG_MMC_DW_ROCKCHIP=y
CONFIG_PINCTRL=y
+CONFIG_PINCTRL_ROCKCHIP_RK3368=y
CONFIG_RAM=y
CONFIG_DEBUG_UART_BASE=0xFF1b0000
CONFIG_DEBUG_UART_CLOCK=24000000
diff --git a/configs/socfpga_de0_nano_soc_defconfig b/configs/socfpga_de0_nano_soc_defconfig
index 0bb9121c26..b4fd29d207 100644
--- a/configs/socfpga_de0_nano_soc_defconfig
+++ b/configs/socfpga_de0_nano_soc_defconfig
@@ -12,6 +12,7 @@ CONFIG_DEFAULT_FDT_FILE="socfpga_cyclone5_de0_nano_soc.dtb"
CONFIG_VERSION_VARIABLE=y
# CONFIG_DISPLAY_BOARDINFO is not set
CONFIG_SPL=y
+# CONFIG_SPL_RAW_IMAGE_SUPPORT is not set
CONFIG_SPL_SYS_MALLOC_SIMPLE=y
CONFIG_SPL_STACK_R=y
CONFIG_HUSH_PARSER=y
@@ -24,6 +25,7 @@ CONFIG_CMD_DFU=y
CONFIG_CMD_GPIO=y
CONFIG_CMD_I2C=y
CONFIG_CMD_MMC=y
+CONFIG_CMD_PART=y
CONFIG_CMD_SF=y
CONFIG_CMD_SPI=y
CONFIG_CMD_USB=y
@@ -38,6 +40,7 @@ CONFIG_CMD_FAT=y
CONFIG_CMD_FS_GENERIC=y
CONFIG_CMD_UBI=y
CONFIG_ENV_IS_IN_MMC=y
+CONFIG_EFI_PARTITION=y
CONFIG_SPL_DM=y
CONFIG_DFU_MMC=y
CONFIG_FPGA_SOCFPGA=y
diff --git a/configs/stih410-b2260_defconfig b/configs/stih410-b2260_defconfig
index 10e1a2d06d..8fd1ff26a2 100644
--- a/configs/stih410-b2260_defconfig
+++ b/configs/stih410-b2260_defconfig
@@ -2,27 +2,58 @@ CONFIG_ARM=y
CONFIG_ARCH_STI=y
CONFIG_IDENT_STRING="STMicroelectronics STiH410-B2260"
CONFIG_DEFAULT_DEVICE_TREE="stih410-b2260"
+CONFIG_DISTRO_DEFAULTS=y
CONFIG_FIT=y
CONFIG_FIT_VERBOSE=y
CONFIG_USE_BOOTARGS=y
CONFIG_BOOTARGS="console=ttyS0,115200 earlyprintk consoleblank=0 ignore_loglevel"
# CONFIG_DISPLAY_CPUINFO is not set
CONFIG_SYS_PROMPT="stih410-b2260 => "
+CONFIG_FASTBOOT=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
+CONFIG_CMD_FASTBOOT=y
+CONFIG_ANDROID_BOOT_IMAGE=y
+CONFIG_FASTBOOT_BUF_ADDR=0x40000000
+CONFIG_FASTBOOT_BUF_SIZE=0x3DF00000
+CONFIG_FASTBOOT_FLASH=y
+CONFIG_FASTBOOT_FLASH_MMC_DEV=0
# CONFIG_CMD_IMLS is not set
+CONFIG_CMD_GPT=y
CONFIG_CMD_MMC=y
+CONFIG_CMD_USB=y
CONFIG_CMD_TIME=y
CONFIG_CMD_TIMER=y
-CONFIG_CMD_EXT2=y
-CONFIG_CMD_EXT4=y
-CONFIG_CMD_FAT=y
-CONFIG_CMD_FS_GENERIC=y
+CONFIG_CMD_EXT4_WRITE=y
+# CONFIG_ISO_PARTITION is not set
CONFIG_OF_CONTROL=y
CONFIG_REGMAP=y
CONFIG_SYSCON=y
+CONFIG_CLK=y
+CONFIG_MISC=y
CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_STI=y
+CONFIG_PHY=y
+CONFIG_STI_USB_PHY=y
CONFIG_PINCTRL=y
+CONFIG_STI_RESET=y
CONFIG_STI_ASC_SERIAL=y
CONFIG_SYSRESET=y
CONFIG_TIMER=y
+CONFIG_USB=y
+CONFIG_DM_USB=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_XHCI_DWC3=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_GENERIC=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_OHCI_GENERIC=y
+CONFIG_USB_DWC3=y
+CONFIG_USB_DWC3_GADGET=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_GADGET_DOWNLOAD=y
+CONFIG_G_DNL_MANUFACTURER="STMicroelectronics"
+CONFIG_G_DNL_VENDOR_NUM=0x483
+CONFIG_G_DNL_PRODUCT_NUM=0x7270
+CONFIG_OF_LIBFDT_OVERLAY=y
CONFIG_SPL_OF_LIBFDT=y
diff --git a/configs/stm32h743-disco_defconfig b/configs/stm32h743-disco_defconfig
new file mode 100644
index 0000000000..eed921d24b
--- /dev/null
+++ b/configs/stm32h743-disco_defconfig
@@ -0,0 +1,30 @@
+CONFIG_ARM=y
+CONFIG_STM32=y
+CONFIG_SYS_MALLOC_F_LEN=0xF00
+CONFIG_STM32H7=y
+CONFIG_TARGET_STM32H743_DISCO=y
+CONFIG_DEFAULT_DEVICE_TREE="stm32h743i-disco"
+CONFIG_BOOTDELAY=3
+CONFIG_DEFAULT_FDT_FILE="stm32h743i-disco"
+# CONFIG_DISPLAY_CPUINFO is not set
+CONFIG_BOARD_EARLY_INIT_F=y
+CONFIG_HUSH_PARSER=y
+CONFIG_SYS_PROMPT="U-Boot > "
+CONFIG_AUTOBOOT_KEYED=y
+CONFIG_AUTOBOOT_PROMPT="Hit SPACE in %d seconds to stop autoboot.\n"
+CONFIG_AUTOBOOT_STOP_STR=" "
+CONFIG_CMD_BOOTZ=y
+# CONFIG_CMD_IMLS is not set
+# CONFIG_CMD_FPGA is not set
+# CONFIG_CMD_SETEXPR is not set
+# CONFIG_CMD_NET is not set
+# CONFIG_CMD_NFS is not set
+CONFIG_CMD_TIMER=y
+CONFIG_OF_CONTROL=y
+CONFIG_OF_EMBED=y
+# CONFIG_PINCTRL_FULL is not set
+# CONFIG_SPL_SERIAL_PRESENT is not set
+CONFIG_REGEX=y
+CONFIG_LIB_RAND=y
+CONFIG_OF_LIBFDT_OVERLAY=y
+# CONFIG_EFI_LOADER is not set
diff --git a/configs/stm32h743-eval_defconfig b/configs/stm32h743-eval_defconfig
new file mode 100644
index 0000000000..61e702e001
--- /dev/null
+++ b/configs/stm32h743-eval_defconfig
@@ -0,0 +1,30 @@
+CONFIG_ARM=y
+CONFIG_STM32=y
+CONFIG_SYS_MALLOC_F_LEN=0xF00
+CONFIG_STM32H7=y
+CONFIG_TARGET_STM32H743_EVAL=y
+CONFIG_DEFAULT_DEVICE_TREE="stm32h743i-eval"
+CONFIG_BOOTDELAY=3
+CONFIG_DEFAULT_FDT_FILE="stm32h743i-eval"
+# CONFIG_DISPLAY_CPUINFO is not set
+CONFIG_BOARD_EARLY_INIT_F=y
+CONFIG_HUSH_PARSER=y
+CONFIG_SYS_PROMPT="U-Boot > "
+CONFIG_AUTOBOOT_KEYED=y
+CONFIG_AUTOBOOT_PROMPT="Hit SPACE in %d seconds to stop autoboot.\n"
+CONFIG_AUTOBOOT_STOP_STR=" "
+CONFIG_CMD_BOOTZ=y
+# CONFIG_CMD_IMLS is not set
+# CONFIG_CMD_FPGA is not set
+# CONFIG_CMD_SETEXPR is not set
+# CONFIG_CMD_NET is not set
+# CONFIG_CMD_NFS is not set
+CONFIG_CMD_TIMER=y
+CONFIG_OF_CONTROL=y
+CONFIG_OF_EMBED=y
+# CONFIG_PINCTRL_FULL is not set
+# CONFIG_SPL_SERIAL_PRESENT is not set
+CONFIG_REGEX=y
+CONFIG_LIB_RAND=y
+CONFIG_OF_LIBFDT_OVERLAY=y
+# CONFIG_EFI_LOADER is not set
diff --git a/configs/theadorable_debug_defconfig b/configs/theadorable_debug_defconfig
index a39497984b..0b4025c228 100644
--- a/configs/theadorable_debug_defconfig
+++ b/configs/theadorable_debug_defconfig
@@ -51,8 +51,8 @@ CONFIG_DM_GPIO=y
CONFIG_SPI_FLASH=y
CONFIG_SPI_FLASH_MACRONIX=y
CONFIG_SPI_FLASH_STMICRO=y
-CONFIG_PHYLIB=y
CONFIG_PHY_GIGE=y
+CONFIG_MVNETA=y
CONFIG_PCI=y
CONFIG_DEBUG_UART_BASE=0xd0012000
CONFIG_DEBUG_UART_CLOCK=250000000
diff --git a/configs/theadorable_defconfig b/configs/theadorable_defconfig
deleted file mode 100644
index 0639f81328..0000000000
--- a/configs/theadorable_defconfig
+++ /dev/null
@@ -1,54 +0,0 @@
-CONFIG_ARM=y
-CONFIG_ARCH_MVEBU=y
-CONFIG_SPL_LIBCOMMON_SUPPORT=y
-CONFIG_SPL_LIBGENERIC_SUPPORT=y
-CONFIG_SYS_MALLOC_F_LEN=0x2000
-CONFIG_TARGET_THEADORABLE=y
-CONFIG_SPL_SERIAL_SUPPORT=y
-CONFIG_SPL_SPI_FLASH_SUPPORT=y
-CONFIG_SPL_SPI_SUPPORT=y
-CONFIG_VIDEO=y
-CONFIG_DEFAULT_DEVICE_TREE="armada-xp-theadorable"
-CONFIG_DEBUG_UART=y
-# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
-CONFIG_FIT=y
-CONFIG_BOOTDELAY=3
-# CONFIG_CONSOLE_MUX is not set
-CONFIG_SYS_CONSOLE_INFO_QUIET=y
-# CONFIG_DISPLAY_BOARDINFO is not set
-CONFIG_SPL=y
-CONFIG_SPL_I2C_SUPPORT=y
-CONFIG_HUSH_PARSER=y
-CONFIG_CMD_BOOTZ=y
-# CONFIG_CMD_IMLS is not set
-# CONFIG_CMD_FLASH is not set
-CONFIG_CMD_I2C=y
-CONFIG_CMD_SF=y
-# CONFIG_CMD_SETEXPR is not set
-# CONFIG_CMD_NET is not set
-# CONFIG_CMD_NFS is not set
-CONFIG_CMD_BMP=y
-CONFIG_CMD_CACHE=y
-CONFIG_CMD_TIME=y
-CONFIG_CMD_EXT2=y
-CONFIG_CMD_EXT4=y
-CONFIG_CMD_FAT=y
-CONFIG_CMD_FS_GENERIC=y
-CONFIG_EFI_PARTITION=y
-# CONFIG_PARTITION_UUIDS is not set
-# CONFIG_SPL_PARTITION_UUIDS is not set
-CONFIG_SPL_OF_TRANSLATE=y
-CONFIG_FPGA_ALTERA=y
-CONFIG_DM_GPIO=y
-# CONFIG_MMC is not set
-CONFIG_SPI_FLASH=y
-CONFIG_SPI_FLASH_MACRONIX=y
-CONFIG_SPI_FLASH_STMICRO=y
-CONFIG_DEBUG_UART_BASE=0xd0012000
-CONFIG_DEBUG_UART_CLOCK=250000000
-CONFIG_DEBUG_UART_SHIFT=2
-CONFIG_SYS_NS16550=y
-CONFIG_VIDEO_MVEBU=y
-# CONFIG_VIDEO_SW_CURSOR is not set
-CONFIG_REGEX=y
-CONFIG_LIB_RAND=y
diff --git a/configs/ti816x_evm_defconfig b/configs/ti816x_evm_defconfig
index 4341d8d01f..d269e3641a 100644
--- a/configs/ti816x_evm_defconfig
+++ b/configs/ti816x_evm_defconfig
@@ -9,7 +9,6 @@ CONFIG_SPL_MMC_SUPPORT=y
CONFIG_SPL_SERIAL_SUPPORT=y
CONFIG_SPL_LIBDISK_SUPPORT=y
CONFIG_SPL_NAND_SUPPORT=y
-CONFIG_SPL_STACK_R_ADDR=0x82000000
CONFIG_SPL_FAT_SUPPORT=y
CONFIG_DEFAULT_DEVICE_TREE="dm8168-evm"
CONFIG_DISTRO_DEFAULTS=y
@@ -20,7 +19,6 @@ CONFIG_SYS_CONSOLE_INFO_QUIET=y
CONFIG_VERSION_VARIABLE=y
# CONFIG_DISPLAY_BOARDINFO is not set
CONFIG_SPL=y
-CONFIG_SPL_STACK_R=y
CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR=y
CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x300
# CONFIG_CMD_IMLS is not set
diff --git a/configs/turris_omnia_defconfig b/configs/turris_omnia_defconfig
index a3834acb96..870cfd51ad 100644
--- a/configs/turris_omnia_defconfig
+++ b/configs/turris_omnia_defconfig
@@ -33,8 +33,8 @@ CONFIG_MISC=y
CONFIG_ATSHA204A=y
CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_MV=y
-CONFIG_PHYLIB=y
CONFIG_PHY_GIGE=y
+CONFIG_MVNETA=y
CONFIG_DEBUG_UART_BASE=0xd0012000
CONFIG_DEBUG_UART_CLOCK=250000000
CONFIG_DEBUG_UART_SHIFT=2
diff --git a/configs/uniphier_pro4_defconfig b/configs/uniphier_pro4_defconfig
deleted file mode 100644
index 7348675f80..0000000000
--- a/configs/uniphier_pro4_defconfig
+++ /dev/null
@@ -1,49 +0,0 @@
-CONFIG_ARM=y
-CONFIG_ARCH_UNIPHIER=y
-CONFIG_SYS_TEXT_BASE=0x84000000
-CONFIG_SYS_MALLOC_F_LEN=0x2000
-CONFIG_SPL_MMC_SUPPORT=y
-CONFIG_SPL_SERIAL_SUPPORT=y
-CONFIG_SPL_NAND_SUPPORT=y
-CONFIG_MICRO_SUPPORT_CARD=y
-CONFIG_DEFAULT_DEVICE_TREE="uniphier-pro4-ref"
-# CONFIG_ARCH_FIXUP_FDT_MEMORY is not set
-CONFIG_SPL=y
-CONFIG_SPL_NOR_SUPPORT=y
-CONFIG_HUSH_PARSER=y
-CONFIG_CMD_CONFIG=y
-CONFIG_CMD_BOOTZ=y
-# CONFIG_CMD_XIMG is not set
-# CONFIG_CMD_ENV_EXISTS is not set
-# CONFIG_CMD_FPGA is not set
-CONFIG_CMD_GPIO=y
-CONFIG_CMD_GPT=y
-CONFIG_CMD_I2C=y
-CONFIG_CMD_MMC=y
-CONFIG_CMD_USB=y
-CONFIG_CMD_TFTPPUT=y
-CONFIG_CMD_PING=y
-CONFIG_CMD_CACHE=y
-CONFIG_CMD_TIME=y
-# CONFIG_CMD_MISC is not set
-CONFIG_CMD_FAT=y
-CONFIG_CMD_FS_GENERIC=y
-# CONFIG_SPL_DOS_PARTITION is not set
-# CONFIG_SPL_EFI_PARTITION is not set
-CONFIG_NET_RANDOM_ETHADDR=y
-CONFIG_GPIO_UNIPHIER=y
-CONFIG_MISC=y
-CONFIG_I2C_EEPROM=y
-CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS=10
-CONFIG_MMC_UNIPHIER=y
-CONFIG_NAND=y
-CONFIG_NAND_DENALI=y
-CONFIG_NAND_DENALI_DT=y
-CONFIG_SYS_NAND_DENALI_64BIT=y
-CONFIG_NAND_DENALI_SPARE_AREA_SKIP_BYTES=8
-CONFIG_SPL_NAND_DENALI=y
-CONFIG_USB=y
-CONFIG_USB_XHCI_HCD=y
-CONFIG_USB_EHCI_HCD=y
-CONFIG_USB_EHCI_GENERIC=y
-CONFIG_USB_STORAGE=y
diff --git a/configs/uniphier_pxs2_ld6b_defconfig b/configs/uniphier_v7_defconfig
index c242776d9c..3c25484939 100644
--- a/configs/uniphier_pxs2_ld6b_defconfig
+++ b/configs/uniphier_v7_defconfig
@@ -5,7 +5,7 @@ CONFIG_SYS_MALLOC_F_LEN=0x2000
CONFIG_SPL_MMC_SUPPORT=y
CONFIG_SPL_SERIAL_SUPPORT=y
CONFIG_SPL_NAND_SUPPORT=y
-CONFIG_ARCH_UNIPHIER_PRO5_PXS2_LD6B=y
+CONFIG_ARCH_UNIPHIER_V7_MULTI=y
CONFIG_MICRO_SUPPORT_CARD=y
CONFIG_DEFAULT_DEVICE_TREE="uniphier-pxs2-vodka"
# CONFIG_ARCH_FIXUP_FDT_MEMORY is not set
@@ -45,4 +45,6 @@ CONFIG_NAND_DENALI_SPARE_AREA_SKIP_BYTES=8
CONFIG_SPL_NAND_DENALI=y
CONFIG_USB=y
CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_GENERIC=y
CONFIG_USB_STORAGE=y
diff --git a/configs/ventana_defconfig b/configs/ventana_defconfig
index 42353f034e..b11dab1196 100644
--- a/configs/ventana_defconfig
+++ b/configs/ventana_defconfig
@@ -34,7 +34,6 @@ CONFIG_USB_ULPI_VIEWPORT=y
CONFIG_USB_ULPI=y
CONFIG_USB_STORAGE=y
CONFIG_USB_KEYBOARD=y
-CONFIG_SYS_USB_EVENT_POLL=y
CONFIG_USB_HOST_ETHER=y
CONFIG_USB_ETHER_ASIX=y
CONFIG_DM_VIDEO=y
diff --git a/configs/vyasa-rk3288_defconfig b/configs/vyasa-rk3288_defconfig
new file mode 100644
index 0000000000..7db7b0b6f9
--- /dev/null
+++ b/configs/vyasa-rk3288_defconfig
@@ -0,0 +1,63 @@
+CONFIG_ARM=y
+CONFIG_ARCH_ROCKCHIP=y
+CONFIG_SYS_MALLOC_F_LEN=0x2000
+CONFIG_ROCKCHIP_RK3288=y
+CONFIG_TARGET_VYASA_RK3288=y
+CONFIG_SPL_STACK_R_ADDR=0x80000
+CONFIG_DEFAULT_DEVICE_TREE="rk3288-vyasa"
+CONFIG_DEBUG_UART=y
+CONFIG_ENV_IS_IN_MMC=y
+CONFIG_SILENT_CONSOLE=y
+# CONFIG_DISPLAY_CPUINFO is not set
+CONFIG_SPL_STACK_R=y
+CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x2000
+# CONFIG_CMD_IMLS is not set
+CONFIG_CMD_GPT=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_I2C=y
+CONFIG_CMD_GPIO=y
+# CONFIG_CMD_SETEXPR is not set
+CONFIG_CMD_CACHE=y
+CONFIG_CMD_TIME=y
+CONFIG_CMD_PMIC=y
+CONFIG_CMD_REGULATOR=y
+# CONFIG_SPL_DOS_PARTITION is not set
+# CONFIG_SPL_ISO_PARTITION is not set
+# CONFIG_SPL_EFI_PARTITION is not set
+CONFIG_SPL_PARTITION_UUIDS=y
+CONFIG_SPL_OF_CONTROL=y
+CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names clock-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents"
+CONFIG_REGMAP=y
+CONFIG_SPL_REGMAP=y
+CONFIG_SYSCON=y
+CONFIG_SPL_SYSCON=y
+# CONFIG_SPL_SIMPLE_BUS is not set
+CONFIG_CLK=y
+CONFIG_SPL_CLK=y
+CONFIG_ROCKCHIP_GPIO=y
+CONFIG_SYS_I2C_ROCKCHIP=y
+CONFIG_LED=y
+CONFIG_LED_GPIO=y
+CONFIG_MMC_DW=y
+CONFIG_MMC_DW_ROCKCHIP=y
+CONFIG_PINCTRL=y
+CONFIG_SPL_PINCTRL=y
+# CONFIG_SPL_PINCTRL_FULL is not set
+CONFIG_PINCTRL_ROCKCHIP_RK3288=y
+CONFIG_DM_PMIC=y
+# CONFIG_SPL_PMIC_CHILDREN is not set
+CONFIG_PMIC_RK8XX=y
+CONFIG_REGULATOR_RK8XX=y
+CONFIG_DM_REGULATOR_FIXED=y
+CONFIG_PWM_ROCKCHIP=y
+CONFIG_RAM=y
+CONFIG_SPL_RAM=y
+CONFIG_DEBUG_UART_BASE=0xff690000
+CONFIG_DEBUG_UART_CLOCK=24000000
+CONFIG_DEBUG_UART_SHIFT=2
+CONFIG_SYS_NS16550=y
+CONFIG_SYSRESET=y
+CONFIG_CONSOLE_SCROLL_LINES=10
+CONFIG_USE_TINY_PRINTF=y
+CONFIG_CMD_DHRYSTONE=y
+CONFIG_ERRNO_STR=y
diff --git a/doc/README.uniphier b/doc/README.uniphier
index fa1f9bcc96..e4fd9a3e3f 100644
--- a/doc/README.uniphier
+++ b/doc/README.uniphier
@@ -27,17 +27,17 @@ The following tables show <defconfig> and <device-tree> for each board.
32bit SoC boards:
- Board | <defconfig> | <device-tree>
----------------|------------------------------|------------------------------
-LD4 reference | uniphier_ld4_sld8_defconfig | uniphier-ld4-ref (default)
-sld8 reference | uniphier_ld4_sld8_defconfig | uniphier-sld8-def
-Pro4 reference | uniphier_pro4_defconfig | uniphier-pro4-ref (default)
-Pro4 Ace | uniphier_pro4_defconfig | uniphier-pro4-ace
-Pro4 Sanji | uniphier_pro4_defconfig | uniphier-pro4-sanji
-Pro5 4KBOX | uniphier_pxs2_ld6b_defconfig | uniphier-pro5-4kbox
-PXs2 Gentil | uniphier_pxs2_ld6b_defconfig | uniphier-pxs2-gentil
-PXs2 Vodka | uniphier_pxs2_ld6b_defconfig | uniphier-pxs2-vodka (default)
-LD6b reference | uniphier_pxs2_ld6b_defconfig | uniphier-ld6b-ref
+ Board | <defconfig> | <device-tree>
+---------------|-----------------------------|------------------------------
+LD4 reference | uniphier_ld4_sld8_defconfig | uniphier-ld4-ref (default)
+sld8 reference | uniphier_ld4_sld8_defconfig | uniphier-sld8-def
+Pro4 reference | uniphier_v7_defconfig | uniphier-pro4-ref
+Pro4 Ace | uniphier_v7_defconfig | uniphier-pro4-ace
+Pro4 Sanji | uniphier_v7_defconfig | uniphier-pro4-sanji
+Pro5 4KBOX | uniphier_v7_defconfig | uniphier-pro5-4kbox
+PXs2 Gentil | uniphier_v7_defconfig | uniphier-pxs2-gentil
+PXs2 Vodka | uniphier_v7_defconfig | uniphier-pxs2-vodka (default)
+LD6b reference | uniphier_v7_defconfig | uniphier-ld6b-ref
64bit SoC boards:
@@ -47,17 +47,18 @@ LD11 reference | uniphier_v8_defconfig | uniphier-ld11-ref
LD11 Global | uniphier_v8_defconfig | uniphier-ld11-global
LD20 reference | uniphier_v8_defconfig | uniphier-ld20-ref (default)
LD20 Global | uniphier_v8_defconfig | uniphier-ld20-global
+PXs3 reference | uniphier_v8_defconfig | uniphier-pxs3-ref
For example, to compile the source for PXs2 Vodka board, run the following:
- $ make uniphier_pxs2_ld6b_defconfig
+ $ make uniphier_v7_defconfig
$ make CROSS_COMPILE=arm-linux-gnueabihf- DEVICE_TREE=uniphier-pxs2-vodka
The device tree marked as (default) can be omitted. `uniphier-pxs2-vodka` is
-the default device tree for the configuration `uniphier_pxs2_ld6b_defconfig`,
-so the following gives the same result.
+the default device tree for the configuration `uniphier_v7_defconfig`, so the
+following gives the same result.
- $ make uniphier_pxs2_ld6b_defconfig
+ $ make uniphier_v7_defconfig
$ make CROSS_COMPILE=arm-linux-gnueabihf-
@@ -178,4 +179,4 @@ newer SoCs. Even if it is, EA[25] is not connected on most of the boards.
--
Masahiro Yamada <yamada.masahiro@socionext.com>
-Jul. 2017
+Sep. 2017
diff --git a/doc/device-tree-bindings/clock/st,stm32h7-rcc.txt b/doc/device-tree-bindings/clock/st,stm32h7-rcc.txt
new file mode 100644
index 0000000000..9d4b5873d9
--- /dev/null
+++ b/doc/device-tree-bindings/clock/st,stm32h7-rcc.txt
@@ -0,0 +1,152 @@
+STMicroelectronics STM32H7 Reset and Clock Controller
+=====================================================
+
+The RCC IP is both a reset and a clock controller.
+
+Please refer to clock-bindings.txt for common clock controller binding usage.
+Please also refer to reset.txt for common reset controller binding usage.
+
+Required properties:
+- compatible: Should be:
+ "st,stm32h743-rcc"
+
+- reg: should be register base and length as documented in the
+ datasheet
+
+- #reset-cells: 1, see below
+
+- #clock-cells : from common clock binding; shall be set to 1
+
+- clocks: External oscillator clock phandle
+ - high speed external clock signal (HSE)
+ - low speed external clock signal (LSE)
+ - external I2S clock (I2S_CKIN)
+
+- st,syscfg: phandle for pwrcfg, mandatory to disable/enable backup domain
+ write protection (RTC clock).
+
+- pll x node: Allow to register a pll with specific parameters.
+ Please see PLL section below.
+
+Example:
+
+ rcc: rcc@58024400 {
+ #reset-cells = <1>;
+ #clock-cells = <2>
+ compatible = "st,stm32h743-rcc", "st,stm32-rcc";
+ reg = <0x58024400 0x400>;
+ clocks = <&clk_hse>, <&clk_lse>, <&clk_i2s_ckin>;
+
+ st,syscfg = <&pwrcfg>;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ vco1@58024430 {
+ #clock-cells = <0>;
+ compatible = "stm32,pll";
+ reg = <0>;
+ };
+
+ vco2@58024438 {
+ #clock-cells = <0>;
+ compatible = "stm32,pll";
+ reg = <1>;
+ st,clock-div = <2>;
+ st,clock-mult = <40>;
+ st,frac-status = <0>;
+ st,frac = <0>;
+ st,vcosel = <1>;
+ st,pllrge = <2>;
+ };
+ };
+
+
+STM32H7 PLL
+-----------
+
+The VCO of STM32 PLL could be reprensented like this:
+
+ Vref --------- --------
+ ---->| / DIVM |---->| x DIVN | ------> VCO
+ --------- --------
+ ^
+ |
+ -------
+ | FRACN |
+ -------
+
+When the PLL is configured in integer mode:
+- VCO = ( Vref / DIVM ) * DIVN
+
+When the PLL is configured in fractional mode:
+- VCO = ( Vref / DIVM ) * ( DIVN + FRACN / 2^13)
+
+
+Required properties for pll node:
+- compatible: Should be:
+ "stm32,pll"
+
+- #clock-cells: from common clock binding; shall be set to 0
+- reg: Should be the pll number.
+
+Optional properties:
+- st,clock-div: DIVM division factor : <1..63>
+- st,clock-mult: DIVN multiplication factor : <4..512>
+
+- st,frac-status:
+ - 0 Pll is configured in integer mode
+ - 1 Pll is configure in fractional mode
+
+- st,frac: Fractional part of the multiplication factor : <0..8191>
+
+- st,vcosel: VCO selection
+ - 0: Wide VCO range:192 to 836 MHz
+ - 1: Medium VCO range:150 to 420 MHz
+
+- st,pllrge: PLL input frequency range
+ - 0: The PLL input (Vref / DIVM) clock range frequency is between 1 and 2 MHz
+ - 1: The PLL input (Vref / DIVM) clock range frequency is between 2 and 4 MHz
+ - 2: The PLL input (Vref / DIVM) clock range frequency is between 4 and 8 MHz
+ - 3: The PLL input (Vref / DIVM) clock range frequency is between 8 and 16 MHz
+
+
+The peripheral clock consumer should specify the desired clock by
+having the clock ID in its "clocks" phandle cell.
+
+All available clocks are defined as preprocessor macros in
+dt-bindings/clock/stm32h7-clks.h header and can be used in device
+tree sources.
+
+Example:
+
+ timer5: timer@40000c00 {
+ compatible = "st,stm32-timer";
+ reg = <0x40000c00 0x400>;
+ interrupts = <50>;
+ clocks = <&rcc TIM5_CK>;
+
+ };
+
+Specifying softreset control of devices
+=======================================
+
+Device nodes should specify the reset channel required in their "resets"
+property, containing a phandle to the reset device node and an index specifying
+which channel to use.
+The index is the bit number within the RCC registers bank, starting from RCC
+base address.
+It is calculated as: index = register_offset / 4 * 32 + bit_offset.
+Where bit_offset is the bit offset within the register.
+
+For example, for CRC reset:
+ crc = AHB4RSTR_offset / 4 * 32 + CRCRST_bit_offset = 0x88 / 4 * 32 + 19 = 1107
+
+All available preprocessor macros for reset are defined dt-bindings//mfd/stm32h7-rcc.h
+header and can be used in device tree sources.
+
+example:
+
+ timer2 {
+ resets = <&rcc STM32H7_APB1L_RESET(TIM2)>;
+ };
diff --git a/doc/device-tree-bindings/phy/phy-stih407-usb.txt b/doc/device-tree-bindings/phy/phy-stih407-usb.txt
new file mode 100644
index 0000000000..371a7fec0a
--- /dev/null
+++ b/doc/device-tree-bindings/phy/phy-stih407-usb.txt
@@ -0,0 +1,24 @@
+ST STiH407 USB PHY controller
+
+This file documents the dt bindings for the usb picoPHY driver which is the PHY for both USB2 and USB3
+host controllers (when controlling usb2/1.1 devices) available on STiH407 SoC family from STMicroelectronics.
+
+Required properties:
+- compatible : should be "st,stih407-usb2-phy"
+- st,syscfg : phandle of sysconfig bank plus integer array containing phyparam and phyctrl register offsets
+- resets : list of phandle and reset specifier pairs. There should be two entries, one
+ for the whole phy and one for the port
+- reset-names : list of reset signal names. Should be "global" and "port"
+See: Documentation/devicetree/bindings/reset/st,sti-powerdown.txt
+See: Documentation/devicetree/bindings/reset/reset.txt
+
+Example:
+
+usb2_picophy0: usbpicophy {
+ compatible = "st,stih407-usb2-phy";
+ #phy-cells = <0>;
+ st,syscfg = <&syscfg_core 0x100 0xf4>;
+ resets = <&softreset STIH407_PICOPHY_SOFTRESET>,
+ <&picophyreset STIH407_PICOPHY0_RESET>;
+ reset-names = "global", "port";
+};
diff --git a/doc/device-tree-bindings/reset/st,stm32-rcc.txt b/doc/device-tree-bindings/reset/st,stm32-rcc.txt
new file mode 100644
index 0000000000..01db343751
--- /dev/null
+++ b/doc/device-tree-bindings/reset/st,stm32-rcc.txt
@@ -0,0 +1,6 @@
+STMicroelectronics STM32 Peripheral Reset Controller
+====================================================
+
+The RCC IP is both a reset and a clock controller.
+
+Please see Documentation/devicetree/bindings/clock/st,stm32-rcc.txt
diff --git a/doc/device-tree-bindings/usb/dwc3-st.txt b/doc/device-tree-bindings/usb/dwc3-st.txt
new file mode 100644
index 0000000000..a26a1397ed
--- /dev/null
+++ b/doc/device-tree-bindings/usb/dwc3-st.txt
@@ -0,0 +1,60 @@
+ST DWC3 glue logic
+
+This file documents the parameters for the dwc3-st driver.
+This driver controls the glue logic used to configure the dwc3 core on
+STiH407 based platforms.
+
+Required properties:
+ - compatible : must be "st,stih407-dwc3"
+ - reg : glue logic base address and USB syscfg ctrl register offset
+ - reg-names : should be "reg-glue" and "syscfg-reg"
+ - st,syscon : should be phandle to system configuration node which
+ encompasses the glue registers
+ - resets : list of phandle and reset specifier pairs. There should be two entries, one
+ for the powerdown and softreset lines of the usb3 IP
+ - reset-names : list of reset signal names. Names should be "powerdown" and "softreset"
+
+ - #address-cells, #size-cells : should be '1' if the device has sub-nodes
+ with 'reg' property
+
+ - pinctl-names : A pinctrl state named "default" must be defined
+
+ - pinctrl-0 : Pin control group
+
+ - ranges : allows valid 1:1 translation between child's address space and
+ parent's address space
+
+Sub-nodes:
+The dwc3 core should be added as subnode to ST DWC3 glue as shown in the
+example below.
+
+NB: The dr_mode property is NOT optional for this driver, as the default value
+is "otg", which isn't supported by this SoC. Valid dr_mode values for dwc3-st are
+either "host" or "device".
+
+Example:
+
+st_dwc3: dwc3@8f94000 {
+ status = "disabled";
+ compatible = "st,stih407-dwc3";
+ reg = <0x08f94000 0x1000>, <0x110 0x4>;
+ reg-names = "reg-glue", "syscfg-reg";
+ st,syscfg = <&syscfg_core>;
+ resets = <&powerdown STIH407_USB3_POWERDOWN>,
+ <&softreset STIH407_MIPHY2_SOFTRESET>;
+ reset-names = "powerdown", "softreset";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usb3>;
+ ranges;
+
+ dwc3: dwc3@9900000 {
+ compatible = "snps,dwc3";
+ reg = <0x09900000 0x100000>;
+ interrupts = <GIC_SPI 155 IRQ_TYPE_NONE>;
+ dr_mode = "host";
+ phy-names = "usb2-phy", "usb3-phy";
+ phys = <&usb2_picophy2>, <&phy_port2 PHY_TYPE_USB3>;
+ };
+};
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index b7735933be..83fe88ce9f 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -22,3 +22,4 @@ obj-$(CONFIG_CLK_BCM6345) += clk_bcm6345.o
obj-$(CONFIG_CLK_BOSTON) += clk_boston.o
obj-$(CONFIG_ARCH_ASPEED) += aspeed/
obj-$(CONFIG_STM32F7) += clk_stm32f7.o
+obj-$(CONFIG_STM32H7) += clk_stm32h7.o
diff --git a/drivers/clk/clk_stm32f7.c b/drivers/clk/clk_stm32f7.c
index 255a583c95..68d6ba0461 100644
--- a/drivers/clk/clk_stm32f7.c
+++ b/drivers/clk/clk_stm32f7.c
@@ -310,10 +310,11 @@ static const struct udevice_id stm32_clk_ids[] = {
};
U_BOOT_DRIVER(stm32f7_clk) = {
- .name = "stm32f7_clk",
- .id = UCLASS_CLK,
- .of_match = stm32_clk_ids,
- .ops = &stm32_clk_ops,
- .probe = stm32_clk_probe,
- .flags = DM_FLAG_PRE_RELOC,
+ .name = "stm32f7_clk",
+ .id = UCLASS_CLK,
+ .of_match = stm32_clk_ids,
+ .ops = &stm32_clk_ops,
+ .probe = stm32_clk_probe,
+ .priv_auto_alloc_size = sizeof(struct stm32_clk),
+ .flags = DM_FLAG_PRE_RELOC,
};
diff --git a/drivers/clk/clk_stm32h7.c b/drivers/clk/clk_stm32h7.c
new file mode 100644
index 0000000000..fd0e3ab100
--- /dev/null
+++ b/drivers/clk/clk_stm32h7.c
@@ -0,0 +1,802 @@
+/*
+ * Copyright (C) STMicroelectronics SA 2017
+ * Author(s): Patrice CHOTARD, <patrice.chotard@st.com> for STMicroelectronics.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <regmap.h>
+#include <syscon.h>
+#include <asm/io.h>
+#include <dm/root.h>
+
+#include <dt-bindings/clock/stm32h7-clks.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* RCC CR specific definitions */
+#define RCC_CR_HSION BIT(0)
+#define RCC_CR_HSIRDY BIT(2)
+
+#define RCC_CR_HSEON BIT(16)
+#define RCC_CR_HSERDY BIT(17)
+#define RCC_CR_HSEBYP BIT(18)
+#define RCC_CR_PLL1ON BIT(24)
+#define RCC_CR_PLL1RDY BIT(25)
+
+#define RCC_CR_HSIDIV_MASK GENMASK(4, 3)
+#define RCC_CR_HSIDIV_SHIFT 3
+
+#define RCC_CFGR_SW_MASK GENMASK(2, 0)
+#define RCC_CFGR_SW_HSI 0
+#define RCC_CFGR_SW_CSI 1
+#define RCC_CFGR_SW_HSE 2
+#define RCC_CFGR_SW_PLL1 3
+
+#define RCC_PLLCKSELR_PLLSRC_HSI 0
+#define RCC_PLLCKSELR_PLLSRC_CSI 1
+#define RCC_PLLCKSELR_PLLSRC_HSE 2
+#define RCC_PLLCKSELR_PLLSRC_NO_CLK 3
+
+#define RCC_PLLCKSELR_PLLSRC_MASK GENMASK(1, 0)
+
+#define RCC_PLLCKSELR_DIVM1_SHIFT 4
+#define RCC_PLLCKSELR_DIVM1_MASK GENMASK(9, 4)
+
+#define RCC_PLL1DIVR_DIVN1_MASK GENMASK(8, 0)
+
+#define RCC_PLL1DIVR_DIVP1_SHIFT 9
+#define RCC_PLL1DIVR_DIVP1_MASK GENMASK(15, 9)
+
+#define RCC_PLL1DIVR_DIVQ1_SHIFT 16
+#define RCC_PLL1DIVR_DIVQ1_MASK GENMASK(22, 16)
+
+#define RCC_PLL1DIVR_DIVR1_SHIFT 24
+#define RCC_PLL1DIVR_DIVR1_MASK GENMASK(30, 24)
+
+#define RCC_PLL1FRACR_FRACN1_SHIFT 3
+#define RCC_PLL1FRACR_FRACN1_MASK GENMASK(15, 3)
+
+#define RCC_PLLCFGR_PLL1RGE_SHIFT 2
+#define PLL1RGE_1_2_MHZ 0
+#define PLL1RGE_2_4_MHZ 1
+#define PLL1RGE_4_8_MHZ 2
+#define PLL1RGE_8_16_MHZ 3
+#define RCC_PLLCFGR_DIVP1EN BIT(16)
+#define RCC_PLLCFGR_DIVQ1EN BIT(17)
+#define RCC_PLLCFGR_DIVR1EN BIT(18)
+
+#define RCC_D1CFGR_HPRE_MASK GENMASK(3, 0)
+#define RCC_D1CFGR_HPRE_DIVIDED BIT(3)
+#define RCC_D1CFGR_HPRE_DIVIDER GENMASK(2, 0)
+
+#define RCC_D1CFGR_HPRE_DIV2 8
+
+#define RCC_D1CFGR_D1PPRE_SHIFT 4
+#define RCC_D1CFGR_D1PPRE_DIVIDED BIT(6)
+#define RCC_D1CFGR_D1PPRE_DIVIDER GENMASK(5, 4)
+
+#define RCC_D1CFGR_D1CPRE_SHIFT 8
+#define RCC_D1CFGR_D1CPRE_DIVIDER GENMASK(10, 8)
+#define RCC_D1CFGR_D1CPRE_DIVIDED BIT(11)
+
+#define RCC_D2CFGR_D2PPRE1_SHIFT 4
+#define RCC_D2CFGR_D2PPRE1_DIVIDED BIT(6)
+#define RCC_D2CFGR_D2PPRE1_DIVIDER GENMASK(5, 4)
+
+#define RCC_D2CFGR_D2PPRE2_SHIFT 8
+#define RCC_D2CFGR_D2PPRE2_DIVIDED BIT(10)
+#define RCC_D2CFGR_D2PPRE2_DIVIDER GENMASK(9, 8)
+
+#define RCC_D3CFGR_D3PPRE_SHIFT 4
+#define RCC_D3CFGR_D3PPRE_DIVIDED BIT(6)
+#define RCC_D3CFGR_D3PPRE_DIVIDER GENMASK(5, 4)
+
+#define RCC_D1CCIPR_FMCSRC_MASK GENMASK(1, 0)
+#define FMCSRC_HCLKD1 0
+#define FMCSRC_PLL1_Q_CK 1
+#define FMCSRC_PLL2_R_CK 2
+#define FMCSRC_PER_CK 3
+
+#define RCC_D1CCIPR_QSPISRC_MASK GENMASK(5, 4)
+#define RCC_D1CCIPR_QSPISRC_SHIFT 4
+#define QSPISRC_HCLKD1 0
+#define QSPISRC_PLL1_Q_CK 1
+#define QSPISRC_PLL2_R_CK 2
+#define QSPISRC_PER_CK 3
+
+#define PWR_CR3 0x0c
+#define PWR_CR3_SDEN BIT(2)
+#define PWR_D3CR 0x18
+#define PWR_D3CR_VOS_MASK GENMASK(15, 14)
+#define PWR_D3CR_VOS_SHIFT 14
+#define VOS_SCALE_3 1
+#define VOS_SCALE_2 2
+#define VOS_SCALE_1 3
+#define PWR_D3CR_VOSREADY BIT(13)
+
+struct stm32_rcc_regs {
+ u32 cr; /* 0x00 Source Control Register */
+ u32 icscr; /* 0x04 Internal Clock Source Calibration Register */
+ u32 crrcr; /* 0x08 Clock Recovery RC Register */
+ u32 reserved1; /* 0x0c reserved */
+ u32 cfgr; /* 0x10 Clock Configuration Register */
+ u32 reserved2; /* 0x14 reserved */
+ u32 d1cfgr; /* 0x18 Domain 1 Clock Configuration Register */
+ u32 d2cfgr; /* 0x1c Domain 2 Clock Configuration Register */
+ u32 d3cfgr; /* 0x20 Domain 3 Clock Configuration Register */
+ u32 reserved3; /* 0x24 reserved */
+ u32 pllckselr; /* 0x28 PLLs Clock Source Selection Register */
+ u32 pllcfgr; /* 0x2c PLLs Configuration Register */
+ u32 pll1divr; /* 0x30 PLL1 Dividers Configuration Register */
+ u32 pll1fracr; /* 0x34 PLL1 Fractional Divider Register */
+ u32 pll2divr; /* 0x38 PLL2 Dividers Configuration Register */
+ u32 pll2fracr; /* 0x3c PLL2 Fractional Divider Register */
+ u32 pll3divr; /* 0x40 PLL3 Dividers Configuration Register */
+ u32 pll3fracr; /* 0x44 PLL3 Fractional Divider Register */
+ u32 reserved4; /* 0x48 reserved */
+ u32 d1ccipr; /* 0x4c Domain 1 Kernel Clock Configuration Register */
+ u32 d2ccip1r; /* 0x50 Domain 2 Kernel Clock Configuration Register */
+ u32 d2ccip2r; /* 0x54 Domain 2 Kernel Clock Configuration Register */
+ u32 d3ccipr; /* 0x58 Domain 3 Kernel Clock Configuration Register */
+ u32 reserved5; /* 0x5c reserved */
+ u32 cier; /* 0x60 Clock Source Interrupt Enable Register */
+ u32 cifr; /* 0x64 Clock Source Interrupt Flag Register */
+ u32 cicr; /* 0x68 Clock Source Interrupt Clear Register */
+ u32 reserved6; /* 0x6c reserved */
+ u32 bdcr; /* 0x70 Backup Domain Control Register */
+ u32 csr; /* 0x74 Clock Control and Status Register */
+ u32 reserved7; /* 0x78 reserved */
+
+ u32 ahb3rstr; /* 0x7c AHB3 Peripheral Reset Register */
+ u32 ahb1rstr; /* 0x80 AHB1 Peripheral Reset Register */
+ u32 ahb2rstr; /* 0x84 AHB2 Peripheral Reset Register */
+ u32 ahb4rstr; /* 0x88 AHB4 Peripheral Reset Register */
+
+ u32 apb3rstr; /* 0x8c APB3 Peripheral Reset Register */
+ u32 apb1lrstr; /* 0x90 APB1 low Peripheral Reset Register */
+ u32 apb1hrstr; /* 0x94 APB1 high Peripheral Reset Register */
+ u32 apb2rstr; /* 0x98 APB2 Clock Register */
+ u32 apb4rstr; /* 0x9c APB4 Clock Register */
+
+ u32 gcr; /* 0xa0 Global Control Register */
+ u32 reserved8; /* 0xa4 reserved */
+ u32 d3amr; /* 0xa8 D3 Autonomous mode Register */
+ u32 reserved9[9];/* 0xac to 0xcc reserved */
+ u32 rsr; /* 0xd0 Reset Status Register */
+ u32 ahb3enr; /* 0xd4 AHB3 Clock Register */
+ u32 ahb1enr; /* 0xd8 AHB1 Clock Register */
+ u32 ahb2enr; /* 0xdc AHB2 Clock Register */
+ u32 ahb4enr; /* 0xe0 AHB4 Clock Register */
+
+ u32 apb3enr; /* 0xe4 APB3 Clock Register */
+ u32 apb1lenr; /* 0xe8 APB1 low Clock Register */
+ u32 apb1henr; /* 0xec APB1 high Clock Register */
+ u32 apb2enr; /* 0xf0 APB2 Clock Register */
+ u32 apb4enr; /* 0xf4 APB4 Clock Register */
+};
+
+#define RCC_AHB3ENR offsetof(struct stm32_rcc_regs, ahb3enr)
+#define RCC_AHB1ENR offsetof(struct stm32_rcc_regs, ahb1enr)
+#define RCC_AHB2ENR offsetof(struct stm32_rcc_regs, ahb2enr)
+#define RCC_AHB4ENR offsetof(struct stm32_rcc_regs, ahb4enr)
+#define RCC_APB3ENR offsetof(struct stm32_rcc_regs, apb3enr)
+#define RCC_APB1LENR offsetof(struct stm32_rcc_regs, apb1lenr)
+#define RCC_APB1HENR offsetof(struct stm32_rcc_regs, apb1henr)
+#define RCC_APB2ENR offsetof(struct stm32_rcc_regs, apb2enr)
+#define RCC_APB4ENR offsetof(struct stm32_rcc_regs, apb4enr)
+
+struct clk_cfg {
+ u32 gate_offset;
+ u8 gate_bit_idx;
+ const char *name;
+};
+
+#define CLK(_gate_offset, _bit_idx, _name) \
+{ \
+ .gate_offset = _gate_offset,\
+ .gate_bit_idx = _bit_idx,\
+ .name = _name,\
+}
+
+/*
+ * the way all these entries are sorted in this array could seem
+ * unlogical, but we are dependant of kernel DT_bindings,
+ * where clocks are separate in 2 banks, peripheral clocks and
+ * kernel clocks.
+ */
+
+static const struct clk_cfg clk_map[] = {
+ CLK(RCC_AHB3ENR, 31, "d1sram1"), /* peripheral clocks */
+ CLK(RCC_AHB3ENR, 30, "itcm"),
+ CLK(RCC_AHB3ENR, 29, "dtcm2"),
+ CLK(RCC_AHB3ENR, 28, "dtcm1"),
+ CLK(RCC_AHB3ENR, 8, "flitf"),
+ CLK(RCC_AHB3ENR, 5, "jpgdec"),
+ CLK(RCC_AHB3ENR, 4, "dma2d"),
+ CLK(RCC_AHB3ENR, 0, "mdma"),
+ CLK(RCC_AHB1ENR, 28, "usb2ulpi"),
+ CLK(RCC_AHB1ENR, 17, "eth1rx"),
+ CLK(RCC_AHB1ENR, 16, "eth1tx"),
+ CLK(RCC_AHB1ENR, 15, "eth1mac"),
+ CLK(RCC_AHB1ENR, 14, "art"),
+ CLK(RCC_AHB1ENR, 26, "usb1ulpi"),
+ CLK(RCC_AHB1ENR, 1, "dma2"),
+ CLK(RCC_AHB1ENR, 0, "dma1"),
+ CLK(RCC_AHB2ENR, 31, "d2sram3"),
+ CLK(RCC_AHB2ENR, 30, "d2sram2"),
+ CLK(RCC_AHB2ENR, 29, "d2sram1"),
+ CLK(RCC_AHB2ENR, 5, "hash"),
+ CLK(RCC_AHB2ENR, 4, "crypt"),
+ CLK(RCC_AHB2ENR, 0, "camitf"),
+ CLK(RCC_AHB4ENR, 28, "bkpram"),
+ CLK(RCC_AHB4ENR, 25, "hsem"),
+ CLK(RCC_AHB4ENR, 21, "bdma"),
+ CLK(RCC_AHB4ENR, 19, "crc"),
+ CLK(RCC_AHB4ENR, 10, "gpiok"),
+ CLK(RCC_AHB4ENR, 9, "gpioj"),
+ CLK(RCC_AHB4ENR, 8, "gpioi"),
+ CLK(RCC_AHB4ENR, 7, "gpioh"),
+ CLK(RCC_AHB4ENR, 6, "gpiog"),
+ CLK(RCC_AHB4ENR, 5, "gpiof"),
+ CLK(RCC_AHB4ENR, 4, "gpioe"),
+ CLK(RCC_AHB4ENR, 3, "gpiod"),
+ CLK(RCC_AHB4ENR, 2, "gpioc"),
+ CLK(RCC_AHB4ENR, 1, "gpiob"),
+ CLK(RCC_AHB4ENR, 0, "gpioa"),
+ CLK(RCC_APB3ENR, 6, "wwdg1"),
+ CLK(RCC_APB1LENR, 29, "dac12"),
+ CLK(RCC_APB1LENR, 11, "wwdg2"),
+ CLK(RCC_APB1LENR, 8, "tim14"),
+ CLK(RCC_APB1LENR, 7, "tim13"),
+ CLK(RCC_APB1LENR, 6, "tim12"),
+ CLK(RCC_APB1LENR, 5, "tim7"),
+ CLK(RCC_APB1LENR, 4, "tim6"),
+ CLK(RCC_APB1LENR, 3, "tim5"),
+ CLK(RCC_APB1LENR, 2, "tim4"),
+ CLK(RCC_APB1LENR, 1, "tim3"),
+ CLK(RCC_APB1LENR, 0, "tim2"),
+ CLK(RCC_APB1HENR, 5, "mdios"),
+ CLK(RCC_APB1HENR, 4, "opamp"),
+ CLK(RCC_APB1HENR, 1, "crs"),
+ CLK(RCC_APB2ENR, 18, "tim17"),
+ CLK(RCC_APB2ENR, 17, "tim16"),
+ CLK(RCC_APB2ENR, 16, "tim15"),
+ CLK(RCC_APB2ENR, 1, "tim8"),
+ CLK(RCC_APB2ENR, 0, "tim1"),
+ CLK(RCC_APB4ENR, 26, "tmpsens"),
+ CLK(RCC_APB4ENR, 16, "rtcapb"),
+ CLK(RCC_APB4ENR, 15, "vref"),
+ CLK(RCC_APB4ENR, 14, "comp12"),
+ CLK(RCC_APB4ENR, 1, "syscfg"),
+ CLK(RCC_AHB3ENR, 16, "sdmmc1"), /* kernel clocks */
+ CLK(RCC_AHB3ENR, 14, "quadspi"),
+ CLK(RCC_AHB3ENR, 12, "fmc"),
+ CLK(RCC_AHB1ENR, 27, "usb2otg"),
+ CLK(RCC_AHB1ENR, 25, "usb1otg"),
+ CLK(RCC_AHB1ENR, 5, "adc12"),
+ CLK(RCC_AHB2ENR, 9, "sdmmc2"),
+ CLK(RCC_AHB2ENR, 6, "rng"),
+ CLK(RCC_AHB4ENR, 24, "adc3"),
+ CLK(RCC_APB3ENR, 4, "dsi"),
+ CLK(RCC_APB3ENR, 3, "ltdc"),
+ CLK(RCC_APB1LENR, 31, "usart8"),
+ CLK(RCC_APB1LENR, 30, "usart7"),
+ CLK(RCC_APB1LENR, 27, "hdmicec"),
+ CLK(RCC_APB1LENR, 23, "i2c3"),
+ CLK(RCC_APB1LENR, 22, "i2c2"),
+ CLK(RCC_APB1LENR, 21, "i2c1"),
+ CLK(RCC_APB1LENR, 20, "uart5"),
+ CLK(RCC_APB1LENR, 19, "uart4"),
+ CLK(RCC_APB1LENR, 18, "usart3"),
+ CLK(RCC_APB1LENR, 17, "usart2"),
+ CLK(RCC_APB1LENR, 16, "spdifrx"),
+ CLK(RCC_APB1LENR, 15, "spi3"),
+ CLK(RCC_APB1LENR, 14, "spi2"),
+ CLK(RCC_APB1LENR, 9, "lptim1"),
+ CLK(RCC_APB1HENR, 8, "fdcan"),
+ CLK(RCC_APB1HENR, 2, "swp"),
+ CLK(RCC_APB2ENR, 29, "hrtim"),
+ CLK(RCC_APB2ENR, 28, "dfsdm1"),
+ CLK(RCC_APB2ENR, 24, "sai3"),
+ CLK(RCC_APB2ENR, 23, "sai2"),
+ CLK(RCC_APB2ENR, 22, "sai1"),
+ CLK(RCC_APB2ENR, 20, "spi5"),
+ CLK(RCC_APB2ENR, 13, "spi4"),
+ CLK(RCC_APB2ENR, 12, "spi1"),
+ CLK(RCC_APB2ENR, 5, "usart6"),
+ CLK(RCC_APB2ENR, 4, "usart1"),
+ CLK(RCC_APB4ENR, 21, "sai4a"),
+ CLK(RCC_APB4ENR, 21, "sai4b"),
+ CLK(RCC_APB4ENR, 12, "lptim5"),
+ CLK(RCC_APB4ENR, 11, "lptim4"),
+ CLK(RCC_APB4ENR, 10, "lptim3"),
+ CLK(RCC_APB4ENR, 9, "lptim2"),
+ CLK(RCC_APB4ENR, 7, "i2c4"),
+ CLK(RCC_APB4ENR, 5, "spi6"),
+ CLK(RCC_APB4ENR, 3, "lpuart1"),
+};
+
+struct stm32_clk {
+ struct stm32_rcc_regs *rcc_base;
+ struct regmap *pwr_regmap;
+};
+
+struct pll_psc {
+ u8 divm;
+ u16 divn;
+ u8 divp;
+ u8 divq;
+ u8 divr;
+};
+
+/*
+ * OSC_HSE = 25 MHz
+ * VCO = 500MHz
+ * pll1_p = 250MHz / pll1_q = 250MHz pll1_r = 250Mhz
+ */
+struct pll_psc sys_pll_psc = {
+ .divm = 4,
+ .divn = 80,
+ .divp = 2,
+ .divq = 2,
+ .divr = 2,
+};
+
+int configure_clocks(struct udevice *dev)
+{
+ struct stm32_clk *priv = dev_get_priv(dev);
+ struct stm32_rcc_regs *regs = priv->rcc_base;
+ uint8_t *pwr_base = (uint8_t *)regmap_get_range(priv->pwr_regmap, 0);
+ uint32_t pllckselr = 0;
+ uint32_t pll1divr = 0;
+ uint32_t pllcfgr = 0;
+
+ /* Switch on HSI */
+ setbits_le32(&regs->cr, RCC_CR_HSION);
+ while (!(readl(&regs->cr) & RCC_CR_HSIRDY))
+ ;
+
+ /* Reset CFGR, now HSI is the default system clock */
+ writel(0, &regs->cfgr);
+
+ /* Set all kernel domain clock registers to reset value*/
+ writel(0x0, &regs->d1ccipr);
+ writel(0x0, &regs->d2ccip1r);
+ writel(0x0, &regs->d2ccip2r);
+
+ /* Set voltage scaling at scale 1 */
+ clrsetbits_le32(pwr_base + PWR_D3CR, PWR_D3CR_VOS_MASK,
+ VOS_SCALE_1 << PWR_D3CR_VOS_SHIFT);
+ /* disable step down converter */
+ clrbits_le32(pwr_base + PWR_CR3, PWR_CR3_SDEN);
+ while (!(readl(pwr_base + PWR_D3CR) & PWR_D3CR_VOSREADY))
+ ;
+
+ /* disable HSE to configure it */
+ clrbits_le32(&regs->cr, RCC_CR_HSEON);
+ while ((readl(&regs->cr) & RCC_CR_HSERDY))
+ ;
+
+ /* clear HSE bypass and set it ON */
+ clrbits_le32(&regs->cr, RCC_CR_HSEBYP);
+ /* Switch on HSE */
+ setbits_le32(&regs->cr, RCC_CR_HSEON);
+ while (!(readl(&regs->cr) & RCC_CR_HSERDY))
+ ;
+
+ /* pll setup, disable it */
+ clrbits_le32(&regs->cr, RCC_CR_PLL1ON);
+ while ((readl(&regs->cr) & RCC_CR_PLL1RDY))
+ ;
+
+ /* Select HSE as PLL clock source */
+ pllckselr |= RCC_PLLCKSELR_PLLSRC_HSE;
+ pllckselr |= sys_pll_psc.divm << RCC_PLLCKSELR_DIVM1_SHIFT;
+ writel(pllckselr, &regs->pllckselr);
+
+ pll1divr |= (sys_pll_psc.divr - 1) << RCC_PLL1DIVR_DIVR1_SHIFT;
+ pll1divr |= (sys_pll_psc.divq - 1) << RCC_PLL1DIVR_DIVQ1_SHIFT;
+ pll1divr |= (sys_pll_psc.divp - 1) << RCC_PLL1DIVR_DIVP1_SHIFT;
+ pll1divr |= (sys_pll_psc.divn - 1);
+ writel(pll1divr, &regs->pll1divr);
+
+ pllcfgr |= PLL1RGE_4_8_MHZ << RCC_PLLCFGR_PLL1RGE_SHIFT;
+ pllcfgr |= RCC_PLLCFGR_DIVP1EN;
+ pllcfgr |= RCC_PLLCFGR_DIVQ1EN;
+ pllcfgr |= RCC_PLLCFGR_DIVR1EN;
+ writel(pllcfgr, &regs->pllcfgr);
+
+ /* pll setup, enable it */
+ setbits_le32(&regs->cr, RCC_CR_PLL1ON);
+
+ /* set HPRE (/2) DI clk --> 125MHz */
+ clrsetbits_le32(&regs->d1cfgr, RCC_D1CFGR_HPRE_MASK,
+ RCC_D1CFGR_HPRE_DIV2);
+
+ /* select PLL1 as system clock source (sys_ck)*/
+ clrsetbits_le32(&regs->cfgr, RCC_CFGR_SW_MASK, RCC_CFGR_SW_PLL1);
+ while ((readl(&regs->cfgr) & RCC_CFGR_SW_MASK) != RCC_CFGR_SW_PLL1)
+ ;
+
+ /* sdram: use pll1_q as fmc_k clk */
+ clrsetbits_le32(&regs->d1ccipr, RCC_D1CCIPR_FMCSRC_MASK,
+ FMCSRC_PLL1_Q_CK);
+
+ return 0;
+}
+
+static u32 stm32_get_HSI_divider(struct stm32_rcc_regs *regs)
+{
+ u32 divider;
+
+ /* get HSI divider value */
+ divider = readl(&regs->cr) & RCC_CR_HSIDIV_MASK;
+ divider = divider >> RCC_CR_HSIDIV_SHIFT;
+
+ return divider;
+};
+
+enum pllsrc {
+ HSE,
+ LSE,
+ HSI,
+ CSI,
+ I2S,
+ TIMER,
+ PLLSRC_NB,
+};
+
+static const char * const pllsrc_name[PLLSRC_NB] = {
+ [HSE] = "clk-hse",
+ [LSE] = "clk-lse",
+ [HSI] = "clk-hsi",
+ [CSI] = "clk-csi",
+ [I2S] = "clk-i2s",
+ [TIMER] = "timer-clk"
+};
+
+static ulong stm32_get_rate(struct stm32_rcc_regs *regs, enum pllsrc pllsrc)
+{
+ struct clk clk;
+ struct udevice *fixed_clock_dev = NULL;
+ u32 divider;
+ int ret;
+ const char *name = pllsrc_name[pllsrc];
+
+ debug("%s name %s\n", __func__, name);
+
+ clk.id = 0;
+ ret = uclass_get_device_by_name(UCLASS_CLK, name, &fixed_clock_dev);
+ if (ret) {
+ error("Can't find clk %s (%d)", name, ret);
+ return 0;
+ }
+
+ ret = clk_request(fixed_clock_dev, &clk);
+ if (ret) {
+ error("Can't request %s clk (%d)", name, ret);
+ return 0;
+ }
+
+ divider = 0;
+ if (pllsrc == HSI)
+ divider = stm32_get_HSI_divider(regs);
+
+ debug("%s divider %d rate %ld\n", __func__,
+ divider, clk_get_rate(&clk));
+
+ return clk_get_rate(&clk) >> divider;
+};
+
+enum pll1_output {
+ PLL1_P_CK,
+ PLL1_Q_CK,
+ PLL1_R_CK,
+};
+
+static u32 stm32_get_PLL1_rate(struct stm32_rcc_regs *regs,
+ enum pll1_output output)
+{
+ ulong pllsrc = 0;
+ u32 divm1, divn1, divp1, divq1, divr1, fracn1;
+ ulong vco, rate;
+
+ /* get the PLLSRC */
+ switch (readl(&regs->pllckselr) & RCC_PLLCKSELR_PLLSRC_MASK) {
+ case RCC_PLLCKSELR_PLLSRC_HSI:
+ pllsrc = stm32_get_rate(regs, HSI);
+ break;
+ case RCC_PLLCKSELR_PLLSRC_CSI:
+ pllsrc = stm32_get_rate(regs, CSI);
+ break;
+ case RCC_PLLCKSELR_PLLSRC_HSE:
+ pllsrc = stm32_get_rate(regs, HSE);
+ break;
+ case RCC_PLLCKSELR_PLLSRC_NO_CLK:
+ /* shouldn't happen */
+ error("wrong value for RCC_PLLCKSELR register\n");
+ pllsrc = 0;
+ break;
+ }
+
+ /* pllsrc = 0 ? no need to go ahead */
+ if (!pllsrc)
+ return pllsrc;
+
+ /* get divm1, divp1, divn1 and divr1 */
+ divm1 = readl(&regs->pllckselr) & RCC_PLLCKSELR_DIVM1_MASK;
+ divm1 = divm1 >> RCC_PLLCKSELR_DIVM1_SHIFT;
+
+ divn1 = (readl(&regs->pll1divr) & RCC_PLL1DIVR_DIVN1_MASK) + 1;
+
+ divp1 = readl(&regs->pll1divr) & RCC_PLL1DIVR_DIVP1_MASK;
+ divp1 = (divp1 >> RCC_PLL1DIVR_DIVP1_SHIFT) + 1;
+
+ divq1 = readl(&regs->pll1divr) & RCC_PLL1DIVR_DIVQ1_MASK;
+ divq1 = (divq1 >> RCC_PLL1DIVR_DIVQ1_SHIFT) + 1;
+
+ divr1 = readl(&regs->pll1divr) & RCC_PLL1DIVR_DIVR1_MASK;
+ divr1 = (divr1 >> RCC_PLL1DIVR_DIVR1_SHIFT) + 1;
+
+ fracn1 = readl(&regs->pll1fracr) & RCC_PLL1DIVR_DIVR1_MASK;
+ fracn1 = fracn1 & RCC_PLL1DIVR_DIVR1_SHIFT;
+
+ vco = (pllsrc / divm1) * divn1;
+ rate = (pllsrc * fracn1) / (divm1 * 8192);
+
+ debug("%s divm1 = %d divn1 = %d divp1 = %d divq1 = %d divr1 = %d\n",
+ __func__, divm1, divn1, divp1, divq1, divr1);
+ debug("%s fracn1 = %d vco = %ld rate = %ld\n",
+ __func__, fracn1, vco, rate);
+
+ switch (output) {
+ case PLL1_P_CK:
+ return (vco + rate) / divp1;
+ break;
+ case PLL1_Q_CK:
+ return (vco + rate) / divq1;
+ break;
+
+ case PLL1_R_CK:
+ return (vco + rate) / divr1;
+ break;
+ }
+
+ return -EINVAL;
+}
+
+static ulong stm32_clk_get_rate(struct clk *clk)
+{
+ struct stm32_clk *priv = dev_get_priv(clk->dev);
+ struct stm32_rcc_regs *regs = priv->rcc_base;
+ ulong sysclk = 0;
+ u32 gate_offset;
+ u32 d1cfgr;
+ /* prescaler table lookups for clock computation */
+ u16 prescaler_table[8] = {2, 4, 8, 16, 64, 128, 256, 512};
+ u8 source, idx;
+
+ /*
+ * get system clock (sys_ck) source
+ * can be HSI_CK, CSI_CK, HSE_CK or pll1_p_ck
+ */
+ source = readl(&regs->cfgr) & RCC_CFGR_SW_MASK;
+ switch (source) {
+ case RCC_CFGR_SW_PLL1:
+ sysclk = stm32_get_PLL1_rate(regs, PLL1_P_CK);
+ break;
+ case RCC_CFGR_SW_HSE:
+ sysclk = stm32_get_rate(regs, HSE);
+ break;
+
+ case RCC_CFGR_SW_CSI:
+ sysclk = stm32_get_rate(regs, CSI);
+ break;
+
+ case RCC_CFGR_SW_HSI:
+ sysclk = stm32_get_rate(regs, HSI);
+ break;
+ }
+
+ /* sysclk = 0 ? no need to go ahead */
+ if (!sysclk)
+ return sysclk;
+
+ debug("%s system clock: source = %d freq = %ld\n",
+ __func__, source, sysclk);
+
+ d1cfgr = readl(&regs->d1cfgr);
+
+ if (d1cfgr & RCC_D1CFGR_D1CPRE_DIVIDED) {
+ /* get D1 domain Core prescaler */
+ idx = (d1cfgr & RCC_D1CFGR_D1CPRE_DIVIDER) >>
+ RCC_D1CFGR_D1CPRE_SHIFT;
+ sysclk = sysclk / prescaler_table[idx];
+ }
+
+ if (d1cfgr & RCC_D1CFGR_HPRE_DIVIDED) {
+ /* get D1 domain AHB prescaler */
+ idx = d1cfgr & RCC_D1CFGR_HPRE_DIVIDER;
+ sysclk = sysclk / prescaler_table[idx];
+ }
+
+ gate_offset = clk_map[clk->id].gate_offset;
+
+ debug("%s clk->id=%ld gate_offset=0x%x sysclk=%ld\n",
+ __func__, clk->id, gate_offset, sysclk);
+
+ switch (gate_offset) {
+ case RCC_AHB3ENR:
+ case RCC_AHB1ENR:
+ case RCC_AHB2ENR:
+ case RCC_AHB4ENR:
+ return sysclk;
+ break;
+
+ case RCC_APB3ENR:
+ if (d1cfgr & RCC_D1CFGR_D1PPRE_DIVIDED) {
+ /* get D1 domain APB3 prescaler */
+ idx = (d1cfgr & RCC_D1CFGR_D1PPRE_DIVIDER) >>
+ RCC_D1CFGR_D1PPRE_SHIFT;
+ sysclk = sysclk / prescaler_table[idx];
+ }
+
+ debug("%s system clock: freq after APB3 prescaler = %ld\n",
+ __func__, sysclk);
+
+ return sysclk;
+ break;
+
+ case RCC_APB4ENR:
+ if (d1cfgr & RCC_D3CFGR_D3PPRE_DIVIDED) {
+ /* get D3 domain APB4 prescaler */
+ idx = (d1cfgr & RCC_D3CFGR_D3PPRE_DIVIDER) >>
+ RCC_D3CFGR_D3PPRE_SHIFT;
+ sysclk = sysclk / prescaler_table[idx];
+ }
+
+ debug("%s system clock: freq after APB4 prescaler = %ld\n",
+ __func__, sysclk);
+
+ return sysclk;
+ break;
+
+ case RCC_APB1LENR:
+ case RCC_APB1HENR:
+ if (d1cfgr & RCC_D2CFGR_D2PPRE1_DIVIDED) {
+ /* get D2 domain APB1 prescaler */
+ idx = (d1cfgr & RCC_D2CFGR_D2PPRE1_DIVIDER) >>
+ RCC_D2CFGR_D2PPRE1_SHIFT;
+ sysclk = sysclk / prescaler_table[idx];
+ }
+
+ debug("%s system clock: freq after APB1 prescaler = %ld\n",
+ __func__, sysclk);
+
+ return sysclk;
+ break;
+
+ case RCC_APB2ENR:
+ if (d1cfgr & RCC_D2CFGR_D2PPRE2_DIVIDED) {
+ /* get D2 domain APB1 prescaler */
+ idx = (d1cfgr & RCC_D2CFGR_D2PPRE2_DIVIDER) >>
+ RCC_D2CFGR_D2PPRE2_SHIFT;
+ sysclk = sysclk / prescaler_table[idx];
+ }
+
+ debug("%s system clock: freq after APB2 prescaler = %ld\n",
+ __func__, sysclk);
+
+ return sysclk;
+ break;
+
+ default:
+ error("unexpected gate_offset value (0x%x)\n", gate_offset);
+ return -EINVAL;
+ break;
+ }
+}
+
+static int stm32_clk_enable(struct clk *clk)
+{
+ struct stm32_clk *priv = dev_get_priv(clk->dev);
+ struct stm32_rcc_regs *regs = priv->rcc_base;
+ u32 gate_offset;
+ u32 gate_bit_index;
+ unsigned long clk_id = clk->id;
+
+ gate_offset = clk_map[clk_id].gate_offset;
+ gate_bit_index = clk_map[clk_id].gate_bit_idx;
+
+ debug("%s: clkid=%ld gate offset=0x%x bit_index=%d name=%s\n",
+ __func__, clk->id, gate_offset, gate_bit_index,
+ clk_map[clk_id].name);
+
+ setbits_le32(&regs->cr + (gate_offset / 4), BIT(gate_bit_index));
+
+ return 0;
+}
+
+static int stm32_clk_probe(struct udevice *dev)
+{
+ struct stm32_clk *priv = dev_get_priv(dev);
+ struct udevice *syscon;
+ fdt_addr_t addr;
+ int err;
+
+ addr = dev_read_addr(dev);
+ if (addr == FDT_ADDR_T_NONE)
+ return -EINVAL;
+
+ priv->rcc_base = (struct stm32_rcc_regs *)addr;
+
+ /* get corresponding syscon phandle */
+ err = uclass_get_device_by_phandle(UCLASS_SYSCON, dev,
+ "st,syscfg", &syscon);
+
+ if (err) {
+ error("unable to find syscon device\n");
+ return err;
+ }
+
+ priv->pwr_regmap = syscon_get_regmap(syscon);
+ if (!priv->pwr_regmap) {
+ error("unable to find regmap\n");
+ return -ENODEV;
+ }
+
+ configure_clocks(dev);
+
+ return 0;
+}
+
+static int stm32_clk_of_xlate(struct clk *clk,
+ struct ofnode_phandle_args *args)
+{
+ if (args->args_count != 1) {
+ debug("Invaild args_count: %d\n", args->args_count);
+ return -EINVAL;
+ }
+
+ if (args->args_count) {
+ clk->id = args->args[0];
+ /*
+ * this computation convert DT clock index which is used to
+ * point into 2 separate clock arrays (peripheral and kernel
+ * clocks bank) (see include/dt-bindings/clock/stm32h7-clks.h)
+ * into index to point into only one array where peripheral
+ * and kernel clocks are consecutive
+ */
+ if (clk->id >= KERN_BANK) {
+ clk->id -= KERN_BANK;
+ clk->id += LAST_PERIF_BANK - PERIF_BANK + 1;
+ } else {
+ clk->id -= PERIF_BANK;
+ }
+ } else {
+ clk->id = 0;
+ }
+
+ debug("%s clk->id %ld\n", __func__, clk->id);
+
+ return 0;
+}
+
+static struct clk_ops stm32_clk_ops = {
+ .of_xlate = stm32_clk_of_xlate,
+ .enable = stm32_clk_enable,
+ .get_rate = stm32_clk_get_rate,
+};
+
+U_BOOT_DRIVER(stm32h7_clk) = {
+ .name = "stm32h7_rcc_clock",
+ .id = UCLASS_CLK,
+ .ops = &stm32_clk_ops,
+ .probe = stm32_clk_probe,
+ .priv_auto_alloc_size = sizeof(struct stm32_clk),
+ .flags = DM_FLAG_PRE_RELOC,
+};
diff --git a/drivers/clk/rockchip/clk_rk3368.c b/drivers/clk/rockchip/clk_rk3368.c
index 0160d50c03..e2747816b9 100644
--- a/drivers/clk/rockchip/clk_rk3368.c
+++ b/drivers/clk/rockchip/clk_rk3368.c
@@ -485,7 +485,7 @@ static int rk3368_clk_ofdata_to_platdata(struct udevice *dev)
#if !CONFIG_IS_ENABLED(OF_PLATDATA)
struct rk3368_clk_priv *priv = dev_get_priv(dev);
- priv->cru = (struct rk3368_cru *)devfdt_get_addr(dev);
+ priv->cru = dev_read_addr_ptr(dev);
#endif
return 0;
diff --git a/drivers/clk/rockchip/clk_rk3399.c b/drivers/clk/rockchip/clk_rk3399.c
index 7232806724..9d963be552 100644
--- a/drivers/clk/rockchip/clk_rk3399.c
+++ b/drivers/clk/rockchip/clk_rk3399.c
@@ -950,9 +950,24 @@ static ulong rk3399_clk_set_rate(struct clk *clk, ulong rate)
return ret;
}
+static int rk3399_clk_enable(struct clk *clk)
+{
+ switch (clk->id) {
+ case HCLK_HOST0:
+ case HCLK_HOST0_ARB:
+ case HCLK_HOST1:
+ case HCLK_HOST1_ARB:
+ return 0;
+ }
+
+ debug("%s: unsupported clk %ld\n", __func__, clk->id);
+ return -ENOENT;
+}
+
static struct clk_ops rk3399_clk_ops = {
.get_rate = rk3399_clk_get_rate,
.set_rate = rk3399_clk_set_rate,
+ .enable = rk3399_clk_enable,
};
static int rk3399_clk_probe(struct udevice *dev)
@@ -975,7 +990,7 @@ static int rk3399_clk_ofdata_to_platdata(struct udevice *dev)
#if !CONFIG_IS_ENABLED(OF_PLATDATA)
struct rk3399_clk_priv *priv = dev_get_priv(dev);
- priv->cru = (struct rk3399_cru *)devfdt_get_addr(dev);
+ priv->cru = dev_read_addr_ptr(dev);
#endif
return 0;
}
@@ -1159,7 +1174,7 @@ static int rk3399_pmuclk_ofdata_to_platdata(struct udevice *dev)
#if !CONFIG_IS_ENABLED(OF_PLATDATA)
struct rk3399_pmuclk_priv *priv = dev_get_priv(dev);
- priv->pmucru = (struct rk3399_pmucru *)devfdt_get_addr(dev);
+ priv->pmucru = dev_read_addr_ptr(dev);
#endif
return 0;
}
diff --git a/drivers/core/read.c b/drivers/core/read.c
index 6acb33388f..eacf1716fd 100644
--- a/drivers/core/read.c
+++ b/drivers/core/read.c
@@ -57,6 +57,13 @@ fdt_addr_t dev_read_addr(struct udevice *dev)
return dev_read_addr_index(dev, 0);
}
+void *dev_read_addr_ptr(struct udevice *dev)
+{
+ fdt_addr_t addr = dev_read_addr(dev);
+
+ return (addr == FDT_ADDR_T_NONE) ? NULL : (void *)addr;
+}
+
fdt_addr_t dev_read_addr_size(struct udevice *dev, const char *property,
fdt_size_t *sizep)
{
@@ -74,6 +81,17 @@ int dev_read_stringlist_search(struct udevice *dev, const char *property,
return ofnode_stringlist_search(dev_ofnode(dev), property, string);
}
+int dev_read_string_index(struct udevice *dev, const char *propname, int index,
+ const char **outp)
+{
+ return ofnode_read_string_index(dev_ofnode(dev), propname, index, outp);
+}
+
+int dev_read_string_count(struct udevice *dev, const char *propname)
+{
+ return ofnode_read_string_count(dev_ofnode(dev), propname);
+}
+
int dev_read_phandle_with_args(struct udevice *dev, const char *list_name,
const char *cells_name, int cell_count,
int index,
diff --git a/drivers/gpio/rk_gpio.c b/drivers/gpio/rk_gpio.c
index 6f7366acba..11fc3e26bd 100644
--- a/drivers/gpio/rk_gpio.c
+++ b/drivers/gpio/rk_gpio.c
@@ -103,8 +103,7 @@ static int rockchip_gpio_probe(struct udevice *dev)
char *end;
int ret;
- /* This only supports RK3288 at present */
- priv->regs = (struct rockchip_gpio_regs *)devfdt_get_addr(dev);
+ priv->regs = dev_read_addr_ptr(dev);
ret = uclass_first_device_err(UCLASS_PINCTRL, &priv->pinctrl);
if (ret)
return ret;
diff --git a/drivers/i2c/rk_i2c.c b/drivers/i2c/rk_i2c.c
index 68e66536e4..840b3f6046 100644
--- a/drivers/i2c/rk_i2c.c
+++ b/drivers/i2c/rk_i2c.c
@@ -382,7 +382,7 @@ static int rockchip_i2c_probe(struct udevice *bus)
{
struct rk_i2c *priv = dev_get_priv(bus);
- priv->regs = (void *)devfdt_get_addr(bus);
+ priv->regs = dev_read_addr_ptr(bus);
return 0;
}
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 4133017e32..f1c15cb9fa 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -158,6 +158,15 @@ config PCA9551_I2C_ADDR
help
The I2C address of the PCA9551 LED controller.
+config STM32_RCC
+ bool "Enable RCC driver for the STM32 SoC's family"
+ depends on STM32 && MISC
+ help
+ Enable the STM32 RCC driver. The RCC block (Reset and Clock Control
+ block) is responsible of the management of the clock and reset
+ generation.
+ This driver is similar to an MFD driver in the Linux kernel.
+
config TEGRA_CAR
bool "Enable support for the Tegra CAR driver"
depends on TEGRA_NO_BPMP
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 21f7e6c6f5..ada7624417 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -52,3 +52,4 @@ obj-$(CONFIG_FSL_DEVICE_DISABLE) += fsl_devdis.o
obj-$(CONFIG_WINBOND_W83627) += winbond_w83627.o
obj-$(CONFIG_QFW) += qfw.o
obj-$(CONFIG_ROCKCHIP_EFUSE) += rockchip-efuse.o
+obj-$(CONFIG_STM32_RCC) += stm32_rcc.o
diff --git a/drivers/misc/rockchip-efuse.c b/drivers/misc/rockchip-efuse.c
index 2e3bc9137a..a2203bf37b 100644
--- a/drivers/misc/rockchip-efuse.c
+++ b/drivers/misc/rockchip-efuse.c
@@ -142,7 +142,7 @@ static int rockchip_efuse_ofdata_to_platdata(struct udevice *dev)
{
struct rockchip_efuse_platdata *plat = dev_get_platdata(dev);
- plat->base = (void *)dev_read_addr(dev);
+ plat->base = dev_read_addr_ptr(dev);
return 0;
}
diff --git a/drivers/misc/stm32_rcc.c b/drivers/misc/stm32_rcc.c
new file mode 100644
index 0000000000..a6c2a757ec
--- /dev/null
+++ b/drivers/misc/stm32_rcc.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) STMicroelectronics SA 2017
+ * Author(s): Patrice CHOTARD, <patrice.chotard@st.com> for STMicroelectronics.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <misc.h>
+#include <dm/lists.h>
+
+static int stm32_rcc_bind(struct udevice *dev)
+{
+ int ret;
+ struct udevice *child;
+
+ debug("%s(dev=%p)\n", __func__, dev);
+
+ ret = device_bind_driver_to_node(dev, "stm32h7_rcc_clock",
+ "stm32h7_rcc_clock",
+ dev_ofnode(dev), &child);
+ if (ret)
+ return ret;
+
+ return device_bind_driver_to_node(dev, "stm32_rcc_reset",
+ "stm32_rcc_reset",
+ dev_ofnode(dev), &child);
+}
+
+static const struct misc_ops stm32_rcc_ops = {
+};
+
+static const struct udevice_id stm32_rcc_ids[] = {
+ {.compatible = "st,stm32h743-rcc"},
+ { }
+};
+
+U_BOOT_DRIVER(stm32_rcc) = {
+ .name = "stm32-rcc",
+ .id = UCLASS_MISC,
+ .of_match = stm32_rcc_ids,
+ .bind = stm32_rcc_bind,
+ .ops = &stm32_rcc_ops,
+};
diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig
index 6de927b8c6..24b4eadd2a 100644
--- a/drivers/mmc/Kconfig
+++ b/drivers/mmc/Kconfig
@@ -136,6 +136,7 @@ config MMC_PCI
config MMC_OMAP_HS
bool "TI OMAP High Speed Multimedia Card Interface support"
select DM_REGULATOR_PBIAS if DM_MMC && DM_REGULATOR
+ select DM_REGULATOR_PBIAS if DM_MMC && DM_REGULATOR
help
This selects the TI OMAP High Speed Multimedia card Interface.
If you have an omap2plus board with a Multimedia Card slot,
@@ -162,12 +163,13 @@ config SH_SDHI
Support for the on-chip SDHI host controller on SuperH/Renesas ARM SoCs platform
config MMC_UNIPHIER
- bool "UniPhier SD/MMC Host Controller support"
- depends on ARCH_UNIPHIER
+ bool "UniPhier/RCar SD/MMC Host Controller support"
+ depends on ARCH_UNIPHIER || ARCH_RMOBILE
depends on BLK && DM_MMC
depends on OF_CONTROL
help
- This selects support for the SD/MMC Host Controller on UniPhier SoCs.
+ This selects support for the Matsushita SD/MMC Host Controller on
+ SocioNext UniPhier and Renesas RCar SoCs.
config MMC_SANDBOX
bool "Sandbox MMC support"
@@ -382,6 +384,14 @@ config GENERIC_ATMEL_MCI
the SD Memory Card Specification V2.0, the SDIO V2.0 specification
and CE-ATA V1.1.
+config STM32_SDMMC2
+ bool "STMicroelectronics STM32H7 SD/MMC Host Controller support"
+ depends on DM_MMC && BLK && OF_CONTROL && DM_MMC_OPS
+ help
+ This selects support for the SD/MMC controller on STM32H7 SoCs.
+ If you have a board based on such a SoC and with a SD/MMC slot,
+ say Y or M here.
+
endif
config TEGRA124_MMC_DISABLE_EXT_LOOPBACK
diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile
index a6becb2309..d505f37f01 100644
--- a/drivers/mmc/Makefile
+++ b/drivers/mmc/Makefile
@@ -43,6 +43,7 @@ obj-$(CONFIG_SUPPORT_EMMC_RPMB) += rpmb.o
obj-$(CONFIG_MMC_SANDBOX) += sandbox_mmc.o
obj-$(CONFIG_SH_MMCIF) += sh_mmcif.o
obj-$(CONFIG_SH_SDHI) += sh_sdhi.o
+obj-$(CONFIG_STM32_SDMMC2) += stm32_sdmmc2.o
# SDHCI
obj-$(CONFIG_MMC_SDHCI) += sdhci.o
diff --git a/drivers/mmc/rockchip_dw_mmc.c b/drivers/mmc/rockchip_dw_mmc.c
index e7fcf89f73..807dc9e72f 100644
--- a/drivers/mmc/rockchip_dw_mmc.c
+++ b/drivers/mmc/rockchip_dw_mmc.c
@@ -58,7 +58,7 @@ static int rockchip_dwmmc_ofdata_to_platdata(struct udevice *dev)
struct dwmci_host *host = &priv->host;
host->name = dev->name;
- host->ioaddr = (void *)devfdt_get_addr(dev);
+ host->ioaddr = dev_read_addr_ptr(dev);
host->buswidth = dev_read_u32_default(dev, "bus-width", 4);
host->get_mmc_clk = rockchip_dwmmc_get_mmc_clk;
host->priv = dev;
diff --git a/drivers/mmc/rockchip_sdhci.c b/drivers/mmc/rockchip_sdhci.c
index f31d329c81..0f31dfc3fd 100644
--- a/drivers/mmc/rockchip_sdhci.c
+++ b/drivers/mmc/rockchip_sdhci.c
@@ -9,7 +9,6 @@
#include <common.h>
#include <dm.h>
#include <dt-structs.h>
-#include <fdtdec.h>
#include <libfdt.h>
#include <malloc.h>
#include <mapmem.h>
@@ -46,7 +45,7 @@ static int arasan_sdhci_probe(struct udevice *dev)
struct dtd_rockchip_rk3399_sdhci_5_1 *dtplat = &plat->dtplat;
host->name = dev->name;
- host->ioaddr = map_sysmem(dtplat->reg[1], dtplat->reg[3]);
+ host->ioaddr = map_sysmem(dtplat->reg[0], dtplat->reg[1]);
max_frequency = dtplat->max_frequency;
ret = clk_get_by_index_platdata(dev, 0, dtplat->clocks, &clk);
#else
@@ -82,7 +81,7 @@ static int arasan_sdhci_ofdata_to_platdata(struct udevice *dev)
struct sdhci_host *host = dev_get_priv(dev);
host->name = dev->name;
- host->ioaddr = devfdt_get_addr_ptr(dev);
+ host->ioaddr = dev_read_addr_ptr(dev);
#endif
return 0;
diff --git a/drivers/mmc/sdhci-cadence.c b/drivers/mmc/sdhci-cadence.c
index f83c1d7241..72d1c646a2 100644
--- a/drivers/mmc/sdhci-cadence.c
+++ b/drivers/mmc/sdhci-cadence.c
@@ -23,6 +23,18 @@
#define SDHCI_CDNS_HRS04_WDATA_SHIFT 8
#define SDHCI_CDNS_HRS04_ADDR_SHIFT 0
+#define SDHCI_CDNS_HRS06 0x18 /* eMMC control */
+#define SDHCI_CDNS_HRS06_TUNE_UP BIT(15)
+#define SDHCI_CDNS_HRS06_TUNE_SHIFT 8
+#define SDHCI_CDNS_HRS06_TUNE_MASK 0x3f
+#define SDHCI_CDNS_HRS06_MODE_MASK 0x7
+#define SDHCI_CDNS_HRS06_MODE_SD 0x0
+#define SDHCI_CDNS_HRS06_MODE_MMC_SDR 0x2
+#define SDHCI_CDNS_HRS06_MODE_MMC_DDR 0x3
+#define SDHCI_CDNS_HRS06_MODE_MMC_HS200 0x4
+#define SDHCI_CDNS_HRS06_MODE_MMC_HS400 0x5
+#define SDHCI_CDNS_HRS06_MODE_MMC_HS400ES 0x6
+
/* SRS - Slot Register Set (SDHCI-compatible) */
#define SDHCI_CDNS_SRS_BASE 0x200
@@ -111,6 +123,44 @@ static int sdhci_cdns_phy_init(struct sdhci_cdns_plat *plat,
return 0;
}
+static void sdhci_cdns_set_control_reg(struct sdhci_host *host)
+{
+ struct mmc *mmc = host->mmc;
+ struct sdhci_cdns_plat *plat = dev_get_platdata(mmc->dev);
+ unsigned int clock = mmc->clock;
+ u32 mode, tmp;
+
+ /*
+ * REVISIT:
+ * The mode should be decided by MMC_TIMING_* like Linux, but
+ * U-Boot does not support timing. Use the clock frequency instead.
+ */
+ if (clock <= 26000000)
+ mode = SDHCI_CDNS_HRS06_MODE_SD; /* use this for Legacy */
+ else if (clock <= 52000000) {
+ if (mmc->ddr_mode)
+ mode = SDHCI_CDNS_HRS06_MODE_MMC_DDR;
+ else
+ mode = SDHCI_CDNS_HRS06_MODE_MMC_SDR;
+ } else {
+ /*
+ * REVISIT:
+ * The IP supports HS200/HS400, revisit once U-Boot support it
+ */
+ printf("unsupported frequency %d\n", clock);
+ return;
+ }
+
+ tmp = readl(plat->hrs_addr + SDHCI_CDNS_HRS06);
+ tmp &= ~SDHCI_CDNS_HRS06_MODE_MASK;
+ tmp |= mode;
+ writel(tmp, plat->hrs_addr + SDHCI_CDNS_HRS06);
+}
+
+static const struct sdhci_ops sdhci_cdns_ops = {
+ .set_control_reg = sdhci_cdns_set_control_reg,
+};
+
static int sdhci_cdns_bind(struct udevice *dev)
{
struct sdhci_cdns_plat *plat = dev_get_platdata(dev);
@@ -137,6 +187,7 @@ static int sdhci_cdns_probe(struct udevice *dev)
host->name = dev->name;
host->ioaddr = plat->hrs_addr + SDHCI_CDNS_SRS_BASE;
+ host->ops = &sdhci_cdns_ops;
host->quirks |= SDHCI_QUIRK_WAIT_SEND_CMD;
ret = sdhci_cdns_phy_init(plat, gd->fdt_blob, dev_of_offset(dev));
diff --git a/drivers/mmc/sti_sdhci.c b/drivers/mmc/sti_sdhci.c
index f85f6b4db6..d8b5888b7c 100644
--- a/drivers/mmc/sti_sdhci.c
+++ b/drivers/mmc/sti_sdhci.c
@@ -8,6 +8,7 @@
#include <common.h>
#include <dm.h>
#include <mmc.h>
+#include <reset-uclass.h>
#include <sdhci.h>
#include <asm/arch/sdhci.h>
@@ -16,18 +17,14 @@ DECLARE_GLOBAL_DATA_PTR;
struct sti_sdhci_plat {
struct mmc_config cfg;
struct mmc mmc;
+ struct reset_ctl reset;
+ int instance;
};
-/*
- * used to get access to MMC1 reset,
- * will be removed when STi reset driver will be available
- */
-#define STIH410_SYSCONF5_BASE 0x092b0000
-
/**
* sti_mmc_core_config: configure the Arasan HC
- * @regbase: base address
- * @mmc_instance: mmc instance id
+ * @dev : udevice
+ *
* Description: this function is to configure the Arasan MMC HC.
* This should be called when the system starts in case of, on the SoC,
* it is needed to configure the host controller.
@@ -36,33 +33,39 @@ struct sti_sdhci_plat {
* W/o these settings the SDHCI could configure and use the embedded controller
* with limited features.
*/
-static void sti_mmc_core_config(const u32 regbase, int mmc_instance)
+static int sti_mmc_core_config(struct udevice *dev)
{
- unsigned long *sysconf;
+ struct sti_sdhci_plat *plat = dev_get_platdata(dev);
+ struct sdhci_host *host = dev_get_priv(dev);
+ int ret;
/* only MMC1 has a reset line */
- if (mmc_instance) {
- sysconf = (unsigned long *)(STIH410_SYSCONF5_BASE +
- ST_MMC_CCONFIG_REG_5);
- generic_set_bit(SYSCONF_MMC1_ENABLE_BIT, sysconf);
+ if (plat->instance) {
+ ret = reset_deassert(&plat->reset);
+ if (ret < 0) {
+ error("MMC1 deassert failed: %d", ret);
+ return ret;
+ }
}
writel(STI_FLASHSS_MMC_CORE_CONFIG_1,
- regbase + FLASHSS_MMC_CORE_CONFIG_1);
+ host->ioaddr + FLASHSS_MMC_CORE_CONFIG_1);
- if (mmc_instance) {
+ if (plat->instance) {
writel(STI_FLASHSS_MMC_CORE_CONFIG2,
- regbase + FLASHSS_MMC_CORE_CONFIG_2);
+ host->ioaddr + FLASHSS_MMC_CORE_CONFIG_2);
writel(STI_FLASHSS_MMC_CORE_CONFIG3,
- regbase + FLASHSS_MMC_CORE_CONFIG_3);
+ host->ioaddr + FLASHSS_MMC_CORE_CONFIG_3);
} else {
writel(STI_FLASHSS_SDCARD_CORE_CONFIG2,
- regbase + FLASHSS_MMC_CORE_CONFIG_2);
+ host->ioaddr + FLASHSS_MMC_CORE_CONFIG_2);
writel(STI_FLASHSS_SDCARD_CORE_CONFIG3,
- regbase + FLASHSS_MMC_CORE_CONFIG_3);
+ host->ioaddr + FLASHSS_MMC_CORE_CONFIG_3);
}
writel(STI_FLASHSS_MMC_CORE_CONFIG4,
- regbase + FLASHSS_MMC_CORE_CONFIG_4);
+ host->ioaddr + FLASHSS_MMC_CORE_CONFIG_4);
+
+ return 0;
}
static int sti_sdhci_probe(struct udevice *dev)
@@ -70,20 +73,25 @@ static int sti_sdhci_probe(struct udevice *dev)
struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
struct sti_sdhci_plat *plat = dev_get_platdata(dev);
struct sdhci_host *host = dev_get_priv(dev);
- int ret, mmc_instance;
+ int ret;
/*
* identify current mmc instance, mmc1 has a reset, not mmc0
* MMC0 is wired to the SD slot,
* MMC1 is wired on the high speed connector
*/
-
- if (fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "resets", NULL))
- mmc_instance = 1;
+ ret = reset_get_by_index(dev, 0, &plat->reset);
+ if (!ret)
+ plat->instance = 1;
else
- mmc_instance = 0;
+ if (ret == -ENOENT)
+ plat->instance = 0;
+ else
+ return ret;
- sti_mmc_core_config((const u32) host->ioaddr, mmc_instance);
+ ret = sti_mmc_core_config(dev);
+ if (ret)
+ return ret;
host->quirks = SDHCI_QUIRK_WAIT_SEND_CMD |
SDHCI_QUIRK_32BIT_DMA_ADDR |
diff --git a/drivers/mmc/stm32_sdmmc2.c b/drivers/mmc/stm32_sdmmc2.c
new file mode 100644
index 0000000000..0e1f40b569
--- /dev/null
+++ b/drivers/mmc/stm32_sdmmc2.c
@@ -0,0 +1,608 @@
+/*
+ * Copyright (C) STMicroelectronics SA 2017
+ * Author(s): Patrice CHOTARD, <patrice.chotard@st.com> for STMicroelectronics.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <clk.h>
+#include <dm.h>
+#include <fdtdec.h>
+#include <libfdt.h>
+#include <mmc.h>
+#include <reset.h>
+#include <asm/io.h>
+#include <asm/gpio.h>
+#include <linux/iopoll.h>
+
+struct stm32_sdmmc2_plat {
+ struct mmc_config cfg;
+ struct mmc mmc;
+};
+
+struct stm32_sdmmc2_priv {
+ fdt_addr_t base;
+ struct clk clk;
+ struct reset_ctl reset_ctl;
+ struct gpio_desc cd_gpio;
+ u32 clk_reg_msk;
+ u32 pwr_reg_msk;
+};
+
+struct stm32_sdmmc2_ctx {
+ u32 cache_start;
+ u32 cache_end;
+ u32 data_length;
+ bool dpsm_abort;
+};
+
+/* SDMMC REGISTERS OFFSET */
+#define SDMMC_POWER 0x00 /* SDMMC power control */
+#define SDMMC_CLKCR 0x04 /* SDMMC clock control */
+#define SDMMC_ARG 0x08 /* SDMMC argument */
+#define SDMMC_CMD 0x0C /* SDMMC command */
+#define SDMMC_RESP1 0x14 /* SDMMC response 1 */
+#define SDMMC_RESP2 0x18 /* SDMMC response 2 */
+#define SDMMC_RESP3 0x1C /* SDMMC response 3 */
+#define SDMMC_RESP4 0x20 /* SDMMC response 4 */
+#define SDMMC_DTIMER 0x24 /* SDMMC data timer */
+#define SDMMC_DLEN 0x28 /* SDMMC data length */
+#define SDMMC_DCTRL 0x2C /* SDMMC data control */
+#define SDMMC_DCOUNT 0x30 /* SDMMC data counter */
+#define SDMMC_STA 0x34 /* SDMMC status */
+#define SDMMC_ICR 0x38 /* SDMMC interrupt clear */
+#define SDMMC_MASK 0x3C /* SDMMC mask */
+#define SDMMC_IDMACTRL 0x50 /* SDMMC DMA control */
+#define SDMMC_IDMABASE0 0x58 /* SDMMC DMA buffer 0 base address */
+
+/* SDMMC_POWER register */
+#define SDMMC_POWER_PWRCTRL GENMASK(1, 0)
+#define SDMMC_POWER_VSWITCH BIT(2)
+#define SDMMC_POWER_VSWITCHEN BIT(3)
+#define SDMMC_POWER_DIRPOL BIT(4)
+
+/* SDMMC_CLKCR register */
+#define SDMMC_CLKCR_CLKDIV GENMASK(9, 0)
+#define SDMMC_CLKCR_CLKDIV_MAX SDMMC_CLKCR_CLKDIV
+#define SDMMC_CLKCR_PWRSAV BIT(12)
+#define SDMMC_CLKCR_WIDBUS_4 BIT(14)
+#define SDMMC_CLKCR_WIDBUS_8 BIT(15)
+#define SDMMC_CLKCR_NEGEDGE BIT(16)
+#define SDMMC_CLKCR_HWFC_EN BIT(17)
+#define SDMMC_CLKCR_DDR BIT(18)
+#define SDMMC_CLKCR_BUSSPEED BIT(19)
+#define SDMMC_CLKCR_SELCLKRX GENMASK(21, 20)
+
+/* SDMMC_CMD register */
+#define SDMMC_CMD_CMDINDEX GENMASK(5, 0)
+#define SDMMC_CMD_CMDTRANS BIT(6)
+#define SDMMC_CMD_CMDSTOP BIT(7)
+#define SDMMC_CMD_WAITRESP GENMASK(9, 8)
+#define SDMMC_CMD_WAITRESP_0 BIT(8)
+#define SDMMC_CMD_WAITRESP_1 BIT(9)
+#define SDMMC_CMD_WAITINT BIT(10)
+#define SDMMC_CMD_WAITPEND BIT(11)
+#define SDMMC_CMD_CPSMEN BIT(12)
+#define SDMMC_CMD_DTHOLD BIT(13)
+#define SDMMC_CMD_BOOTMODE BIT(14)
+#define SDMMC_CMD_BOOTEN BIT(15)
+#define SDMMC_CMD_CMDSUSPEND BIT(16)
+
+/* SDMMC_DCTRL register */
+#define SDMMC_DCTRL_DTEN BIT(0)
+#define SDMMC_DCTRL_DTDIR BIT(1)
+#define SDMMC_DCTRL_DTMODE GENMASK(3, 2)
+#define SDMMC_DCTRL_DBLOCKSIZE GENMASK(7, 4)
+#define SDMMC_DCTRL_DBLOCKSIZE_SHIFT 4
+#define SDMMC_DCTRL_RWSTART BIT(8)
+#define SDMMC_DCTRL_RWSTOP BIT(9)
+#define SDMMC_DCTRL_RWMOD BIT(10)
+#define SDMMC_DCTRL_SDMMCEN BIT(11)
+#define SDMMC_DCTRL_BOOTACKEN BIT(12)
+#define SDMMC_DCTRL_FIFORST BIT(13)
+
+/* SDMMC_STA register */
+#define SDMMC_STA_CCRCFAIL BIT(0)
+#define SDMMC_STA_DCRCFAIL BIT(1)
+#define SDMMC_STA_CTIMEOUT BIT(2)
+#define SDMMC_STA_DTIMEOUT BIT(3)
+#define SDMMC_STA_TXUNDERR BIT(4)
+#define SDMMC_STA_RXOVERR BIT(5)
+#define SDMMC_STA_CMDREND BIT(6)
+#define SDMMC_STA_CMDSENT BIT(7)
+#define SDMMC_STA_DATAEND BIT(8)
+#define SDMMC_STA_DHOLD BIT(9)
+#define SDMMC_STA_DBCKEND BIT(10)
+#define SDMMC_STA_DABORT BIT(11)
+#define SDMMC_STA_DPSMACT BIT(12)
+#define SDMMC_STA_CPSMACT BIT(13)
+#define SDMMC_STA_TXFIFOHE BIT(14)
+#define SDMMC_STA_RXFIFOHF BIT(15)
+#define SDMMC_STA_TXFIFOF BIT(16)
+#define SDMMC_STA_RXFIFOF BIT(17)
+#define SDMMC_STA_TXFIFOE BIT(18)
+#define SDMMC_STA_RXFIFOE BIT(19)
+#define SDMMC_STA_BUSYD0 BIT(20)
+#define SDMMC_STA_BUSYD0END BIT(21)
+#define SDMMC_STA_SDMMCIT BIT(22)
+#define SDMMC_STA_ACKFAIL BIT(23)
+#define SDMMC_STA_ACKTIMEOUT BIT(24)
+#define SDMMC_STA_VSWEND BIT(25)
+#define SDMMC_STA_CKSTOP BIT(26)
+#define SDMMC_STA_IDMATE BIT(27)
+#define SDMMC_STA_IDMABTC BIT(28)
+
+/* SDMMC_ICR register */
+#define SDMMC_ICR_CCRCFAILC BIT(0)
+#define SDMMC_ICR_DCRCFAILC BIT(1)
+#define SDMMC_ICR_CTIMEOUTC BIT(2)
+#define SDMMC_ICR_DTIMEOUTC BIT(3)
+#define SDMMC_ICR_TXUNDERRC BIT(4)
+#define SDMMC_ICR_RXOVERRC BIT(5)
+#define SDMMC_ICR_CMDRENDC BIT(6)
+#define SDMMC_ICR_CMDSENTC BIT(7)
+#define SDMMC_ICR_DATAENDC BIT(8)
+#define SDMMC_ICR_DHOLDC BIT(9)
+#define SDMMC_ICR_DBCKENDC BIT(10)
+#define SDMMC_ICR_DABORTC BIT(11)
+#define SDMMC_ICR_BUSYD0ENDC BIT(21)
+#define SDMMC_ICR_SDMMCITC BIT(22)
+#define SDMMC_ICR_ACKFAILC BIT(23)
+#define SDMMC_ICR_ACKTIMEOUTC BIT(24)
+#define SDMMC_ICR_VSWENDC BIT(25)
+#define SDMMC_ICR_CKSTOPC BIT(26)
+#define SDMMC_ICR_IDMATEC BIT(27)
+#define SDMMC_ICR_IDMABTCC BIT(28)
+#define SDMMC_ICR_STATIC_FLAGS ((GENMASK(28, 21)) | (GENMASK(11, 0)))
+
+/* SDMMC_MASK register */
+#define SDMMC_MASK_CCRCFAILIE BIT(0)
+#define SDMMC_MASK_DCRCFAILIE BIT(1)
+#define SDMMC_MASK_CTIMEOUTIE BIT(2)
+#define SDMMC_MASK_DTIMEOUTIE BIT(3)
+#define SDMMC_MASK_TXUNDERRIE BIT(4)
+#define SDMMC_MASK_RXOVERRIE BIT(5)
+#define SDMMC_MASK_CMDRENDIE BIT(6)
+#define SDMMC_MASK_CMDSENTIE BIT(7)
+#define SDMMC_MASK_DATAENDIE BIT(8)
+#define SDMMC_MASK_DHOLDIE BIT(9)
+#define SDMMC_MASK_DBCKENDIE BIT(10)
+#define SDMMC_MASK_DABORTIE BIT(11)
+#define SDMMC_MASK_TXFIFOHEIE BIT(14)
+#define SDMMC_MASK_RXFIFOHFIE BIT(15)
+#define SDMMC_MASK_RXFIFOFIE BIT(17)
+#define SDMMC_MASK_TXFIFOEIE BIT(18)
+#define SDMMC_MASK_BUSYD0ENDIE BIT(21)
+#define SDMMC_MASK_SDMMCITIE BIT(22)
+#define SDMMC_MASK_ACKFAILIE BIT(23)
+#define SDMMC_MASK_ACKTIMEOUTIE BIT(24)
+#define SDMMC_MASK_VSWENDIE BIT(25)
+#define SDMMC_MASK_CKSTOPIE BIT(26)
+#define SDMMC_MASK_IDMABTCIE BIT(28)
+
+/* SDMMC_IDMACTRL register */
+#define SDMMC_IDMACTRL_IDMAEN BIT(0)
+
+#define SDMMC_CMD_TIMEOUT 0xFFFFFFFF
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static void stm32_sdmmc2_start_data(struct stm32_sdmmc2_priv *priv,
+ struct mmc_data *data,
+ struct stm32_sdmmc2_ctx *ctx)
+{
+ u32 data_ctrl, idmabase0;
+
+ /* Configure the SDMMC DPSM (Data Path State Machine) */
+ data_ctrl = (__ilog2(data->blocksize) <<
+ SDMMC_DCTRL_DBLOCKSIZE_SHIFT) &
+ SDMMC_DCTRL_DBLOCKSIZE;
+
+ if (data->flags & MMC_DATA_READ) {
+ data_ctrl |= SDMMC_DCTRL_DTDIR;
+ idmabase0 = (u32)data->dest;
+ } else {
+ idmabase0 = (u32)data->src;
+ }
+
+ /* Set the SDMMC Data TimeOut value */
+ writel(SDMMC_CMD_TIMEOUT, priv->base + SDMMC_DTIMER);
+
+ /* Set the SDMMC DataLength value */
+ writel(ctx->data_length, priv->base + SDMMC_DLEN);
+
+ /* Write to SDMMC DCTRL */
+ writel(data_ctrl, priv->base + SDMMC_DCTRL);
+
+ /* Cache align */
+ ctx->cache_start = rounddown(idmabase0, ARCH_DMA_MINALIGN);
+ ctx->cache_end = roundup(idmabase0 + ctx->data_length,
+ ARCH_DMA_MINALIGN);
+
+ /*
+ * Flush data cache before DMA start (clean and invalidate)
+ * Clean also needed for read
+ * Avoid issue on buffer not cached-aligned
+ */
+ flush_dcache_range(ctx->cache_start, ctx->cache_end);
+
+ /* Enable internal DMA */
+ writel(idmabase0, priv->base + SDMMC_IDMABASE0);
+ writel(SDMMC_IDMACTRL_IDMAEN, priv->base + SDMMC_IDMACTRL);
+}
+
+static void stm32_sdmmc2_start_cmd(struct stm32_sdmmc2_priv *priv,
+ struct mmc_cmd *cmd, u32 cmd_param)
+{
+ if (readl(priv->base + SDMMC_ARG) & SDMMC_CMD_CPSMEN)
+ writel(0, priv->base + SDMMC_ARG);
+
+ cmd_param |= cmd->cmdidx | SDMMC_CMD_CPSMEN;
+ if (cmd->resp_type & MMC_RSP_PRESENT) {
+ if (cmd->resp_type & MMC_RSP_136)
+ cmd_param |= SDMMC_CMD_WAITRESP;
+ else if (cmd->resp_type & MMC_RSP_CRC)
+ cmd_param |= SDMMC_CMD_WAITRESP_0;
+ else
+ cmd_param |= SDMMC_CMD_WAITRESP_1;
+ }
+
+ /* Clear flags */
+ writel(SDMMC_ICR_STATIC_FLAGS, priv->base + SDMMC_ICR);
+
+ /* Set SDMMC argument value */
+ writel(cmd->cmdarg, priv->base + SDMMC_ARG);
+
+ /* Set SDMMC command parameters */
+ writel(cmd_param, priv->base + SDMMC_CMD);
+}
+
+static int stm32_sdmmc2_end_cmd(struct stm32_sdmmc2_priv *priv,
+ struct mmc_cmd *cmd,
+ struct stm32_sdmmc2_ctx *ctx)
+{
+ u32 mask = SDMMC_STA_CTIMEOUT;
+ u32 status;
+ int ret;
+
+ if (cmd->resp_type & MMC_RSP_PRESENT) {
+ mask |= SDMMC_STA_CMDREND;
+ if (cmd->resp_type & MMC_RSP_CRC)
+ mask |= SDMMC_STA_CCRCFAIL;
+ } else {
+ mask |= SDMMC_STA_CMDSENT;
+ }
+
+ /* Polling status register */
+ ret = readl_poll_timeout(priv->base + SDMMC_STA, status, status & mask,
+ 300);
+
+ if (ret < 0) {
+ debug("%s: timeout reading SDMMC_STA register\n", __func__);
+ ctx->dpsm_abort = true;
+ return ret;
+ }
+
+ /* Check status */
+ if (status & SDMMC_STA_CTIMEOUT) {
+ debug("%s: error SDMMC_STA_CTIMEOUT (0x%x) for cmd %d\n",
+ __func__, status, cmd->cmdidx);
+ ctx->dpsm_abort = true;
+ return -ETIMEDOUT;
+ }
+
+ if (status & SDMMC_STA_CCRCFAIL && cmd->resp_type & MMC_RSP_CRC) {
+ debug("%s: error SDMMC_STA_CCRCFAIL (0x%x) for cmd %d\n",
+ __func__, status, cmd->cmdidx);
+ ctx->dpsm_abort = true;
+ return -EILSEQ;
+ }
+
+ if (status & SDMMC_STA_CMDREND && cmd->resp_type & MMC_RSP_PRESENT) {
+ cmd->response[0] = readl(priv->base + SDMMC_RESP1);
+ if (cmd->resp_type & MMC_RSP_136) {
+ cmd->response[1] = readl(priv->base + SDMMC_RESP2);
+ cmd->response[2] = readl(priv->base + SDMMC_RESP3);
+ cmd->response[3] = readl(priv->base + SDMMC_RESP4);
+ }
+ }
+
+ return 0;
+}
+
+static int stm32_sdmmc2_end_data(struct stm32_sdmmc2_priv *priv,
+ struct mmc_cmd *cmd,
+ struct mmc_data *data,
+ struct stm32_sdmmc2_ctx *ctx)
+{
+ u32 mask = SDMMC_STA_DCRCFAIL | SDMMC_STA_DTIMEOUT |
+ SDMMC_STA_IDMATE | SDMMC_STA_DATAEND;
+ u32 status;
+
+ if (data->flags & MMC_DATA_READ)
+ mask |= SDMMC_STA_RXOVERR;
+ else
+ mask |= SDMMC_STA_TXUNDERR;
+
+ status = readl(priv->base + SDMMC_STA);
+ while (!(status & mask))
+ status = readl(priv->base + SDMMC_STA);
+
+ /*
+ * Need invalidate the dcache again to avoid any
+ * cache-refill during the DMA operations (pre-fetching)
+ */
+ if (data->flags & MMC_DATA_READ)
+ invalidate_dcache_range(ctx->cache_start, ctx->cache_end);
+
+ if (status & SDMMC_STA_DCRCFAIL) {
+ debug("%s: error SDMMC_STA_DCRCFAIL (0x%x) for cmd %d\n",
+ __func__, status, cmd->cmdidx);
+ if (readl(priv->base + SDMMC_DCOUNT))
+ ctx->dpsm_abort = true;
+ return -EILSEQ;
+ }
+
+ if (status & SDMMC_STA_DTIMEOUT) {
+ debug("%s: error SDMMC_STA_DTIMEOUT (0x%x) for cmd %d\n",
+ __func__, status, cmd->cmdidx);
+ ctx->dpsm_abort = true;
+ return -ETIMEDOUT;
+ }
+
+ if (status & SDMMC_STA_TXUNDERR) {
+ debug("%s: error SDMMC_STA_TXUNDERR (0x%x) for cmd %d\n",
+ __func__, status, cmd->cmdidx);
+ ctx->dpsm_abort = true;
+ return -EIO;
+ }
+
+ if (status & SDMMC_STA_RXOVERR) {
+ debug("%s: error SDMMC_STA_RXOVERR (0x%x) for cmd %d\n",
+ __func__, status, cmd->cmdidx);
+ ctx->dpsm_abort = true;
+ return -EIO;
+ }
+
+ if (status & SDMMC_STA_IDMATE) {
+ debug("%s: error SDMMC_STA_IDMATE (0x%x) for cmd %d\n",
+ __func__, status, cmd->cmdidx);
+ ctx->dpsm_abort = true;
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int stm32_sdmmc2_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
+ struct mmc_data *data)
+{
+ struct stm32_sdmmc2_priv *priv = dev_get_priv(dev);
+ struct stm32_sdmmc2_ctx ctx;
+ u32 cmdat = data ? SDMMC_CMD_CMDTRANS : 0;
+ int ret, retry = 3;
+
+retry_cmd:
+ ctx.data_length = 0;
+ ctx.dpsm_abort = false;
+
+ if (data) {
+ ctx.data_length = data->blocks * data->blocksize;
+ stm32_sdmmc2_start_data(priv, data, &ctx);
+ }
+
+ stm32_sdmmc2_start_cmd(priv, cmd, cmdat);
+
+ debug("%s: send cmd %d data: 0x%x @ 0x%x\n",
+ __func__, cmd->cmdidx,
+ data ? ctx.data_length : 0, (unsigned int)data);
+
+ ret = stm32_sdmmc2_end_cmd(priv, cmd, &ctx);
+
+ if (data && !ret)
+ ret = stm32_sdmmc2_end_data(priv, cmd, data, &ctx);
+
+ /* Clear flags */
+ writel(SDMMC_ICR_STATIC_FLAGS, priv->base + SDMMC_ICR);
+ if (data)
+ writel(0x0, priv->base + SDMMC_IDMACTRL);
+
+ /*
+ * To stop Data Path State Machine, a stop_transmission command
+ * shall be send on cmd or data errors.
+ */
+ if (ctx.dpsm_abort && (cmd->cmdidx != MMC_CMD_STOP_TRANSMISSION)) {
+ struct mmc_cmd stop_cmd;
+
+ stop_cmd.cmdidx = MMC_CMD_STOP_TRANSMISSION;
+ stop_cmd.cmdarg = 0;
+ stop_cmd.resp_type = MMC_RSP_R1b;
+
+ debug("%s: send STOP command to abort dpsm treatments\n",
+ __func__);
+
+ stm32_sdmmc2_start_cmd(priv, &stop_cmd, SDMMC_CMD_CMDSTOP);
+ stm32_sdmmc2_end_cmd(priv, &stop_cmd, &ctx);
+
+ writel(SDMMC_ICR_STATIC_FLAGS, priv->base + SDMMC_ICR);
+ }
+
+ if ((ret != -ETIMEDOUT) && (ret != 0) && retry) {
+ printf("%s: cmd %d failed, retrying ...\n",
+ __func__, cmd->cmdidx);
+ retry--;
+ goto retry_cmd;
+ }
+
+ debug("%s: end for CMD %d, ret = %d\n", __func__, cmd->cmdidx, ret);
+
+ return ret;
+}
+
+static void stm32_sdmmc2_pwron(struct stm32_sdmmc2_priv *priv)
+{
+ /* Reset */
+ reset_assert(&priv->reset_ctl);
+ udelay(2);
+ reset_deassert(&priv->reset_ctl);
+
+ udelay(1000);
+
+ /* Set Power State to ON */
+ writel(SDMMC_POWER_PWRCTRL | priv->pwr_reg_msk, priv->base + SDMMC_POWER);
+
+ /*
+ * 1ms: required power up waiting time before starting the
+ * SD initialization sequence
+ */
+ udelay(1000);
+}
+
+#define IS_RISING_EDGE(reg) (reg & SDMMC_CLKCR_NEGEDGE ? 0 : 1)
+static int stm32_sdmmc2_set_ios(struct udevice *dev)
+{
+ struct mmc *mmc = mmc_get_mmc_dev(dev);
+ struct stm32_sdmmc2_priv *priv = dev_get_priv(dev);
+ struct stm32_sdmmc2_plat *plat = dev_get_platdata(dev);
+ struct mmc_config *cfg = &plat->cfg;
+ u32 desired = mmc->clock;
+ u32 sys_clock = clk_get_rate(&priv->clk);
+ u32 clk = 0;
+
+ debug("%s: bus_with = %d, clock = %d\n", __func__,
+ mmc->bus_width, mmc->clock);
+
+ if ((mmc->bus_width == 1) && (desired == cfg->f_min))
+ stm32_sdmmc2_pwron(priv);
+
+ /*
+ * clk_div = 0 => command and data generated on SDMMCCLK falling edge
+ * clk_div > 0 and NEGEDGE = 0 => command and data generated on
+ * SDMMCCLK rising edge
+ * clk_div > 0 and NEGEDGE = 1 => command and data generated on
+ * SDMMCCLK falling edge
+ */
+ if (desired && ((sys_clock > desired) ||
+ IS_RISING_EDGE(priv->clk_reg_msk))) {
+ clk = DIV_ROUND_UP(sys_clock, 2 * desired);
+ if (clk > SDMMC_CLKCR_CLKDIV_MAX)
+ clk = SDMMC_CLKCR_CLKDIV_MAX;
+ }
+
+ if (mmc->bus_width == 4)
+ clk |= SDMMC_CLKCR_WIDBUS_4;
+ if (mmc->bus_width == 8)
+ clk |= SDMMC_CLKCR_WIDBUS_8;
+
+ writel(clk | priv->clk_reg_msk, priv->base + SDMMC_CLKCR);
+
+ return 0;
+}
+
+static int stm32_sdmmc2_getcd(struct udevice *dev)
+{
+ struct stm32_sdmmc2_priv *priv = dev_get_priv(dev);
+
+ debug("stm32_sdmmc2_getcd called\n");
+
+ if (dm_gpio_is_valid(&priv->cd_gpio))
+ return dm_gpio_get_value(&priv->cd_gpio);
+
+ return 1;
+}
+
+static const struct dm_mmc_ops stm32_sdmmc2_ops = {
+ .send_cmd = stm32_sdmmc2_send_cmd,
+ .set_ios = stm32_sdmmc2_set_ios,
+ .get_cd = stm32_sdmmc2_getcd,
+};
+
+static int stm32_sdmmc2_probe(struct udevice *dev)
+{
+ struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
+ struct stm32_sdmmc2_plat *plat = dev_get_platdata(dev);
+ struct stm32_sdmmc2_priv *priv = dev_get_priv(dev);
+ struct mmc_config *cfg = &plat->cfg;
+ int ret;
+
+ priv->base = dev_read_addr(dev);
+ if (priv->base == FDT_ADDR_T_NONE)
+ return -EINVAL;
+
+ if (dev_read_bool(dev, "st,negedge"))
+ priv->clk_reg_msk |= SDMMC_CLKCR_NEGEDGE;
+ if (dev_read_bool(dev, "st,dirpol"))
+ priv->pwr_reg_msk |= SDMMC_POWER_DIRPOL;
+
+ ret = clk_get_by_index(dev, 0, &priv->clk);
+ if (ret)
+ return ret;
+
+ ret = clk_enable(&priv->clk);
+ if (ret)
+ goto clk_free;
+
+ ret = reset_get_by_index(dev, 0, &priv->reset_ctl);
+ if (ret)
+ goto clk_disable;
+
+ gpio_request_by_name(dev, "cd-gpios", 0, &priv->cd_gpio,
+ GPIOD_IS_IN);
+
+ cfg->f_min = 400000;
+ cfg->f_max = dev_read_u32_default(dev, "max-frequency", 52000000);
+ cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;
+ cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
+ cfg->name = "STM32 SDMMC2";
+
+ cfg->host_caps = 0;
+ if (cfg->f_max > 25000000)
+ cfg->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
+
+ switch (dev_read_u32_default(dev, "bus-width", 1)) {
+ case 8:
+ cfg->host_caps |= MMC_MODE_8BIT;
+ case 4:
+ cfg->host_caps |= MMC_MODE_4BIT;
+ break;
+ case 1:
+ break;
+ default:
+ error("invalid \"bus-width\" property, force to 1\n");
+ }
+
+ upriv->mmc = &plat->mmc;
+
+ return 0;
+
+clk_disable:
+ clk_disable(&priv->clk);
+clk_free:
+ clk_free(&priv->clk);
+
+ return ret;
+}
+
+int stm32_sdmmc_bind(struct udevice *dev)
+{
+ struct stm32_sdmmc2_plat *plat = dev_get_platdata(dev);
+
+ return mmc_bind(dev, &plat->mmc, &plat->cfg);
+}
+
+static const struct udevice_id stm32_sdmmc2_ids[] = {
+ { .compatible = "st,stm32-sdmmc2" },
+ { }
+};
+
+U_BOOT_DRIVER(stm32_sdmmc2) = {
+ .name = "stm32_sdmmc2",
+ .id = UCLASS_MMC,
+ .of_match = stm32_sdmmc2_ids,
+ .ops = &stm32_sdmmc2_ops,
+ .probe = stm32_sdmmc2_probe,
+ .bind = stm32_sdmmc_bind,
+ .priv_auto_alloc_size = sizeof(struct stm32_sdmmc2_priv),
+ .platdata_auto_alloc_size = sizeof(struct stm32_sdmmc2_plat),
+};
diff --git a/drivers/mmc/uniphier-sd.c b/drivers/mmc/uniphier-sd.c
index 721b75fdda..0d1203cb76 100644
--- a/drivers/mmc/uniphier-sd.c
+++ b/drivers/mmc/uniphier-sd.c
@@ -14,6 +14,7 @@
#include <linux/dma-direction.h>
#include <linux/io.h>
#include <linux/sizes.h>
+#include <power/regulator.h>
#include <asm/unaligned.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -132,8 +133,43 @@ struct uniphier_sd_priv {
#define UNIPHIER_SD_CAP_NONREMOVABLE BIT(0) /* Nonremovable e.g. eMMC */
#define UNIPHIER_SD_CAP_DMA_INTERNAL BIT(1) /* have internal DMA engine */
#define UNIPHIER_SD_CAP_DIV1024 BIT(2) /* divisor 1024 is available */
+#define UNIPHIER_SD_CAP_64BIT BIT(3) /* Controller is 64bit */
};
+static u64 uniphier_sd_readq(struct uniphier_sd_priv *priv, unsigned int reg)
+{
+ if (priv->caps & UNIPHIER_SD_CAP_64BIT)
+ return readq(priv->regbase + (reg << 1));
+ else
+ return readq(priv->regbase + reg);
+}
+
+static void uniphier_sd_writeq(struct uniphier_sd_priv *priv,
+ u64 val, unsigned int reg)
+{
+ if (priv->caps & UNIPHIER_SD_CAP_64BIT)
+ writeq(val, priv->regbase + (reg << 1));
+ else
+ writeq(val, priv->regbase + reg);
+}
+
+static u32 uniphier_sd_readl(struct uniphier_sd_priv *priv, unsigned int reg)
+{
+ if (priv->caps & UNIPHIER_SD_CAP_64BIT)
+ return readl(priv->regbase + (reg << 1));
+ else
+ return readl(priv->regbase + reg);
+}
+
+static void uniphier_sd_writel(struct uniphier_sd_priv *priv,
+ u32 val, unsigned int reg)
+{
+ if (priv->caps & UNIPHIER_SD_CAP_64BIT)
+ writel(val, priv->regbase + (reg << 1));
+ else
+ writel(val, priv->regbase + reg);
+}
+
static dma_addr_t __dma_map_single(void *ptr, size_t size,
enum dma_data_direction dir)
{
@@ -157,7 +193,7 @@ static void __dma_unmap_single(dma_addr_t addr, size_t size,
static int uniphier_sd_check_error(struct udevice *dev)
{
struct uniphier_sd_priv *priv = dev_get_priv(dev);
- u32 info2 = readl(priv->regbase + UNIPHIER_SD_INFO2);
+ u32 info2 = uniphier_sd_readl(priv, UNIPHIER_SD_INFO2);
if (info2 & UNIPHIER_SD_INFO2_ERR_RTO) {
/*
@@ -195,7 +231,7 @@ static int uniphier_sd_wait_for_irq(struct udevice *dev, unsigned int reg,
long wait = 1000000;
int ret;
- while (!(readl(priv->regbase + reg) & flag)) {
+ while (!(uniphier_sd_readl(priv, reg) & flag)) {
if (wait-- < 0) {
dev_err(dev, "timeout\n");
return -ETIMEDOUT;
@@ -211,7 +247,7 @@ static int uniphier_sd_wait_for_irq(struct udevice *dev, unsigned int reg,
return 0;
}
-static int uniphier_sd_pio_read_one_block(struct udevice *dev, u32 **pbuf,
+static int uniphier_sd_pio_read_one_block(struct udevice *dev, char *pbuf,
uint blocksize)
{
struct uniphier_sd_priv *priv = dev_get_priv(dev);
@@ -227,22 +263,44 @@ static int uniphier_sd_pio_read_one_block(struct udevice *dev, u32 **pbuf,
* Clear the status flag _before_ read the buffer out because
* UNIPHIER_SD_INFO2_BRE is edge-triggered, not level-triggered.
*/
- writel(0, priv->regbase + UNIPHIER_SD_INFO2);
-
- if (likely(IS_ALIGNED((unsigned long)*pbuf, 4))) {
- for (i = 0; i < blocksize / 4; i++)
- *(*pbuf)++ = readl(priv->regbase + UNIPHIER_SD_BUF);
+ uniphier_sd_writel(priv, 0, UNIPHIER_SD_INFO2);
+
+ if (priv->caps & UNIPHIER_SD_CAP_64BIT) {
+ u64 *buf = (u64 *)pbuf;
+ if (likely(IS_ALIGNED((uintptr_t)buf, 8))) {
+ for (i = 0; i < blocksize / 8; i++) {
+ *buf++ = uniphier_sd_readq(priv,
+ UNIPHIER_SD_BUF);
+ }
+ } else {
+ for (i = 0; i < blocksize / 8; i++) {
+ u64 data;
+ data = uniphier_sd_readq(priv,
+ UNIPHIER_SD_BUF);
+ put_unaligned(data, buf++);
+ }
+ }
} else {
- for (i = 0; i < blocksize / 4; i++)
- put_unaligned(readl(priv->regbase + UNIPHIER_SD_BUF),
- (*pbuf)++);
+ u32 *buf = (u32 *)pbuf;
+ if (likely(IS_ALIGNED((uintptr_t)buf, 4))) {
+ for (i = 0; i < blocksize / 4; i++) {
+ *buf++ = uniphier_sd_readl(priv,
+ UNIPHIER_SD_BUF);
+ }
+ } else {
+ for (i = 0; i < blocksize / 4; i++) {
+ u32 data;
+ data = uniphier_sd_readl(priv, UNIPHIER_SD_BUF);
+ put_unaligned(data, buf++);
+ }
+ }
}
return 0;
}
static int uniphier_sd_pio_write_one_block(struct udevice *dev,
- const u32 **pbuf, uint blocksize)
+ const char *pbuf, uint blocksize)
{
struct uniphier_sd_priv *priv = dev_get_priv(dev);
int i, ret;
@@ -253,15 +311,36 @@ static int uniphier_sd_pio_write_one_block(struct udevice *dev,
if (ret)
return ret;
- writel(0, priv->regbase + UNIPHIER_SD_INFO2);
-
- if (likely(IS_ALIGNED((unsigned long)*pbuf, 4))) {
- for (i = 0; i < blocksize / 4; i++)
- writel(*(*pbuf)++, priv->regbase + UNIPHIER_SD_BUF);
+ uniphier_sd_writel(priv, 0, UNIPHIER_SD_INFO2);
+
+ if (priv->caps & UNIPHIER_SD_CAP_64BIT) {
+ const u64 *buf = (const u64 *)pbuf;
+ if (likely(IS_ALIGNED((uintptr_t)buf, 8))) {
+ for (i = 0; i < blocksize / 8; i++) {
+ uniphier_sd_writeq(priv, *buf++,
+ UNIPHIER_SD_BUF);
+ }
+ } else {
+ for (i = 0; i < blocksize / 8; i++) {
+ u64 data = get_unaligned(buf++);
+ uniphier_sd_writeq(priv, data,
+ UNIPHIER_SD_BUF);
+ }
+ }
} else {
- for (i = 0; i < blocksize / 4; i++)
- writel(get_unaligned((*pbuf)++),
- priv->regbase + UNIPHIER_SD_BUF);
+ const u32 *buf = (const u32 *)pbuf;
+ if (likely(IS_ALIGNED((uintptr_t)buf, 4))) {
+ for (i = 0; i < blocksize / 4; i++) {
+ uniphier_sd_writel(priv, *buf++,
+ UNIPHIER_SD_BUF);
+ }
+ } else {
+ for (i = 0; i < blocksize / 4; i++) {
+ u32 data = get_unaligned(buf++);
+ uniphier_sd_writel(priv, data,
+ UNIPHIER_SD_BUF);
+ }
+ }
}
return 0;
@@ -269,19 +348,24 @@ static int uniphier_sd_pio_write_one_block(struct udevice *dev,
static int uniphier_sd_pio_xfer(struct udevice *dev, struct mmc_data *data)
{
- u32 *dest = (u32 *)data->dest;
- const u32 *src = (const u32 *)data->src;
+ const char *src = data->src;
+ char *dest = data->dest;
int i, ret;
for (i = 0; i < data->blocks; i++) {
if (data->flags & MMC_DATA_READ)
- ret = uniphier_sd_pio_read_one_block(dev, &dest,
+ ret = uniphier_sd_pio_read_one_block(dev, dest,
data->blocksize);
else
- ret = uniphier_sd_pio_write_one_block(dev, &src,
+ ret = uniphier_sd_pio_write_one_block(dev, src,
data->blocksize);
if (ret)
return ret;
+
+ if (data->flags & MMC_DATA_READ)
+ dest += data->blocksize;
+ else
+ src += data->blocksize;
}
return 0;
@@ -292,22 +376,22 @@ static void uniphier_sd_dma_start(struct uniphier_sd_priv *priv,
{
u32 tmp;
- writel(0, priv->regbase + UNIPHIER_SD_DMA_INFO1);
- writel(0, priv->regbase + UNIPHIER_SD_DMA_INFO2);
+ uniphier_sd_writel(priv, 0, UNIPHIER_SD_DMA_INFO1);
+ uniphier_sd_writel(priv, 0, UNIPHIER_SD_DMA_INFO2);
/* enable DMA */
- tmp = readl(priv->regbase + UNIPHIER_SD_EXTMODE);
+ tmp = uniphier_sd_readl(priv, UNIPHIER_SD_EXTMODE);
tmp |= UNIPHIER_SD_EXTMODE_DMA_EN;
- writel(tmp, priv->regbase + UNIPHIER_SD_EXTMODE);
+ uniphier_sd_writel(priv, tmp, UNIPHIER_SD_EXTMODE);
- writel(dma_addr & U32_MAX, priv->regbase + UNIPHIER_SD_DMA_ADDR_L);
+ uniphier_sd_writel(priv, dma_addr & U32_MAX, UNIPHIER_SD_DMA_ADDR_L);
/* suppress the warning "right shift count >= width of type" */
dma_addr >>= min_t(int, 32, 8 * sizeof(dma_addr));
- writel(dma_addr & U32_MAX, priv->regbase + UNIPHIER_SD_DMA_ADDR_H);
+ uniphier_sd_writel(priv, dma_addr & U32_MAX, UNIPHIER_SD_DMA_ADDR_H);
- writel(UNIPHIER_SD_DMA_CTL_START, priv->regbase + UNIPHIER_SD_DMA_CTL);
+ uniphier_sd_writel(priv, UNIPHIER_SD_DMA_CTL_START, UNIPHIER_SD_DMA_CTL);
}
static int uniphier_sd_dma_wait_for_irq(struct udevice *dev, u32 flag,
@@ -316,7 +400,7 @@ static int uniphier_sd_dma_wait_for_irq(struct udevice *dev, u32 flag,
struct uniphier_sd_priv *priv = dev_get_priv(dev);
long wait = 1000000 + 10 * blocks;
- while (!(readl(priv->regbase + UNIPHIER_SD_DMA_INFO1) & flag)) {
+ while (!(uniphier_sd_readl(priv, UNIPHIER_SD_DMA_INFO1) & flag)) {
if (wait-- < 0) {
dev_err(dev, "timeout during DMA\n");
return -ETIMEDOUT;
@@ -325,7 +409,7 @@ static int uniphier_sd_dma_wait_for_irq(struct udevice *dev, u32 flag,
udelay(10);
}
- if (readl(priv->regbase + UNIPHIER_SD_DMA_INFO2)) {
+ if (uniphier_sd_readl(priv, UNIPHIER_SD_DMA_INFO2)) {
dev_err(dev, "error during DMA\n");
return -EIO;
}
@@ -343,7 +427,7 @@ static int uniphier_sd_dma_xfer(struct udevice *dev, struct mmc_data *data)
u32 poll_flag, tmp;
int ret;
- tmp = readl(priv->regbase + UNIPHIER_SD_DMA_MODE);
+ tmp = uniphier_sd_readl(priv, UNIPHIER_SD_DMA_MODE);
if (data->flags & MMC_DATA_READ) {
buf = data->dest;
@@ -357,7 +441,7 @@ static int uniphier_sd_dma_xfer(struct udevice *dev, struct mmc_data *data)
tmp &= ~UNIPHIER_SD_DMA_MODE_DIR_RD;
}
- writel(tmp, priv->regbase + UNIPHIER_SD_DMA_MODE);
+ uniphier_sd_writel(priv, tmp, UNIPHIER_SD_DMA_MODE);
dma_addr = __dma_map_single(buf, len, dir);
@@ -396,27 +480,27 @@ static int uniphier_sd_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
int ret;
u32 tmp;
- if (readl(priv->regbase + UNIPHIER_SD_INFO2) & UNIPHIER_SD_INFO2_CBSY) {
+ if (uniphier_sd_readl(priv, UNIPHIER_SD_INFO2) & UNIPHIER_SD_INFO2_CBSY) {
dev_err(dev, "command busy\n");
return -EBUSY;
}
/* clear all status flags */
- writel(0, priv->regbase + UNIPHIER_SD_INFO1);
- writel(0, priv->regbase + UNIPHIER_SD_INFO2);
+ uniphier_sd_writel(priv, 0, UNIPHIER_SD_INFO1);
+ uniphier_sd_writel(priv, 0, UNIPHIER_SD_INFO2);
/* disable DMA once */
- tmp = readl(priv->regbase + UNIPHIER_SD_EXTMODE);
+ tmp = uniphier_sd_readl(priv, UNIPHIER_SD_EXTMODE);
tmp &= ~UNIPHIER_SD_EXTMODE_DMA_EN;
- writel(tmp, priv->regbase + UNIPHIER_SD_EXTMODE);
+ uniphier_sd_writel(priv, tmp, UNIPHIER_SD_EXTMODE);
- writel(cmd->cmdarg, priv->regbase + UNIPHIER_SD_ARG);
+ uniphier_sd_writel(priv, cmd->cmdarg, UNIPHIER_SD_ARG);
tmp = cmd->cmdidx;
if (data) {
- writel(data->blocksize, priv->regbase + UNIPHIER_SD_SIZE);
- writel(data->blocks, priv->regbase + UNIPHIER_SD_SECCNT);
+ uniphier_sd_writel(priv, data->blocksize, UNIPHIER_SD_SIZE);
+ uniphier_sd_writel(priv, data->blocks, UNIPHIER_SD_SECCNT);
/* Do not send CMD12 automatically */
tmp |= UNIPHIER_SD_CMD_NOSTOP | UNIPHIER_SD_CMD_DATA;
@@ -457,7 +541,7 @@ static int uniphier_sd_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
dev_dbg(dev, "sending CMD%d (SD_CMD=%08x, SD_ARG=%08x)\n",
cmd->cmdidx, tmp, cmd->cmdarg);
- writel(tmp, priv->regbase + UNIPHIER_SD_CMD);
+ uniphier_sd_writel(priv, tmp, UNIPHIER_SD_CMD);
ret = uniphier_sd_wait_for_irq(dev, UNIPHIER_SD_INFO1,
UNIPHIER_SD_INFO1_RSP);
@@ -465,10 +549,10 @@ static int uniphier_sd_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
return ret;
if (cmd->resp_type & MMC_RSP_136) {
- u32 rsp_127_104 = readl(priv->regbase + UNIPHIER_SD_RSP76);
- u32 rsp_103_72 = readl(priv->regbase + UNIPHIER_SD_RSP54);
- u32 rsp_71_40 = readl(priv->regbase + UNIPHIER_SD_RSP32);
- u32 rsp_39_8 = readl(priv->regbase + UNIPHIER_SD_RSP10);
+ u32 rsp_127_104 = uniphier_sd_readl(priv, UNIPHIER_SD_RSP76);
+ u32 rsp_103_72 = uniphier_sd_readl(priv, UNIPHIER_SD_RSP54);
+ u32 rsp_71_40 = uniphier_sd_readl(priv, UNIPHIER_SD_RSP32);
+ u32 rsp_39_8 = uniphier_sd_readl(priv, UNIPHIER_SD_RSP10);
cmd->response[0] = ((rsp_127_104 & 0x00ffffff) << 8) |
((rsp_103_72 & 0xff000000) >> 24);
@@ -479,7 +563,7 @@ static int uniphier_sd_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
cmd->response[3] = (rsp_39_8 & 0xffffff) << 8;
} else {
/* bit 39-8 */
- cmd->response[0] = readl(priv->regbase + UNIPHIER_SD_RSP10);
+ cmd->response[0] = uniphier_sd_readl(priv, UNIPHIER_SD_RSP10);
}
if (data) {
@@ -518,10 +602,10 @@ static int uniphier_sd_set_bus_width(struct uniphier_sd_priv *priv,
return -EINVAL;
}
- tmp = readl(priv->regbase + UNIPHIER_SD_OPTION);
+ tmp = uniphier_sd_readl(priv, UNIPHIER_SD_OPTION);
tmp &= ~UNIPHIER_SD_OPTION_WIDTH_MASK;
tmp |= val;
- writel(tmp, priv->regbase + UNIPHIER_SD_OPTION);
+ uniphier_sd_writel(priv, tmp, UNIPHIER_SD_OPTION);
return 0;
}
@@ -531,12 +615,12 @@ static void uniphier_sd_set_ddr_mode(struct uniphier_sd_priv *priv,
{
u32 tmp;
- tmp = readl(priv->regbase + UNIPHIER_SD_IF_MODE);
+ tmp = uniphier_sd_readl(priv, UNIPHIER_SD_IF_MODE);
if (mmc->ddr_mode)
tmp |= UNIPHIER_SD_IF_MODE_DDR;
else
tmp &= ~UNIPHIER_SD_IF_MODE_DDR;
- writel(tmp, priv->regbase + UNIPHIER_SD_IF_MODE);
+ uniphier_sd_writel(priv, tmp, UNIPHIER_SD_IF_MODE);
}
static void uniphier_sd_set_clk_rate(struct uniphier_sd_priv *priv,
@@ -573,21 +657,21 @@ static void uniphier_sd_set_clk_rate(struct uniphier_sd_priv *priv,
else
val = UNIPHIER_SD_CLKCTL_DIV1024;
- tmp = readl(priv->regbase + UNIPHIER_SD_CLKCTL);
+ tmp = uniphier_sd_readl(priv, UNIPHIER_SD_CLKCTL);
if (tmp & UNIPHIER_SD_CLKCTL_SCLKEN &&
(tmp & UNIPHIER_SD_CLKCTL_DIV_MASK) == val)
return;
/* stop the clock before changing its rate to avoid a glitch signal */
tmp &= ~UNIPHIER_SD_CLKCTL_SCLKEN;
- writel(tmp, priv->regbase + UNIPHIER_SD_CLKCTL);
+ uniphier_sd_writel(priv, tmp, UNIPHIER_SD_CLKCTL);
tmp &= ~UNIPHIER_SD_CLKCTL_DIV_MASK;
tmp |= val | UNIPHIER_SD_CLKCTL_OFFEN;
- writel(tmp, priv->regbase + UNIPHIER_SD_CLKCTL);
+ uniphier_sd_writel(priv, tmp, UNIPHIER_SD_CLKCTL);
tmp |= UNIPHIER_SD_CLKCTL_SCLKEN;
- writel(tmp, priv->regbase + UNIPHIER_SD_CLKCTL);
+ uniphier_sd_writel(priv, tmp, UNIPHIER_SD_CLKCTL);
udelay(1000);
}
@@ -617,7 +701,7 @@ static int uniphier_sd_get_cd(struct udevice *dev)
if (priv->caps & UNIPHIER_SD_CAP_NONREMOVABLE)
return 1;
- return !!(readl(priv->regbase + UNIPHIER_SD_INFO1) &
+ return !!(uniphier_sd_readl(priv, UNIPHIER_SD_INFO1) &
UNIPHIER_SD_INFO1_CD);
}
@@ -632,28 +716,28 @@ static void uniphier_sd_host_init(struct uniphier_sd_priv *priv)
u32 tmp;
/* soft reset of the host */
- tmp = readl(priv->regbase + UNIPHIER_SD_SOFT_RST);
+ tmp = uniphier_sd_readl(priv, UNIPHIER_SD_SOFT_RST);
tmp &= ~UNIPHIER_SD_SOFT_RST_RSTX;
- writel(tmp, priv->regbase + UNIPHIER_SD_SOFT_RST);
+ uniphier_sd_writel(priv, tmp, UNIPHIER_SD_SOFT_RST);
tmp |= UNIPHIER_SD_SOFT_RST_RSTX;
- writel(tmp, priv->regbase + UNIPHIER_SD_SOFT_RST);
+ uniphier_sd_writel(priv, tmp, UNIPHIER_SD_SOFT_RST);
/* FIXME: implement eMMC hw_reset */
- writel(UNIPHIER_SD_STOP_SEC, priv->regbase + UNIPHIER_SD_STOP);
+ uniphier_sd_writel(priv, UNIPHIER_SD_STOP_SEC, UNIPHIER_SD_STOP);
/*
* Connected to 32bit AXI.
* This register dropped backward compatibility at version 0x10.
* Write an appropriate value depending on the IP version.
*/
- writel(priv->version >= 0x10 ? 0x00000101 : 0x00000000,
- priv->regbase + UNIPHIER_SD_HOST_MODE);
+ uniphier_sd_writel(priv, priv->version >= 0x10 ? 0x00000101 : 0x00000000,
+ UNIPHIER_SD_HOST_MODE);
if (priv->caps & UNIPHIER_SD_CAP_DMA_INTERNAL) {
- tmp = readl(priv->regbase + UNIPHIER_SD_DMA_MODE);
+ tmp = uniphier_sd_readl(priv, UNIPHIER_SD_DMA_MODE);
tmp |= UNIPHIER_SD_DMA_MODE_ADDR_INC;
- writel(tmp, priv->regbase + UNIPHIER_SD_DMA_MODE);
+ uniphier_sd_writel(priv, tmp, UNIPHIER_SD_DMA_MODE);
}
}
@@ -669,9 +753,13 @@ static int uniphier_sd_probe(struct udevice *dev)
struct uniphier_sd_plat *plat = dev_get_platdata(dev);
struct uniphier_sd_priv *priv = dev_get_priv(dev);
struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
+ const u32 quirks = dev_get_driver_data(dev);
fdt_addr_t base;
struct clk clk;
int ret;
+#ifdef CONFIG_DM_REGULATOR
+ struct udevice *vqmmc_dev;
+#endif
base = devfdt_get_addr(dev);
if (base == FDT_ADDR_T_NONE)
@@ -681,6 +769,15 @@ static int uniphier_sd_probe(struct udevice *dev)
if (!priv->regbase)
return -ENOMEM;
+#ifdef CONFIG_DM_REGULATOR
+ ret = device_get_supply_regulator(dev, "vqmmc-supply", &vqmmc_dev);
+ if (!ret) {
+ /* Set the regulator to 3.3V until we support 1.8V modes */
+ regulator_set_value(vqmmc_dev, 3300000);
+ regulator_set_enable(vqmmc_dev, true);
+ }
+#endif
+
ret = clk_get_by_index(dev, 0, &clk);
if (ret < 0) {
dev_err(dev, "failed to get host clock\n");
@@ -720,18 +817,22 @@ static int uniphier_sd_probe(struct udevice *dev)
return -EINVAL;
}
+ if (quirks) {
+ priv->caps = quirks;
+ } else {
+ priv->version = uniphier_sd_readl(priv, UNIPHIER_SD_VERSION) &
+ UNIPHIER_SD_VERSION_IP;
+ dev_dbg(dev, "version %x\n", priv->version);
+ if (priv->version >= 0x10) {
+ priv->caps |= UNIPHIER_SD_CAP_DMA_INTERNAL;
+ priv->caps |= UNIPHIER_SD_CAP_DIV1024;
+ }
+ }
+
if (fdt_get_property(gd->fdt_blob, dev_of_offset(dev), "non-removable",
NULL))
priv->caps |= UNIPHIER_SD_CAP_NONREMOVABLE;
- priv->version = readl(priv->regbase + UNIPHIER_SD_VERSION) &
- UNIPHIER_SD_VERSION_IP;
- dev_dbg(dev, "version %x\n", priv->version);
- if (priv->version >= 0x10) {
- priv->caps |= UNIPHIER_SD_CAP_DMA_INTERNAL;
- priv->caps |= UNIPHIER_SD_CAP_DIV1024;
- }
-
uniphier_sd_host_init(priv);
plat->cfg.voltages = MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34;
@@ -746,7 +847,9 @@ static int uniphier_sd_probe(struct udevice *dev)
}
static const struct udevice_id uniphier_sd_match[] = {
- { .compatible = "socionext,uniphier-sdhc" },
+ { .compatible = "renesas,sdhi-r8a7795", .data = UNIPHIER_SD_CAP_64BIT },
+ { .compatible = "renesas,sdhi-r8a7796", .data = UNIPHIER_SD_CAP_64BIT },
+ { .compatible = "socionext,uniphier-sdhc", .data = 0 },
{ /* sentinel */ }
};
diff --git a/drivers/mtd/cfi_flash.c b/drivers/mtd/cfi_flash.c
index f3bb72788a..8a5babea7b 100644
--- a/drivers/mtd/cfi_flash.c
+++ b/drivers/mtd/cfi_flash.c
@@ -111,11 +111,9 @@ static void cfi_flash_init_dm(void)
}
}
-static phys_addr_t cfi_flash_base[CFI_MAX_FLASH_BANKS];
-
phys_addr_t cfi_flash_bank_addr(int i)
{
- return cfi_flash_base[i];
+ return flash_info[i].base;
}
#else
__weak phys_addr_t cfi_flash_bank_addr(int i)
@@ -546,7 +544,16 @@ static int flash_is_busy (flash_info_t * info, flash_sect_t sect)
#ifdef CONFIG_FLASH_CFI_LEGACY
case CFI_CMDSET_AMD_LEGACY:
#endif
- retval = flash_toggle (info, sect, 0, AMD_STATUS_TOGGLE);
+ if (info->sr_supported) {
+ flash_write_cmd (info, sect, info->addr_unlock1,
+ FLASH_CMD_READ_STATUS);
+ retval = !flash_isset (info, sect, 0,
+ FLASH_STATUS_DONE);
+ } else {
+ retval = flash_toggle (info, sect, 0,
+ AMD_STATUS_TOGGLE);
+ }
+
break;
default:
retval = 0;
@@ -1687,6 +1694,7 @@ static void cmdset_amd_read_jedec_ids(flash_info_t *info)
{
ushort bankId = 0;
uchar manuId;
+ uchar lsbits;
flash_write_cmd(info, 0, 0, AMD_CMD_RESET);
flash_unlock_seq(info, 0);
@@ -1702,6 +1710,9 @@ static void cmdset_amd_read_jedec_ids(flash_info_t *info)
}
info->manufacturer_id = manuId;
+ lsbits = flash_read_uchar(info, FLASH_OFFSET_LOWER_SW_BITS);
+ info->sr_supported = lsbits & BIT(0);
+
switch (info->chipwidth){
case FLASH_CFI_8BIT:
info->device_id = flash_read_uchar (info,
@@ -2458,10 +2469,12 @@ static int cfi_flash_probe(struct udevice *dev)
while (idx < len) {
addr = fdt_translate_address((void *)blob,
node, cell + idx);
- cfi_flash_base[cfi_flash_num_flash_banks++] = addr;
+ flash_info[cfi_flash_num_flash_banks].dev = dev;
+ flash_info[cfi_flash_num_flash_banks].base = addr;
+ cfi_flash_num_flash_banks++;
idx += addrc + sizec;
}
- gd->bd->bi_flashstart = cfi_flash_base[0];
+ gd->bd->bi_flashstart = flash_info[0].base;
return 0;
}
diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c
index 47cf37d1d9..54718f418c 100644
--- a/drivers/mtd/nand/denali.c
+++ b/drivers/mtd/nand/denali.c
@@ -10,7 +10,7 @@
#include <malloc.h>
#include <nand.h>
#include <linux/errno.h>
-#include <asm/io.h>
+#include <linux/io.h>
#include "denali.h"
@@ -433,17 +433,13 @@ static void find_valid_banks(struct denali_nand_info *denali)
*/
static void detect_max_banks(struct denali_nand_info *denali)
{
- uint32_t features = readl(denali->flash_reg + FEATURES);
- /*
- * Read the revision register, so we can calculate the max_banks
- * properly: the encoding changed from rev 5.0 to 5.1
- */
- u32 revision = MAKE_COMPARABLE_REVISION(
- readl(denali->flash_reg + REVISION));
- if (revision < REVISION_5_1)
- denali->max_banks = 2 << (features & FEATURES__N_BANKS);
- else
- denali->max_banks = 1 << (features & FEATURES__N_BANKS);
+ uint32_t features = ioread32(denali->flash_reg + FEATURES);
+
+ denali->max_banks = 1 << (features & FEATURES__N_BANKS);
+
+ /* the encoding changed from rev 5.0 to 5.1 */
+ if (denali->revision < 0x0501)
+ denali->max_banks <<= 1;
}
static void detect_partition_feature(struct denali_nand_info *denali)
@@ -1154,6 +1150,13 @@ static void denali_cmdfunc(struct mtd_info *mtd, unsigned int cmd, int col,
static void denali_hw_init(struct denali_nand_info *denali)
{
/*
+ * The REVISION register may not be reliable. Platforms are allowed to
+ * override it.
+ */
+ if (!denali->revision)
+ denali->revision = swab16(ioread32(denali->flash_reg + REVISION));
+
+ /*
* tell driver how many bit controller will skip before writing
* ECC code in OOB. This is normally used for bad block marker
*/
diff --git a/drivers/mtd/nand/denali.h b/drivers/mtd/nand/denali.h
index 694bce53a9..08db48843d 100644
--- a/drivers/mtd/nand/denali.h
+++ b/drivers/mtd/nand/denali.h
@@ -166,8 +166,6 @@
#define REVISION 0x370
#define REVISION__VALUE 0xffff
-#define MAKE_COMPARABLE_REVISION(x) swab16((x) & REVISION__VALUE)
-#define REVISION_5_1 0x00000501
#define ONFI_DEVICE_FEATURES 0x380
#define ONFI_DEVICE_FEATURES__VALUE 0x003f
@@ -462,8 +460,13 @@ struct denali_nand_info {
uint32_t blksperchip;
uint32_t bbtskipbytes;
uint32_t max_banks;
+ unsigned int revision;
+ unsigned int caps;
};
+#define DENALI_CAP_HW_ECC_FIXUP BIT(0)
+#define DENALI_CAP_DMA_64BIT BIT(1)
+
int denali_init(struct denali_nand_info *denali);
#endif /* __DENALI_H__ */
diff --git a/drivers/mtd/nand/denali_dt.c b/drivers/mtd/nand/denali_dt.c
index 0a6155c748..4afd679a04 100644
--- a/drivers/mtd/nand/denali_dt.c
+++ b/drivers/mtd/nand/denali_dt.c
@@ -12,15 +12,38 @@
#include "denali.h"
+struct denali_dt_data {
+ unsigned int revision;
+ unsigned int caps;
+};
+
+static const struct denali_dt_data denali_socfpga_data = {
+ .caps = DENALI_CAP_HW_ECC_FIXUP,
+};
+
+static const struct denali_dt_data denali_uniphier_v5a_data = {
+ .caps = DENALI_CAP_HW_ECC_FIXUP |
+ DENALI_CAP_DMA_64BIT,
+};
+
+static const struct denali_dt_data denali_uniphier_v5b_data = {
+ .revision = 0x0501,
+ .caps = DENALI_CAP_HW_ECC_FIXUP |
+ DENALI_CAP_DMA_64BIT,
+};
+
static const struct udevice_id denali_nand_dt_ids[] = {
{
.compatible = "altr,socfpga-denali-nand",
+ .data = (unsigned long)&denali_socfpga_data,
},
{
.compatible = "socionext,uniphier-denali-nand-v5a",
+ .data = (unsigned long)&denali_uniphier_v5a_data,
},
{
.compatible = "socionext,uniphier-denali-nand-v5b",
+ .data = (unsigned long)&denali_uniphier_v5b_data,
},
{ /* sentinel */ }
};
@@ -28,9 +51,16 @@ static const struct udevice_id denali_nand_dt_ids[] = {
static int denali_dt_probe(struct udevice *dev)
{
struct denali_nand_info *denali = dev_get_priv(dev);
+ const struct denali_dt_data *data;
struct resource res;
int ret;
+ data = (void *)dev_get_driver_data(dev);
+ if (data) {
+ denali->revision = data->revision;
+ denali->caps = data->caps;
+ }
+
ret = dev_read_resource_byname(dev, "denali_reg", &res);
if (ret)
return ret;
diff --git a/drivers/mtd/spi/spi_flash_ids.c b/drivers/mtd/spi/spi_flash_ids.c
index c4ccf48af4..13f64e773f 100644
--- a/drivers/mtd/spi/spi_flash_ids.c
+++ b/drivers/mtd/spi/spi_flash_ids.c
@@ -83,6 +83,7 @@ const struct spi_flash_info spi_flash_ids[] = {
{"mx25l51235f", INFO(0xc2201a, 0x0, 64 * 1024, 1024, RD_FULL | WR_QPP) },
{"mx25u6435f", INFO(0xc22537, 0x0, 64 * 1024, 128, RD_FULL | WR_QPP) },
{"mx25l12855e", INFO(0xc22618, 0x0, 64 * 1024, 256, RD_FULL | WR_QPP) },
+ {"mx25u1635e", INFO(0xc22535, 0x0, 64 * 1024, 32, SECT_4K) },
{"mx66u51235f", INFO(0xc2253a, 0x0, 64 * 1024, 1024, RD_FULL | WR_QPP) },
{"mx66l1g45g", INFO(0xc2201b, 0x0, 64 * 1024, 2048, RD_FULL | WR_QPP) },
#endif
@@ -91,7 +92,7 @@ const struct spi_flash_info spi_flash_ids[] = {
{"s25fl016a", INFO(0x010214, 0x0, 64 * 1024, 32, 0) },
{"s25fl032a", INFO(0x010215, 0x0, 64 * 1024, 64, 0) },
{"s25fl064a", INFO(0x010216, 0x0, 64 * 1024, 128, 0) },
- {"s25fl116k", INFO(0x014015, 0x0, 64 * 1024, 128, 0) },
+ {"s25fl116k", INFO(0x014015, 0x0, 64 * 1024, 32, 0) },
{"s25fl164k", INFO(0x014017, 0x0140, 64 * 1024, 128, 0) },
{"s25fl128p_256k", INFO(0x012018, 0x0300, 256 * 1024, 64, RD_FULL | WR_QPP) },
{"s25fl128p_64k", INFO(0x012018, 0x0301, 64 * 1024, 256, RD_FULL | WR_QPP) },
@@ -100,8 +101,8 @@ const struct spi_flash_info spi_flash_ids[] = {
{"s25fl128s_256k", INFO(0x012018, 0x4d00, 256 * 1024, 64, RD_FULL | WR_QPP) },
{"s25fl128s_64k", INFO(0x012018, 0x4d01, 64 * 1024, 256, RD_FULL | WR_QPP) },
{"s25fl256s_256k", INFO(0x010219, 0x4d00, 256 * 1024, 128, RD_FULL | WR_QPP) },
- {"s25fl256s_64k", INFO(0x010219, 0x4d01, 64 * 1024, 512, RD_FULL | WR_QPP) },
{"s25fs256s_64k", INFO6(0x010219, 0x4d0181, 64 * 1024, 512, RD_FULL | WR_QPP | SECT_4K) },
+ {"s25fl256s_64k", INFO(0x010219, 0x4d01, 64 * 1024, 512, RD_FULL | WR_QPP) },
{"s25fs512s", INFO6(0x010220, 0x4d0081, 128 * 1024, 512, RD_FULL | WR_QPP | SECT_4K) },
{"s25fl512s_256k", INFO(0x010220, 0x4d00, 256 * 1024, 256, RD_FULL | WR_QPP) },
{"s25fl512s_64k", INFO(0x010220, 0x4d01, 64 * 1024, 1024, RD_FULL | WR_QPP) },
@@ -134,6 +135,7 @@ const struct spi_flash_info spi_flash_ids[] = {
{"n25q1024a", INFO(0x20bb21, 0x0, 64 * 1024, 2048, RD_FULL | WR_QPP | E_FSR | SECT_4K) },
{"mt25qu02g", INFO(0x20bb22, 0x0, 64 * 1024, 4096, RD_FULL | WR_QPP | E_FSR | SECT_4K) },
{"mt25ql02g", INFO(0x20ba22, 0x0, 64 * 1024, 4096, RD_FULL | WR_QPP | E_FSR | SECT_4K) },
+ {"mt35xu512g", INFO6(0x2c5b1a, 0x104100, 128 * 1024, 512, E_FSR | SECT_4K) },
#endif
#ifdef CONFIG_SPI_FLASH_SST /* SST */
{"sst25vf040b", INFO(0xbf258d, 0x0, 64 * 1024, 8, SECT_4K | SST_WR) },
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 5ceea44c60..d67927cd3b 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -159,6 +159,14 @@ config FTMAC100
help
This MAC is present in Andestech SoCs.
+config MVNETA
+ bool "Marvell Armada 385 network interface support"
+ depends on ARMADA_XP || ARMADA_38X
+ select PHYLIB
+ help
+ This driver supports the network interface units in the
+ Marvell ARMADA XP and 38X SoCs
+
config MVPP2
bool "Marvell Armada 375/7K/8K network interface support"
depends on ARMADA_375 || ARMADA_8K
diff --git a/drivers/net/designware.c b/drivers/net/designware.c
index 521e4dde41..036d231071 100644
--- a/drivers/net/designware.c
+++ b/drivers/net/designware.c
@@ -737,16 +737,14 @@ int designware_eth_ofdata_to_platdata(struct udevice *dev)
#endif
struct eth_pdata *pdata = &dw_pdata->eth_pdata;
const char *phy_mode;
- const fdt32_t *cell;
#ifdef CONFIG_DM_GPIO
int reset_flags = GPIOD_IS_OUT;
#endif
int ret = 0;
- pdata->iobase = devfdt_get_addr(dev);
+ pdata->iobase = dev_read_addr(dev);
pdata->phy_interface = -1;
- phy_mode = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "phy-mode",
- NULL);
+ phy_mode = dev_read_string(dev, "phy-mode");
if (phy_mode)
pdata->phy_interface = phy_get_interface_by_name(phy_mode);
if (pdata->phy_interface == -1) {
@@ -754,10 +752,7 @@ int designware_eth_ofdata_to_platdata(struct udevice *dev)
return -EINVAL;
}
- pdata->max_speed = 0;
- cell = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "max-speed", NULL);
- if (cell)
- pdata->max_speed = fdt32_to_cpu(*cell);
+ pdata->max_speed = dev_read_u32_default(dev, "max-speed", 0);
#ifdef CONFIG_DM_GPIO
if (dev_read_bool(dev, "snps,reset-active-low"))
diff --git a/drivers/net/ftmac100.c b/drivers/net/ftmac100.c
index f231e6b33b..e64bf3d651 100644
--- a/drivers/net/ftmac100.c
+++ b/drivers/net/ftmac100.c
@@ -40,7 +40,12 @@ static void ftmac100_reset(struct ftmac100_data *priv)
writel (FTMAC100_MACCR_SW_RST, &ftmac100->maccr);
while (readl (&ftmac100->maccr) & FTMAC100_MACCR_SW_RST)
- ;
+ mdelay(1);
+ /*
+ * When soft reset complete, write mac address immediately maybe fail somehow
+ * Wait for a while can avoid this problem
+ */
+ mdelay(1);
}
/*
@@ -79,7 +84,6 @@ static int _ftmac100_init(struct ftmac100_data *priv, unsigned char enetaddr[6])
struct ftmac100_rxdes *rxdes = priv->rxdes;
unsigned int maccr;
int i;
-
debug ("%s()\n", __func__);
ftmac100_reset(priv);
@@ -156,7 +160,6 @@ static int __ftmac100_recv(struct ftmac100_data *priv)
unsigned short rxlen;
curr_des = &priv->rxdes[priv->rx_index];
-
if (curr_des->rxdes0 & FTMAC100_RXDES0_RXDMA_OWN)
return 0;
@@ -169,7 +172,7 @@ static int __ftmac100_recv(struct ftmac100_data *priv)
}
rxlen = FTMAC100_RXDES0_RFL (curr_des->rxdes0);
-
+ invalidate_dcache_range(curr_des->rxdes2,curr_des->rxdes2+rxlen);
debug ("%s(): RX buffer %d, %x received\n",
__func__, priv->rx_index, rxlen);
@@ -196,6 +199,7 @@ static int _ftmac100_send(struct ftmac100_data *priv, void *packet, int length)
/* initiate a transmit sequence */
+ flush_dcache_range((u32)packet,(u32)packet+length);
curr_des->txdes2 = (unsigned int)packet; /* TXBUF_BADR */
curr_des->txdes1 &= FTMAC100_TXDES1_EDOTR;
diff --git a/drivers/net/phy/micrel_ksz90x1.c b/drivers/net/phy/micrel_ksz90x1.c
index 0bb99e6bc6..b350a61aa6 100644
--- a/drivers/net/phy/micrel_ksz90x1.c
+++ b/drivers/net/phy/micrel_ksz90x1.c
@@ -9,11 +9,11 @@
* (C) Copyright 2017 Adaptrum, Inc.
* Written by Alexandru Gagniuc <alex.g@adaptrum.com> for Adaptrum, Inc.
*/
+
#include <config.h>
#include <common.h>
#include <dm.h>
#include <errno.h>
-#include <fdtdec.h>
#include <micrel.h>
#include <phy.h>
@@ -120,8 +120,7 @@ static int ksz90x1_of_config_group(struct phy_device *phydev,
return -EOPNOTSUPP;
for (i = 0; i < ofcfg->grpsz; i++) {
- val[i] = fdtdec_get_uint(gd->fdt_blob, dev_of_offset(dev),
- ofcfg->grp[i].name, -1);
+ val[i] = dev_read_u32_default(dev, ofcfg->grp[i].name, ~0);
offset = ofcfg->grp[i].off;
if (val[i] == -1) {
/* Default register value for KSZ9021 */
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
index e2a1c0a409..8af2470268 100644
--- a/drivers/pci/Kconfig
+++ b/drivers/pci/Kconfig
@@ -35,7 +35,6 @@ config PCI_PNP
config PCIE_DW_MVEBU
bool "Enable Armada-8K PCIe driver (DesignWare core)"
- default n
depends on DM_PCI
depends on ARMADA_8K
help
diff --git a/drivers/pci/pci_tegra.c b/drivers/pci/pci_tegra.c
index cb5cf8b043..7d920d423d 100644
--- a/drivers/pci/pci_tegra.c
+++ b/drivers/pci/pci_tegra.c
@@ -218,8 +218,6 @@ struct tegra_pcie_soc {
};
struct tegra_pcie {
- struct pci_controller hose;
-
struct resource pads;
struct resource afi;
struct resource cs;
diff --git a/drivers/pci/pcie_layerscape.h b/drivers/pci/pcie_layerscape.h
index 782e3ab7ad..3a6cecb07d 100644
--- a/drivers/pci/pcie_layerscape.h
+++ b/drivers/pci/pcie_layerscape.h
@@ -145,7 +145,6 @@ struct ls_pcie {
bool big_endian;
bool enabled;
int next_lut_index;
- struct pci_controller hose;
};
extern struct list_head ls_pcie_list;
diff --git a/drivers/pci/pcie_layerscape_fixup.c b/drivers/pci/pcie_layerscape_fixup.c
index 9e6c2f5dfc..3dae20103d 100644
--- a/drivers/pci/pcie_layerscape_fixup.c
+++ b/drivers/pci/pcie_layerscape_fixup.c
@@ -130,19 +130,28 @@ static void fdt_pcie_set_iommu_map_entry(void *blob, struct ls_pcie *pcie,
u32 iommu_map[4];
int nodeoffset;
int lenp;
+ uint svr;
+ char *compat = NULL;
/* find pci controller node */
nodeoffset = fdt_node_offset_by_compat_reg(blob, "fsl,ls-pcie",
pcie->dbi_res.start);
if (nodeoffset < 0) {
#ifdef CONFIG_FSL_PCIE_COMPAT /* Compatible with older version of dts node */
- nodeoffset = fdt_node_offset_by_compat_reg(blob,
- CONFIG_FSL_PCIE_COMPAT, pcie->dbi_res.start);
+ svr = (get_svr() >> SVR_VAR_PER_SHIFT) & 0xFFFFFE;
+ if (svr == SVR_LS2088A || svr == SVR_LS2084A ||
+ svr == SVR_LS2048A || svr == SVR_LS2044A ||
+ svr == SVR_LS2081A || svr == SVR_LS2041A)
+ compat = "fsl,ls2088a-pcie";
+ else
+ compat = CONFIG_FSL_PCIE_COMPAT;
+
+ if (compat)
+ nodeoffset = fdt_node_offset_by_compat_reg(blob,
+ compat, pcie->dbi_res.start);
+#endif
if (nodeoffset < 0)
return;
-#else
- return;
-#endif
}
/* get phandle to iommu controller */
diff --git a/drivers/pci/pcie_xilinx.c b/drivers/pci/pcie_xilinx.c
index 08e2e93445..4ba32df516 100644
--- a/drivers/pci/pcie_xilinx.c
+++ b/drivers/pci/pcie_xilinx.c
@@ -14,11 +14,9 @@
/**
* struct xilinx_pcie - Xilinx PCIe controller state
- * @hose: The parent classes PCI controller state
* @cfg_base: The base address of memory mapped configuration space
*/
struct xilinx_pcie {
- struct pci_controller hose;
void *cfg_base;
};
@@ -87,7 +85,7 @@ static int pcie_xilinx_config_address(struct xilinx_pcie *pcie, pci_dev_t bdf,
/**
* pcie_xilinx_read_config() - Read from configuration space
- * @pcie: Pointer to the PCI controller state
+ * @bus: Pointer to the PCI bus
* @bdf: Identifies the PCIe device to access
* @offset: The offset into the device's configuration space
* @valuep: A pointer at which to store the read value
@@ -130,7 +128,7 @@ static int pcie_xilinx_read_config(struct udevice *bus, pci_dev_t bdf,
/**
* pcie_xilinx_write_config() - Write to configuration space
- * @pcie: Pointer to the PCI controller state
+ * @bus: Pointer to the PCI bus
* @bdf: Identifies the PCIe device to access
* @offset: The offset into the device's configuration space
* @value: The value to write
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index 98f2a1b047..3b9a09ce18 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -77,4 +77,12 @@ config SPL_PIPE3_PHY
This PHY is found on omap devices supporting SATA such as dra7, am57x
and omap5
+config STI_USB_PHY
+ bool "STMicroelectronics USB2 picoPHY driver for STiH407 family"
+ depends on PHY && ARCH_STI
+ help
+ This is the generic phy driver for the picoPHY ports
+ used by USB2 and USB3 Host controllers available on
+ STiH407 SoC families.
+
endmenu
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
index ab56c46bb4..668040b0bb 100644
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
@@ -9,3 +9,4 @@ obj-$(CONFIG_$(SPL_)PHY) += phy-uclass.o
obj-$(CONFIG_$(SPL_)NOP_PHY) += nop-phy.o
obj-$(CONFIG_PHY_SANDBOX) += sandbox-phy.o
obj-$(CONFIG_$(SPL_)PIPE3_PHY) += ti-pipe3-phy.o
+obj-$(CONFIG_STI_USB_PHY) += sti_usb_phy.o
diff --git a/drivers/phy/sti_usb_phy.c b/drivers/phy/sti_usb_phy.c
new file mode 100644
index 0000000000..0e0b1c02d2
--- /dev/null
+++ b/drivers/phy/sti_usb_phy.c
@@ -0,0 +1,181 @@
+/*
+ * Copyright (c) 2017
+ * Patrice Chotard <patrice.chotard@st.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <bitfield.h>
+#include <dm.h>
+#include <errno.h>
+#include <fdtdec.h>
+#include <generic-phy.h>
+#include <libfdt.h>
+#include <regmap.h>
+#include <reset-uclass.h>
+#include <syscon.h>
+#include <wait_bit.h>
+
+#include <linux/bitops.h>
+#include <linux/compat.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* Default PHY_SEL and REFCLKSEL configuration */
+#define STIH407_USB_PICOPHY_CTRL_PORT_CONF 0x6
+
+/* ports parameters overriding */
+#define STIH407_USB_PICOPHY_PARAM_DEF 0x39a4dc
+
+#define PHYPARAM_REG 1
+#define PHYCTRL_REG 2
+#define PHYPARAM_NB 3
+
+struct sti_usb_phy {
+ struct regmap *regmap;
+ struct reset_ctl global_ctl;
+ struct reset_ctl port_ctl;
+ int param;
+ int ctrl;
+};
+
+static int sti_usb_phy_deassert(struct sti_usb_phy *phy)
+{
+ int ret;
+
+ ret = reset_deassert(&phy->global_ctl);
+ if (ret < 0) {
+ error("PHY global deassert failed: %d", ret);
+ return ret;
+ }
+
+ ret = reset_deassert(&phy->port_ctl);
+ if (ret < 0)
+ error("PHY port deassert failed: %d", ret);
+
+ return ret;
+}
+
+static int sti_usb_phy_init(struct phy *usb_phy)
+{
+ struct udevice *dev = usb_phy->dev;
+ struct sti_usb_phy *phy = dev_get_priv(dev);
+ void __iomem *reg;
+
+ /* set ctrl picophy value */
+ reg = (void __iomem *)phy->regmap->base + phy->ctrl;
+ /* CTRL_PORT mask is 0x1f */
+ clrsetbits_le32(reg, 0x1f, STIH407_USB_PICOPHY_CTRL_PORT_CONF);
+
+ /* set ports parameters overriding */
+ reg = (void __iomem *)phy->regmap->base + phy->param;
+ /* PARAM_DEF mask is 0xffffffff */
+ clrsetbits_le32(reg, 0xffffffff, STIH407_USB_PICOPHY_PARAM_DEF);
+
+ return sti_usb_phy_deassert(phy);
+}
+
+static int sti_usb_phy_exit(struct phy *usb_phy)
+{
+ struct udevice *dev = usb_phy->dev;
+ struct sti_usb_phy *phy = dev_get_priv(dev);
+ int ret;
+
+ ret = reset_assert(&phy->port_ctl);
+ if (ret < 0) {
+ error("PHY port assert failed: %d", ret);
+ return ret;
+ }
+
+ ret = reset_assert(&phy->global_ctl);
+ if (ret < 0)
+ error("PHY global assert failed: %d", ret);
+
+ return ret;
+}
+
+struct phy_ops sti_usb_phy_ops = {
+ .init = sti_usb_phy_init,
+ .exit = sti_usb_phy_exit,
+};
+
+int sti_usb_phy_probe(struct udevice *dev)
+{
+ struct sti_usb_phy *priv = dev_get_priv(dev);
+ struct udevice *syscon;
+ struct ofnode_phandle_args syscfg_phandle;
+ u32 cells[PHYPARAM_NB];
+ int ret, count;
+
+ /* get corresponding syscon phandle */
+ ret = dev_read_phandle_with_args(dev, "st,syscfg", NULL, 0, 0,
+ &syscfg_phandle);
+
+ if (ret < 0) {
+ error("Can't get syscfg phandle: %d\n", ret);
+ return ret;
+ }
+
+ ret = uclass_get_device_by_ofnode(UCLASS_SYSCON, syscfg_phandle.node,
+ &syscon);
+ if (ret) {
+ error("unable to find syscon device (%d)\n", ret);
+ return ret;
+ }
+
+ priv->regmap = syscon_get_regmap(syscon);
+ if (!priv->regmap) {
+ error("unable to find regmap\n");
+ return -ENODEV;
+ }
+
+ /* get phy param offset */
+ count = fdtdec_get_int_array_count(gd->fdt_blob, dev_of_offset(dev),
+ "st,syscfg", cells,
+ ARRAY_SIZE(cells));
+
+ if (count < 0) {
+ error("Bad PHY st,syscfg property %d\n", count);
+ return -EINVAL;
+ }
+
+ if (count > PHYPARAM_NB) {
+ error("Unsupported PHY param count %d\n", count);
+ return -EINVAL;
+ }
+
+ priv->param = cells[PHYPARAM_REG];
+ priv->ctrl = cells[PHYCTRL_REG];
+
+ /* get global reset control */
+ ret = reset_get_by_name(dev, "global", &priv->global_ctl);
+ if (ret) {
+ error("can't get global reset for %s (%d)", dev->name, ret);
+ return ret;
+ }
+
+ /* get port reset control */
+ ret = reset_get_by_name(dev, "port", &priv->port_ctl);
+ if (ret) {
+ error("can't get port reset for %s (%d)", dev->name, ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static const struct udevice_id sti_usb_phy_ids[] = {
+ { .compatible = "st,stih407-usb2-phy" },
+ { }
+};
+
+U_BOOT_DRIVER(sti_usb_phy) = {
+ .name = "sti_usb_phy",
+ .id = UCLASS_PHY,
+ .of_match = sti_usb_phy_ids,
+ .probe = sti_usb_phy_probe,
+ .ops = &sti_usb_phy_ops,
+ .priv_auto_alloc_size = sizeof(struct sti_usb_phy),
+};
diff --git a/drivers/pinctrl/pinctrl_stm32.c b/drivers/pinctrl/pinctrl_stm32.c
index fb2593c690..bf2a86c636 100644
--- a/drivers/pinctrl/pinctrl_stm32.c
+++ b/drivers/pinctrl/pinctrl_stm32.c
@@ -183,6 +183,7 @@ static struct pinctrl_ops stm32_pinctrl_ops = {
static const struct udevice_id stm32_pinctrl_ids[] = {
{ .compatible = "st,stm32f746-pinctrl" },
+ { .compatible = "st,stm32h743-pinctrl" },
{ }
};
diff --git a/drivers/pinctrl/rockchip/pinctrl_rk3368.c b/drivers/pinctrl/rockchip/pinctrl_rk3368.c
index 81ce2e31a7..b1f5704164 100644
--- a/drivers/pinctrl/rockchip/pinctrl_rk3368.c
+++ b/drivers/pinctrl/rockchip/pinctrl_rk3368.c
@@ -632,8 +632,7 @@ static int rk3368_pinctrl_get_periph_id(struct udevice *dev,
u32 cell[3];
int ret;
- ret = fdtdec_get_int_array(gd->fdt_blob, dev_of_offset(periph),
- "interrupts", cell, ARRAY_SIZE(cell));
+ ret = dev_read_u32_array(periph, "interrupts", cell, ARRAY_SIZE(cell));
if (ret < 0)
return -EINVAL;
diff --git a/drivers/power/pmic/rk8xx.c b/drivers/power/pmic/rk8xx.c
index eb3ec0f601..735046dc43 100644
--- a/drivers/power/pmic/rk8xx.c
+++ b/drivers/power/pmic/rk8xx.c
@@ -8,8 +8,6 @@
#include <common.h>
#include <dm.h>
#include <errno.h>
-#include <fdtdec.h>
-#include <libfdt.h>
#include <power/rk8xx_pmic.h>
#include <power/pmic.h>
diff --git a/drivers/power/regulator/Kconfig b/drivers/power/regulator/Kconfig
index c82a936e8a..2cfade1cb2 100644
--- a/drivers/power/regulator/Kconfig
+++ b/drivers/power/regulator/Kconfig
@@ -151,6 +151,19 @@ config DM_REGULATOR_PALMAS
features for REGULATOR PALMAS and the family of PALMAS PMICs.
The driver implements get/set api for: value and enable.
+config DM_REGULATOR_PBIAS
+ bool "Enable driver for PBIAS regulator"
+ depends on DM_REGULATOR
+ select REGMAP
+ select SYSCON
+ ---help---
+ This enables implementation of driver-model regulator uclass
+ features for pseudo-regulator PBIAS found in the OMAP SOCs.
+ This pseudo-regulator is used to provide a BIAS voltage to MMC1
+ signal pads and must be configured properly during a voltage switch.
+ Voltage switching is required by some operating modes of SDcards and
+ eMMC.
+
config DM_REGULATOR_LP873X
bool "Enable driver for LP873X PMIC regulators"
depends on PMIC_LP873X
diff --git a/drivers/power/regulator/Makefile b/drivers/power/regulator/Makefile
index 18fb870e43..6c149a9263 100644
--- a/drivers/power/regulator/Makefile
+++ b/drivers/power/regulator/Makefile
@@ -18,5 +18,6 @@ obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o
obj-$(CONFIG_DM_REGULATOR_SANDBOX) += sandbox.o
obj-$(CONFIG_REGULATOR_TPS65090) += tps65090_regulator.o
obj-$(CONFIG_$(SPL_)DM_REGULATOR_PALMAS) += palmas_regulator.o
+obj-$(CONFIG_$(SPL_)DM_REGULATOR_PBIAS) += pbias_regulator.o
obj-$(CONFIG_$(SPL_)DM_REGULATOR_LP873X) += lp873x_regulator.o
obj-$(CONFIG_$(SPL_)DM_REGULATOR_LP87565) += lp87565_regulator.o
diff --git a/drivers/power/regulator/pbias_regulator.c b/drivers/power/regulator/pbias_regulator.c
new file mode 100644
index 0000000000..914500b729
--- /dev/null
+++ b/drivers/power/regulator/pbias_regulator.c
@@ -0,0 +1,301 @@
+/*
+ * (C) Copyright 2016 Texas Instruments Incorporated, <www.ti.com>
+ * Jean-Jacques Hiblot <jjhiblot@ti.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <dm.h>
+#include <power/pmic.h>
+#include <power/regulator.h>
+#include <regmap.h>
+#include <syscon.h>
+#include <linux/bitops.h>
+#include <linux/ioport.h>
+#include <dm/read.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct pbias_reg_info {
+ u32 enable;
+ u32 enable_mask;
+ u32 disable_val;
+ u32 vmode;
+ unsigned int enable_time;
+ char *name;
+};
+
+struct pbias_priv {
+ struct regmap *regmap;
+ int offset;
+};
+
+static const struct pmic_child_info pmic_children_info[] = {
+ { .prefix = "pbias", .driver = "pbias_regulator"},
+ { },
+};
+
+static int pbias_write(struct udevice *dev, uint reg, const uint8_t *buff,
+ int len)
+{
+ struct pbias_priv *priv = dev_get_priv(dev);
+ u32 val = *(u32 *)buff;
+
+ if (len != 4)
+ return -EINVAL;
+
+ return regmap_write(priv->regmap, priv->offset, val);
+}
+
+static int pbias_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
+{
+ struct pbias_priv *priv = dev_get_priv(dev);
+
+ if (len != 4)
+ return -EINVAL;
+
+ return regmap_read(priv->regmap, priv->offset, (u32 *)buff);
+}
+
+static int pbias_ofdata_to_platdata(struct udevice *dev)
+{
+ struct pbias_priv *priv = dev_get_priv(dev);
+ struct udevice *syscon;
+ struct regmap *regmap;
+ struct resource res;
+ int err;
+
+ err = uclass_get_device_by_phandle(UCLASS_SYSCON, dev,
+ "syscon", &syscon);
+ if (err) {
+ error("%s: unable to find syscon device (%d)\n", __func__,
+ err);
+ return err;
+ }
+
+ regmap = syscon_get_regmap(syscon);
+ if (IS_ERR(regmap)) {
+ error("%s: unable to find regmap (%ld)\n", __func__,
+ PTR_ERR(regmap));
+ return PTR_ERR(regmap);
+ }
+ priv->regmap = regmap;
+
+ err = dev_read_resource(dev, 0, &res);
+ if (err) {
+ error("%s: unable to find offset (%d)\n", __func__, err);
+ return err;
+ }
+ priv->offset = res.start;
+
+ return 0;
+}
+
+static int pbias_bind(struct udevice *dev)
+{
+ int children;
+
+ children = pmic_bind_children(dev, dev->node, pmic_children_info);
+ if (!children)
+ debug("%s: %s - no child found\n", __func__, dev->name);
+
+ return 0;
+}
+
+static struct dm_pmic_ops pbias_ops = {
+ .read = pbias_read,
+ .write = pbias_write,
+};
+
+static const struct udevice_id pbias_ids[] = {
+ { .compatible = "ti,pbias-dra7" },
+ { }
+};
+
+U_BOOT_DRIVER(pbias_pmic) = {
+ .name = "pbias_pmic",
+ .id = UCLASS_PMIC,
+ .of_match = pbias_ids,
+ .bind = pbias_bind,
+ .ops = &pbias_ops,
+ .ofdata_to_platdata = pbias_ofdata_to_platdata,
+ .priv_auto_alloc_size = sizeof(struct pbias_priv),
+};
+
+static const struct pbias_reg_info pbias_mmc_omap2430 = {
+ .enable = BIT(1),
+ .enable_mask = BIT(1),
+ .vmode = BIT(0),
+ .disable_val = 0,
+ .enable_time = 100,
+ .name = "pbias_mmc_omap2430"
+};
+
+static const struct pbias_reg_info pbias_sim_omap3 = {
+ .enable = BIT(9),
+ .enable_mask = BIT(9),
+ .vmode = BIT(8),
+ .enable_time = 100,
+ .name = "pbias_sim_omap3"
+};
+
+static const struct pbias_reg_info pbias_mmc_omap4 = {
+ .enable = BIT(26) | BIT(22),
+ .enable_mask = BIT(26) | BIT(25) | BIT(22),
+ .disable_val = BIT(25),
+ .vmode = BIT(21),
+ .enable_time = 100,
+ .name = "pbias_mmc_omap4"
+};
+
+static const struct pbias_reg_info pbias_mmc_omap5 = {
+ .enable = BIT(27) | BIT(26),
+ .enable_mask = BIT(27) | BIT(25) | BIT(26),
+ .disable_val = BIT(25),
+ .vmode = BIT(21),
+ .enable_time = 100,
+ .name = "pbias_mmc_omap5"
+};
+
+static const struct pbias_reg_info *pbias_reg_infos[] = {
+ &pbias_mmc_omap5,
+ &pbias_mmc_omap4,
+ &pbias_sim_omap3,
+ &pbias_mmc_omap2430,
+ NULL
+};
+
+static int pbias_regulator_probe(struct udevice *dev)
+{
+ const struct pbias_reg_info **p = pbias_reg_infos;
+ struct dm_regulator_uclass_platdata *uc_pdata;
+
+ uc_pdata = dev_get_uclass_platdata(dev);
+
+ while (*p) {
+ int rc;
+
+ rc = dev_read_stringlist_search(dev, "regulator-name",
+ (*p)->name);
+ if (rc >= 0) {
+ debug("found regulator %s\n", (*p)->name);
+ break;
+ } else if (rc != -ENODATA) {
+ return rc;
+ }
+ p++;
+ }
+ if (!*p) {
+ int i = 0;
+ const char *s;
+
+ debug("regulator ");
+ while (dev_read_string_index(dev, "regulator-name", i++, &s) >= 0)
+ debug("%s'%s' ", (i > 1) ? ", " : "", s);
+ debug("%s not supported\n", (i > 2) ? "are" : "is");
+ return -EINVAL;
+ }
+
+ uc_pdata->type = REGULATOR_TYPE_OTHER;
+ dev->priv = (void *)*p;
+
+ return 0;
+}
+
+static int pbias_regulator_get_value(struct udevice *dev)
+{
+ const struct pbias_reg_info *p = dev_get_priv(dev);
+ int rc;
+ u32 reg;
+
+ rc = pmic_read(dev->parent, 0, (uint8_t *)&reg, sizeof(reg));
+ if (rc)
+ return rc;
+
+ debug("%s voltage id %s\n", p->name,
+ (reg & p->vmode) ? "3.0v" : "1.8v");
+ return (reg & p->vmode) ? 3000000 : 1800000;
+}
+
+static int pbias_regulator_set_value(struct udevice *dev, int uV)
+{
+ const struct pbias_reg_info *p = dev_get_priv(dev);
+ int rc;
+ u32 reg;
+
+ debug("Setting %s voltage to %s\n", p->name,
+ (reg & p->vmode) ? "3.0v" : "1.8v");
+
+ rc = pmic_read(dev->parent, 0, (uint8_t *)&reg, sizeof(reg));
+ if (rc)
+ return rc;
+
+ if (uV == 3000000)
+ reg |= p->vmode;
+ else if (uV == 1800000)
+ reg &= ~p->vmode;
+ else
+ return -EINVAL;
+
+ return pmic_write(dev->parent, 0, (uint8_t *)&reg, sizeof(reg));
+}
+
+static int pbias_regulator_get_enable(struct udevice *dev)
+{
+ const struct pbias_reg_info *p = dev_get_priv(dev);
+ int rc;
+ u32 reg;
+
+ rc = pmic_read(dev->parent, 0, (uint8_t *)&reg, sizeof(reg));
+ if (rc)
+ return rc;
+
+ debug("%s id %s\n", p->name,
+ (reg & p->enable_mask) == (p->disable_val) ? "on" : "off");
+
+ return (reg & p->enable_mask) == (p->disable_val);
+}
+
+static int pbias_regulator_set_enable(struct udevice *dev, bool enable)
+{
+ const struct pbias_reg_info *p = dev_get_priv(dev);
+ int rc;
+ u32 reg;
+
+ debug("Turning %s %s\n", enable ? "on" : "off", p->name);
+
+ rc = pmic_read(dev->parent, 0, (uint8_t *)&reg, sizeof(reg));
+ if (rc)
+ return rc;
+
+ reg &= ~p->enable_mask;
+ if (enable)
+ reg |= p->enable;
+ else
+ reg |= p->disable_val;
+
+ rc = pmic_write(dev->parent, 0, (uint8_t *)&reg, sizeof(reg));
+ if (rc)
+ return rc;
+
+ if (enable)
+ udelay(p->enable_time);
+
+ return 0;
+}
+
+static const struct dm_regulator_ops pbias_regulator_ops = {
+ .get_value = pbias_regulator_get_value,
+ .set_value = pbias_regulator_set_value,
+ .get_enable = pbias_regulator_get_enable,
+ .set_enable = pbias_regulator_set_enable,
+};
+
+U_BOOT_DRIVER(pbias_regulator) = {
+ .name = "pbias_regulator",
+ .id = UCLASS_REGULATOR,
+ .ops = &pbias_regulator_ops,
+ .probe = pbias_regulator_probe,
+};
diff --git a/drivers/ram/rockchip/dmc-rk3368.c b/drivers/ram/rockchip/dmc-rk3368.c
index ca7b1ff0c8..7577ff0363 100644
--- a/drivers/ram/rockchip/dmc-rk3368.c
+++ b/drivers/ram/rockchip/dmc-rk3368.c
@@ -893,18 +893,11 @@ static int conv_of_platdata(struct udevice *dev)
{
struct rk3368_sdram_params *plat = dev_get_platdata(dev);
struct dtd_rockchip_rk3368_dmc *of_plat = &plat->of_plat;
- int ret;
plat->ddr_freq = of_plat->rockchip_ddr_frequency;
plat->ddr_speed_bin = of_plat->rockchip_ddr_speed_bin;
plat->memory_schedule = of_plat->rockchip_memory_schedule;
- ret = regmap_init_mem_platdata(dev, of_plat->reg,
- ARRAY_SIZE(of_plat->reg) / 2,
- &plat->map);
- if (ret)
- return ret;
-
return 0;
}
#endif
@@ -933,8 +926,8 @@ static int rk3368_dmc_probe(struct udevice *dev)
debug("%s: pmugrf=%p\n", __func__, priv->pmugrf);
#ifdef CONFIG_TPL_BUILD
- pctl = regmap_get_range(plat->map, 0);
- ddrphy = regmap_get_range(plat->map, 1);
+ pctl = (struct rk3368_ddr_pctl *)plat->of_plat.reg[0];
+ ddrphy = (struct rk3368_ddrphy *)plat->of_plat.reg[2];
msch = syscon_get_first_range(ROCKCHIP_SYSCON_MSCH);
grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
index e6af7da8fe..ce46e2752c 100644
--- a/drivers/reset/Kconfig
+++ b/drivers/reset/Kconfig
@@ -28,6 +28,13 @@ config STI_RESET
Say Y if you want to control reset signals provided by system config
block.
+config STM32_RESET
+ bool "Enable the STM32 reset"
+ depends on STM32
+ help
+ Support for reset controllers on STMicroelectronics STM32 family SoCs.
+ This resset driver is compatible with STM32 F4/F7 and H7 SoCs.
+
config TEGRA_CAR_RESET
bool "Enable Tegra CAR-based reset driver"
depends on TEGRA_CAR
diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
index d5e06c2241..252cefeed5 100644
--- a/drivers/reset/Makefile
+++ b/drivers/reset/Makefile
@@ -6,6 +6,7 @@ obj-$(CONFIG_DM_RESET) += reset-uclass.o
obj-$(CONFIG_SANDBOX_MBOX) += sandbox-reset.o
obj-$(CONFIG_SANDBOX_MBOX) += sandbox-reset-test.o
obj-$(CONFIG_STI_RESET) += sti-reset.o
+obj-$(CONFIG_STM32_RESET) += stm32-reset.o
obj-$(CONFIG_TEGRA_CAR_RESET) += tegra-car-reset.o
obj-$(CONFIG_TEGRA186_RESET) += tegra186-reset.o
obj-$(CONFIG_RESET_BCM6345) += reset-bcm6345.o
diff --git a/drivers/reset/stm32-reset.c b/drivers/reset/stm32-reset.c
new file mode 100644
index 0000000000..9c627d879f
--- /dev/null
+++ b/drivers/reset/stm32-reset.c
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) STMicroelectronics SA 2017
+ * Author(s): Patrice CHOTARD, <patrice.chotard@st.com> for STMicroelectronics.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <reset-uclass.h>
+#include <asm/io.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct stm32_reset_priv {
+ fdt_addr_t base;
+};
+
+static int stm32_reset_request(struct reset_ctl *reset_ctl)
+{
+ return 0;
+}
+
+static int stm32_reset_free(struct reset_ctl *reset_ctl)
+{
+ return 0;
+}
+
+static int stm32_reset_assert(struct reset_ctl *reset_ctl)
+{
+ struct stm32_reset_priv *priv = dev_get_priv(reset_ctl->dev);
+ int bank = (reset_ctl->id / BITS_PER_LONG) * 4;
+ int offset = reset_ctl->id % BITS_PER_LONG;
+ debug("%s: reset id = %ld bank = %d offset = %d)\n", __func__,
+ reset_ctl->id, bank, offset);
+
+ setbits_le32(priv->base + bank, BIT(offset));
+
+ return 0;
+}
+
+static int stm32_reset_deassert(struct reset_ctl *reset_ctl)
+{
+ struct stm32_reset_priv *priv = dev_get_priv(reset_ctl->dev);
+ int bank = (reset_ctl->id / BITS_PER_LONG) * 4;
+ int offset = reset_ctl->id % BITS_PER_LONG;
+ debug("%s: reset id = %ld bank = %d offset = %d)\n", __func__,
+ reset_ctl->id, bank, offset);
+
+ clrbits_le32(priv->base + bank, BIT(offset));
+
+ return 0;
+}
+
+static const struct reset_ops stm32_reset_ops = {
+ .request = stm32_reset_request,
+ .free = stm32_reset_free,
+ .rst_assert = stm32_reset_assert,
+ .rst_deassert = stm32_reset_deassert,
+};
+
+static int stm32_reset_probe(struct udevice *dev)
+{
+ struct stm32_reset_priv *priv = dev_get_priv(dev);
+
+ priv->base = devfdt_get_addr(dev);
+ if (priv->base == FDT_ADDR_T_NONE)
+ return -EINVAL;
+
+ return 0;
+}
+
+U_BOOT_DRIVER(stm32_rcc_reset) = {
+ .name = "stm32_rcc_reset",
+ .id = UCLASS_RESET,
+ .probe = stm32_reset_probe,
+ .priv_auto_alloc_size = sizeof(struct stm32_reset_priv),
+ .ops = &stm32_reset_ops,
+};
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 13b2550d3b..9bf2e26e9d 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -531,10 +531,11 @@ config STI_ASC_SERIAL
config STM32X7_SERIAL
bool "STMicroelectronics STM32 SoCs on-chip UART"
- depends on DM_SERIAL && STM32F7
+ depends on DM_SERIAL && (STM32F7 || STM32H7)
help
- If you have a machine based on a STM32 F7 you can enable its
- onboard serial ports, say Y to this option. If unsure, say N.
+ If you have a machine based on a STM32 F7 or H7 SoC you can
+ enable its onboard serial ports, say Y to this option.
+ If unsure, say N.
config MPC8XX_CONS
bool "Console driver for MPC8XX"
diff --git a/drivers/serial/serial_stm32x7.c b/drivers/serial/serial_stm32x7.c
index bf118a78cf..2f4eafa885 100644
--- a/drivers/serial/serial_stm32x7.c
+++ b/drivers/serial/serial_stm32x7.c
@@ -112,6 +112,8 @@ static int stm32_serial_probe(struct udevice *dev)
static const struct udevice_id stm32_serial_id[] = {
{.compatible = "st,stm32f7-usart"},
{.compatible = "st,stm32f7-uart"},
+ {.compatible = "st,stm32h7-usart"},
+ {.compatible = "st,stm32h7-uart"},
{}
};
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 3c5582a950..88da9a4c8e 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -210,6 +210,13 @@ config FSL_QSPI
used to access the SPI NOR flash on platforms embedding this
Freescale IP core.
+config NDS_AE3XX_SPI
+ bool "Andestech AE3XX SPI driver"
+ help
+ Enable the Andestech AE3XX SPI driver. This driver can be
+ used to access the SPI flash on platforms embedding this
+ Andestech IP core.
+
config TI_QSPI
bool "TI QSPI driver"
help
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 9f8b86de76..cd7c7556a7 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -35,6 +35,7 @@ obj-$(CONFIG_MPC8XXX_SPI) += mpc8xxx_spi.o
obj-$(CONFIG_MVEBU_A3700_SPI) += mvebu_a3700_spi.o
obj-$(CONFIG_MXC_SPI) += mxc_spi.o
obj-$(CONFIG_MXS_SPI) += mxs_spi.o
+obj-$(CONFIG_NDS_AE3XX_SPI) += nds_ae3xx_spi.o
obj-$(CONFIG_OMAP3_SPI) += omap3_spi.o
obj-$(CONFIG_PIC32_SPI) += pic32_spi.o
obj-$(CONFIG_ROCKCHIP_SPI) += rk_spi.o
diff --git a/drivers/spi/davinci_spi.c b/drivers/spi/davinci_spi.c
index 291ef9576a..eda252d0b3 100644
--- a/drivers/spi/davinci_spi.c
+++ b/drivers/spi/davinci_spi.c
@@ -563,6 +563,7 @@ static const struct dm_spi_ops davinci_spi_ops = {
static const struct udevice_id davinci_spi_ids[] = {
{ .compatible = "ti,keystone-spi" },
{ .compatible = "ti,dm6441-spi" },
+ { .compatible = "ti,da830-spi" },
{ }
};
diff --git a/drivers/spi/fsl_qspi.c b/drivers/spi/fsl_qspi.c
index 1dfa89afc9..0f3f7d97f0 100644
--- a/drivers/spi/fsl_qspi.c
+++ b/drivers/spi/fsl_qspi.c
@@ -14,6 +14,7 @@
#include <dm.h>
#include <errno.h>
#include <watchdog.h>
+#include <wait_bit.h>
#include "fsl_qspi.h"
DECLARE_GLOBAL_DATA_PTR;
@@ -663,22 +664,20 @@ static void qspi_op_write(struct fsl_qspi_priv *priv, u8 *txbuf, u32 len)
tx_size = (len > TX_BUFFER_SIZE) ?
TX_BUFFER_SIZE : len;
- size = tx_size / 4;
- for (i = 0; i < size; i++) {
+ size = tx_size / 16;
+ /*
+ * There must be atleast 128bit data
+ * available in TX FIFO for any pop operation
+ */
+ if (tx_size % 16)
+ size++;
+ for (i = 0; i < size * 4; i++) {
memcpy(&data, txbuf, 4);
data = qspi_endian_xchg(data);
qspi_write32(priv->flags, &regs->tbdr, data);
txbuf += 4;
}
- size = tx_size % 4;
- if (size) {
- data = 0;
- memcpy(&data, txbuf, size);
- data = qspi_endian_xchg(data);
- qspi_write32(priv->flags, &regs->tbdr, data);
- }
-
qspi_write32(priv->flags, &regs->ipcr,
(seqid << QSPI_IPCR_SEQID_SHIFT) | tx_size);
while (qspi_read32(priv->flags, &regs->sr) & QSPI_SR_BUSY_MASK)
@@ -991,7 +990,7 @@ static int fsl_qspi_probe(struct udevice *bus)
struct fsl_qspi_platdata *plat = dev_get_platdata(bus);
struct fsl_qspi_priv *priv = dev_get_priv(bus);
struct dm_spi_bus *dm_spi_bus;
- int i;
+ int i, ret;
dm_spi_bus = bus->uclass_priv;
@@ -1011,6 +1010,18 @@ static int fsl_qspi_probe(struct udevice *bus)
priv->flash_num = plat->flash_num;
priv->num_chipselect = plat->num_chipselect;
+ /* make sure controller is not busy anywhere */
+ ret = wait_for_bit(__func__, &priv->regs->sr,
+ QSPI_SR_BUSY_MASK |
+ QSPI_SR_AHB_ACC_MASK |
+ QSPI_SR_IP_ACC_MASK,
+ false, 100, false);
+
+ if (ret) {
+ debug("ERROR : The controller is busy\n");
+ return ret;
+ }
+
mcr_val = qspi_read32(priv->flags, &priv->regs->mcr);
qspi_write32(priv->flags, &priv->regs->mcr,
QSPI_MCR_RESERVED_MASK | QSPI_MCR_MDIS_MASK |
@@ -1156,10 +1167,23 @@ static int fsl_qspi_claim_bus(struct udevice *dev)
struct fsl_qspi_priv *priv;
struct udevice *bus;
struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev);
+ int ret;
bus = dev->parent;
priv = dev_get_priv(bus);
+ /* make sure controller is not busy anywhere */
+ ret = wait_for_bit(__func__, &priv->regs->sr,
+ QSPI_SR_BUSY_MASK |
+ QSPI_SR_AHB_ACC_MASK |
+ QSPI_SR_IP_ACC_MASK,
+ false, 100, false);
+
+ if (ret) {
+ debug("ERROR : The controller is busy\n");
+ return ret;
+ }
+
priv->cur_amba_base = priv->amba_base[slave_plat->cs];
qspi_module_disable(priv, 0);
diff --git a/drivers/spi/fsl_qspi.h b/drivers/spi/fsl_qspi.h
index 6cb361018b..e468eb2529 100644
--- a/drivers/spi/fsl_qspi.h
+++ b/drivers/spi/fsl_qspi.h
@@ -105,6 +105,10 @@ struct fsl_qspi_regs {
#define QSPI_RBCT_RXBRD_SHIFT 8
#define QSPI_RBCT_RXBRD_USEIPS (1 << QSPI_RBCT_RXBRD_SHIFT)
+#define QSPI_SR_AHB_ACC_SHIFT 2
+#define QSPI_SR_AHB_ACC_MASK (1 << QSPI_SR_AHB_ACC_SHIFT)
+#define QSPI_SR_IP_ACC_SHIFT 1
+#define QSPI_SR_IP_ACC_MASK (1 << QSPI_SR_IP_ACC_SHIFT)
#define QSPI_SR_BUSY_SHIFT 0
#define QSPI_SR_BUSY_MASK (1 << QSPI_SR_BUSY_SHIFT)
diff --git a/drivers/spi/mxc_spi.c b/drivers/spi/mxc_spi.c
index e1562c36b7..41f0cfcd6b 100644
--- a/drivers/spi/mxc_spi.c
+++ b/drivers/spi/mxc_spi.c
@@ -5,6 +5,7 @@
*/
#include <common.h>
+#include <dm.h>
#include <malloc.h>
#include <spi.h>
#include <linux/errno.h>
@@ -14,6 +15,8 @@
#include <asm/arch/clock.h>
#include <asm/mach-imx/spi.h>
+DECLARE_GLOBAL_DATA_PTR;
+
#ifdef CONFIG_MX27
/* i.MX27 has a completely wrong register layout and register definitions in the
* datasheet, the correct one is in the Freescale's Linux driver */
@@ -22,10 +25,6 @@
"See linux mxc_spi driver from Freescale for details."
#endif
-static unsigned long spi_bases[] = {
- MXC_SPI_BASE_ADDRESSES
-};
-
__weak int board_spi_cs_gpio(unsigned bus, unsigned cs)
{
return -1;
@@ -51,6 +50,7 @@ struct mxc_spi_slave {
int ss_pol;
unsigned int max_hz;
unsigned int mode;
+ struct gpio_desc ss;
};
static inline struct mxc_spi_slave *to_mxc_spi_slave(struct spi_slave *slave)
@@ -58,19 +58,24 @@ static inline struct mxc_spi_slave *to_mxc_spi_slave(struct spi_slave *slave)
return container_of(slave, struct mxc_spi_slave, slave);
}
-void spi_cs_activate(struct spi_slave *slave)
+static void mxc_spi_cs_activate(struct mxc_spi_slave *mxcs)
{
- struct mxc_spi_slave *mxcs = to_mxc_spi_slave(slave);
- if (mxcs->gpio > 0)
- gpio_set_value(mxcs->gpio, mxcs->ss_pol);
+ if (CONFIG_IS_ENABLED(DM_SPI)) {
+ dm_gpio_set_value(&mxcs->ss, mxcs->ss_pol);
+ } else {
+ if (mxcs->gpio > 0)
+ gpio_set_value(mxcs->gpio, mxcs->ss_pol);
+ }
}
-void spi_cs_deactivate(struct spi_slave *slave)
+static void mxc_spi_cs_deactivate(struct mxc_spi_slave *mxcs)
{
- struct mxc_spi_slave *mxcs = to_mxc_spi_slave(slave);
- if (mxcs->gpio > 0)
- gpio_set_value(mxcs->gpio,
- !(mxcs->ss_pol));
+ if (CONFIG_IS_ENABLED(DM_SPI)) {
+ dm_gpio_set_value(&mxcs->ss, !(mxcs->ss_pol));
+ } else {
+ if (mxcs->gpio > 0)
+ gpio_set_value(mxcs->gpio, !(mxcs->ss_pol));
+ }
}
u32 get_cspi_div(u32 div)
@@ -211,10 +216,9 @@ static s32 spi_cfg_mxc(struct mxc_spi_slave *mxcs, unsigned int cs)
}
#endif
-int spi_xchg_single(struct spi_slave *slave, unsigned int bitlen,
+int spi_xchg_single(struct mxc_spi_slave *mxcs, unsigned int bitlen,
const u8 *dout, u8 *din, unsigned long flags)
{
- struct mxc_spi_slave *mxcs = to_mxc_spi_slave(slave);
int nbytes = DIV_ROUND_UP(bitlen, 8);
u32 data, cnt, i;
struct cspi_regs *regs = (struct cspi_regs *)mxcs->base;
@@ -327,8 +331,9 @@ int spi_xchg_single(struct spi_slave *slave, unsigned int bitlen,
}
-int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
- void *din, unsigned long flags)
+static int mxc_spi_xfer_internal(struct mxc_spi_slave *mxcs,
+ unsigned int bitlen, const void *dout,
+ void *din, unsigned long flags)
{
int n_bytes = DIV_ROUND_UP(bitlen, 8);
int n_bits;
@@ -337,11 +342,11 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
u8 *p_outbuf = (u8 *)dout;
u8 *p_inbuf = (u8 *)din;
- if (!slave)
- return -1;
+ if (!mxcs)
+ return -EINVAL;
if (flags & SPI_XFER_BEGIN)
- spi_cs_activate(slave);
+ mxc_spi_cs_activate(mxcs);
while (n_bytes > 0) {
if (n_bytes < MAX_SPI_BYTES)
@@ -351,7 +356,7 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
n_bits = blk_size * 8;
- ret = spi_xchg_single(slave, n_bits, p_outbuf, p_inbuf, 0);
+ ret = spi_xchg_single(mxcs, n_bits, p_outbuf, p_inbuf, 0);
if (ret)
return ret;
@@ -363,12 +368,39 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
}
if (flags & SPI_XFER_END) {
- spi_cs_deactivate(slave);
+ mxc_spi_cs_deactivate(mxcs);
}
return 0;
}
+static int mxc_spi_claim_bus_internal(struct mxc_spi_slave *mxcs, int cs)
+{
+ struct cspi_regs *regs = (struct cspi_regs *)mxcs->base;
+ int ret;
+
+ reg_write(&regs->rxdata, 1);
+ udelay(1);
+ ret = spi_cfg_mxc(mxcs, cs);
+ if (ret) {
+ printf("mxc_spi: cannot setup SPI controller\n");
+ return ret;
+ }
+ reg_write(&regs->period, MXC_CSPIPERIOD_32KHZ);
+ reg_write(&regs->intr, 0);
+
+ return 0;
+}
+
+#ifndef CONFIG_DM_SPI
+int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
+ void *din, unsigned long flags)
+{
+ struct mxc_spi_slave *mxcs = to_mxc_spi_slave(slave);
+
+ return mxc_spi_xfer_internal(mxcs, bitlen, dout, din, flags);
+}
+
void spi_init(void)
{
}
@@ -390,6 +422,7 @@ static int setup_cs_gpio(struct mxc_spi_slave *mxcs,
if (mxcs->gpio == -1)
return 0;
+ gpio_request(mxcs->gpio, "spi-cs");
ret = gpio_direction_output(mxcs->gpio, !(mxcs->ss_pol));
if (ret) {
printf("mxc_spi: cannot setup gpio %d\n", mxcs->gpio);
@@ -399,6 +432,10 @@ static int setup_cs_gpio(struct mxc_spi_slave *mxcs,
return 0;
}
+static unsigned long spi_bases[] = {
+ MXC_SPI_BASE_ADDRESSES
+};
+
struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
unsigned int max_hz, unsigned int mode)
{
@@ -443,24 +480,104 @@ void spi_free_slave(struct spi_slave *slave)
int spi_claim_bus(struct spi_slave *slave)
{
- int ret;
struct mxc_spi_slave *mxcs = to_mxc_spi_slave(slave);
- struct cspi_regs *regs = (struct cspi_regs *)mxcs->base;
- reg_write(&regs->rxdata, 1);
- udelay(1);
- ret = spi_cfg_mxc(mxcs, slave->cs);
+ return mxc_spi_claim_bus_internal(mxcs, slave->cs);
+}
+
+void spi_release_bus(struct spi_slave *slave)
+{
+ /* TODO: Shut the controller down */
+}
+#else
+
+static int mxc_spi_probe(struct udevice *bus)
+{
+ struct mxc_spi_slave *plat = bus->platdata;
+ struct mxc_spi_slave *mxcs = dev_get_platdata(bus);
+ int node = dev_of_offset(bus);
+ const void *blob = gd->fdt_blob;
+ int ret;
+
+ if (gpio_request_by_name(bus, "cs-gpios", 0, &plat->ss,
+ GPIOD_IS_OUT)) {
+ dev_err(bus, "No cs-gpios property\n");
+ return -EINVAL;
+ }
+
+ plat->base = dev_get_addr(bus);
+ if (plat->base == FDT_ADDR_T_NONE)
+ return -ENODEV;
+
+ ret = dm_gpio_set_value(&plat->ss, !(mxcs->ss_pol));
if (ret) {
- printf("mxc_spi: cannot setup SPI controller\n");
+ dev_err(bus, "Setting cs error\n");
return ret;
}
- reg_write(&regs->period, MXC_CSPIPERIOD_32KHZ);
- reg_write(&regs->intr, 0);
+
+ mxcs->max_hz = fdtdec_get_int(blob, node, "spi-max-frequency",
+ 20000000);
return 0;
}
-void spi_release_bus(struct spi_slave *slave)
+static int mxc_spi_xfer(struct udevice *dev, unsigned int bitlen,
+ const void *dout, void *din, unsigned long flags)
{
- /* TODO: Shut the controller down */
+ struct mxc_spi_slave *mxcs = dev_get_platdata(dev->parent);
+
+
+ return mxc_spi_xfer_internal(mxcs, bitlen, dout, din, flags);
+}
+
+static int mxc_spi_claim_bus(struct udevice *dev)
+{
+ struct mxc_spi_slave *mxcs = dev_get_platdata(dev->parent);
+ struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev);
+
+ return mxc_spi_claim_bus_internal(mxcs, slave_plat->cs);
}
+
+static int mxc_spi_release_bus(struct udevice *dev)
+{
+ return 0;
+}
+
+static int mxc_spi_set_speed(struct udevice *bus, uint speed)
+{
+ /* Nothing to do */
+ return 0;
+}
+
+static int mxc_spi_set_mode(struct udevice *bus, uint mode)
+{
+ struct mxc_spi_slave *mxcs = dev_get_platdata(bus);
+
+ mxcs->mode = mode;
+ mxcs->ss_pol = (mode & SPI_CS_HIGH) ? 1 : 0;
+
+ return 0;
+}
+
+static const struct dm_spi_ops mxc_spi_ops = {
+ .claim_bus = mxc_spi_claim_bus,
+ .release_bus = mxc_spi_release_bus,
+ .xfer = mxc_spi_xfer,
+ .set_speed = mxc_spi_set_speed,
+ .set_mode = mxc_spi_set_mode,
+};
+
+static const struct udevice_id mxc_spi_ids[] = {
+ { .compatible = "fsl,imx51-ecspi" },
+ { }
+};
+
+U_BOOT_DRIVER(mxc_spi) = {
+ .name = "mxc_spi",
+ .id = UCLASS_SPI,
+ .of_match = mxc_spi_ids,
+ .ops = &mxc_spi_ops,
+ .platdata_auto_alloc_size = sizeof(struct mxc_spi_slave),
+ .probe = mxc_spi_probe,
+};
+#endif
diff --git a/drivers/spi/nds_ae3xx_spi.c b/drivers/spi/nds_ae3xx_spi.c
new file mode 100644
index 0000000000..f5bd99a605
--- /dev/null
+++ b/drivers/spi/nds_ae3xx_spi.c
@@ -0,0 +1,499 @@
+/*
+ * NDS SPI controller driver.
+ *
+ * Copyright 2017 Andes Technology, Inc.
+ * Author: Rick Chen (rick@andestech.com)
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <clk.h>
+#include <common.h>
+#include <malloc.h>
+#include <spi.h>
+#include <asm/io.h>
+#include <dm.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define MAX_TRANSFER_LEN 512
+#define CHUNK_SIZE 1
+#define SPI_TIMEOUT 0x100000
+#define SPI0_BUS 0
+#define SPI1_BUS 1
+#define SPI0_BASE 0xf0b00000
+#define SPI1_BASE 0xf0f00000
+#define NSPI_MAX_CS_NUM 1
+
+struct ae3xx_spi_regs {
+ u32 rev;
+ u32 reserve1[3];
+ u32 format; /* 0x10 */
+#define DATA_LENGTH(x) ((x-1)<<8)
+ u32 pio;
+ u32 reserve2[2];
+ u32 tctrl; /* 0x20 */
+#define TRAMODE_OFFSET 24
+#define TRAMODE_MASK (0x0F<<TRAMODE_OFFSET)
+#define TRAMODE_WR_SYNC (0<<TRAMODE_OFFSET)
+#define TRAMODE_WO (1<<TRAMODE_OFFSET)
+#define TRAMODE_RO (2<<TRAMODE_OFFSET)
+#define TRAMODE_WR (3<<TRAMODE_OFFSET)
+#define TRAMODE_RW (4<<TRAMODE_OFFSET)
+#define TRAMODE_WDR (5<<TRAMODE_OFFSET)
+#define TRAMODE_RDW (6<<TRAMODE_OFFSET)
+#define TRAMODE_NONE (7<<TRAMODE_OFFSET)
+#define TRAMODE_DW (8<<TRAMODE_OFFSET)
+#define TRAMODE_DR (9<<TRAMODE_OFFSET)
+#define WCNT_OFFSET 12
+#define WCNT_MASK (0x1FF<<WCNT_OFFSET)
+#define RCNT_OFFSET 0
+#define RCNT_MASK (0x1FF<<RCNT_OFFSET)
+ u32 cmd;
+ u32 addr;
+ u32 data;
+ u32 ctrl; /* 0x30 */
+#define TXFTH_OFFSET 16
+#define RXFTH_OFFSET 8
+#define TXDMAEN (1<<4)
+#define RXDMAEN (1<<3)
+#define TXFRST (1<<2)
+#define RXFRST (1<<1)
+#define SPIRST (1<<0)
+ u32 status;
+#define TXFFL (1<<23)
+#define TXEPTY (1<<22)
+#define TXFVE_MASK (0x1F<<16)
+#define RXFEM (1<<14)
+#define RXFVE_OFFSET (8)
+#define RXFVE_MASK (0x1F<<RXFVE_OFFSET)
+#define SPIBSY (1<<0)
+ u32 inten;
+ u32 intsta;
+ u32 timing; /* 0x40 */
+#define SCLK_DIV_MASK 0xFF
+};
+
+struct nds_spi_slave {
+#ifndef CONFIG_DM_SPI
+ struct spi_slave slave;
+#endif
+ volatile struct ae3xx_spi_regs *regs;
+ int to;
+ unsigned int freq;
+ ulong clock;
+ unsigned int mode;
+ u8 num_cs;
+ unsigned int mtiming;
+ size_t cmd_len;
+ u8 cmd_buf[16];
+ size_t data_len;
+ size_t tran_len;
+ u8 *din;
+ u8 *dout;
+ unsigned int max_transfer_length;
+};
+
+static int __ae3xx_spi_set_speed(struct nds_spi_slave *ns)
+{
+ u32 tm;
+ u8 div;
+ tm = ns->regs->timing;
+ tm &= ~SCLK_DIV_MASK;
+
+ if(ns->freq >= ns->clock)
+ div =0xff;
+ else{
+ for (div = 0; div < 0xff; div++) {
+ if (ns->freq >= ns->clock / (2 * (div + 1)))
+ break;
+ }
+ }
+
+ tm |= div;
+ ns->regs->timing = tm;
+
+ return 0;
+
+}
+
+static int __ae3xx_spi_claim_bus(struct nds_spi_slave *ns)
+{
+ unsigned int format=0;
+ ns->regs->ctrl |= (TXFRST|RXFRST|SPIRST);
+ while((ns->regs->ctrl &(TXFRST|RXFRST|SPIRST))&&(ns->to--))
+ if(!ns->to)
+ return -EINVAL;
+
+ ns->cmd_len = 0;
+ format = ns->mode|DATA_LENGTH(8);
+ ns->regs->format = format;
+ __ae3xx_spi_set_speed(ns);
+
+ return 0;
+}
+
+static int __ae3xx_spi_release_bus(struct nds_spi_slave *ns)
+{
+ /* do nothing */
+ return 0;
+}
+
+static int __ae3xx_spi_start(struct nds_spi_slave *ns)
+{
+ int i,olen=0;
+ int tc = ns->regs->tctrl;
+
+ tc &= ~(WCNT_MASK|RCNT_MASK|TRAMODE_MASK);
+ if ((ns->din)&&(ns->cmd_len))
+ tc |= TRAMODE_WR;
+ else if (ns->din)
+ tc |= TRAMODE_RO;
+ else
+ tc |= TRAMODE_WO;
+
+ if(ns->dout)
+ olen = ns->tran_len;
+ tc |= (ns->cmd_len+olen-1) << WCNT_OFFSET;
+
+ if(ns->din)
+ tc |= (ns->tran_len-1) << RCNT_OFFSET;
+
+ ns->regs->tctrl = tc;
+ ns->regs->cmd = 1;
+
+ for (i=0;i<ns->cmd_len;i++)
+ ns->regs->data = ns->cmd_buf[i];
+
+ return 0;
+}
+
+static int __ae3xx_spi_stop(struct nds_spi_slave *ns)
+{
+ ns->regs->timing = ns->mtiming;
+ while ((ns->regs->status & SPIBSY)&&(ns->to--))
+ if (!ns->to)
+ return -EINVAL;
+
+ return 0;
+}
+
+static void __nspi_espi_tx(struct nds_spi_slave *ns, const void *dout)
+{
+ ns->regs->data = *(u8 *)dout;
+}
+
+static int __nspi_espi_rx(struct nds_spi_slave *ns, void *din, unsigned int bytes)
+{
+ *(u8 *)din = ns->regs->data;
+ return bytes;
+}
+
+
+static int __ae3xx_spi_xfer(struct nds_spi_slave *ns,
+ unsigned int bitlen, const void *data_out, void *data_in,
+ unsigned long flags)
+{
+ unsigned int event, rx_bytes;
+ const void *dout = NULL;
+ void *din = NULL;
+ int num_blks, num_chunks, max_tran_len, tran_len;
+ int num_bytes;
+ u8 *cmd_buf = ns->cmd_buf;
+ size_t cmd_len = ns->cmd_len;
+ size_t data_len = bitlen / 8;
+ int rf_cnt;
+ int ret = 0;
+
+ max_tran_len = ns->max_transfer_length;
+ switch (flags) {
+ case SPI_XFER_BEGIN:
+ cmd_len = ns->cmd_len = data_len;
+ memcpy(cmd_buf, data_out, cmd_len);
+ return 0;
+
+ case 0:
+ case SPI_XFER_END:
+ if (bitlen == 0) {
+ return 0;
+ }
+ ns->data_len = data_len;
+ ns->din = (u8 *)data_in;
+ ns->dout = (u8 *)data_out;
+ break;
+
+ case SPI_XFER_BEGIN | SPI_XFER_END:
+ ns->data_len = 0;
+ ns->din = 0;
+ ns->dout = 0;
+ cmd_len = ns->cmd_len = data_len;
+ memcpy(cmd_buf, data_out, cmd_len);
+ data_out = 0;
+ data_len = 0;
+ __ae3xx_spi_start(ns);
+ break;
+ }
+ debug("spi_xfer: data_out %08X(%p) data_in %08X(%p) data_len %u\n",
+ *(uint *)data_out, data_out, *(uint *)data_in, data_in, data_len);
+ num_chunks = DIV_ROUND_UP(data_len, max_tran_len);
+ din = data_in;
+ dout = data_out;
+ while (num_chunks--) {
+ tran_len = min(data_len, (size_t)max_tran_len);
+ ns->tran_len = tran_len;
+ num_blks = DIV_ROUND_UP(tran_len , CHUNK_SIZE);
+ num_bytes = (tran_len) % CHUNK_SIZE;
+ if(num_bytes == 0)
+ num_bytes = CHUNK_SIZE;
+ __ae3xx_spi_start(ns);
+
+ while (num_blks) {
+ event = in_le32(&ns->regs->status);
+ if ((event & TXEPTY) && (data_out)) {
+ __nspi_espi_tx(ns, dout);
+ num_blks -= CHUNK_SIZE;
+ dout += CHUNK_SIZE;
+ }
+
+ if ((event & RXFVE_MASK) && (data_in)) {
+ rf_cnt = ((event & RXFVE_MASK)>> RXFVE_OFFSET);
+ if (rf_cnt >= CHUNK_SIZE)
+ rx_bytes = CHUNK_SIZE;
+ else if (num_blks == 1 && rf_cnt == num_bytes)
+ rx_bytes = num_bytes;
+ else
+ continue;
+
+ if (__nspi_espi_rx(ns, din, rx_bytes) == rx_bytes) {
+ num_blks -= CHUNK_SIZE;
+ din = (unsigned char *)din + rx_bytes;
+ }
+ }
+ }
+
+ data_len -= tran_len;
+ if(data_len)
+ {
+ ns->cmd_buf[1] += ((tran_len>>16)&0xff);
+ ns->cmd_buf[2] += ((tran_len>>8)&0xff);
+ ns->cmd_buf[3] += ((tran_len)&0xff);
+ ns->data_len = data_len;
+ }
+ ret = __ae3xx_spi_stop(ns);
+ }
+ ret = __ae3xx_spi_stop(ns);
+
+ return ret;
+}
+
+#ifndef CONFIG_DM_SPI
+#define to_nds_spi_slave(s) container_of(s, struct nds_spi_slave, slave)
+struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
+ unsigned int max_hz, unsigned int mode)
+{
+ struct nds_spi_slave *ns;
+
+ if (!spi_cs_is_valid(bus, cs))
+ return NULL;
+
+ ns = spi_alloc_slave(struct nds_spi_slave, bus, cs);
+
+ switch (bus) {
+ case SPI0_BUS:
+ ns->regs = (struct ae3xx_spi_regs *)SPI0_BASE;
+ break;
+
+ case SPI1_BUS:
+ ns->regs = (struct ae3xx_spi_regs *)SPI1_BASE;
+ break;
+
+ default:
+ return NULL;
+ }
+
+ ns->freq= max_hz;
+ ns->mode = mode;
+ ns->to = SPI_TIMEOUT;
+ ns->max_transfer_length = MAX_TRANSFER_LEN;
+ ns->slave.max_write_size = MAX_TRANSFER_LEN;
+ if (!ns)
+ return NULL;
+
+ return &ns->slave;
+}
+
+void spi_free_slave(struct spi_slave *slave)
+{
+ struct nds_spi_slave *ns = to_nds_spi_slave(slave);
+ free(ns);
+}
+
+void spi_init(void)
+{
+ /* do nothing */
+}
+
+int spi_claim_bus(struct spi_slave *slave)
+{
+ struct nds_spi_slave *ns = to_nds_spi_slave(slave);
+ return __ae3xx_spi_claim_bus(ns);
+}
+
+void spi_release_bus(struct spi_slave *slave)
+{
+ struct nds_spi_slave *ns = to_nds_spi_slave(slave);
+ __ae3xx_spi_release_bus(ns);
+}
+
+int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *data_out,
+ void *data_in, unsigned long flags)
+{
+ struct nds_spi_slave *ns = to_nds_spi_slave(slave);
+ return __ae3xx_spi_xfer(ns, bitlen, data_out, data_in, flags);
+}
+
+int spi_cs_is_valid(unsigned int bus, unsigned int cs)
+{
+ return bus == 0 && cs < NSPI_MAX_CS_NUM;
+}
+
+void spi_cs_activate(struct spi_slave *slave)
+{
+ struct nds_spi_slave *ns = to_nds_spi_slave(slave);
+ __ae3xx_spi_start(ns);
+}
+
+void spi_cs_deactivate(struct spi_slave *slave)
+{
+ struct nds_spi_slave *ns = to_nds_spi_slave(slave);
+ __ae3xx_spi_stop(ns);
+}
+#else
+static int ae3xx_spi_set_speed(struct udevice *bus, uint max_hz)
+{
+ struct nds_spi_slave *ns = dev_get_priv(bus);
+
+ debug("%s speed %u\n", __func__, max_hz);
+
+ ns->freq = max_hz;
+ __ae3xx_spi_set_speed(ns);
+
+ return 0;
+}
+
+static int ae3xx_spi_set_mode(struct udevice *bus, uint mode)
+{
+ struct nds_spi_slave *ns = dev_get_priv(bus);
+
+ debug("%s mode %u\n", __func__, mode);
+ ns->mode = mode;
+
+ return 0;
+}
+
+static int ae3xx_spi_claim_bus(struct udevice *dev)
+{
+ struct dm_spi_slave_platdata *slave_plat =
+ dev_get_parent_platdata(dev);
+ struct udevice *bus = dev->parent;
+ struct nds_spi_slave *ns = dev_get_priv(bus);
+
+ if (slave_plat->cs >= ns->num_cs) {
+ printf("Invalid SPI chipselect\n");
+ return -EINVAL;
+ }
+
+ return __ae3xx_spi_claim_bus(ns);
+}
+
+static int ae3xx_spi_release_bus(struct udevice *dev)
+{
+ struct nds_spi_slave *ns = dev_get_priv(dev->parent);
+
+ return __ae3xx_spi_release_bus(ns);
+}
+
+static int ae3xx_spi_xfer(struct udevice *dev, unsigned int bitlen,
+ const void *dout, void *din,
+ unsigned long flags)
+{
+ struct udevice *bus = dev->parent;
+ struct nds_spi_slave *ns = dev_get_priv(bus);
+
+ return __ae3xx_spi_xfer(ns, bitlen, dout, din, flags);
+}
+
+static int ae3xx_spi_get_clk(struct udevice *bus)
+{
+ struct nds_spi_slave *ns = dev_get_priv(bus);
+ struct clk clk;
+ ulong clk_rate;
+ int ret;
+
+ ret = clk_get_by_index(bus, 0, &clk);
+ if (ret)
+ return -EINVAL;
+
+ clk_rate = clk_get_rate(&clk);
+ if (!clk_rate)
+ return -EINVAL;
+
+ ns->clock = clk_rate;
+ clk_free(&clk);
+
+ return 0;
+}
+
+static int ae3xx_spi_probe(struct udevice *bus)
+{
+ struct nds_spi_slave *ns = dev_get_priv(bus);
+
+ ns->to = SPI_TIMEOUT;
+ ns->max_transfer_length = MAX_TRANSFER_LEN;
+ ns->mtiming = ns->regs->timing;
+ ae3xx_spi_get_clk(bus);
+
+ return 0;
+}
+
+static int ae3xx_ofdata_to_platadata(struct udevice *bus)
+{
+ struct nds_spi_slave *ns = dev_get_priv(bus);
+ const void *blob = gd->fdt_blob;
+ int node = dev_of_offset(bus);
+
+ ns->regs = map_physmem(devfdt_get_addr(bus),
+ sizeof(struct ae3xx_spi_regs),
+ MAP_NOCACHE);
+ if (!ns->regs) {
+ printf("%s: could not map device address\n", __func__);
+ return -EINVAL;
+ }
+ ns->num_cs = fdtdec_get_int(blob, node, "num-cs", 4);
+
+ return 0;
+}
+
+static const struct dm_spi_ops ae3xx_spi_ops = {
+ .claim_bus = ae3xx_spi_claim_bus,
+ .release_bus = ae3xx_spi_release_bus,
+ .xfer = ae3xx_spi_xfer,
+ .set_speed = ae3xx_spi_set_speed,
+ .set_mode = ae3xx_spi_set_mode,
+};
+
+static const struct udevice_id ae3xx_spi_ids[] = {
+ { .compatible = "andestech,atcspi200" },
+ { }
+};
+
+U_BOOT_DRIVER(ae3xx_spi) = {
+ .name = "ae3xx_spi",
+ .id = UCLASS_SPI,
+ .of_match = ae3xx_spi_ids,
+ .ops = &ae3xx_spi_ops,
+ .ofdata_to_platdata = ae3xx_ofdata_to_platadata,
+ .priv_auto_alloc_size = sizeof(struct nds_spi_slave),
+ .probe = ae3xx_spi_probe,
+};
+#endif
diff --git a/drivers/spi/rk_spi.c b/drivers/spi/rk_spi.c
index c70d636277..b18db74e7e 100644
--- a/drivers/spi/rk_spi.c
+++ b/drivers/spi/rk_spi.c
@@ -184,7 +184,7 @@ static int rockchip_spi_ofdata_to_platdata(struct udevice *bus)
struct rockchip_spi_priv *priv = dev_get_priv(bus);
int ret;
- plat->base = devfdt_get_addr(bus);
+ plat->base = dev_read_addr(bus);
ret = clk_get_by_index(bus, 0, &priv->clk);
if (ret < 0) {
diff --git a/drivers/sysreset/Makefile b/drivers/sysreset/Makefile
index a5200d377d..476d361297 100644
--- a/drivers/sysreset/Makefile
+++ b/drivers/sysreset/Makefile
@@ -13,6 +13,7 @@ ifndef CONFIG_SPL_BUILD
obj-$(CONFIG_ROCKCHIP_RK3036) += sysreset_rk3036.o
endif
obj-$(CONFIG_ROCKCHIP_RK3188) += sysreset_rk3188.o
+obj-$(CONFIG_ROCKCHIP_RK322X) += sysreset_rk322x.o
obj-$(CONFIG_ROCKCHIP_RK3288) += sysreset_rk3288.o
obj-$(CONFIG_ROCKCHIP_RK3328) += sysreset_rk3328.o
obj-$(CONFIG_ROCKCHIP_RK3368) += sysreset_rk3368.o
diff --git a/drivers/timer/rockchip_timer.c b/drivers/timer/rockchip_timer.c
index eb44965a19..07d14482d6 100644
--- a/drivers/timer/rockchip_timer.c
+++ b/drivers/timer/rockchip_timer.c
@@ -6,6 +6,7 @@
#include <common.h>
#include <dm.h>
+#include <dm/ofnode.h>
#include <mapmem.h>
#include <asm/arch/timer.h>
#include <dt-structs.h>
@@ -25,17 +26,72 @@ struct rockchip_timer_priv {
struct rk_timer *timer;
};
-static int rockchip_timer_get_count(struct udevice *dev, u64 *count)
+static inline int64_t rockchip_timer_get_curr_value(struct rk_timer *timer)
{
- struct rockchip_timer_priv *priv = dev_get_priv(dev);
uint64_t timebase_h, timebase_l;
uint64_t cntr;
- timebase_l = readl(&priv->timer->timer_curr_value0);
- timebase_h = readl(&priv->timer->timer_curr_value1);
+ timebase_l = readl(&timer->timer_curr_value0);
+ timebase_h = readl(&timer->timer_curr_value1);
- /* timers are down-counting */
cntr = timebase_h << 32 | timebase_l;
+ return cntr;
+}
+
+#if CONFIG_IS_ENABLED(BOOTSTAGE)
+ulong timer_get_boot_us(void)
+{
+ uint64_t ticks = 0;
+ uint32_t rate;
+ uint64_t us;
+ int ret;
+
+ ret = dm_timer_init();
+
+ if (!ret) {
+ /* The timer is available */
+ rate = timer_get_rate(gd->timer);
+ timer_get_count(gd->timer, &ticks);
+#if !CONFIG_IS_ENABLED(OF_PLATDATA)
+ } else if (ret == -EAGAIN) {
+ /* We have been called so early that the DM is not ready,... */
+ ofnode node = offset_to_ofnode(-1);
+ struct rk_timer *timer = NULL;
+
+ /*
+ * ... so we try to access the raw timer, if it is specified
+ * via the tick-timer property in /chosen.
+ */
+ node = ofnode_get_chosen_node("tick-timer");
+ if (!ofnode_valid(node)) {
+ debug("%s: no /chosen/tick-timer\n", __func__);
+ return 0;
+ }
+
+ timer = (struct rk_timer *)ofnode_get_addr(node);
+
+ /* This timer is down-counting */
+ ticks = ~0uLL - rockchip_timer_get_curr_value(timer);
+ if (ofnode_read_u32(node, "clock-frequency", &rate)) {
+ debug("%s: could not read clock-frequency\n", __func__);
+ return 0;
+ }
+#endif
+ } else {
+ return 0;
+ }
+
+ us = (ticks * 1000) / rate;
+ return us;
+}
+#endif
+
+static int rockchip_timer_get_count(struct udevice *dev, u64 *count)
+{
+ struct rockchip_timer_priv *priv = dev_get_priv(dev);
+ uint64_t cntr = rockchip_timer_get_curr_value(priv->timer);
+
+ /* timers are down-counting */
*count = ~0ull - cntr;
return 0;
}
@@ -45,7 +101,9 @@ static int rockchip_clk_ofdata_to_platdata(struct udevice *dev)
#if !CONFIG_IS_ENABLED(OF_PLATDATA)
struct rockchip_timer_priv *priv = dev_get_priv(dev);
- priv->timer = (struct rk_timer *)devfdt_get_addr(dev);
+ priv->timer = dev_read_addr_ptr(dev);
+ if (!priv->timer)
+ return -ENOENT;
#endif
return 0;
@@ -58,6 +116,12 @@ static int rockchip_timer_start(struct udevice *dev)
const uint32_t reload_val_l = reload_val & 0xffffffff;
const uint32_t reload_val_h = reload_val >> 32;
+ /* don't reinit, if the timer is already running and set up */
+ if ((readl(&priv->timer->timer_ctrl_reg) & 1) == 1 &&
+ (readl(&priv->timer->timer_load_count0) == reload_val_l) &&
+ (readl(&priv->timer->timer_load_count1) == reload_val_h))
+ return 0;
+
/* disable timer and reset all control */
writel(0, &priv->timer->timer_ctrl_reg);
/* write reload value */
@@ -76,7 +140,7 @@ static int rockchip_timer_probe(struct udevice *dev)
struct rockchip_timer_priv *priv = dev_get_priv(dev);
struct rockchip_timer_plat *plat = dev_get_platdata(dev);
- priv->timer = map_sysmem(plat->dtd.reg[1], plat->dtd.reg[3]);
+ priv->timer = map_sysmem(plat->dtd.reg[0], plat->dtd.reg[1]);
uc_priv->clock_rate = plat->dtd.clock_frequency;
#endif
diff --git a/drivers/timer/timer-uclass.c b/drivers/timer/timer-uclass.c
index a84755f4c5..45397b230f 100644
--- a/drivers/timer/timer-uclass.c
+++ b/drivers/timer/timer-uclass.c
@@ -8,6 +8,7 @@
#include <dm.h>
#include <dm/lists.h>
#include <dm/device-internal.h>
+#include <dm/root.h>
#include <clk.h>
#include <errno.h>
#include <timer.h>
@@ -54,9 +55,10 @@ static int timer_pre_probe(struct udevice *dev)
if (IS_ERR_VALUE(ret))
return ret;
uc_priv->clock_rate = ret;
- } else
- uc_priv->clock_rate = fdtdec_get_int(gd->fdt_blob,
- dev_of_offset(dev), "clock-frequency", 0);
+ } else {
+ uc_priv->clock_rate =
+ dev_read_u32_default(dev, "clock-frequency", 0);
+ }
#endif
return 0;
@@ -83,37 +85,43 @@ u64 timer_conv_64(u32 count)
int notrace dm_timer_init(void)
{
- __maybe_unused const void *blob = gd->fdt_blob;
struct udevice *dev = NULL;
- int node = -ENOENT;
+ __maybe_unused ofnode node;
int ret;
if (gd->timer)
return 0;
+ /*
+ * Directly access gd->dm_root to suppress error messages, if the
+ * virtual root driver does not yet exist.
+ */
+ if (gd->dm_root == NULL)
+ return -EAGAIN;
+
#if !CONFIG_IS_ENABLED(OF_PLATDATA)
/* Check for a chosen timer to be used for tick */
- node = fdtdec_get_chosen_node(blob, "tick-timer");
+ node = ofnode_get_chosen_node("tick-timer");
+
+ if (ofnode_valid(node) &&
+ uclass_get_device_by_ofnode(UCLASS_TIMER, node, &dev)) {
+ /*
+ * If the timer is not marked to be bound before
+ * relocation, bind it anyway.
+ */
+ if (!lists_bind_fdt(dm_root(), node, &dev)) {
+ ret = device_probe(dev);
+ if (ret)
+ return ret;
+ }
+ }
#endif
- if (node < 0) {
- /* No chosen timer, trying first available timer */
+
+ if (!dev) {
+ /* Fall back to the first available timer */
ret = uclass_first_device_err(UCLASS_TIMER, &dev);
if (ret)
return ret;
- } else {
- if (uclass_get_device_by_of_offset(UCLASS_TIMER, node, &dev)) {
- /*
- * If the timer is not marked to be bound before
- * relocation, bind it anyway.
- */
- if (node > 0 &&
- !lists_bind_fdt(gd->dm_root, offset_to_ofnode(node),
- &dev)) {
- ret = device_probe(dev);
- if (ret)
- return ret;
- }
- }
}
if (dev) {
diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig
index 62126aad2f..e7658b4d95 100644
--- a/drivers/usb/Kconfig
+++ b/drivers/usb/Kconfig
@@ -75,7 +75,7 @@ if USB_KEYBOARD
choice
prompt "USB keyboard polling"
- optional
+ default SYS_USB_EVENT_POLL
---help---
Enable a polling mechanism for USB keyboard.
diff --git a/drivers/usb/gadget/dwc2_udc_otg_xfer_dma.c b/drivers/usb/gadget/dwc2_udc_otg_xfer_dma.c
index 0d6d2fba8a..b6164afa92 100644
--- a/drivers/usb/gadget/dwc2_udc_otg_xfer_dma.c
+++ b/drivers/usb/gadget/dwc2_udc_otg_xfer_dma.c
@@ -111,7 +111,8 @@ static int setdma_rx(struct dwc2_ep *ep, struct dwc2_request *req)
ctrl = readl(&reg->out_endp[ep_num].doepctl);
invalidate_dcache_range((unsigned long) ep->dma_buf,
- (unsigned long) ep->dma_buf + ep->len);
+ (unsigned long) ep->dma_buf +
+ ROUND(ep->len, CONFIG_SYS_CACHELINE_SIZE));
writel((unsigned int) ep->dma_buf, &reg->out_endp[ep_num].doepdma);
writel(DOEPT_SIZ_PKT_CNT(pktcnt) | DOEPT_SIZ_XFER_SIZE(length),
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index eb035a476b..f797a2568c 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -47,6 +47,15 @@ config USB_XHCI_ROCKCHIP
help
Enables support for the on-chip xHCI controller on Rockchip SoCs.
+config USB_XHCI_STI
+ bool "Support for STMicroelectronics STiH407 family on-chip xHCI USB controller"
+ depends on ARCH_STI
+ default y
+ help
+ Enables support for the on-chip xHCI controller on STMicroelectronics
+ STiH407 family SoCs. This is a driver for the dwc3 to provide the glue logic
+ to configure the controller.
+
config USB_XHCI_ZYNQMP
bool "Support for Xilinx ZynqMP on-chip xHCI USB controller"
depends on ARCH_ZYNQMP
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index ab5a99faa8..29afb7cf1d 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -60,6 +60,7 @@ obj-$(CONFIG_USB_XHCI_FSL) += xhci-fsl.o
obj-$(CONFIG_USB_XHCI_MVEBU) += xhci-mvebu.o
obj-$(CONFIG_USB_XHCI_OMAP) += xhci-omap.o
obj-$(CONFIG_USB_XHCI_PCI) += xhci-pci.o
+obj-$(CONFIG_USB_XHCI_STI) += dwc3-sti-glue.o
# designware
obj-$(CONFIG_USB_DWC2) += dwc2.o
diff --git a/drivers/usb/host/dwc2.c b/drivers/usb/host/dwc2.c
index 64c42ac471..0ed72d5ae7 100644
--- a/drivers/usb/host/dwc2.c
+++ b/drivers/usb/host/dwc2.c
@@ -1245,7 +1245,7 @@ static int dwc2_usb_ofdata_to_platdata(struct udevice *dev)
struct dwc2_priv *priv = dev_get_priv(dev);
fdt_addr_t addr;
- addr = devfdt_get_addr(dev);
+ addr = dev_read_addr(dev);
if (addr == FDT_ADDR_T_NONE)
return -EINVAL;
priv->regs = (struct dwc2_core_regs *)addr;
diff --git a/drivers/usb/host/dwc3-sti-glue.c b/drivers/usb/host/dwc3-sti-glue.c
new file mode 100644
index 0000000000..02ad3115df
--- /dev/null
+++ b/drivers/usb/host/dwc3-sti-glue.c
@@ -0,0 +1,257 @@
+/*
+ * STiH407 family DWC3 specific Glue layer
+ *
+ * Copyright (c) 2017
+ * Patrice Chotard <patrice.chotard@st.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <dm.h>
+#include <errno.h>
+#include <fdtdec.h>
+#include <libfdt.h>
+#include <dm/lists.h>
+#include <regmap.h>
+#include <reset-uclass.h>
+#include <syscon.h>
+#include <usb.h>
+
+#include <linux/usb/dwc3.h>
+#include <linux/usb/otg.h>
+#include <dwc3-sti-glue.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/*
+ * struct sti_dwc3_glue_platdata - dwc3 STi glue driver private structure
+ * @syscfg_base: addr for the glue syscfg
+ * @glue_base: addr for the glue registers
+ * @syscfg_offset: usb syscfg control offset
+ * @powerdown_ctl: rest controller for powerdown signal
+ * @softreset_ctl: reset controller for softreset signal
+ * @mode: drd static host/device config
+ */
+struct sti_dwc3_glue_platdata {
+ phys_addr_t syscfg_base;
+ phys_addr_t glue_base;
+ phys_addr_t syscfg_offset;
+ struct reset_ctl powerdown_ctl;
+ struct reset_ctl softreset_ctl;
+ enum usb_dr_mode mode;
+};
+
+static int sti_dwc3_glue_drd_init(struct sti_dwc3_glue_platdata *plat)
+{
+ unsigned long val;
+
+ val = readl(plat->syscfg_base + plat->syscfg_offset);
+
+ val &= USB3_CONTROL_MASK;
+
+ switch (plat->mode) {
+ case USB_DR_MODE_PERIPHERAL:
+ val &= ~(USB3_DELAY_VBUSVALID
+ | USB3_SEL_FORCE_OPMODE | USB3_FORCE_OPMODE(0x3)
+ | USB3_SEL_FORCE_DPPULLDOWN2 | USB3_FORCE_DPPULLDOWN2
+ | USB3_SEL_FORCE_DMPULLDOWN2 | USB3_FORCE_DMPULLDOWN2);
+
+ val |= USB3_DEVICE_NOT_HOST | USB3_FORCE_VBUSVALID;
+ break;
+
+ case USB_DR_MODE_HOST:
+ val &= ~(USB3_DEVICE_NOT_HOST | USB3_FORCE_VBUSVALID
+ | USB3_SEL_FORCE_OPMODE | USB3_FORCE_OPMODE(0x3)
+ | USB3_SEL_FORCE_DPPULLDOWN2 | USB3_FORCE_DPPULLDOWN2
+ | USB3_SEL_FORCE_DMPULLDOWN2 | USB3_FORCE_DMPULLDOWN2);
+
+ val |= USB3_DELAY_VBUSVALID;
+ break;
+
+ default:
+ error("Unsupported mode of operation %d\n", plat->mode);
+ return -EINVAL;
+ }
+ writel(val, plat->syscfg_base + plat->syscfg_offset);
+
+ return 0;
+}
+
+static void sti_dwc3_glue_init(struct sti_dwc3_glue_platdata *plat)
+{
+ unsigned long reg;
+
+ reg = readl(plat->glue_base + CLKRST_CTRL);
+
+ reg |= AUX_CLK_EN | EXT_CFG_RESET_N | XHCI_REVISION;
+ reg &= ~SW_PIPEW_RESET_N;
+
+ writel(reg, plat->glue_base + CLKRST_CTRL);
+
+ /* configure mux for vbus, powerpresent and bvalid signals */
+ reg = readl(plat->glue_base + USB2_VBUS_MNGMNT_SEL1);
+
+ reg |= SEL_OVERRIDE_VBUSVALID(USB2_VBUS_UTMIOTG) |
+ SEL_OVERRIDE_POWERPRESENT(USB2_VBUS_UTMIOTG) |
+ SEL_OVERRIDE_BVALID(USB2_VBUS_UTMIOTG);
+
+ writel(reg, plat->glue_base + USB2_VBUS_MNGMNT_SEL1);
+
+ setbits_le32(plat->glue_base + CLKRST_CTRL, SW_PIPEW_RESET_N);
+}
+
+static int sti_dwc3_glue_ofdata_to_platdata(struct udevice *dev)
+{
+ struct sti_dwc3_glue_platdata *plat = dev_get_platdata(dev);
+ struct udevice *syscon;
+ struct regmap *regmap;
+ int ret;
+ u32 reg[4];
+
+ ret = fdtdec_get_int_array(gd->fdt_blob, dev_of_offset(dev),
+ "reg", reg, ARRAY_SIZE(reg));
+ if (ret) {
+ error("unable to find st,stih407-dwc3 reg property(%d)\n", ret);
+ return ret;
+ }
+
+ plat->glue_base = reg[0];
+ plat->syscfg_offset = reg[2];
+
+ /* get corresponding syscon phandle */
+ ret = uclass_get_device_by_phandle(UCLASS_SYSCON, dev, "st,syscfg",
+ &syscon);
+ if (ret) {
+ error("unable to find syscon device (%d)\n", ret);
+ return ret;
+ }
+
+ /* get syscfg-reg base address */
+ regmap = syscon_get_regmap(syscon);
+ if (!regmap) {
+ error("unable to find regmap\n");
+ return -ENODEV;
+ }
+ plat->syscfg_base = regmap->base;
+
+ /* get powerdown reset */
+ ret = reset_get_by_name(dev, "powerdown", &plat->powerdown_ctl);
+ if (ret) {
+ error("can't get powerdown reset for %s (%d)", dev->name, ret);
+ return ret;
+ }
+
+ /* get softreset reset */
+ ret = reset_get_by_name(dev, "softreset", &plat->softreset_ctl);
+ if (ret)
+ error("can't get soft reset for %s (%d)", dev->name, ret);
+
+ return ret;
+};
+
+static int sti_dwc3_glue_bind(struct udevice *dev)
+{
+ struct sti_dwc3_glue_platdata *plat = dev_get_platdata(dev);
+ int dwc3_node;
+
+ /* check if one subnode is present */
+ dwc3_node = fdt_first_subnode(gd->fdt_blob, dev_of_offset(dev));
+ if (dwc3_node <= 0) {
+ error("Can't find subnode for %s\n", dev->name);
+ return -ENODEV;
+ }
+
+ /* check if the subnode compatible string is the dwc3 one*/
+ if (fdt_node_check_compatible(gd->fdt_blob, dwc3_node,
+ "snps,dwc3") != 0) {
+ error("Can't find dwc3 subnode for %s\n", dev->name);
+ return -ENODEV;
+ }
+
+ /* retrieve the DWC3 dual role mode */
+ plat->mode = usb_get_dr_mode(dwc3_node);
+ if (plat->mode == USB_DR_MODE_UNKNOWN)
+ /* by default set dual role mode to HOST */
+ plat->mode = USB_DR_MODE_HOST;
+
+ return dm_scan_fdt_dev(dev);
+}
+
+static int sti_dwc3_glue_probe(struct udevice *dev)
+{
+ struct sti_dwc3_glue_platdata *plat = dev_get_platdata(dev);
+ int ret;
+
+ /* deassert both powerdown and softreset */
+ ret = reset_deassert(&plat->powerdown_ctl);
+ if (ret < 0) {
+ error("DWC3 powerdown reset deassert failed: %d", ret);
+ return ret;
+ }
+
+ ret = reset_deassert(&plat->softreset_ctl);
+ if (ret < 0) {
+ error("DWC3 soft reset deassert failed: %d", ret);
+ goto softreset_err;
+ }
+
+ ret = sti_dwc3_glue_drd_init(plat);
+ if (ret)
+ goto init_err;
+
+ sti_dwc3_glue_init(plat);
+
+ return 0;
+
+init_err:
+ ret = reset_assert(&plat->softreset_ctl);
+ if (ret < 0) {
+ error("DWC3 soft reset deassert failed: %d", ret);
+ return ret;
+ }
+
+softreset_err:
+ ret = reset_assert(&plat->powerdown_ctl);
+ if (ret < 0)
+ error("DWC3 powerdown reset deassert failed: %d", ret);
+
+ return ret;
+}
+
+static int sti_dwc3_glue_remove(struct udevice *dev)
+{
+ struct sti_dwc3_glue_platdata *plat = dev_get_platdata(dev);
+ int ret;
+
+ /* assert both powerdown and softreset */
+ ret = reset_assert(&plat->powerdown_ctl);
+ if (ret < 0) {
+ error("DWC3 powerdown reset deassert failed: %d", ret);
+ return ret;
+ }
+
+ ret = reset_assert(&plat->softreset_ctl);
+ if (ret < 0)
+ error("DWC3 soft reset deassert failed: %d", ret);
+
+ return ret;
+}
+
+static const struct udevice_id sti_dwc3_glue_ids[] = {
+ { .compatible = "st,stih407-dwc3" },
+ { }
+};
+
+U_BOOT_DRIVER(dwc3_sti_glue) = {
+ .name = "dwc3_sti_glue",
+ .id = UCLASS_MISC,
+ .of_match = sti_dwc3_glue_ids,
+ .ofdata_to_platdata = sti_dwc3_glue_ofdata_to_platdata,
+ .probe = sti_dwc3_glue_probe,
+ .remove = sti_dwc3_glue_remove,
+ .bind = sti_dwc3_glue_bind,
+ .platdata_auto_alloc_size = sizeof(struct sti_dwc3_glue_platdata),
+ .flags = DM_FLAG_ALLOC_PRIV_DMA,
+};
diff --git a/drivers/usb/host/ehci-generic.c b/drivers/usb/host/ehci-generic.c
index 03f8d321af..18e1e0ee88 100644
--- a/drivers/usb/host/ehci-generic.c
+++ b/drivers/usb/host/ehci-generic.c
@@ -108,7 +108,7 @@ static int ehci_usb_probe(struct udevice *dev)
}
}
- hccr = map_physmem(devfdt_get_addr(dev), 0x100, MAP_NOCACHE);
+ hccr = map_physmem(dev_read_addr(dev), 0x100, MAP_NOCACHE);
hcor = (struct ehci_hcor *)((uintptr_t)hccr +
HC_LENGTH(ehci_readl(&hccr->cr_capbase)));
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 3243c1d1cf..be3e842dcc 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -1596,6 +1596,17 @@ static int ehci_destroy_int_queue(struct udevice *dev, struct usb_device *udev,
return _ehci_destroy_int_queue(udev, queue);
}
+static int ehci_get_max_xfer_size(struct udevice *dev, size_t *size)
+{
+ /*
+ * EHCD can handle any transfer length as long as there is enough
+ * free heap space left, hence set the theoretical max number here.
+ */
+ *size = SIZE_MAX;
+
+ return 0;
+}
+
int ehci_register(struct udevice *dev, struct ehci_hccr *hccr,
struct ehci_hcor *hcor, const struct ehci_ops *ops,
uint tweaks, enum usb_init_type init)
@@ -1658,6 +1669,7 @@ struct dm_usb_ops ehci_usb_ops = {
.create_int_queue = ehci_create_int_queue,
.poll_int_queue = ehci_poll_int_queue,
.destroy_int_queue = ehci_destroy_int_queue,
+ .get_max_xfer_size = ehci_get_max_xfer_size,
};
#endif
diff --git a/drivers/usb/host/usb-uclass.c b/drivers/usb/host/usb-uclass.c
index 0b8a501ce8..bc44fc3394 100644
--- a/drivers/usb/host/usb-uclass.c
+++ b/drivers/usb/host/usb-uclass.c
@@ -150,6 +150,17 @@ int usb_update_hub_device(struct usb_device *udev)
return ops->update_hub_device(bus, udev);
}
+int usb_get_max_xfer_size(struct usb_device *udev, size_t *size)
+{
+ struct udevice *bus = udev->controller_dev;
+ struct dm_usb_ops *ops = usb_get_ops(bus);
+
+ if (!ops->get_max_xfer_size)
+ return -ENOSYS;
+
+ return ops->get_max_xfer_size(bus, size);
+}
+
int usb_stop(void)
{
struct udevice *bus;
diff --git a/drivers/usb/host/xhci-rockchip.c b/drivers/usb/host/xhci-rockchip.c
index ec55f4e59f..ca3abffba0 100644
--- a/drivers/usb/host/xhci-rockchip.c
+++ b/drivers/usb/host/xhci-rockchip.c
@@ -6,8 +6,6 @@
*/
#include <common.h>
#include <dm.h>
-#include <fdtdec.h>
-#include <libfdt.h>
#include <malloc.h>
#include <usb.h>
#include <watchdog.h>
@@ -46,7 +44,7 @@ static int xhci_usb_ofdata_to_platdata(struct udevice *dev)
/*
* Get the base address for XHCI controller from the device node
*/
- plat->hcd_base = devfdt_get_addr(dev);
+ plat->hcd_base = dev_read_addr(dev);
if (plat->hcd_base == FDT_ADDR_T_NONE) {
error("Can't get the XHCI register base address\n");
return -ENXIO;
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 9b82ee5c60..04eb1eb14d 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -1228,6 +1228,20 @@ static int xhci_update_hub_device(struct udevice *dev, struct usb_device *udev)
return xhci_configure_endpoints(udev, false);
}
+static int xhci_get_max_xfer_size(struct udevice *dev, size_t *size)
+{
+ /*
+ * xHCD allocates one segment which includes 64 TRBs for each endpoint
+ * and the last TRB in this segment is configured as a link TRB to form
+ * a TRB ring. Each TRB can transfer up to 64K bytes, however data
+ * buffers referenced by transfer TRBs shall not span 64KB boundaries.
+ * Hence the maximum number of TRBs we can use in one transfer is 62.
+ */
+ *size = (TRBS_PER_SEGMENT - 2) * TRB_MAX_BUFF_SIZE;
+
+ return 0;
+}
+
int xhci_register(struct udevice *dev, struct xhci_hccr *hccr,
struct xhci_hcor *hcor)
{
@@ -1281,6 +1295,7 @@ struct dm_usb_ops xhci_usb_ops = {
.interrupt = xhci_submit_int_msg,
.alloc_device = xhci_alloc_device,
.update_hub_device = xhci_update_hub_device,
+ .get_max_xfer_size = xhci_get_max_xfer_size,
};
#endif
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index a497d9d830..3377450fca 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1045,9 +1045,9 @@ struct xhci_scratchpad {
* (1K bytes * 8bytes/bit) / (4*32 bits) = 64 segment entries in the table,
* meaning 64 ring segments.
* Initial allocated size of the ERST, in number of entries */
-#define ERST_NUM_SEGS 3
+#define ERST_NUM_SEGS 1
/* Initial number of event segment rings allocated */
-#define ERST_ENTRIES 3
+#define ERST_ENTRIES 1
/* Initial allocated size of the ERST, in number of entries */
#define ERST_SIZE 64
/* Poll every 60 seconds */
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 082cc4a528..7ba7b580db 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -14,6 +14,27 @@ config DM_VIDEO
option compiles in the video uclass and routes all LCD/video access
through this.
+config BACKLIGHT_PWM
+ bool "Generic PWM based Backlight Driver"
+ depends on DM_VIDEO && DM_PWM
+ default y
+ help
+ If you have a LCD backlight adjustable by PWM, say Y to enable
+ this driver.
+ This driver can be use with "simple-panel" and
+ it understands the standard device tree
+ (leds/backlight/pwm-backlight.txt)
+
+config BACKLIGHT_GPIO
+ bool "Generic GPIO based Backlight Driver"
+ depends on DM_VIDEO
+ help
+ If you have a LCD backlight adjustable by GPIO, say Y to enable
+ this driver.
+ This driver can be used with "simple-panel" and
+ it understands the standard device tree
+ (leds/backlight/gpio-backlight.txt)
+
config VIDEO_BPP8
bool "Support 8-bit-per-pixel displays"
depends on DM_VIDEO
@@ -98,6 +119,14 @@ config SYS_WHITE_ON_BLACK
better in low-light situations or to reduce eye strain in some
cases.
+config NO_FB_CLEAR
+ bool "Skip framebuffer clear"
+ help
+ If firmware (whatever loads u-boot) has already put a splash image
+ on screen, you might want to preserve it until whatever u-boot
+ loads takes over the screen. This, for example, can be used to
+ keep splash image on screen until grub graphical boot menu starts.
+
source "drivers/video/fonts/Kconfig"
config VIDCONSOLE_AS_LCD
@@ -436,6 +465,8 @@ config VIDEO_SANDBOX_SDL
console device and can display stdout output. Within U-Boot is is
a normal bitmap display and can display images as well as text.
+source "drivers/video/stm32/Kconfig"
+
config VIDEO_TEGRA20
bool "Enable LCD support on Tegra20"
depends on OF_CONTROL
@@ -601,4 +632,14 @@ config VIDEO_DW_HDMI
rather requires a SoC-specific glue driver to call it), it
can not be enabled from the configuration menu.
+config VIDEO_SIMPLE
+ bool "Simple display driver for preconfigured display"
+ help
+ Enables a simple generic display driver which utilizes the
+ simple-framebuffer devicetree bindings.
+
+ This driver assumes that the display hardware has been initialized
+ before u-boot starts, and u-boot will simply render to the pre-
+ allocated frame buffer surface.
+
endmenu
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 5cf8909295..dfafe08fc5 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -11,9 +11,8 @@ obj-$(CONFIG_DM_VIDEO) += backlight-uclass.o
obj-$(CONFIG_DM_VIDEO) += panel-uclass.o simple_panel.o
obj-$(CONFIG_DM_VIDEO) += video-uclass.o vidconsole-uclass.o
obj-$(CONFIG_DM_VIDEO) += video_bmp.o
-ifdef CONFIG_DM_VIDEO
-obj-$(CONFIG_DM_PWM) += pwm_backlight.o
-endif
+obj-$(CONFIG_BACKLIGHT_PWM) += pwm_backlight.o
+obj-$(CONFIG_BACKLIGHT_GPIO) += backlight_gpio.o
obj-$(CONFIG_CONSOLE_NORMAL) += console_normal.o
obj-$(CONFIG_CONSOLE_ROTATION) += console_rotate.o
obj-$(CONFIG_CONSOLE_TRUETYPE) += console_truetype.o fonts/
@@ -53,10 +52,11 @@ obj-$(CONFIG_FORMIKE) += formike.o
obj-$(CONFIG_LG4573) += lg4573.o
obj-$(CONFIG_AM335X_LCD) += am335x-fb.o
obj-$(CONFIG_VIDEO_DW_HDMI) += dw_hdmi.o
-
+obj-$(CONFIG_VIDEO_SIMPLE) += simplefb.o
obj-${CONFIG_VIDEO_TEGRA124} += tegra124/
obj-${CONFIG_EXYNOS_FB} += exynos/
obj-${CONFIG_VIDEO_ROCKCHIP} += rockchip/
+obj-${CONFIG_VIDEO_STM32} += stm32/
obj-y += bridge/
obj-y += sunxi/
diff --git a/drivers/video/backlight_gpio.c b/drivers/video/backlight_gpio.c
new file mode 100644
index 0000000000..772df5d302
--- /dev/null
+++ b/drivers/video/backlight_gpio.c
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2017, STMicroelectronics - All Rights Reserved
+ * Author: Patrick Delaunay <patrick.delaunay@st.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <backlight.h>
+#include <asm/gpio.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct gpio_backlight_priv {
+ struct gpio_desc gpio;
+ bool def_value;
+};
+
+static int gpio_backlight_enable(struct udevice *dev)
+{
+ struct gpio_backlight_priv *priv = dev_get_priv(dev);
+
+ dm_gpio_set_value(&priv->gpio, 1);
+
+ return 0;
+}
+
+static int gpio_backlight_ofdata_to_platdata(struct udevice *dev)
+{
+ struct gpio_backlight_priv *priv = dev_get_priv(dev);
+ int ret;
+
+ ret = gpio_request_by_name(dev, "gpios", 0, &priv->gpio,
+ GPIOD_IS_OUT);
+ if (ret) {
+ debug("%s: Warning: cannot get GPIO: ret=%d\n",
+ __func__, ret);
+ return ret;
+ }
+
+ priv->def_value = dev_read_bool(dev, "default-on");
+
+ return 0;
+}
+
+static int gpio_backlight_probe(struct udevice *dev)
+{
+ struct gpio_backlight_priv *priv = dev_get_priv(dev);
+
+ if (priv->def_value)
+ gpio_backlight_enable(dev);
+
+ return 0;
+}
+
+static const struct backlight_ops gpio_backlight_ops = {
+ .enable = gpio_backlight_enable,
+};
+
+static const struct udevice_id gpio_backlight_ids[] = {
+ { .compatible = "gpio-backlight" },
+ { }
+};
+
+U_BOOT_DRIVER(gpio_backlight) = {
+ .name = "gpio_backlight",
+ .id = UCLASS_PANEL_BACKLIGHT,
+ .of_match = gpio_backlight_ids,
+ .ops = &gpio_backlight_ops,
+ .ofdata_to_platdata = gpio_backlight_ofdata_to_platdata,
+ .probe = gpio_backlight_probe,
+ .priv_auto_alloc_size = sizeof(struct gpio_backlight_priv),
+};
diff --git a/drivers/video/cfb_console.c b/drivers/video/cfb_console.c
index 6c5425c195..74cc20d653 100644
--- a/drivers/video/cfb_console.c
+++ b/drivers/video/cfb_console.c
@@ -2081,7 +2081,8 @@ static int cfg_video_init(void)
}
eorx = fgx ^ bgx;
- video_clear();
+ if (!CONFIG_IS_ENABLED(NO_FB_CLEAR))
+ video_clear();
#ifdef CONFIG_VIDEO_LOGO
/* Plot the logo and get start point of console */
diff --git a/drivers/video/simplefb.c b/drivers/video/simplefb.c
new file mode 100644
index 0000000000..850a279d64
--- /dev/null
+++ b/drivers/video/simplefb.c
@@ -0,0 +1,73 @@
+/*
+ * (C) Copyright 2017 Rob Clark
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <fdtdec.h>
+#include <fdt_support.h>
+#include <video.h>
+
+static int simple_video_probe(struct udevice *dev)
+{
+ struct video_uc_platdata *plat = dev_get_uclass_platdata(dev);
+ struct video_priv *uc_priv = dev_get_uclass_priv(dev);
+ const void *blob = gd->fdt_blob;
+ const int node = dev_of_offset(dev);
+ const char *format;
+ fdt_addr_t base;
+ fdt_size_t size;
+
+ base = fdtdec_get_addr_size_auto_parent(blob, dev_of_offset(dev->parent),
+ node, "reg", 0, &size, false);
+ if (base == FDT_ADDR_T_NONE) {
+ debug("%s: Failed to decode memory region\n", __func__);
+ return -EINVAL;
+ }
+
+ debug("%s: base=%llx, size=%llu\n", __func__, base, size);
+
+ /*
+ * TODO is there some way to reserve the framebuffer
+ * region so it isn't clobbered?
+ */
+ plat->base = base;
+ plat->size = size;
+
+ video_set_flush_dcache(dev, true);
+
+ debug("%s: Query resolution...\n", __func__);
+
+ uc_priv->xsize = fdtdec_get_uint(blob, node, "width", 0);
+ uc_priv->ysize = fdtdec_get_uint(blob, node, "height", 0);
+ uc_priv->rot = 0;
+
+ format = fdt_getprop(blob, node, "format", NULL);
+ debug("%s: %dx%d@%s\n", __func__, uc_priv->xsize, uc_priv->ysize, format);
+
+ if (strcmp(format, "r5g6b5") == 0) {
+ uc_priv->bpix = VIDEO_BPP16;
+ } else if (strcmp(format, "a8b8g8r8") == 0) {
+ uc_priv->bpix = VIDEO_BPP32;
+ } else {
+ printf("%s: invalid format: %s\n", __func__, format);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static const struct udevice_id simple_video_ids[] = {
+ { .compatible = "simple-framebuffer" },
+ { }
+};
+
+U_BOOT_DRIVER(simple_video) = {
+ .name = "simple_video",
+ .id = UCLASS_VIDEO,
+ .of_match = simple_video_ids,
+ .probe = simple_video_probe,
+ .flags = DM_FLAG_PRE_RELOC,
+};
diff --git a/drivers/video/stm32/Kconfig b/drivers/video/stm32/Kconfig
new file mode 100644
index 0000000000..113a2bbb33
--- /dev/null
+++ b/drivers/video/stm32/Kconfig
@@ -0,0 +1,44 @@
+#
+# Copyright (C) STMicroelectronics SA 2017
+#
+# Authors: Philippe Cornu <philippe.cornu@st.com>
+# Yannick Fertre <yannick.fertre@st.com>
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+menuconfig VIDEO_STM32
+ bool "Enable STM32 video support"
+ depends on DM_VIDEO
+ help
+ STM32 supports many video output options including RGB and
+ DSI. This option enables these supports which can be used on
+ devices which have RGB TFT or DSI display connected.
+
+config VIDEO_STM32_MAX_XRES
+ int "Maximum horizontal resolution (for memory allocation purposes)"
+ depends on VIDEO_STM32
+ default 640
+ help
+ The maximum horizontal resolution to support for the framebuffer.
+ This configuration is used for reserving/allocating memory for the
+ framebuffer during device-model binding/probing.
+
+config VIDEO_STM32_MAX_YRES
+ int "Maximum vertical resolution (for memory allocation purposes)"
+ depends on VIDEO_STM32
+ default 480
+ help
+ The maximum vertical resolution to support for the framebuffer.
+ This configuration is used for reserving/allocating memory for the
+ framebuffer during device-model binding/probing.
+
+config VIDEO_STM32_MAX_BPP
+ int "Maximum bits per pixel (for memory allocation purposes)"
+ depends on VIDEO_STM32
+ default 16
+ help
+ The maximum bits per pixel to support for the framebuffer.
+ This configuration is used for reserving/allocating memory for the
+ framebuffer during device-model binding/probing.
+
diff --git a/drivers/video/stm32/Makefile b/drivers/video/stm32/Makefile
new file mode 100644
index 0000000000..372a2e10c6
--- /dev/null
+++ b/drivers/video/stm32/Makefile
@@ -0,0 +1,10 @@
+#
+# Copyright (C) STMicroelectronics SA 2017
+#
+# Authors: Philippe Cornu <philippe.cornu@st.com>
+# Yannick Fertre <yannick.fertre@st.com>
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+obj-${CONFIG_VIDEO_STM32} = stm32_ltdc.o
diff --git a/drivers/video/stm32/stm32_ltdc.c b/drivers/video/stm32/stm32_ltdc.c
new file mode 100644
index 0000000000..b417ac260a
--- /dev/null
+++ b/drivers/video/stm32/stm32_ltdc.c
@@ -0,0 +1,406 @@
+/*
+ * Copyright (C) STMicroelectronics SA 2017
+ *
+ * Authors: Philippe Cornu <philippe.cornu@st.com>
+ * Yannick Fertre <yannick.fertre@st.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <clk.h>
+#include <dm.h>
+#include <panel.h>
+#include <video.h>
+#include <asm/io.h>
+#include <asm/arch/gpio.h>
+#include <dm/device-internal.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct stm32_ltdc_priv {
+ void __iomem *regs;
+ struct display_timing timing;
+ enum video_log2_bpp l2bpp;
+ u32 bg_col_argb;
+ u32 crop_x, crop_y, crop_w, crop_h;
+ u32 alpha;
+};
+
+/* LTDC main registers */
+#define LTDC_IDR 0x00 /* IDentification */
+#define LTDC_LCR 0x04 /* Layer Count */
+#define LTDC_SSCR 0x08 /* Synchronization Size Configuration */
+#define LTDC_BPCR 0x0C /* Back Porch Configuration */
+#define LTDC_AWCR 0x10 /* Active Width Configuration */
+#define LTDC_TWCR 0x14 /* Total Width Configuration */
+#define LTDC_GCR 0x18 /* Global Control */
+#define LTDC_GC1R 0x1C /* Global Configuration 1 */
+#define LTDC_GC2R 0x20 /* Global Configuration 2 */
+#define LTDC_SRCR 0x24 /* Shadow Reload Configuration */
+#define LTDC_GACR 0x28 /* GAmma Correction */
+#define LTDC_BCCR 0x2C /* Background Color Configuration */
+#define LTDC_IER 0x34 /* Interrupt Enable */
+#define LTDC_ISR 0x38 /* Interrupt Status */
+#define LTDC_ICR 0x3C /* Interrupt Clear */
+#define LTDC_LIPCR 0x40 /* Line Interrupt Position Conf. */
+#define LTDC_CPSR 0x44 /* Current Position Status */
+#define LTDC_CDSR 0x48 /* Current Display Status */
+
+/* LTDC layer 1 registers */
+#define LTDC_L1LC1R 0x80 /* L1 Layer Configuration 1 */
+#define LTDC_L1LC2R 0x84 /* L1 Layer Configuration 2 */
+#define LTDC_L1CR 0x84 /* L1 Control */
+#define LTDC_L1WHPCR 0x88 /* L1 Window Hor Position Config */
+#define LTDC_L1WVPCR 0x8C /* L1 Window Vert Position Config */
+#define LTDC_L1CKCR 0x90 /* L1 Color Keying Configuration */
+#define LTDC_L1PFCR 0x94 /* L1 Pixel Format Configuration */
+#define LTDC_L1CACR 0x98 /* L1 Constant Alpha Config */
+#define LTDC_L1DCCR 0x9C /* L1 Default Color Configuration */
+#define LTDC_L1BFCR 0xA0 /* L1 Blend Factors Configuration */
+#define LTDC_L1FBBCR 0xA4 /* L1 FrameBuffer Bus Control */
+#define LTDC_L1AFBCR 0xA8 /* L1 AuxFB Control */
+#define LTDC_L1CFBAR 0xAC /* L1 Color FrameBuffer Address */
+#define LTDC_L1CFBLR 0xB0 /* L1 Color FrameBuffer Length */
+#define LTDC_L1CFBLNR 0xB4 /* L1 Color FrameBuffer Line Nb */
+#define LTDC_L1AFBAR 0xB8 /* L1 AuxFB Address */
+#define LTDC_L1AFBLR 0xBC /* L1 AuxFB Length */
+#define LTDC_L1AFBLNR 0xC0 /* L1 AuxFB Line Number */
+#define LTDC_L1CLUTWR 0xC4 /* L1 CLUT Write */
+
+/* Bit definitions */
+#define SSCR_VSH GENMASK(10, 0) /* Vertical Synchronization Height */
+#define SSCR_HSW GENMASK(27, 16) /* Horizontal Synchronization Width */
+
+#define BPCR_AVBP GENMASK(10, 0) /* Accumulated Vertical Back Porch */
+#define BPCR_AHBP GENMASK(27, 16) /* Accumulated Horizontal Back Porch */
+
+#define AWCR_AAH GENMASK(10, 0) /* Accumulated Active Height */
+#define AWCR_AAW GENMASK(27, 16) /* Accumulated Active Width */
+
+#define TWCR_TOTALH GENMASK(10, 0) /* TOTAL Height */
+#define TWCR_TOTALW GENMASK(27, 16) /* TOTAL Width */
+
+#define GCR_LTDCEN BIT(0) /* LTDC ENable */
+#define GCR_DEN BIT(16) /* Dither ENable */
+#define GCR_PCPOL BIT(28) /* Pixel Clock POLarity-Inverted */
+#define GCR_DEPOL BIT(29) /* Data Enable POLarity-High */
+#define GCR_VSPOL BIT(30) /* Vertical Synchro POLarity-High */
+#define GCR_HSPOL BIT(31) /* Horizontal Synchro POLarity-High */
+
+#define GC1R_WBCH GENMASK(3, 0) /* Width of Blue CHannel output */
+#define GC1R_WGCH GENMASK(7, 4) /* Width of Green Channel output */
+#define GC1R_WRCH GENMASK(11, 8) /* Width of Red Channel output */
+#define GC1R_PBEN BIT(12) /* Precise Blending ENable */
+#define GC1R_DT GENMASK(15, 14) /* Dithering Technique */
+#define GC1R_GCT GENMASK(19, 17) /* Gamma Correction Technique */
+#define GC1R_SHREN BIT(21) /* SHadow Registers ENabled */
+#define GC1R_BCP BIT(22) /* Background Colour Programmable */
+#define GC1R_BBEN BIT(23) /* Background Blending ENabled */
+#define GC1R_LNIP BIT(24) /* Line Number IRQ Position */
+#define GC1R_TP BIT(25) /* Timing Programmable */
+#define GC1R_IPP BIT(26) /* IRQ Polarity Programmable */
+#define GC1R_SPP BIT(27) /* Sync Polarity Programmable */
+#define GC1R_DWP BIT(28) /* Dither Width Programmable */
+#define GC1R_STREN BIT(29) /* STatus Registers ENabled */
+#define GC1R_BMEN BIT(31) /* Blind Mode ENabled */
+
+#define GC2R_EDCA BIT(0) /* External Display Control Ability */
+#define GC2R_STSAEN BIT(1) /* Slave Timing Sync Ability ENabled */
+#define GC2R_DVAEN BIT(2) /* Dual-View Ability ENabled */
+#define GC2R_DPAEN BIT(3) /* Dual-Port Ability ENabled */
+#define GC2R_BW GENMASK(6, 4) /* Bus Width (log2 of nb of bytes) */
+#define GC2R_EDCEN BIT(7) /* External Display Control ENabled */
+
+#define SRCR_IMR BIT(0) /* IMmediate Reload */
+#define SRCR_VBR BIT(1) /* Vertical Blanking Reload */
+
+#define LXCR_LEN BIT(0) /* Layer ENable */
+#define LXCR_COLKEN BIT(1) /* Color Keying Enable */
+#define LXCR_CLUTEN BIT(4) /* Color Look-Up Table ENable */
+
+#define LXWHPCR_WHSTPOS GENMASK(11, 0) /* Window Horizontal StarT POSition */
+#define LXWHPCR_WHSPPOS GENMASK(27, 16) /* Window Horizontal StoP POSition */
+
+#define LXWVPCR_WVSTPOS GENMASK(10, 0) /* Window Vertical StarT POSition */
+#define LXWVPCR_WVSPPOS GENMASK(26, 16) /* Window Vertical StoP POSition */
+
+#define LXPFCR_PF GENMASK(2, 0) /* Pixel Format */
+
+#define LXCACR_CONSTA GENMASK(7, 0) /* CONSTant Alpha */
+
+#define LXBFCR_BF2 GENMASK(2, 0) /* Blending Factor 2 */
+#define LXBFCR_BF1 GENMASK(10, 8) /* Blending Factor 1 */
+
+#define LXCFBLR_CFBLL GENMASK(12, 0) /* Color Frame Buffer Line Length */
+#define LXCFBLR_CFBP GENMASK(28, 16) /* Color Frame Buffer Pitch in bytes */
+
+#define LXCFBLNR_CFBLN GENMASK(10, 0) /* Color Frame Buffer Line Number */
+
+#define BF1_PAXCA 0x600 /* Pixel Alpha x Constant Alpha */
+#define BF2_1PAXCA 0x007 /* 1 - (Pixel Alpha x Constant Alpha) */
+
+enum stm32_ltdc_pix_fmt {
+ PF_ARGB8888 = 0,
+ PF_RGB888,
+ PF_RGB565,
+ PF_ARGB1555,
+ PF_ARGB4444,
+ PF_L8,
+ PF_AL44,
+ PF_AL88
+};
+
+/* TODO add more color format support */
+static u32 stm32_ltdc_get_pixel_format(enum video_log2_bpp l2bpp)
+{
+ enum stm32_ltdc_pix_fmt pf;
+
+ switch (l2bpp) {
+ case VIDEO_BPP16:
+ pf = PF_RGB565;
+ break;
+
+ case VIDEO_BPP1:
+ case VIDEO_BPP2:
+ case VIDEO_BPP4:
+ case VIDEO_BPP8:
+ case VIDEO_BPP32:
+ default:
+ debug("%s: warning %dbpp not supported yet, %dbpp instead\n",
+ __func__, VNBITS(l2bpp), VNBITS(VIDEO_BPP16));
+ pf = PF_RGB565;
+ break;
+ }
+
+ debug("%s: %d bpp -> ltdc pf %d\n", __func__, VNBITS(l2bpp), pf);
+
+ return (u32)pf;
+}
+
+static void stm32_ltdc_enable(struct stm32_ltdc_priv *priv)
+{
+ /* Reload configuration immediately & enable LTDC */
+ setbits_le32(priv->regs + LTDC_SRCR, SRCR_IMR);
+ setbits_le32(priv->regs + LTDC_GCR, GCR_LTDCEN);
+}
+
+static void stm32_ltdc_set_mode(struct stm32_ltdc_priv *priv)
+{
+ void __iomem *regs = priv->regs;
+ struct display_timing *timing = &priv->timing;
+ u32 hsync, vsync, acc_hbp, acc_vbp, acc_act_w, acc_act_h;
+ u32 total_w, total_h;
+ u32 val;
+
+ /* Convert video timings to ltdc timings */
+ hsync = timing->hsync_len.typ - 1;
+ vsync = timing->vsync_len.typ - 1;
+ acc_hbp = hsync + timing->hback_porch.typ;
+ acc_vbp = vsync + timing->vback_porch.typ;
+ acc_act_w = acc_hbp + timing->hactive.typ;
+ acc_act_h = acc_vbp + timing->vactive.typ;
+ total_w = acc_act_w + timing->hfront_porch.typ;
+ total_h = acc_act_h + timing->vfront_porch.typ;
+
+ /* Synchronization sizes */
+ val = (hsync << 16) | vsync;
+ clrsetbits_le32(regs + LTDC_SSCR, SSCR_VSH | SSCR_HSW, val);
+
+ /* Accumulated back porch */
+ val = (acc_hbp << 16) | acc_vbp;
+ clrsetbits_le32(regs + LTDC_BPCR, BPCR_AVBP | BPCR_AHBP, val);
+
+ /* Accumulated active width */
+ val = (acc_act_w << 16) | acc_act_h;
+ clrsetbits_le32(regs + LTDC_AWCR, AWCR_AAW | AWCR_AAH, val);
+
+ /* Total width & height */
+ val = (total_w << 16) | total_h;
+ clrsetbits_le32(regs + LTDC_TWCR, TWCR_TOTALH | TWCR_TOTALW, val);
+
+ /* Signal polarities */
+ val = 0;
+ debug("%s: timing->flags 0x%08x\n", __func__, timing->flags);
+ if (timing->flags & DISPLAY_FLAGS_HSYNC_HIGH)
+ val |= GCR_HSPOL;
+ if (timing->flags & DISPLAY_FLAGS_VSYNC_HIGH)
+ val |= GCR_VSPOL;
+ if (timing->flags & DISPLAY_FLAGS_DE_HIGH)
+ val |= GCR_DEPOL;
+ if (timing->flags & DISPLAY_FLAGS_PIXDATA_NEGEDGE)
+ val |= GCR_PCPOL;
+ clrsetbits_le32(regs + LTDC_GCR,
+ GCR_HSPOL | GCR_VSPOL | GCR_DEPOL | GCR_PCPOL, val);
+
+ /* Overall background color */
+ writel(priv->bg_col_argb, priv->regs + LTDC_BCCR);
+}
+
+static void stm32_ltdc_set_layer1(struct stm32_ltdc_priv *priv, ulong fb_addr)
+{
+ void __iomem *regs = priv->regs;
+ u32 x0, x1, y0, y1;
+ u32 pitch_in_bytes;
+ u32 line_length;
+ u32 bus_width;
+ u32 val, tmp, bpp;
+
+ x0 = priv->crop_x;
+ x1 = priv->crop_x + priv->crop_w - 1;
+ y0 = priv->crop_y;
+ y1 = priv->crop_y + priv->crop_h - 1;
+
+ /* Horizontal start and stop position */
+ tmp = (readl(regs + LTDC_BPCR) & BPCR_AHBP) >> 16;
+ val = ((x1 + 1 + tmp) << 16) + (x0 + 1 + tmp);
+ clrsetbits_le32(regs + LTDC_L1WHPCR, LXWHPCR_WHSTPOS | LXWHPCR_WHSPPOS,
+ val);
+
+ /* Vertical start & stop position */
+ tmp = readl(regs + LTDC_BPCR) & BPCR_AVBP;
+ val = ((y1 + 1 + tmp) << 16) + (y0 + 1 + tmp);
+ clrsetbits_le32(regs + LTDC_L1WVPCR, LXWVPCR_WVSTPOS | LXWVPCR_WVSPPOS,
+ val);
+
+ /* Layer background color */
+ writel(priv->bg_col_argb, regs + LTDC_L1DCCR);
+
+ /* Color frame buffer pitch in bytes & line length */
+ bpp = VNBITS(priv->l2bpp);
+ pitch_in_bytes = priv->crop_w * (bpp >> 3);
+ bus_width = 8 << ((readl(regs + LTDC_GC2R) & GC2R_BW) >> 4);
+ line_length = ((bpp >> 3) * priv->crop_w) + (bus_width >> 3) - 1;
+ val = (pitch_in_bytes << 16) | line_length;
+ clrsetbits_le32(regs + LTDC_L1CFBLR, LXCFBLR_CFBLL | LXCFBLR_CFBP, val);
+
+ /* Pixel format */
+ val = stm32_ltdc_get_pixel_format(priv->l2bpp);
+ clrsetbits_le32(regs + LTDC_L1PFCR, LXPFCR_PF, val);
+
+ /* Constant alpha value */
+ clrsetbits_le32(regs + LTDC_L1CACR, LXCACR_CONSTA, priv->alpha);
+
+ /* Blending factors */
+ clrsetbits_le32(regs + LTDC_L1BFCR, LXBFCR_BF2 | LXBFCR_BF1,
+ BF1_PAXCA | BF2_1PAXCA);
+
+ /* Frame buffer line number */
+ clrsetbits_le32(regs + LTDC_L1CFBLNR, LXCFBLNR_CFBLN, priv->crop_h);
+
+ /* Frame buffer address */
+ writel(fb_addr, regs + LTDC_L1CFBAR);
+
+ /* Enable layer 1 */
+ setbits_le32(priv->regs + LTDC_L1CR, LXCR_LEN);
+}
+
+static int stm32_ltdc_probe(struct udevice *dev)
+{
+ struct video_uc_platdata *uc_plat = dev_get_uclass_platdata(dev);
+ struct video_priv *uc_priv = dev_get_uclass_priv(dev);
+ struct stm32_ltdc_priv *priv = dev_get_priv(dev);
+ struct udevice *panel;
+ struct clk pclk, pxclk;
+ int ret;
+
+ priv->regs = (void *)dev_read_addr(dev);
+ if ((fdt_addr_t)priv->regs == FDT_ADDR_T_NONE) {
+ debug("%s: ltdc dt register address error\n", __func__);
+ return -EINVAL;
+ }
+
+ ret = uclass_first_device(UCLASS_PANEL, &panel);
+ if (ret) {
+ debug("%s: panel device error %d\n", __func__, ret);
+ return ret;
+ }
+
+ ret = panel_enable_backlight(panel);
+ if (ret) {
+ debug("%s: panel %s enable backlight error %d\n",
+ __func__, panel->name, ret);
+ return ret;
+ }
+
+ ret = fdtdec_decode_display_timing(gd->fdt_blob, dev_of_offset(dev),
+ 0, &priv->timing);
+ if (ret) {
+ debug("%s: decode display timing error %d\n", __func__, ret);
+ return -EINVAL;
+ }
+
+ ret = clk_get_by_name(dev, "pclk", &pclk);
+ if (ret) {
+ debug("%s: peripheral clock get error %d\n", __func__, ret);
+ return ret;
+ }
+
+ ret = clk_enable(&pclk);
+ if (ret) {
+ debug("%s: peripheral clock enable error %d\n", __func__, ret);
+ return ret;
+ }
+
+ /* Verify pixel clock value if any & inform user accordingly */
+ ret = clk_get_by_name(dev, "pxclk", &pxclk);
+ if (!ret) {
+ if (clk_get_rate(&pxclk) != priv->timing.pixelclock.typ)
+ printf("Warning: please adjust ltdc pixel clock\n");
+ }
+
+ /* TODO Below parameters are hard-coded for the moment... */
+ priv->l2bpp = VIDEO_BPP16;
+ priv->bg_col_argb = 0xFFFFFFFF; /* white no transparency */
+ priv->crop_x = 0;
+ priv->crop_y = 0;
+ priv->crop_w = priv->timing.hactive.typ;
+ priv->crop_h = priv->timing.vactive.typ;
+ priv->alpha = 0xFF;
+
+ debug("%s: %dx%d %dbpp frame buffer at 0x%lx\n", __func__,
+ priv->timing.hactive.typ, priv->timing.vactive.typ,
+ VNBITS(priv->l2bpp), uc_plat->base);
+ debug("%s: crop %d,%d %dx%d bg 0x%08x alpha %d\n", __func__,
+ priv->crop_x, priv->crop_y, priv->crop_w, priv->crop_h,
+ priv->bg_col_argb, priv->alpha);
+
+ /* Configure & start LTDC */
+ stm32_ltdc_set_mode(priv);
+ stm32_ltdc_set_layer1(priv, uc_plat->base);
+ stm32_ltdc_enable(priv);
+
+ uc_priv->xsize = priv->timing.hactive.typ;
+ uc_priv->ysize = priv->timing.vactive.typ;
+ uc_priv->bpix = priv->l2bpp;
+
+ video_set_flush_dcache(dev, true);
+
+ return 0;
+}
+
+static int stm32_ltdc_bind(struct udevice *dev)
+{
+ struct video_uc_platdata *uc_plat = dev_get_uclass_platdata(dev);
+
+ uc_plat->size = CONFIG_VIDEO_STM32_MAX_XRES *
+ CONFIG_VIDEO_STM32_MAX_YRES *
+ (CONFIG_VIDEO_STM32_MAX_BPP >> 3);
+ debug("%s: frame buffer max size %d bytes\n", __func__, uc_plat->size);
+
+ return 0;
+}
+
+static const struct udevice_id stm32_ltdc_ids[] = {
+ { .compatible = "st,stm32-ltdc" },
+ { }
+};
+
+U_BOOT_DRIVER(stm32_ltdc) = {
+ .name = "stm32_ltdc",
+ .id = UCLASS_VIDEO,
+ .of_match = stm32_ltdc_ids,
+ .probe = stm32_ltdc_probe,
+ .bind = stm32_ltdc_bind,
+ .priv_auto_alloc_size = sizeof(struct stm32_ltdc_priv),
+};
diff --git a/drivers/video/video-uclass.c b/drivers/video/video-uclass.c
index 3036e3a1f2..dfa39b0d1b 100644
--- a/drivers/video/video-uclass.c
+++ b/drivers/video/video-uclass.c
@@ -199,7 +199,9 @@ static int video_post_probe(struct udevice *dev)
#else
priv->colour_bg = 0xffffff;
#endif
- video_clear(dev);
+
+ if (!CONFIG_IS_ENABLED(NO_FB_CLEAR))
+ video_clear(dev);
/*
* Create a text console device. For now we always do this, although
diff --git a/dts/Kconfig b/dts/Kconfig
index b4b7ddc144..4ee0510943 100644
--- a/dts/Kconfig
+++ b/dts/Kconfig
@@ -5,11 +5,15 @@
config SUPPORT_OF_CONTROL
bool
+config DTC
+ bool
+
menu "Device Tree Control"
depends on SUPPORT_OF_CONTROL
config OF_CONTROL
bool "Run-time configuration via Device Tree"
+ select DTC
help
This feature provides for run-time configuration of U-Boot
via a flattened device tree.
@@ -166,3 +170,12 @@ config TPL_OF_PLATDATA
information.
endmenu
+
+config MKIMAGE_DTC_PATH
+ string "Path to dtc binary for use within mkimage"
+ default "dtc"
+ help
+ The mkimage host tool will, in order to generate FIT images make
+ calls to the dtc application in order to create the output. In
+ some cases the system dtc may not support all required features
+ and the path to a different version should be given here.
diff --git a/fs/fat/fat.c b/fs/fat/fat.c
index f0284398b4..36a309c73c 100644
--- a/fs/fat/fat.c
+++ b/fs/fat/fat.c
@@ -1034,24 +1034,27 @@ int file_fat_detectfs(void)
int fat_exists(const char *filename)
{
fsdata fsdata;
- fat_itr itrblock, *itr = &itrblock;
+ fat_itr *itr;
int ret;
+ itr = malloc(sizeof(fat_itr));
ret = fat_itr_root(itr, &fsdata);
if (ret)
return 0;
ret = fat_itr_resolve(itr, filename, TYPE_ANY);
free(fsdata.fatbuf);
+ free(itr);
return ret == 0;
}
int fat_size(const char *filename, loff_t *size)
{
fsdata fsdata;
- fat_itr itrblock, *itr = &itrblock;
+ fat_itr *itr;
int ret;
+ itr = malloc(sizeof(fat_itr));
ret = fat_itr_root(itr, &fsdata);
if (ret)
return ret;
@@ -1072,8 +1075,9 @@ int fat_size(const char *filename, loff_t *size)
}
*size = FAT2CPU32(itr->dent->size);
-out:
free(fsdata.fatbuf);
+out:
+ free(itr);
return ret;
}
@@ -1081,9 +1085,10 @@ int file_fat_read_at(const char *filename, loff_t pos, void *buffer,
loff_t maxsize, loff_t *actread)
{
fsdata fsdata;
- fat_itr itrblock, *itr = &itrblock;
+ fat_itr *itr;
int ret;
+ itr = malloc(sizeof(fat_itr));
ret = fat_itr_root(itr, &fsdata);
if (ret)
return ret;
@@ -1097,6 +1102,7 @@ int file_fat_read_at(const char *filename, loff_t pos, void *buffer,
out:
free(fsdata.fatbuf);
+ free(itr);
return ret;
}
diff --git a/include/configs/adp-ae3xx.h b/include/configs/adp-ae3xx.h
index f47e45b433..6946029333 100644
--- a/include/configs/adp-ae3xx.h
+++ b/include/configs/adp-ae3xx.h
@@ -23,8 +23,7 @@
#define CONFIG_CMDLINE_EDITING
#define CONFIG_PANIC_HANG
-#define CONFIG_SYS_ICACHE_OFF
-#define CONFIG_SYS_DCACHE_OFF
+#define CONFIG_ARCH_MAP_SYSMEM
#define CONFIG_BOOTP_SEND_HOSTNAME
#define CONFIG_BOOTP_SERVERIP
@@ -221,14 +220,25 @@
/* max number of sectors on one chip */
#define CONFIG_FLASH_SECTOR_SIZE (0x10000*2)
-#define CONFIG_ENV_SECT_SIZE CONFIG_FLASH_SECTOR_SIZE
#define CONFIG_SYS_MAX_FLASH_SECT 512
/* environments */
-#define CONFIG_ENV_ADDR (CONFIG_SYS_MONITOR_BASE + 0x140000)
+#define CONFIG_ENV_SPI_BUS 0
+#define CONFIG_ENV_SPI_CS 0
+#define CONFIG_ENV_SPI_MAX_HZ 50000000
+#define CONFIG_ENV_SPI_MODE 0
+#define CONFIG_ENV_SECT_SIZE 0x1000
+#define CONFIG_ENV_OFFSET 0x140000
#define CONFIG_ENV_SIZE 8192
#define CONFIG_ENV_OVERWRITE
+
+/* SPI FLASH */
+#define CONFIG_SF_DEFAULT_BUS 0
+#define CONFIG_SF_DEFAULT_CS 0
+#define CONFIG_SF_DEFAULT_SPEED 1000000
+#define CONFIG_SF_DEFAULT_MODE 0
+
/*
* For booting Linux, the board info and command line data
* have to be in the first 16 MB of memory, since this is
diff --git a/include/configs/adp-ag101p.h b/include/configs/adp-ag101p.h
index bf713b806d..fad4d308e0 100644
--- a/include/configs/adp-ag101p.h
+++ b/include/configs/adp-ag101p.h
@@ -22,8 +22,7 @@
#define CONFIG_CMDLINE_EDITING
-#define CONFIG_SYS_ICACHE_OFF
-#define CONFIG_SYS_DCACHE_OFF
+#define CONFIG_ARCH_MAP_SYSMEM
#define CONFIG_BOOTP_SEND_HOSTNAME
#define CONFIG_BOOTP_SERVERIP
diff --git a/include/configs/am3517_evm.h b/include/configs/am3517_evm.h
index 708a98f827..adb33a9e3e 100644
--- a/include/configs/am3517_evm.h
+++ b/include/configs/am3517_evm.h
@@ -21,6 +21,7 @@
* header. That is 0x800FFFC0--0x80100000 should not be used for any
* other needs.
*/
+
#define CONFIG_SYS_TEXT_BASE 0x80100000
#define CONFIG_SYS_SPL_MALLOC_START 0x80208000
#define CONFIG_SYS_SPL_MALLOC_SIZE 0x100000
@@ -33,16 +34,6 @@
/* Hardware drivers */
-/* NS16550 Configuration */
-#define CONFIG_SYS_NS16550_SERIAL
-#define CONFIG_SYS_NS16550_REG_SIZE (-4)
-
-/* select serial console configuration */
-#define CONFIG_CONS_INDEX 3
-#define CONFIG_SYS_NS16550_COM3 OMAP34XX_UART3
-#define CONFIG_SERIAL3 3 /* UART3 on AM3517 EVM */
-
-
/* allow to overwrite serial and ethaddr */
#define CONFIG_ENV_OVERWRITE
@@ -72,7 +63,6 @@
#endif /* CONFIG_USB_MUSB_AM35X */
/* I2C */
-#define CONFIG_SYS_I2C
#define CONFIG_SYS_OMAP24_I2C_SPEED 100000
#define CONFIG_SYS_OMAP24_I2C_SLAVE 1
@@ -250,8 +240,6 @@
#define CONFIG_SPL_FRAMEWORK
#undef CONFIG_SPL_TEXT_BASE
#define CONFIG_SPL_TEXT_BASE 0x40200000
-#define CONFIG_SPL_MAX_SIZE (SRAM_SCRATCH_SPACE_ADDR - \
- CONFIG_SPL_TEXT_BASE)
#undef CONFIG_SPL_BSS_START_ADDR
#define CONFIG_SPL_BSS_START_ADDR 0x80000000
diff --git a/include/configs/am43xx_evm.h b/include/configs/am43xx_evm.h
index b84f6e3480..7ee69b0c78 100644
--- a/include/configs/am43xx_evm.h
+++ b/include/configs/am43xx_evm.h
@@ -326,4 +326,9 @@
#define NANDBOOT
#endif /* CONFIG_NAND */
+#if defined(CONFIG_TI_SECURE_DEVICE)
+/* Avoid relocating onto firewalled area at end of DRAM */
+#define CONFIG_PRAM (64 * 1024)
+#endif /* CONFIG_TI_SECURE_DEVICE */
+
#endif /* __CONFIG_AM43XX_EVM_H */
diff --git a/include/configs/am57xx_evm.h b/include/configs/am57xx_evm.h
index 0c70c53050..bf555ccdc2 100644
--- a/include/configs/am57xx_evm.h
+++ b/include/configs/am57xx_evm.h
@@ -44,7 +44,8 @@
#define PARTS_DEFAULT \
/* Linux partitions */ \
"uuid_disk=${uuid_gpt_disk};" \
- "name=rootfs,start=2MiB,size=-,uuid=${uuid_gpt_rootfs}\0" \
+ "name=bootloader,start=384K,size=1792K,uuid=${uuid_gpt_bootloader};" \
+ "name=rootfs,start=2688K,size=-,uuid=${uuid_gpt_rootfs}\0" \
/* Android partitions */ \
"partitions_android=" \
"uuid_disk=${uuid_gpt_disk};" \
diff --git a/include/configs/da850evm.h b/include/configs/da850evm.h
index c05c64cad7..821b1fe534 100644
--- a/include/configs/da850evm.h
+++ b/include/configs/da850evm.h
@@ -21,6 +21,16 @@
#endif
/*
+* Disable DM_* for SPL build and can be re-enabled after adding
+* DM support in SPL
+*/
+#ifdef CONFIG_SPL_BUILD
+#undef CONFIG_DM_SPI
+#undef CONFIG_DM_SPI_FLASH
+#undef CONFIG_DM_I2C
+#undef CONFIG_DM_I2C_COMPAT
+#endif
+/*
* SoC Configuration
*/
#define CONFIG_MACH_DAVINCI_DA850_EVM
@@ -130,18 +140,23 @@
/*
* Serial Driver info
*/
+
+#if defined(CONFIG_SPL_BUILD) || defined(CONFIG_DIRECT_NOR_BOOT)
#define CONFIG_SYS_NS16550_SERIAL
#define CONFIG_SYS_NS16550_REG_SIZE -4 /* NS16550 register size */
#define CONFIG_SYS_NS16550_COM1 DAVINCI_UART2_BASE /* Base address of UART2 */
+#endif
#define CONFIG_SYS_NS16550_CLK clk_get(DAVINCI_UART2_CLKID)
#define CONFIG_CONS_INDEX 1 /* use UART0 for console */
#define CONFIG_SPI
#define CONFIG_DAVINCI_SPI
-#define CONFIG_SYS_SPI_BASE DAVINCI_SPI1_BASE
#define CONFIG_SYS_SPI_CLK clk_get(DAVINCI_SPI1_CLKID)
+#ifdef CONFIG_SPL_BUILD
+#define CONFIG_SYS_SPI_BASE DAVINCI_SPI1_BASE
#define CONFIG_SF_DEFAULT_SPEED 30000000
#define CONFIG_ENV_SPI_MAX_HZ CONFIG_SF_DEFAULT_SPEED
+#endif
#ifdef CONFIG_USE_SPIFLASH
#define CONFIG_SPL_SPI_LOAD
@@ -152,11 +167,10 @@
/*
* I2C Configuration
*/
-#define CONFIG_SYS_I2C
+#ifndef CONFIG_SPL_BUILD
#define CONFIG_SYS_I2C_DAVINCI
-#define CONFIG_SYS_DAVINCI_I2C_SPEED 25000
-#define CONFIG_SYS_DAVINCI_I2C_SLAVE 10 /* Bogus, master-only in U-Boot */
#define CONFIG_SYS_I2C_EXPANDER_ADDR 0x20
+#endif
/*
* Flash & Environment
@@ -234,6 +248,17 @@
#define CONFIG_ENV_SIZE (64 << 10)
#define CONFIG_ENV_OFFSET (512 << 10)
#define CONFIG_ENV_SECT_SIZE (64 << 10)
+#ifdef CONFIG_SPL_BUILD
+#undef CONFIG_SPI_FLASH_MTD
+#endif
+#define CONFIG_MTD_DEVICE /* needed for mtdparts commands */
+#define CONFIG_MTD_PARTITIONS /* required for UBI partition support */
+#define MTDIDS_DEFAULT "nor0=spi0.0"
+#define MTDPARTS_DEFAULT "mtdparts=spi0.0:"\
+ "512k(u-boot.ais),"\
+ "64k(u-boot-env),"\
+ "7552k(kernel-spare),"\
+ "64k(MAC-Address)"
#endif
/*
@@ -257,7 +282,29 @@
#define CONFIG_CMDLINE_TAG
#define CONFIG_REVISION_TAG
#define CONFIG_SETUP_MEMORY_TAGS
-#define CONFIG_EXTRA_ENV_SETTINGS "hwconfig=dsp:wake=yes"
+
+#define CONFIG_BOOTCOMMAND \
+ "run envboot; " \
+ "run mmcboot; "
+
+#define DEFAULT_LINUX_BOOT_ENV \
+ "loadaddr=0xc0700000\0" \
+ "fdtaddr=0xc0600000\0" \
+ "scriptaddr=0xc0600000\0"
+
+#include <environment/ti/mmc.h>
+
+#define CONFIG_EXTRA_ENV_SETTINGS \
+ DEFAULT_LINUX_BOOT_ENV \
+ DEFAULT_MMC_TI_ARGS \
+ "bootpart=0:2\0" \
+ "bootdir=/boot\0" \
+ "bootfile=zImage\0" \
+ "fdtfile=da850-evm.dtb\0" \
+ "boot_fdt=yes\0" \
+ "boot_fit=0\0" \
+ "console=ttyS2,115200n8\0" \
+ "hwconfig=dsp:wake=yes"
#ifdef CONFIG_CMD_BDI
#define CONFIG_CLOCKS
diff --git a/include/configs/dra7xx_evm.h b/include/configs/dra7xx_evm.h
index 6c0fc35d3a..1555fc1b50 100644
--- a/include/configs/dra7xx_evm.h
+++ b/include/configs/dra7xx_evm.h
@@ -51,7 +51,8 @@
#define PARTS_DEFAULT \
/* Linux partitions */ \
"uuid_disk=${uuid_gpt_disk};" \
- "name=rootfs,start=2MiB,size=-,uuid=${uuid_gpt_rootfs}\0" \
+ "name=bootloader,start=384K,size=1792K,uuid=${uuid_gpt_bootloader};" \
+ "name=rootfs,start=2688K,size=-,uuid=${uuid_gpt_rootfs}\0" \
/* Android partitions */ \
"partitions_android=" \
"uuid_disk=${uuid_gpt_disk};" \
diff --git a/include/configs/ge_bx50v3.h b/include/configs/ge_bx50v3.h
index a0468d204b..33f5101c14 100644
--- a/include/configs/ge_bx50v3.h
+++ b/include/configs/ge_bx50v3.h
@@ -299,4 +299,19 @@
#define CONFIG_SYS_I2C_MXC_I2C2
#define CONFIG_SYS_I2C_MXC_I2C3
+#define CONFIG_SYS_NUM_I2C_BUSES 9
+#define CONFIG_SYS_I2C_MAX_HOPS 1
+#define CONFIG_SYS_I2C_BUSES { {0, {I2C_NULL_HOP} }, \
+ {0, {{I2C_MUX_PCA9547, 0x70, 0} } }, \
+ {0, {{I2C_MUX_PCA9547, 0x70, 1} } }, \
+ {0, {{I2C_MUX_PCA9547, 0x70, 2} } }, \
+ {0, {{I2C_MUX_PCA9547, 0x70, 3} } }, \
+ {0, {{I2C_MUX_PCA9547, 0x70, 4} } }, \
+ {0, {{I2C_MUX_PCA9547, 0x70, 5} } }, \
+ {0, {{I2C_MUX_PCA9547, 0x70, 6} } }, \
+ {0, {{I2C_MUX_PCA9547, 0x70, 7} } }, \
+ }
+
+#define CONFIG_BCH
+
#endif /* __GE_BX50V3_CONFIG_H */
diff --git a/include/configs/k2g_evm.h b/include/configs/k2g_evm.h
index 1950740405..df81c09d86 100644
--- a/include/configs/k2g_evm.h
+++ b/include/configs/k2g_evm.h
@@ -38,7 +38,7 @@
"setenv name_fdt keystone-k2g-ice.dtb; " \
"else if test $name_fdt = undefined; then " \
"echo WARNING: Could not determine device tree to use;"\
- "fi;fi;fi;\0" \
+ "fi;fi;fi; setenv fdtfile ${name_fdt}\0" \
"name_mon=skern-k2g.bin\0" \
"name_ubi=k2g-evm-ubifs.ubi\0" \
"name_uboot=u-boot-spi-k2g-evm.gph\0" \
diff --git a/include/configs/ls1043a_common.h b/include/configs/ls1043a_common.h
index 002830c27e..1f9efffa56 100644
--- a/include/configs/ls1043a_common.h
+++ b/include/configs/ls1043a_common.h
@@ -22,7 +22,7 @@
#if (defined(CONFIG_SPL_BUILD) && defined(CONFIG_NAND_BOOT))
#define SPL_NO_MMC
#endif
-#if (defined(CONFIG_SPL_BUILD) && defined(CONFIG_SD_BOOT))
+#if (defined(CONFIG_SPL_BUILD) && defined(CONFIG_SD_BOOT_QSPI))
#define SPL_NO_IFC
#endif
diff --git a/include/configs/ls2080ardb.h b/include/configs/ls2080ardb.h
index 145b285685..9e9979e1c7 100644
--- a/include/configs/ls2080ardb.h
+++ b/include/configs/ls2080ardb.h
@@ -18,7 +18,6 @@
#define CONFIG_QIXIS_I2C_ACCESS
#endif
#define CONFIG_SYS_I2C_EARLY_INIT
-#define CONFIG_DISPLAY_BOARDINFO_LATE
#endif
#define I2C_MUX_CH_VOL_MONITOR 0xa
@@ -289,19 +288,15 @@ unsigned long get_board_sys_clk(void);
/* SPI */
#if defined(CONFIG_FSL_QSPI) || defined(CONFIG_FSL_DSPI)
#define CONFIG_SPI_FLASH
-#ifdef CONFIG_FSL_QSPI
+#ifdef CONFIG_FSL_DSPI
#define CONFIG_SPI_FLASH_STMICRO
#endif
#ifdef CONFIG_FSL_QSPI
-#ifdef CONFIG_TARGET_LS2081ARDB
-#define CONFIG_SPI_FLASH_STMICRO
-#else
#define CONFIG_SPI_FLASH_SPANSION
#endif
#define FSL_QSPI_FLASH_SIZE SZ_64M /* 64MB */
#define FSL_QSPI_FLASH_NUM 2
#endif
-#endif
/*
* RTC configuration
@@ -392,6 +387,7 @@ unsigned long get_board_sys_clk(void);
"load_addr=0xa0000000\0" \
"kernel_size=0x2800000\0" \
"console=ttyAMA0,38400n8\0" \
+ "mcmemsize=0x70000000\0" \
MC_INIT_CMD \
BOOTENV \
"boot_scripts=ls2088ardb_boot.scr\0" \
diff --git a/include/configs/mvebu_armada-37xx.h b/include/configs/mvebu_armada-37xx.h
index 66c7001f09..1b2e0d71b4 100644
--- a/include/configs/mvebu_armada-37xx.h
+++ b/include/configs/mvebu_armada-37xx.h
@@ -84,7 +84,6 @@
/*
* Ethernet Driver configuration
*/
-#define CONFIG_MVNETA /* Enable Marvell Gbe Controller Driver */
#define CONFIG_ENV_OVERWRITE /* ethaddr can be reprogrammed */
#define CONFIG_ARP_TIMEOUT 200
#define CONFIG_NET_RETRY_COUNT 50
diff --git a/include/configs/mx6cuboxi.h b/include/configs/mx6cuboxi.h
index 4e12de1212..7fefe8edcb 100644
--- a/include/configs/mx6cuboxi.h
+++ b/include/configs/mx6cuboxi.h
@@ -106,6 +106,10 @@
"fi; " \
"fi\0" \
"findfdt="\
+ "if test $board_name = HUMMINGBOARD2 && test $board_rev = MX6Q ; then " \
+ "setenv fdtfile imx6q-hummingboard2.dtb; fi; " \
+ "if test $board_name = HUMMINGBOARD2 && test $board_rev = MX6DL ; then " \
+ "setenv fdtfile imx6dl-hummingboard2.dtb; fi; " \
"if test $board_name = HUMMINGBOARD && test $board_rev = MX6Q ; then " \
"setenv fdtfile imx6q-hummingboard.dtb; fi; " \
"if test $board_name = HUMMINGBOARD && test $board_rev = MX6DL ; then " \
diff --git a/include/configs/rk3368_common.h b/include/configs/rk3368_common.h
index 8cba92c56d..8b4155f37c 100644
--- a/include/configs/rk3368_common.h
+++ b/include/configs/rk3368_common.h
@@ -51,6 +51,7 @@
#include <config_distro_bootcmd.h>
#define CONFIG_EXTRA_ENV_SETTINGS \
+ ENV_MEM_LAYOUT_SETTINGS \
BOOTENV
#endif
diff --git a/include/configs/rv1108_common.h b/include/configs/rv1108_common.h
index 04779162d0..5ee45594a3 100644
--- a/include/configs/rv1108_common.h
+++ b/include/configs/rv1108_common.h
@@ -28,4 +28,7 @@
#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_TEXT_BASE + 0x100000)
#define CONFIG_SYS_LOAD_ADDR (CONFIG_SYS_SDRAM_BASE + 0x2000000)
+/* rockchip ohci host driver */
+#define CONFIG_USB_OHCI_NEW
+#define CONFIG_SYS_USB_OHCI_MAX_ROOT_PORTS 1
#endif
diff --git a/include/configs/socfpga_common.h b/include/configs/socfpga_common.h
index 9897e11b59..7b5417a75b 100644
--- a/include/configs/socfpga_common.h
+++ b/include/configs/socfpga_common.h
@@ -142,12 +142,10 @@
*/
#ifdef CONFIG_NAND_DENALI
#define CONFIG_SYS_MAX_NAND_DEVICE 1
-#define CONFIG_SYS_NAND_MAX_CHIPS 1
#define CONFIG_SYS_NAND_ONFI_DETECTION
#define CONFIG_NAND_DENALI_ECC_SIZE 512
#define CONFIG_SYS_NAND_REGS_BASE SOCFPGA_NANDREGS_ADDRESS
#define CONFIG_SYS_NAND_DATA_BASE SOCFPGA_NANDDATA_ADDRESS
-#define CONFIG_SYS_NAND_BASE (CONFIG_SYS_NAND_DATA_BASE + 0x10)
#endif
/*
diff --git a/include/configs/stih410-b2260.h b/include/configs/stih410-b2260.h
index e07dd0e103..372c083601 100644
--- a/include/configs/stih410-b2260.h
+++ b/include/configs/stih410-b2260.h
@@ -45,4 +45,19 @@
#define CONFIG_SKIP_LOWLEVEL_INIT
+/* USB Configs */
+#define CONFIG_USB_OHCI_NEW
+#define CONFIG_SYS_USB_OHCI_MAX_ROOT_PORTS 2
+
+#define CONFIG_USB_HOST_ETHER
+#define CONFIG_USB_ETHER_ASIX
+#define CONFIG_USB_ETHER_MCS7830
+#define CONFIG_USB_ETHER_SMSC95XX
+
+/* NET Configs */
+#define CONFIG_BOOTP_SUBNETMASK
+#define CONFIG_BOOTP_GATEWAY
+#define CONFIG_BOOTP_HOSTNAME
+#define CONFIG_BOOTP_BOOTPATH
+
#endif /* __CONFIG_H */
diff --git a/include/configs/stm32h743-disco.h b/include/configs/stm32h743-disco.h
new file mode 100644
index 0000000000..b0061cd0de
--- /dev/null
+++ b/include/configs/stm32h743-disco.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) STMicroelectronics SA 2017
+ * Author(s): Patrice CHOTARD, <patrice.chotard@st.com> for STMicroelectronics.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#include <config.h>
+
+#define CONFIG_SYS_FLASH_BASE 0x08000000
+#define CONFIG_SYS_INIT_SP_ADDR 0x30020000
+#define CONFIG_SYS_TEXT_BASE 0x08000000
+
+/*
+ * Configuration of the external SDRAM memory
+ */
+#define CONFIG_NR_DRAM_BANKS 1
+#define CONFIG_SYS_RAM_BASE 0xD0000000
+#define CONFIG_SYS_SDRAM_BASE CONFIG_SYS_RAM_BASE
+#define CONFIG_SYS_LOAD_ADDR 0xD0400000
+#define CONFIG_LOADADDR 0xD0400000
+
+#define CONFIG_ENV_SIZE (8 << 10)
+
+#define CONFIG_SYS_ARCH_TIMER
+#define CONFIG_SYS_HZ_CLOCK 250000000
+
+#define CONFIG_CMDLINE_TAG
+#define CONFIG_SETUP_MEMORY_TAGS
+#define CONFIG_INITRD_TAG
+#define CONFIG_REVISION_TAG
+
+#define CONFIG_SYS_MAXARGS 16
+#define CONFIG_SYS_MALLOC_LEN (1 * 1024 * 1024)
+
+#define CONFIG_BOOTARGS \
+ "console=ttyS0,115200 earlyprintk consoleblank=0 ignore_loglevel"
+
+/*
+ * Command line configuration.
+ */
+#define CONFIG_SYS_LONGHELP
+#define CONFIG_AUTO_COMPLETE
+#define CONFIG_CMDLINE_EDITING
+#define CONFIG_CMD_CACHE
+#define CONFIG_BOARD_LATE_INIT
+
+#endif /* __CONFIG_H */
diff --git a/include/configs/stm32h743-eval.h b/include/configs/stm32h743-eval.h
new file mode 100644
index 0000000000..b0061cd0de
--- /dev/null
+++ b/include/configs/stm32h743-eval.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) STMicroelectronics SA 2017
+ * Author(s): Patrice CHOTARD, <patrice.chotard@st.com> for STMicroelectronics.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#include <config.h>
+
+#define CONFIG_SYS_FLASH_BASE 0x08000000
+#define CONFIG_SYS_INIT_SP_ADDR 0x30020000
+#define CONFIG_SYS_TEXT_BASE 0x08000000
+
+/*
+ * Configuration of the external SDRAM memory
+ */
+#define CONFIG_NR_DRAM_BANKS 1
+#define CONFIG_SYS_RAM_BASE 0xD0000000
+#define CONFIG_SYS_SDRAM_BASE CONFIG_SYS_RAM_BASE
+#define CONFIG_SYS_LOAD_ADDR 0xD0400000
+#define CONFIG_LOADADDR 0xD0400000
+
+#define CONFIG_ENV_SIZE (8 << 10)
+
+#define CONFIG_SYS_ARCH_TIMER
+#define CONFIG_SYS_HZ_CLOCK 250000000
+
+#define CONFIG_CMDLINE_TAG
+#define CONFIG_SETUP_MEMORY_TAGS
+#define CONFIG_INITRD_TAG
+#define CONFIG_REVISION_TAG
+
+#define CONFIG_SYS_MAXARGS 16
+#define CONFIG_SYS_MALLOC_LEN (1 * 1024 * 1024)
+
+#define CONFIG_BOOTARGS \
+ "console=ttyS0,115200 earlyprintk consoleblank=0 ignore_loglevel"
+
+/*
+ * Command line configuration.
+ */
+#define CONFIG_SYS_LONGHELP
+#define CONFIG_AUTO_COMPLETE
+#define CONFIG_CMDLINE_EDITING
+#define CONFIG_CMD_CACHE
+#define CONFIG_BOARD_LATE_INIT
+
+#endif /* __CONFIG_H */
diff --git a/include/configs/ti_armv7_keystone2.h b/include/configs/ti_armv7_keystone2.h
index 2b2b85d085..53046a2110 100644
--- a/include/configs/ti_armv7_keystone2.h
+++ b/include/configs/ti_armv7_keystone2.h
@@ -270,7 +270,7 @@
"${bootdir}/${fit_bootfile}\0" \
"get_uboot_net=dhcp ${loadaddr} ${tftp_root}/${name_uboot}\0" \
"get_uboot_nfs=nfs ${loadaddr} ${nfs_root}/boot/${name_uboot}\0" \
- "burn_uboot_spi=sf probe; sf erase 0 0x80000; " \
+ "burn_uboot_spi=sf probe; sf erase 0 0x90000; " \
"sf write ${loadaddr} 0 ${filesize}\0" \
"burn_uboot_nand=nand erase 0 0x100000; " \
"nand write ${loadaddr} 0 ${filesize}\0" \
diff --git a/include/configs/vyasa-rk3288.h b/include/configs/vyasa-rk3288.h
new file mode 100644
index 0000000000..9d6c80f549
--- /dev/null
+++ b/include/configs/vyasa-rk3288.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2017 Amarula Solutions
+ *
+ * Configuration settings for Amarula Vyasa RK3288.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#define ROCKCHIP_DEVICE_SETTINGS
+#include <configs/rk3288_common.h>
+
+#undef BOOT_TARGET_DEVICES
+
+#define BOOT_TARGET_DEVICES(func) \
+ func(MMC, mmc, 1) \
+
+#define CONFIG_SYS_MMC_ENV_DEV 1
+#undef CONFIG_CMD_USB_MASS_STORAGE
+
+#endif
diff --git a/include/dm/read.h b/include/dm/read.h
index 49d69c990f..8114037e97 100644
--- a/include/dm/read.h
+++ b/include/dm/read.h
@@ -113,6 +113,16 @@ fdt_addr_t dev_read_addr_index(struct udevice *dev, int index);
fdt_addr_t dev_read_addr(struct udevice *dev);
/**
+ * dev_read_addr_ptr() - Get the reg property of a device
+ * as a pointer
+ *
+ * @dev: Device to read from
+ *
+ * @return pointer or NULL if not found
+ */
+void *dev_read_addr_ptr(struct udevice *dev);
+
+/**
* dev_read_addr_size() - get address and size from a device property
*
* This does no address translation. It simply reads an property that contains
@@ -156,6 +166,29 @@ int dev_read_stringlist_search(struct udevice *dev, const char *property,
const char *string);
/**
+ * dev_read_string_index() - obtain an indexed string from a string list
+ *
+ * @dev: device to examine
+ * @propname: name of the property containing the string list
+ * @index: index of the string to return
+ * @out: return location for the string
+ *
+ * @return:
+ * length of string, if found or -ve error value if not found
+ */
+int dev_read_string_index(struct udevice *dev, const char *propname, int index,
+ const char **outp);
+
+/**
+ * dev_read_string_count() - find the number of strings in a string list
+ *
+ * @dev: device to examine
+ * @propname: name of the property containing the string list
+ * @return:
+ * number of strings in the list, or -ve error value if not found
+ */
+int dev_read_string_count(struct udevice *dev, const char *propname);
+/**
* dev_read_phandle_with_args() - Find a node pointed by phandle in a list
*
* This function is useful to parse lists of phandles and their arguments.
@@ -417,6 +450,11 @@ static inline fdt_addr_t dev_read_addr(struct udevice *dev)
return devfdt_get_addr(dev);
}
+static inline void *dev_read_addr_ptr(struct udevice *dev)
+{
+ return devfdt_get_addr_ptr(dev);
+}
+
static inline fdt_addr_t dev_read_addr_size(struct udevice *dev,
const char *propname,
fdt_size_t *sizep)
@@ -436,6 +474,19 @@ static inline int dev_read_stringlist_search(struct udevice *dev,
return ofnode_stringlist_search(dev_ofnode(dev), propname, string);
}
+static inline int dev_read_string_index(struct udevice *dev,
+ const char *propname, int index,
+ const char **outp)
+{
+ return ofnode_read_string_index(dev_ofnode(dev), propname, index, outp);
+}
+
+static inline int dev_read_string_count(struct udevice *dev,
+ const char *propname)
+{
+ return ofnode_read_string_count(dev_ofnode(dev), propname);
+}
+
static inline int dev_read_phandle_with_args(struct udevice *dev,
const char *list_name, const char *cells_name, int cell_count,
int index, struct ofnode_phandle_args *out_args)
diff --git a/include/dt-bindings/clock/stm32h7-clks.h b/include/dt-bindings/clock/stm32h7-clks.h
new file mode 100644
index 0000000000..4d87e7ebc3
--- /dev/null
+++ b/include/dt-bindings/clock/stm32h7-clks.h
@@ -0,0 +1,167 @@
+/* SYS, CORE AND BUS CLOCKS */
+#define SYS_D1CPRE 0
+#define HCLK 1
+#define PCLK1 2
+#define PCLK2 3
+#define PCLK3 4
+#define PCLK4 5
+#define HSI_DIV 6
+#define HSE_1M 7
+#define I2S_CKIN 8
+#define CK_DSI_PHY 9
+#define HSE_CK 10
+#define LSE_CK 11
+#define CSI_KER_DIV122 12
+#define RTC_CK 13
+#define CPU_SYSTICK 14
+
+/* OSCILLATOR BANK */
+#define OSC_BANK 18
+#define HSI_CK 18
+#define HSI_KER_CK 19
+#define CSI_CK 20
+#define CSI_KER_CK 21
+#define RC48_CK 22
+#define LSI_CK 23
+
+/* MCLOCK BANK */
+#define MCLK_BANK 28
+#define PER_CK 28
+#define PLLSRC 29
+#define SYS_CK 30
+#define TRACEIN_CK 31
+
+/* ODF BANK */
+#define ODF_BANK 32
+#define PLL1_P 32
+#define PLL1_Q 33
+#define PLL1_R 34
+#define PLL2_P 35
+#define PLL2_Q 36
+#define PLL2_R 37
+#define PLL3_P 38
+#define PLL3_Q 39
+#define PLL3_R 40
+
+/* MCO BANK */
+#define MCO_BANK 41
+#define MCO1 41
+#define MCO2 42
+
+/* PERIF BANK */
+#define PERIF_BANK 50
+#define D1SRAM1_CK 50
+#define ITCM_CK 51
+#define DTCM2_CK 52
+#define DTCM1_CK 53
+#define FLITF_CK 54
+#define JPGDEC_CK 55
+#define DMA2D_CK 56
+#define MDMA_CK 57
+#define USB2ULPI_CK 58
+#define USB1ULPI_CK 59
+#define ETH1RX_CK 60
+#define ETH1TX_CK 61
+#define ETH1MAC_CK 62
+#define ART_CK 63
+#define DMA2_CK 64
+#define DMA1_CK 65
+#define D2SRAM3_CK 66
+#define D2SRAM2_CK 67
+#define D2SRAM1_CK 68
+#define HASH_CK 69
+#define CRYPT_CK 70
+#define CAMITF_CK 71
+#define BKPRAM_CK 72
+#define HSEM_CK 73
+#define BDMA_CK 74
+#define CRC_CK 75
+#define GPIOK_CK 76
+#define GPIOJ_CK 77
+#define GPIOI_CK 78
+#define GPIOH_CK 79
+#define GPIOG_CK 80
+#define GPIOF_CK 81
+#define GPIOE_CK 82
+#define GPIOD_CK 83
+#define GPIOC_CK 84
+#define GPIOB_CK 85
+#define GPIOA_CK 86
+#define WWDG1_CK 87
+#define DAC12_CK 88
+#define WWDG2_CK 89
+#define TIM14_CK 90
+#define TIM13_CK 91
+#define TIM12_CK 92
+#define TIM7_CK 93
+#define TIM6_CK 94
+#define TIM5_CK 95
+#define TIM4_CK 96
+#define TIM3_CK 97
+#define TIM2_CK 98
+#define MDIOS_CK 99
+#define OPAMP_CK 100
+#define CRS_CK 101
+#define TIM17_CK 102
+#define TIM16_CK 103
+#define TIM15_CK 104
+#define TIM8_CK 105
+#define TIM1_CK 106
+#define TMPSENS_CK 107
+#define RTCAPB_CK 108
+#define VREF_CK 109
+#define COMP12_CK 110
+#define SYSCFG_CK 111
+/* must be equal to last peripheral clock index */
+#define LAST_PERIF_BANK SYSCFG_CK
+
+/* KERNEL BANK */
+#define KERN_BANK 120
+#define SDMMC1_CK 120
+#define QUADSPI_CK 121
+#define FMC_CK 122
+#define USB2OTG_CK 123
+#define USB1OTG_CK 124
+#define ADC12_CK 125
+#define SDMMC2_CK 126
+#define RNG_CK 127
+#define ADC3_CK 128
+#define DSI_CK 129
+#define LTDC_CK 130
+#define USART8_CK 131
+#define USART7_CK 132
+#define HDMICEC_CK 133
+#define I2C3_CK 134
+#define I2C2_CK 135
+#define I2C1_CK 136
+#define UART5_CK 137
+#define UART4_CK 138
+#define USART3_CK 139
+#define USART2_CK 140
+#define SPDIFRX_CK 141
+#define SPI3_CK 142
+#define SPI2_CK 143
+#define LPTIM1_CK 144
+#define FDCAN_CK 145
+#define SWP_CK 146
+#define HRTIM_CK 147
+#define DFSDM1_CK 148
+#define SAI3_CK 149
+#define SAI2_CK 150
+#define SAI1_CK 151
+#define SPI5_CK 152
+#define SPI4_CK 153
+#define SPI1_CK 154
+#define USART6_CK 155
+#define USART1_CK 156
+#define SAI4B_CK 157
+#define SAI4A_CK 158
+#define LPTIM5_CK 159
+#define LPTIM4_CK 160
+#define LPTIM3_CK 161
+#define LPTIM2_CK 162
+#define I2C4_CK 163
+#define SPI6_CK 164
+#define LPUART1_CK 165
+
+#define STM32H7_MAX_CLKS 166
diff --git a/include/dt-bindings/memory/stm32-sdram.h b/include/dt-bindings/memory/stm32-sdram.h
index 89b719af53..c2b911febf 100644
--- a/include/dt-bindings/memory/stm32-sdram.h
+++ b/include/dt-bindings/memory/stm32-sdram.h
@@ -18,7 +18,9 @@
#define CAS_1 0x1
#define CAS_2 0x2
#define CAS_3 0x3
+#define SDCLK_DIS 0x0
#define SDCLK_2 0x2
+#define SDCLK_3 0x3
#define RD_BURST_EN 0x1
#define RD_BURST_DIS 0x0
#define RD_PIPE_DL_0 0x0
@@ -26,12 +28,17 @@
#define RD_PIPE_DL_2 0x2
/* Timing = value +1 cycles */
+#define TMRD_1 (1 - 1)
#define TMRD_2 (2 - 1)
+#define TXSR_1 (1 - 1)
#define TXSR_6 (6 - 1)
+#define TRAS_1 (1 - 1)
#define TRAS_4 (4 - 1)
#define TRC_6 (6 - 1)
+#define TWR_1 (1 - 1)
#define TWR_2 (2 - 1)
#define TRP_2 (2 - 1)
+#define TRCD_1 (1 - 1)
#define TRCD_2 (2 - 1)
#endif
diff --git a/include/dt-bindings/mfd/stm32h7-rcc.h b/include/dt-bindings/mfd/stm32h7-rcc.h
new file mode 100644
index 0000000000..b96b3c3ac1
--- /dev/null
+++ b/include/dt-bindings/mfd/stm32h7-rcc.h
@@ -0,0 +1,138 @@
+/*
+ * This header provides constants for the STM32H7 RCC IP
+ */
+
+#ifndef _DT_BINDINGS_MFD_STM32H7_RCC_H
+#define _DT_BINDINGS_MFD_STM32H7_RCC_H
+
+/* AHB3 */
+#define STM32H7_RCC_AHB3_MDMA 0
+#define STM32H7_RCC_AHB3_DMA2D 4
+#define STM32H7_RCC_AHB3_JPGDEC 5
+#define STM32H7_RCC_AHB3_FMC 12
+#define STM32H7_RCC_AHB3_QUADSPI 14
+#define STM32H7_RCC_AHB3_SDMMC1 16
+#define STM32H7_RCC_AHB3_CPU1 31
+
+#define STM32H7_AHB3_RESET(bit) (STM32H7_RCC_AHB3_##bit + (0x7C * 8))
+
+/* AHB1 */
+#define STM32H7_RCC_AHB1_DMA1 0
+#define STM32H7_RCC_AHB1_DMA2 1
+#define STM32H7_RCC_AHB1_ADC12 5
+#define STM32H7_RCC_AHB1_ART 14
+#define STM32H7_RCC_AHB1_ETH1MAC 15
+#define STM32H7_RCC_AHB1_USB1OTG 25
+#define STM32H7_RCC_AHB1_USB2OTG 27
+#define STM32H7_RCC_AHB1_CPU2 31
+
+#define STM32H7_AHB1_RESET(bit) (STM32H7_RCC_AHB1_##bit + (0x80 * 8))
+
+/* AHB2 */
+#define STM32H7_RCC_AHB2_CAMITF 0
+#define STM32H7_RCC_AHB2_CRYPT 4
+#define STM32H7_RCC_AHB2_HASH 5
+#define STM32H7_RCC_AHB2_RNG 6
+#define STM32H7_RCC_AHB2_SDMMC2 9
+
+#define STM32H7_AHB2_RESET(bit) (STM32H7_RCC_AHB2_##bit + (0x84 * 8))
+
+/* AHB4 */
+#define STM32H7_RCC_AHB4_GPIOA 0
+#define STM32H7_RCC_AHB4_GPIOB 1
+#define STM32H7_RCC_AHB4_GPIOC 2
+#define STM32H7_RCC_AHB4_GPIOD 3
+#define STM32H7_RCC_AHB4_GPIOE 4
+#define STM32H7_RCC_AHB4_GPIOF 5
+#define STM32H7_RCC_AHB4_GPIOG 6
+#define STM32H7_RCC_AHB4_GPIOH 7
+#define STM32H7_RCC_AHB4_GPIOI 8
+#define STM32H7_RCC_AHB4_GPIOJ 9
+#define STM32H7_RCC_AHB4_GPIOK 10
+#define STM32H7_RCC_AHB4_CRC 19
+#define STM32H7_RCC_AHB4_BDMA 21
+#define STM32H7_RCC_AHB4_ADC3 24
+#define STM32H7_RCC_AHB4_HSEM 25
+
+#define STM32H7_AHB4_RESET(bit) (STM32H7_RCC_AHB4_##bit + (0x88 * 8))
+
+
+/* APB3 */
+#define STM32H7_RCC_APB3_LTDC 3
+#define STM32H7_RCC_APB3_DSI 4
+
+#define STM32H7_APB3_RESET(bit) (STM32H7_RCC_APB3_##bit + (0x8C * 8))
+
+/* APB1L */
+#define STM32H7_RCC_APB1L_TIM2 0
+#define STM32H7_RCC_APB1L_TIM3 1
+#define STM32H7_RCC_APB1L_TIM4 2
+#define STM32H7_RCC_APB1L_TIM5 3
+#define STM32H7_RCC_APB1L_TIM6 4
+#define STM32H7_RCC_APB1L_TIM7 5
+#define STM32H7_RCC_APB1L_TIM12 6
+#define STM32H7_RCC_APB1L_TIM13 7
+#define STM32H7_RCC_APB1L_TIM14 8
+#define STM32H7_RCC_APB1L_LPTIM1 9
+#define STM32H7_RCC_APB1L_SPI2 14
+#define STM32H7_RCC_APB1L_SPI3 15
+#define STM32H7_RCC_APB1L_SPDIF_RX 16
+#define STM32H7_RCC_APB1L_USART2 17
+#define STM32H7_RCC_APB1L_USART3 18
+#define STM32H7_RCC_APB1L_UART4 19
+#define STM32H7_RCC_APB1L_UART5 20
+#define STM32H7_RCC_APB1L_I2C1 21
+#define STM32H7_RCC_APB1L_I2C2 22
+#define STM32H7_RCC_APB1L_I2C3 23
+#define STM32H7_RCC_APB1L_HDMICEC 27
+#define STM32H7_RCC_APB1L_DAC12 29
+#define STM32H7_RCC_APB1L_USART7 30
+#define STM32H7_RCC_APB1L_USART8 31
+
+#define STM32H7_APB1L_RESET(bit) (STM32H7_RCC_APB1L_##bit + (0x90 * 8))
+
+/* APB1H */
+#define STM32H7_RCC_APB1H_CRS 1
+#define STM32H7_RCC_APB1H_SWP 2
+#define STM32H7_RCC_APB1H_OPAMP 4
+#define STM32H7_RCC_APB1H_MDIOS 5
+#define STM32H7_RCC_APB1H_FDCAN 8
+
+#define STM32H7_APB1H_RESET(bit) (STM32H7_RCC_APB1H_##bit + (0x94 * 8))
+
+/* APB2 */
+#define STM32H7_RCC_APB2_TIM1 0
+#define STM32H7_RCC_APB2_TIM8 1
+#define STM32H7_RCC_APB2_USART1 4
+#define STM32H7_RCC_APB2_USART6 5
+#define STM32H7_RCC_APB2_SPI1 12
+#define STM32H7_RCC_APB2_SPI4 13
+#define STM32H7_RCC_APB2_TIM15 16
+#define STM32H7_RCC_APB2_TIM16 17
+#define STM32H7_RCC_APB2_TIM17 18
+#define STM32H7_RCC_APB2_SPI5 20
+#define STM32H7_RCC_APB2_SAI1 22
+#define STM32H7_RCC_APB2_SAI2 23
+#define STM32H7_RCC_APB2_SAI3 24
+#define STM32H7_RCC_APB2_DFSDM1 28
+#define STM32H7_RCC_APB2_HRTIM 29
+
+#define STM32H7_APB2_RESET(bit) (STM32H7_RCC_APB2_##bit + (0x98 * 8))
+
+/* APB4 */
+#define STM32H7_RCC_APB4_SYSCFG 1
+#define STM32H7_RCC_APB4_LPUART1 3
+#define STM32H7_RCC_APB4_SPI6 5
+#define STM32H7_RCC_APB4_I2C4 7
+#define STM32H7_RCC_APB4_LPTIM2 9
+#define STM32H7_RCC_APB4_LPTIM3 10
+#define STM32H7_RCC_APB4_LPTIM4 11
+#define STM32H7_RCC_APB4_LPTIM5 12
+#define STM32H7_RCC_APB4_COMP12 14
+#define STM32H7_RCC_APB4_VREF 15
+#define STM32H7_RCC_APB4_SAI4 21
+#define STM32H7_RCC_APB4_TMPSENS 26
+
+#define STM32H7_APB4_RESET(bit) (STM32H7_RCC_APB4_##bit + (0x9C * 8))
+
+#endif /* _DT_BINDINGS_MFD_STM32H7_RCC_H */
diff --git a/include/dt-bindings/pinctrl/stm32h7-pinfunc.h b/include/dt-bindings/pinctrl/stm32h7-pinfunc.h
new file mode 100644
index 0000000000..cb673b5e8e
--- /dev/null
+++ b/include/dt-bindings/pinctrl/stm32h7-pinfunc.h
@@ -0,0 +1,1612 @@
+#ifndef _DT_BINDINGS_STM32H7_PINFUNC_H
+#define _DT_BINDINGS_STM32H7_PINFUNC_H
+
+#define STM32H7_PA0_FUNC_GPIO 0x0
+#define STM32H7_PA0_FUNC_TIM2_CH1_TIM2_ETR 0x2
+#define STM32H7_PA0_FUNC_TIM5_CH1 0x3
+#define STM32H7_PA0_FUNC_TIM8_ETR 0x4
+#define STM32H7_PA0_FUNC_TIM15_BKIN 0x5
+#define STM32H7_PA0_FUNC_USART2_CTS_NSS 0x8
+#define STM32H7_PA0_FUNC_UART4_TX 0x9
+#define STM32H7_PA0_FUNC_SDMMC2_CMD 0xa
+#define STM32H7_PA0_FUNC_SAI2_SD_B 0xb
+#define STM32H7_PA0_FUNC_ETH_MII_CRS 0xc
+#define STM32H7_PA0_FUNC_EVENTOUT 0x10
+#define STM32H7_PA0_FUNC_ANALOG 0x11
+
+#define STM32H7_PA1_FUNC_GPIO 0x100
+#define STM32H7_PA1_FUNC_TIM2_CH2 0x102
+#define STM32H7_PA1_FUNC_TIM5_CH2 0x103
+#define STM32H7_PA1_FUNC_LPTIM3_OUT 0x104
+#define STM32H7_PA1_FUNC_TIM15_CH1N 0x105
+#define STM32H7_PA1_FUNC_USART2_RTS 0x108
+#define STM32H7_PA1_FUNC_UART4_RX 0x109
+#define STM32H7_PA1_FUNC_QUADSPI_BK1_IO3 0x10a
+#define STM32H7_PA1_FUNC_SAI2_MCK_B 0x10b
+#define STM32H7_PA1_FUNC_ETH_MII_RX_CLK_ETH_RMII_REF_CLK 0x10c
+#define STM32H7_PA1_FUNC_LCD_R2 0x10f
+#define STM32H7_PA1_FUNC_EVENTOUT 0x110
+#define STM32H7_PA1_FUNC_ANALOG 0x111
+
+#define STM32H7_PA2_FUNC_GPIO 0x200
+#define STM32H7_PA2_FUNC_TIM2_CH3 0x202
+#define STM32H7_PA2_FUNC_TIM5_CH3 0x203
+#define STM32H7_PA2_FUNC_LPTIM4_OUT 0x204
+#define STM32H7_PA2_FUNC_TIM15_CH1 0x205
+#define STM32H7_PA2_FUNC_USART2_TX 0x208
+#define STM32H7_PA2_FUNC_SAI2_SCK_B 0x209
+#define STM32H7_PA2_FUNC_ETH_MDIO 0x20c
+#define STM32H7_PA2_FUNC_MDIOS_MDIO 0x20d
+#define STM32H7_PA2_FUNC_LCD_R1 0x20f
+#define STM32H7_PA2_FUNC_EVENTOUT 0x210
+#define STM32H7_PA2_FUNC_ANALOG 0x211
+
+#define STM32H7_PA3_FUNC_GPIO 0x300
+#define STM32H7_PA3_FUNC_TIM2_CH4 0x302
+#define STM32H7_PA3_FUNC_TIM5_CH4 0x303
+#define STM32H7_PA3_FUNC_LPTIM5_OUT 0x304
+#define STM32H7_PA3_FUNC_TIM15_CH2 0x305
+#define STM32H7_PA3_FUNC_USART2_RX 0x308
+#define STM32H7_PA3_FUNC_LCD_B2 0x30a
+#define STM32H7_PA3_FUNC_OTG_HS_ULPI_D0 0x30b
+#define STM32H7_PA3_FUNC_ETH_MII_COL 0x30c
+#define STM32H7_PA3_FUNC_LCD_B5 0x30f
+#define STM32H7_PA3_FUNC_EVENTOUT 0x310
+#define STM32H7_PA3_FUNC_ANALOG 0x311
+
+#define STM32H7_PA4_FUNC_GPIO 0x400
+#define STM32H7_PA4_FUNC_TIM5_ETR 0x403
+#define STM32H7_PA4_FUNC_SPI1_NSS_I2S1_WS 0x406
+#define STM32H7_PA4_FUNC_SPI3_NSS_I2S3_WS 0x407
+#define STM32H7_PA4_FUNC_USART2_CK 0x408
+#define STM32H7_PA4_FUNC_SPI6_NSS 0x409
+#define STM32H7_PA4_FUNC_OTG_HS_SOF 0x40d
+#define STM32H7_PA4_FUNC_DCMI_HSYNC 0x40e
+#define STM32H7_PA4_FUNC_LCD_VSYNC 0x40f
+#define STM32H7_PA4_FUNC_EVENTOUT 0x410
+#define STM32H7_PA4_FUNC_ANALOG 0x411
+
+#define STM32H7_PA5_FUNC_GPIO 0x500
+#define STM32H7_PA5_FUNC_TIM2_CH1_TIM2_ETR 0x502
+#define STM32H7_PA5_FUNC_TIM8_CH1N 0x504
+#define STM32H7_PA5_FUNC_SPI1_SCK_I2S1_CK 0x506
+#define STM32H7_PA5_FUNC_SPI6_SCK 0x509
+#define STM32H7_PA5_FUNC_OTG_HS_ULPI_CK 0x50b
+#define STM32H7_PA5_FUNC_LCD_R4 0x50f
+#define STM32H7_PA5_FUNC_EVENTOUT 0x510
+#define STM32H7_PA5_FUNC_ANALOG 0x511
+
+#define STM32H7_PA6_FUNC_GPIO 0x600
+#define STM32H7_PA6_FUNC_TIM1_BKIN 0x602
+#define STM32H7_PA6_FUNC_TIM3_CH1 0x603
+#define STM32H7_PA6_FUNC_TIM8_BKIN 0x604
+#define STM32H7_PA6_FUNC_SPI1_MISO_I2S1_SDI 0x606
+#define STM32H7_PA6_FUNC_SPI6_MISO 0x609
+#define STM32H7_PA6_FUNC_TIM13_CH1 0x60a
+#define STM32H7_PA6_FUNC_TIM8_BKIN_COMP12 0x60b
+#define STM32H7_PA6_FUNC_MDIOS_MDC 0x60c
+#define STM32H7_PA6_FUNC_TIM1_BKIN_COMP12 0x60d
+#define STM32H7_PA6_FUNC_DCMI_PIXCLK 0x60e
+#define STM32H7_PA6_FUNC_LCD_G2 0x60f
+#define STM32H7_PA6_FUNC_EVENTOUT 0x610
+#define STM32H7_PA6_FUNC_ANALOG 0x611
+
+#define STM32H7_PA7_FUNC_GPIO 0x700
+#define STM32H7_PA7_FUNC_TIM1_CH1N 0x702
+#define STM32H7_PA7_FUNC_TIM3_CH2 0x703
+#define STM32H7_PA7_FUNC_TIM8_CH1N 0x704
+#define STM32H7_PA7_FUNC_SPI1_MOSI_I2S1_SDO 0x706
+#define STM32H7_PA7_FUNC_SPI6_MOSI 0x709
+#define STM32H7_PA7_FUNC_TIM14_CH1 0x70a
+#define STM32H7_PA7_FUNC_ETH_MII_RX_DV_ETH_RMII_CRS_DV 0x70c
+#define STM32H7_PA7_FUNC_FMC_SDNWE 0x70d
+#define STM32H7_PA7_FUNC_EVENTOUT 0x710
+#define STM32H7_PA7_FUNC_ANALOG 0x711
+
+#define STM32H7_PA8_FUNC_GPIO 0x800
+#define STM32H7_PA8_FUNC_MCO1 0x801
+#define STM32H7_PA8_FUNC_TIM1_CH1 0x802
+#define STM32H7_PA8_FUNC_HRTIM_CHB2 0x803
+#define STM32H7_PA8_FUNC_TIM8_BKIN2 0x804
+#define STM32H7_PA8_FUNC_I2C3_SCL 0x805
+#define STM32H7_PA8_FUNC_USART1_CK 0x808
+#define STM32H7_PA8_FUNC_OTG_FS_SOF 0x80b
+#define STM32H7_PA8_FUNC_UART7_RX 0x80c
+#define STM32H7_PA8_FUNC_TIM8_BKIN2_COMP12 0x80d
+#define STM32H7_PA8_FUNC_LCD_B3 0x80e
+#define STM32H7_PA8_FUNC_LCD_R6 0x80f
+#define STM32H7_PA8_FUNC_EVENTOUT 0x810
+#define STM32H7_PA8_FUNC_ANALOG 0x811
+
+#define STM32H7_PA9_FUNC_GPIO 0x900
+#define STM32H7_PA9_FUNC_TIM1_CH2 0x902
+#define STM32H7_PA9_FUNC_HRTIM_CHC1 0x903
+#define STM32H7_PA9_FUNC_LPUART1_TX 0x904
+#define STM32H7_PA9_FUNC_I2C3_SMBA 0x905
+#define STM32H7_PA9_FUNC_SPI2_SCK_I2S2_CK 0x906
+#define STM32H7_PA9_FUNC_USART1_TX 0x908
+#define STM32H7_PA9_FUNC_CAN1_RXFD 0x90a
+#define STM32H7_PA9_FUNC_ETH_TX_ER 0x90c
+#define STM32H7_PA9_FUNC_DCMI_D0 0x90e
+#define STM32H7_PA9_FUNC_LCD_R5 0x90f
+#define STM32H7_PA9_FUNC_EVENTOUT 0x910
+#define STM32H7_PA9_FUNC_ANALOG 0x911
+
+#define STM32H7_PA10_FUNC_GPIO 0xa00
+#define STM32H7_PA10_FUNC_TIM1_CH3 0xa02
+#define STM32H7_PA10_FUNC_HRTIM_CHC2 0xa03
+#define STM32H7_PA10_FUNC_LPUART1_RX 0xa04
+#define STM32H7_PA10_FUNC_USART1_RX 0xa08
+#define STM32H7_PA10_FUNC_CAN1_TXFD 0xa0a
+#define STM32H7_PA10_FUNC_OTG_FS_ID 0xa0b
+#define STM32H7_PA10_FUNC_MDIOS_MDIO 0xa0c
+#define STM32H7_PA10_FUNC_LCD_B4 0xa0d
+#define STM32H7_PA10_FUNC_DCMI_D1 0xa0e
+#define STM32H7_PA10_FUNC_LCD_B1 0xa0f
+#define STM32H7_PA10_FUNC_EVENTOUT 0xa10
+#define STM32H7_PA10_FUNC_ANALOG 0xa11
+
+#define STM32H7_PA11_FUNC_GPIO 0xb00
+#define STM32H7_PA11_FUNC_TIM1_CH4 0xb02
+#define STM32H7_PA11_FUNC_HRTIM_CHD1 0xb03
+#define STM32H7_PA11_FUNC_LPUART1_CTS 0xb04
+#define STM32H7_PA11_FUNC_SPI2_NSS_I2S2_WS 0xb06
+#define STM32H7_PA11_FUNC_UART4_RX 0xb07
+#define STM32H7_PA11_FUNC_USART1_CTS_NSS 0xb08
+#define STM32H7_PA11_FUNC_CAN1_RX 0xb0a
+#define STM32H7_PA11_FUNC_OTG_FS_DM 0xb0b
+#define STM32H7_PA11_FUNC_LCD_R4 0xb0f
+#define STM32H7_PA11_FUNC_EVENTOUT 0xb10
+#define STM32H7_PA11_FUNC_ANALOG 0xb11
+
+#define STM32H7_PA12_FUNC_GPIO 0xc00
+#define STM32H7_PA12_FUNC_TIM1_ETR 0xc02
+#define STM32H7_PA12_FUNC_HRTIM_CHD2 0xc03
+#define STM32H7_PA12_FUNC_LPUART1_RTS 0xc04
+#define STM32H7_PA12_FUNC_SPI2_SCK_I2S2_CK 0xc06
+#define STM32H7_PA12_FUNC_UART4_TX 0xc07
+#define STM32H7_PA12_FUNC_USART1_RTS 0xc08
+#define STM32H7_PA12_FUNC_SAI2_FS_B 0xc09
+#define STM32H7_PA12_FUNC_CAN1_TX 0xc0a
+#define STM32H7_PA12_FUNC_OTG_FS_DP 0xc0b
+#define STM32H7_PA12_FUNC_LCD_R5 0xc0f
+#define STM32H7_PA12_FUNC_EVENTOUT 0xc10
+#define STM32H7_PA12_FUNC_ANALOG 0xc11
+
+#define STM32H7_PA13_FUNC_GPIO 0xd00
+#define STM32H7_PA13_FUNC_JTMS_SWDIO 0xd01
+#define STM32H7_PA13_FUNC_EVENTOUT 0xd10
+#define STM32H7_PA13_FUNC_ANALOG 0xd11
+
+#define STM32H7_PA14_FUNC_GPIO 0xe00
+#define STM32H7_PA14_FUNC_JTCK_SWCLK 0xe01
+#define STM32H7_PA14_FUNC_EVENTOUT 0xe10
+#define STM32H7_PA14_FUNC_ANALOG 0xe11
+
+#define STM32H7_PA15_FUNC_GPIO 0xf00
+#define STM32H7_PA15_FUNC_JTDI 0xf01
+#define STM32H7_PA15_FUNC_TIM2_CH1_TIM2_ETR 0xf02
+#define STM32H7_PA15_FUNC_HRTIM_FLT1 0xf03
+#define STM32H7_PA15_FUNC_HDMI_CEC 0xf05
+#define STM32H7_PA15_FUNC_SPI1_NSS_I2S1_WS 0xf06
+#define STM32H7_PA15_FUNC_SPI3_NSS_I2S3_WS 0xf07
+#define STM32H7_PA15_FUNC_SPI6_NSS 0xf08
+#define STM32H7_PA15_FUNC_UART4_RTS 0xf09
+#define STM32H7_PA15_FUNC_UART7_TX 0xf0c
+#define STM32H7_PA15_FUNC_DSI_TE 0xf0e
+#define STM32H7_PA15_FUNC_EVENTOUT 0xf10
+#define STM32H7_PA15_FUNC_ANALOG 0xf11
+
+#define STM32H7_PB0_FUNC_GPIO 0x1000
+#define STM32H7_PB0_FUNC_TIM1_CH2N 0x1002
+#define STM32H7_PB0_FUNC_TIM3_CH3 0x1003
+#define STM32H7_PB0_FUNC_TIM8_CH2N 0x1004
+#define STM32H7_PB0_FUNC_DFSDM_CKOUT 0x1007
+#define STM32H7_PB0_FUNC_UART4_CTS 0x1009
+#define STM32H7_PB0_FUNC_LCD_R3 0x100a
+#define STM32H7_PB0_FUNC_OTG_HS_ULPI_D1 0x100b
+#define STM32H7_PB0_FUNC_ETH_MII_RXD2 0x100c
+#define STM32H7_PB0_FUNC_LCD_G1 0x100f
+#define STM32H7_PB0_FUNC_EVENTOUT 0x1010
+#define STM32H7_PB0_FUNC_ANALOG 0x1011
+
+#define STM32H7_PB1_FUNC_GPIO 0x1100
+#define STM32H7_PB1_FUNC_TIM1_CH3N 0x1102
+#define STM32H7_PB1_FUNC_TIM3_CH4 0x1103
+#define STM32H7_PB1_FUNC_TIM8_CH3N 0x1104
+#define STM32H7_PB1_FUNC_DFSDM_DATIN1 0x1107
+#define STM32H7_PB1_FUNC_LCD_R6 0x110a
+#define STM32H7_PB1_FUNC_OTG_HS_ULPI_D2 0x110b
+#define STM32H7_PB1_FUNC_ETH_MII_RXD3 0x110c
+#define STM32H7_PB1_FUNC_LCD_G0 0x110f
+#define STM32H7_PB1_FUNC_EVENTOUT 0x1110
+#define STM32H7_PB1_FUNC_ANALOG 0x1111
+
+#define STM32H7_PB2_FUNC_GPIO 0x1200
+#define STM32H7_PB2_FUNC_SAI1_D1 0x1203
+#define STM32H7_PB2_FUNC_DFSDM_CKIN1 0x1205
+#define STM32H7_PB2_FUNC_SAI1_SD_A 0x1207
+#define STM32H7_PB2_FUNC_SPI3_MOSI_I2S3_SDO 0x1208
+#define STM32H7_PB2_FUNC_SAI4_SD_A 0x1209
+#define STM32H7_PB2_FUNC_QUADSPI_CLK 0x120a
+#define STM32H7_PB2_FUNC_SAI4_D1 0x120b
+#define STM32H7_PB2_FUNC_ETH_TX_ER 0x120c
+#define STM32H7_PB2_FUNC_EVENTOUT 0x1210
+#define STM32H7_PB2_FUNC_ANALOG 0x1211
+
+#define STM32H7_PB3_FUNC_GPIO 0x1300
+#define STM32H7_PB3_FUNC_JTDO_TRACESWO 0x1301
+#define STM32H7_PB3_FUNC_TIM2_CH2 0x1302
+#define STM32H7_PB3_FUNC_HRTIM_FLT4 0x1303
+#define STM32H7_PB3_FUNC_SPI1_SCK_I2S1_CK 0x1306
+#define STM32H7_PB3_FUNC_SPI3_SCK_I2S3_CK 0x1307
+#define STM32H7_PB3_FUNC_SPI6_SCK 0x1309
+#define STM32H7_PB3_FUNC_SDMMC2_D2 0x130a
+#define STM32H7_PB3_FUNC_UART7_RX 0x130c
+#define STM32H7_PB3_FUNC_EVENTOUT 0x1310
+#define STM32H7_PB3_FUNC_ANALOG 0x1311
+
+#define STM32H7_PB4_FUNC_GPIO 0x1400
+#define STM32H7_PB4_FUNC_NJTRST 0x1401
+#define STM32H7_PB4_FUNC_TIM16_BKIN 0x1402
+#define STM32H7_PB4_FUNC_TIM3_CH1 0x1403
+#define STM32H7_PB4_FUNC_HRTIM_EEV6 0x1404
+#define STM32H7_PB4_FUNC_SPI1_MISO_I2S1_SDI 0x1406
+#define STM32H7_PB4_FUNC_SPI3_MISO_I2S3_SDI 0x1407
+#define STM32H7_PB4_FUNC_SPI2_NSS_I2S2_WS 0x1408
+#define STM32H7_PB4_FUNC_SPI6_MISO 0x1409
+#define STM32H7_PB4_FUNC_SDMMC2_D3 0x140a
+#define STM32H7_PB4_FUNC_UART7_TX 0x140c
+#define STM32H7_PB4_FUNC_EVENTOUT 0x1410
+#define STM32H7_PB4_FUNC_ANALOG 0x1411
+
+#define STM32H7_PB5_FUNC_GPIO 0x1500
+#define STM32H7_PB5_FUNC_TIM17_BKIN 0x1502
+#define STM32H7_PB5_FUNC_TIM3_CH2 0x1503
+#define STM32H7_PB5_FUNC_HRTIM_EEV7 0x1504
+#define STM32H7_PB5_FUNC_I2C1_SMBA 0x1505
+#define STM32H7_PB5_FUNC_SPI1_MOSI_I2S1_SDO 0x1506
+#define STM32H7_PB5_FUNC_I2C4_SMBA 0x1507
+#define STM32H7_PB5_FUNC_SPI3_MOSI_I2S3_SDO 0x1508
+#define STM32H7_PB5_FUNC_SPI6_MOSI 0x1509
+#define STM32H7_PB5_FUNC_CAN2_RX 0x150a
+#define STM32H7_PB5_FUNC_OTG_HS_ULPI_D7 0x150b
+#define STM32H7_PB5_FUNC_ETH_PPS_OUT 0x150c
+#define STM32H7_PB5_FUNC_FMC_SDCKE1 0x150d
+#define STM32H7_PB5_FUNC_DCMI_D10 0x150e
+#define STM32H7_PB5_FUNC_UART5_RX 0x150f
+#define STM32H7_PB5_FUNC_EVENTOUT 0x1510
+#define STM32H7_PB5_FUNC_ANALOG 0x1511
+
+#define STM32H7_PB6_FUNC_GPIO 0x1600
+#define STM32H7_PB6_FUNC_TIM16_CH1N 0x1602
+#define STM32H7_PB6_FUNC_TIM4_CH1 0x1603
+#define STM32H7_PB6_FUNC_HRTIM_EEV8 0x1604
+#define STM32H7_PB6_FUNC_I2C1_SCL 0x1605
+#define STM32H7_PB6_FUNC_HDMI_CEC 0x1606
+#define STM32H7_PB6_FUNC_I2C4_SCL 0x1607
+#define STM32H7_PB6_FUNC_USART1_TX 0x1608
+#define STM32H7_PB6_FUNC_LPUART1_TX 0x1609
+#define STM32H7_PB6_FUNC_CAN2_TX 0x160a
+#define STM32H7_PB6_FUNC_QUADSPI_BK1_NCS 0x160b
+#define STM32H7_PB6_FUNC_DFSDM_DATIN5 0x160c
+#define STM32H7_PB6_FUNC_FMC_SDNE1 0x160d
+#define STM32H7_PB6_FUNC_DCMI_D5 0x160e
+#define STM32H7_PB6_FUNC_UART5_TX 0x160f
+#define STM32H7_PB6_FUNC_EVENTOUT 0x1610
+#define STM32H7_PB6_FUNC_ANALOG 0x1611
+
+#define STM32H7_PB7_FUNC_GPIO 0x1700
+#define STM32H7_PB7_FUNC_TIM17_CH1N 0x1702
+#define STM32H7_PB7_FUNC_TIM4_CH2 0x1703
+#define STM32H7_PB7_FUNC_HRTIM_EEV9 0x1704
+#define STM32H7_PB7_FUNC_I2C1_SDA 0x1705
+#define STM32H7_PB7_FUNC_I2C4_SDA 0x1707
+#define STM32H7_PB7_FUNC_USART1_RX 0x1708
+#define STM32H7_PB7_FUNC_LPUART1_RX 0x1709
+#define STM32H7_PB7_FUNC_CAN2_TXFD 0x170a
+#define STM32H7_PB7_FUNC_DFSDM_CKIN5 0x170c
+#define STM32H7_PB7_FUNC_FMC_NL 0x170d
+#define STM32H7_PB7_FUNC_DCMI_VSYNC 0x170e
+#define STM32H7_PB7_FUNC_EVENTOUT 0x1710
+#define STM32H7_PB7_FUNC_ANALOG 0x1711
+
+#define STM32H7_PB8_FUNC_GPIO 0x1800
+#define STM32H7_PB8_FUNC_TIM16_CH1 0x1802
+#define STM32H7_PB8_FUNC_TIM4_CH3 0x1803
+#define STM32H7_PB8_FUNC_DFSDM_CKIN7 0x1804
+#define STM32H7_PB8_FUNC_I2C1_SCL 0x1805
+#define STM32H7_PB8_FUNC_I2C4_SCL 0x1807
+#define STM32H7_PB8_FUNC_SDMMC1_CKIN 0x1808
+#define STM32H7_PB8_FUNC_UART4_RX 0x1809
+#define STM32H7_PB8_FUNC_CAN1_RX 0x180a
+#define STM32H7_PB8_FUNC_SDMMC2_D4 0x180b
+#define STM32H7_PB8_FUNC_ETH_MII_TXD3 0x180c
+#define STM32H7_PB8_FUNC_SDMMC1_D4 0x180d
+#define STM32H7_PB8_FUNC_DCMI_D6 0x180e
+#define STM32H7_PB8_FUNC_LCD_B6 0x180f
+#define STM32H7_PB8_FUNC_EVENTOUT 0x1810
+#define STM32H7_PB8_FUNC_ANALOG 0x1811
+
+#define STM32H7_PB9_FUNC_GPIO 0x1900
+#define STM32H7_PB9_FUNC_TIM17_CH1 0x1902
+#define STM32H7_PB9_FUNC_TIM4_CH4 0x1903
+#define STM32H7_PB9_FUNC_DFSDM_DATIN7 0x1904
+#define STM32H7_PB9_FUNC_I2C1_SDA 0x1905
+#define STM32H7_PB9_FUNC_SPI2_NSS_I2S2_WS 0x1906
+#define STM32H7_PB9_FUNC_I2C4_SDA 0x1907
+#define STM32H7_PB9_FUNC_SDMMC1_CDIR 0x1908
+#define STM32H7_PB9_FUNC_UART4_TX 0x1909
+#define STM32H7_PB9_FUNC_CAN1_TX 0x190a
+#define STM32H7_PB9_FUNC_SDMMC2_D5 0x190b
+#define STM32H7_PB9_FUNC_I2C4_SMBA 0x190c
+#define STM32H7_PB9_FUNC_SDMMC1_D5 0x190d
+#define STM32H7_PB9_FUNC_DCMI_D7 0x190e
+#define STM32H7_PB9_FUNC_LCD_B7 0x190f
+#define STM32H7_PB9_FUNC_EVENTOUT 0x1910
+#define STM32H7_PB9_FUNC_ANALOG 0x1911
+
+#define STM32H7_PB10_FUNC_GPIO 0x1a00
+#define STM32H7_PB10_FUNC_TIM2_CH3 0x1a02
+#define STM32H7_PB10_FUNC_HRTIM_SCOUT 0x1a03
+#define STM32H7_PB10_FUNC_LPTIM2_IN1 0x1a04
+#define STM32H7_PB10_FUNC_I2C2_SCL 0x1a05
+#define STM32H7_PB10_FUNC_SPI2_SCK_I2S2_CK 0x1a06
+#define STM32H7_PB10_FUNC_DFSDM_DATIN7 0x1a07
+#define STM32H7_PB10_FUNC_USART3_TX 0x1a08
+#define STM32H7_PB10_FUNC_QUADSPI_BK1_NCS 0x1a0a
+#define STM32H7_PB10_FUNC_OTG_HS_ULPI_D3 0x1a0b
+#define STM32H7_PB10_FUNC_ETH_MII_RX_ER 0x1a0c
+#define STM32H7_PB10_FUNC_LCD_G4 0x1a0f
+#define STM32H7_PB10_FUNC_EVENTOUT 0x1a10
+#define STM32H7_PB10_FUNC_ANALOG 0x1a11
+
+#define STM32H7_PB11_FUNC_GPIO 0x1b00
+#define STM32H7_PB11_FUNC_TIM2_CH4 0x1b02
+#define STM32H7_PB11_FUNC_HRTIM_SCIN 0x1b03
+#define STM32H7_PB11_FUNC_LPTIM2_ETR 0x1b04
+#define STM32H7_PB11_FUNC_I2C2_SDA 0x1b05
+#define STM32H7_PB11_FUNC_DFSDM_CKIN7 0x1b07
+#define STM32H7_PB11_FUNC_USART3_RX 0x1b08
+#define STM32H7_PB11_FUNC_OTG_HS_ULPI_D4 0x1b0b
+#define STM32H7_PB11_FUNC_ETH_MII_TX_EN_ETH_RMII_TX_EN 0x1b0c
+#define STM32H7_PB11_FUNC_DSI_TE 0x1b0e
+#define STM32H7_PB11_FUNC_LCD_G5 0x1b0f
+#define STM32H7_PB11_FUNC_EVENTOUT 0x1b10
+#define STM32H7_PB11_FUNC_ANALOG 0x1b11
+
+#define STM32H7_PB12_FUNC_GPIO 0x1c00
+#define STM32H7_PB12_FUNC_TIM1_BKIN 0x1c02
+#define STM32H7_PB12_FUNC_I2C2_SMBA 0x1c05
+#define STM32H7_PB12_FUNC_SPI2_NSS_I2S2_WS 0x1c06
+#define STM32H7_PB12_FUNC_DFSDM_DATIN1 0x1c07
+#define STM32H7_PB12_FUNC_USART3_CK 0x1c08
+#define STM32H7_PB12_FUNC_CAN2_RX 0x1c0a
+#define STM32H7_PB12_FUNC_OTG_HS_ULPI_D5 0x1c0b
+#define STM32H7_PB12_FUNC_ETH_MII_TXD0_ETH_RMII_TXD0 0x1c0c
+#define STM32H7_PB12_FUNC_OTG_HS_ID 0x1c0d
+#define STM32H7_PB12_FUNC_TIM1_BKIN_COMP12 0x1c0e
+#define STM32H7_PB12_FUNC_UART5_RX 0x1c0f
+#define STM32H7_PB12_FUNC_EVENTOUT 0x1c10
+#define STM32H7_PB12_FUNC_ANALOG 0x1c11
+
+#define STM32H7_PB13_FUNC_GPIO 0x1d00
+#define STM32H7_PB13_FUNC_TIM1_CH1N 0x1d02
+#define STM32H7_PB13_FUNC_LPTIM2_OUT 0x1d04
+#define STM32H7_PB13_FUNC_SPI2_SCK_I2S2_CK 0x1d06
+#define STM32H7_PB13_FUNC_DFSDM_CKIN1 0x1d07
+#define STM32H7_PB13_FUNC_USART3_CTS_NSS 0x1d08
+#define STM32H7_PB13_FUNC_CAN2_TX 0x1d0a
+#define STM32H7_PB13_FUNC_OTG_HS_ULPI_D6 0x1d0b
+#define STM32H7_PB13_FUNC_ETH_MII_TXD1_ETH_RMII_TXD1 0x1d0c
+#define STM32H7_PB13_FUNC_UART5_TX 0x1d0f
+#define STM32H7_PB13_FUNC_EVENTOUT 0x1d10
+#define STM32H7_PB13_FUNC_ANALOG 0x1d11
+
+#define STM32H7_PB14_FUNC_GPIO 0x1e00
+#define STM32H7_PB14_FUNC_TIM1_CH2N 0x1e02
+#define STM32H7_PB14_FUNC_TIM8_CH2N 0x1e04
+#define STM32H7_PB14_FUNC_USART1_TX 0x1e05
+#define STM32H7_PB14_FUNC_SPI2_MISO_I2S2_SDI 0x1e06
+#define STM32H7_PB14_FUNC_DFSDM_DATIN2 0x1e07
+#define STM32H7_PB14_FUNC_USART3_RTS 0x1e08
+#define STM32H7_PB14_FUNC_UART4_RTS 0x1e09
+#define STM32H7_PB14_FUNC_SDMMC2_D0 0x1e0a
+#define STM32H7_PB14_FUNC_OTG_HS_DM 0x1e0d
+#define STM32H7_PB14_FUNC_EVENTOUT 0x1e10
+#define STM32H7_PB14_FUNC_ANALOG 0x1e11
+
+#define STM32H7_PB15_FUNC_GPIO 0x1f00
+#define STM32H7_PB15_FUNC_RTC_REFIN 0x1f01
+#define STM32H7_PB15_FUNC_TIM1_CH3N 0x1f02
+#define STM32H7_PB15_FUNC_TIM8_CH3N 0x1f04
+#define STM32H7_PB15_FUNC_USART1_RX 0x1f05
+#define STM32H7_PB15_FUNC_SPI2_MOSI_I2S2_SDO 0x1f06
+#define STM32H7_PB15_FUNC_DFSDM_CKIN2 0x1f07
+#define STM32H7_PB15_FUNC_UART4_CTS 0x1f09
+#define STM32H7_PB15_FUNC_SDMMC2_D1 0x1f0a
+#define STM32H7_PB15_FUNC_OTG_HS_DP 0x1f0d
+#define STM32H7_PB15_FUNC_EVENTOUT 0x1f10
+#define STM32H7_PB15_FUNC_ANALOG 0x1f11
+
+#define STM32H7_PC0_FUNC_GPIO 0x2000
+#define STM32H7_PC0_FUNC_DFSDM_CKIN0 0x2004
+#define STM32H7_PC0_FUNC_DFSDM_DATIN4 0x2007
+#define STM32H7_PC0_FUNC_SAI2_FS_B 0x2009
+#define STM32H7_PC0_FUNC_OTG_HS_ULPI_STP 0x200b
+#define STM32H7_PC0_FUNC_FMC_SDNWE 0x200d
+#define STM32H7_PC0_FUNC_LCD_R5 0x200f
+#define STM32H7_PC0_FUNC_EVENTOUT 0x2010
+#define STM32H7_PC0_FUNC_ANALOG 0x2011
+
+#define STM32H7_PC1_FUNC_GPIO 0x2100
+#define STM32H7_PC1_FUNC_TRACED0 0x2101
+#define STM32H7_PC1_FUNC_SAI1_D1 0x2103
+#define STM32H7_PC1_FUNC_DFSDM_DATIN0 0x2104
+#define STM32H7_PC1_FUNC_DFSDM_CKIN4 0x2105
+#define STM32H7_PC1_FUNC_SPI2_MOSI_I2S2_SDO 0x2106
+#define STM32H7_PC1_FUNC_SAI1_SD_A 0x2107
+#define STM32H7_PC1_FUNC_SAI4_SD_A 0x2109
+#define STM32H7_PC1_FUNC_SDMMC2_CK 0x210a
+#define STM32H7_PC1_FUNC_SAI4_D1 0x210b
+#define STM32H7_PC1_FUNC_ETH_MDC 0x210c
+#define STM32H7_PC1_FUNC_MDIOS_MDC 0x210d
+#define STM32H7_PC1_FUNC_EVENTOUT 0x2110
+#define STM32H7_PC1_FUNC_ANALOG 0x2111
+
+#define STM32H7_PC2_FUNC_GPIO 0x2200
+#define STM32H7_PC2_FUNC_DFSDM_CKIN1 0x2204
+#define STM32H7_PC2_FUNC_SPI2_MISO_I2S2_SDI 0x2206
+#define STM32H7_PC2_FUNC_DFSDM_CKOUT 0x2207
+#define STM32H7_PC2_FUNC_OTG_HS_ULPI_DIR 0x220b
+#define STM32H7_PC2_FUNC_ETH_MII_TXD2 0x220c
+#define STM32H7_PC2_FUNC_FMC_SDNE0 0x220d
+#define STM32H7_PC2_FUNC_EVENTOUT 0x2210
+#define STM32H7_PC2_FUNC_ANALOG 0x2211
+
+#define STM32H7_PC3_FUNC_GPIO 0x2300
+#define STM32H7_PC3_FUNC_DFSDM_DATIN1 0x2304
+#define STM32H7_PC3_FUNC_SPI2_MOSI_I2S2_SDO 0x2306
+#define STM32H7_PC3_FUNC_OTG_HS_ULPI_NXT 0x230b
+#define STM32H7_PC3_FUNC_ETH_MII_TX_CLK 0x230c
+#define STM32H7_PC3_FUNC_FMC_SDCKE0 0x230d
+#define STM32H7_PC3_FUNC_EVENTOUT 0x2310
+#define STM32H7_PC3_FUNC_ANALOG 0x2311
+
+#define STM32H7_PC4_FUNC_GPIO 0x2400
+#define STM32H7_PC4_FUNC_DFSDM_CKIN2 0x2404
+#define STM32H7_PC4_FUNC_I2S1_MCK 0x2406
+#define STM32H7_PC4_FUNC_SPDIFRX_IN2 0x240a
+#define STM32H7_PC4_FUNC_ETH_MII_RXD0_ETH_RMII_RXD0 0x240c
+#define STM32H7_PC4_FUNC_FMC_SDNE0 0x240d
+#define STM32H7_PC4_FUNC_EVENTOUT 0x2410
+#define STM32H7_PC4_FUNC_ANALOG 0x2411
+
+#define STM32H7_PC5_FUNC_GPIO 0x2500
+#define STM32H7_PC5_FUNC_SAI1_D3 0x2503
+#define STM32H7_PC5_FUNC_DFSDM_DATIN2 0x2504
+#define STM32H7_PC5_FUNC_SPDIFRX_IN3 0x250a
+#define STM32H7_PC5_FUNC_SAI4_D3 0x250b
+#define STM32H7_PC5_FUNC_ETH_MII_RXD1_ETH_RMII_RXD1 0x250c
+#define STM32H7_PC5_FUNC_FMC_SDCKE0 0x250d
+#define STM32H7_PC5_FUNC_COMP_1_OUT 0x250e
+#define STM32H7_PC5_FUNC_EVENTOUT 0x2510
+#define STM32H7_PC5_FUNC_ANALOG 0x2511
+
+#define STM32H7_PC6_FUNC_GPIO 0x2600
+#define STM32H7_PC6_FUNC_HRTIM_CHA1 0x2602
+#define STM32H7_PC6_FUNC_TIM3_CH1 0x2603
+#define STM32H7_PC6_FUNC_TIM8_CH1 0x2604
+#define STM32H7_PC6_FUNC_DFSDM_CKIN3 0x2605
+#define STM32H7_PC6_FUNC_I2S2_MCK 0x2606
+#define STM32H7_PC6_FUNC_USART6_TX 0x2608
+#define STM32H7_PC6_FUNC_SDMMC1_D0DIR 0x2609
+#define STM32H7_PC6_FUNC_FMC_NWAIT 0x260a
+#define STM32H7_PC6_FUNC_SDMMC2_D6 0x260b
+#define STM32H7_PC6_FUNC_SDMMC1_D6 0x260d
+#define STM32H7_PC6_FUNC_DCMI_D0 0x260e
+#define STM32H7_PC6_FUNC_LCD_HSYNC 0x260f
+#define STM32H7_PC6_FUNC_EVENTOUT 0x2610
+#define STM32H7_PC6_FUNC_ANALOG 0x2611
+
+#define STM32H7_PC7_FUNC_GPIO 0x2700
+#define STM32H7_PC7_FUNC_TRGIO 0x2701
+#define STM32H7_PC7_FUNC_HRTIM_CHA2 0x2702
+#define STM32H7_PC7_FUNC_TIM3_CH2 0x2703
+#define STM32H7_PC7_FUNC_TIM8_CH2 0x2704
+#define STM32H7_PC7_FUNC_DFSDM_DATIN3 0x2705
+#define STM32H7_PC7_FUNC_I2S3_MCK 0x2707
+#define STM32H7_PC7_FUNC_USART6_RX 0x2708
+#define STM32H7_PC7_FUNC_SDMMC1_D123DIR 0x2709
+#define STM32H7_PC7_FUNC_FMC_NE1 0x270a
+#define STM32H7_PC7_FUNC_SDMMC2_D7 0x270b
+#define STM32H7_PC7_FUNC_SWPMI_TX 0x270c
+#define STM32H7_PC7_FUNC_SDMMC1_D7 0x270d
+#define STM32H7_PC7_FUNC_DCMI_D1 0x270e
+#define STM32H7_PC7_FUNC_LCD_G6 0x270f
+#define STM32H7_PC7_FUNC_EVENTOUT 0x2710
+#define STM32H7_PC7_FUNC_ANALOG 0x2711
+
+#define STM32H7_PC8_FUNC_GPIO 0x2800
+#define STM32H7_PC8_FUNC_TRACED1 0x2801
+#define STM32H7_PC8_FUNC_HRTIM_CHB1 0x2802
+#define STM32H7_PC8_FUNC_TIM3_CH3 0x2803
+#define STM32H7_PC8_FUNC_TIM8_CH3 0x2804
+#define STM32H7_PC8_FUNC_USART6_CK 0x2808
+#define STM32H7_PC8_FUNC_UART5_RTS 0x2809
+#define STM32H7_PC8_FUNC_FMC_NE2_FMC_NCE 0x280a
+#define STM32H7_PC8_FUNC_SWPMI_RX 0x280c
+#define STM32H7_PC8_FUNC_SDMMC1_D0 0x280d
+#define STM32H7_PC8_FUNC_DCMI_D2 0x280e
+#define STM32H7_PC8_FUNC_EVENTOUT 0x2810
+#define STM32H7_PC8_FUNC_ANALOG 0x2811
+
+#define STM32H7_PC9_FUNC_GPIO 0x2900
+#define STM32H7_PC9_FUNC_MCO2 0x2901
+#define STM32H7_PC9_FUNC_TIM3_CH4 0x2903
+#define STM32H7_PC9_FUNC_TIM8_CH4 0x2904
+#define STM32H7_PC9_FUNC_I2C3_SDA 0x2905
+#define STM32H7_PC9_FUNC_I2S_CKIN 0x2906
+#define STM32H7_PC9_FUNC_UART5_CTS 0x2909
+#define STM32H7_PC9_FUNC_QUADSPI_BK1_IO0 0x290a
+#define STM32H7_PC9_FUNC_LCD_G3 0x290b
+#define STM32H7_PC9_FUNC_SWPMI_SUSPEND 0x290c
+#define STM32H7_PC9_FUNC_SDMMC1_D1 0x290d
+#define STM32H7_PC9_FUNC_DCMI_D3 0x290e
+#define STM32H7_PC9_FUNC_LCD_B2 0x290f
+#define STM32H7_PC9_FUNC_EVENTOUT 0x2910
+#define STM32H7_PC9_FUNC_ANALOG 0x2911
+
+#define STM32H7_PC10_FUNC_GPIO 0x2a00
+#define STM32H7_PC10_FUNC_HRTIM_EEV1 0x2a03
+#define STM32H7_PC10_FUNC_DFSDM_CKIN5 0x2a04
+#define STM32H7_PC10_FUNC_SPI3_SCK_I2S3_CK 0x2a07
+#define STM32H7_PC10_FUNC_USART3_TX 0x2a08
+#define STM32H7_PC10_FUNC_UART4_TX 0x2a09
+#define STM32H7_PC10_FUNC_QUADSPI_BK1_IO1 0x2a0a
+#define STM32H7_PC10_FUNC_SDMMC1_D2 0x2a0d
+#define STM32H7_PC10_FUNC_DCMI_D8 0x2a0e
+#define STM32H7_PC10_FUNC_LCD_R2 0x2a0f
+#define STM32H7_PC10_FUNC_EVENTOUT 0x2a10
+#define STM32H7_PC10_FUNC_ANALOG 0x2a11
+
+#define STM32H7_PC11_FUNC_GPIO 0x2b00
+#define STM32H7_PC11_FUNC_HRTIM_FLT2 0x2b03
+#define STM32H7_PC11_FUNC_DFSDM_DATIN5 0x2b04
+#define STM32H7_PC11_FUNC_SPI3_MISO_I2S3_SDI 0x2b07
+#define STM32H7_PC11_FUNC_USART3_RX 0x2b08
+#define STM32H7_PC11_FUNC_UART4_RX 0x2b09
+#define STM32H7_PC11_FUNC_QUADSPI_BK2_NCS 0x2b0a
+#define STM32H7_PC11_FUNC_SDMMC1_D3 0x2b0d
+#define STM32H7_PC11_FUNC_DCMI_D4 0x2b0e
+#define STM32H7_PC11_FUNC_EVENTOUT 0x2b10
+#define STM32H7_PC11_FUNC_ANALOG 0x2b11
+
+#define STM32H7_PC12_FUNC_GPIO 0x2c00
+#define STM32H7_PC12_FUNC_TRACED3 0x2c01
+#define STM32H7_PC12_FUNC_HRTIM_EEV2 0x2c03
+#define STM32H7_PC12_FUNC_SPI3_MOSI_I2S3_SDO 0x2c07
+#define STM32H7_PC12_FUNC_USART3_CK 0x2c08
+#define STM32H7_PC12_FUNC_UART5_TX 0x2c09
+#define STM32H7_PC12_FUNC_SDMMC1_CK 0x2c0d
+#define STM32H7_PC12_FUNC_DCMI_D9 0x2c0e
+#define STM32H7_PC12_FUNC_EVENTOUT 0x2c10
+#define STM32H7_PC12_FUNC_ANALOG 0x2c11
+
+#define STM32H7_PC13_FUNC_GPIO 0x2d00
+#define STM32H7_PC13_FUNC_EVENTOUT 0x2d10
+#define STM32H7_PC13_FUNC_ANALOG 0x2d11
+
+#define STM32H7_PC14_FUNC_GPIO 0x2e00
+#define STM32H7_PC14_FUNC_EVENTOUT 0x2e10
+#define STM32H7_PC14_FUNC_ANALOG 0x2e11
+
+#define STM32H7_PC15_FUNC_GPIO 0x2f00
+#define STM32H7_PC15_FUNC_EVENTOUT 0x2f10
+#define STM32H7_PC15_FUNC_ANALOG 0x2f11
+
+#define STM32H7_PD0_FUNC_GPIO 0x3000
+#define STM32H7_PD0_FUNC_DFSDM_CKIN6 0x3004
+#define STM32H7_PD0_FUNC_SAI3_SCK_A 0x3007
+#define STM32H7_PD0_FUNC_UART4_RX 0x3009
+#define STM32H7_PD0_FUNC_CAN1_RX 0x300a
+#define STM32H7_PD0_FUNC_FMC_D2_FMC_DA2 0x300d
+#define STM32H7_PD0_FUNC_EVENTOUT 0x3010
+#define STM32H7_PD0_FUNC_ANALOG 0x3011
+
+#define STM32H7_PD1_FUNC_GPIO 0x3100
+#define STM32H7_PD1_FUNC_DFSDM_DATIN6 0x3104
+#define STM32H7_PD1_FUNC_SAI3_SD_A 0x3107
+#define STM32H7_PD1_FUNC_UART4_TX 0x3109
+#define STM32H7_PD1_FUNC_CAN1_TX 0x310a
+#define STM32H7_PD1_FUNC_FMC_D3_FMC_DA3 0x310d
+#define STM32H7_PD1_FUNC_EVENTOUT 0x3110
+#define STM32H7_PD1_FUNC_ANALOG 0x3111
+
+#define STM32H7_PD2_FUNC_GPIO 0x3200
+#define STM32H7_PD2_FUNC_TRACED2 0x3201
+#define STM32H7_PD2_FUNC_TIM3_ETR 0x3203
+#define STM32H7_PD2_FUNC_UART5_RX 0x3209
+#define STM32H7_PD2_FUNC_SDMMC1_CMD 0x320d
+#define STM32H7_PD2_FUNC_DCMI_D11 0x320e
+#define STM32H7_PD2_FUNC_EVENTOUT 0x3210
+#define STM32H7_PD2_FUNC_ANALOG 0x3211
+
+#define STM32H7_PD3_FUNC_GPIO 0x3300
+#define STM32H7_PD3_FUNC_DFSDM_CKOUT 0x3304
+#define STM32H7_PD3_FUNC_SPI2_SCK_I2S2_CK 0x3306
+#define STM32H7_PD3_FUNC_USART2_CTS_NSS 0x3308
+#define STM32H7_PD3_FUNC_FMC_CLK 0x330d
+#define STM32H7_PD3_FUNC_DCMI_D5 0x330e
+#define STM32H7_PD3_FUNC_LCD_G7 0x330f
+#define STM32H7_PD3_FUNC_EVENTOUT 0x3310
+#define STM32H7_PD3_FUNC_ANALOG 0x3311
+
+#define STM32H7_PD4_FUNC_GPIO 0x3400
+#define STM32H7_PD4_FUNC_HRTIM_FLT3 0x3403
+#define STM32H7_PD4_FUNC_SAI3_FS_A 0x3407
+#define STM32H7_PD4_FUNC_USART2_RTS 0x3408
+#define STM32H7_PD4_FUNC_CAN1_RXFD 0x340a
+#define STM32H7_PD4_FUNC_FMC_NOE 0x340d
+#define STM32H7_PD4_FUNC_EVENTOUT 0x3410
+#define STM32H7_PD4_FUNC_ANALOG 0x3411
+
+#define STM32H7_PD5_FUNC_GPIO 0x3500
+#define STM32H7_PD5_FUNC_HRTIM_EEV3 0x3503
+#define STM32H7_PD5_FUNC_USART2_TX 0x3508
+#define STM32H7_PD5_FUNC_CAN1_TXFD 0x350a
+#define STM32H7_PD5_FUNC_FMC_NWE 0x350d
+#define STM32H7_PD5_FUNC_EVENTOUT 0x3510
+#define STM32H7_PD5_FUNC_ANALOG 0x3511
+
+#define STM32H7_PD6_FUNC_GPIO 0x3600
+#define STM32H7_PD6_FUNC_SAI1_D1 0x3603
+#define STM32H7_PD6_FUNC_DFSDM_CKIN4 0x3604
+#define STM32H7_PD6_FUNC_DFSDM_DATIN1 0x3605
+#define STM32H7_PD6_FUNC_SPI3_MOSI_I2S3_SDO 0x3606
+#define STM32H7_PD6_FUNC_SAI1_SD_A 0x3607
+#define STM32H7_PD6_FUNC_USART2_RX 0x3608
+#define STM32H7_PD6_FUNC_SAI4_SD_A 0x3609
+#define STM32H7_PD6_FUNC_CAN2_RXFD 0x360a
+#define STM32H7_PD6_FUNC_SAI4_D1 0x360b
+#define STM32H7_PD6_FUNC_SDMMC2_CK 0x360c
+#define STM32H7_PD6_FUNC_FMC_NWAIT 0x360d
+#define STM32H7_PD6_FUNC_DCMI_D10 0x360e
+#define STM32H7_PD6_FUNC_LCD_B2 0x360f
+#define STM32H7_PD6_FUNC_EVENTOUT 0x3610
+#define STM32H7_PD6_FUNC_ANALOG 0x3611
+
+#define STM32H7_PD7_FUNC_GPIO 0x3700
+#define STM32H7_PD7_FUNC_DFSDM_DATIN4 0x3704
+#define STM32H7_PD7_FUNC_SPI1_MOSI_I2S1_SDO 0x3706
+#define STM32H7_PD7_FUNC_DFSDM_CKIN1 0x3707
+#define STM32H7_PD7_FUNC_USART2_CK 0x3708
+#define STM32H7_PD7_FUNC_SPDIFRX_IN0 0x370a
+#define STM32H7_PD7_FUNC_SDMMC2_CMD 0x370c
+#define STM32H7_PD7_FUNC_FMC_NE1 0x370d
+#define STM32H7_PD7_FUNC_EVENTOUT 0x3710
+#define STM32H7_PD7_FUNC_ANALOG 0x3711
+
+#define STM32H7_PD8_FUNC_GPIO 0x3800
+#define STM32H7_PD8_FUNC_DFSDM_CKIN3 0x3804
+#define STM32H7_PD8_FUNC_SAI3_SCK_B 0x3807
+#define STM32H7_PD8_FUNC_USART3_TX 0x3808
+#define STM32H7_PD8_FUNC_SPDIFRX_IN1 0x380a
+#define STM32H7_PD8_FUNC_FMC_D13_FMC_DA13 0x380d
+#define STM32H7_PD8_FUNC_EVENTOUT 0x3810
+#define STM32H7_PD8_FUNC_ANALOG 0x3811
+
+#define STM32H7_PD9_FUNC_GPIO 0x3900
+#define STM32H7_PD9_FUNC_DFSDM_DATIN3 0x3904
+#define STM32H7_PD9_FUNC_SAI3_SD_B 0x3907
+#define STM32H7_PD9_FUNC_USART3_RX 0x3908
+#define STM32H7_PD9_FUNC_CAN2_RXFD 0x390a
+#define STM32H7_PD9_FUNC_FMC_D14_FMC_DA14 0x390d
+#define STM32H7_PD9_FUNC_EVENTOUT 0x3910
+#define STM32H7_PD9_FUNC_ANALOG 0x3911
+
+#define STM32H7_PD10_FUNC_GPIO 0x3a00
+#define STM32H7_PD10_FUNC_DFSDM_CKOUT 0x3a04
+#define STM32H7_PD10_FUNC_SAI3_FS_B 0x3a07
+#define STM32H7_PD10_FUNC_USART3_CK 0x3a08
+#define STM32H7_PD10_FUNC_CAN2_TXFD 0x3a0a
+#define STM32H7_PD10_FUNC_FMC_D15_FMC_DA15 0x3a0d
+#define STM32H7_PD10_FUNC_LCD_B3 0x3a0f
+#define STM32H7_PD10_FUNC_EVENTOUT 0x3a10
+#define STM32H7_PD10_FUNC_ANALOG 0x3a11
+
+#define STM32H7_PD11_FUNC_GPIO 0x3b00
+#define STM32H7_PD11_FUNC_LPTIM2_IN2 0x3b04
+#define STM32H7_PD11_FUNC_I2C4_SMBA 0x3b05
+#define STM32H7_PD11_FUNC_USART3_CTS_NSS 0x3b08
+#define STM32H7_PD11_FUNC_QUADSPI_BK1_IO0 0x3b0a
+#define STM32H7_PD11_FUNC_SAI2_SD_A 0x3b0b
+#define STM32H7_PD11_FUNC_FMC_A16 0x3b0d
+#define STM32H7_PD11_FUNC_EVENTOUT 0x3b10
+#define STM32H7_PD11_FUNC_ANALOG 0x3b11
+
+#define STM32H7_PD12_FUNC_GPIO 0x3c00
+#define STM32H7_PD12_FUNC_LPTIM1_IN1 0x3c02
+#define STM32H7_PD12_FUNC_TIM4_CH1 0x3c03
+#define STM32H7_PD12_FUNC_LPTIM2_IN1 0x3c04
+#define STM32H7_PD12_FUNC_I2C4_SCL 0x3c05
+#define STM32H7_PD12_FUNC_USART3_RTS 0x3c08
+#define STM32H7_PD12_FUNC_QUADSPI_BK1_IO1 0x3c0a
+#define STM32H7_PD12_FUNC_SAI2_FS_A 0x3c0b
+#define STM32H7_PD12_FUNC_FMC_A17 0x3c0d
+#define STM32H7_PD12_FUNC_EVENTOUT 0x3c10
+#define STM32H7_PD12_FUNC_ANALOG 0x3c11
+
+#define STM32H7_PD13_FUNC_GPIO 0x3d00
+#define STM32H7_PD13_FUNC_LPTIM1_OUT 0x3d02
+#define STM32H7_PD13_FUNC_TIM4_CH2 0x3d03
+#define STM32H7_PD13_FUNC_I2C4_SDA 0x3d05
+#define STM32H7_PD13_FUNC_QUADSPI_BK1_IO3 0x3d0a
+#define STM32H7_PD13_FUNC_SAI2_SCK_A 0x3d0b
+#define STM32H7_PD13_FUNC_FMC_A18 0x3d0d
+#define STM32H7_PD13_FUNC_EVENTOUT 0x3d10
+#define STM32H7_PD13_FUNC_ANALOG 0x3d11
+
+#define STM32H7_PD14_FUNC_GPIO 0x3e00
+#define STM32H7_PD14_FUNC_TIM4_CH3 0x3e03
+#define STM32H7_PD14_FUNC_SAI3_MCLK_B 0x3e07
+#define STM32H7_PD14_FUNC_UART8_CTS 0x3e09
+#define STM32H7_PD14_FUNC_FMC_D0_FMC_DA0 0x3e0d
+#define STM32H7_PD14_FUNC_EVENTOUT 0x3e10
+#define STM32H7_PD14_FUNC_ANALOG 0x3e11
+
+#define STM32H7_PD15_FUNC_GPIO 0x3f00
+#define STM32H7_PD15_FUNC_TIM4_CH4 0x3f03
+#define STM32H7_PD15_FUNC_SAI3_MCLK_A 0x3f07
+#define STM32H7_PD15_FUNC_UART8_RTS 0x3f09
+#define STM32H7_PD15_FUNC_FMC_D1_FMC_DA1 0x3f0d
+#define STM32H7_PD15_FUNC_EVENTOUT 0x3f10
+#define STM32H7_PD15_FUNC_ANALOG 0x3f11
+
+#define STM32H7_PE0_FUNC_GPIO 0x4000
+#define STM32H7_PE0_FUNC_LPTIM1_ETR 0x4002
+#define STM32H7_PE0_FUNC_TIM4_ETR 0x4003
+#define STM32H7_PE0_FUNC_HRTIM_SCIN 0x4004
+#define STM32H7_PE0_FUNC_LPTIM2_ETR 0x4005
+#define STM32H7_PE0_FUNC_UART8_RX 0x4009
+#define STM32H7_PE0_FUNC_CAN1_RXFD 0x400a
+#define STM32H7_PE0_FUNC_SAI2_MCK_A 0x400b
+#define STM32H7_PE0_FUNC_FMC_NBL0 0x400d
+#define STM32H7_PE0_FUNC_DCMI_D2 0x400e
+#define STM32H7_PE0_FUNC_EVENTOUT 0x4010
+#define STM32H7_PE0_FUNC_ANALOG 0x4011
+
+#define STM32H7_PE1_FUNC_GPIO 0x4100
+#define STM32H7_PE1_FUNC_LPTIM1_IN2 0x4102
+#define STM32H7_PE1_FUNC_HRTIM_SCOUT 0x4104
+#define STM32H7_PE1_FUNC_UART8_TX 0x4109
+#define STM32H7_PE1_FUNC_CAN1_TXFD 0x410a
+#define STM32H7_PE1_FUNC_FMC_NBL1 0x410d
+#define STM32H7_PE1_FUNC_DCMI_D3 0x410e
+#define STM32H7_PE1_FUNC_EVENTOUT 0x4110
+#define STM32H7_PE1_FUNC_ANALOG 0x4111
+
+#define STM32H7_PE2_FUNC_GPIO 0x4200
+#define STM32H7_PE2_FUNC_TRACECLK 0x4201
+#define STM32H7_PE2_FUNC_SAI1_CK1 0x4203
+#define STM32H7_PE2_FUNC_SPI4_SCK 0x4206
+#define STM32H7_PE2_FUNC_SAI1_MCLK_A 0x4207
+#define STM32H7_PE2_FUNC_SAI4_MCLK_A 0x4209
+#define STM32H7_PE2_FUNC_QUADSPI_BK1_IO2 0x420a
+#define STM32H7_PE2_FUNC_SAI4_CK1 0x420b
+#define STM32H7_PE2_FUNC_ETH_MII_TXD3 0x420c
+#define STM32H7_PE2_FUNC_FMC_A23 0x420d
+#define STM32H7_PE2_FUNC_EVENTOUT 0x4210
+#define STM32H7_PE2_FUNC_ANALOG 0x4211
+
+#define STM32H7_PE3_FUNC_GPIO 0x4300
+#define STM32H7_PE3_FUNC_TRACED0 0x4301
+#define STM32H7_PE3_FUNC_TIM15_BKIN 0x4305
+#define STM32H7_PE3_FUNC_SAI1_SD_B 0x4307
+#define STM32H7_PE3_FUNC_SAI4_SD_B 0x4309
+#define STM32H7_PE3_FUNC_FMC_A19 0x430d
+#define STM32H7_PE3_FUNC_EVENTOUT 0x4310
+#define STM32H7_PE3_FUNC_ANALOG 0x4311
+
+#define STM32H7_PE4_FUNC_GPIO 0x4400
+#define STM32H7_PE4_FUNC_TRACED1 0x4401
+#define STM32H7_PE4_FUNC_SAI1_D2 0x4403
+#define STM32H7_PE4_FUNC_DFSDM_DATIN3 0x4404
+#define STM32H7_PE4_FUNC_TIM15_CH1N 0x4405
+#define STM32H7_PE4_FUNC_SPI4_NSS 0x4406
+#define STM32H7_PE4_FUNC_SAI1_FS_A 0x4407
+#define STM32H7_PE4_FUNC_SAI4_FS_A 0x4409
+#define STM32H7_PE4_FUNC_SAI4_D2 0x440b
+#define STM32H7_PE4_FUNC_FMC_A20 0x440d
+#define STM32H7_PE4_FUNC_DCMI_D4 0x440e
+#define STM32H7_PE4_FUNC_LCD_B0 0x440f
+#define STM32H7_PE4_FUNC_EVENTOUT 0x4410
+#define STM32H7_PE4_FUNC_ANALOG 0x4411
+
+#define STM32H7_PE5_FUNC_GPIO 0x4500
+#define STM32H7_PE5_FUNC_TRACED2 0x4501
+#define STM32H7_PE5_FUNC_SAI1_CK2 0x4503
+#define STM32H7_PE5_FUNC_DFSDM_CKIN3 0x4504
+#define STM32H7_PE5_FUNC_TIM15_CH1 0x4505
+#define STM32H7_PE5_FUNC_SPI4_MISO 0x4506
+#define STM32H7_PE5_FUNC_SAI1_SCK_A 0x4507
+#define STM32H7_PE5_FUNC_SAI4_SCK_A 0x4509
+#define STM32H7_PE5_FUNC_SAI4_CK2 0x450b
+#define STM32H7_PE5_FUNC_FMC_A21 0x450d
+#define STM32H7_PE5_FUNC_DCMI_D6 0x450e
+#define STM32H7_PE5_FUNC_LCD_G0 0x450f
+#define STM32H7_PE5_FUNC_EVENTOUT 0x4510
+#define STM32H7_PE5_FUNC_ANALOG 0x4511
+
+#define STM32H7_PE6_FUNC_GPIO 0x4600
+#define STM32H7_PE6_FUNC_TRACED3 0x4601
+#define STM32H7_PE6_FUNC_TIM1_BKIN2 0x4602
+#define STM32H7_PE6_FUNC_SAI1_D1 0x4603
+#define STM32H7_PE6_FUNC_TIM15_CH2 0x4605
+#define STM32H7_PE6_FUNC_SPI4_MOSI 0x4606
+#define STM32H7_PE6_FUNC_SAI1_SD_A 0x4607
+#define STM32H7_PE6_FUNC_SAI4_SD_A 0x4609
+#define STM32H7_PE6_FUNC_SAI4_D1 0x460a
+#define STM32H7_PE6_FUNC_SAI2_MCK_B 0x460b
+#define STM32H7_PE6_FUNC_TIM1_BKIN2_COMP12 0x460c
+#define STM32H7_PE6_FUNC_FMC_A22 0x460d
+#define STM32H7_PE6_FUNC_DCMI_D7 0x460e
+#define STM32H7_PE6_FUNC_LCD_G1 0x460f
+#define STM32H7_PE6_FUNC_EVENTOUT 0x4610
+#define STM32H7_PE6_FUNC_ANALOG 0x4611
+
+#define STM32H7_PE7_FUNC_GPIO 0x4700
+#define STM32H7_PE7_FUNC_TIM1_ETR 0x4702
+#define STM32H7_PE7_FUNC_DFSDM_DATIN2 0x4704
+#define STM32H7_PE7_FUNC_UART7_RX 0x4708
+#define STM32H7_PE7_FUNC_QUADSPI_BK2_IO0 0x470b
+#define STM32H7_PE7_FUNC_FMC_D4_FMC_DA4 0x470d
+#define STM32H7_PE7_FUNC_EVENTOUT 0x4710
+#define STM32H7_PE7_FUNC_ANALOG 0x4711
+
+#define STM32H7_PE8_FUNC_GPIO 0x4800
+#define STM32H7_PE8_FUNC_TIM1_CH1N 0x4802
+#define STM32H7_PE8_FUNC_DFSDM_CKIN2 0x4804
+#define STM32H7_PE8_FUNC_UART7_TX 0x4808
+#define STM32H7_PE8_FUNC_QUADSPI_BK2_IO1 0x480b
+#define STM32H7_PE8_FUNC_FMC_D5_FMC_DA5 0x480d
+#define STM32H7_PE8_FUNC_COMP_2_OUT 0x480e
+#define STM32H7_PE8_FUNC_EVENTOUT 0x4810
+#define STM32H7_PE8_FUNC_ANALOG 0x4811
+
+#define STM32H7_PE9_FUNC_GPIO 0x4900
+#define STM32H7_PE9_FUNC_TIM1_CH1 0x4902
+#define STM32H7_PE9_FUNC_DFSDM_CKOUT 0x4904
+#define STM32H7_PE9_FUNC_UART7_RTS 0x4908
+#define STM32H7_PE9_FUNC_QUADSPI_BK2_IO2 0x490b
+#define STM32H7_PE9_FUNC_FMC_D6_FMC_DA6 0x490d
+#define STM32H7_PE9_FUNC_EVENTOUT 0x4910
+#define STM32H7_PE9_FUNC_ANALOG 0x4911
+
+#define STM32H7_PE10_FUNC_GPIO 0x4a00
+#define STM32H7_PE10_FUNC_TIM1_CH2N 0x4a02
+#define STM32H7_PE10_FUNC_DFSDM_DATIN4 0x4a04
+#define STM32H7_PE10_FUNC_UART7_CTS 0x4a08
+#define STM32H7_PE10_FUNC_QUADSPI_BK2_IO3 0x4a0b
+#define STM32H7_PE10_FUNC_FMC_D7_FMC_DA7 0x4a0d
+#define STM32H7_PE10_FUNC_EVENTOUT 0x4a10
+#define STM32H7_PE10_FUNC_ANALOG 0x4a11
+
+#define STM32H7_PE11_FUNC_GPIO 0x4b00
+#define STM32H7_PE11_FUNC_TIM1_CH2 0x4b02
+#define STM32H7_PE11_FUNC_DFSDM_CKIN4 0x4b04
+#define STM32H7_PE11_FUNC_SPI4_NSS 0x4b06
+#define STM32H7_PE11_FUNC_SAI2_SD_B 0x4b0b
+#define STM32H7_PE11_FUNC_FMC_D8_FMC_DA8 0x4b0d
+#define STM32H7_PE11_FUNC_LCD_G3 0x4b0f
+#define STM32H7_PE11_FUNC_EVENTOUT 0x4b10
+#define STM32H7_PE11_FUNC_ANALOG 0x4b11
+
+#define STM32H7_PE12_FUNC_GPIO 0x4c00
+#define STM32H7_PE12_FUNC_TIM1_CH3N 0x4c02
+#define STM32H7_PE12_FUNC_DFSDM_DATIN5 0x4c04
+#define STM32H7_PE12_FUNC_SPI4_SCK 0x4c06
+#define STM32H7_PE12_FUNC_SAI2_SCK_B 0x4c0b
+#define STM32H7_PE12_FUNC_FMC_D9_FMC_DA9 0x4c0d
+#define STM32H7_PE12_FUNC_COMP_1_OUT 0x4c0e
+#define STM32H7_PE12_FUNC_LCD_B4 0x4c0f
+#define STM32H7_PE12_FUNC_EVENTOUT 0x4c10
+#define STM32H7_PE12_FUNC_ANALOG 0x4c11
+
+#define STM32H7_PE13_FUNC_GPIO 0x4d00
+#define STM32H7_PE13_FUNC_TIM1_CH3 0x4d02
+#define STM32H7_PE13_FUNC_DFSDM_CKIN5 0x4d04
+#define STM32H7_PE13_FUNC_SPI4_MISO 0x4d06
+#define STM32H7_PE13_FUNC_SAI2_FS_B 0x4d0b
+#define STM32H7_PE13_FUNC_FMC_D10_FMC_DA10 0x4d0d
+#define STM32H7_PE13_FUNC_COMP_2_OUT 0x4d0e
+#define STM32H7_PE13_FUNC_LCD_DE 0x4d0f
+#define STM32H7_PE13_FUNC_EVENTOUT 0x4d10
+#define STM32H7_PE13_FUNC_ANALOG 0x4d11
+
+#define STM32H7_PE14_FUNC_GPIO 0x4e00
+#define STM32H7_PE14_FUNC_TIM1_CH4 0x4e02
+#define STM32H7_PE14_FUNC_SPI4_MOSI 0x4e06
+#define STM32H7_PE14_FUNC_SAI2_MCK_B 0x4e0b
+#define STM32H7_PE14_FUNC_FMC_D11_FMC_DA11 0x4e0d
+#define STM32H7_PE14_FUNC_LCD_CLK 0x4e0f
+#define STM32H7_PE14_FUNC_EVENTOUT 0x4e10
+#define STM32H7_PE14_FUNC_ANALOG 0x4e11
+
+#define STM32H7_PE15_FUNC_GPIO 0x4f00
+#define STM32H7_PE15_FUNC_TIM1_BKIN 0x4f02
+#define STM32H7_PE15_FUNC_HDMI__TIM1_BKIN 0x4f06
+#define STM32H7_PE15_FUNC_FMC_D12_FMC_DA12 0x4f0d
+#define STM32H7_PE15_FUNC_TIM1_BKIN_COMP12 0x4f0e
+#define STM32H7_PE15_FUNC_LCD_R7 0x4f0f
+#define STM32H7_PE15_FUNC_EVENTOUT 0x4f10
+#define STM32H7_PE15_FUNC_ANALOG 0x4f11
+
+#define STM32H7_PF0_FUNC_GPIO 0x5000
+#define STM32H7_PF0_FUNC_I2C2_SDA 0x5005
+#define STM32H7_PF0_FUNC_FMC_A0 0x500d
+#define STM32H7_PF0_FUNC_EVENTOUT 0x5010
+#define STM32H7_PF0_FUNC_ANALOG 0x5011
+
+#define STM32H7_PF1_FUNC_GPIO 0x5100
+#define STM32H7_PF1_FUNC_I2C2_SCL 0x5105
+#define STM32H7_PF1_FUNC_FMC_A1 0x510d
+#define STM32H7_PF1_FUNC_EVENTOUT 0x5110
+#define STM32H7_PF1_FUNC_ANALOG 0x5111
+
+#define STM32H7_PF2_FUNC_GPIO 0x5200
+#define STM32H7_PF2_FUNC_I2C2_SMBA 0x5205
+#define STM32H7_PF2_FUNC_FMC_A2 0x520d
+#define STM32H7_PF2_FUNC_EVENTOUT 0x5210
+#define STM32H7_PF2_FUNC_ANALOG 0x5211
+
+#define STM32H7_PF3_FUNC_GPIO 0x5300
+#define STM32H7_PF3_FUNC_FMC_A3 0x530d
+#define STM32H7_PF3_FUNC_EVENTOUT 0x5310
+#define STM32H7_PF3_FUNC_ANALOG 0x5311
+
+#define STM32H7_PF4_FUNC_GPIO 0x5400
+#define STM32H7_PF4_FUNC_FMC_A4 0x540d
+#define STM32H7_PF4_FUNC_EVENTOUT 0x5410
+#define STM32H7_PF4_FUNC_ANALOG 0x5411
+
+#define STM32H7_PF5_FUNC_GPIO 0x5500
+#define STM32H7_PF5_FUNC_FMC_A5 0x550d
+#define STM32H7_PF5_FUNC_EVENTOUT 0x5510
+#define STM32H7_PF5_FUNC_ANALOG 0x5511
+
+#define STM32H7_PF6_FUNC_GPIO 0x5600
+#define STM32H7_PF6_FUNC_TIM16_CH1 0x5602
+#define STM32H7_PF6_FUNC_SPI5_NSS 0x5606
+#define STM32H7_PF6_FUNC_SAI1_SD_B 0x5607
+#define STM32H7_PF6_FUNC_UART7_RX 0x5608
+#define STM32H7_PF6_FUNC_SAI4_SD_B 0x5609
+#define STM32H7_PF6_FUNC_QUADSPI_BK1_IO3 0x560a
+#define STM32H7_PF6_FUNC_EVENTOUT 0x5610
+#define STM32H7_PF6_FUNC_ANALOG 0x5611
+
+#define STM32H7_PF7_FUNC_GPIO 0x5700
+#define STM32H7_PF7_FUNC_TIM17_CH1 0x5702
+#define STM32H7_PF7_FUNC_SPI5_SCK 0x5706
+#define STM32H7_PF7_FUNC_SAI1_MCLK_B 0x5707
+#define STM32H7_PF7_FUNC_UART7_TX 0x5708
+#define STM32H7_PF7_FUNC_SAI4_MCLK_B 0x5709
+#define STM32H7_PF7_FUNC_QUADSPI_BK1_IO2 0x570a
+#define STM32H7_PF7_FUNC_EVENTOUT 0x5710
+#define STM32H7_PF7_FUNC_ANALOG 0x5711
+
+#define STM32H7_PF8_FUNC_GPIO 0x5800
+#define STM32H7_PF8_FUNC_TIM16_CH1N 0x5802
+#define STM32H7_PF8_FUNC_SPI5_MISO 0x5806
+#define STM32H7_PF8_FUNC_SAI1_SCK_B 0x5807
+#define STM32H7_PF8_FUNC_UART7_RTS 0x5808
+#define STM32H7_PF8_FUNC_SAI4_SCK_B 0x5809
+#define STM32H7_PF8_FUNC_TIM13_CH1 0x580a
+#define STM32H7_PF8_FUNC_QUADSPI_BK1_IO0 0x580b
+#define STM32H7_PF8_FUNC_EVENTOUT 0x5810
+#define STM32H7_PF8_FUNC_ANALOG 0x5811
+
+#define STM32H7_PF9_FUNC_GPIO 0x5900
+#define STM32H7_PF9_FUNC_TIM17_CH1N 0x5902
+#define STM32H7_PF9_FUNC_SPI5_MOSI 0x5906
+#define STM32H7_PF9_FUNC_SAI1_FS_B 0x5907
+#define STM32H7_PF9_FUNC_UART7_CTS 0x5908
+#define STM32H7_PF9_FUNC_SAI4_FS_B 0x5909
+#define STM32H7_PF9_FUNC_TIM14_CH1 0x590a
+#define STM32H7_PF9_FUNC_QUADSPI_BK1_IO1 0x590b
+#define STM32H7_PF9_FUNC_EVENTOUT 0x5910
+#define STM32H7_PF9_FUNC_ANALOG 0x5911
+
+#define STM32H7_PF10_FUNC_GPIO 0x5a00
+#define STM32H7_PF10_FUNC_TIM16_BKIN 0x5a02
+#define STM32H7_PF10_FUNC_SAI1_D3 0x5a03
+#define STM32H7_PF10_FUNC_QUADSPI_CLK 0x5a0a
+#define STM32H7_PF10_FUNC_SAI4_D3 0x5a0b
+#define STM32H7_PF10_FUNC_DCMI_D11 0x5a0e
+#define STM32H7_PF10_FUNC_LCD_DE 0x5a0f
+#define STM32H7_PF10_FUNC_EVENTOUT 0x5a10
+#define STM32H7_PF10_FUNC_ANALOG 0x5a11
+
+#define STM32H7_PF11_FUNC_GPIO 0x5b00
+#define STM32H7_PF11_FUNC_SPI5_MOSI 0x5b06
+#define STM32H7_PF11_FUNC_SAI2_SD_B 0x5b0b
+#define STM32H7_PF11_FUNC_FMC_SDNRAS 0x5b0d
+#define STM32H7_PF11_FUNC_DCMI_D12 0x5b0e
+#define STM32H7_PF11_FUNC_EVENTOUT 0x5b10
+#define STM32H7_PF11_FUNC_ANALOG 0x5b11
+
+#define STM32H7_PF12_FUNC_GPIO 0x5c00
+#define STM32H7_PF12_FUNC_FMC_A6 0x5c0d
+#define STM32H7_PF12_FUNC_EVENTOUT 0x5c10
+#define STM32H7_PF12_FUNC_ANALOG 0x5c11
+
+#define STM32H7_PF13_FUNC_GPIO 0x5d00
+#define STM32H7_PF13_FUNC_DFSDM_DATIN6 0x5d04
+#define STM32H7_PF13_FUNC_I2C4_SMBA 0x5d05
+#define STM32H7_PF13_FUNC_FMC_A7 0x5d0d
+#define STM32H7_PF13_FUNC_EVENTOUT 0x5d10
+#define STM32H7_PF13_FUNC_ANALOG 0x5d11
+
+#define STM32H7_PF14_FUNC_GPIO 0x5e00
+#define STM32H7_PF14_FUNC_DFSDM_CKIN6 0x5e04
+#define STM32H7_PF14_FUNC_I2C4_SCL 0x5e05
+#define STM32H7_PF14_FUNC_FMC_A8 0x5e0d
+#define STM32H7_PF14_FUNC_EVENTOUT 0x5e10
+#define STM32H7_PF14_FUNC_ANALOG 0x5e11
+
+#define STM32H7_PF15_FUNC_GPIO 0x5f00
+#define STM32H7_PF15_FUNC_I2C4_SDA 0x5f05
+#define STM32H7_PF15_FUNC_FMC_A9 0x5f0d
+#define STM32H7_PF15_FUNC_EVENTOUT 0x5f10
+#define STM32H7_PF15_FUNC_ANALOG 0x5f11
+
+#define STM32H7_PG0_FUNC_GPIO 0x6000
+#define STM32H7_PG0_FUNC_FMC_A10 0x600d
+#define STM32H7_PG0_FUNC_EVENTOUT 0x6010
+#define STM32H7_PG0_FUNC_ANALOG 0x6011
+
+#define STM32H7_PG1_FUNC_GPIO 0x6100
+#define STM32H7_PG1_FUNC_FMC_A11 0x610d
+#define STM32H7_PG1_FUNC_EVENTOUT 0x6110
+#define STM32H7_PG1_FUNC_ANALOG 0x6111
+
+#define STM32H7_PG2_FUNC_GPIO 0x6200
+#define STM32H7_PG2_FUNC_TIM8_BKIN 0x6204
+#define STM32H7_PG2_FUNC_TIM8_BKIN_COMP12 0x620c
+#define STM32H7_PG2_FUNC_FMC_A12 0x620d
+#define STM32H7_PG2_FUNC_EVENTOUT 0x6210
+#define STM32H7_PG2_FUNC_ANALOG 0x6211
+
+#define STM32H7_PG3_FUNC_GPIO 0x6300
+#define STM32H7_PG3_FUNC_TIM8_BKIN2 0x6304
+#define STM32H7_PG3_FUNC_TIM8_BKIN2_COMP12 0x630c
+#define STM32H7_PG3_FUNC_FMC_A13 0x630d
+#define STM32H7_PG3_FUNC_EVENTOUT 0x6310
+#define STM32H7_PG3_FUNC_ANALOG 0x6311
+
+#define STM32H7_PG4_FUNC_GPIO 0x6400
+#define STM32H7_PG4_FUNC_TIM1_BKIN2 0x6402
+#define STM32H7_PG4_FUNC_TIM1_BKIN2_COMP12 0x640c
+#define STM32H7_PG4_FUNC_FMC_A14_FMC_BA0 0x640d
+#define STM32H7_PG4_FUNC_EVENTOUT 0x6410
+#define STM32H7_PG4_FUNC_ANALOG 0x6411
+
+#define STM32H7_PG5_FUNC_GPIO 0x6500
+#define STM32H7_PG5_FUNC_TIM1_ETR 0x6502
+#define STM32H7_PG5_FUNC_FMC_A15_FMC_BA1 0x650d
+#define STM32H7_PG5_FUNC_EVENTOUT 0x6510
+#define STM32H7_PG5_FUNC_ANALOG 0x6511
+
+#define STM32H7_PG6_FUNC_GPIO 0x6600
+#define STM32H7_PG6_FUNC_TIM17_BKIN 0x6602
+#define STM32H7_PG6_FUNC_HRTIM_CHE1 0x6603
+#define STM32H7_PG6_FUNC_QUADSPI_BK1_NCS 0x660b
+#define STM32H7_PG6_FUNC_FMC_NE3 0x660d
+#define STM32H7_PG6_FUNC_DCMI_D12 0x660e
+#define STM32H7_PG6_FUNC_LCD_R7 0x660f
+#define STM32H7_PG6_FUNC_EVENTOUT 0x6610
+#define STM32H7_PG6_FUNC_ANALOG 0x6611
+
+#define STM32H7_PG7_FUNC_GPIO 0x6700
+#define STM32H7_PG7_FUNC_HRTIM_CHE2 0x6703
+#define STM32H7_PG7_FUNC_SAI1_MCLK_A 0x6707
+#define STM32H7_PG7_FUNC_USART6_CK 0x6708
+#define STM32H7_PG7_FUNC_FMC_INT 0x670d
+#define STM32H7_PG7_FUNC_DCMI_D13 0x670e
+#define STM32H7_PG7_FUNC_LCD_CLK 0x670f
+#define STM32H7_PG7_FUNC_EVENTOUT 0x6710
+#define STM32H7_PG7_FUNC_ANALOG 0x6711
+
+#define STM32H7_PG8_FUNC_GPIO 0x6800
+#define STM32H7_PG8_FUNC_TIM8_ETR 0x6804
+#define STM32H7_PG8_FUNC_SPI6_NSS 0x6806
+#define STM32H7_PG8_FUNC_USART6_RTS 0x6808
+#define STM32H7_PG8_FUNC_SPDIFRX_IN2 0x6809
+#define STM32H7_PG8_FUNC_ETH_PPS_OUT 0x680c
+#define STM32H7_PG8_FUNC_FMC_SDCLK 0x680d
+#define STM32H7_PG8_FUNC_LCD_G7 0x680f
+#define STM32H7_PG8_FUNC_EVENTOUT 0x6810
+#define STM32H7_PG8_FUNC_ANALOG 0x6811
+
+#define STM32H7_PG9_FUNC_GPIO 0x6900
+#define STM32H7_PG9_FUNC_SPI1_MISO_I2S1_SDI 0x6906
+#define STM32H7_PG9_FUNC_USART6_RX 0x6908
+#define STM32H7_PG9_FUNC_SPDIFRX_IN3 0x6909
+#define STM32H7_PG9_FUNC_QUADSPI_BK2_IO2 0x690a
+#define STM32H7_PG9_FUNC_SAI2_FS_B 0x690b
+#define STM32H7_PG9_FUNC_FMC_NE2_FMC_NCE 0x690d
+#define STM32H7_PG9_FUNC_DCMI_VSYNC 0x690e
+#define STM32H7_PG9_FUNC_EVENTOUT 0x6910
+#define STM32H7_PG9_FUNC_ANALOG 0x6911
+
+#define STM32H7_PG10_FUNC_GPIO 0x6a00
+#define STM32H7_PG10_FUNC_HRTIM_FLT5 0x6a03
+#define STM32H7_PG10_FUNC_SPI1_NSS_I2S1_WS 0x6a06
+#define STM32H7_PG10_FUNC_LCD_G3 0x6a0a
+#define STM32H7_PG10_FUNC_SAI2_SD_B 0x6a0b
+#define STM32H7_PG10_FUNC_FMC_NE3 0x6a0d
+#define STM32H7_PG10_FUNC_DCMI_D2 0x6a0e
+#define STM32H7_PG10_FUNC_LCD_B2 0x6a0f
+#define STM32H7_PG10_FUNC_EVENTOUT 0x6a10
+#define STM32H7_PG10_FUNC_ANALOG 0x6a11
+
+#define STM32H7_PG11_FUNC_GPIO 0x6b00
+#define STM32H7_PG11_FUNC_HRTIM_EEV4 0x6b03
+#define STM32H7_PG11_FUNC_SPI1_SCK_I2S1_CK 0x6b06
+#define STM32H7_PG11_FUNC_SPDIFRX_IN0 0x6b09
+#define STM32H7_PG11_FUNC_SDMMC2_D2 0x6b0b
+#define STM32H7_PG11_FUNC_ETH_MII_TX_EN_ETH_RMII_TX_EN 0x6b0c
+#define STM32H7_PG11_FUNC_DCMI_D3 0x6b0e
+#define STM32H7_PG11_FUNC_LCD_B3 0x6b0f
+#define STM32H7_PG11_FUNC_EVENTOUT 0x6b10
+#define STM32H7_PG11_FUNC_ANALOG 0x6b11
+
+#define STM32H7_PG12_FUNC_GPIO 0x6c00
+#define STM32H7_PG12_FUNC_LPTIM1_IN1 0x6c02
+#define STM32H7_PG12_FUNC_HRTIM_EEV5 0x6c03
+#define STM32H7_PG12_FUNC_SPI6_MISO 0x6c06
+#define STM32H7_PG12_FUNC_USART6_RTS 0x6c08
+#define STM32H7_PG12_FUNC_SPDIFRX_IN1 0x6c09
+#define STM32H7_PG12_FUNC_LCD_B4 0x6c0a
+#define STM32H7_PG12_FUNC_ETH_MII_TXD1_ETH_RMII_TXD1 0x6c0c
+#define STM32H7_PG12_FUNC_FMC_NE4 0x6c0d
+#define STM32H7_PG12_FUNC_LCD_B1 0x6c0f
+#define STM32H7_PG12_FUNC_EVENTOUT 0x6c10
+#define STM32H7_PG12_FUNC_ANALOG 0x6c11
+
+#define STM32H7_PG13_FUNC_GPIO 0x6d00
+#define STM32H7_PG13_FUNC_TRACED0 0x6d01
+#define STM32H7_PG13_FUNC_LPTIM1_OUT 0x6d02
+#define STM32H7_PG13_FUNC_HRTIM_EEV10 0x6d03
+#define STM32H7_PG13_FUNC_SPI6_SCK 0x6d06
+#define STM32H7_PG13_FUNC_USART6_CTS_NSS 0x6d08
+#define STM32H7_PG13_FUNC_ETH_MII_TXD0_ETH_RMII_TXD0 0x6d0c
+#define STM32H7_PG13_FUNC_FMC_A24 0x6d0d
+#define STM32H7_PG13_FUNC_LCD_R0 0x6d0f
+#define STM32H7_PG13_FUNC_EVENTOUT 0x6d10
+#define STM32H7_PG13_FUNC_ANALOG 0x6d11
+
+#define STM32H7_PG14_FUNC_GPIO 0x6e00
+#define STM32H7_PG14_FUNC_TRACED1 0x6e01
+#define STM32H7_PG14_FUNC_LPTIM1_ETR 0x6e02
+#define STM32H7_PG14_FUNC_SPI6_MOSI 0x6e06
+#define STM32H7_PG14_FUNC_USART6_TX 0x6e08
+#define STM32H7_PG14_FUNC_QUADSPI_BK2_IO3 0x6e0a
+#define STM32H7_PG14_FUNC_ETH_MII_TXD1_ETH_RMII_TXD1 0x6e0c
+#define STM32H7_PG14_FUNC_FMC_A25 0x6e0d
+#define STM32H7_PG14_FUNC_LCD_B0 0x6e0f
+#define STM32H7_PG14_FUNC_EVENTOUT 0x6e10
+#define STM32H7_PG14_FUNC_ANALOG 0x6e11
+
+#define STM32H7_PG15_FUNC_GPIO 0x6f00
+#define STM32H7_PG15_FUNC_USART6_CTS_NSS 0x6f08
+#define STM32H7_PG15_FUNC_FMC_SDNCAS 0x6f0d
+#define STM32H7_PG15_FUNC_DCMI_D13 0x6f0e
+#define STM32H7_PG15_FUNC_EVENTOUT 0x6f10
+#define STM32H7_PG15_FUNC_ANALOG 0x6f11
+
+#define STM32H7_PH0_FUNC_GPIO 0x7000
+#define STM32H7_PH0_FUNC_EVENTOUT 0x7010
+#define STM32H7_PH0_FUNC_ANALOG 0x7011
+
+#define STM32H7_PH1_FUNC_GPIO 0x7100
+#define STM32H7_PH1_FUNC_EVENTOUT 0x7110
+#define STM32H7_PH1_FUNC_ANALOG 0x7111
+
+#define STM32H7_PH2_FUNC_GPIO 0x7200
+#define STM32H7_PH2_FUNC_LPTIM1_IN2 0x7202
+#define STM32H7_PH2_FUNC_QUADSPI_BK2_IO0 0x720a
+#define STM32H7_PH2_FUNC_SAI2_SCK_B 0x720b
+#define STM32H7_PH2_FUNC_ETH_MII_CRS 0x720c
+#define STM32H7_PH2_FUNC_FMC_SDCKE0 0x720d
+#define STM32H7_PH2_FUNC_LCD_R0 0x720f
+#define STM32H7_PH2_FUNC_EVENTOUT 0x7210
+#define STM32H7_PH2_FUNC_ANALOG 0x7211
+
+#define STM32H7_PH3_FUNC_GPIO 0x7300
+#define STM32H7_PH3_FUNC_QUADSPI_BK2_IO1 0x730a
+#define STM32H7_PH3_FUNC_SAI2_MCK_B 0x730b
+#define STM32H7_PH3_FUNC_ETH_MII_COL 0x730c
+#define STM32H7_PH3_FUNC_FMC_SDNE0 0x730d
+#define STM32H7_PH3_FUNC_LCD_R1 0x730f
+#define STM32H7_PH3_FUNC_EVENTOUT 0x7310
+#define STM32H7_PH3_FUNC_ANALOG 0x7311
+
+#define STM32H7_PH4_FUNC_GPIO 0x7400
+#define STM32H7_PH4_FUNC_I2C2_SCL 0x7405
+#define STM32H7_PH4_FUNC_LCD_G5 0x740a
+#define STM32H7_PH4_FUNC_OTG_HS_ULPI_NXT 0x740b
+#define STM32H7_PH4_FUNC_LCD_G4 0x740f
+#define STM32H7_PH4_FUNC_EVENTOUT 0x7410
+#define STM32H7_PH4_FUNC_ANALOG 0x7411
+
+#define STM32H7_PH5_FUNC_GPIO 0x7500
+#define STM32H7_PH5_FUNC_I2C2_SDA 0x7505
+#define STM32H7_PH5_FUNC_SPI5_NSS 0x7506
+#define STM32H7_PH5_FUNC_FMC_SDNWE 0x750d
+#define STM32H7_PH5_FUNC_EVENTOUT 0x7510
+#define STM32H7_PH5_FUNC_ANALOG 0x7511
+
+#define STM32H7_PH6_FUNC_GPIO 0x7600
+#define STM32H7_PH6_FUNC_I2C2_SMBA 0x7605
+#define STM32H7_PH6_FUNC_SPI5_SCK 0x7606
+#define STM32H7_PH6_FUNC_ETH_MII_RXD2 0x760c
+#define STM32H7_PH6_FUNC_FMC_SDNE1 0x760d
+#define STM32H7_PH6_FUNC_DCMI_D8 0x760e
+#define STM32H7_PH6_FUNC_EVENTOUT 0x7610
+#define STM32H7_PH6_FUNC_ANALOG 0x7611
+
+#define STM32H7_PH7_FUNC_GPIO 0x7700
+#define STM32H7_PH7_FUNC_I2C3_SCL 0x7705
+#define STM32H7_PH7_FUNC_SPI5_MISO 0x7706
+#define STM32H7_PH7_FUNC_ETH_MII_RXD3 0x770c
+#define STM32H7_PH7_FUNC_FMC_SDCKE1 0x770d
+#define STM32H7_PH7_FUNC_DCMI_D9 0x770e
+#define STM32H7_PH7_FUNC_EVENTOUT 0x7710
+#define STM32H7_PH7_FUNC_ANALOG 0x7711
+
+#define STM32H7_PH8_FUNC_GPIO 0x7800
+#define STM32H7_PH8_FUNC_TIM5_ETR 0x7803
+#define STM32H7_PH8_FUNC_I2C3_SDA 0x7805
+#define STM32H7_PH8_FUNC_FMC_D16 0x780d
+#define STM32H7_PH8_FUNC_DCMI_HSYNC 0x780e
+#define STM32H7_PH8_FUNC_LCD_R2 0x780f
+#define STM32H7_PH8_FUNC_EVENTOUT 0x7810
+#define STM32H7_PH8_FUNC_ANALOG 0x7811
+
+#define STM32H7_PH9_FUNC_GPIO 0x7900
+#define STM32H7_PH9_FUNC_I2C3_SMBA 0x7905
+#define STM32H7_PH9_FUNC_FMC_D17 0x790d
+#define STM32H7_PH9_FUNC_DCMI_D0 0x790e
+#define STM32H7_PH9_FUNC_LCD_R3 0x790f
+#define STM32H7_PH9_FUNC_EVENTOUT 0x7910
+#define STM32H7_PH9_FUNC_ANALOG 0x7911
+
+#define STM32H7_PH10_FUNC_GPIO 0x7a00
+#define STM32H7_PH10_FUNC_TIM5_CH1 0x7a03
+#define STM32H7_PH10_FUNC_I2C4_SMBA 0x7a05
+#define STM32H7_PH10_FUNC_FMC_D18 0x7a0d
+#define STM32H7_PH10_FUNC_DCMI_D1 0x7a0e
+#define STM32H7_PH10_FUNC_LCD_R4 0x7a0f
+#define STM32H7_PH10_FUNC_EVENTOUT 0x7a10
+#define STM32H7_PH10_FUNC_ANALOG 0x7a11
+
+#define STM32H7_PH11_FUNC_GPIO 0x7b00
+#define STM32H7_PH11_FUNC_TIM5_CH2 0x7b03
+#define STM32H7_PH11_FUNC_I2C4_SCL 0x7b05
+#define STM32H7_PH11_FUNC_FMC_D19 0x7b0d
+#define STM32H7_PH11_FUNC_DCMI_D2 0x7b0e
+#define STM32H7_PH11_FUNC_LCD_R5 0x7b0f
+#define STM32H7_PH11_FUNC_EVENTOUT 0x7b10
+#define STM32H7_PH11_FUNC_ANALOG 0x7b11
+
+#define STM32H7_PH12_FUNC_GPIO 0x7c00
+#define STM32H7_PH12_FUNC_TIM5_CH3 0x7c03
+#define STM32H7_PH12_FUNC_I2C4_SDA 0x7c05
+#define STM32H7_PH12_FUNC_FMC_D20 0x7c0d
+#define STM32H7_PH12_FUNC_DCMI_D3 0x7c0e
+#define STM32H7_PH12_FUNC_LCD_R6 0x7c0f
+#define STM32H7_PH12_FUNC_EVENTOUT 0x7c10
+#define STM32H7_PH12_FUNC_ANALOG 0x7c11
+
+#define STM32H7_PH13_FUNC_GPIO 0x7d00
+#define STM32H7_PH13_FUNC_TIM8_CH1N 0x7d04
+#define STM32H7_PH13_FUNC_UART4_TX 0x7d09
+#define STM32H7_PH13_FUNC_CAN1_TX 0x7d0a
+#define STM32H7_PH13_FUNC_FMC_D21 0x7d0d
+#define STM32H7_PH13_FUNC_LCD_G2 0x7d0f
+#define STM32H7_PH13_FUNC_EVENTOUT 0x7d10
+#define STM32H7_PH13_FUNC_ANALOG 0x7d11
+
+#define STM32H7_PH14_FUNC_GPIO 0x7e00
+#define STM32H7_PH14_FUNC_TIM8_CH2N 0x7e04
+#define STM32H7_PH14_FUNC_UART4_RX 0x7e09
+#define STM32H7_PH14_FUNC_CAN1_RX 0x7e0a
+#define STM32H7_PH14_FUNC_FMC_D22 0x7e0d
+#define STM32H7_PH14_FUNC_DCMI_D4 0x7e0e
+#define STM32H7_PH14_FUNC_LCD_G3 0x7e0f
+#define STM32H7_PH14_FUNC_EVENTOUT 0x7e10
+#define STM32H7_PH14_FUNC_ANALOG 0x7e11
+
+#define STM32H7_PH15_FUNC_GPIO 0x7f00
+#define STM32H7_PH15_FUNC_TIM8_CH3N 0x7f04
+#define STM32H7_PH15_FUNC_CAN1_TXFD 0x7f0a
+#define STM32H7_PH15_FUNC_FMC_D23 0x7f0d
+#define STM32H7_PH15_FUNC_DCMI_D11 0x7f0e
+#define STM32H7_PH15_FUNC_LCD_G4 0x7f0f
+#define STM32H7_PH15_FUNC_EVENTOUT 0x7f10
+#define STM32H7_PH15_FUNC_ANALOG 0x7f11
+
+#define STM32H7_PI0_FUNC_GPIO 0x8000
+#define STM32H7_PI0_FUNC_TIM5_CH4 0x8003
+#define STM32H7_PI0_FUNC_SPI2_NSS_I2S2_WS 0x8006
+#define STM32H7_PI0_FUNC_CAN1_RXFD 0x800a
+#define STM32H7_PI0_FUNC_FMC_D24 0x800d
+#define STM32H7_PI0_FUNC_DCMI_D13 0x800e
+#define STM32H7_PI0_FUNC_LCD_G5 0x800f
+#define STM32H7_PI0_FUNC_EVENTOUT 0x8010
+#define STM32H7_PI0_FUNC_ANALOG 0x8011
+
+#define STM32H7_PI1_FUNC_GPIO 0x8100
+#define STM32H7_PI1_FUNC_TIM8_BKIN2 0x8104
+#define STM32H7_PI1_FUNC_SPI2_SCK_I2S2_CK 0x8106
+#define STM32H7_PI1_FUNC_TIM8_BKIN2_COMP12 0x810c
+#define STM32H7_PI1_FUNC_FMC_D25 0x810d
+#define STM32H7_PI1_FUNC_DCMI_D8 0x810e
+#define STM32H7_PI1_FUNC_LCD_G6 0x810f
+#define STM32H7_PI1_FUNC_EVENTOUT 0x8110
+#define STM32H7_PI1_FUNC_ANALOG 0x8111
+
+#define STM32H7_PI2_FUNC_GPIO 0x8200
+#define STM32H7_PI2_FUNC_TIM8_CH4 0x8204
+#define STM32H7_PI2_FUNC_SPI2_MISO_I2S2_SDI 0x8206
+#define STM32H7_PI2_FUNC_FMC_D26 0x820d
+#define STM32H7_PI2_FUNC_DCMI_D9 0x820e
+#define STM32H7_PI2_FUNC_LCD_G7 0x820f
+#define STM32H7_PI2_FUNC_EVENTOUT 0x8210
+#define STM32H7_PI2_FUNC_ANALOG 0x8211
+
+#define STM32H7_PI3_FUNC_GPIO 0x8300
+#define STM32H7_PI3_FUNC_TIM8_ETR 0x8304
+#define STM32H7_PI3_FUNC_SPI2_MOSI_I2S2_SDO 0x8306
+#define STM32H7_PI3_FUNC_FMC_D27 0x830d
+#define STM32H7_PI3_FUNC_DCMI_D10 0x830e
+#define STM32H7_PI3_FUNC_EVENTOUT 0x8310
+#define STM32H7_PI3_FUNC_ANALOG 0x8311
+
+#define STM32H7_PI4_FUNC_GPIO 0x8400
+#define STM32H7_PI4_FUNC_TIM8_BKIN 0x8404
+#define STM32H7_PI4_FUNC_SAI2_MCK_A 0x840b
+#define STM32H7_PI4_FUNC_TIM8_BKIN_COMP12 0x840c
+#define STM32H7_PI4_FUNC_FMC_NBL2 0x840d
+#define STM32H7_PI4_FUNC_DCMI_D5 0x840e
+#define STM32H7_PI4_FUNC_LCD_B4 0x840f
+#define STM32H7_PI4_FUNC_EVENTOUT 0x8410
+#define STM32H7_PI4_FUNC_ANALOG 0x8411
+
+#define STM32H7_PI5_FUNC_GPIO 0x8500
+#define STM32H7_PI5_FUNC_TIM8_CH1 0x8504
+#define STM32H7_PI5_FUNC_SAI2_SCK_A 0x850b
+#define STM32H7_PI5_FUNC_FMC_NBL3 0x850d
+#define STM32H7_PI5_FUNC_DCMI_VSYNC 0x850e
+#define STM32H7_PI5_FUNC_LCD_B5 0x850f
+#define STM32H7_PI5_FUNC_EVENTOUT 0x8510
+#define STM32H7_PI5_FUNC_ANALOG 0x8511
+
+#define STM32H7_PI6_FUNC_GPIO 0x8600
+#define STM32H7_PI6_FUNC_TIM8_CH2 0x8604
+#define STM32H7_PI6_FUNC_SAI2_SD_A 0x860b
+#define STM32H7_PI6_FUNC_FMC_D28 0x860d
+#define STM32H7_PI6_FUNC_DCMI_D6 0x860e
+#define STM32H7_PI6_FUNC_LCD_B6 0x860f
+#define STM32H7_PI6_FUNC_EVENTOUT 0x8610
+#define STM32H7_PI6_FUNC_ANALOG 0x8611
+
+#define STM32H7_PI7_FUNC_GPIO 0x8700
+#define STM32H7_PI7_FUNC_TIM8_CH3 0x8704
+#define STM32H7_PI7_FUNC_SAI2_FS_A 0x870b
+#define STM32H7_PI7_FUNC_FMC_D29 0x870d
+#define STM32H7_PI7_FUNC_DCMI_D7 0x870e
+#define STM32H7_PI7_FUNC_LCD_B7 0x870f
+#define STM32H7_PI7_FUNC_EVENTOUT 0x8710
+#define STM32H7_PI7_FUNC_ANALOG 0x8711
+
+#define STM32H7_PI8_FUNC_GPIO 0x8800
+#define STM32H7_PI8_FUNC_EVENTOUT 0x8810
+#define STM32H7_PI8_FUNC_ANALOG 0x8811
+
+#define STM32H7_PI9_FUNC_GPIO 0x8900
+#define STM32H7_PI9_FUNC_UART4_RX 0x8909
+#define STM32H7_PI9_FUNC_CAN1_RX 0x890a
+#define STM32H7_PI9_FUNC_FMC_D30 0x890d
+#define STM32H7_PI9_FUNC_LCD_VSYNC 0x890f
+#define STM32H7_PI9_FUNC_EVENTOUT 0x8910
+#define STM32H7_PI9_FUNC_ANALOG 0x8911
+
+#define STM32H7_PI10_FUNC_GPIO 0x8a00
+#define STM32H7_PI10_FUNC_CAN1_RXFD 0x8a0a
+#define STM32H7_PI10_FUNC_ETH_MII_RX_ER 0x8a0c
+#define STM32H7_PI10_FUNC_FMC_D31 0x8a0d
+#define STM32H7_PI10_FUNC_LCD_HSYNC 0x8a0f
+#define STM32H7_PI10_FUNC_EVENTOUT 0x8a10
+#define STM32H7_PI10_FUNC_ANALOG 0x8a11
+
+#define STM32H7_PI11_FUNC_GPIO 0x8b00
+#define STM32H7_PI11_FUNC_LCD_G6 0x8b0a
+#define STM32H7_PI11_FUNC_OTG_HS_ULPI_DIR 0x8b0b
+#define STM32H7_PI11_FUNC_EVENTOUT 0x8b10
+#define STM32H7_PI11_FUNC_ANALOG 0x8b11
+
+#define STM32H7_PI12_FUNC_GPIO 0x8c00
+#define STM32H7_PI12_FUNC_ETH_TX_ER 0x8c0c
+#define STM32H7_PI12_FUNC_LCD_HSYNC 0x8c0f
+#define STM32H7_PI12_FUNC_EVENTOUT 0x8c10
+#define STM32H7_PI12_FUNC_ANALOG 0x8c11
+
+#define STM32H7_PI13_FUNC_GPIO 0x8d00
+#define STM32H7_PI13_FUNC_LCD_VSYNC 0x8d0f
+#define STM32H7_PI13_FUNC_EVENTOUT 0x8d10
+#define STM32H7_PI13_FUNC_ANALOG 0x8d11
+
+#define STM32H7_PI14_FUNC_GPIO 0x8e00
+#define STM32H7_PI14_FUNC_LCD_CLK 0x8e0f
+#define STM32H7_PI14_FUNC_EVENTOUT 0x8e10
+#define STM32H7_PI14_FUNC_ANALOG 0x8e11
+
+#define STM32H7_PI15_FUNC_GPIO 0x8f00
+#define STM32H7_PI15_FUNC_LCD_G2 0x8f0a
+#define STM32H7_PI15_FUNC_LCD_R0 0x8f0f
+#define STM32H7_PI15_FUNC_EVENTOUT 0x8f10
+#define STM32H7_PI15_FUNC_ANALOG 0x8f11
+
+#define STM32H7_PJ0_FUNC_GPIO 0x9000
+#define STM32H7_PJ0_FUNC_LCD_R7 0x900a
+#define STM32H7_PJ0_FUNC_LCD_R1 0x900f
+#define STM32H7_PJ0_FUNC_EVENTOUT 0x9010
+#define STM32H7_PJ0_FUNC_ANALOG 0x9011
+
+#define STM32H7_PJ1_FUNC_GPIO 0x9100
+#define STM32H7_PJ1_FUNC_LCD_R2 0x910f
+#define STM32H7_PJ1_FUNC_EVENTOUT 0x9110
+#define STM32H7_PJ1_FUNC_ANALOG 0x9111
+
+#define STM32H7_PJ2_FUNC_GPIO 0x9200
+#define STM32H7_PJ2_FUNC_DSI_TE 0x920e
+#define STM32H7_PJ2_FUNC_LCD_R3 0x920f
+#define STM32H7_PJ2_FUNC_EVENTOUT 0x9210
+#define STM32H7_PJ2_FUNC_ANALOG 0x9211
+
+#define STM32H7_PJ3_FUNC_GPIO 0x9300
+#define STM32H7_PJ3_FUNC_LCD_R4 0x930f
+#define STM32H7_PJ3_FUNC_EVENTOUT 0x9310
+#define STM32H7_PJ3_FUNC_ANALOG 0x9311
+
+#define STM32H7_PJ4_FUNC_GPIO 0x9400
+#define STM32H7_PJ4_FUNC_LCD_R5 0x940f
+#define STM32H7_PJ4_FUNC_EVENTOUT 0x9410
+#define STM32H7_PJ4_FUNC_ANALOG 0x9411
+
+#define STM32H7_PJ5_FUNC_GPIO 0x9500
+#define STM32H7_PJ5_FUNC_LCD_R6 0x950f
+#define STM32H7_PJ5_FUNC_EVENTOUT 0x9510
+#define STM32H7_PJ5_FUNC_ANALOG 0x9511
+
+#define STM32H7_PJ6_FUNC_GPIO 0x9600
+#define STM32H7_PJ6_FUNC_TIM8_CH2 0x9604
+#define STM32H7_PJ6_FUNC_LCD_R7 0x960f
+#define STM32H7_PJ6_FUNC_EVENTOUT 0x9610
+#define STM32H7_PJ6_FUNC_ANALOG 0x9611
+
+#define STM32H7_PJ7_FUNC_GPIO 0x9700
+#define STM32H7_PJ7_FUNC_TRGIN 0x9701
+#define STM32H7_PJ7_FUNC_TIM8_CH2N 0x9704
+#define STM32H7_PJ7_FUNC_LCD_G0 0x970f
+#define STM32H7_PJ7_FUNC_EVENTOUT 0x9710
+#define STM32H7_PJ7_FUNC_ANALOG 0x9711
+
+#define STM32H7_PJ8_FUNC_GPIO 0x9800
+#define STM32H7_PJ8_FUNC_TIM1_CH3N 0x9802
+#define STM32H7_PJ8_FUNC_TIM8_CH1 0x9804
+#define STM32H7_PJ8_FUNC_UART8_TX 0x9809
+#define STM32H7_PJ8_FUNC_LCD_G1 0x980f
+#define STM32H7_PJ8_FUNC_EVENTOUT 0x9810
+#define STM32H7_PJ8_FUNC_ANALOG 0x9811
+
+#define STM32H7_PJ9_FUNC_GPIO 0x9900
+#define STM32H7_PJ9_FUNC_TIM1_CH3 0x9902
+#define STM32H7_PJ9_FUNC_TIM8_CH1N 0x9904
+#define STM32H7_PJ9_FUNC_UART8_RX 0x9909
+#define STM32H7_PJ9_FUNC_LCD_G2 0x990f
+#define STM32H7_PJ9_FUNC_EVENTOUT 0x9910
+#define STM32H7_PJ9_FUNC_ANALOG 0x9911
+
+#define STM32H7_PJ10_FUNC_GPIO 0x9a00
+#define STM32H7_PJ10_FUNC_TIM1_CH2N 0x9a02
+#define STM32H7_PJ10_FUNC_TIM8_CH2 0x9a04
+#define STM32H7_PJ10_FUNC_SPI5_MOSI 0x9a06
+#define STM32H7_PJ10_FUNC_LCD_G3 0x9a0f
+#define STM32H7_PJ10_FUNC_EVENTOUT 0x9a10
+#define STM32H7_PJ10_FUNC_ANALOG 0x9a11
+
+#define STM32H7_PJ11_FUNC_GPIO 0x9b00
+#define STM32H7_PJ11_FUNC_TIM1_CH2 0x9b02
+#define STM32H7_PJ11_FUNC_TIM8_CH2N 0x9b04
+#define STM32H7_PJ11_FUNC_SPI5_MISO 0x9b06
+#define STM32H7_PJ11_FUNC_LCD_G4 0x9b0f
+#define STM32H7_PJ11_FUNC_EVENTOUT 0x9b10
+#define STM32H7_PJ11_FUNC_ANALOG 0x9b11
+
+#define STM32H7_PJ12_FUNC_GPIO 0x9c00
+#define STM32H7_PJ12_FUNC_TRGOUT 0x9c01
+#define STM32H7_PJ12_FUNC_LCD_G3 0x9c0a
+#define STM32H7_PJ12_FUNC_LCD_B0 0x9c0f
+#define STM32H7_PJ12_FUNC_EVENTOUT 0x9c10
+#define STM32H7_PJ12_FUNC_ANALOG 0x9c11
+
+#define STM32H7_PJ13_FUNC_GPIO 0x9d00
+#define STM32H7_PJ13_FUNC_LCD_B4 0x9d0a
+#define STM32H7_PJ13_FUNC_LCD_B1 0x9d0f
+#define STM32H7_PJ13_FUNC_EVENTOUT 0x9d10
+#define STM32H7_PJ13_FUNC_ANALOG 0x9d11
+
+#define STM32H7_PJ14_FUNC_GPIO 0x9e00
+#define STM32H7_PJ14_FUNC_LCD_B2 0x9e0f
+#define STM32H7_PJ14_FUNC_EVENTOUT 0x9e10
+#define STM32H7_PJ14_FUNC_ANALOG 0x9e11
+
+#define STM32H7_PJ15_FUNC_GPIO 0x9f00
+#define STM32H7_PJ15_FUNC_LCD_B3 0x9f0f
+#define STM32H7_PJ15_FUNC_EVENTOUT 0x9f10
+#define STM32H7_PJ15_FUNC_ANALOG 0x9f11
+
+#define STM32H7_PK0_FUNC_GPIO 0xa000
+#define STM32H7_PK0_FUNC_TIM1_CH1N 0xa002
+#define STM32H7_PK0_FUNC_TIM8_CH3 0xa004
+#define STM32H7_PK0_FUNC_SPI5_SCK 0xa006
+#define STM32H7_PK0_FUNC_LCD_G5 0xa00f
+#define STM32H7_PK0_FUNC_EVENTOUT 0xa010
+#define STM32H7_PK0_FUNC_ANALOG 0xa011
+
+#define STM32H7_PK1_FUNC_GPIO 0xa100
+#define STM32H7_PK1_FUNC_TIM1_CH1 0xa102
+#define STM32H7_PK1_FUNC_TIM8_CH3N 0xa104
+#define STM32H7_PK1_FUNC_SPI5_NSS 0xa106
+#define STM32H7_PK1_FUNC_LCD_G6 0xa10f
+#define STM32H7_PK1_FUNC_EVENTOUT 0xa110
+#define STM32H7_PK1_FUNC_ANALOG 0xa111
+
+#define STM32H7_PK2_FUNC_GPIO 0xa200
+#define STM32H7_PK2_FUNC_TIM1_BKIN 0xa202
+#define STM32H7_PK2_FUNC_TIM8_BKIN 0xa204
+#define STM32H7_PK2_FUNC_TIM8_BKIN_COMP12 0xa20b
+#define STM32H7_PK2_FUNC_TIM1_BKIN_COMP12 0xa20c
+#define STM32H7_PK2_FUNC_LCD_G7 0xa20f
+#define STM32H7_PK2_FUNC_EVENTOUT 0xa210
+#define STM32H7_PK2_FUNC_ANALOG 0xa211
+
+#define STM32H7_PK3_FUNC_GPIO 0xa300
+#define STM32H7_PK3_FUNC_LCD_B4 0xa30f
+#define STM32H7_PK3_FUNC_EVENTOUT 0xa310
+#define STM32H7_PK3_FUNC_ANALOG 0xa311
+
+#define STM32H7_PK4_FUNC_GPIO 0xa400
+#define STM32H7_PK4_FUNC_LCD_B5 0xa40f
+#define STM32H7_PK4_FUNC_EVENTOUT 0xa410
+#define STM32H7_PK4_FUNC_ANALOG 0xa411
+
+#define STM32H7_PK5_FUNC_GPIO 0xa500
+#define STM32H7_PK5_FUNC_LCD_B6 0xa50f
+#define STM32H7_PK5_FUNC_EVENTOUT 0xa510
+#define STM32H7_PK5_FUNC_ANALOG 0xa511
+
+#define STM32H7_PK6_FUNC_GPIO 0xa600
+#define STM32H7_PK6_FUNC_LCD_B7 0xa60f
+#define STM32H7_PK6_FUNC_EVENTOUT 0xa610
+#define STM32H7_PK6_FUNC_ANALOG 0xa611
+
+#define STM32H7_PK7_FUNC_GPIO 0xa700
+#define STM32H7_PK7_FUNC_LCD_DE 0xa70f
+#define STM32H7_PK7_FUNC_EVENTOUT 0xa710
+#define STM32H7_PK7_FUNC_ANALOG 0xa711
+
+#endif /* _DT_BINDINGS_STM32H7_PINFUNC_H */
diff --git a/include/dwc3-sti-glue.h b/include/dwc3-sti-glue.h
new file mode 100644
index 0000000000..98e76961b6
--- /dev/null
+++ b/include/dwc3-sti-glue.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2017
+ * Patrice Chotard <patrice.chotard@st.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __DWC3_STI_UBOOT_H_
+#define __DWC3_STI_UBOOT_H_
+
+/* glue registers */
+#define CLKRST_CTRL 0x00
+#define AUX_CLK_EN BIT(0)
+#define SW_PIPEW_RESET_N BIT(4)
+#define EXT_CFG_RESET_N BIT(8)
+
+#define XHCI_REVISION BIT(12)
+
+#define USB2_VBUS_MNGMNT_SEL1 0x2C
+#define USB2_VBUS_UTMIOTG 0x1
+
+#define SEL_OVERRIDE_VBUSVALID(n) ((n) << 0)
+#define SEL_OVERRIDE_POWERPRESENT(n) ((n) << 4)
+#define SEL_OVERRIDE_BVALID(n) ((n) << 8)
+
+/* Static DRD configuration */
+#define USB3_CONTROL_MASK 0xf77
+
+#define USB3_DEVICE_NOT_HOST BIT(0)
+#define USB3_FORCE_VBUSVALID BIT(1)
+#define USB3_DELAY_VBUSVALID BIT(2)
+#define USB3_SEL_FORCE_OPMODE BIT(4)
+#define USB3_FORCE_OPMODE(n) ((n) << 5)
+#define USB3_SEL_FORCE_DPPULLDOWN2 BIT(8)
+#define USB3_FORCE_DPPULLDOWN2 BIT(9)
+#define USB3_SEL_FORCE_DMPULLDOWN2 BIT(10)
+#define USB3_FORCE_DMPULLDOWN2 BIT(11)
+
+int sti_dwc3_init(enum usb_dr_mode mode);
+
+#endif /* __DWC3_STI_UBOOT_H_ */
diff --git a/include/environment/ti/boot.h b/include/environment/ti/boot.h
index 5b1b97bafe..799d9840aa 100644
--- a/include/environment/ti/boot.h
+++ b/include/environment/ti/boot.h
@@ -29,7 +29,14 @@
"partitions=" PARTS_DEFAULT "\0" \
"optargs=\0" \
"dofastboot=0\0" \
+ "emmc_linux_boot=" \
+ "echo Trying to boot Linux from eMMC ...; " \
+ "setenv mmcdev 1; " \
+ "setenv bootpart 1:2; " \
+ "setenv mmcroot /dev/mmcblk0p2 rw; " \
+ "run mmcboot;\0" \
"emmc_android_boot=" \
+ "echo Trying to boot Android from eMMC ...; " \
"setenv eval_bootargs setenv bootargs $bootargs; " \
"run eval_bootargs; " \
"setenv mmcdev 1; " \
@@ -44,7 +51,6 @@
"part size mmc ${mmcdev} ${boot_part} boot_size; " \
"mmc read ${fdtaddr} ${fdt_start} ${fdt_size}; " \
"mmc read ${loadaddr} ${boot_start} ${boot_size}; " \
- "echo Booting from eMMC ...; " \
"bootm $loadaddr $loadaddr $fdtaddr;\0"
#ifdef CONFIG_OMAP54XX
@@ -93,10 +99,7 @@
"run findfdt; " \
"run envboot; " \
"run mmcboot;" \
- "setenv mmcdev 1; " \
- "setenv bootpart 1:2; " \
- "setenv mmcroot /dev/mmcblk0p2 rw; " \
- "run mmcboot;" \
+ "run emmc_linux_boot; " \
"run emmc_android_boot; " \
""
diff --git a/include/flash.h b/include/flash.h
index f53fe91349..dc67cb2df6 100644
--- a/include/flash.h
+++ b/include/flash.h
@@ -42,11 +42,16 @@ typedef struct {
ushort cfi_offset; /* offset for cfi query */
ulong addr_unlock1; /* unlock address 1 for AMD flash roms */
ulong addr_unlock2; /* unlock address 2 for AMD flash roms */
+ uchar sr_supported; /* status register supported */
const char *name; /* human-readable name */
#endif
#ifdef CONFIG_MTD
struct mtd_info *mtd;
#endif
+#ifdef CONFIG_CFI_FLASH /* DM-specific parts */
+ struct udevice *dev;
+ phys_addr_t base;
+#endif
} flash_info_t;
extern flash_info_t flash_info[]; /* info for FLASH chips */
diff --git a/include/mtd/cfi_flash.h b/include/mtd/cfi_flash.h
index eade2b3614..095725a805 100644
--- a/include/mtd/cfi_flash.h
+++ b/include/mtd/cfi_flash.h
@@ -62,6 +62,7 @@
#define FLASH_OFFSET_MANUFACTURER_ID 0x00
#define FLASH_OFFSET_DEVICE_ID 0x01
+#define FLASH_OFFSET_LOWER_SW_BITS 0x0C
#define FLASH_OFFSET_DEVICE_ID2 0x0E
#define FLASH_OFFSET_DEVICE_ID3 0x0F
#define FLASH_OFFSET_CFI 0x55
diff --git a/include/usb.h b/include/usb.h
index fad04016a3..0ddc0822b4 100644
--- a/include/usb.h
+++ b/include/usb.h
@@ -766,6 +766,14 @@ struct dm_usb_ops {
* representation of this hub can be updated (xHCI)
*/
int (*update_hub_device)(struct udevice *bus, struct usb_device *udev);
+
+ /**
+ * get_max_xfer_size() - Get HCD's maximum transfer bytes
+ *
+ * The HCD may have limitation on the maximum bytes to be transferred
+ * in a USB transfer. USB class driver needs to be aware of this.
+ */
+ int (*get_max_xfer_size)(struct udevice *bus, size_t *size);
};
#define usb_get_ops(dev) ((struct dm_usb_ops *)(dev)->driver->ops)
@@ -939,7 +947,7 @@ int usb_new_device(struct usb_device *dev);
int usb_alloc_device(struct usb_device *dev);
/**
- * update_hub_device() - Update HCD's internal representation of hub
+ * usb_update_hub_device() - Update HCD's internal representation of hub
*
* After a hub descriptor is fetched, notify HCD so that its internal
* representation of this hub can be updated.
@@ -950,6 +958,18 @@ int usb_alloc_device(struct usb_device *dev);
int usb_update_hub_device(struct usb_device *dev);
/**
+ * usb_get_max_xfer_size() - Get HCD's maximum transfer bytes
+ *
+ * The HCD may have limitation on the maximum bytes to be transferred
+ * in a USB transfer. USB class driver needs to be aware of this.
+ *
+ * @dev: USB device
+ * @size: maximum transfer bytes
+ * @return 0 if OK, -ve on error
+ */
+int usb_get_max_xfer_size(struct usb_device *dev, size_t *size);
+
+/**
* usb_emul_setup_device() - Set up a new USB device emulation
*
* This is normally called when a new emulation device is bound. It tells
diff --git a/include/usb/ehci-ci.h b/include/usb/ehci-ci.h
index cd3eb47da4..59bfc14df6 100644
--- a/include/usb/ehci-ci.h
+++ b/include/usb/ehci-ci.h
@@ -156,7 +156,7 @@
#elif defined(CONFIG_MPC85xx)
#define CONFIG_SYS_FSL_USB1_ADDR CONFIG_SYS_MPC85xx_USB1_ADDR
#define CONFIG_SYS_FSL_USB2_ADDR CONFIG_SYS_MPC85xx_USB2_ADDR
-#elif defined(CONFIG_LS102XA) || defined(CONFIG_ARCH_LS1012A)
+#elif defined(CONFIG_ARCH_LS1021A) || defined(CONFIG_ARCH_LS1012A)
#define CONFIG_SYS_FSL_USB1_ADDR CONFIG_SYS_EHCI_USB1_ADDR
#define CONFIG_SYS_FSL_USB2_ADDR 0
#endif
diff --git a/net/tftp.c b/net/tftp.c
index a5ed8c5d0a..6671b1f7ca 100644
--- a/net/tftp.c
+++ b/net/tftp.c
@@ -805,7 +805,9 @@ void tftp_start(enum proto_t protocol)
printf("Load address: 0x%lx\n", load_addr);
puts("Loading: *\b");
tftp_state = STATE_SEND_RRQ;
+#ifdef CONFIG_CMD_BOOTEFI
efi_set_bootdev("Net", "", tftp_filename);
+#endif
}
time_start = get_timer(0);
diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include
index a3a5c59d0d..2c7918ad37 100644
--- a/scripts/Kbuild.include
+++ b/scripts/Kbuild.include
@@ -172,11 +172,6 @@ ld-version = $(shell $(LD) --version | $(srctree)/scripts/ld-version.sh)
# Usage: $(call ld-ifversion, -ge, 22252, y)
ld-ifversion = $(shell [ $(ld-version) $(1) $(2) ] && echo $(3) || echo $(4))
-# dtc-option
-# Usage: DTC_FLAGS += $(call dtc-option,-Wno-unit_address_vs_reg)
-dtc-option = $(call try-run,\
- echo '/dts-v1/; / {};' | $(DTC) $(1),$(1),$(2))
-
######
###
diff --git a/scripts/Makefile b/scripts/Makefile
index 3e10c16d59..9d55241463 100644
--- a/scripts/Makefile
+++ b/scripts/Makefile
@@ -21,3 +21,4 @@ build_docproc: $(obj)/docproc
# Let clean descend into subdirs
subdir- += basic kconfig
+subdir-$(CONFIG_DTC) += dtc
diff --git a/scripts/Makefile.extrawarn b/scripts/Makefile.extrawarn
index 90dc149df3..1d3a570594 100644
--- a/scripts/Makefile.extrawarn
+++ b/scripts/Makefile.extrawarn
@@ -58,8 +58,8 @@ endif
KBUILD_CFLAGS += $(warning)
-dtc-warning-2 += $(call dtc-option,-Wnode_name_chars_strict)
-dtc-warning-2 += $(call dtc-option,-Wproperty_name_chars_strict)
+dtc-warning-2 += -Wnode_name_chars_strict
+dtc-warning-2 += -Wproperty_name_chars_strict
dtc-warning := $(dtc-warning-$(findstring 1, $(KBUILD_ENABLE_EXTRA_GCC_CHECKS)))
dtc-warning += $(dtc-warning-$(findstring 2, $(KBUILD_ENABLE_EXTRA_GCC_CHECKS)))
@@ -70,11 +70,11 @@ DTC_FLAGS += $(dtc-warning)
else
# Disable noisy checks by default
-DTC_FLAGS += $(call dtc-option,-Wno-unit_address_vs_reg)
-DTC_FLAGS += $(call dtc-option,-Wno-simple_bus_reg)
-DTC_FLAGS += $(call dtc-option,-Wno-unit_address_format)
-DTC_FLAGS += $(call dtc-option,-Wno-pci_bridge)
-DTC_FLAGS += $(call dtc-option,-Wno-pci_device_bus_num)
-DTC_FLAGS += $(call dtc-option,-Wno-pci_device_reg)
+DTC_FLAGS += -Wno-unit_address_vs_reg
+DTC_FLAGS += -Wno-simple_bus_reg
+DTC_FLAGS += -Wno-unit_address_format
+DTC_FLAGS += -Wno-pci_bridge
+DTC_FLAGS += -Wno-pci_device_bus_num
+DTC_FLAGS += -Wno-pci_device_reg
endif
diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt
index 56bb639091..db5d88b4b5 100644
--- a/scripts/config_whitelist.txt
+++ b/scripts/config_whitelist.txt
@@ -1497,7 +1497,6 @@ CONFIG_MVEBU_MMC
CONFIG_MVGBE
CONFIG_MVGBE_PORTS
CONFIG_MVMFP_V2
-CONFIG_MVNETA
CONFIG_MVS
CONFIG_MVSATA_IDE
CONFIG_MVSATA_IDE_USE_PORT0
diff --git a/scripts/dtc-version.sh b/scripts/dtc-version.sh
index e8c94d390b..0744c39eb0 100755
--- a/scripts/dtc-version.sh
+++ b/scripts/dtc-version.sh
@@ -2,8 +2,8 @@
#
# dtc-version dtc-command
#
-# Prints the dtc version of `dtc-command' in a canonical 4-digit form
-# such as `0222' for binutils 2.22
+# Prints the dtc version of `dtc-command' in a canonical 6-digit form
+# such as `010404' for dtc 1.4.4
#
dtc="$*"
@@ -16,5 +16,6 @@ fi
MAJOR=$($dtc -v | head -1 | awk '{print $NF}' | cut -d . -f 1)
MINOR=$($dtc -v | head -1 | awk '{print $NF}' | cut -d . -f 2)
+PATCH=$($dtc -v | head -1 | awk '{print $NF}' | cut -d . -f 3 | cut -d - -f 1)
-printf "%02d%02d\\n" $MAJOR $MINOR
+printf "%02d%02d%02d\\n" $MAJOR $MINOR $PATCH
diff --git a/scripts/dtc/Makefile b/scripts/dtc/Makefile
new file mode 100644
index 0000000000..2a48022c41
--- /dev/null
+++ b/scripts/dtc/Makefile
@@ -0,0 +1,31 @@
+# scripts/dtc makefile
+
+hostprogs-y := dtc
+always := $(hostprogs-y)
+
+dtc-objs := dtc.o flattree.o fstree.o data.o livetree.o treesource.o \
+ srcpos.o checks.o util.o
+dtc-objs += dtc-lexer.lex.o dtc-parser.tab.o
+
+# Source files need to get at the userspace version of libfdt_env.h to compile
+
+HOSTCFLAGS_DTC := -I$(src) -I$(src)/libfdt
+
+HOSTCFLAGS_checks.o := $(HOSTCFLAGS_DTC)
+HOSTCFLAGS_data.o := $(HOSTCFLAGS_DTC)
+HOSTCFLAGS_dtc.o := $(HOSTCFLAGS_DTC)
+HOSTCFLAGS_flattree.o := $(HOSTCFLAGS_DTC)
+HOSTCFLAGS_fstree.o := $(HOSTCFLAGS_DTC)
+HOSTCFLAGS_livetree.o := $(HOSTCFLAGS_DTC)
+HOSTCFLAGS_srcpos.o := $(HOSTCFLAGS_DTC)
+HOSTCFLAGS_treesource.o := $(HOSTCFLAGS_DTC)
+HOSTCFLAGS_util.o := $(HOSTCFLAGS_DTC)
+
+HOSTCFLAGS_dtc-lexer.lex.o := $(HOSTCFLAGS_DTC)
+HOSTCFLAGS_dtc-parser.tab.o := $(HOSTCFLAGS_DTC)
+
+# dependencies on generated files need to be listed explicitly
+$(obj)/dtc-lexer.lex.o: $(obj)/dtc-parser.tab.h
+
+# generated files need to be cleaned explicitly
+clean-files := dtc-lexer.lex.c dtc-parser.tab.c dtc-parser.tab.h
diff --git a/scripts/dtc/Makefile.dtc b/scripts/dtc/Makefile.dtc
new file mode 100644
index 0000000000..bece49b355
--- /dev/null
+++ b/scripts/dtc/Makefile.dtc
@@ -0,0 +1,18 @@
+# Makefile.dtc
+#
+# This is not a complete Makefile of itself. Instead, it is designed to
+# be easily embeddable into other systems of Makefiles.
+#
+DTC_SRCS = \
+ checks.c \
+ data.c \
+ dtc.c \
+ flattree.c \
+ fstree.c \
+ livetree.c \
+ srcpos.c \
+ treesource.c \
+ util.c
+
+DTC_GEN_SRCS = dtc-lexer.lex.c dtc-parser.tab.c
+DTC_OBJS = $(DTC_SRCS:%.c=%.o) $(DTC_GEN_SRCS:%.c=%.o)
diff --git a/scripts/dtc/checks.c b/scripts/dtc/checks.c
new file mode 100644
index 0000000000..afabf64337
--- /dev/null
+++ b/scripts/dtc/checks.c
@@ -0,0 +1,1076 @@
+/*
+ * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2007.
+ *
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ */
+
+#include "dtc.h"
+
+#ifdef TRACE_CHECKS
+#define TRACE(c, ...) \
+ do { \
+ fprintf(stderr, "=== %s: ", (c)->name); \
+ fprintf(stderr, __VA_ARGS__); \
+ fprintf(stderr, "\n"); \
+ } while (0)
+#else
+#define TRACE(c, fmt, ...) do { } while (0)
+#endif
+
+enum checkstatus {
+ UNCHECKED = 0,
+ PREREQ,
+ PASSED,
+ FAILED,
+};
+
+struct check;
+
+typedef void (*check_fn)(struct check *c, struct dt_info *dti, struct node *node);
+
+struct check {
+ const char *name;
+ check_fn fn;
+ void *data;
+ bool warn, error;
+ enum checkstatus status;
+ bool inprogress;
+ int num_prereqs;
+ struct check **prereq;
+};
+
+#define CHECK_ENTRY(_nm, _fn, _d, _w, _e, ...) \
+ static struct check *_nm##_prereqs[] = { __VA_ARGS__ }; \
+ static struct check _nm = { \
+ .name = #_nm, \
+ .fn = (_fn), \
+ .data = (_d), \
+ .warn = (_w), \
+ .error = (_e), \
+ .status = UNCHECKED, \
+ .num_prereqs = ARRAY_SIZE(_nm##_prereqs), \
+ .prereq = _nm##_prereqs, \
+ };
+#define WARNING(_nm, _fn, _d, ...) \
+ CHECK_ENTRY(_nm, _fn, _d, true, false, __VA_ARGS__)
+#define ERROR(_nm, _fn, _d, ...) \
+ CHECK_ENTRY(_nm, _fn, _d, false, true, __VA_ARGS__)
+#define CHECK(_nm, _fn, _d, ...) \
+ CHECK_ENTRY(_nm, _fn, _d, false, false, __VA_ARGS__)
+
+static inline void PRINTF(3, 4) check_msg(struct check *c, struct dt_info *dti,
+ const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+
+ if ((c->warn && (quiet < 1))
+ || (c->error && (quiet < 2))) {
+ fprintf(stderr, "%s: %s (%s): ",
+ strcmp(dti->outname, "-") ? dti->outname : "<stdout>",
+ (c->error) ? "ERROR" : "Warning", c->name);
+ vfprintf(stderr, fmt, ap);
+ fprintf(stderr, "\n");
+ }
+ va_end(ap);
+}
+
+#define FAIL(c, dti, ...) \
+ do { \
+ TRACE((c), "\t\tFAILED at %s:%d", __FILE__, __LINE__); \
+ (c)->status = FAILED; \
+ check_msg((c), dti, __VA_ARGS__); \
+ } while (0)
+
+static void check_nodes_props(struct check *c, struct dt_info *dti, struct node *node)
+{
+ struct node *child;
+
+ TRACE(c, "%s", node->fullpath);
+ if (c->fn)
+ c->fn(c, dti, node);
+
+ for_each_child(node, child)
+ check_nodes_props(c, dti, child);
+}
+
+static bool run_check(struct check *c, struct dt_info *dti)
+{
+ struct node *dt = dti->dt;
+ bool error = false;
+ int i;
+
+ assert(!c->inprogress);
+
+ if (c->status != UNCHECKED)
+ goto out;
+
+ c->inprogress = true;
+
+ for (i = 0; i < c->num_prereqs; i++) {
+ struct check *prq = c->prereq[i];
+ error = error || run_check(prq, dti);
+ if (prq->status != PASSED) {
+ c->status = PREREQ;
+ check_msg(c, dti, "Failed prerequisite '%s'",
+ c->prereq[i]->name);
+ }
+ }
+
+ if (c->status != UNCHECKED)
+ goto out;
+
+ check_nodes_props(c, dti, dt);
+
+ if (c->status == UNCHECKED)
+ c->status = PASSED;
+
+ TRACE(c, "\tCompleted, status %d", c->status);
+
+out:
+ c->inprogress = false;
+ if ((c->status != PASSED) && (c->error))
+ error = true;
+ return error;
+}
+
+/*
+ * Utility check functions
+ */
+
+/* A check which always fails, for testing purposes only */
+static inline void check_always_fail(struct check *c, struct dt_info *dti,
+ struct node *node)
+{
+ FAIL(c, dti, "always_fail check");
+}
+CHECK(always_fail, check_always_fail, NULL);
+
+static void check_is_string(struct check *c, struct dt_info *dti,
+ struct node *node)
+{
+ struct property *prop;
+ char *propname = c->data;
+
+ prop = get_property(node, propname);
+ if (!prop)
+ return; /* Not present, assumed ok */
+
+ if (!data_is_one_string(prop->val))
+ FAIL(c, dti, "\"%s\" property in %s is not a string",
+ propname, node->fullpath);
+}
+#define WARNING_IF_NOT_STRING(nm, propname) \
+ WARNING(nm, check_is_string, (propname))
+#define ERROR_IF_NOT_STRING(nm, propname) \
+ ERROR(nm, check_is_string, (propname))
+
+static void check_is_cell(struct check *c, struct dt_info *dti,
+ struct node *node)
+{
+ struct property *prop;
+ char *propname = c->data;
+
+ prop = get_property(node, propname);
+ if (!prop)
+ return; /* Not present, assumed ok */
+
+ if (prop->val.len != sizeof(cell_t))
+ FAIL(c, dti, "\"%s\" property in %s is not a single cell",
+ propname, node->fullpath);
+}
+#define WARNING_IF_NOT_CELL(nm, propname) \
+ WARNING(nm, check_is_cell, (propname))
+#define ERROR_IF_NOT_CELL(nm, propname) \
+ ERROR(nm, check_is_cell, (propname))
+
+/*
+ * Structural check functions
+ */
+
+static void check_duplicate_node_names(struct check *c, struct dt_info *dti,
+ struct node *node)
+{
+ struct node *child, *child2;
+
+ for_each_child(node, child)
+ for (child2 = child->next_sibling;
+ child2;
+ child2 = child2->next_sibling)
+ if (streq(child->name, child2->name))
+ FAIL(c, dti, "Duplicate node name %s",
+ child->fullpath);
+}
+ERROR(duplicate_node_names, check_duplicate_node_names, NULL);
+
+static void check_duplicate_property_names(struct check *c, struct dt_info *dti,
+ struct node *node)
+{
+ struct property *prop, *prop2;
+
+ for_each_property(node, prop) {
+ for (prop2 = prop->next; prop2; prop2 = prop2->next) {
+ if (prop2->deleted)
+ continue;
+ if (streq(prop->name, prop2->name))
+ FAIL(c, dti, "Duplicate property name %s in %s",
+ prop->name, node->fullpath);
+ }
+ }
+}
+ERROR(duplicate_property_names, check_duplicate_property_names, NULL);
+
+#define LOWERCASE "abcdefghijklmnopqrstuvwxyz"
+#define UPPERCASE "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+#define DIGITS "0123456789"
+#define PROPNODECHARS LOWERCASE UPPERCASE DIGITS ",._+*#?-"
+#define PROPNODECHARSSTRICT LOWERCASE UPPERCASE DIGITS ",-"
+
+static void check_node_name_chars(struct check *c, struct dt_info *dti,
+ struct node *node)
+{
+ int n = strspn(node->name, c->data);
+
+ if (n < strlen(node->name))
+ FAIL(c, dti, "Bad character '%c' in node %s",
+ node->name[n], node->fullpath);
+}
+ERROR(node_name_chars, check_node_name_chars, PROPNODECHARS "@");
+
+static void check_node_name_chars_strict(struct check *c, struct dt_info *dti,
+ struct node *node)
+{
+ int n = strspn(node->name, c->data);
+
+ if (n < node->basenamelen)
+ FAIL(c, dti, "Character '%c' not recommended in node %s",
+ node->name[n], node->fullpath);
+}
+CHECK(node_name_chars_strict, check_node_name_chars_strict, PROPNODECHARSSTRICT);
+
+static void check_node_name_format(struct check *c, struct dt_info *dti,
+ struct node *node)
+{
+ if (strchr(get_unitname(node), '@'))
+ FAIL(c, dti, "Node %s has multiple '@' characters in name",
+ node->fullpath);
+}
+ERROR(node_name_format, check_node_name_format, NULL, &node_name_chars);
+
+static void check_unit_address_vs_reg(struct check *c, struct dt_info *dti,
+ struct node *node)
+{
+ const char *unitname = get_unitname(node);
+ struct property *prop = get_property(node, "reg");
+
+ if (!prop) {
+ prop = get_property(node, "ranges");
+ if (prop && !prop->val.len)
+ prop = NULL;
+ }
+
+ if (prop) {
+ if (!unitname[0])
+ FAIL(c, dti, "Node %s has a reg or ranges property, but no unit name",
+ node->fullpath);
+ } else {
+ if (unitname[0])
+ FAIL(c, dti, "Node %s has a unit name, but no reg property",
+ node->fullpath);
+ }
+}
+WARNING(unit_address_vs_reg, check_unit_address_vs_reg, NULL);
+
+static void check_property_name_chars(struct check *c, struct dt_info *dti,
+ struct node *node)
+{
+ struct property *prop;
+
+ for_each_property(node, prop) {
+ int n = strspn(prop->name, c->data);
+
+ if (n < strlen(prop->name))
+ FAIL(c, dti, "Bad character '%c' in property name \"%s\", node %s",
+ prop->name[n], prop->name, node->fullpath);
+ }
+}
+ERROR(property_name_chars, check_property_name_chars, PROPNODECHARS);
+
+static void check_property_name_chars_strict(struct check *c,
+ struct dt_info *dti,
+ struct node *node)
+{
+ struct property *prop;
+
+ for_each_property(node, prop) {
+ const char *name = prop->name;
+ int n = strspn(name, c->data);
+
+ if (n == strlen(prop->name))
+ continue;
+
+ /* Certain names are whitelisted */
+ if (streq(name, "device_type"))
+ continue;
+
+ /*
+ * # is only allowed at the beginning of property names not counting
+ * the vendor prefix.
+ */
+ if (name[n] == '#' && ((n == 0) || (name[n-1] == ','))) {
+ name += n + 1;
+ n = strspn(name, c->data);
+ }
+ if (n < strlen(name))
+ FAIL(c, dti, "Character '%c' not recommended in property name \"%s\", node %s",
+ name[n], prop->name, node->fullpath);
+ }
+}
+CHECK(property_name_chars_strict, check_property_name_chars_strict, PROPNODECHARSSTRICT);
+
+#define DESCLABEL_FMT "%s%s%s%s%s"
+#define DESCLABEL_ARGS(node,prop,mark) \
+ ((mark) ? "value of " : ""), \
+ ((prop) ? "'" : ""), \
+ ((prop) ? (prop)->name : ""), \
+ ((prop) ? "' in " : ""), (node)->fullpath
+
+static void check_duplicate_label(struct check *c, struct dt_info *dti,
+ const char *label, struct node *node,
+ struct property *prop, struct marker *mark)
+{
+ struct node *dt = dti->dt;
+ struct node *othernode = NULL;
+ struct property *otherprop = NULL;
+ struct marker *othermark = NULL;
+
+ othernode = get_node_by_label(dt, label);
+
+ if (!othernode)
+ otherprop = get_property_by_label(dt, label, &othernode);
+ if (!othernode)
+ othermark = get_marker_label(dt, label, &othernode,
+ &otherprop);
+
+ if (!othernode)
+ return;
+
+ if ((othernode != node) || (otherprop != prop) || (othermark != mark))
+ FAIL(c, dti, "Duplicate label '%s' on " DESCLABEL_FMT
+ " and " DESCLABEL_FMT,
+ label, DESCLABEL_ARGS(node, prop, mark),
+ DESCLABEL_ARGS(othernode, otherprop, othermark));
+}
+
+static void check_duplicate_label_node(struct check *c, struct dt_info *dti,
+ struct node *node)
+{
+ struct label *l;
+ struct property *prop;
+
+ for_each_label(node->labels, l)
+ check_duplicate_label(c, dti, l->label, node, NULL, NULL);
+
+ for_each_property(node, prop) {
+ struct marker *m = prop->val.markers;
+
+ for_each_label(prop->labels, l)
+ check_duplicate_label(c, dti, l->label, node, prop, NULL);
+
+ for_each_marker_of_type(m, LABEL)
+ check_duplicate_label(c, dti, m->ref, node, prop, m);
+ }
+}
+ERROR(duplicate_label, check_duplicate_label_node, NULL);
+
+static cell_t check_phandle_prop(struct check *c, struct dt_info *dti,
+ struct node *node, const char *propname)
+{
+ struct node *root = dti->dt;
+ struct property *prop;
+ struct marker *m;
+ cell_t phandle;
+
+ prop = get_property(node, propname);
+ if (!prop)
+ return 0;
+
+ if (prop->val.len != sizeof(cell_t)) {
+ FAIL(c, dti, "%s has bad length (%d) %s property",
+ node->fullpath, prop->val.len, prop->name);
+ return 0;
+ }
+
+ m = prop->val.markers;
+ for_each_marker_of_type(m, REF_PHANDLE) {
+ assert(m->offset == 0);
+ if (node != get_node_by_ref(root, m->ref))
+ /* "Set this node's phandle equal to some
+ * other node's phandle". That's nonsensical
+ * by construction. */ {
+ FAIL(c, dti, "%s in %s is a reference to another node",
+ prop->name, node->fullpath);
+ }
+ /* But setting this node's phandle equal to its own
+ * phandle is allowed - that means allocate a unique
+ * phandle for this node, even if it's not otherwise
+ * referenced. The value will be filled in later, so
+ * we treat it as having no phandle data for now. */
+ return 0;
+ }
+
+ phandle = propval_cell(prop);
+
+ if ((phandle == 0) || (phandle == -1)) {
+ FAIL(c, dti, "%s has bad value (0x%x) in %s property",
+ node->fullpath, phandle, prop->name);
+ return 0;
+ }
+
+ return phandle;
+}
+
+static void check_explicit_phandles(struct check *c, struct dt_info *dti,
+ struct node *node)
+{
+ struct node *root = dti->dt;
+ struct node *other;
+ cell_t phandle, linux_phandle;
+
+ /* Nothing should have assigned phandles yet */
+ assert(!node->phandle);
+
+ phandle = check_phandle_prop(c, dti, node, "phandle");
+
+ linux_phandle = check_phandle_prop(c, dti, node, "linux,phandle");
+
+ if (!phandle && !linux_phandle)
+ /* No valid phandles; nothing further to check */
+ return;
+
+ if (linux_phandle && phandle && (phandle != linux_phandle))
+ FAIL(c, dti, "%s has mismatching 'phandle' and 'linux,phandle'"
+ " properties", node->fullpath);
+
+ if (linux_phandle && !phandle)
+ phandle = linux_phandle;
+
+ other = get_node_by_phandle(root, phandle);
+ if (other && (other != node)) {
+ FAIL(c, dti, "%s has duplicated phandle 0x%x (seen before at %s)",
+ node->fullpath, phandle, other->fullpath);
+ return;
+ }
+
+ node->phandle = phandle;
+}
+ERROR(explicit_phandles, check_explicit_phandles, NULL);
+
+static void check_name_properties(struct check *c, struct dt_info *dti,
+ struct node *node)
+{
+ struct property **pp, *prop = NULL;
+
+ for (pp = &node->proplist; *pp; pp = &((*pp)->next))
+ if (streq((*pp)->name, "name")) {
+ prop = *pp;
+ break;
+ }
+
+ if (!prop)
+ return; /* No name property, that's fine */
+
+ if ((prop->val.len != node->basenamelen+1)
+ || (memcmp(prop->val.val, node->name, node->basenamelen) != 0)) {
+ FAIL(c, dti, "\"name\" property in %s is incorrect (\"%s\" instead"
+ " of base node name)", node->fullpath, prop->val.val);
+ } else {
+ /* The name property is correct, and therefore redundant.
+ * Delete it */
+ *pp = prop->next;
+ free(prop->name);
+ data_free(prop->val);
+ free(prop);
+ }
+}
+ERROR_IF_NOT_STRING(name_is_string, "name");
+ERROR(name_properties, check_name_properties, NULL, &name_is_string);
+
+/*
+ * Reference fixup functions
+ */
+
+static void fixup_phandle_references(struct check *c, struct dt_info *dti,
+ struct node *node)
+{
+ struct node *dt = dti->dt;
+ struct property *prop;
+
+ for_each_property(node, prop) {
+ struct marker *m = prop->val.markers;
+ struct node *refnode;
+ cell_t phandle;
+
+ for_each_marker_of_type(m, REF_PHANDLE) {
+ assert(m->offset + sizeof(cell_t) <= prop->val.len);
+
+ refnode = get_node_by_ref(dt, m->ref);
+ if (! refnode) {
+ if (!(dti->dtsflags & DTSF_PLUGIN))
+ FAIL(c, dti, "Reference to non-existent node or "
+ "label \"%s\"\n", m->ref);
+ else /* mark the entry as unresolved */
+ *((fdt32_t *)(prop->val.val + m->offset)) =
+ cpu_to_fdt32(0xffffffff);
+ continue;
+ }
+
+ phandle = get_node_phandle(dt, refnode);
+ *((fdt32_t *)(prop->val.val + m->offset)) = cpu_to_fdt32(phandle);
+ }
+ }
+}
+ERROR(phandle_references, fixup_phandle_references, NULL,
+ &duplicate_node_names, &explicit_phandles);
+
+static void fixup_path_references(struct check *c, struct dt_info *dti,
+ struct node *node)
+{
+ struct node *dt = dti->dt;
+ struct property *prop;
+
+ for_each_property(node, prop) {
+ struct marker *m = prop->val.markers;
+ struct node *refnode;
+ char *path;
+
+ for_each_marker_of_type(m, REF_PATH) {
+ assert(m->offset <= prop->val.len);
+
+ refnode = get_node_by_ref(dt, m->ref);
+ if (!refnode) {
+ FAIL(c, dti, "Reference to non-existent node or label \"%s\"\n",
+ m->ref);
+ continue;
+ }
+
+ path = refnode->fullpath;
+ prop->val = data_insert_at_marker(prop->val, m, path,
+ strlen(path) + 1);
+ }
+ }
+}
+ERROR(path_references, fixup_path_references, NULL, &duplicate_node_names);
+
+/*
+ * Semantic checks
+ */
+WARNING_IF_NOT_CELL(address_cells_is_cell, "#address-cells");
+WARNING_IF_NOT_CELL(size_cells_is_cell, "#size-cells");
+WARNING_IF_NOT_CELL(interrupt_cells_is_cell, "#interrupt-cells");
+
+WARNING_IF_NOT_STRING(device_type_is_string, "device_type");
+WARNING_IF_NOT_STRING(model_is_string, "model");
+WARNING_IF_NOT_STRING(status_is_string, "status");
+
+static void fixup_addr_size_cells(struct check *c, struct dt_info *dti,
+ struct node *node)
+{
+ struct property *prop;
+
+ node->addr_cells = -1;
+ node->size_cells = -1;
+
+ prop = get_property(node, "#address-cells");
+ if (prop)
+ node->addr_cells = propval_cell(prop);
+
+ prop = get_property(node, "#size-cells");
+ if (prop)
+ node->size_cells = propval_cell(prop);
+}
+WARNING(addr_size_cells, fixup_addr_size_cells, NULL,
+ &address_cells_is_cell, &size_cells_is_cell);
+
+#define node_addr_cells(n) \
+ (((n)->addr_cells == -1) ? 2 : (n)->addr_cells)
+#define node_size_cells(n) \
+ (((n)->size_cells == -1) ? 1 : (n)->size_cells)
+
+static void check_reg_format(struct check *c, struct dt_info *dti,
+ struct node *node)
+{
+ struct property *prop;
+ int addr_cells, size_cells, entrylen;
+
+ prop = get_property(node, "reg");
+ if (!prop)
+ return; /* No "reg", that's fine */
+
+ if (!node->parent) {
+ FAIL(c, dti, "Root node has a \"reg\" property");
+ return;
+ }
+
+ if (prop->val.len == 0)
+ FAIL(c, dti, "\"reg\" property in %s is empty", node->fullpath);
+
+ addr_cells = node_addr_cells(node->parent);
+ size_cells = node_size_cells(node->parent);
+ entrylen = (addr_cells + size_cells) * sizeof(cell_t);
+
+ if (!entrylen || (prop->val.len % entrylen) != 0)
+ FAIL(c, dti, "\"reg\" property in %s has invalid length (%d bytes) "
+ "(#address-cells == %d, #size-cells == %d)",
+ node->fullpath, prop->val.len, addr_cells, size_cells);
+}
+WARNING(reg_format, check_reg_format, NULL, &addr_size_cells);
+
+static void check_ranges_format(struct check *c, struct dt_info *dti,
+ struct node *node)
+{
+ struct property *prop;
+ int c_addr_cells, p_addr_cells, c_size_cells, p_size_cells, entrylen;
+
+ prop = get_property(node, "ranges");
+ if (!prop)
+ return;
+
+ if (!node->parent) {
+ FAIL(c, dti, "Root node has a \"ranges\" property");
+ return;
+ }
+
+ p_addr_cells = node_addr_cells(node->parent);
+ p_size_cells = node_size_cells(node->parent);
+ c_addr_cells = node_addr_cells(node);
+ c_size_cells = node_size_cells(node);
+ entrylen = (p_addr_cells + c_addr_cells + c_size_cells) * sizeof(cell_t);
+
+ if (prop->val.len == 0) {
+ if (p_addr_cells != c_addr_cells)
+ FAIL(c, dti, "%s has empty \"ranges\" property but its "
+ "#address-cells (%d) differs from %s (%d)",
+ node->fullpath, c_addr_cells, node->parent->fullpath,
+ p_addr_cells);
+ if (p_size_cells != c_size_cells)
+ FAIL(c, dti, "%s has empty \"ranges\" property but its "
+ "#size-cells (%d) differs from %s (%d)",
+ node->fullpath, c_size_cells, node->parent->fullpath,
+ p_size_cells);
+ } else if ((prop->val.len % entrylen) != 0) {
+ FAIL(c, dti, "\"ranges\" property in %s has invalid length (%d bytes) "
+ "(parent #address-cells == %d, child #address-cells == %d, "
+ "#size-cells == %d)", node->fullpath, prop->val.len,
+ p_addr_cells, c_addr_cells, c_size_cells);
+ }
+}
+WARNING(ranges_format, check_ranges_format, NULL, &addr_size_cells);
+
+static const struct bus_type pci_bus = {
+ .name = "PCI",
+};
+
+static void check_pci_bridge(struct check *c, struct dt_info *dti, struct node *node)
+{
+ struct property *prop;
+ cell_t *cells;
+
+ prop = get_property(node, "device_type");
+ if (!prop || !streq(prop->val.val, "pci"))
+ return;
+
+ node->bus = &pci_bus;
+
+ if (!strneq(node->name, "pci", node->basenamelen) &&
+ !strneq(node->name, "pcie", node->basenamelen))
+ FAIL(c, dti, "Node %s node name is not \"pci\" or \"pcie\"",
+ node->fullpath);
+
+ prop = get_property(node, "ranges");
+ if (!prop)
+ FAIL(c, dti, "Node %s missing ranges for PCI bridge (or not a bridge)",
+ node->fullpath);
+
+ if (node_addr_cells(node) != 3)
+ FAIL(c, dti, "Node %s incorrect #address-cells for PCI bridge",
+ node->fullpath);
+ if (node_size_cells(node) != 2)
+ FAIL(c, dti, "Node %s incorrect #size-cells for PCI bridge",
+ node->fullpath);
+
+ prop = get_property(node, "bus-range");
+ if (!prop) {
+ FAIL(c, dti, "Node %s missing bus-range for PCI bridge",
+ node->fullpath);
+ return;
+ }
+ if (prop->val.len != (sizeof(cell_t) * 2)) {
+ FAIL(c, dti, "Node %s bus-range must be 2 cells",
+ node->fullpath);
+ return;
+ }
+ cells = (cell_t *)prop->val.val;
+ if (fdt32_to_cpu(cells[0]) > fdt32_to_cpu(cells[1]))
+ FAIL(c, dti, "Node %s bus-range 1st cell must be less than or equal to 2nd cell",
+ node->fullpath);
+ if (fdt32_to_cpu(cells[1]) > 0xff)
+ FAIL(c, dti, "Node %s bus-range maximum bus number must be less than 256",
+ node->fullpath);
+}
+WARNING(pci_bridge, check_pci_bridge, NULL,
+ &device_type_is_string, &addr_size_cells);
+
+static void check_pci_device_bus_num(struct check *c, struct dt_info *dti, struct node *node)
+{
+ struct property *prop;
+ unsigned int bus_num, min_bus, max_bus;
+ cell_t *cells;
+
+ if (!node->parent || (node->parent->bus != &pci_bus))
+ return;
+
+ prop = get_property(node, "reg");
+ if (!prop)
+ return;
+
+ cells = (cell_t *)prop->val.val;
+ bus_num = (fdt32_to_cpu(cells[0]) & 0x00ff0000) >> 16;
+
+ prop = get_property(node->parent, "bus-range");
+ if (!prop) {
+ min_bus = max_bus = 0;
+ } else {
+ cells = (cell_t *)prop->val.val;
+ min_bus = fdt32_to_cpu(cells[0]);
+ max_bus = fdt32_to_cpu(cells[0]);
+ }
+ if ((bus_num < min_bus) || (bus_num > max_bus))
+ FAIL(c, dti, "Node %s PCI bus number %d out of range, expected (%d - %d)",
+ node->fullpath, bus_num, min_bus, max_bus);
+}
+WARNING(pci_device_bus_num, check_pci_device_bus_num, NULL, &reg_format, &pci_bridge);
+
+static void check_pci_device_reg(struct check *c, struct dt_info *dti, struct node *node)
+{
+ struct property *prop;
+ const char *unitname = get_unitname(node);
+ char unit_addr[5];
+ unsigned int dev, func, reg;
+ cell_t *cells;
+
+ if (!node->parent || (node->parent->bus != &pci_bus))
+ return;
+
+ prop = get_property(node, "reg");
+ if (!prop) {
+ FAIL(c, dti, "Node %s missing PCI reg property", node->fullpath);
+ return;
+ }
+
+ cells = (cell_t *)prop->val.val;
+ if (cells[1] || cells[2])
+ FAIL(c, dti, "Node %s PCI reg config space address cells 2 and 3 must be 0",
+ node->fullpath);
+
+ reg = fdt32_to_cpu(cells[0]);
+ dev = (reg & 0xf800) >> 11;
+ func = (reg & 0x700) >> 8;
+
+ if (reg & 0xff000000)
+ FAIL(c, dti, "Node %s PCI reg address is not configuration space",
+ node->fullpath);
+ if (reg & 0x000000ff)
+ FAIL(c, dti, "Node %s PCI reg config space address register number must be 0",
+ node->fullpath);
+
+ if (func == 0) {
+ snprintf(unit_addr, sizeof(unit_addr), "%x", dev);
+ if (streq(unitname, unit_addr))
+ return;
+ }
+
+ snprintf(unit_addr, sizeof(unit_addr), "%x,%x", dev, func);
+ if (streq(unitname, unit_addr))
+ return;
+
+ FAIL(c, dti, "Node %s PCI unit address format error, expected \"%s\"",
+ node->fullpath, unit_addr);
+}
+WARNING(pci_device_reg, check_pci_device_reg, NULL, &reg_format, &pci_bridge);
+
+static const struct bus_type simple_bus = {
+ .name = "simple-bus",
+};
+
+static bool node_is_compatible(struct node *node, const char *compat)
+{
+ struct property *prop;
+ const char *str, *end;
+
+ prop = get_property(node, "compatible");
+ if (!prop)
+ return false;
+
+ for (str = prop->val.val, end = str + prop->val.len; str < end;
+ str += strnlen(str, end - str) + 1) {
+ if (strneq(str, compat, end - str))
+ return true;
+ }
+ return false;
+}
+
+static void check_simple_bus_bridge(struct check *c, struct dt_info *dti, struct node *node)
+{
+ if (node_is_compatible(node, "simple-bus"))
+ node->bus = &simple_bus;
+}
+WARNING(simple_bus_bridge, check_simple_bus_bridge, NULL, &addr_size_cells);
+
+static void check_simple_bus_reg(struct check *c, struct dt_info *dti, struct node *node)
+{
+ struct property *prop;
+ const char *unitname = get_unitname(node);
+ char unit_addr[17];
+ unsigned int size;
+ uint64_t reg = 0;
+ cell_t *cells = NULL;
+
+ if (!node->parent || (node->parent->bus != &simple_bus))
+ return;
+
+ prop = get_property(node, "reg");
+ if (prop)
+ cells = (cell_t *)prop->val.val;
+ else {
+ prop = get_property(node, "ranges");
+ if (prop && prop->val.len)
+ /* skip of child address */
+ cells = ((cell_t *)prop->val.val) + node_addr_cells(node);
+ }
+
+ if (!cells) {
+ if (node->parent->parent && !(node->bus == &simple_bus))
+ FAIL(c, dti, "Node %s missing or empty reg/ranges property", node->fullpath);
+ return;
+ }
+
+ size = node_addr_cells(node->parent);
+ while (size--)
+ reg = (reg << 32) | fdt32_to_cpu(*(cells++));
+
+ snprintf(unit_addr, sizeof(unit_addr), "%"PRIx64, reg);
+ if (!streq(unitname, unit_addr))
+ FAIL(c, dti, "Node %s simple-bus unit address format error, expected \"%s\"",
+ node->fullpath, unit_addr);
+}
+WARNING(simple_bus_reg, check_simple_bus_reg, NULL, &reg_format, &simple_bus_bridge);
+
+static void check_unit_address_format(struct check *c, struct dt_info *dti,
+ struct node *node)
+{
+ const char *unitname = get_unitname(node);
+
+ if (node->parent && node->parent->bus)
+ return;
+
+ if (!unitname[0])
+ return;
+
+ if (!strncmp(unitname, "0x", 2)) {
+ FAIL(c, dti, "Node %s unit name should not have leading \"0x\"",
+ node->fullpath);
+ /* skip over 0x for next test */
+ unitname += 2;
+ }
+ if (unitname[0] == '0' && isxdigit(unitname[1]))
+ FAIL(c, dti, "Node %s unit name should not have leading 0s",
+ node->fullpath);
+}
+WARNING(unit_address_format, check_unit_address_format, NULL,
+ &node_name_format, &pci_bridge, &simple_bus_bridge);
+
+/*
+ * Style checks
+ */
+static void check_avoid_default_addr_size(struct check *c, struct dt_info *dti,
+ struct node *node)
+{
+ struct property *reg, *ranges;
+
+ if (!node->parent)
+ return; /* Ignore root node */
+
+ reg = get_property(node, "reg");
+ ranges = get_property(node, "ranges");
+
+ if (!reg && !ranges)
+ return;
+
+ if (node->parent->addr_cells == -1)
+ FAIL(c, dti, "Relying on default #address-cells value for %s",
+ node->fullpath);
+
+ if (node->parent->size_cells == -1)
+ FAIL(c, dti, "Relying on default #size-cells value for %s",
+ node->fullpath);
+}
+WARNING(avoid_default_addr_size, check_avoid_default_addr_size, NULL,
+ &addr_size_cells);
+
+static void check_obsolete_chosen_interrupt_controller(struct check *c,
+ struct dt_info *dti,
+ struct node *node)
+{
+ struct node *dt = dti->dt;
+ struct node *chosen;
+ struct property *prop;
+
+ if (node != dt)
+ return;
+
+
+ chosen = get_node_by_path(dt, "/chosen");
+ if (!chosen)
+ return;
+
+ prop = get_property(chosen, "interrupt-controller");
+ if (prop)
+ FAIL(c, dti, "/chosen has obsolete \"interrupt-controller\" "
+ "property");
+}
+WARNING(obsolete_chosen_interrupt_controller,
+ check_obsolete_chosen_interrupt_controller, NULL);
+
+static struct check *check_table[] = {
+ &duplicate_node_names, &duplicate_property_names,
+ &node_name_chars, &node_name_format, &property_name_chars,
+ &name_is_string, &name_properties,
+
+ &duplicate_label,
+
+ &explicit_phandles,
+ &phandle_references, &path_references,
+
+ &address_cells_is_cell, &size_cells_is_cell, &interrupt_cells_is_cell,
+ &device_type_is_string, &model_is_string, &status_is_string,
+
+ &property_name_chars_strict,
+ &node_name_chars_strict,
+
+ &addr_size_cells, &reg_format, &ranges_format,
+
+ &unit_address_vs_reg,
+ &unit_address_format,
+
+ &pci_bridge,
+ &pci_device_reg,
+ &pci_device_bus_num,
+
+ &simple_bus_bridge,
+ &simple_bus_reg,
+
+ &avoid_default_addr_size,
+ &obsolete_chosen_interrupt_controller,
+
+ &always_fail,
+};
+
+static void enable_warning_error(struct check *c, bool warn, bool error)
+{
+ int i;
+
+ /* Raising level, also raise it for prereqs */
+ if ((warn && !c->warn) || (error && !c->error))
+ for (i = 0; i < c->num_prereqs; i++)
+ enable_warning_error(c->prereq[i], warn, error);
+
+ c->warn = c->warn || warn;
+ c->error = c->error || error;
+}
+
+static void disable_warning_error(struct check *c, bool warn, bool error)
+{
+ int i;
+
+ /* Lowering level, also lower it for things this is the prereq
+ * for */
+ if ((warn && c->warn) || (error && c->error)) {
+ for (i = 0; i < ARRAY_SIZE(check_table); i++) {
+ struct check *cc = check_table[i];
+ int j;
+
+ for (j = 0; j < cc->num_prereqs; j++)
+ if (cc->prereq[j] == c)
+ disable_warning_error(cc, warn, error);
+ }
+ }
+
+ c->warn = c->warn && !warn;
+ c->error = c->error && !error;
+}
+
+void parse_checks_option(bool warn, bool error, const char *arg)
+{
+ int i;
+ const char *name = arg;
+ bool enable = true;
+
+ if ((strncmp(arg, "no-", 3) == 0)
+ || (strncmp(arg, "no_", 3) == 0)) {
+ name = arg + 3;
+ enable = false;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(check_table); i++) {
+ struct check *c = check_table[i];
+
+ if (streq(c->name, name)) {
+ if (enable)
+ enable_warning_error(c, warn, error);
+ else
+ disable_warning_error(c, warn, error);
+ return;
+ }
+ }
+
+ die("Unrecognized check name \"%s\"\n", name);
+}
+
+void process_checks(bool force, struct dt_info *dti)
+{
+ int i;
+ int error = 0;
+
+ for (i = 0; i < ARRAY_SIZE(check_table); i++) {
+ struct check *c = check_table[i];
+
+ if (c->warn || c->error)
+ error = error || run_check(c, dti);
+ }
+
+ if (error) {
+ if (!force) {
+ fprintf(stderr, "ERROR: Input tree has errors, aborting "
+ "(use -f to force output)\n");
+ exit(2);
+ } else if (quiet < 3) {
+ fprintf(stderr, "Warning: Input tree has errors, "
+ "output forced\n");
+ }
+ }
+}
diff --git a/scripts/dtc/data.c b/scripts/dtc/data.c
new file mode 100644
index 0000000000..aa37a16c88
--- /dev/null
+++ b/scripts/dtc/data.c
@@ -0,0 +1,269 @@
+/*
+ * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2005.
+ *
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ */
+
+#include "dtc.h"
+
+void data_free(struct data d)
+{
+ struct marker *m, *nm;
+
+ m = d.markers;
+ while (m) {
+ nm = m->next;
+ free(m->ref);
+ free(m);
+ m = nm;
+ }
+
+ if (d.val)
+ free(d.val);
+}
+
+struct data data_grow_for(struct data d, int xlen)
+{
+ struct data nd;
+ int newsize;
+
+ if (xlen == 0)
+ return d;
+
+ nd = d;
+
+ newsize = xlen;
+
+ while ((d.len + xlen) > newsize)
+ newsize *= 2;
+
+ nd.val = xrealloc(d.val, newsize);
+
+ return nd;
+}
+
+struct data data_copy_mem(const char *mem, int len)
+{
+ struct data d;
+
+ d = data_grow_for(empty_data, len);
+
+ d.len = len;
+ memcpy(d.val, mem, len);
+
+ return d;
+}
+
+struct data data_copy_escape_string(const char *s, int len)
+{
+ int i = 0;
+ struct data d;
+ char *q;
+
+ d = data_grow_for(empty_data, len + 1);
+
+ q = d.val;
+ while (i < len) {
+ char c = s[i++];
+
+ if (c == '\\')
+ c = get_escape_char(s, &i);
+
+ q[d.len++] = c;
+ }
+
+ q[d.len++] = '\0';
+ return d;
+}
+
+struct data data_copy_file(FILE *f, size_t maxlen)
+{
+ struct data d = empty_data;
+
+ while (!feof(f) && (d.len < maxlen)) {
+ size_t chunksize, ret;
+
+ if (maxlen == -1)
+ chunksize = 4096;
+ else
+ chunksize = maxlen - d.len;
+
+ d = data_grow_for(d, chunksize);
+ ret = fread(d.val + d.len, 1, chunksize, f);
+
+ if (ferror(f))
+ die("Error reading file into data: %s", strerror(errno));
+
+ if (d.len + ret < d.len)
+ die("Overflow reading file into data\n");
+
+ d.len += ret;
+ }
+
+ return d;
+}
+
+struct data data_append_data(struct data d, const void *p, int len)
+{
+ d = data_grow_for(d, len);
+ memcpy(d.val + d.len, p, len);
+ d.len += len;
+ return d;
+}
+
+struct data data_insert_at_marker(struct data d, struct marker *m,
+ const void *p, int len)
+{
+ d = data_grow_for(d, len);
+ memmove(d.val + m->offset + len, d.val + m->offset, d.len - m->offset);
+ memcpy(d.val + m->offset, p, len);
+ d.len += len;
+
+ /* Adjust all markers after the one we're inserting at */
+ m = m->next;
+ for_each_marker(m)
+ m->offset += len;
+ return d;
+}
+
+static struct data data_append_markers(struct data d, struct marker *m)
+{
+ struct marker **mp = &d.markers;
+
+ /* Find the end of the markerlist */
+ while (*mp)
+ mp = &((*mp)->next);
+ *mp = m;
+ return d;
+}
+
+struct data data_merge(struct data d1, struct data d2)
+{
+ struct data d;
+ struct marker *m2 = d2.markers;
+
+ d = data_append_markers(data_append_data(d1, d2.val, d2.len), m2);
+
+ /* Adjust for the length of d1 */
+ for_each_marker(m2)
+ m2->offset += d1.len;
+
+ d2.markers = NULL; /* So data_free() doesn't clobber them */
+ data_free(d2);
+
+ return d;
+}
+
+struct data data_append_integer(struct data d, uint64_t value, int bits)
+{
+ uint8_t value_8;
+ fdt16_t value_16;
+ fdt32_t value_32;
+ fdt64_t value_64;
+
+ switch (bits) {
+ case 8:
+ value_8 = value;
+ return data_append_data(d, &value_8, 1);
+
+ case 16:
+ value_16 = cpu_to_fdt16(value);
+ return data_append_data(d, &value_16, 2);
+
+ case 32:
+ value_32 = cpu_to_fdt32(value);
+ return data_append_data(d, &value_32, 4);
+
+ case 64:
+ value_64 = cpu_to_fdt64(value);
+ return data_append_data(d, &value_64, 8);
+
+ default:
+ die("Invalid literal size (%d)\n", bits);
+ }
+}
+
+struct data data_append_re(struct data d, uint64_t address, uint64_t size)
+{
+ struct fdt_reserve_entry re;
+
+ re.address = cpu_to_fdt64(address);
+ re.size = cpu_to_fdt64(size);
+
+ return data_append_data(d, &re, sizeof(re));
+}
+
+struct data data_append_cell(struct data d, cell_t word)
+{
+ return data_append_integer(d, word, sizeof(word) * 8);
+}
+
+struct data data_append_addr(struct data d, uint64_t addr)
+{
+ return data_append_integer(d, addr, sizeof(addr) * 8);
+}
+
+struct data data_append_byte(struct data d, uint8_t byte)
+{
+ return data_append_data(d, &byte, 1);
+}
+
+struct data data_append_zeroes(struct data d, int len)
+{
+ d = data_grow_for(d, len);
+
+ memset(d.val + d.len, 0, len);
+ d.len += len;
+ return d;
+}
+
+struct data data_append_align(struct data d, int align)
+{
+ int newlen = ALIGN(d.len, align);
+ return data_append_zeroes(d, newlen - d.len);
+}
+
+struct data data_add_marker(struct data d, enum markertype type, char *ref)
+{
+ struct marker *m;
+
+ m = xmalloc(sizeof(*m));
+ m->offset = d.len;
+ m->type = type;
+ m->ref = ref;
+ m->next = NULL;
+
+ return data_append_markers(d, m);
+}
+
+bool data_is_one_string(struct data d)
+{
+ int i;
+ int len = d.len;
+
+ if (len == 0)
+ return false;
+
+ for (i = 0; i < len-1; i++)
+ if (d.val[i] == '\0')
+ return false;
+
+ if (d.val[len-1] != '\0')
+ return false;
+
+ return true;
+}
diff --git a/scripts/dtc/dtc-lexer.l b/scripts/dtc/dtc-lexer.l
new file mode 100644
index 0000000000..fd825ebba6
--- /dev/null
+++ b/scripts/dtc/dtc-lexer.l
@@ -0,0 +1,306 @@
+/*
+ * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2005.
+ *
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ */
+
+%option noyywrap nounput noinput never-interactive
+
+%x BYTESTRING
+%x PROPNODENAME
+%s V1
+
+PROPNODECHAR [a-zA-Z0-9,._+*#?@-]
+PATHCHAR ({PROPNODECHAR}|[/])
+LABEL [a-zA-Z_][a-zA-Z0-9_]*
+STRING \"([^\\"]|\\.)*\"
+CHAR_LITERAL '([^']|\\')*'
+WS [[:space:]]
+COMMENT "/*"([^*]|\*+[^*/])*\*+"/"
+LINECOMMENT "//".*\n
+
+%{
+#include "dtc.h"
+#include "srcpos.h"
+#include "dtc-parser.tab.h"
+
+YYLTYPE yylloc;
+extern bool treesource_error;
+
+/* CAUTION: this will stop working if we ever use yyless() or yyunput() */
+#define YY_USER_ACTION \
+ { \
+ srcpos_update(&yylloc, yytext, yyleng); \
+ }
+
+/*#define LEXDEBUG 1*/
+
+#ifdef LEXDEBUG
+#define DPRINT(fmt, ...) fprintf(stderr, fmt, ##__VA_ARGS__)
+#else
+#define DPRINT(fmt, ...) do { } while (0)
+#endif
+
+static int dts_version = 1;
+
+#define BEGIN_DEFAULT() DPRINT("<V1>\n"); \
+ BEGIN(V1); \
+
+static void push_input_file(const char *filename);
+static bool pop_input_file(void);
+static void PRINTF(1, 2) lexical_error(const char *fmt, ...);
+
+%}
+
+%%
+<*>"/include/"{WS}*{STRING} {
+ char *name = strchr(yytext, '\"') + 1;
+ yytext[yyleng-1] = '\0';
+ push_input_file(name);
+ }
+
+<*>^"#"(line)?[ \t]+[0-9]+[ \t]+{STRING}([ \t]+[0-9]+)? {
+ char *line, *fnstart, *fnend;
+ struct data fn;
+ /* skip text before line # */
+ line = yytext;
+ while (!isdigit((unsigned char)*line))
+ line++;
+
+ /* regexp ensures that first and list "
+ * in the whole yytext are those at
+ * beginning and end of the filename string */
+ fnstart = memchr(yytext, '"', yyleng);
+ for (fnend = yytext + yyleng - 1;
+ *fnend != '"'; fnend--)
+ ;
+ assert(fnstart && fnend && (fnend > fnstart));
+
+ fn = data_copy_escape_string(fnstart + 1,
+ fnend - fnstart - 1);
+
+ /* Don't allow nuls in filenames */
+ if (memchr(fn.val, '\0', fn.len - 1))
+ lexical_error("nul in line number directive");
+
+ /* -1 since #line is the number of the next line */
+ srcpos_set_line(xstrdup(fn.val), atoi(line) - 1);
+ data_free(fn);
+ }
+
+<*><<EOF>> {
+ if (!pop_input_file()) {
+ yyterminate();
+ }
+ }
+
+<*>{STRING} {
+ DPRINT("String: %s\n", yytext);
+ yylval.data = data_copy_escape_string(yytext+1,
+ yyleng-2);
+ return DT_STRING;
+ }
+
+<*>"/dts-v1/" {
+ DPRINT("Keyword: /dts-v1/\n");
+ dts_version = 1;
+ BEGIN_DEFAULT();
+ return DT_V1;
+ }
+
+<*>"/plugin/" {
+ DPRINT("Keyword: /plugin/\n");
+ return DT_PLUGIN;
+ }
+
+<*>"/memreserve/" {
+ DPRINT("Keyword: /memreserve/\n");
+ BEGIN_DEFAULT();
+ return DT_MEMRESERVE;
+ }
+
+<*>"/bits/" {
+ DPRINT("Keyword: /bits/\n");
+ BEGIN_DEFAULT();
+ return DT_BITS;
+ }
+
+<*>"/delete-property/" {
+ DPRINT("Keyword: /delete-property/\n");
+ DPRINT("<PROPNODENAME>\n");
+ BEGIN(PROPNODENAME);
+ return DT_DEL_PROP;
+ }
+
+<*>"/delete-node/" {
+ DPRINT("Keyword: /delete-node/\n");
+ DPRINT("<PROPNODENAME>\n");
+ BEGIN(PROPNODENAME);
+ return DT_DEL_NODE;
+ }
+
+<*>{LABEL}: {
+ DPRINT("Label: %s\n", yytext);
+ yylval.labelref = xstrdup(yytext);
+ yylval.labelref[yyleng-1] = '\0';
+ return DT_LABEL;
+ }
+
+<V1>([0-9]+|0[xX][0-9a-fA-F]+)(U|L|UL|LL|ULL)? {
+ char *e;
+ DPRINT("Integer Literal: '%s'\n", yytext);
+
+ errno = 0;
+ yylval.integer = strtoull(yytext, &e, 0);
+
+ if (*e && e[strspn(e, "UL")]) {
+ lexical_error("Bad integer literal '%s'",
+ yytext);
+ }
+
+ if (errno == ERANGE)
+ lexical_error("Integer literal '%s' out of range",
+ yytext);
+ else
+ /* ERANGE is the only strtoull error triggerable
+ * by strings matching the pattern */
+ assert(errno == 0);
+ return DT_LITERAL;
+ }
+
+<*>{CHAR_LITERAL} {
+ struct data d;
+ DPRINT("Character literal: %s\n", yytext);
+
+ d = data_copy_escape_string(yytext+1, yyleng-2);
+ if (d.len == 1) {
+ lexical_error("Empty character literal");
+ yylval.integer = 0;
+ } else {
+ yylval.integer = (unsigned char)d.val[0];
+
+ if (d.len > 2)
+ lexical_error("Character literal has %d"
+ " characters instead of 1",
+ d.len - 1);
+ }
+
+ data_free(d);
+ return DT_CHAR_LITERAL;
+ }
+
+<*>\&{LABEL} { /* label reference */
+ DPRINT("Ref: %s\n", yytext+1);
+ yylval.labelref = xstrdup(yytext+1);
+ return DT_REF;
+ }
+
+<*>"&{/"{PATHCHAR}*\} { /* new-style path reference */
+ yytext[yyleng-1] = '\0';
+ DPRINT("Ref: %s\n", yytext+2);
+ yylval.labelref = xstrdup(yytext+2);
+ return DT_REF;
+ }
+
+<BYTESTRING>[0-9a-fA-F]{2} {
+ yylval.byte = strtol(yytext, NULL, 16);
+ DPRINT("Byte: %02x\n", (int)yylval.byte);
+ return DT_BYTE;
+ }
+
+<BYTESTRING>"]" {
+ DPRINT("/BYTESTRING\n");
+ BEGIN_DEFAULT();
+ return ']';
+ }
+
+<PROPNODENAME>\\?{PROPNODECHAR}+ {
+ DPRINT("PropNodeName: %s\n", yytext);
+ yylval.propnodename = xstrdup((yytext[0] == '\\') ?
+ yytext + 1 : yytext);
+ BEGIN_DEFAULT();
+ return DT_PROPNODENAME;
+ }
+
+"/incbin/" {
+ DPRINT("Binary Include\n");
+ return DT_INCBIN;
+ }
+
+<*>{WS}+ /* eat whitespace */
+<*>{COMMENT}+ /* eat C-style comments */
+<*>{LINECOMMENT}+ /* eat C++-style comments */
+
+<*>"<<" { return DT_LSHIFT; };
+<*>">>" { return DT_RSHIFT; };
+<*>"<=" { return DT_LE; };
+<*>">=" { return DT_GE; };
+<*>"==" { return DT_EQ; };
+<*>"!=" { return DT_NE; };
+<*>"&&" { return DT_AND; };
+<*>"||" { return DT_OR; };
+
+<*>. {
+ DPRINT("Char: %c (\\x%02x)\n", yytext[0],
+ (unsigned)yytext[0]);
+ if (yytext[0] == '[') {
+ DPRINT("<BYTESTRING>\n");
+ BEGIN(BYTESTRING);
+ }
+ if ((yytext[0] == '{')
+ || (yytext[0] == ';')) {
+ DPRINT("<PROPNODENAME>\n");
+ BEGIN(PROPNODENAME);
+ }
+ return yytext[0];
+ }
+
+%%
+
+static void push_input_file(const char *filename)
+{
+ assert(filename);
+
+ srcfile_push(filename);
+
+ yyin = current_srcfile->f;
+
+ yypush_buffer_state(yy_create_buffer(yyin, YY_BUF_SIZE));
+}
+
+
+static bool pop_input_file(void)
+{
+ if (srcfile_pop() == 0)
+ return false;
+
+ yypop_buffer_state();
+ yyin = current_srcfile->f;
+
+ return true;
+}
+
+static void lexical_error(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ srcpos_verror(&yylloc, "Lexical error", fmt, ap);
+ va_end(ap);
+
+ treesource_error = true;
+}
diff --git a/scripts/dtc/dtc-lexer.lex.c_shipped b/scripts/dtc/dtc-lexer.lex.c_shipped
new file mode 100644
index 0000000000..3934d8624d
--- /dev/null
+++ b/scripts/dtc/dtc-lexer.lex.c_shipped
@@ -0,0 +1,2255 @@
+#line 2 "dtc-lexer.lex.c"
+
+#line 4 "dtc-lexer.lex.c"
+
+#define YY_INT_ALIGNED short int
+
+/* A lexical scanner generated by flex */
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 5
+#define YY_FLEX_SUBMINOR_VERSION 35
+#if YY_FLEX_SUBMINOR_VERSION > 0
+#define FLEX_BETA
+#endif
+
+/* First, we deal with platform-specific or compiler-specific issues. */
+
+/* begin standard C headers. */
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
+/* end standard C headers. */
+
+/* flex integer type definitions */
+
+#ifndef FLEXINT_H
+#define FLEXINT_H
+
+/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
+
+#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+
+/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
+ * if you want the limit (max/min) macros for int types.
+ */
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS 1
+#endif
+
+#include <inttypes.h>
+typedef int8_t flex_int8_t;
+typedef uint8_t flex_uint8_t;
+typedef int16_t flex_int16_t;
+typedef uint16_t flex_uint16_t;
+typedef int32_t flex_int32_t;
+typedef uint32_t flex_uint32_t;
+#else
+typedef signed char flex_int8_t;
+typedef short int flex_int16_t;
+typedef int flex_int32_t;
+typedef unsigned char flex_uint8_t;
+typedef unsigned short int flex_uint16_t;
+typedef unsigned int flex_uint32_t;
+
+/* Limits of integral types. */
+#ifndef INT8_MIN
+#define INT8_MIN (-128)
+#endif
+#ifndef INT16_MIN
+#define INT16_MIN (-32767-1)
+#endif
+#ifndef INT32_MIN
+#define INT32_MIN (-2147483647-1)
+#endif
+#ifndef INT8_MAX
+#define INT8_MAX (127)
+#endif
+#ifndef INT16_MAX
+#define INT16_MAX (32767)
+#endif
+#ifndef INT32_MAX
+#define INT32_MAX (2147483647)
+#endif
+#ifndef UINT8_MAX
+#define UINT8_MAX (255U)
+#endif
+#ifndef UINT16_MAX
+#define UINT16_MAX (65535U)
+#endif
+#ifndef UINT32_MAX
+#define UINT32_MAX (4294967295U)
+#endif
+
+#endif /* ! C99 */
+
+#endif /* ! FLEXINT_H */
+
+#ifdef __cplusplus
+
+/* The "const" storage-class-modifier is valid. */
+#define YY_USE_CONST
+
+#else /* ! __cplusplus */
+
+/* C99 requires __STDC__ to be defined as 1. */
+#if defined (__STDC__)
+
+#define YY_USE_CONST
+
+#endif /* defined (__STDC__) */
+#endif /* ! __cplusplus */
+
+#ifdef YY_USE_CONST
+#define yyconst const
+#else
+#define yyconst
+#endif
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+
+/* Promotes a possibly negative, possibly signed char to an unsigned
+ * integer for use as an array index. If the signed char is negative,
+ * we want to instead treat it as an 8-bit unsigned char, hence the
+ * double cast.
+ */
+#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+
+/* Enter a start condition. This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN (yy_start) = 1 + 2 *
+
+/* Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state. The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START (((yy_start) - 1) / 2)
+#define YYSTATE YY_START
+
+/* Action number for EOF rule of a given start state. */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+
+/* Special action meaning "start processing a new file". */
+#define YY_NEW_FILE yyrestart(yyin )
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#ifndef YY_BUF_SIZE
+#ifdef __ia64__
+/* On IA-64, the buffer size is 16k, not 8k.
+ * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case.
+ * Ditto for the __ia64__ case accordingly.
+ */
+#define YY_BUF_SIZE 32768
+#else
+#define YY_BUF_SIZE 16384
+#endif /* __ia64__ */
+#endif
+
+/* The state buf must be large enough to hold one state per character in the main buffer.
+ */
+#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
+
+#ifndef YY_TYPEDEF_YY_BUFFER_STATE
+#define YY_TYPEDEF_YY_BUFFER_STATE
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+#endif
+
+extern int yyleng;
+
+extern FILE *yyin, *yyout;
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+ #define YY_LESS_LINENO(n)
+
+/* Return all but the first "n" matched characters back to the input stream. */
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ int yyless_macro_arg = (n); \
+ YY_LESS_LINENO(yyless_macro_arg);\
+ *yy_cp = (yy_hold_char); \
+ YY_RESTORE_YY_MORE_OFFSET \
+ (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
+ YY_DO_BEFORE_ACTION; /* set up yytext again */ \
+ } \
+ while ( 0 )
+
+#define unput(c) yyunput( c, (yytext_ptr) )
+
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef size_t yy_size_t;
+#endif
+
+#ifndef YY_STRUCT_YY_BUFFER_STATE
+#define YY_STRUCT_YY_BUFFER_STATE
+struct yy_buffer_state
+ {
+ FILE *yy_input_file;
+
+ char *yy_ch_buf; /* input buffer */
+ char *yy_buf_pos; /* current position in input buffer */
+
+ /* Size of input buffer in bytes, not including room for EOB
+ * characters.
+ */
+ yy_size_t yy_buf_size;
+
+ /* Number of characters read into yy_ch_buf, not including EOB
+ * characters.
+ */
+ int yy_n_chars;
+
+ /* Whether we "own" the buffer - i.e., we know we created it,
+ * and can realloc() it to grow it, and should free() it to
+ * delete it.
+ */
+ int yy_is_our_buffer;
+
+ /* Whether this is an "interactive" input source; if so, and
+ * if we're using stdio for input, then we want to use getc()
+ * instead of fread(), to make sure we stop fetching input after
+ * each newline.
+ */
+ int yy_is_interactive;
+
+ /* Whether we're considered to be at the beginning of a line.
+ * If so, '^' rules will be active on the next match, otherwise
+ * not.
+ */
+ int yy_at_bol;
+
+ int yy_bs_lineno; /**< The line count. */
+ int yy_bs_column; /**< The column count. */
+
+ /* Whether to try to fill the input buffer when we reach the
+ * end of it.
+ */
+ int yy_fill_buffer;
+
+ int yy_buffer_status;
+
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+ /* When an EOF's been seen but there's still some text to process
+ * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+ * shouldn't try reading from the input source any more. We might
+ * still have a bunch of tokens to match, though, because of
+ * possible backing-up.
+ *
+ * When we actually see the EOF, we change the status to "new"
+ * (via yyrestart()), so that the user can continue scanning by
+ * just pointing yyin at a new input file.
+ */
+#define YY_BUFFER_EOF_PENDING 2
+
+ };
+#endif /* !YY_STRUCT_YY_BUFFER_STATE */
+
+/* Stack of input buffers. */
+static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */
+static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */
+static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */
+
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state".
+ *
+ * Returns the top of the stack, or NULL.
+ */
+#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \
+ ? (yy_buffer_stack)[(yy_buffer_stack_top)] \
+ : NULL)
+
+/* Same as previous macro, but useful when we know that the buffer stack is not
+ * NULL or when we need an lvalue. For internal use only.
+ */
+#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)]
+
+/* yy_hold_char holds the character lost when yytext is formed. */
+static char yy_hold_char;
+static int yy_n_chars; /* number of characters read into yy_ch_buf */
+int yyleng;
+
+/* Points to current character in buffer. */
+static char *yy_c_buf_p = (char *) 0;
+static int yy_init = 0; /* whether we need to initialize */
+static int yy_start = 0; /* start state number */
+
+/* Flag which is used to allow yywrap()'s to do buffer switches
+ * instead of setting up a fresh yyin. A bit of a hack ...
+ */
+static int yy_did_buffer_switch_on_eof;
+
+void yyrestart (FILE *input_file );
+void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer );
+YY_BUFFER_STATE yy_create_buffer (FILE *file,int size );
+void yy_delete_buffer (YY_BUFFER_STATE b );
+void yy_flush_buffer (YY_BUFFER_STATE b );
+void yypush_buffer_state (YY_BUFFER_STATE new_buffer );
+void yypop_buffer_state (void );
+
+static void yyensure_buffer_stack (void );
+static void yy_load_buffer_state (void );
+static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file );
+
+#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER )
+
+YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size );
+YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str );
+YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len );
+
+void *yyalloc (yy_size_t );
+void *yyrealloc (void *,yy_size_t );
+void yyfree (void * );
+
+#define yy_new_buffer yy_create_buffer
+
+#define yy_set_interactive(is_interactive) \
+ { \
+ if ( ! YY_CURRENT_BUFFER ){ \
+ yyensure_buffer_stack (); \
+ YY_CURRENT_BUFFER_LVALUE = \
+ yy_create_buffer(yyin,YY_BUF_SIZE ); \
+ } \
+ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
+ }
+
+#define yy_set_bol(at_bol) \
+ { \
+ if ( ! YY_CURRENT_BUFFER ){\
+ yyensure_buffer_stack (); \
+ YY_CURRENT_BUFFER_LVALUE = \
+ yy_create_buffer(yyin,YY_BUF_SIZE ); \
+ } \
+ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
+ }
+
+#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
+
+/* Begin user sect3 */
+
+#define yywrap(n) 1
+#define YY_SKIP_YYWRAP
+
+typedef unsigned char YY_CHAR;
+
+FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;
+
+typedef int yy_state_type;
+
+extern int yylineno;
+
+int yylineno = 1;
+
+extern char *yytext;
+#define yytext_ptr yytext
+
+static yy_state_type yy_get_previous_state (void );
+static yy_state_type yy_try_NUL_trans (yy_state_type current_state );
+static int yy_get_next_buffer (void );
+static void yy_fatal_error (yyconst char msg[] );
+
+/* Done after the current pattern has been matched and before the
+ * corresponding action - sets up yytext.
+ */
+#define YY_DO_BEFORE_ACTION \
+ (yytext_ptr) = yy_bp; \
+ yyleng = (size_t) (yy_cp - yy_bp); \
+ (yy_hold_char) = *yy_cp; \
+ *yy_cp = '\0'; \
+ (yy_c_buf_p) = yy_cp;
+
+#define YY_NUM_RULES 31
+#define YY_END_OF_BUFFER 32
+/* This struct is not used in this scanner,
+ but its presence is necessary. */
+struct yy_trans_info
+ {
+ flex_int32_t yy_verify;
+ flex_int32_t yy_nxt;
+ };
+static yyconst flex_int16_t yy_accept[166] =
+ { 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 32, 30,
+ 19, 19, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 16, 17, 17, 30,
+ 17, 11, 11, 19, 27, 0, 3, 0, 28, 13,
+ 0, 0, 12, 0, 0, 0, 0, 0, 0, 0,
+ 0, 22, 24, 26, 25, 23, 0, 10, 29, 0,
+ 0, 0, 15, 15, 17, 17, 17, 11, 11, 11,
+ 0, 13, 0, 12, 0, 0, 0, 21, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 17, 11, 11,
+ 11, 0, 14, 20, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 17, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 17, 7, 0, 0, 0,
+ 0, 0, 0, 0, 2, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 4, 18, 0, 0, 5, 2,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 1, 0, 0, 0, 0, 6, 9, 0,
+ 0, 0, 0, 8, 0
+ } ;
+
+static yyconst flex_int32_t yy_ec[256] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
+ 4, 4, 4, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 5, 6, 7, 1, 1, 8, 9, 1,
+ 1, 10, 11, 11, 12, 11, 13, 14, 15, 16,
+ 16, 16, 16, 16, 16, 16, 16, 17, 1, 18,
+ 19, 20, 11, 11, 21, 21, 21, 21, 21, 21,
+ 22, 22, 22, 22, 22, 23, 22, 22, 22, 22,
+ 22, 22, 22, 22, 24, 22, 22, 25, 22, 22,
+ 1, 26, 27, 1, 22, 1, 21, 28, 29, 30,
+
+ 31, 21, 32, 22, 33, 22, 22, 34, 35, 36,
+ 37, 38, 22, 39, 40, 41, 42, 43, 22, 25,
+ 44, 22, 45, 46, 47, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1
+ } ;
+
+static yyconst flex_int32_t yy_meta[48] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 2, 3, 1, 2,
+ 2, 2, 4, 5, 5, 5, 6, 1, 1, 1,
+ 7, 8, 8, 8, 8, 1, 1, 7, 7, 7,
+ 7, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 3, 1, 4
+ } ;
+
+static yyconst flex_int16_t yy_base[180] =
+ { 0,
+ 0, 393, 35, 392, 66, 391, 38, 107, 397, 401,
+ 55, 113, 377, 112, 111, 111, 114, 42, 376, 106,
+ 377, 347, 126, 120, 0, 147, 401, 0, 124, 0,
+ 137, 158, 170, 163, 401, 153, 401, 389, 401, 0,
+ 378, 120, 401, 131, 380, 386, 355, 139, 351, 355,
+ 351, 401, 401, 401, 401, 401, 367, 401, 401, 185,
+ 350, 346, 401, 364, 0, 185, 347, 189, 356, 355,
+ 0, 0, 330, 180, 366, 141, 372, 361, 332, 338,
+ 331, 341, 334, 326, 205, 331, 337, 329, 401, 341,
+ 167, 316, 401, 349, 348, 320, 328, 346, 180, 318,
+
+ 324, 209, 324, 320, 322, 342, 338, 309, 306, 315,
+ 305, 315, 312, 192, 342, 341, 401, 293, 306, 282,
+ 268, 252, 255, 203, 285, 282, 272, 268, 252, 233,
+ 232, 239, 208, 107, 401, 401, 238, 211, 401, 211,
+ 212, 208, 228, 203, 215, 207, 233, 222, 212, 211,
+ 203, 227, 401, 237, 225, 204, 185, 401, 401, 149,
+ 128, 88, 42, 401, 401, 253, 259, 267, 271, 275,
+ 281, 288, 292, 300, 308, 312, 318, 326, 334
+ } ;
+
+static yyconst flex_int16_t yy_def[180] =
+ { 0,
+ 165, 1, 1, 3, 165, 5, 1, 1, 165, 165,
+ 165, 165, 165, 166, 167, 168, 165, 165, 165, 165,
+ 169, 165, 165, 165, 170, 169, 165, 171, 172, 171,
+ 171, 165, 165, 165, 165, 166, 165, 166, 165, 173,
+ 165, 168, 165, 168, 174, 175, 165, 165, 165, 165,
+ 165, 165, 165, 165, 165, 165, 169, 165, 165, 165,
+ 165, 165, 165, 169, 171, 172, 171, 165, 165, 165,
+ 176, 173, 177, 168, 174, 174, 175, 165, 165, 165,
+ 165, 165, 165, 165, 165, 165, 165, 171, 165, 165,
+ 176, 177, 165, 165, 165, 165, 165, 165, 165, 165,
+
+ 165, 165, 165, 165, 171, 165, 165, 165, 165, 165,
+ 165, 165, 165, 178, 165, 171, 165, 165, 165, 165,
+ 165, 165, 165, 178, 165, 178, 165, 165, 165, 165,
+ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165,
+ 165, 165, 165, 165, 165, 165, 165, 179, 165, 165,
+ 165, 179, 165, 179, 165, 165, 165, 165, 165, 165,
+ 165, 165, 165, 165, 0, 165, 165, 165, 165, 165,
+ 165, 165, 165, 165, 165, 165, 165, 165, 165
+ } ;
+
+static yyconst flex_int16_t yy_nxt[449] =
+ { 0,
+ 10, 11, 12, 11, 13, 14, 10, 15, 16, 10,
+ 10, 10, 17, 10, 10, 10, 10, 18, 19, 20,
+ 21, 21, 21, 21, 21, 10, 10, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 10, 22, 10, 24, 25, 25,
+ 25, 32, 33, 33, 164, 26, 34, 34, 34, 52,
+ 53, 27, 26, 26, 26, 26, 10, 11, 12, 11,
+ 13, 14, 28, 15, 16, 28, 28, 28, 24, 28,
+ 28, 28, 10, 18, 19, 20, 29, 29, 29, 29,
+ 29, 30, 10, 29, 29, 29, 29, 29, 29, 29,
+
+ 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+ 10, 22, 10, 23, 34, 34, 34, 37, 39, 43,
+ 32, 33, 33, 45, 55, 56, 46, 60, 43, 45,
+ 65, 163, 46, 65, 65, 65, 44, 38, 60, 74,
+ 58, 47, 141, 48, 142, 44, 49, 47, 50, 48,
+ 76, 51, 62, 94, 50, 41, 44, 51, 37, 61,
+ 64, 64, 64, 58, 34, 34, 34, 64, 162, 80,
+ 67, 68, 68, 68, 64, 64, 64, 64, 38, 81,
+ 69, 70, 71, 68, 68, 68, 60, 161, 43, 69,
+ 70, 65, 69, 70, 65, 65, 65, 125, 85, 85,
+
+ 85, 58, 68, 68, 68, 44, 102, 110, 125, 133,
+ 102, 69, 70, 111, 114, 160, 159, 126, 85, 85,
+ 85, 140, 140, 140, 140, 140, 140, 153, 126, 147,
+ 147, 147, 153, 148, 147, 147, 147, 158, 148, 165,
+ 157, 156, 155, 151, 150, 149, 146, 154, 145, 144,
+ 143, 139, 154, 36, 36, 36, 36, 36, 36, 36,
+ 36, 40, 138, 137, 136, 40, 40, 42, 42, 42,
+ 42, 42, 42, 42, 42, 57, 57, 57, 57, 63,
+ 135, 63, 65, 134, 165, 65, 133, 65, 65, 66,
+ 132, 131, 66, 66, 66, 66, 72, 130, 72, 72,
+
+ 75, 75, 75, 75, 75, 75, 75, 75, 77, 77,
+ 77, 77, 77, 77, 77, 77, 91, 129, 91, 92,
+ 128, 92, 92, 127, 92, 92, 124, 124, 124, 124,
+ 124, 124, 124, 124, 152, 152, 152, 152, 152, 152,
+ 152, 152, 60, 60, 123, 122, 121, 120, 119, 118,
+ 117, 45, 116, 111, 115, 113, 112, 109, 108, 107,
+ 46, 106, 93, 89, 105, 104, 103, 101, 100, 99,
+ 98, 97, 96, 95, 78, 76, 93, 90, 89, 88,
+ 58, 87, 86, 58, 84, 83, 82, 79, 78, 76,
+ 73, 165, 59, 58, 54, 35, 165, 31, 23, 23,
+
+ 9, 165, 165, 165, 165, 165, 165, 165, 165, 165,
+ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165,
+ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165,
+ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165,
+ 165, 165, 165, 165, 165, 165, 165, 165
+ } ;
+
+static yyconst flex_int16_t yy_chk[449] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 3, 3, 3,
+ 3, 7, 7, 7, 163, 3, 11, 11, 11, 18,
+ 18, 3, 3, 3, 3, 3, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 8, 12, 12, 12, 14, 15, 16,
+ 8, 8, 8, 17, 20, 20, 17, 23, 42, 24,
+ 29, 162, 24, 29, 29, 29, 16, 14, 31, 44,
+ 29, 17, 134, 17, 134, 42, 17, 24, 17, 24,
+ 76, 17, 24, 76, 24, 15, 44, 24, 36, 23,
+ 26, 26, 26, 26, 34, 34, 34, 26, 161, 48,
+ 31, 32, 32, 32, 26, 26, 26, 26, 36, 48,
+ 32, 32, 32, 33, 33, 33, 60, 160, 74, 91,
+ 91, 66, 33, 33, 66, 66, 66, 114, 60, 60,
+
+ 60, 66, 68, 68, 68, 74, 85, 99, 124, 133,
+ 102, 68, 68, 99, 102, 157, 156, 114, 85, 85,
+ 85, 133, 133, 133, 140, 140, 140, 148, 124, 143,
+ 143, 143, 152, 143, 147, 147, 147, 155, 147, 154,
+ 151, 150, 149, 146, 145, 144, 142, 148, 141, 138,
+ 137, 132, 152, 166, 166, 166, 166, 166, 166, 166,
+ 166, 167, 131, 130, 129, 167, 167, 168, 168, 168,
+ 168, 168, 168, 168, 168, 169, 169, 169, 169, 170,
+ 128, 170, 171, 127, 126, 171, 125, 171, 171, 172,
+ 123, 122, 172, 172, 172, 172, 173, 121, 173, 173,
+
+ 174, 174, 174, 174, 174, 174, 174, 174, 175, 175,
+ 175, 175, 175, 175, 175, 175, 176, 120, 176, 177,
+ 119, 177, 177, 118, 177, 177, 178, 178, 178, 178,
+ 178, 178, 178, 178, 179, 179, 179, 179, 179, 179,
+ 179, 179, 116, 115, 113, 112, 111, 110, 109, 108,
+ 107, 106, 105, 104, 103, 101, 100, 98, 97, 96,
+ 95, 94, 92, 90, 88, 87, 86, 84, 83, 82,
+ 81, 80, 79, 78, 77, 75, 73, 70, 69, 67,
+ 64, 62, 61, 57, 51, 50, 49, 47, 46, 45,
+ 41, 38, 22, 21, 19, 13, 9, 6, 4, 2,
+
+ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165,
+ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165,
+ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165,
+ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165,
+ 165, 165, 165, 165, 165, 165, 165, 165
+ } ;
+
+static yy_state_type yy_last_accepting_state;
+static char *yy_last_accepting_cpos;
+
+extern int yy_flex_debug;
+int yy_flex_debug = 0;
+
+/* The intent behind this definition is that it'll catch
+ * any uses of REJECT which flex missed.
+ */
+#define REJECT reject_used_but_not_detected
+#define yymore() yymore_used_but_not_detected
+#define YY_MORE_ADJ 0
+#define YY_RESTORE_YY_MORE_OFFSET
+char *yytext;
+#line 1 "dtc-lexer.l"
+/*
+ * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2005.
+ *
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ */
+#define YY_NO_INPUT 1
+
+
+
+#line 37 "dtc-lexer.l"
+#include "dtc.h"
+#include "srcpos.h"
+#include "dtc-parser.tab.h"
+
+YYLTYPE yylloc;
+extern bool treesource_error;
+
+/* CAUTION: this will stop working if we ever use yyless() or yyunput() */
+#define YY_USER_ACTION \
+ { \
+ srcpos_update(&yylloc, yytext, yyleng); \
+ }
+
+/*#define LEXDEBUG 1*/
+
+#ifdef LEXDEBUG
+#define DPRINT(fmt, ...) fprintf(stderr, fmt, ##__VA_ARGS__)
+#else
+#define DPRINT(fmt, ...) do { } while (0)
+#endif
+
+static int dts_version = 1;
+
+#define BEGIN_DEFAULT() DPRINT("<V1>\n"); \
+ BEGIN(V1); \
+
+static void push_input_file(const char *filename);
+static bool pop_input_file(void);
+static void PRINTF(1, 2) lexical_error(const char *fmt, ...);
+
+#line 669 "dtc-lexer.lex.c"
+
+#define INITIAL 0
+#define BYTESTRING 1
+#define PROPNODENAME 2
+#define V1 3
+
+#ifndef YY_NO_UNISTD_H
+/* Special case for "unistd.h", since it is non-ANSI. We include it way
+ * down here because we want the user's section 1 to have been scanned first.
+ * The user has a chance to override it with an option.
+ */
+#include <unistd.h>
+#endif
+
+#ifndef YY_EXTRA_TYPE
+#define YY_EXTRA_TYPE void *
+#endif
+
+static int yy_init_globals (void );
+
+/* Accessor methods to globals.
+ These are made visible to non-reentrant scanners for convenience. */
+
+int yylex_destroy (void );
+
+int yyget_debug (void );
+
+void yyset_debug (int debug_flag );
+
+YY_EXTRA_TYPE yyget_extra (void );
+
+void yyset_extra (YY_EXTRA_TYPE user_defined );
+
+FILE *yyget_in (void );
+
+void yyset_in (FILE * in_str );
+
+FILE *yyget_out (void );
+
+void yyset_out (FILE * out_str );
+
+int yyget_leng (void );
+
+char *yyget_text (void );
+
+int yyget_lineno (void );
+
+void yyset_lineno (int line_number );
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int yywrap (void );
+#else
+extern int yywrap (void );
+#endif
+#endif
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char *,yyconst char *,int );
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * );
+#endif
+
+#ifndef YY_NO_INPUT
+
+#ifdef __cplusplus
+static int yyinput (void );
+#else
+static int input (void );
+#endif
+
+#endif
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#ifdef __ia64__
+/* On IA-64, the buffer size is 16k, not 8k */
+#define YY_READ_BUF_SIZE 16384
+#else
+#define YY_READ_BUF_SIZE 8192
+#endif /* __ia64__ */
+#endif
+
+/* Copy whatever the last rule matched to the standard output. */
+#ifndef ECHO
+/* This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0)
+#endif
+
+/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
+ { \
+ int c = '*'; \
+ size_t n; \
+ for ( n = 0; n < max_size && \
+ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
+ buf[n] = (char) c; \
+ if ( c == '\n' ) \
+ buf[n++] = (char) c; \
+ if ( c == EOF && ferror( yyin ) ) \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ result = n; \
+ } \
+ else \
+ { \
+ errno=0; \
+ while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \
+ { \
+ if( errno != EINTR) \
+ { \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ break; \
+ } \
+ errno=0; \
+ clearerr(yyin); \
+ } \
+ }\
+\
+
+#endif
+
+/* No semi-colon after return; correct usage is to write "yyterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
+#endif
+
+/* end tables serialization structures and prototypes */
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL_IS_OURS 1
+
+extern int yylex (void);
+
+#define YY_DECL int yylex (void)
+#endif /* !YY_DECL */
+
+/* Code executed at the beginning of each rule, after yytext and yyleng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_BREAK
+#define YY_BREAK break;
+#endif
+
+#define YY_RULE_SETUP \
+ if ( yyleng > 0 ) \
+ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = \
+ (yytext[yyleng - 1] == '\n'); \
+ YY_USER_ACTION
+
+/** The main scanner function which does all the work.
+ */
+YY_DECL
+{
+ register yy_state_type yy_current_state;
+ register char *yy_cp, *yy_bp;
+ register int yy_act;
+
+#line 69 "dtc-lexer.l"
+
+#line 862 "dtc-lexer.lex.c"
+
+ if ( !(yy_init) )
+ {
+ (yy_init) = 1;
+
+#ifdef YY_USER_INIT
+ YY_USER_INIT;
+#endif
+
+ if ( ! (yy_start) )
+ (yy_start) = 1; /* first start state */
+
+ if ( ! yyin )
+ yyin = stdin;
+
+ if ( ! yyout )
+ yyout = stdout;
+
+ if ( ! YY_CURRENT_BUFFER ) {
+ yyensure_buffer_stack ();
+ YY_CURRENT_BUFFER_LVALUE =
+ yy_create_buffer(yyin,YY_BUF_SIZE );
+ }
+
+ yy_load_buffer_state( );
+ }
+
+ while ( 1 ) /* loops until end-of-file is reached */
+ {
+ yy_cp = (yy_c_buf_p);
+
+ /* Support of yytext. */
+ *yy_cp = (yy_hold_char);
+
+ /* yy_bp points to the position in yy_ch_buf of the start of
+ * the current run.
+ */
+ yy_bp = yy_cp;
+
+ yy_current_state = (yy_start);
+ yy_current_state += YY_AT_BOL();
+yy_match:
+ do
+ {
+ register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
+ if ( yy_accept[yy_current_state] )
+ {
+ (yy_last_accepting_state) = yy_current_state;
+ (yy_last_accepting_cpos) = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 166 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ ++yy_cp;
+ }
+ while ( yy_current_state != 165 );
+ yy_cp = (yy_last_accepting_cpos);
+ yy_current_state = (yy_last_accepting_state);
+
+yy_find_action:
+ yy_act = yy_accept[yy_current_state];
+
+ YY_DO_BEFORE_ACTION;
+
+do_action: /* This label is used only to access EOF actions. */
+
+ switch ( yy_act )
+ { /* beginning of action switch */
+ case 0: /* must back up */
+ /* undo the effects of YY_DO_BEFORE_ACTION */
+ *yy_cp = (yy_hold_char);
+ yy_cp = (yy_last_accepting_cpos);
+ yy_current_state = (yy_last_accepting_state);
+ goto yy_find_action;
+
+case 1:
+/* rule 1 can match eol */
+YY_RULE_SETUP
+#line 70 "dtc-lexer.l"
+{
+ char *name = strchr(yytext, '\"') + 1;
+ yytext[yyleng-1] = '\0';
+ push_input_file(name);
+ }
+ YY_BREAK
+case 2:
+/* rule 2 can match eol */
+YY_RULE_SETUP
+#line 76 "dtc-lexer.l"
+{
+ char *line, *fnstart, *fnend;
+ struct data fn;
+ /* skip text before line # */
+ line = yytext;
+ while (!isdigit((unsigned char)*line))
+ line++;
+
+ /* regexp ensures that first and list "
+ * in the whole yytext are those at
+ * beginning and end of the filename string */
+ fnstart = memchr(yytext, '"', yyleng);
+ for (fnend = yytext + yyleng - 1;
+ *fnend != '"'; fnend--)
+ ;
+ assert(fnstart && fnend && (fnend > fnstart));
+
+ fn = data_copy_escape_string(fnstart + 1,
+ fnend - fnstart - 1);
+
+ /* Don't allow nuls in filenames */
+ if (memchr(fn.val, '\0', fn.len - 1))
+ lexical_error("nul in line number directive");
+
+ /* -1 since #line is the number of the next line */
+ srcpos_set_line(xstrdup(fn.val), atoi(line) - 1);
+ data_free(fn);
+ }
+ YY_BREAK
+case YY_STATE_EOF(INITIAL):
+case YY_STATE_EOF(BYTESTRING):
+case YY_STATE_EOF(PROPNODENAME):
+case YY_STATE_EOF(V1):
+#line 105 "dtc-lexer.l"
+{
+ if (!pop_input_file()) {
+ yyterminate();
+ }
+ }
+ YY_BREAK
+case 3:
+/* rule 3 can match eol */
+YY_RULE_SETUP
+#line 111 "dtc-lexer.l"
+{
+ DPRINT("String: %s\n", yytext);
+ yylval.data = data_copy_escape_string(yytext+1,
+ yyleng-2);
+ return DT_STRING;
+ }
+ YY_BREAK
+case 4:
+YY_RULE_SETUP
+#line 118 "dtc-lexer.l"
+{
+ DPRINT("Keyword: /dts-v1/\n");
+ dts_version = 1;
+ BEGIN_DEFAULT();
+ return DT_V1;
+ }
+ YY_BREAK
+case 5:
+YY_RULE_SETUP
+#line 125 "dtc-lexer.l"
+{
+ DPRINT("Keyword: /plugin/\n");
+ return DT_PLUGIN;
+ }
+ YY_BREAK
+case 6:
+YY_RULE_SETUP
+#line 130 "dtc-lexer.l"
+{
+ DPRINT("Keyword: /memreserve/\n");
+ BEGIN_DEFAULT();
+ return DT_MEMRESERVE;
+ }
+ YY_BREAK
+case 7:
+YY_RULE_SETUP
+#line 136 "dtc-lexer.l"
+{
+ DPRINT("Keyword: /bits/\n");
+ BEGIN_DEFAULT();
+ return DT_BITS;
+ }
+ YY_BREAK
+case 8:
+YY_RULE_SETUP
+#line 142 "dtc-lexer.l"
+{
+ DPRINT("Keyword: /delete-property/\n");
+ DPRINT("<PROPNODENAME>\n");
+ BEGIN(PROPNODENAME);
+ return DT_DEL_PROP;
+ }
+ YY_BREAK
+case 9:
+YY_RULE_SETUP
+#line 149 "dtc-lexer.l"
+{
+ DPRINT("Keyword: /delete-node/\n");
+ DPRINT("<PROPNODENAME>\n");
+ BEGIN(PROPNODENAME);
+ return DT_DEL_NODE;
+ }
+ YY_BREAK
+case 10:
+YY_RULE_SETUP
+#line 156 "dtc-lexer.l"
+{
+ DPRINT("Label: %s\n", yytext);
+ yylval.labelref = xstrdup(yytext);
+ yylval.labelref[yyleng-1] = '\0';
+ return DT_LABEL;
+ }
+ YY_BREAK
+case 11:
+YY_RULE_SETUP
+#line 163 "dtc-lexer.l"
+{
+ char *e;
+ DPRINT("Integer Literal: '%s'\n", yytext);
+
+ errno = 0;
+ yylval.integer = strtoull(yytext, &e, 0);
+
+ if (*e && e[strspn(e, "UL")]) {
+ lexical_error("Bad integer literal '%s'",
+ yytext);
+ }
+
+ if (errno == ERANGE)
+ lexical_error("Integer literal '%s' out of range",
+ yytext);
+ else
+ /* ERANGE is the only strtoull error triggerable
+ * by strings matching the pattern */
+ assert(errno == 0);
+ return DT_LITERAL;
+ }
+ YY_BREAK
+case 12:
+/* rule 12 can match eol */
+YY_RULE_SETUP
+#line 185 "dtc-lexer.l"
+{
+ struct data d;
+ DPRINT("Character literal: %s\n", yytext);
+
+ d = data_copy_escape_string(yytext+1, yyleng-2);
+ if (d.len == 1) {
+ lexical_error("Empty character literal");
+ yylval.integer = 0;
+ } else {
+ yylval.integer = (unsigned char)d.val[0];
+
+ if (d.len > 2)
+ lexical_error("Character literal has %d"
+ " characters instead of 1",
+ d.len - 1);
+ }
+
+ data_free(d);
+ return DT_CHAR_LITERAL;
+ }
+ YY_BREAK
+case 13:
+YY_RULE_SETUP
+#line 206 "dtc-lexer.l"
+{ /* label reference */
+ DPRINT("Ref: %s\n", yytext+1);
+ yylval.labelref = xstrdup(yytext+1);
+ return DT_REF;
+ }
+ YY_BREAK
+case 14:
+YY_RULE_SETUP
+#line 212 "dtc-lexer.l"
+{ /* new-style path reference */
+ yytext[yyleng-1] = '\0';
+ DPRINT("Ref: %s\n", yytext+2);
+ yylval.labelref = xstrdup(yytext+2);
+ return DT_REF;
+ }
+ YY_BREAK
+case 15:
+YY_RULE_SETUP
+#line 219 "dtc-lexer.l"
+{
+ yylval.byte = strtol(yytext, NULL, 16);
+ DPRINT("Byte: %02x\n", (int)yylval.byte);
+ return DT_BYTE;
+ }
+ YY_BREAK
+case 16:
+YY_RULE_SETUP
+#line 225 "dtc-lexer.l"
+{
+ DPRINT("/BYTESTRING\n");
+ BEGIN_DEFAULT();
+ return ']';
+ }
+ YY_BREAK
+case 17:
+YY_RULE_SETUP
+#line 231 "dtc-lexer.l"
+{
+ DPRINT("PropNodeName: %s\n", yytext);
+ yylval.propnodename = xstrdup((yytext[0] == '\\') ?
+ yytext + 1 : yytext);
+ BEGIN_DEFAULT();
+ return DT_PROPNODENAME;
+ }
+ YY_BREAK
+case 18:
+YY_RULE_SETUP
+#line 239 "dtc-lexer.l"
+{
+ DPRINT("Binary Include\n");
+ return DT_INCBIN;
+ }
+ YY_BREAK
+case 19:
+/* rule 19 can match eol */
+YY_RULE_SETUP
+#line 244 "dtc-lexer.l"
+/* eat whitespace */
+ YY_BREAK
+case 20:
+/* rule 20 can match eol */
+YY_RULE_SETUP
+#line 245 "dtc-lexer.l"
+/* eat C-style comments */
+ YY_BREAK
+case 21:
+/* rule 21 can match eol */
+YY_RULE_SETUP
+#line 246 "dtc-lexer.l"
+/* eat C++-style comments */
+ YY_BREAK
+case 22:
+YY_RULE_SETUP
+#line 248 "dtc-lexer.l"
+{ return DT_LSHIFT; };
+ YY_BREAK
+case 23:
+YY_RULE_SETUP
+#line 249 "dtc-lexer.l"
+{ return DT_RSHIFT; };
+ YY_BREAK
+case 24:
+YY_RULE_SETUP
+#line 250 "dtc-lexer.l"
+{ return DT_LE; };
+ YY_BREAK
+case 25:
+YY_RULE_SETUP
+#line 251 "dtc-lexer.l"
+{ return DT_GE; };
+ YY_BREAK
+case 26:
+YY_RULE_SETUP
+#line 252 "dtc-lexer.l"
+{ return DT_EQ; };
+ YY_BREAK
+case 27:
+YY_RULE_SETUP
+#line 253 "dtc-lexer.l"
+{ return DT_NE; };
+ YY_BREAK
+case 28:
+YY_RULE_SETUP
+#line 254 "dtc-lexer.l"
+{ return DT_AND; };
+ YY_BREAK
+case 29:
+YY_RULE_SETUP
+#line 255 "dtc-lexer.l"
+{ return DT_OR; };
+ YY_BREAK
+case 30:
+YY_RULE_SETUP
+#line 257 "dtc-lexer.l"
+{
+ DPRINT("Char: %c (\\x%02x)\n", yytext[0],
+ (unsigned)yytext[0]);
+ if (yytext[0] == '[') {
+ DPRINT("<BYTESTRING>\n");
+ BEGIN(BYTESTRING);
+ }
+ if ((yytext[0] == '{')
+ || (yytext[0] == ';')) {
+ DPRINT("<PROPNODENAME>\n");
+ BEGIN(PROPNODENAME);
+ }
+ return yytext[0];
+ }
+ YY_BREAK
+case 31:
+YY_RULE_SETUP
+#line 272 "dtc-lexer.l"
+ECHO;
+ YY_BREAK
+#line 1260 "dtc-lexer.lex.c"
+
+ case YY_END_OF_BUFFER:
+ {
+ /* Amount of text matched not including the EOB char. */
+ int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1;
+
+ /* Undo the effects of YY_DO_BEFORE_ACTION. */
+ *yy_cp = (yy_hold_char);
+ YY_RESTORE_YY_MORE_OFFSET
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
+ {
+ /* We're scanning a new file or input source. It's
+ * possible that this happened because the user
+ * just pointed yyin at a new source and called
+ * yylex(). If so, then we have to assure
+ * consistency between YY_CURRENT_BUFFER and our
+ * globals. Here is the right place to do so, because
+ * this is the first action (other than possibly a
+ * back-up) that will match for the new input source.
+ */
+ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+ YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin;
+ YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
+ }
+
+ /* Note that here we test for yy_c_buf_p "<=" to the position
+ * of the first EOB in the buffer, since yy_c_buf_p will
+ * already have been incremented past the NUL character
+ * (since all states make transitions on EOB to the
+ * end-of-buffer state). Contrast this with the test
+ * in input().
+ */
+ if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+ { /* This was really a NUL. */
+ yy_state_type yy_next_state;
+
+ (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state( );
+
+ /* Okay, we're now positioned to make the NUL
+ * transition. We couldn't have
+ * yy_get_previous_state() go ahead and do it
+ * for us because it doesn't know how to deal
+ * with the possibility of jamming (and we don't
+ * want to build jamming into it because then it
+ * will run more slowly).
+ */
+
+ yy_next_state = yy_try_NUL_trans( yy_current_state );
+
+ yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+
+ if ( yy_next_state )
+ {
+ /* Consume the NUL. */
+ yy_cp = ++(yy_c_buf_p);
+ yy_current_state = yy_next_state;
+ goto yy_match;
+ }
+
+ else
+ {
+ yy_cp = (yy_last_accepting_cpos);
+ yy_current_state = (yy_last_accepting_state);
+ goto yy_find_action;
+ }
+ }
+
+ else switch ( yy_get_next_buffer( ) )
+ {
+ case EOB_ACT_END_OF_FILE:
+ {
+ (yy_did_buffer_switch_on_eof) = 0;
+
+ if ( yywrap( ) )
+ {
+ /* Note: because we've taken care in
+ * yy_get_next_buffer() to have set up
+ * yytext, we can now set up
+ * yy_c_buf_p so that if some total
+ * hoser (like flex itself) wants to
+ * call the scanner after we return the
+ * YY_NULL, it'll still work - another
+ * YY_NULL will get returned.
+ */
+ (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ;
+
+ yy_act = YY_STATE_EOF(YY_START);
+ goto do_action;
+ }
+
+ else
+ {
+ if ( ! (yy_did_buffer_switch_on_eof) )
+ YY_NEW_FILE;
+ }
+ break;
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ (yy_c_buf_p) =
+ (yytext_ptr) + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state( );
+
+ yy_cp = (yy_c_buf_p);
+ yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+ goto yy_match;
+
+ case EOB_ACT_LAST_MATCH:
+ (yy_c_buf_p) =
+ &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)];
+
+ yy_current_state = yy_get_previous_state( );
+
+ yy_cp = (yy_c_buf_p);
+ yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+ goto yy_find_action;
+ }
+ break;
+ }
+
+ default:
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--no action found" );
+ } /* end of action switch */
+ } /* end of scanning one token */
+} /* end of yylex */
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ * EOB_ACT_LAST_MATCH -
+ * EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ * EOB_ACT_END_OF_FILE - end of file
+ */
+static int yy_get_next_buffer (void)
+{
+ register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
+ register char *source = (yytext_ptr);
+ register int number_to_move, i;
+ int ret_val;
+
+ if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] )
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--end of buffer missed" );
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
+ { /* Don't try to fill the buffer, so this is an EOF. */
+ if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 )
+ {
+ /* We matched a single character, the EOB, so
+ * treat this as a final EOF.
+ */
+ return EOB_ACT_END_OF_FILE;
+ }
+
+ else
+ {
+ /* We matched some text prior to the EOB, first
+ * process it.
+ */
+ return EOB_ACT_LAST_MATCH;
+ }
+ }
+
+ /* Try to read more data. */
+
+ /* First move last chars to start of buffer. */
+ number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1;
+
+ for ( i = 0; i < number_to_move; ++i )
+ *(dest++) = *(source++);
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+ /* don't do the read, it's not guaranteed to return an EOF,
+ * just force an EOF
+ */
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0;
+
+ else
+ {
+ int num_to_read =
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
+
+ while ( num_to_read <= 0 )
+ { /* Not enough room in the buffer - grow it. */
+
+ /* just a shorter name for the current buffer */
+ YY_BUFFER_STATE b = YY_CURRENT_BUFFER;
+
+ int yy_c_buf_p_offset =
+ (int) ((yy_c_buf_p) - b->yy_ch_buf);
+
+ if ( b->yy_is_our_buffer )
+ {
+ int new_size = b->yy_buf_size * 2;
+
+ if ( new_size <= 0 )
+ b->yy_buf_size += b->yy_buf_size / 8;
+ else
+ b->yy_buf_size *= 2;
+
+ b->yy_ch_buf = (char *)
+ /* Include room in for 2 EOB chars. */
+ yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 );
+ }
+ else
+ /* Can't grow it, we don't own it. */
+ b->yy_ch_buf = 0;
+
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR(
+ "fatal error - scanner input buffer overflow" );
+
+ (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset];
+
+ num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
+ number_to_move - 1;
+
+ }
+
+ if ( num_to_read > YY_READ_BUF_SIZE )
+ num_to_read = YY_READ_BUF_SIZE;
+
+ /* Read in more data. */
+ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
+ (yy_n_chars), (size_t) num_to_read );
+
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+ }
+
+ if ( (yy_n_chars) == 0 )
+ {
+ if ( number_to_move == YY_MORE_ADJ )
+ {
+ ret_val = EOB_ACT_END_OF_FILE;
+ yyrestart(yyin );
+ }
+
+ else
+ {
+ ret_val = EOB_ACT_LAST_MATCH;
+ YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
+ YY_BUFFER_EOF_PENDING;
+ }
+ }
+
+ else
+ ret_val = EOB_ACT_CONTINUE_SCAN;
+
+ if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
+ /* Extend the array by 50%, plus the number we really need. */
+ yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1);
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size );
+ if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
+ }
+
+ (yy_n_chars) += number_to_move;
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR;
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR;
+
+ (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
+
+ return ret_val;
+}
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+ static yy_state_type yy_get_previous_state (void)
+{
+ register yy_state_type yy_current_state;
+ register char *yy_cp;
+
+ yy_current_state = (yy_start);
+ yy_current_state += YY_AT_BOL();
+
+ for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp )
+ {
+ register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
+ if ( yy_accept[yy_current_state] )
+ {
+ (yy_last_accepting_state) = yy_current_state;
+ (yy_last_accepting_cpos) = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 166 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ }
+
+ return yy_current_state;
+}
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ * next_state = yy_try_NUL_trans( current_state );
+ */
+ static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state )
+{
+ register int yy_is_jam;
+ register char *yy_cp = (yy_c_buf_p);
+
+ register YY_CHAR yy_c = 1;
+ if ( yy_accept[yy_current_state] )
+ {
+ (yy_last_accepting_state) = yy_current_state;
+ (yy_last_accepting_cpos) = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 166 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ yy_is_jam = (yy_current_state == 165);
+
+ return yy_is_jam ? 0 : yy_current_state;
+}
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+ static int yyinput (void)
+#else
+ static int input (void)
+#endif
+
+{
+ int c;
+
+ *(yy_c_buf_p) = (yy_hold_char);
+
+ if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR )
+ {
+ /* yy_c_buf_p now points to the character we want to return.
+ * If this occurs *before* the EOB characters, then it's a
+ * valid NUL; if not, then we've hit the end of the buffer.
+ */
+ if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+ /* This was really a NUL. */
+ *(yy_c_buf_p) = '\0';
+
+ else
+ { /* need more input */
+ int offset = (yy_c_buf_p) - (yytext_ptr);
+ ++(yy_c_buf_p);
+
+ switch ( yy_get_next_buffer( ) )
+ {
+ case EOB_ACT_LAST_MATCH:
+ /* This happens because yy_g_n_b()
+ * sees that we've accumulated a
+ * token and flags that we need to
+ * try matching the token before
+ * proceeding. But for input(),
+ * there's no matching to consider.
+ * So convert the EOB_ACT_LAST_MATCH
+ * to EOB_ACT_END_OF_FILE.
+ */
+
+ /* Reset buffer status. */
+ yyrestart(yyin );
+
+ /*FALLTHROUGH*/
+
+ case EOB_ACT_END_OF_FILE:
+ {
+ if ( yywrap( ) )
+ return EOF;
+
+ if ( ! (yy_did_buffer_switch_on_eof) )
+ YY_NEW_FILE;
+#ifdef __cplusplus
+ return yyinput();
+#else
+ return input();
+#endif
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ (yy_c_buf_p) = (yytext_ptr) + offset;
+ break;
+ }
+ }
+ }
+
+ c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */
+ *(yy_c_buf_p) = '\0'; /* preserve yytext */
+ (yy_hold_char) = *++(yy_c_buf_p);
+
+ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = (c == '\n');
+
+ return c;
+}
+#endif /* ifndef YY_NO_INPUT */
+
+/** Immediately switch to a different input stream.
+ * @param input_file A readable stream.
+ *
+ * @note This function does not reset the start condition to @c INITIAL .
+ */
+ void yyrestart (FILE * input_file )
+{
+
+ if ( ! YY_CURRENT_BUFFER ){
+ yyensure_buffer_stack ();
+ YY_CURRENT_BUFFER_LVALUE =
+ yy_create_buffer(yyin,YY_BUF_SIZE );
+ }
+
+ yy_init_buffer(YY_CURRENT_BUFFER,input_file );
+ yy_load_buffer_state( );
+}
+
+/** Switch to a different input buffer.
+ * @param new_buffer The new input buffer.
+ *
+ */
+ void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer )
+{
+
+ /* TODO. We should be able to replace this entire function body
+ * with
+ * yypop_buffer_state();
+ * yypush_buffer_state(new_buffer);
+ */
+ yyensure_buffer_stack ();
+ if ( YY_CURRENT_BUFFER == new_buffer )
+ return;
+
+ if ( YY_CURRENT_BUFFER )
+ {
+ /* Flush out information for old buffer. */
+ *(yy_c_buf_p) = (yy_hold_char);
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+ }
+
+ YY_CURRENT_BUFFER_LVALUE = new_buffer;
+ yy_load_buffer_state( );
+
+ /* We don't actually know whether we did this switch during
+ * EOF (yywrap()) processing, but the only time this flag
+ * is looked at is after yywrap() is called, so it's safe
+ * to go ahead and always set it.
+ */
+ (yy_did_buffer_switch_on_eof) = 1;
+}
+
+static void yy_load_buffer_state (void)
+{
+ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+ (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
+ yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
+ (yy_hold_char) = *(yy_c_buf_p);
+}
+
+/** Allocate and initialize an input buffer state.
+ * @param file A readable stream.
+ * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
+ *
+ * @return the allocated buffer state.
+ */
+ YY_BUFFER_STATE yy_create_buffer (FILE * file, int size )
+{
+ YY_BUFFER_STATE b;
+
+ b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+ b->yy_buf_size = size;
+
+ /* yy_ch_buf has to be 2 characters longer than the size given because
+ * we need to put in 2 end-of-buffer characters.
+ */
+ b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2 );
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+ b->yy_is_our_buffer = 1;
+
+ yy_init_buffer(b,file );
+
+ return b;
+}
+
+/** Destroy the buffer.
+ * @param b a buffer created with yy_create_buffer()
+ *
+ */
+ void yy_delete_buffer (YY_BUFFER_STATE b )
+{
+
+ if ( ! b )
+ return;
+
+ if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
+ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
+
+ if ( b->yy_is_our_buffer )
+ yyfree((void *) b->yy_ch_buf );
+
+ yyfree((void *) b );
+}
+
+/* Initializes or reinitializes a buffer.
+ * This function is sometimes called more than once on the same buffer,
+ * such as during a yyrestart() or at EOF.
+ */
+ static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file )
+
+{
+ int oerrno = errno;
+
+ yy_flush_buffer(b );
+
+ b->yy_input_file = file;
+ b->yy_fill_buffer = 1;
+
+ /* If b is the current buffer, then yy_init_buffer was _probably_
+ * called from yyrestart() or through yy_get_next_buffer.
+ * In that case, we don't want to reset the lineno or column.
+ */
+ if (b != YY_CURRENT_BUFFER){
+ b->yy_bs_lineno = 1;
+ b->yy_bs_column = 0;
+ }
+
+ b->yy_is_interactive = 0;
+
+ errno = oerrno;
+}
+
+/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
+ * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
+ *
+ */
+ void yy_flush_buffer (YY_BUFFER_STATE b )
+{
+ if ( ! b )
+ return;
+
+ b->yy_n_chars = 0;
+
+ /* We always need two end-of-buffer characters. The first causes
+ * a transition to the end-of-buffer state. The second causes
+ * a jam in that state.
+ */
+ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+ b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+ b->yy_buf_pos = &b->yy_ch_buf[0];
+
+ b->yy_at_bol = 1;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ if ( b == YY_CURRENT_BUFFER )
+ yy_load_buffer_state( );
+}
+
+/** Pushes the new state onto the stack. The new state becomes
+ * the current state. This function will allocate the stack
+ * if necessary.
+ * @param new_buffer The new state.
+ *
+ */
+void yypush_buffer_state (YY_BUFFER_STATE new_buffer )
+{
+ if (new_buffer == NULL)
+ return;
+
+ yyensure_buffer_stack();
+
+ /* This block is copied from yy_switch_to_buffer. */
+ if ( YY_CURRENT_BUFFER )
+ {
+ /* Flush out information for old buffer. */
+ *(yy_c_buf_p) = (yy_hold_char);
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+ }
+
+ /* Only push if top exists. Otherwise, replace top. */
+ if (YY_CURRENT_BUFFER)
+ (yy_buffer_stack_top)++;
+ YY_CURRENT_BUFFER_LVALUE = new_buffer;
+
+ /* copied from yy_switch_to_buffer. */
+ yy_load_buffer_state( );
+ (yy_did_buffer_switch_on_eof) = 1;
+}
+
+/** Removes and deletes the top of the stack, if present.
+ * The next element becomes the new top.
+ *
+ */
+void yypop_buffer_state (void)
+{
+ if (!YY_CURRENT_BUFFER)
+ return;
+
+ yy_delete_buffer(YY_CURRENT_BUFFER );
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ if ((yy_buffer_stack_top) > 0)
+ --(yy_buffer_stack_top);
+
+ if (YY_CURRENT_BUFFER) {
+ yy_load_buffer_state( );
+ (yy_did_buffer_switch_on_eof) = 1;
+ }
+}
+
+/* Allocates the stack if it does not exist.
+ * Guarantees space for at least one push.
+ */
+static void yyensure_buffer_stack (void)
+{
+ int num_to_alloc;
+
+ if (!(yy_buffer_stack)) {
+
+ /* First allocation is just for 2 elements, since we don't know if this
+ * scanner will even need a stack. We use 2 instead of 1 to avoid an
+ * immediate realloc on the next call.
+ */
+ num_to_alloc = 1;
+ (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc
+ (num_to_alloc * sizeof(struct yy_buffer_state*)
+ );
+ if ( ! (yy_buffer_stack) )
+ YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
+
+ memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
+
+ (yy_buffer_stack_max) = num_to_alloc;
+ (yy_buffer_stack_top) = 0;
+ return;
+ }
+
+ if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){
+
+ /* Increase the buffer to prepare for a possible push. */
+ int grow_size = 8 /* arbitrary grow size */;
+
+ num_to_alloc = (yy_buffer_stack_max) + grow_size;
+ (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc
+ ((yy_buffer_stack),
+ num_to_alloc * sizeof(struct yy_buffer_state*)
+ );
+ if ( ! (yy_buffer_stack) )
+ YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
+
+ /* zero only the new slots.*/
+ memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*));
+ (yy_buffer_stack_max) = num_to_alloc;
+ }
+}
+
+/** Setup the input buffer state to scan directly from a user-specified character buffer.
+ * @param base the character buffer
+ * @param size the size in bytes of the character buffer
+ *
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size )
+{
+ YY_BUFFER_STATE b;
+
+ if ( size < 2 ||
+ base[size-2] != YY_END_OF_BUFFER_CHAR ||
+ base[size-1] != YY_END_OF_BUFFER_CHAR )
+ /* They forgot to leave room for the EOB's. */
+ return 0;
+
+ b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
+
+ b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */
+ b->yy_buf_pos = b->yy_ch_buf = base;
+ b->yy_is_our_buffer = 0;
+ b->yy_input_file = 0;
+ b->yy_n_chars = b->yy_buf_size;
+ b->yy_is_interactive = 0;
+ b->yy_at_bol = 1;
+ b->yy_fill_buffer = 0;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ yy_switch_to_buffer(b );
+
+ return b;
+}
+
+/** Setup the input buffer state to scan a string. The next call to yylex() will
+ * scan from a @e copy of @a str.
+ * @param yystr a NUL-terminated string to scan
+ *
+ * @return the newly allocated buffer state object.
+ * @note If you want to scan bytes that may contain NUL values, then use
+ * yy_scan_bytes() instead.
+ */
+YY_BUFFER_STATE yy_scan_string (yyconst char * yystr )
+{
+
+ return yy_scan_bytes(yystr,strlen(yystr) );
+}
+
+/** Setup the input buffer state to scan the given bytes. The next call to yylex() will
+ * scan from a @e copy of @a bytes.
+ * @param yybytes the byte buffer to scan
+ * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes.
+ *
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, int _yybytes_len )
+{
+ YY_BUFFER_STATE b;
+ char *buf;
+ yy_size_t n;
+ int i;
+
+ /* Get memory for full buffer, including space for trailing EOB's. */
+ n = _yybytes_len + 2;
+ buf = (char *) yyalloc(n );
+ if ( ! buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
+
+ for ( i = 0; i < _yybytes_len; ++i )
+ buf[i] = yybytes[i];
+
+ buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
+
+ b = yy_scan_buffer(buf,n );
+ if ( ! b )
+ YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
+
+ /* It's okay to grow etc. this buffer, and we should throw it
+ * away when we're done.
+ */
+ b->yy_is_our_buffer = 1;
+
+ return b;
+}
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+static void yy_fatal_error (yyconst char* msg )
+{
+ (void) fprintf( stderr, "%s\n", msg );
+ exit( YY_EXIT_FAILURE );
+}
+
+/* Redefine yyless() so it works in section 3 code. */
+
+#undef yyless
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ int yyless_macro_arg = (n); \
+ YY_LESS_LINENO(yyless_macro_arg);\
+ yytext[yyleng] = (yy_hold_char); \
+ (yy_c_buf_p) = yytext + yyless_macro_arg; \
+ (yy_hold_char) = *(yy_c_buf_p); \
+ *(yy_c_buf_p) = '\0'; \
+ yyleng = yyless_macro_arg; \
+ } \
+ while ( 0 )
+
+/* Accessor methods (get/set functions) to struct members. */
+
+/** Get the current line number.
+ *
+ */
+int yyget_lineno (void)
+{
+
+ return yylineno;
+}
+
+/** Get the input stream.
+ *
+ */
+FILE *yyget_in (void)
+{
+ return yyin;
+}
+
+/** Get the output stream.
+ *
+ */
+FILE *yyget_out (void)
+{
+ return yyout;
+}
+
+/** Get the length of the current token.
+ *
+ */
+int yyget_leng (void)
+{
+ return yyleng;
+}
+
+/** Get the current token.
+ *
+ */
+
+char *yyget_text (void)
+{
+ return yytext;
+}
+
+/** Set the current line number.
+ * @param line_number
+ *
+ */
+void yyset_lineno (int line_number )
+{
+
+ yylineno = line_number;
+}
+
+/** Set the input stream. This does not discard the current
+ * input buffer.
+ * @param in_str A readable stream.
+ *
+ * @see yy_switch_to_buffer
+ */
+void yyset_in (FILE * in_str )
+{
+ yyin = in_str ;
+}
+
+void yyset_out (FILE * out_str )
+{
+ yyout = out_str ;
+}
+
+int yyget_debug (void)
+{
+ return yy_flex_debug;
+}
+
+void yyset_debug (int bdebug )
+{
+ yy_flex_debug = bdebug ;
+}
+
+static int yy_init_globals (void)
+{
+ /* Initialization is the same as for the non-reentrant scanner.
+ * This function is called from yylex_destroy(), so don't allocate here.
+ */
+
+ (yy_buffer_stack) = 0;
+ (yy_buffer_stack_top) = 0;
+ (yy_buffer_stack_max) = 0;
+ (yy_c_buf_p) = (char *) 0;
+ (yy_init) = 0;
+ (yy_start) = 0;
+
+/* Defined in main.c */
+#ifdef YY_STDINIT
+ yyin = stdin;
+ yyout = stdout;
+#else
+ yyin = (FILE *) 0;
+ yyout = (FILE *) 0;
+#endif
+
+ /* For future reference: Set errno on error, since we are called by
+ * yylex_init()
+ */
+ return 0;
+}
+
+/* yylex_destroy is for both reentrant and non-reentrant scanners. */
+int yylex_destroy (void)
+{
+
+ /* Pop the buffer stack, destroying each element. */
+ while(YY_CURRENT_BUFFER){
+ yy_delete_buffer(YY_CURRENT_BUFFER );
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ yypop_buffer_state();
+ }
+
+ /* Destroy the stack itself. */
+ yyfree((yy_buffer_stack) );
+ (yy_buffer_stack) = NULL;
+
+ /* Reset the globals. This is important in a non-reentrant scanner so the next time
+ * yylex() is called, initialization will occur. */
+ yy_init_globals( );
+
+ return 0;
+}
+
+/*
+ * Internal utility routines.
+ */
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char* s1, yyconst char * s2, int n )
+{
+ register int i;
+ for ( i = 0; i < n; ++i )
+ s1[i] = s2[i];
+}
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * s )
+{
+ register int n;
+ for ( n = 0; s[n]; ++n )
+ ;
+
+ return n;
+}
+#endif
+
+void *yyalloc (yy_size_t size )
+{
+ return (void *) malloc( size );
+}
+
+void *yyrealloc (void * ptr, yy_size_t size )
+{
+ /* The cast to (char *) in the following accommodates both
+ * implementations that use char* generic pointers, and those
+ * that use void* generic pointers. It works with the latter
+ * because both ANSI C and C++ allow castless assignment from
+ * any pointer type to void*, and deal with argument conversions
+ * as though doing an assignment.
+ */
+ return (void *) realloc( (char *) ptr, size );
+}
+
+void yyfree (void * ptr )
+{
+ free( (char *) ptr ); /* see yyrealloc() for (char *) cast */
+}
+
+#define YYTABLES_NAME "yytables"
+
+#line 272 "dtc-lexer.l"
+
+
+
+static void push_input_file(const char *filename)
+{
+ assert(filename);
+
+ srcfile_push(filename);
+
+ yyin = current_srcfile->f;
+
+ yypush_buffer_state(yy_create_buffer(yyin,YY_BUF_SIZE));
+}
+
+
+static bool pop_input_file(void)
+{
+ if (srcfile_pop() == 0)
+ return false;
+
+ yypop_buffer_state();
+ yyin = current_srcfile->f;
+
+ return true;
+}
+
+static void lexical_error(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ srcpos_verror(&yylloc, "Lexical error", fmt, ap);
+ va_end(ap);
+
+ treesource_error = true;
+}
+
diff --git a/scripts/dtc/dtc-parser.tab.c_shipped b/scripts/dtc/dtc-parser.tab.c_shipped
new file mode 100644
index 0000000000..4d10814b3f
--- /dev/null
+++ b/scripts/dtc/dtc-parser.tab.c_shipped
@@ -0,0 +1,2301 @@
+/* A Bison parser, made by GNU Bison 3.0.2. */
+
+/* Bison implementation for Yacc-like parsers in C
+
+ Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* As a special exception, you may create a larger work that contains
+ part or all of the Bison parser skeleton and distribute that work
+ under terms of your choice, so long as that work isn't itself a
+ parser generator using the skeleton or a modified version thereof
+ as a parser skeleton. Alternatively, if you modify or redistribute
+ the parser skeleton itself, you may (at your option) remove this
+ special exception, which will cause the skeleton and the resulting
+ Bison output files to be licensed under the GNU General Public
+ License without this special exception.
+
+ This special exception was added by the Free Software Foundation in
+ version 2.2 of Bison. */
+
+/* C LALR(1) parser skeleton written by Richard Stallman, by
+ simplifying the original so-called "semantic" parser. */
+
+/* All symbols defined below should begin with yy or YY, to avoid
+ infringing on user name space. This should be done even for local
+ variables, as they might otherwise be expanded by user macros.
+ There are some unavoidable exceptions within include files to
+ define necessary library symbols; they are noted "INFRINGES ON
+ USER NAME SPACE" below. */
+
+/* Identify Bison output. */
+#define YYBISON 1
+
+/* Bison version. */
+#define YYBISON_VERSION "3.0.2"
+
+/* Skeleton name. */
+#define YYSKELETON_NAME "yacc.c"
+
+/* Pure parsers. */
+#define YYPURE 0
+
+/* Push parsers. */
+#define YYPUSH 0
+
+/* Pull parsers. */
+#define YYPULL 1
+
+
+
+
+/* Copy the first part of user declarations. */
+#line 20 "dtc-parser.y" /* yacc.c:339 */
+
+#include <stdio.h>
+#include <inttypes.h>
+
+#include "dtc.h"
+#include "srcpos.h"
+
+extern int yylex(void);
+extern void yyerror(char const *s);
+#define ERROR(loc, ...) \
+ do { \
+ srcpos_error((loc), "Error", __VA_ARGS__); \
+ treesource_error = true; \
+ } while (0)
+
+extern struct dt_info *parser_output;
+extern bool treesource_error;
+
+#line 85 "dtc-parser.tab.c" /* yacc.c:339 */
+
+# ifndef YY_NULLPTR
+# if defined __cplusplus && 201103L <= __cplusplus
+# define YY_NULLPTR nullptr
+# else
+# define YY_NULLPTR 0
+# endif
+# endif
+
+/* Enabling verbose error messages. */
+#ifdef YYERROR_VERBOSE
+# undef YYERROR_VERBOSE
+# define YYERROR_VERBOSE 1
+#else
+# define YYERROR_VERBOSE 0
+#endif
+
+/* In a future release of Bison, this section will be replaced
+ by #include "dtc-parser.tab.h". */
+#ifndef YY_YY_DTC_PARSER_TAB_H_INCLUDED
+# define YY_YY_DTC_PARSER_TAB_H_INCLUDED
+/* Debug traces. */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+#if YYDEBUG
+extern int yydebug;
+#endif
+
+/* Token type. */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+ enum yytokentype
+ {
+ DT_V1 = 258,
+ DT_PLUGIN = 259,
+ DT_MEMRESERVE = 260,
+ DT_LSHIFT = 261,
+ DT_RSHIFT = 262,
+ DT_LE = 263,
+ DT_GE = 264,
+ DT_EQ = 265,
+ DT_NE = 266,
+ DT_AND = 267,
+ DT_OR = 268,
+ DT_BITS = 269,
+ DT_DEL_PROP = 270,
+ DT_DEL_NODE = 271,
+ DT_PROPNODENAME = 272,
+ DT_LITERAL = 273,
+ DT_CHAR_LITERAL = 274,
+ DT_BYTE = 275,
+ DT_STRING = 276,
+ DT_LABEL = 277,
+ DT_REF = 278,
+ DT_INCBIN = 279
+ };
+#endif
+
+/* Value type. */
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+typedef union YYSTYPE YYSTYPE;
+union YYSTYPE
+{
+#line 39 "dtc-parser.y" /* yacc.c:355 */
+
+ char *propnodename;
+ char *labelref;
+ uint8_t byte;
+ struct data data;
+
+ struct {
+ struct data data;
+ int bits;
+ } array;
+
+ struct property *prop;
+ struct property *proplist;
+ struct node *node;
+ struct node *nodelist;
+ struct reserve_info *re;
+ uint64_t integer;
+ unsigned int flags;
+
+#line 170 "dtc-parser.tab.c" /* yacc.c:355 */
+};
+# define YYSTYPE_IS_TRIVIAL 1
+# define YYSTYPE_IS_DECLARED 1
+#endif
+
+/* Location type. */
+#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
+typedef struct YYLTYPE YYLTYPE;
+struct YYLTYPE
+{
+ int first_line;
+ int first_column;
+ int last_line;
+ int last_column;
+};
+# define YYLTYPE_IS_DECLARED 1
+# define YYLTYPE_IS_TRIVIAL 1
+#endif
+
+
+extern YYSTYPE yylval;
+extern YYLTYPE yylloc;
+int yyparse (void);
+
+#endif /* !YY_YY_DTC_PARSER_TAB_H_INCLUDED */
+
+/* Copy the second part of user declarations. */
+
+#line 199 "dtc-parser.tab.c" /* yacc.c:358 */
+
+#ifdef short
+# undef short
+#endif
+
+#ifdef YYTYPE_UINT8
+typedef YYTYPE_UINT8 yytype_uint8;
+#else
+typedef unsigned char yytype_uint8;
+#endif
+
+#ifdef YYTYPE_INT8
+typedef YYTYPE_INT8 yytype_int8;
+#else
+typedef signed char yytype_int8;
+#endif
+
+#ifdef YYTYPE_UINT16
+typedef YYTYPE_UINT16 yytype_uint16;
+#else
+typedef unsigned short int yytype_uint16;
+#endif
+
+#ifdef YYTYPE_INT16
+typedef YYTYPE_INT16 yytype_int16;
+#else
+typedef short int yytype_int16;
+#endif
+
+#ifndef YYSIZE_T
+# ifdef __SIZE_TYPE__
+# define YYSIZE_T __SIZE_TYPE__
+# elif defined size_t
+# define YYSIZE_T size_t
+# elif ! defined YYSIZE_T
+# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+# define YYSIZE_T size_t
+# else
+# define YYSIZE_T unsigned int
+# endif
+#endif
+
+#define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
+
+#ifndef YY_
+# if defined YYENABLE_NLS && YYENABLE_NLS
+# if ENABLE_NLS
+# include <libintl.h> /* INFRINGES ON USER NAME SPACE */
+# define YY_(Msgid) dgettext ("bison-runtime", Msgid)
+# endif
+# endif
+# ifndef YY_
+# define YY_(Msgid) Msgid
+# endif
+#endif
+
+#ifndef YY_ATTRIBUTE
+# if (defined __GNUC__ \
+ && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__))) \
+ || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C
+# define YY_ATTRIBUTE(Spec) __attribute__(Spec)
+# else
+# define YY_ATTRIBUTE(Spec) /* empty */
+# endif
+#endif
+
+#ifndef YY_ATTRIBUTE_PURE
+# define YY_ATTRIBUTE_PURE YY_ATTRIBUTE ((__pure__))
+#endif
+
+#ifndef YY_ATTRIBUTE_UNUSED
+# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__))
+#endif
+
+#if !defined _Noreturn \
+ && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112)
+# if defined _MSC_VER && 1200 <= _MSC_VER
+# define _Noreturn __declspec (noreturn)
+# else
+# define _Noreturn YY_ATTRIBUTE ((__noreturn__))
+# endif
+#endif
+
+/* Suppress unused-variable warnings by "using" E. */
+#if ! defined lint || defined __GNUC__
+# define YYUSE(E) ((void) (E))
+#else
+# define YYUSE(E) /* empty */
+#endif
+
+#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
+/* Suppress an incorrect diagnostic about yylval being uninitialized. */
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
+ _Pragma ("GCC diagnostic push") \
+ _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\
+ _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
+# define YY_IGNORE_MAYBE_UNINITIALIZED_END \
+ _Pragma ("GCC diagnostic pop")
+#else
+# define YY_INITIAL_VALUE(Value) Value
+#endif
+#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+# define YY_IGNORE_MAYBE_UNINITIALIZED_END
+#endif
+#ifndef YY_INITIAL_VALUE
+# define YY_INITIAL_VALUE(Value) /* Nothing. */
+#endif
+
+
+#if ! defined yyoverflow || YYERROR_VERBOSE
+
+/* The parser invokes alloca or malloc; define the necessary symbols. */
+
+# ifdef YYSTACK_USE_ALLOCA
+# if YYSTACK_USE_ALLOCA
+# ifdef __GNUC__
+# define YYSTACK_ALLOC __builtin_alloca
+# elif defined __BUILTIN_VA_ARG_INCR
+# include <alloca.h> /* INFRINGES ON USER NAME SPACE */
+# elif defined _AIX
+# define YYSTACK_ALLOC __alloca
+# elif defined _MSC_VER
+# include <malloc.h> /* INFRINGES ON USER NAME SPACE */
+# define alloca _alloca
+# else
+# define YYSTACK_ALLOC alloca
+# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS
+# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+ /* Use EXIT_SUCCESS as a witness for stdlib.h. */
+# ifndef EXIT_SUCCESS
+# define EXIT_SUCCESS 0
+# endif
+# endif
+# endif
+# endif
+# endif
+
+# ifdef YYSTACK_ALLOC
+ /* Pacify GCC's 'empty if-body' warning. */
+# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
+# ifndef YYSTACK_ALLOC_MAXIMUM
+ /* The OS might guarantee only one guard page at the bottom of the stack,
+ and a page size can be as small as 4096 bytes. So we cannot safely
+ invoke alloca (N) if N exceeds 4096. Use a slightly smaller number
+ to allow for a few compiler-allocated temporary stack slots. */
+# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
+# endif
+# else
+# define YYSTACK_ALLOC YYMALLOC
+# define YYSTACK_FREE YYFREE
+# ifndef YYSTACK_ALLOC_MAXIMUM
+# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
+# endif
+# if (defined __cplusplus && ! defined EXIT_SUCCESS \
+ && ! ((defined YYMALLOC || defined malloc) \
+ && (defined YYFREE || defined free)))
+# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+# ifndef EXIT_SUCCESS
+# define EXIT_SUCCESS 0
+# endif
+# endif
+# ifndef YYMALLOC
+# define YYMALLOC malloc
+# if ! defined malloc && ! defined EXIT_SUCCESS
+void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
+# endif
+# endif
+# ifndef YYFREE
+# define YYFREE free
+# if ! defined free && ! defined EXIT_SUCCESS
+void free (void *); /* INFRINGES ON USER NAME SPACE */
+# endif
+# endif
+# endif
+#endif /* ! defined yyoverflow || YYERROR_VERBOSE */
+
+
+#if (! defined yyoverflow \
+ && (! defined __cplusplus \
+ || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \
+ && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
+
+/* A type that is properly aligned for any stack member. */
+union yyalloc
+{
+ yytype_int16 yyss_alloc;
+ YYSTYPE yyvs_alloc;
+ YYLTYPE yyls_alloc;
+};
+
+/* The size of the maximum gap between one aligned stack and the next. */
+# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
+
+/* The size of an array large to enough to hold all stacks, each with
+ N elements. */
+# define YYSTACK_BYTES(N) \
+ ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \
+ + 2 * YYSTACK_GAP_MAXIMUM)
+
+# define YYCOPY_NEEDED 1
+
+/* Relocate STACK from its old location to the new one. The
+ local variables YYSIZE and YYSTACKSIZE give the old and new number of
+ elements in the stack, and YYPTR gives the new location of the
+ stack. Advance YYPTR to a properly aligned location for the next
+ stack. */
+# define YYSTACK_RELOCATE(Stack_alloc, Stack) \
+ do \
+ { \
+ YYSIZE_T yynewbytes; \
+ YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \
+ Stack = &yyptr->Stack_alloc; \
+ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
+ yyptr += yynewbytes / sizeof (*yyptr); \
+ } \
+ while (0)
+
+#endif
+
+#if defined YYCOPY_NEEDED && YYCOPY_NEEDED
+/* Copy COUNT objects from SRC to DST. The source and destination do
+ not overlap. */
+# ifndef YYCOPY
+# if defined __GNUC__ && 1 < __GNUC__
+# define YYCOPY(Dst, Src, Count) \
+ __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src)))
+# else
+# define YYCOPY(Dst, Src, Count) \
+ do \
+ { \
+ YYSIZE_T yyi; \
+ for (yyi = 0; yyi < (Count); yyi++) \
+ (Dst)[yyi] = (Src)[yyi]; \
+ } \
+ while (0)
+# endif
+# endif
+#endif /* !YYCOPY_NEEDED */
+
+/* YYFINAL -- State number of the termination state. */
+#define YYFINAL 6
+/* YYLAST -- Last index in YYTABLE. */
+#define YYLAST 138
+
+/* YYNTOKENS -- Number of terminals. */
+#define YYNTOKENS 48
+/* YYNNTS -- Number of nonterminals. */
+#define YYNNTS 30
+/* YYNRULES -- Number of rules. */
+#define YYNRULES 84
+/* YYNSTATES -- Number of states. */
+#define YYNSTATES 149
+
+/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned
+ by yylex, with out-of-bounds checking. */
+#define YYUNDEFTOK 2
+#define YYMAXUTOK 279
+
+#define YYTRANSLATE(YYX) \
+ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
+
+/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM
+ as returned by yylex, without out-of-bounds checking. */
+static const yytype_uint8 yytranslate[] =
+{
+ 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 47, 2, 2, 2, 45, 41, 2,
+ 33, 35, 44, 42, 34, 43, 2, 26, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 38, 25,
+ 36, 29, 30, 37, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 31, 2, 32, 40, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 27, 39, 28, 46, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
+ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24
+};
+
+#if YYDEBUG
+ /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
+static const yytype_uint16 yyrline[] =
+{
+ 0, 109, 109, 117, 121, 128, 129, 139, 142, 149,
+ 153, 161, 165, 170, 181, 191, 206, 214, 217, 224,
+ 228, 232, 236, 244, 248, 252, 256, 260, 276, 286,
+ 294, 297, 301, 308, 324, 329, 348, 362, 369, 370,
+ 371, 378, 382, 383, 387, 388, 392, 393, 397, 398,
+ 402, 403, 407, 408, 412, 413, 414, 418, 419, 420,
+ 421, 422, 426, 427, 428, 432, 433, 434, 438, 439,
+ 448, 457, 461, 462, 463, 464, 469, 472, 476, 484,
+ 487, 491, 499, 503, 507
+};
+#endif
+
+#if YYDEBUG || YYERROR_VERBOSE || 0
+/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+ First, the terminals, then, starting at YYNTOKENS, nonterminals. */
+static const char *const yytname[] =
+{
+ "$end", "error", "$undefined", "DT_V1", "DT_PLUGIN", "DT_MEMRESERVE",
+ "DT_LSHIFT", "DT_RSHIFT", "DT_LE", "DT_GE", "DT_EQ", "DT_NE", "DT_AND",
+ "DT_OR", "DT_BITS", "DT_DEL_PROP", "DT_DEL_NODE", "DT_PROPNODENAME",
+ "DT_LITERAL", "DT_CHAR_LITERAL", "DT_BYTE", "DT_STRING", "DT_LABEL",
+ "DT_REF", "DT_INCBIN", "';'", "'/'", "'{'", "'}'", "'='", "'>'", "'['",
+ "']'", "'('", "','", "')'", "'<'", "'?'", "':'", "'|'", "'^'", "'&'",
+ "'+'", "'-'", "'*'", "'%'", "'~'", "'!'", "$accept", "sourcefile",
+ "header", "headers", "memreserves", "memreserve", "devicetree",
+ "nodedef", "proplist", "propdef", "propdata", "propdataprefix",
+ "arrayprefix", "integer_prim", "integer_expr", "integer_trinary",
+ "integer_or", "integer_and", "integer_bitor", "integer_bitxor",
+ "integer_bitand", "integer_eq", "integer_rela", "integer_shift",
+ "integer_add", "integer_mul", "integer_unary", "bytestring", "subnodes",
+ "subnode", YY_NULLPTR
+};
+#endif
+
+# ifdef YYPRINT
+/* YYTOKNUM[NUM] -- (External) token number corresponding to the
+ (internal) symbol number NUM (which must be that of a token). */
+static const yytype_uint16 yytoknum[] =
+{
+ 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
+ 265, 266, 267, 268, 269, 270, 271, 272, 273, 274,
+ 275, 276, 277, 278, 279, 59, 47, 123, 125, 61,
+ 62, 91, 93, 40, 44, 41, 60, 63, 58, 124,
+ 94, 38, 43, 45, 42, 37, 126, 33
+};
+# endif
+
+#define YYPACT_NINF -44
+
+#define yypact_value_is_default(Yystate) \
+ (!!((Yystate) == (-44)))
+
+#define YYTABLE_NINF -1
+
+#define yytable_value_is_error(Yytable_value) \
+ 0
+
+ /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+ STATE-NUM. */
+static const yytype_int8 yypact[] =
+{
+ 14, 27, 61, 14, 8, 18, -44, -44, 37, 8,
+ 40, 8, 64, -44, -44, -12, 37, -44, 50, 52,
+ -44, -44, -12, -12, -12, -44, 51, -44, -4, 78,
+ 53, 54, 55, 17, 2, 30, 38, -3, -44, 66,
+ -44, -44, 70, 72, 50, 50, -44, -44, -44, -44,
+ -12, -12, -12, -12, -12, -12, -12, -12, -12, -12,
+ -12, -12, -12, -12, -12, -12, -12, -12, -12, -44,
+ 3, 73, 50, -44, -44, 78, 59, 53, 54, 55,
+ 17, 2, 2, 30, 30, 30, 30, 38, 38, -3,
+ -3, -44, -44, -44, 82, 83, 44, 3, -44, 74,
+ 3, -44, -44, -12, 76, 79, -44, -44, -44, -44,
+ -44, 80, -44, -44, -44, -44, -44, -10, 36, -44,
+ -44, -44, -44, 85, -44, -44, -44, 75, -44, -44,
+ 21, 71, 88, -6, -44, -44, -44, -44, -44, 11,
+ -44, -44, -44, 37, -44, 77, 37, 81, -44
+};
+
+ /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
+ Performed when YYTABLE does not specify something else to do. Zero
+ means the default is an error. */
+static const yytype_uint8 yydefact[] =
+{
+ 0, 0, 0, 5, 7, 3, 1, 6, 0, 0,
+ 0, 7, 0, 38, 39, 0, 0, 10, 0, 2,
+ 8, 4, 0, 0, 0, 72, 0, 41, 42, 44,
+ 46, 48, 50, 52, 54, 57, 64, 67, 71, 0,
+ 17, 11, 0, 0, 0, 0, 73, 74, 75, 40,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 9,
+ 79, 0, 0, 14, 12, 45, 0, 47, 49, 51,
+ 53, 55, 56, 60, 61, 59, 58, 62, 63, 65,
+ 66, 69, 68, 70, 0, 0, 0, 0, 18, 0,
+ 79, 15, 13, 0, 0, 0, 20, 30, 82, 22,
+ 84, 0, 81, 80, 43, 21, 83, 0, 0, 16,
+ 29, 19, 31, 0, 23, 32, 26, 0, 76, 34,
+ 0, 0, 0, 0, 37, 36, 24, 35, 33, 0,
+ 77, 78, 25, 0, 28, 0, 0, 0, 27
+};
+
+ /* YYPGOTO[NTERM-NUM]. */
+static const yytype_int8 yypgoto[] =
+{
+ -44, -44, -44, 103, 99, 104, -44, -43, -44, -21,
+ -44, -44, -44, -8, 63, 9, -44, 65, 67, 68,
+ 69, 62, 26, 4, 22, 23, -19, -44, 20, 28
+};
+
+ /* YYDEFGOTO[NTERM-NUM]. */
+static const yytype_int16 yydefgoto[] =
+{
+ -1, 2, 3, 4, 10, 11, 19, 41, 70, 98,
+ 117, 118, 130, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 35, 36, 37, 38, 133, 99, 100
+};
+
+ /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If
+ positive, shift that token. If negative, reduce the rule whose
+ number is the opposite. If YYTABLE_NINF, syntax error. */
+static const yytype_uint8 yytable[] =
+{
+ 16, 73, 74, 46, 47, 48, 13, 14, 39, 50,
+ 58, 59, 120, 8, 140, 121, 141, 1, 94, 95,
+ 96, 15, 12, 66, 122, 97, 142, 56, 57, 102,
+ 9, 22, 60, 51, 23, 24, 62, 63, 61, 13,
+ 14, 67, 68, 134, 135, 143, 144, 91, 92, 93,
+ 123, 136, 5, 108, 15, 13, 14, 124, 125, 126,
+ 127, 6, 83, 84, 85, 86, 18, 128, 42, 106,
+ 15, 40, 129, 107, 43, 44, 109, 40, 45, 112,
+ 64, 65, 81, 82, 87, 88, 49, 89, 90, 21,
+ 52, 69, 53, 71, 54, 72, 55, 103, 101, 104,
+ 105, 115, 111, 131, 116, 119, 7, 138, 132, 139,
+ 20, 146, 114, 17, 76, 75, 148, 80, 0, 77,
+ 113, 78, 137, 79, 0, 110, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 145, 0, 0, 147
+};
+
+static const yytype_int16 yycheck[] =
+{
+ 8, 44, 45, 22, 23, 24, 18, 19, 16, 13,
+ 8, 9, 22, 5, 20, 25, 22, 3, 15, 16,
+ 17, 33, 4, 26, 34, 22, 32, 10, 11, 72,
+ 22, 43, 30, 37, 46, 47, 6, 7, 36, 18,
+ 19, 44, 45, 22, 23, 34, 35, 66, 67, 68,
+ 14, 30, 25, 96, 33, 18, 19, 21, 22, 23,
+ 24, 0, 58, 59, 60, 61, 26, 31, 16, 25,
+ 33, 27, 36, 29, 22, 23, 97, 27, 26, 100,
+ 42, 43, 56, 57, 62, 63, 35, 64, 65, 25,
+ 12, 25, 39, 23, 40, 23, 41, 38, 25, 17,
+ 17, 25, 28, 18, 25, 25, 3, 36, 33, 21,
+ 11, 34, 103, 9, 51, 50, 35, 55, -1, 52,
+ 100, 53, 130, 54, -1, 97, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 143, -1, -1, 146
+};
+
+ /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+ symbol of state STATE-NUM. */
+static const yytype_uint8 yystos[] =
+{
+ 0, 3, 49, 50, 51, 25, 0, 51, 5, 22,
+ 52, 53, 4, 18, 19, 33, 61, 53, 26, 54,
+ 52, 25, 43, 46, 47, 61, 62, 63, 64, 65,
+ 66, 67, 68, 69, 70, 71, 72, 73, 74, 61,
+ 27, 55, 16, 22, 23, 26, 74, 74, 74, 35,
+ 13, 37, 12, 39, 40, 41, 10, 11, 8, 9,
+ 30, 36, 6, 7, 42, 43, 26, 44, 45, 25,
+ 56, 23, 23, 55, 55, 65, 62, 66, 67, 68,
+ 69, 70, 70, 71, 71, 71, 71, 72, 72, 73,
+ 73, 74, 74, 74, 15, 16, 17, 22, 57, 76,
+ 77, 25, 55, 38, 17, 17, 25, 29, 55, 57,
+ 77, 28, 57, 76, 63, 25, 25, 58, 59, 25,
+ 22, 25, 34, 14, 21, 22, 23, 24, 31, 36,
+ 60, 18, 33, 75, 22, 23, 30, 61, 36, 21,
+ 20, 22, 32, 34, 35, 61, 34, 61, 35
+};
+
+ /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
+static const yytype_uint8 yyr1[] =
+{
+ 0, 48, 49, 50, 50, 51, 51, 52, 52, 53,
+ 53, 54, 54, 54, 54, 54, 55, 56, 56, 57,
+ 57, 57, 57, 58, 58, 58, 58, 58, 58, 58,
+ 59, 59, 59, 60, 60, 60, 60, 60, 61, 61,
+ 61, 62, 63, 63, 64, 64, 65, 65, 66, 66,
+ 67, 67, 68, 68, 69, 69, 69, 70, 70, 70,
+ 70, 70, 71, 71, 71, 72, 72, 72, 73, 73,
+ 73, 73, 74, 74, 74, 74, 75, 75, 75, 76,
+ 76, 76, 77, 77, 77
+};
+
+ /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */
+static const yytype_uint8 yyr2[] =
+{
+ 0, 2, 3, 2, 4, 1, 2, 0, 2, 4,
+ 2, 2, 3, 4, 3, 4, 5, 0, 2, 4,
+ 2, 3, 2, 2, 3, 4, 2, 9, 5, 2,
+ 0, 2, 2, 3, 1, 2, 2, 2, 1, 1,
+ 3, 1, 1, 5, 1, 3, 1, 3, 1, 3,
+ 1, 3, 1, 3, 1, 3, 3, 1, 3, 3,
+ 3, 3, 3, 3, 1, 3, 3, 1, 3, 3,
+ 3, 1, 1, 2, 2, 2, 0, 2, 2, 0,
+ 2, 2, 2, 3, 2
+};
+
+
+#define yyerrok (yyerrstatus = 0)
+#define yyclearin (yychar = YYEMPTY)
+#define YYEMPTY (-2)
+#define YYEOF 0
+
+#define YYACCEPT goto yyacceptlab
+#define YYABORT goto yyabortlab
+#define YYERROR goto yyerrorlab
+
+
+#define YYRECOVERING() (!!yyerrstatus)
+
+#define YYBACKUP(Token, Value) \
+do \
+ if (yychar == YYEMPTY) \
+ { \
+ yychar = (Token); \
+ yylval = (Value); \
+ YYPOPSTACK (yylen); \
+ yystate = *yyssp; \
+ goto yybackup; \
+ } \
+ else \
+ { \
+ yyerror (YY_("syntax error: cannot back up")); \
+ YYERROR; \
+ } \
+while (0)
+
+/* Error token number */
+#define YYTERROR 1
+#define YYERRCODE 256
+
+
+/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
+ If N is 0, then set CURRENT to the empty location which ends
+ the previous symbol: RHS[0] (always defined). */
+
+#ifndef YYLLOC_DEFAULT
+# define YYLLOC_DEFAULT(Current, Rhs, N) \
+ do \
+ if (N) \
+ { \
+ (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \
+ (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \
+ (Current).last_line = YYRHSLOC (Rhs, N).last_line; \
+ (Current).last_column = YYRHSLOC (Rhs, N).last_column; \
+ } \
+ else \
+ { \
+ (Current).first_line = (Current).last_line = \
+ YYRHSLOC (Rhs, 0).last_line; \
+ (Current).first_column = (Current).last_column = \
+ YYRHSLOC (Rhs, 0).last_column; \
+ } \
+ while (0)
+#endif
+
+#define YYRHSLOC(Rhs, K) ((Rhs)[K])
+
+
+/* Enable debugging if requested. */
+#if YYDEBUG
+
+# ifndef YYFPRINTF
+# include <stdio.h> /* INFRINGES ON USER NAME SPACE */
+# define YYFPRINTF fprintf
+# endif
+
+# define YYDPRINTF(Args) \
+do { \
+ if (yydebug) \
+ YYFPRINTF Args; \
+} while (0)
+
+
+/* YY_LOCATION_PRINT -- Print the location on the stream.
+ This macro was not mandated originally: define only if we know
+ we won't break user code: when these are the locations we know. */
+
+#ifndef YY_LOCATION_PRINT
+# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL
+
+/* Print *YYLOCP on YYO. Private, do not rely on its existence. */
+
+YY_ATTRIBUTE_UNUSED
+static unsigned
+yy_location_print_ (FILE *yyo, YYLTYPE const * const yylocp)
+{
+ unsigned res = 0;
+ int end_col = 0 != yylocp->last_column ? yylocp->last_column - 1 : 0;
+ if (0 <= yylocp->first_line)
+ {
+ res += YYFPRINTF (yyo, "%d", yylocp->first_line);
+ if (0 <= yylocp->first_column)
+ res += YYFPRINTF (yyo, ".%d", yylocp->first_column);
+ }
+ if (0 <= yylocp->last_line)
+ {
+ if (yylocp->first_line < yylocp->last_line)
+ {
+ res += YYFPRINTF (yyo, "-%d", yylocp->last_line);
+ if (0 <= end_col)
+ res += YYFPRINTF (yyo, ".%d", end_col);
+ }
+ else if (0 <= end_col && yylocp->first_column < end_col)
+ res += YYFPRINTF (yyo, "-%d", end_col);
+ }
+ return res;
+ }
+
+# define YY_LOCATION_PRINT(File, Loc) \
+ yy_location_print_ (File, &(Loc))
+
+# else
+# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+# endif
+#endif
+
+
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
+do { \
+ if (yydebug) \
+ { \
+ YYFPRINTF (stderr, "%s ", Title); \
+ yy_symbol_print (stderr, \
+ Type, Value, Location); \
+ YYFPRINTF (stderr, "\n"); \
+ } \
+} while (0)
+
+
+/*----------------------------------------.
+| Print this symbol's value on YYOUTPUT. |
+`----------------------------------------*/
+
+static void
+yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp)
+{
+ FILE *yyo = yyoutput;
+ YYUSE (yyo);
+ YYUSE (yylocationp);
+ if (!yyvaluep)
+ return;
+# ifdef YYPRINT
+ if (yytype < YYNTOKENS)
+ YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+# endif
+ YYUSE (yytype);
+}
+
+
+/*--------------------------------.
+| Print this symbol on YYOUTPUT. |
+`--------------------------------*/
+
+static void
+yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp)
+{
+ YYFPRINTF (yyoutput, "%s %s (",
+ yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]);
+
+ YY_LOCATION_PRINT (yyoutput, *yylocationp);
+ YYFPRINTF (yyoutput, ": ");
+ yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp);
+ YYFPRINTF (yyoutput, ")");
+}
+
+/*------------------------------------------------------------------.
+| yy_stack_print -- Print the state stack from its BOTTOM up to its |
+| TOP (included). |
+`------------------------------------------------------------------*/
+
+static void
+yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)
+{
+ YYFPRINTF (stderr, "Stack now");
+ for (; yybottom <= yytop; yybottom++)
+ {
+ int yybot = *yybottom;
+ YYFPRINTF (stderr, " %d", yybot);
+ }
+ YYFPRINTF (stderr, "\n");
+}
+
+# define YY_STACK_PRINT(Bottom, Top) \
+do { \
+ if (yydebug) \
+ yy_stack_print ((Bottom), (Top)); \
+} while (0)
+
+
+/*------------------------------------------------.
+| Report that the YYRULE is going to be reduced. |
+`------------------------------------------------*/
+
+static void
+yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule)
+{
+ unsigned long int yylno = yyrline[yyrule];
+ int yynrhs = yyr2[yyrule];
+ int yyi;
+ YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
+ yyrule - 1, yylno);
+ /* The symbols being reduced. */
+ for (yyi = 0; yyi < yynrhs; yyi++)
+ {
+ YYFPRINTF (stderr, " $%d = ", yyi + 1);
+ yy_symbol_print (stderr,
+ yystos[yyssp[yyi + 1 - yynrhs]],
+ &(yyvsp[(yyi + 1) - (yynrhs)])
+ , &(yylsp[(yyi + 1) - (yynrhs)]) );
+ YYFPRINTF (stderr, "\n");
+ }
+}
+
+# define YY_REDUCE_PRINT(Rule) \
+do { \
+ if (yydebug) \
+ yy_reduce_print (yyssp, yyvsp, yylsp, Rule); \
+} while (0)
+
+/* Nonzero means print parse trace. It is left uninitialized so that
+ multiple parsers can coexist. */
+int yydebug;
+#else /* !YYDEBUG */
+# define YYDPRINTF(Args)
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
+# define YY_STACK_PRINT(Bottom, Top)
+# define YY_REDUCE_PRINT(Rule)
+#endif /* !YYDEBUG */
+
+
+/* YYINITDEPTH -- initial size of the parser's stacks. */
+#ifndef YYINITDEPTH
+# define YYINITDEPTH 200
+#endif
+
+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
+ if the built-in stack extension method is used).
+
+ Do not make this value too large; the results are undefined if
+ YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
+ evaluated with infinite-precision integer arithmetic. */
+
+#ifndef YYMAXDEPTH
+# define YYMAXDEPTH 10000
+#endif
+
+
+#if YYERROR_VERBOSE
+
+# ifndef yystrlen
+# if defined __GLIBC__ && defined _STRING_H
+# define yystrlen strlen
+# else
+/* Return the length of YYSTR. */
+static YYSIZE_T
+yystrlen (const char *yystr)
+{
+ YYSIZE_T yylen;
+ for (yylen = 0; yystr[yylen]; yylen++)
+ continue;
+ return yylen;
+}
+# endif
+# endif
+
+# ifndef yystpcpy
+# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
+# define yystpcpy stpcpy
+# else
+/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
+ YYDEST. */
+static char *
+yystpcpy (char *yydest, const char *yysrc)
+{
+ char *yyd = yydest;
+ const char *yys = yysrc;
+
+ while ((*yyd++ = *yys++) != '\0')
+ continue;
+
+ return yyd - 1;
+}
+# endif
+# endif
+
+# ifndef yytnamerr
+/* Copy to YYRES the contents of YYSTR after stripping away unnecessary
+ quotes and backslashes, so that it's suitable for yyerror. The
+ heuristic is that double-quoting is unnecessary unless the string
+ contains an apostrophe, a comma, or backslash (other than
+ backslash-backslash). YYSTR is taken from yytname. If YYRES is
+ null, do not copy; instead, return the length of what the result
+ would have been. */
+static YYSIZE_T
+yytnamerr (char *yyres, const char *yystr)
+{
+ if (*yystr == '"')
+ {
+ YYSIZE_T yyn = 0;
+ char const *yyp = yystr;
+
+ for (;;)
+ switch (*++yyp)
+ {
+ case '\'':
+ case ',':
+ goto do_not_strip_quotes;
+
+ case '\\':
+ if (*++yyp != '\\')
+ goto do_not_strip_quotes;
+ /* Fall through. */
+ default:
+ if (yyres)
+ yyres[yyn] = *yyp;
+ yyn++;
+ break;
+
+ case '"':
+ if (yyres)
+ yyres[yyn] = '\0';
+ return yyn;
+ }
+ do_not_strip_quotes: ;
+ }
+
+ if (! yyres)
+ return yystrlen (yystr);
+
+ return yystpcpy (yyres, yystr) - yyres;
+}
+# endif
+
+/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message
+ about the unexpected token YYTOKEN for the state stack whose top is
+ YYSSP.
+
+ Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is
+ not large enough to hold the message. In that case, also set
+ *YYMSG_ALLOC to the required number of bytes. Return 2 if the
+ required number of bytes is too large to store. */
+static int
+yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
+ yytype_int16 *yyssp, int yytoken)
+{
+ YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]);
+ YYSIZE_T yysize = yysize0;
+ enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
+ /* Internationalized format string. */
+ const char *yyformat = YY_NULLPTR;
+ /* Arguments of yyformat. */
+ char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
+ /* Number of reported tokens (one for the "unexpected", one per
+ "expected"). */
+ int yycount = 0;
+
+ /* There are many possibilities here to consider:
+ - If this state is a consistent state with a default action, then
+ the only way this function was invoked is if the default action
+ is an error action. In that case, don't check for expected
+ tokens because there are none.
+ - The only way there can be no lookahead present (in yychar) is if
+ this state is a consistent state with a default action. Thus,
+ detecting the absence of a lookahead is sufficient to determine
+ that there is no unexpected or expected token to report. In that
+ case, just report a simple "syntax error".
+ - Don't assume there isn't a lookahead just because this state is a
+ consistent state with a default action. There might have been a
+ previous inconsistent state, consistent state with a non-default
+ action, or user semantic action that manipulated yychar.
+ - Of course, the expected token list depends on states to have
+ correct lookahead information, and it depends on the parser not
+ to perform extra reductions after fetching a lookahead from the
+ scanner and before detecting a syntax error. Thus, state merging
+ (from LALR or IELR) and default reductions corrupt the expected
+ token list. However, the list is correct for canonical LR with
+ one exception: it will still contain any token that will not be
+ accepted due to an error action in a later state.
+ */
+ if (yytoken != YYEMPTY)
+ {
+ int yyn = yypact[*yyssp];
+ yyarg[yycount++] = yytname[yytoken];
+ if (!yypact_value_is_default (yyn))
+ {
+ /* Start YYX at -YYN if negative to avoid negative indexes in
+ YYCHECK. In other words, skip the first -YYN actions for
+ this state because they are default actions. */
+ int yyxbegin = yyn < 0 ? -yyn : 0;
+ /* Stay within bounds of both yycheck and yytname. */
+ int yychecklim = YYLAST - yyn + 1;
+ int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+ int yyx;
+
+ for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR
+ && !yytable_value_is_error (yytable[yyx + yyn]))
+ {
+ if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+ {
+ yycount = 1;
+ yysize = yysize0;
+ break;
+ }
+ yyarg[yycount++] = yytname[yyx];
+ {
+ YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]);
+ if (! (yysize <= yysize1
+ && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+ return 2;
+ yysize = yysize1;
+ }
+ }
+ }
+ }
+
+ switch (yycount)
+ {
+# define YYCASE_(N, S) \
+ case N: \
+ yyformat = S; \
+ break
+ YYCASE_(0, YY_("syntax error"));
+ YYCASE_(1, YY_("syntax error, unexpected %s"));
+ YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
+ YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s"));
+ YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s"));
+ YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"));
+# undef YYCASE_
+ }
+
+ {
+ YYSIZE_T yysize1 = yysize + yystrlen (yyformat);
+ if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+ return 2;
+ yysize = yysize1;
+ }
+
+ if (*yymsg_alloc < yysize)
+ {
+ *yymsg_alloc = 2 * yysize;
+ if (! (yysize <= *yymsg_alloc
+ && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM))
+ *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM;
+ return 1;
+ }
+
+ /* Avoid sprintf, as that infringes on the user's name space.
+ Don't have undefined behavior even if the translation
+ produced a string with the wrong number of "%s"s. */
+ {
+ char *yyp = *yymsg;
+ int yyi = 0;
+ while ((*yyp = *yyformat) != '\0')
+ if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount)
+ {
+ yyp += yytnamerr (yyp, yyarg[yyi++]);
+ yyformat += 2;
+ }
+ else
+ {
+ yyp++;
+ yyformat++;
+ }
+ }
+ return 0;
+}
+#endif /* YYERROR_VERBOSE */
+
+/*-----------------------------------------------.
+| Release the memory associated to this symbol. |
+`-----------------------------------------------*/
+
+static void
+yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp)
+{
+ YYUSE (yyvaluep);
+ YYUSE (yylocationp);
+ if (!yymsg)
+ yymsg = "Deleting";
+ YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
+
+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+ YYUSE (yytype);
+ YY_IGNORE_MAYBE_UNINITIALIZED_END
+}
+
+
+
+
+/* The lookahead symbol. */
+int yychar;
+
+/* The semantic value of the lookahead symbol. */
+YYSTYPE yylval;
+/* Location data for the lookahead symbol. */
+YYLTYPE yylloc
+# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL
+ = { 1, 1, 1, 1 }
+# endif
+;
+/* Number of syntax errors so far. */
+int yynerrs;
+
+
+/*----------.
+| yyparse. |
+`----------*/
+
+int
+yyparse (void)
+{
+ int yystate;
+ /* Number of tokens to shift before error messages enabled. */
+ int yyerrstatus;
+
+ /* The stacks and their tools:
+ 'yyss': related to states.
+ 'yyvs': related to semantic values.
+ 'yyls': related to locations.
+
+ Refer to the stacks through separate pointers, to allow yyoverflow
+ to reallocate them elsewhere. */
+
+ /* The state stack. */
+ yytype_int16 yyssa[YYINITDEPTH];
+ yytype_int16 *yyss;
+ yytype_int16 *yyssp;
+
+ /* The semantic value stack. */
+ YYSTYPE yyvsa[YYINITDEPTH];
+ YYSTYPE *yyvs;
+ YYSTYPE *yyvsp;
+
+ /* The location stack. */
+ YYLTYPE yylsa[YYINITDEPTH];
+ YYLTYPE *yyls;
+ YYLTYPE *yylsp;
+
+ /* The locations where the error started and ended. */
+ YYLTYPE yyerror_range[3];
+
+ YYSIZE_T yystacksize;
+
+ int yyn;
+ int yyresult;
+ /* Lookahead token as an internal (translated) token number. */
+ int yytoken = 0;
+ /* The variables used to return semantic value and location from the
+ action routines. */
+ YYSTYPE yyval;
+ YYLTYPE yyloc;
+
+#if YYERROR_VERBOSE
+ /* Buffer for error messages, and its allocated size. */
+ char yymsgbuf[128];
+ char *yymsg = yymsgbuf;
+ YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
+#endif
+
+#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N), yylsp -= (N))
+
+ /* The number of symbols on the RHS of the reduced rule.
+ Keep to zero when no symbol should be popped. */
+ int yylen = 0;
+
+ yyssp = yyss = yyssa;
+ yyvsp = yyvs = yyvsa;
+ yylsp = yyls = yylsa;
+ yystacksize = YYINITDEPTH;
+
+ YYDPRINTF ((stderr, "Starting parse\n"));
+
+ yystate = 0;
+ yyerrstatus = 0;
+ yynerrs = 0;
+ yychar = YYEMPTY; /* Cause a token to be read. */
+ yylsp[0] = yylloc;
+ goto yysetstate;
+
+/*------------------------------------------------------------.
+| yynewstate -- Push a new state, which is found in yystate. |
+`------------------------------------------------------------*/
+ yynewstate:
+ /* In all cases, when you get here, the value and location stacks
+ have just been pushed. So pushing a state here evens the stacks. */
+ yyssp++;
+
+ yysetstate:
+ *yyssp = yystate;
+
+ if (yyss + yystacksize - 1 <= yyssp)
+ {
+ /* Get the current used size of the three stacks, in elements. */
+ YYSIZE_T yysize = yyssp - yyss + 1;
+
+#ifdef yyoverflow
+ {
+ /* Give user a chance to reallocate the stack. Use copies of
+ these so that the &'s don't force the real ones into
+ memory. */
+ YYSTYPE *yyvs1 = yyvs;
+ yytype_int16 *yyss1 = yyss;
+ YYLTYPE *yyls1 = yyls;
+
+ /* Each stack pointer address is followed by the size of the
+ data in use in that stack, in bytes. This used to be a
+ conditional around just the two extra args, but that might
+ be undefined if yyoverflow is a macro. */
+ yyoverflow (YY_("memory exhausted"),
+ &yyss1, yysize * sizeof (*yyssp),
+ &yyvs1, yysize * sizeof (*yyvsp),
+ &yyls1, yysize * sizeof (*yylsp),
+ &yystacksize);
+
+ yyls = yyls1;
+ yyss = yyss1;
+ yyvs = yyvs1;
+ }
+#else /* no yyoverflow */
+# ifndef YYSTACK_RELOCATE
+ goto yyexhaustedlab;
+# else
+ /* Extend the stack our own way. */
+ if (YYMAXDEPTH <= yystacksize)
+ goto yyexhaustedlab;
+ yystacksize *= 2;
+ if (YYMAXDEPTH < yystacksize)
+ yystacksize = YYMAXDEPTH;
+
+ {
+ yytype_int16 *yyss1 = yyss;
+ union yyalloc *yyptr =
+ (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
+ if (! yyptr)
+ goto yyexhaustedlab;
+ YYSTACK_RELOCATE (yyss_alloc, yyss);
+ YYSTACK_RELOCATE (yyvs_alloc, yyvs);
+ YYSTACK_RELOCATE (yyls_alloc, yyls);
+# undef YYSTACK_RELOCATE
+ if (yyss1 != yyssa)
+ YYSTACK_FREE (yyss1);
+ }
+# endif
+#endif /* no yyoverflow */
+
+ yyssp = yyss + yysize - 1;
+ yyvsp = yyvs + yysize - 1;
+ yylsp = yyls + yysize - 1;
+
+ YYDPRINTF ((stderr, "Stack size increased to %lu\n",
+ (unsigned long int) yystacksize));
+
+ if (yyss + yystacksize - 1 <= yyssp)
+ YYABORT;
+ }
+
+ YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+
+ if (yystate == YYFINAL)
+ YYACCEPT;
+
+ goto yybackup;
+
+/*-----------.
+| yybackup. |
+`-----------*/
+yybackup:
+
+ /* Do appropriate processing given the current state. Read a
+ lookahead token if we need one and don't already have one. */
+
+ /* First try to decide what to do without reference to lookahead token. */
+ yyn = yypact[yystate];
+ if (yypact_value_is_default (yyn))
+ goto yydefault;
+
+ /* Not known => get a lookahead token if don't already have one. */
+
+ /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */
+ if (yychar == YYEMPTY)
+ {
+ YYDPRINTF ((stderr, "Reading a token: "));
+ yychar = yylex ();
+ }
+
+ if (yychar <= YYEOF)
+ {
+ yychar = yytoken = YYEOF;
+ YYDPRINTF ((stderr, "Now at end of input.\n"));
+ }
+ else
+ {
+ yytoken = YYTRANSLATE (yychar);
+ YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
+ }
+
+ /* If the proper action on seeing token YYTOKEN is to reduce or to
+ detect an error, take that action. */
+ yyn += yytoken;
+ if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
+ goto yydefault;
+ yyn = yytable[yyn];
+ if (yyn <= 0)
+ {
+ if (yytable_value_is_error (yyn))
+ goto yyerrlab;
+ yyn = -yyn;
+ goto yyreduce;
+ }
+
+ /* Count tokens shifted since error; after three, turn off error
+ status. */
+ if (yyerrstatus)
+ yyerrstatus--;
+
+ /* Shift the lookahead token. */
+ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
+
+ /* Discard the shifted token. */
+ yychar = YYEMPTY;
+
+ yystate = yyn;
+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+ *++yyvsp = yylval;
+ YY_IGNORE_MAYBE_UNINITIALIZED_END
+ *++yylsp = yylloc;
+ goto yynewstate;
+
+
+/*-----------------------------------------------------------.
+| yydefault -- do the default action for the current state. |
+`-----------------------------------------------------------*/
+yydefault:
+ yyn = yydefact[yystate];
+ if (yyn == 0)
+ goto yyerrlab;
+ goto yyreduce;
+
+
+/*-----------------------------.
+| yyreduce -- Do a reduction. |
+`-----------------------------*/
+yyreduce:
+ /* yyn is the number of a rule to reduce with. */
+ yylen = yyr2[yyn];
+
+ /* If YYLEN is nonzero, implement the default value of the action:
+ '$$ = $1'.
+
+ Otherwise, the following line sets YYVAL to garbage.
+ This behavior is undocumented and Bison
+ users should not rely upon it. Assigning to YYVAL
+ unconditionally makes the parser a bit smaller, and it avoids a
+ GCC warning that YYVAL may be used uninitialized. */
+ yyval = yyvsp[1-yylen];
+
+ /* Default location. */
+ YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen);
+ YY_REDUCE_PRINT (yyn);
+ switch (yyn)
+ {
+ case 2:
+#line 110 "dtc-parser.y" /* yacc.c:1646 */
+ {
+ parser_output = build_dt_info((yyvsp[-2].flags), (yyvsp[-1].re), (yyvsp[0].node),
+ guess_boot_cpuid((yyvsp[0].node)));
+ }
+#line 1476 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 3:
+#line 118 "dtc-parser.y" /* yacc.c:1646 */
+ {
+ (yyval.flags) = DTSF_V1;
+ }
+#line 1484 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 4:
+#line 122 "dtc-parser.y" /* yacc.c:1646 */
+ {
+ (yyval.flags) = DTSF_V1 | DTSF_PLUGIN;
+ }
+#line 1492 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 6:
+#line 130 "dtc-parser.y" /* yacc.c:1646 */
+ {
+ if ((yyvsp[0].flags) != (yyvsp[-1].flags))
+ ERROR(&(yylsp[0]), "Header flags don't match earlier ones");
+ (yyval.flags) = (yyvsp[-1].flags);
+ }
+#line 1502 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 7:
+#line 139 "dtc-parser.y" /* yacc.c:1646 */
+ {
+ (yyval.re) = NULL;
+ }
+#line 1510 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 8:
+#line 143 "dtc-parser.y" /* yacc.c:1646 */
+ {
+ (yyval.re) = chain_reserve_entry((yyvsp[-1].re), (yyvsp[0].re));
+ }
+#line 1518 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 9:
+#line 150 "dtc-parser.y" /* yacc.c:1646 */
+ {
+ (yyval.re) = build_reserve_entry((yyvsp[-2].integer), (yyvsp[-1].integer));
+ }
+#line 1526 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 10:
+#line 154 "dtc-parser.y" /* yacc.c:1646 */
+ {
+ add_label(&(yyvsp[0].re)->labels, (yyvsp[-1].labelref));
+ (yyval.re) = (yyvsp[0].re);
+ }
+#line 1535 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 11:
+#line 162 "dtc-parser.y" /* yacc.c:1646 */
+ {
+ (yyval.node) = name_node((yyvsp[0].node), "");
+ }
+#line 1543 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 12:
+#line 166 "dtc-parser.y" /* yacc.c:1646 */
+ {
+ (yyval.node) = merge_nodes((yyvsp[-2].node), (yyvsp[0].node));
+ }
+#line 1551 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 13:
+#line 171 "dtc-parser.y" /* yacc.c:1646 */
+ {
+ struct node *target = get_node_by_ref((yyvsp[-3].node), (yyvsp[-1].labelref));
+
+ if (target) {
+ add_label(&target->labels, (yyvsp[-2].labelref));
+ merge_nodes(target, (yyvsp[0].node));
+ } else
+ ERROR(&(yylsp[-1]), "Label or path %s not found", (yyvsp[-1].labelref));
+ (yyval.node) = (yyvsp[-3].node);
+ }
+#line 1566 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 14:
+#line 182 "dtc-parser.y" /* yacc.c:1646 */
+ {
+ struct node *target = get_node_by_ref((yyvsp[-2].node), (yyvsp[-1].labelref));
+
+ if (target)
+ merge_nodes(target, (yyvsp[0].node));
+ else
+ ERROR(&(yylsp[-1]), "Label or path %s not found", (yyvsp[-1].labelref));
+ (yyval.node) = (yyvsp[-2].node);
+ }
+#line 1580 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 15:
+#line 192 "dtc-parser.y" /* yacc.c:1646 */
+ {
+ struct node *target = get_node_by_ref((yyvsp[-3].node), (yyvsp[-1].labelref));
+
+ if (target)
+ delete_node(target);
+ else
+ ERROR(&(yylsp[-1]), "Label or path %s not found", (yyvsp[-1].labelref));
+
+
+ (yyval.node) = (yyvsp[-3].node);
+ }
+#line 1596 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 16:
+#line 207 "dtc-parser.y" /* yacc.c:1646 */
+ {
+ (yyval.node) = build_node((yyvsp[-3].proplist), (yyvsp[-2].nodelist));
+ }
+#line 1604 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 17:
+#line 214 "dtc-parser.y" /* yacc.c:1646 */
+ {
+ (yyval.proplist) = NULL;
+ }
+#line 1612 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 18:
+#line 218 "dtc-parser.y" /* yacc.c:1646 */
+ {
+ (yyval.proplist) = chain_property((yyvsp[0].prop), (yyvsp[-1].proplist));
+ }
+#line 1620 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 19:
+#line 225 "dtc-parser.y" /* yacc.c:1646 */
+ {
+ (yyval.prop) = build_property((yyvsp[-3].propnodename), (yyvsp[-1].data));
+ }
+#line 1628 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 20:
+#line 229 "dtc-parser.y" /* yacc.c:1646 */
+ {
+ (yyval.prop) = build_property((yyvsp[-1].propnodename), empty_data);
+ }
+#line 1636 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 21:
+#line 233 "dtc-parser.y" /* yacc.c:1646 */
+ {
+ (yyval.prop) = build_property_delete((yyvsp[-1].propnodename));
+ }
+#line 1644 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 22:
+#line 237 "dtc-parser.y" /* yacc.c:1646 */
+ {
+ add_label(&(yyvsp[0].prop)->labels, (yyvsp[-1].labelref));
+ (yyval.prop) = (yyvsp[0].prop);
+ }
+#line 1653 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 23:
+#line 245 "dtc-parser.y" /* yacc.c:1646 */
+ {
+ (yyval.data) = data_merge((yyvsp[-1].data), (yyvsp[0].data));
+ }
+#line 1661 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 24:
+#line 249 "dtc-parser.y" /* yacc.c:1646 */
+ {
+ (yyval.data) = data_merge((yyvsp[-2].data), (yyvsp[-1].array).data);
+ }
+#line 1669 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 25:
+#line 253 "dtc-parser.y" /* yacc.c:1646 */
+ {
+ (yyval.data) = data_merge((yyvsp[-3].data), (yyvsp[-1].data));
+ }
+#line 1677 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 26:
+#line 257 "dtc-parser.y" /* yacc.c:1646 */
+ {
+ (yyval.data) = data_add_marker((yyvsp[-1].data), REF_PATH, (yyvsp[0].labelref));
+ }
+#line 1685 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 27:
+#line 261 "dtc-parser.y" /* yacc.c:1646 */
+ {
+ FILE *f = srcfile_relative_open((yyvsp[-5].data).val, NULL);
+ struct data d;
+
+ if ((yyvsp[-3].integer) != 0)
+ if (fseek(f, (yyvsp[-3].integer), SEEK_SET) != 0)
+ die("Couldn't seek to offset %llu in \"%s\": %s",
+ (unsigned long long)(yyvsp[-3].integer), (yyvsp[-5].data).val,
+ strerror(errno));
+
+ d = data_copy_file(f, (yyvsp[-1].integer));
+
+ (yyval.data) = data_merge((yyvsp[-8].data), d);
+ fclose(f);
+ }
+#line 1705 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 28:
+#line 277 "dtc-parser.y" /* yacc.c:1646 */
+ {
+ FILE *f = srcfile_relative_open((yyvsp[-1].data).val, NULL);
+ struct data d = empty_data;
+
+ d = data_copy_file(f, -1);
+
+ (yyval.data) = data_merge((yyvsp[-4].data), d);
+ fclose(f);
+ }
+#line 1719 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 29:
+#line 287 "dtc-parser.y" /* yacc.c:1646 */
+ {
+ (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref));
+ }
+#line 1727 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 30:
+#line 294 "dtc-parser.y" /* yacc.c:1646 */
+ {
+ (yyval.data) = empty_data;
+ }
+#line 1735 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 31:
+#line 298 "dtc-parser.y" /* yacc.c:1646 */
+ {
+ (yyval.data) = (yyvsp[-1].data);
+ }
+#line 1743 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 32:
+#line 302 "dtc-parser.y" /* yacc.c:1646 */
+ {
+ (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref));
+ }
+#line 1751 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 33:
+#line 309 "dtc-parser.y" /* yacc.c:1646 */
+ {
+ unsigned long long bits;
+
+ bits = (yyvsp[-1].integer);
+
+ if ((bits != 8) && (bits != 16) &&
+ (bits != 32) && (bits != 64)) {
+ ERROR(&(yylsp[-1]), "Array elements must be"
+ " 8, 16, 32 or 64-bits");
+ bits = 32;
+ }
+
+ (yyval.array).data = empty_data;
+ (yyval.array).bits = bits;
+ }
+#line 1771 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 34:
+#line 325 "dtc-parser.y" /* yacc.c:1646 */
+ {
+ (yyval.array).data = empty_data;
+ (yyval.array).bits = 32;
+ }
+#line 1780 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 35:
+#line 330 "dtc-parser.y" /* yacc.c:1646 */
+ {
+ if ((yyvsp[-1].array).bits < 64) {
+ uint64_t mask = (1ULL << (yyvsp[-1].array).bits) - 1;
+ /*
+ * Bits above mask must either be all zero
+ * (positive within range of mask) or all one
+ * (negative and sign-extended). The second
+ * condition is true if when we set all bits
+ * within the mask to one (i.e. | in the
+ * mask), all bits are one.
+ */
+ if (((yyvsp[0].integer) > mask) && (((yyvsp[0].integer) | mask) != -1ULL))
+ ERROR(&(yylsp[0]), "Value out of range for"
+ " %d-bit array element", (yyvsp[-1].array).bits);
+ }
+
+ (yyval.array).data = data_append_integer((yyvsp[-1].array).data, (yyvsp[0].integer), (yyvsp[-1].array).bits);
+ }
+#line 1803 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 36:
+#line 349 "dtc-parser.y" /* yacc.c:1646 */
+ {
+ uint64_t val = ~0ULL >> (64 - (yyvsp[-1].array).bits);
+
+ if ((yyvsp[-1].array).bits == 32)
+ (yyvsp[-1].array).data = data_add_marker((yyvsp[-1].array).data,
+ REF_PHANDLE,
+ (yyvsp[0].labelref));
+ else
+ ERROR(&(yylsp[0]), "References are only allowed in "
+ "arrays with 32-bit elements.");
+
+ (yyval.array).data = data_append_integer((yyvsp[-1].array).data, val, (yyvsp[-1].array).bits);
+ }
+#line 1821 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 37:
+#line 363 "dtc-parser.y" /* yacc.c:1646 */
+ {
+ (yyval.array).data = data_add_marker((yyvsp[-1].array).data, LABEL, (yyvsp[0].labelref));
+ }
+#line 1829 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 40:
+#line 372 "dtc-parser.y" /* yacc.c:1646 */
+ {
+ (yyval.integer) = (yyvsp[-1].integer);
+ }
+#line 1837 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 43:
+#line 383 "dtc-parser.y" /* yacc.c:1646 */
+ { (yyval.integer) = (yyvsp[-4].integer) ? (yyvsp[-2].integer) : (yyvsp[0].integer); }
+#line 1843 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 45:
+#line 388 "dtc-parser.y" /* yacc.c:1646 */
+ { (yyval.integer) = (yyvsp[-2].integer) || (yyvsp[0].integer); }
+#line 1849 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 47:
+#line 393 "dtc-parser.y" /* yacc.c:1646 */
+ { (yyval.integer) = (yyvsp[-2].integer) && (yyvsp[0].integer); }
+#line 1855 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 49:
+#line 398 "dtc-parser.y" /* yacc.c:1646 */
+ { (yyval.integer) = (yyvsp[-2].integer) | (yyvsp[0].integer); }
+#line 1861 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 51:
+#line 403 "dtc-parser.y" /* yacc.c:1646 */
+ { (yyval.integer) = (yyvsp[-2].integer) ^ (yyvsp[0].integer); }
+#line 1867 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 53:
+#line 408 "dtc-parser.y" /* yacc.c:1646 */
+ { (yyval.integer) = (yyvsp[-2].integer) & (yyvsp[0].integer); }
+#line 1873 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 55:
+#line 413 "dtc-parser.y" /* yacc.c:1646 */
+ { (yyval.integer) = (yyvsp[-2].integer) == (yyvsp[0].integer); }
+#line 1879 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 56:
+#line 414 "dtc-parser.y" /* yacc.c:1646 */
+ { (yyval.integer) = (yyvsp[-2].integer) != (yyvsp[0].integer); }
+#line 1885 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 58:
+#line 419 "dtc-parser.y" /* yacc.c:1646 */
+ { (yyval.integer) = (yyvsp[-2].integer) < (yyvsp[0].integer); }
+#line 1891 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 59:
+#line 420 "dtc-parser.y" /* yacc.c:1646 */
+ { (yyval.integer) = (yyvsp[-2].integer) > (yyvsp[0].integer); }
+#line 1897 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 60:
+#line 421 "dtc-parser.y" /* yacc.c:1646 */
+ { (yyval.integer) = (yyvsp[-2].integer) <= (yyvsp[0].integer); }
+#line 1903 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 61:
+#line 422 "dtc-parser.y" /* yacc.c:1646 */
+ { (yyval.integer) = (yyvsp[-2].integer) >= (yyvsp[0].integer); }
+#line 1909 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 62:
+#line 426 "dtc-parser.y" /* yacc.c:1646 */
+ { (yyval.integer) = (yyvsp[-2].integer) << (yyvsp[0].integer); }
+#line 1915 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 63:
+#line 427 "dtc-parser.y" /* yacc.c:1646 */
+ { (yyval.integer) = (yyvsp[-2].integer) >> (yyvsp[0].integer); }
+#line 1921 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 65:
+#line 432 "dtc-parser.y" /* yacc.c:1646 */
+ { (yyval.integer) = (yyvsp[-2].integer) + (yyvsp[0].integer); }
+#line 1927 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 66:
+#line 433 "dtc-parser.y" /* yacc.c:1646 */
+ { (yyval.integer) = (yyvsp[-2].integer) - (yyvsp[0].integer); }
+#line 1933 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 68:
+#line 438 "dtc-parser.y" /* yacc.c:1646 */
+ { (yyval.integer) = (yyvsp[-2].integer) * (yyvsp[0].integer); }
+#line 1939 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 69:
+#line 440 "dtc-parser.y" /* yacc.c:1646 */
+ {
+ if ((yyvsp[0].integer) != 0) {
+ (yyval.integer) = (yyvsp[-2].integer) / (yyvsp[0].integer);
+ } else {
+ ERROR(&(yyloc), "Division by zero");
+ (yyval.integer) = 0;
+ }
+ }
+#line 1952 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 70:
+#line 449 "dtc-parser.y" /* yacc.c:1646 */
+ {
+ if ((yyvsp[0].integer) != 0) {
+ (yyval.integer) = (yyvsp[-2].integer) % (yyvsp[0].integer);
+ } else {
+ ERROR(&(yyloc), "Division by zero");
+ (yyval.integer) = 0;
+ }
+ }
+#line 1965 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 73:
+#line 462 "dtc-parser.y" /* yacc.c:1646 */
+ { (yyval.integer) = -(yyvsp[0].integer); }
+#line 1971 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 74:
+#line 463 "dtc-parser.y" /* yacc.c:1646 */
+ { (yyval.integer) = ~(yyvsp[0].integer); }
+#line 1977 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 75:
+#line 464 "dtc-parser.y" /* yacc.c:1646 */
+ { (yyval.integer) = !(yyvsp[0].integer); }
+#line 1983 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 76:
+#line 469 "dtc-parser.y" /* yacc.c:1646 */
+ {
+ (yyval.data) = empty_data;
+ }
+#line 1991 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 77:
+#line 473 "dtc-parser.y" /* yacc.c:1646 */
+ {
+ (yyval.data) = data_append_byte((yyvsp[-1].data), (yyvsp[0].byte));
+ }
+#line 1999 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 78:
+#line 477 "dtc-parser.y" /* yacc.c:1646 */
+ {
+ (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref));
+ }
+#line 2007 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 79:
+#line 484 "dtc-parser.y" /* yacc.c:1646 */
+ {
+ (yyval.nodelist) = NULL;
+ }
+#line 2015 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 80:
+#line 488 "dtc-parser.y" /* yacc.c:1646 */
+ {
+ (yyval.nodelist) = chain_node((yyvsp[-1].node), (yyvsp[0].nodelist));
+ }
+#line 2023 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 81:
+#line 492 "dtc-parser.y" /* yacc.c:1646 */
+ {
+ ERROR(&(yylsp[0]), "Properties must precede subnodes");
+ YYERROR;
+ }
+#line 2032 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 82:
+#line 500 "dtc-parser.y" /* yacc.c:1646 */
+ {
+ (yyval.node) = name_node((yyvsp[0].node), (yyvsp[-1].propnodename));
+ }
+#line 2040 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 83:
+#line 504 "dtc-parser.y" /* yacc.c:1646 */
+ {
+ (yyval.node) = name_node(build_node_delete(), (yyvsp[-1].propnodename));
+ }
+#line 2048 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 84:
+#line 508 "dtc-parser.y" /* yacc.c:1646 */
+ {
+ add_label(&(yyvsp[0].node)->labels, (yyvsp[-1].labelref));
+ (yyval.node) = (yyvsp[0].node);
+ }
+#line 2057 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+
+#line 2061 "dtc-parser.tab.c" /* yacc.c:1646 */
+ default: break;
+ }
+ /* User semantic actions sometimes alter yychar, and that requires
+ that yytoken be updated with the new translation. We take the
+ approach of translating immediately before every use of yytoken.
+ One alternative is translating here after every semantic action,
+ but that translation would be missed if the semantic action invokes
+ YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or
+ if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an
+ incorrect destructor might then be invoked immediately. In the
+ case of YYERROR or YYBACKUP, subsequent parser actions might lead
+ to an incorrect destructor call or verbose syntax error message
+ before the lookahead is translated. */
+ YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
+
+ YYPOPSTACK (yylen);
+ yylen = 0;
+ YY_STACK_PRINT (yyss, yyssp);
+
+ *++yyvsp = yyval;
+ *++yylsp = yyloc;
+
+ /* Now 'shift' the result of the reduction. Determine what state
+ that goes to, based on the state we popped back to and the rule
+ number reduced by. */
+
+ yyn = yyr1[yyn];
+
+ yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
+ if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+ yystate = yytable[yystate];
+ else
+ yystate = yydefgoto[yyn - YYNTOKENS];
+
+ goto yynewstate;
+
+
+/*--------------------------------------.
+| yyerrlab -- here on detecting error. |
+`--------------------------------------*/
+yyerrlab:
+ /* Make sure we have latest lookahead translation. See comments at
+ user semantic actions for why this is necessary. */
+ yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar);
+
+ /* If not already recovering from an error, report this error. */
+ if (!yyerrstatus)
+ {
+ ++yynerrs;
+#if ! YYERROR_VERBOSE
+ yyerror (YY_("syntax error"));
+#else
+# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \
+ yyssp, yytoken)
+ {
+ char const *yymsgp = YY_("syntax error");
+ int yysyntax_error_status;
+ yysyntax_error_status = YYSYNTAX_ERROR;
+ if (yysyntax_error_status == 0)
+ yymsgp = yymsg;
+ else if (yysyntax_error_status == 1)
+ {
+ if (yymsg != yymsgbuf)
+ YYSTACK_FREE (yymsg);
+ yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc);
+ if (!yymsg)
+ {
+ yymsg = yymsgbuf;
+ yymsg_alloc = sizeof yymsgbuf;
+ yysyntax_error_status = 2;
+ }
+ else
+ {
+ yysyntax_error_status = YYSYNTAX_ERROR;
+ yymsgp = yymsg;
+ }
+ }
+ yyerror (yymsgp);
+ if (yysyntax_error_status == 2)
+ goto yyexhaustedlab;
+ }
+# undef YYSYNTAX_ERROR
+#endif
+ }
+
+ yyerror_range[1] = yylloc;
+
+ if (yyerrstatus == 3)
+ {
+ /* If just tried and failed to reuse lookahead token after an
+ error, discard it. */
+
+ if (yychar <= YYEOF)
+ {
+ /* Return failure if at end of input. */
+ if (yychar == YYEOF)
+ YYABORT;
+ }
+ else
+ {
+ yydestruct ("Error: discarding",
+ yytoken, &yylval, &yylloc);
+ yychar = YYEMPTY;
+ }
+ }
+
+ /* Else will try to reuse lookahead token after shifting the error
+ token. */
+ goto yyerrlab1;
+
+
+/*---------------------------------------------------.
+| yyerrorlab -- error raised explicitly by YYERROR. |
+`---------------------------------------------------*/
+yyerrorlab:
+
+ /* Pacify compilers like GCC when the user code never invokes
+ YYERROR and the label yyerrorlab therefore never appears in user
+ code. */
+ if (/*CONSTCOND*/ 0)
+ goto yyerrorlab;
+
+ yyerror_range[1] = yylsp[1-yylen];
+ /* Do not reclaim the symbols of the rule whose action triggered
+ this YYERROR. */
+ YYPOPSTACK (yylen);
+ yylen = 0;
+ YY_STACK_PRINT (yyss, yyssp);
+ yystate = *yyssp;
+ goto yyerrlab1;
+
+
+/*-------------------------------------------------------------.
+| yyerrlab1 -- common code for both syntax error and YYERROR. |
+`-------------------------------------------------------------*/
+yyerrlab1:
+ yyerrstatus = 3; /* Each real token shifted decrements this. */
+
+ for (;;)
+ {
+ yyn = yypact[yystate];
+ if (!yypact_value_is_default (yyn))
+ {
+ yyn += YYTERROR;
+ if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
+ {
+ yyn = yytable[yyn];
+ if (0 < yyn)
+ break;
+ }
+ }
+
+ /* Pop the current state because it cannot handle the error token. */
+ if (yyssp == yyss)
+ YYABORT;
+
+ yyerror_range[1] = *yylsp;
+ yydestruct ("Error: popping",
+ yystos[yystate], yyvsp, yylsp);
+ YYPOPSTACK (1);
+ yystate = *yyssp;
+ YY_STACK_PRINT (yyss, yyssp);
+ }
+
+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+ *++yyvsp = yylval;
+ YY_IGNORE_MAYBE_UNINITIALIZED_END
+
+ yyerror_range[2] = yylloc;
+ /* Using YYLLOC is tempting, but would change the location of
+ the lookahead. YYLOC is available though. */
+ YYLLOC_DEFAULT (yyloc, yyerror_range, 2);
+ *++yylsp = yyloc;
+
+ /* Shift the error token. */
+ YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
+
+ yystate = yyn;
+ goto yynewstate;
+
+
+/*-------------------------------------.
+| yyacceptlab -- YYACCEPT comes here. |
+`-------------------------------------*/
+yyacceptlab:
+ yyresult = 0;
+ goto yyreturn;
+
+/*-----------------------------------.
+| yyabortlab -- YYABORT comes here. |
+`-----------------------------------*/
+yyabortlab:
+ yyresult = 1;
+ goto yyreturn;
+
+#if !defined yyoverflow || YYERROR_VERBOSE
+/*-------------------------------------------------.
+| yyexhaustedlab -- memory exhaustion comes here. |
+`-------------------------------------------------*/
+yyexhaustedlab:
+ yyerror (YY_("memory exhausted"));
+ yyresult = 2;
+ /* Fall through. */
+#endif
+
+yyreturn:
+ if (yychar != YYEMPTY)
+ {
+ /* Make sure we have latest lookahead translation. See comments at
+ user semantic actions for why this is necessary. */
+ yytoken = YYTRANSLATE (yychar);
+ yydestruct ("Cleanup: discarding lookahead",
+ yytoken, &yylval, &yylloc);
+ }
+ /* Do not reclaim the symbols of the rule whose action triggered
+ this YYABORT or YYACCEPT. */
+ YYPOPSTACK (yylen);
+ YY_STACK_PRINT (yyss, yyssp);
+ while (yyssp != yyss)
+ {
+ yydestruct ("Cleanup: popping",
+ yystos[*yyssp], yyvsp, yylsp);
+ YYPOPSTACK (1);
+ }
+#ifndef yyoverflow
+ if (yyss != yyssa)
+ YYSTACK_FREE (yyss);
+#endif
+#if YYERROR_VERBOSE
+ if (yymsg != yymsgbuf)
+ YYSTACK_FREE (yymsg);
+#endif
+ return yyresult;
+}
+#line 514 "dtc-parser.y" /* yacc.c:1906 */
+
+
+void yyerror(char const *s)
+{
+ ERROR(&yylloc, "%s", s);
+}
diff --git a/scripts/dtc/dtc-parser.tab.h_shipped b/scripts/dtc/dtc-parser.tab.h_shipped
new file mode 100644
index 0000000000..e7b04dd016
--- /dev/null
+++ b/scripts/dtc/dtc-parser.tab.h_shipped
@@ -0,0 +1,123 @@
+/* A Bison parser, made by GNU Bison 3.0.2. */
+
+/* Bison interface for Yacc-like parsers in C
+
+ Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* As a special exception, you may create a larger work that contains
+ part or all of the Bison parser skeleton and distribute that work
+ under terms of your choice, so long as that work isn't itself a
+ parser generator using the skeleton or a modified version thereof
+ as a parser skeleton. Alternatively, if you modify or redistribute
+ the parser skeleton itself, you may (at your option) remove this
+ special exception, which will cause the skeleton and the resulting
+ Bison output files to be licensed under the GNU General Public
+ License without this special exception.
+
+ This special exception was added by the Free Software Foundation in
+ version 2.2 of Bison. */
+
+#ifndef YY_YY_DTC_PARSER_TAB_H_INCLUDED
+# define YY_YY_DTC_PARSER_TAB_H_INCLUDED
+/* Debug traces. */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+#if YYDEBUG
+extern int yydebug;
+#endif
+
+/* Token type. */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+ enum yytokentype
+ {
+ DT_V1 = 258,
+ DT_PLUGIN = 259,
+ DT_MEMRESERVE = 260,
+ DT_LSHIFT = 261,
+ DT_RSHIFT = 262,
+ DT_LE = 263,
+ DT_GE = 264,
+ DT_EQ = 265,
+ DT_NE = 266,
+ DT_AND = 267,
+ DT_OR = 268,
+ DT_BITS = 269,
+ DT_DEL_PROP = 270,
+ DT_DEL_NODE = 271,
+ DT_PROPNODENAME = 272,
+ DT_LITERAL = 273,
+ DT_CHAR_LITERAL = 274,
+ DT_BYTE = 275,
+ DT_STRING = 276,
+ DT_LABEL = 277,
+ DT_REF = 278,
+ DT_INCBIN = 279
+ };
+#endif
+
+/* Value type. */
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+typedef union YYSTYPE YYSTYPE;
+union YYSTYPE
+{
+#line 39 "dtc-parser.y" /* yacc.c:1909 */
+
+ char *propnodename;
+ char *labelref;
+ uint8_t byte;
+ struct data data;
+
+ struct {
+ struct data data;
+ int bits;
+ } array;
+
+ struct property *prop;
+ struct property *proplist;
+ struct node *node;
+ struct node *nodelist;
+ struct reserve_info *re;
+ uint64_t integer;
+ unsigned int flags;
+
+#line 99 "dtc-parser.tab.h" /* yacc.c:1909 */
+};
+# define YYSTYPE_IS_TRIVIAL 1
+# define YYSTYPE_IS_DECLARED 1
+#endif
+
+/* Location type. */
+#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
+typedef struct YYLTYPE YYLTYPE;
+struct YYLTYPE
+{
+ int first_line;
+ int first_column;
+ int last_line;
+ int last_column;
+};
+# define YYLTYPE_IS_DECLARED 1
+# define YYLTYPE_IS_TRIVIAL 1
+#endif
+
+
+extern YYSTYPE yylval;
+extern YYLTYPE yylloc;
+int yyparse (void);
+
+#endif /* !YY_YY_DTC_PARSER_TAB_H_INCLUDED */
diff --git a/scripts/dtc/dtc-parser.y b/scripts/dtc/dtc-parser.y
new file mode 100644
index 0000000000..ca3f500342
--- /dev/null
+++ b/scripts/dtc/dtc-parser.y
@@ -0,0 +1,519 @@
+/*
+ * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2005.
+ *
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ */
+%{
+#include <stdio.h>
+#include <inttypes.h>
+
+#include "dtc.h"
+#include "srcpos.h"
+
+extern int yylex(void);
+extern void yyerror(char const *s);
+#define ERROR(loc, ...) \
+ do { \
+ srcpos_error((loc), "Error", __VA_ARGS__); \
+ treesource_error = true; \
+ } while (0)
+
+extern struct dt_info *parser_output;
+extern bool treesource_error;
+%}
+
+%union {
+ char *propnodename;
+ char *labelref;
+ uint8_t byte;
+ struct data data;
+
+ struct {
+ struct data data;
+ int bits;
+ } array;
+
+ struct property *prop;
+ struct property *proplist;
+ struct node *node;
+ struct node *nodelist;
+ struct reserve_info *re;
+ uint64_t integer;
+ unsigned int flags;
+}
+
+%token DT_V1
+%token DT_PLUGIN
+%token DT_MEMRESERVE
+%token DT_LSHIFT DT_RSHIFT DT_LE DT_GE DT_EQ DT_NE DT_AND DT_OR
+%token DT_BITS
+%token DT_DEL_PROP
+%token DT_DEL_NODE
+%token <propnodename> DT_PROPNODENAME
+%token <integer> DT_LITERAL
+%token <integer> DT_CHAR_LITERAL
+%token <byte> DT_BYTE
+%token <data> DT_STRING
+%token <labelref> DT_LABEL
+%token <labelref> DT_REF
+%token DT_INCBIN
+
+%type <data> propdata
+%type <data> propdataprefix
+%type <flags> header
+%type <flags> headers
+%type <re> memreserve
+%type <re> memreserves
+%type <array> arrayprefix
+%type <data> bytestring
+%type <prop> propdef
+%type <proplist> proplist
+
+%type <node> devicetree
+%type <node> nodedef
+%type <node> subnode
+%type <nodelist> subnodes
+
+%type <integer> integer_prim
+%type <integer> integer_unary
+%type <integer> integer_mul
+%type <integer> integer_add
+%type <integer> integer_shift
+%type <integer> integer_rela
+%type <integer> integer_eq
+%type <integer> integer_bitand
+%type <integer> integer_bitxor
+%type <integer> integer_bitor
+%type <integer> integer_and
+%type <integer> integer_or
+%type <integer> integer_trinary
+%type <integer> integer_expr
+
+%%
+
+sourcefile:
+ headers memreserves devicetree
+ {
+ parser_output = build_dt_info($1, $2, $3,
+ guess_boot_cpuid($3));
+ }
+ ;
+
+header:
+ DT_V1 ';'
+ {
+ $$ = DTSF_V1;
+ }
+ | DT_V1 ';' DT_PLUGIN ';'
+ {
+ $$ = DTSF_V1 | DTSF_PLUGIN;
+ }
+ ;
+
+headers:
+ header
+ | header headers
+ {
+ if ($2 != $1)
+ ERROR(&@2, "Header flags don't match earlier ones");
+ $$ = $1;
+ }
+ ;
+
+memreserves:
+ /* empty */
+ {
+ $$ = NULL;
+ }
+ | memreserve memreserves
+ {
+ $$ = chain_reserve_entry($1, $2);
+ }
+ ;
+
+memreserve:
+ DT_MEMRESERVE integer_prim integer_prim ';'
+ {
+ $$ = build_reserve_entry($2, $3);
+ }
+ | DT_LABEL memreserve
+ {
+ add_label(&$2->labels, $1);
+ $$ = $2;
+ }
+ ;
+
+devicetree:
+ '/' nodedef
+ {
+ $$ = name_node($2, "");
+ }
+ | devicetree '/' nodedef
+ {
+ $$ = merge_nodes($1, $3);
+ }
+
+ | devicetree DT_LABEL DT_REF nodedef
+ {
+ struct node *target = get_node_by_ref($1, $3);
+
+ if (target) {
+ add_label(&target->labels, $2);
+ merge_nodes(target, $4);
+ } else
+ ERROR(&@3, "Label or path %s not found", $3);
+ $$ = $1;
+ }
+ | devicetree DT_REF nodedef
+ {
+ struct node *target = get_node_by_ref($1, $2);
+
+ if (target)
+ merge_nodes(target, $3);
+ else
+ ERROR(&@2, "Label or path %s not found", $2);
+ $$ = $1;
+ }
+ | devicetree DT_DEL_NODE DT_REF ';'
+ {
+ struct node *target = get_node_by_ref($1, $3);
+
+ if (target)
+ delete_node(target);
+ else
+ ERROR(&@3, "Label or path %s not found", $3);
+
+
+ $$ = $1;
+ }
+ ;
+
+nodedef:
+ '{' proplist subnodes '}' ';'
+ {
+ $$ = build_node($2, $3);
+ }
+ ;
+
+proplist:
+ /* empty */
+ {
+ $$ = NULL;
+ }
+ | proplist propdef
+ {
+ $$ = chain_property($2, $1);
+ }
+ ;
+
+propdef:
+ DT_PROPNODENAME '=' propdata ';'
+ {
+ $$ = build_property($1, $3);
+ }
+ | DT_PROPNODENAME ';'
+ {
+ $$ = build_property($1, empty_data);
+ }
+ | DT_DEL_PROP DT_PROPNODENAME ';'
+ {
+ $$ = build_property_delete($2);
+ }
+ | DT_LABEL propdef
+ {
+ add_label(&$2->labels, $1);
+ $$ = $2;
+ }
+ ;
+
+propdata:
+ propdataprefix DT_STRING
+ {
+ $$ = data_merge($1, $2);
+ }
+ | propdataprefix arrayprefix '>'
+ {
+ $$ = data_merge($1, $2.data);
+ }
+ | propdataprefix '[' bytestring ']'
+ {
+ $$ = data_merge($1, $3);
+ }
+ | propdataprefix DT_REF
+ {
+ $$ = data_add_marker($1, REF_PATH, $2);
+ }
+ | propdataprefix DT_INCBIN '(' DT_STRING ',' integer_prim ',' integer_prim ')'
+ {
+ FILE *f = srcfile_relative_open($4.val, NULL);
+ struct data d;
+
+ if ($6 != 0)
+ if (fseek(f, $6, SEEK_SET) != 0)
+ die("Couldn't seek to offset %llu in \"%s\": %s",
+ (unsigned long long)$6, $4.val,
+ strerror(errno));
+
+ d = data_copy_file(f, $8);
+
+ $$ = data_merge($1, d);
+ fclose(f);
+ }
+ | propdataprefix DT_INCBIN '(' DT_STRING ')'
+ {
+ FILE *f = srcfile_relative_open($4.val, NULL);
+ struct data d = empty_data;
+
+ d = data_copy_file(f, -1);
+
+ $$ = data_merge($1, d);
+ fclose(f);
+ }
+ | propdata DT_LABEL
+ {
+ $$ = data_add_marker($1, LABEL, $2);
+ }
+ ;
+
+propdataprefix:
+ /* empty */
+ {
+ $$ = empty_data;
+ }
+ | propdata ','
+ {
+ $$ = $1;
+ }
+ | propdataprefix DT_LABEL
+ {
+ $$ = data_add_marker($1, LABEL, $2);
+ }
+ ;
+
+arrayprefix:
+ DT_BITS DT_LITERAL '<'
+ {
+ unsigned long long bits;
+
+ bits = $2;
+
+ if ((bits != 8) && (bits != 16) &&
+ (bits != 32) && (bits != 64)) {
+ ERROR(&@2, "Array elements must be"
+ " 8, 16, 32 or 64-bits");
+ bits = 32;
+ }
+
+ $$.data = empty_data;
+ $$.bits = bits;
+ }
+ | '<'
+ {
+ $$.data = empty_data;
+ $$.bits = 32;
+ }
+ | arrayprefix integer_prim
+ {
+ if ($1.bits < 64) {
+ uint64_t mask = (1ULL << $1.bits) - 1;
+ /*
+ * Bits above mask must either be all zero
+ * (positive within range of mask) or all one
+ * (negative and sign-extended). The second
+ * condition is true if when we set all bits
+ * within the mask to one (i.e. | in the
+ * mask), all bits are one.
+ */
+ if (($2 > mask) && (($2 | mask) != -1ULL))
+ ERROR(&@2, "Value out of range for"
+ " %d-bit array element", $1.bits);
+ }
+
+ $$.data = data_append_integer($1.data, $2, $1.bits);
+ }
+ | arrayprefix DT_REF
+ {
+ uint64_t val = ~0ULL >> (64 - $1.bits);
+
+ if ($1.bits == 32)
+ $1.data = data_add_marker($1.data,
+ REF_PHANDLE,
+ $2);
+ else
+ ERROR(&@2, "References are only allowed in "
+ "arrays with 32-bit elements.");
+
+ $$.data = data_append_integer($1.data, val, $1.bits);
+ }
+ | arrayprefix DT_LABEL
+ {
+ $$.data = data_add_marker($1.data, LABEL, $2);
+ }
+ ;
+
+integer_prim:
+ DT_LITERAL
+ | DT_CHAR_LITERAL
+ | '(' integer_expr ')'
+ {
+ $$ = $2;
+ }
+ ;
+
+integer_expr:
+ integer_trinary
+ ;
+
+integer_trinary:
+ integer_or
+ | integer_or '?' integer_expr ':' integer_trinary { $$ = $1 ? $3 : $5; }
+ ;
+
+integer_or:
+ integer_and
+ | integer_or DT_OR integer_and { $$ = $1 || $3; }
+ ;
+
+integer_and:
+ integer_bitor
+ | integer_and DT_AND integer_bitor { $$ = $1 && $3; }
+ ;
+
+integer_bitor:
+ integer_bitxor
+ | integer_bitor '|' integer_bitxor { $$ = $1 | $3; }
+ ;
+
+integer_bitxor:
+ integer_bitand
+ | integer_bitxor '^' integer_bitand { $$ = $1 ^ $3; }
+ ;
+
+integer_bitand:
+ integer_eq
+ | integer_bitand '&' integer_eq { $$ = $1 & $3; }
+ ;
+
+integer_eq:
+ integer_rela
+ | integer_eq DT_EQ integer_rela { $$ = $1 == $3; }
+ | integer_eq DT_NE integer_rela { $$ = $1 != $3; }
+ ;
+
+integer_rela:
+ integer_shift
+ | integer_rela '<' integer_shift { $$ = $1 < $3; }
+ | integer_rela '>' integer_shift { $$ = $1 > $3; }
+ | integer_rela DT_LE integer_shift { $$ = $1 <= $3; }
+ | integer_rela DT_GE integer_shift { $$ = $1 >= $3; }
+ ;
+
+integer_shift:
+ integer_shift DT_LSHIFT integer_add { $$ = $1 << $3; }
+ | integer_shift DT_RSHIFT integer_add { $$ = $1 >> $3; }
+ | integer_add
+ ;
+
+integer_add:
+ integer_add '+' integer_mul { $$ = $1 + $3; }
+ | integer_add '-' integer_mul { $$ = $1 - $3; }
+ | integer_mul
+ ;
+
+integer_mul:
+ integer_mul '*' integer_unary { $$ = $1 * $3; }
+ | integer_mul '/' integer_unary
+ {
+ if ($3 != 0) {
+ $$ = $1 / $3;
+ } else {
+ ERROR(&@$, "Division by zero");
+ $$ = 0;
+ }
+ }
+ | integer_mul '%' integer_unary
+ {
+ if ($3 != 0) {
+ $$ = $1 % $3;
+ } else {
+ ERROR(&@$, "Division by zero");
+ $$ = 0;
+ }
+ }
+ | integer_unary
+ ;
+
+integer_unary:
+ integer_prim
+ | '-' integer_unary { $$ = -$2; }
+ | '~' integer_unary { $$ = ~$2; }
+ | '!' integer_unary { $$ = !$2; }
+ ;
+
+bytestring:
+ /* empty */
+ {
+ $$ = empty_data;
+ }
+ | bytestring DT_BYTE
+ {
+ $$ = data_append_byte($1, $2);
+ }
+ | bytestring DT_LABEL
+ {
+ $$ = data_add_marker($1, LABEL, $2);
+ }
+ ;
+
+subnodes:
+ /* empty */
+ {
+ $$ = NULL;
+ }
+ | subnode subnodes
+ {
+ $$ = chain_node($1, $2);
+ }
+ | subnode propdef
+ {
+ ERROR(&@2, "Properties must precede subnodes");
+ YYERROR;
+ }
+ ;
+
+subnode:
+ DT_PROPNODENAME nodedef
+ {
+ $$ = name_node($2, $1);
+ }
+ | DT_DEL_NODE DT_PROPNODENAME ';'
+ {
+ $$ = name_node(build_node_delete(), $2);
+ }
+ | DT_LABEL subnode
+ {
+ add_label(&$2->labels, $1);
+ $$ = $2;
+ }
+ ;
+
+%%
+
+void yyerror(char const *s)
+{
+ ERROR(&yylloc, "%s", s);
+}
diff --git a/scripts/dtc/dtc.c b/scripts/dtc/dtc.c
new file mode 100644
index 0000000000..5ed873c72a
--- /dev/null
+++ b/scripts/dtc/dtc.c
@@ -0,0 +1,365 @@
+/*
+ * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2005.
+ *
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ */
+
+#include <sys/stat.h>
+
+#include "dtc.h"
+#include "srcpos.h"
+
+/*
+ * Command line options
+ */
+int quiet; /* Level of quietness */
+int reservenum; /* Number of memory reservation slots */
+int minsize; /* Minimum blob size */
+int padsize; /* Additional padding to blob */
+int alignsize; /* Additional padding to blob accroding to the alignsize */
+int phandle_format = PHANDLE_EPAPR; /* Use linux,phandle or phandle properties */
+int generate_symbols; /* enable symbols & fixup support */
+int generate_fixups; /* suppress generation of fixups on symbol support */
+int auto_label_aliases; /* auto generate labels -> aliases */
+
+static int is_power_of_2(int x)
+{
+ return (x > 0) && ((x & (x - 1)) == 0);
+}
+
+static void fill_fullpaths(struct node *tree, const char *prefix)
+{
+ struct node *child;
+ const char *unit;
+
+ tree->fullpath = join_path(prefix, tree->name);
+
+ unit = strchr(tree->name, '@');
+ if (unit)
+ tree->basenamelen = unit - tree->name;
+ else
+ tree->basenamelen = strlen(tree->name);
+
+ for_each_child(tree, child)
+ fill_fullpaths(child, tree->fullpath);
+}
+
+/* Usage related data. */
+#define FDT_VERSION(version) _FDT_VERSION(version)
+#define _FDT_VERSION(version) #version
+static const char usage_synopsis[] = "dtc [options] <input file>";
+static const char usage_short_opts[] = "qI:O:o:V:d:R:S:p:a:fb:i:H:sW:E:@Ahv";
+static struct option const usage_long_opts[] = {
+ {"quiet", no_argument, NULL, 'q'},
+ {"in-format", a_argument, NULL, 'I'},
+ {"out", a_argument, NULL, 'o'},
+ {"out-format", a_argument, NULL, 'O'},
+ {"out-version", a_argument, NULL, 'V'},
+ {"out-dependency", a_argument, NULL, 'd'},
+ {"reserve", a_argument, NULL, 'R'},
+ {"space", a_argument, NULL, 'S'},
+ {"pad", a_argument, NULL, 'p'},
+ {"align", a_argument, NULL, 'a'},
+ {"boot-cpu", a_argument, NULL, 'b'},
+ {"force", no_argument, NULL, 'f'},
+ {"include", a_argument, NULL, 'i'},
+ {"sort", no_argument, NULL, 's'},
+ {"phandle", a_argument, NULL, 'H'},
+ {"warning", a_argument, NULL, 'W'},
+ {"error", a_argument, NULL, 'E'},
+ {"symbols", no_argument, NULL, '@'},
+ {"auto-alias", no_argument, NULL, 'A'},
+ {"help", no_argument, NULL, 'h'},
+ {"version", no_argument, NULL, 'v'},
+ {NULL, no_argument, NULL, 0x0},
+};
+static const char * const usage_opts_help[] = {
+ "\n\tQuiet: -q suppress warnings, -qq errors, -qqq all",
+ "\n\tInput formats are:\n"
+ "\t\tdts - device tree source text\n"
+ "\t\tdtb - device tree blob\n"
+ "\t\tfs - /proc/device-tree style directory",
+ "\n\tOutput file",
+ "\n\tOutput formats are:\n"
+ "\t\tdts - device tree source text\n"
+ "\t\tdtb - device tree blob\n"
+ "\t\tasm - assembler source",
+ "\n\tBlob version to produce, defaults to "FDT_VERSION(DEFAULT_FDT_VERSION)" (for dtb and asm output)",
+ "\n\tOutput dependency file",
+ "\n\tMake space for <number> reserve map entries (for dtb and asm output)",
+ "\n\tMake the blob at least <bytes> long (extra space)",
+ "\n\tAdd padding to the blob of <bytes> long (extra space)",
+ "\n\tMake the blob align to the <bytes> (extra space)",
+ "\n\tSet the physical boot cpu",
+ "\n\tTry to produce output even if the input tree has errors",
+ "\n\tAdd a path to search for include files",
+ "\n\tSort nodes and properties before outputting (useful for comparing trees)",
+ "\n\tValid phandle formats are:\n"
+ "\t\tlegacy - \"linux,phandle\" properties only\n"
+ "\t\tepapr - \"phandle\" properties only\n"
+ "\t\tboth - Both \"linux,phandle\" and \"phandle\" properties",
+ "\n\tEnable/disable warnings (prefix with \"no-\")",
+ "\n\tEnable/disable errors (prefix with \"no-\")",
+ "\n\tEnable generation of symbols",
+ "\n\tEnable auto-alias of labels",
+ "\n\tPrint this help and exit",
+ "\n\tPrint version and exit",
+ NULL,
+};
+
+static const char *guess_type_by_name(const char *fname, const char *fallback)
+{
+ const char *s;
+
+ s = strrchr(fname, '.');
+ if (s == NULL)
+ return fallback;
+ if (!strcasecmp(s, ".dts"))
+ return "dts";
+ if (!strcasecmp(s, ".dtb"))
+ return "dtb";
+ return fallback;
+}
+
+static const char *guess_input_format(const char *fname, const char *fallback)
+{
+ struct stat statbuf;
+ fdt32_t magic;
+ FILE *f;
+
+ if (stat(fname, &statbuf) != 0)
+ return fallback;
+
+ if (S_ISDIR(statbuf.st_mode))
+ return "fs";
+
+ if (!S_ISREG(statbuf.st_mode))
+ return fallback;
+
+ f = fopen(fname, "r");
+ if (f == NULL)
+ return fallback;
+ if (fread(&magic, 4, 1, f) != 1) {
+ fclose(f);
+ return fallback;
+ }
+ fclose(f);
+
+ if (fdt32_to_cpu(magic) == FDT_MAGIC)
+ return "dtb";
+
+ return guess_type_by_name(fname, fallback);
+}
+
+int main(int argc, char *argv[])
+{
+ struct dt_info *dti;
+ const char *inform = NULL;
+ const char *outform = NULL;
+ const char *outname = "-";
+ const char *depname = NULL;
+ bool force = false, sort = false;
+ const char *arg;
+ int opt;
+ FILE *outf = NULL;
+ int outversion = DEFAULT_FDT_VERSION;
+ long long cmdline_boot_cpuid = -1;
+
+ quiet = 0;
+ reservenum = 0;
+ minsize = 0;
+ padsize = 0;
+ alignsize = 0;
+
+ while ((opt = util_getopt_long()) != EOF) {
+ switch (opt) {
+ case 'I':
+ inform = optarg;
+ break;
+ case 'O':
+ outform = optarg;
+ break;
+ case 'o':
+ outname = optarg;
+ break;
+ case 'V':
+ outversion = strtol(optarg, NULL, 0);
+ break;
+ case 'd':
+ depname = optarg;
+ break;
+ case 'R':
+ reservenum = strtol(optarg, NULL, 0);
+ break;
+ case 'S':
+ minsize = strtol(optarg, NULL, 0);
+ break;
+ case 'p':
+ padsize = strtol(optarg, NULL, 0);
+ break;
+ case 'a':
+ alignsize = strtol(optarg, NULL, 0);
+ if (!is_power_of_2(alignsize))
+ die("Invalid argument \"%d\" to -a option\n",
+ alignsize);
+ break;
+ case 'f':
+ force = true;
+ break;
+ case 'q':
+ quiet++;
+ break;
+ case 'b':
+ cmdline_boot_cpuid = strtoll(optarg, NULL, 0);
+ break;
+ case 'i':
+ srcfile_add_search_path(optarg);
+ break;
+ case 'v':
+ util_version();
+ case 'H':
+ if (streq(optarg, "legacy"))
+ phandle_format = PHANDLE_LEGACY;
+ else if (streq(optarg, "epapr"))
+ phandle_format = PHANDLE_EPAPR;
+ else if (streq(optarg, "both"))
+ phandle_format = PHANDLE_BOTH;
+ else
+ die("Invalid argument \"%s\" to -H option\n",
+ optarg);
+ break;
+
+ case 's':
+ sort = true;
+ break;
+
+ case 'W':
+ parse_checks_option(true, false, optarg);
+ break;
+
+ case 'E':
+ parse_checks_option(false, true, optarg);
+ break;
+
+ case '@':
+ generate_symbols = 1;
+ break;
+ case 'A':
+ auto_label_aliases = 1;
+ break;
+
+ case 'h':
+ usage(NULL);
+ default:
+ usage("unknown option");
+ }
+ }
+
+ if (argc > (optind+1))
+ usage("missing files");
+ else if (argc < (optind+1))
+ arg = "-";
+ else
+ arg = argv[optind];
+
+ /* minsize and padsize are mutually exclusive */
+ if (minsize && padsize)
+ die("Can't set both -p and -S\n");
+
+ if (depname) {
+ depfile = fopen(depname, "w");
+ if (!depfile)
+ die("Couldn't open dependency file %s: %s\n", depname,
+ strerror(errno));
+ fprintf(depfile, "%s:", outname);
+ }
+
+ if (inform == NULL)
+ inform = guess_input_format(arg, "dts");
+ if (outform == NULL) {
+ outform = guess_type_by_name(outname, NULL);
+ if (outform == NULL) {
+ if (streq(inform, "dts"))
+ outform = "dtb";
+ else
+ outform = "dts";
+ }
+ }
+ if (streq(inform, "dts"))
+ dti = dt_from_source(arg);
+ else if (streq(inform, "fs"))
+ dti = dt_from_fs(arg);
+ else if(streq(inform, "dtb"))
+ dti = dt_from_blob(arg);
+ else
+ die("Unknown input format \"%s\"\n", inform);
+
+ dti->outname = outname;
+
+ if (depfile) {
+ fputc('\n', depfile);
+ fclose(depfile);
+ }
+
+ if (cmdline_boot_cpuid != -1)
+ dti->boot_cpuid_phys = cmdline_boot_cpuid;
+
+ fill_fullpaths(dti->dt, "");
+ process_checks(force, dti);
+
+ /* on a plugin, generate by default */
+ if (dti->dtsflags & DTSF_PLUGIN) {
+ generate_fixups = 1;
+ }
+
+ if (auto_label_aliases)
+ generate_label_tree(dti, "aliases", false);
+
+ if (generate_symbols)
+ generate_label_tree(dti, "__symbols__", true);
+
+ if (generate_fixups) {
+ generate_fixups_tree(dti, "__fixups__");
+ generate_local_fixups_tree(dti, "__local_fixups__");
+ }
+
+ if (sort)
+ sort_tree(dti);
+
+ if (streq(outname, "-")) {
+ outf = stdout;
+ } else {
+ outf = fopen(outname, "wb");
+ if (! outf)
+ die("Couldn't open output file %s: %s\n",
+ outname, strerror(errno));
+ }
+
+ if (streq(outform, "dts")) {
+ dt_to_source(outf, dti);
+ } else if (streq(outform, "dtb")) {
+ dt_to_blob(outf, dti, outversion);
+ } else if (streq(outform, "asm")) {
+ dt_to_asm(outf, dti, outversion);
+ } else if (streq(outform, "null")) {
+ /* do nothing */
+ } else {
+ die("Unknown output format \"%s\"\n", outform);
+ }
+
+ exit(0);
+}
diff --git a/scripts/dtc/dtc.h b/scripts/dtc/dtc.h
new file mode 100644
index 0000000000..409db76c94
--- /dev/null
+++ b/scripts/dtc/dtc.h
@@ -0,0 +1,290 @@
+#ifndef _DTC_H
+#define _DTC_H
+
+/*
+ * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2005.
+ *
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
+#include <errno.h>
+#include <unistd.h>
+#include <inttypes.h>
+
+#include <libfdt_env.h>
+#include <fdt.h>
+
+#include "util.h"
+
+#ifdef DEBUG
+#define debug(...) printf(__VA_ARGS__)
+#else
+#define debug(...)
+#endif
+
+#define DEFAULT_FDT_VERSION 17
+
+/*
+ * Command line options
+ */
+extern int quiet; /* Level of quietness */
+extern int reservenum; /* Number of memory reservation slots */
+extern int minsize; /* Minimum blob size */
+extern int padsize; /* Additional padding to blob */
+extern int alignsize; /* Additional padding to blob accroding to the alignsize */
+extern int phandle_format; /* Use linux,phandle or phandle properties */
+extern int generate_symbols; /* generate symbols for nodes with labels */
+extern int generate_fixups; /* generate fixups */
+extern int auto_label_aliases; /* auto generate labels -> aliases */
+
+#define PHANDLE_LEGACY 0x1
+#define PHANDLE_EPAPR 0x2
+#define PHANDLE_BOTH 0x3
+
+typedef uint32_t cell_t;
+
+
+#define streq(a, b) (strcmp((a), (b)) == 0)
+#define strneq(a, b, n) (strncmp((a), (b), (n)) == 0)
+
+#define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
+
+/* Data blobs */
+enum markertype {
+ REF_PHANDLE,
+ REF_PATH,
+ LABEL,
+};
+
+struct marker {
+ enum markertype type;
+ int offset;
+ char *ref;
+ struct marker *next;
+};
+
+struct data {
+ int len;
+ char *val;
+ struct marker *markers;
+};
+
+
+#define empty_data ((struct data){ 0 /* all .members = 0 or NULL */ })
+
+#define for_each_marker(m) \
+ for (; (m); (m) = (m)->next)
+#define for_each_marker_of_type(m, t) \
+ for_each_marker(m) \
+ if ((m)->type == (t))
+
+void data_free(struct data d);
+
+struct data data_grow_for(struct data d, int xlen);
+
+struct data data_copy_mem(const char *mem, int len);
+struct data data_copy_escape_string(const char *s, int len);
+struct data data_copy_file(FILE *f, size_t len);
+
+struct data data_append_data(struct data d, const void *p, int len);
+struct data data_insert_at_marker(struct data d, struct marker *m,
+ const void *p, int len);
+struct data data_merge(struct data d1, struct data d2);
+struct data data_append_cell(struct data d, cell_t word);
+struct data data_append_integer(struct data d, uint64_t word, int bits);
+struct data data_append_re(struct data d, uint64_t address, uint64_t size);
+struct data data_append_addr(struct data d, uint64_t addr);
+struct data data_append_byte(struct data d, uint8_t byte);
+struct data data_append_zeroes(struct data d, int len);
+struct data data_append_align(struct data d, int align);
+
+struct data data_add_marker(struct data d, enum markertype type, char *ref);
+
+bool data_is_one_string(struct data d);
+
+/* DT constraints */
+
+#define MAX_PROPNAME_LEN 31
+#define MAX_NODENAME_LEN 31
+
+/* Live trees */
+struct label {
+ bool deleted;
+ char *label;
+ struct label *next;
+};
+
+struct bus_type {
+ const char *name;
+};
+
+struct property {
+ bool deleted;
+ char *name;
+ struct data val;
+
+ struct property *next;
+
+ struct label *labels;
+};
+
+struct node {
+ bool deleted;
+ char *name;
+ struct property *proplist;
+ struct node *children;
+
+ struct node *parent;
+ struct node *next_sibling;
+
+ char *fullpath;
+ int basenamelen;
+
+ cell_t phandle;
+ int addr_cells, size_cells;
+
+ struct label *labels;
+ const struct bus_type *bus;
+};
+
+#define for_each_label_withdel(l0, l) \
+ for ((l) = (l0); (l); (l) = (l)->next)
+
+#define for_each_label(l0, l) \
+ for_each_label_withdel(l0, l) \
+ if (!(l)->deleted)
+
+#define for_each_property_withdel(n, p) \
+ for ((p) = (n)->proplist; (p); (p) = (p)->next)
+
+#define for_each_property(n, p) \
+ for_each_property_withdel(n, p) \
+ if (!(p)->deleted)
+
+#define for_each_child_withdel(n, c) \
+ for ((c) = (n)->children; (c); (c) = (c)->next_sibling)
+
+#define for_each_child(n, c) \
+ for_each_child_withdel(n, c) \
+ if (!(c)->deleted)
+
+void add_label(struct label **labels, char *label);
+void delete_labels(struct label **labels);
+
+struct property *build_property(char *name, struct data val);
+struct property *build_property_delete(char *name);
+struct property *chain_property(struct property *first, struct property *list);
+struct property *reverse_properties(struct property *first);
+
+struct node *build_node(struct property *proplist, struct node *children);
+struct node *build_node_delete(void);
+struct node *name_node(struct node *node, char *name);
+struct node *chain_node(struct node *first, struct node *list);
+struct node *merge_nodes(struct node *old_node, struct node *new_node);
+
+void add_property(struct node *node, struct property *prop);
+void delete_property_by_name(struct node *node, char *name);
+void delete_property(struct property *prop);
+void add_child(struct node *parent, struct node *child);
+void delete_node_by_name(struct node *parent, char *name);
+void delete_node(struct node *node);
+void append_to_property(struct node *node,
+ char *name, const void *data, int len);
+
+const char *get_unitname(struct node *node);
+struct property *get_property(struct node *node, const char *propname);
+cell_t propval_cell(struct property *prop);
+struct property *get_property_by_label(struct node *tree, const char *label,
+ struct node **node);
+struct marker *get_marker_label(struct node *tree, const char *label,
+ struct node **node, struct property **prop);
+struct node *get_subnode(struct node *node, const char *nodename);
+struct node *get_node_by_path(struct node *tree, const char *path);
+struct node *get_node_by_label(struct node *tree, const char *label);
+struct node *get_node_by_phandle(struct node *tree, cell_t phandle);
+struct node *get_node_by_ref(struct node *tree, const char *ref);
+cell_t get_node_phandle(struct node *root, struct node *node);
+
+uint32_t guess_boot_cpuid(struct node *tree);
+
+/* Boot info (tree plus memreserve information */
+
+struct reserve_info {
+ uint64_t address, size;
+
+ struct reserve_info *next;
+
+ struct label *labels;
+};
+
+struct reserve_info *build_reserve_entry(uint64_t start, uint64_t len);
+struct reserve_info *chain_reserve_entry(struct reserve_info *first,
+ struct reserve_info *list);
+struct reserve_info *add_reserve_entry(struct reserve_info *list,
+ struct reserve_info *new);
+
+
+struct dt_info {
+ unsigned int dtsflags;
+ struct reserve_info *reservelist;
+ uint32_t boot_cpuid_phys;
+ struct node *dt; /* the device tree */
+ const char *outname; /* filename being written to, "-" for stdout */
+};
+
+/* DTS version flags definitions */
+#define DTSF_V1 0x0001 /* /dts-v1/ */
+#define DTSF_PLUGIN 0x0002 /* /plugin/ */
+
+struct dt_info *build_dt_info(unsigned int dtsflags,
+ struct reserve_info *reservelist,
+ struct node *tree, uint32_t boot_cpuid_phys);
+void sort_tree(struct dt_info *dti);
+void generate_label_tree(struct dt_info *dti, char *name, bool allocph);
+void generate_fixups_tree(struct dt_info *dti, char *name);
+void generate_local_fixups_tree(struct dt_info *dti, char *name);
+
+/* Checks */
+
+void parse_checks_option(bool warn, bool error, const char *arg);
+void process_checks(bool force, struct dt_info *dti);
+
+/* Flattened trees */
+
+void dt_to_blob(FILE *f, struct dt_info *dti, int version);
+void dt_to_asm(FILE *f, struct dt_info *dti, int version);
+
+struct dt_info *dt_from_blob(const char *fname);
+
+/* Tree source */
+
+void dt_to_source(FILE *f, struct dt_info *dti);
+struct dt_info *dt_from_source(const char *f);
+
+/* FS trees */
+
+struct dt_info *dt_from_fs(const char *dirname);
+
+#endif /* _DTC_H */
diff --git a/scripts/dtc/flattree.c b/scripts/dtc/flattree.c
new file mode 100644
index 0000000000..fcf71541d8
--- /dev/null
+++ b/scripts/dtc/flattree.c
@@ -0,0 +1,940 @@
+/*
+ * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2005.
+ *
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ */
+
+#include "dtc.h"
+#include "srcpos.h"
+
+#define FTF_FULLPATH 0x1
+#define FTF_VARALIGN 0x2
+#define FTF_NAMEPROPS 0x4
+#define FTF_BOOTCPUID 0x8
+#define FTF_STRTABSIZE 0x10
+#define FTF_STRUCTSIZE 0x20
+#define FTF_NOPS 0x40
+
+static struct version_info {
+ int version;
+ int last_comp_version;
+ int hdr_size;
+ int flags;
+} version_table[] = {
+ {1, 1, FDT_V1_SIZE,
+ FTF_FULLPATH|FTF_VARALIGN|FTF_NAMEPROPS},
+ {2, 1, FDT_V2_SIZE,
+ FTF_FULLPATH|FTF_VARALIGN|FTF_NAMEPROPS|FTF_BOOTCPUID},
+ {3, 1, FDT_V3_SIZE,
+ FTF_FULLPATH|FTF_VARALIGN|FTF_NAMEPROPS|FTF_BOOTCPUID|FTF_STRTABSIZE},
+ {16, 16, FDT_V3_SIZE,
+ FTF_BOOTCPUID|FTF_STRTABSIZE|FTF_NOPS},
+ {17, 16, FDT_V17_SIZE,
+ FTF_BOOTCPUID|FTF_STRTABSIZE|FTF_STRUCTSIZE|FTF_NOPS},
+};
+
+struct emitter {
+ void (*cell)(void *, cell_t);
+ void (*string)(void *, const char *, int);
+ void (*align)(void *, int);
+ void (*data)(void *, struct data);
+ void (*beginnode)(void *, struct label *labels);
+ void (*endnode)(void *, struct label *labels);
+ void (*property)(void *, struct label *labels);
+};
+
+static void bin_emit_cell(void *e, cell_t val)
+{
+ struct data *dtbuf = e;
+
+ *dtbuf = data_append_cell(*dtbuf, val);
+}
+
+static void bin_emit_string(void *e, const char *str, int len)
+{
+ struct data *dtbuf = e;
+
+ if (len == 0)
+ len = strlen(str);
+
+ *dtbuf = data_append_data(*dtbuf, str, len);
+ *dtbuf = data_append_byte(*dtbuf, '\0');
+}
+
+static void bin_emit_align(void *e, int a)
+{
+ struct data *dtbuf = e;
+
+ *dtbuf = data_append_align(*dtbuf, a);
+}
+
+static void bin_emit_data(void *e, struct data d)
+{
+ struct data *dtbuf = e;
+
+ *dtbuf = data_append_data(*dtbuf, d.val, d.len);
+}
+
+static void bin_emit_beginnode(void *e, struct label *labels)
+{
+ bin_emit_cell(e, FDT_BEGIN_NODE);
+}
+
+static void bin_emit_endnode(void *e, struct label *labels)
+{
+ bin_emit_cell(e, FDT_END_NODE);
+}
+
+static void bin_emit_property(void *e, struct label *labels)
+{
+ bin_emit_cell(e, FDT_PROP);
+}
+
+static struct emitter bin_emitter = {
+ .cell = bin_emit_cell,
+ .string = bin_emit_string,
+ .align = bin_emit_align,
+ .data = bin_emit_data,
+ .beginnode = bin_emit_beginnode,
+ .endnode = bin_emit_endnode,
+ .property = bin_emit_property,
+};
+
+static void emit_label(FILE *f, const char *prefix, const char *label)
+{
+ fprintf(f, "\t.globl\t%s_%s\n", prefix, label);
+ fprintf(f, "%s_%s:\n", prefix, label);
+ fprintf(f, "_%s_%s:\n", prefix, label);
+}
+
+static void emit_offset_label(FILE *f, const char *label, int offset)
+{
+ fprintf(f, "\t.globl\t%s\n", label);
+ fprintf(f, "%s\t= . + %d\n", label, offset);
+}
+
+#define ASM_EMIT_BELONG(f, fmt, ...) \
+ { \
+ fprintf((f), "\t.byte\t((" fmt ") >> 24) & 0xff\n", __VA_ARGS__); \
+ fprintf((f), "\t.byte\t((" fmt ") >> 16) & 0xff\n", __VA_ARGS__); \
+ fprintf((f), "\t.byte\t((" fmt ") >> 8) & 0xff\n", __VA_ARGS__); \
+ fprintf((f), "\t.byte\t(" fmt ") & 0xff\n", __VA_ARGS__); \
+ }
+
+static void asm_emit_cell(void *e, cell_t val)
+{
+ FILE *f = e;
+
+ fprintf(f, "\t.byte 0x%02x; .byte 0x%02x; .byte 0x%02x; .byte 0x%02x\n",
+ (val >> 24) & 0xff, (val >> 16) & 0xff,
+ (val >> 8) & 0xff, val & 0xff);
+}
+
+static void asm_emit_string(void *e, const char *str, int len)
+{
+ FILE *f = e;
+
+ if (len != 0)
+ fprintf(f, "\t.string\t\"%.*s\"\n", len, str);
+ else
+ fprintf(f, "\t.string\t\"%s\"\n", str);
+}
+
+static void asm_emit_align(void *e, int a)
+{
+ FILE *f = e;
+
+ fprintf(f, "\t.balign\t%d, 0\n", a);
+}
+
+static void asm_emit_data(void *e, struct data d)
+{
+ FILE *f = e;
+ int off = 0;
+ struct marker *m = d.markers;
+
+ for_each_marker_of_type(m, LABEL)
+ emit_offset_label(f, m->ref, m->offset);
+
+ while ((d.len - off) >= sizeof(uint32_t)) {
+ asm_emit_cell(e, fdt32_to_cpu(*((fdt32_t *)(d.val+off))));
+ off += sizeof(uint32_t);
+ }
+
+ while ((d.len - off) >= 1) {
+ fprintf(f, "\t.byte\t0x%hhx\n", d.val[off]);
+ off += 1;
+ }
+
+ assert(off == d.len);
+}
+
+static void asm_emit_beginnode(void *e, struct label *labels)
+{
+ FILE *f = e;
+ struct label *l;
+
+ for_each_label(labels, l) {
+ fprintf(f, "\t.globl\t%s\n", l->label);
+ fprintf(f, "%s:\n", l->label);
+ }
+ fprintf(f, "\t/* FDT_BEGIN_NODE */\n");
+ asm_emit_cell(e, FDT_BEGIN_NODE);
+}
+
+static void asm_emit_endnode(void *e, struct label *labels)
+{
+ FILE *f = e;
+ struct label *l;
+
+ fprintf(f, "\t/* FDT_END_NODE */\n");
+ asm_emit_cell(e, FDT_END_NODE);
+ for_each_label(labels, l) {
+ fprintf(f, "\t.globl\t%s_end\n", l->label);
+ fprintf(f, "%s_end:\n", l->label);
+ }
+}
+
+static void asm_emit_property(void *e, struct label *labels)
+{
+ FILE *f = e;
+ struct label *l;
+
+ for_each_label(labels, l) {
+ fprintf(f, "\t.globl\t%s\n", l->label);
+ fprintf(f, "%s:\n", l->label);
+ }
+ fprintf(f, "\t/* FDT_PROP */\n");
+ asm_emit_cell(e, FDT_PROP);
+}
+
+static struct emitter asm_emitter = {
+ .cell = asm_emit_cell,
+ .string = asm_emit_string,
+ .align = asm_emit_align,
+ .data = asm_emit_data,
+ .beginnode = asm_emit_beginnode,
+ .endnode = asm_emit_endnode,
+ .property = asm_emit_property,
+};
+
+static int stringtable_insert(struct data *d, const char *str)
+{
+ int i;
+
+ /* FIXME: do this more efficiently? */
+
+ for (i = 0; i < d->len; i++) {
+ if (streq(str, d->val + i))
+ return i;
+ }
+
+ *d = data_append_data(*d, str, strlen(str)+1);
+ return i;
+}
+
+static void flatten_tree(struct node *tree, struct emitter *emit,
+ void *etarget, struct data *strbuf,
+ struct version_info *vi)
+{
+ struct property *prop;
+ struct node *child;
+ bool seen_name_prop = false;
+
+ if (tree->deleted)
+ return;
+
+ emit->beginnode(etarget, tree->labels);
+
+ if (vi->flags & FTF_FULLPATH)
+ emit->string(etarget, tree->fullpath, 0);
+ else
+ emit->string(etarget, tree->name, 0);
+
+ emit->align(etarget, sizeof(cell_t));
+
+ for_each_property(tree, prop) {
+ int nameoff;
+
+ if (streq(prop->name, "name"))
+ seen_name_prop = true;
+
+ nameoff = stringtable_insert(strbuf, prop->name);
+
+ emit->property(etarget, prop->labels);
+ emit->cell(etarget, prop->val.len);
+ emit->cell(etarget, nameoff);
+
+ if ((vi->flags & FTF_VARALIGN) && (prop->val.len >= 8))
+ emit->align(etarget, 8);
+
+ emit->data(etarget, prop->val);
+ emit->align(etarget, sizeof(cell_t));
+ }
+
+ if ((vi->flags & FTF_NAMEPROPS) && !seen_name_prop) {
+ emit->property(etarget, NULL);
+ emit->cell(etarget, tree->basenamelen+1);
+ emit->cell(etarget, stringtable_insert(strbuf, "name"));
+
+ if ((vi->flags & FTF_VARALIGN) && ((tree->basenamelen+1) >= 8))
+ emit->align(etarget, 8);
+
+ emit->string(etarget, tree->name, tree->basenamelen);
+ emit->align(etarget, sizeof(cell_t));
+ }
+
+ for_each_child(tree, child) {
+ flatten_tree(child, emit, etarget, strbuf, vi);
+ }
+
+ emit->endnode(etarget, tree->labels);
+}
+
+static struct data flatten_reserve_list(struct reserve_info *reservelist,
+ struct version_info *vi)
+{
+ struct reserve_info *re;
+ struct data d = empty_data;
+ int j;
+
+ for (re = reservelist; re; re = re->next) {
+ d = data_append_re(d, re->address, re->size);
+ }
+ /*
+ * Add additional reserved slots if the user asked for them.
+ */
+ for (j = 0; j < reservenum; j++) {
+ d = data_append_re(d, 0, 0);
+ }
+
+ return d;
+}
+
+static void make_fdt_header(struct fdt_header *fdt,
+ struct version_info *vi,
+ int reservesize, int dtsize, int strsize,
+ int boot_cpuid_phys)
+{
+ int reserve_off;
+
+ reservesize += sizeof(struct fdt_reserve_entry);
+
+ memset(fdt, 0xff, sizeof(*fdt));
+
+ fdt->magic = cpu_to_fdt32(FDT_MAGIC);
+ fdt->version = cpu_to_fdt32(vi->version);
+ fdt->last_comp_version = cpu_to_fdt32(vi->last_comp_version);
+
+ /* Reserve map should be doubleword aligned */
+ reserve_off = ALIGN(vi->hdr_size, 8);
+
+ fdt->off_mem_rsvmap = cpu_to_fdt32(reserve_off);
+ fdt->off_dt_struct = cpu_to_fdt32(reserve_off + reservesize);
+ fdt->off_dt_strings = cpu_to_fdt32(reserve_off + reservesize
+ + dtsize);
+ fdt->totalsize = cpu_to_fdt32(reserve_off + reservesize + dtsize + strsize);
+
+ if (vi->flags & FTF_BOOTCPUID)
+ fdt->boot_cpuid_phys = cpu_to_fdt32(boot_cpuid_phys);
+ if (vi->flags & FTF_STRTABSIZE)
+ fdt->size_dt_strings = cpu_to_fdt32(strsize);
+ if (vi->flags & FTF_STRUCTSIZE)
+ fdt->size_dt_struct = cpu_to_fdt32(dtsize);
+}
+
+void dt_to_blob(FILE *f, struct dt_info *dti, int version)
+{
+ struct version_info *vi = NULL;
+ int i;
+ struct data blob = empty_data;
+ struct data reservebuf = empty_data;
+ struct data dtbuf = empty_data;
+ struct data strbuf = empty_data;
+ struct fdt_header fdt;
+ int padlen = 0;
+
+ for (i = 0; i < ARRAY_SIZE(version_table); i++) {
+ if (version_table[i].version == version)
+ vi = &version_table[i];
+ }
+ if (!vi)
+ die("Unknown device tree blob version %d\n", version);
+
+ flatten_tree(dti->dt, &bin_emitter, &dtbuf, &strbuf, vi);
+ bin_emit_cell(&dtbuf, FDT_END);
+
+ reservebuf = flatten_reserve_list(dti->reservelist, vi);
+
+ /* Make header */
+ make_fdt_header(&fdt, vi, reservebuf.len, dtbuf.len, strbuf.len,
+ dti->boot_cpuid_phys);
+
+ /*
+ * If the user asked for more space than is used, adjust the totalsize.
+ */
+ if (minsize > 0) {
+ padlen = minsize - fdt32_to_cpu(fdt.totalsize);
+ if (padlen < 0) {
+ padlen = 0;
+ if (quiet < 1)
+ fprintf(stderr,
+ "Warning: blob size %d >= minimum size %d\n",
+ fdt32_to_cpu(fdt.totalsize), minsize);
+ }
+ }
+
+ if (padsize > 0)
+ padlen = padsize;
+
+ if (alignsize > 0)
+ padlen = ALIGN(fdt32_to_cpu(fdt.totalsize) + padlen, alignsize)
+ - fdt32_to_cpu(fdt.totalsize);
+
+ if (padlen > 0) {
+ int tsize = fdt32_to_cpu(fdt.totalsize);
+ tsize += padlen;
+ fdt.totalsize = cpu_to_fdt32(tsize);
+ }
+
+ /*
+ * Assemble the blob: start with the header, add with alignment
+ * the reserve buffer, add the reserve map terminating zeroes,
+ * the device tree itself, and finally the strings.
+ */
+ blob = data_append_data(blob, &fdt, vi->hdr_size);
+ blob = data_append_align(blob, 8);
+ blob = data_merge(blob, reservebuf);
+ blob = data_append_zeroes(blob, sizeof(struct fdt_reserve_entry));
+ blob = data_merge(blob, dtbuf);
+ blob = data_merge(blob, strbuf);
+
+ /*
+ * If the user asked for more space than is used, pad out the blob.
+ */
+ if (padlen > 0)
+ blob = data_append_zeroes(blob, padlen);
+
+ if (fwrite(blob.val, blob.len, 1, f) != 1) {
+ if (ferror(f))
+ die("Error writing device tree blob: %s\n",
+ strerror(errno));
+ else
+ die("Short write on device tree blob\n");
+ }
+
+ /*
+ * data_merge() frees the right-hand element so only the blob
+ * remains to be freed.
+ */
+ data_free(blob);
+}
+
+static void dump_stringtable_asm(FILE *f, struct data strbuf)
+{
+ const char *p;
+ int len;
+
+ p = strbuf.val;
+
+ while (p < (strbuf.val + strbuf.len)) {
+ len = strlen(p);
+ fprintf(f, "\t.string \"%s\"\n", p);
+ p += len+1;
+ }
+}
+
+void dt_to_asm(FILE *f, struct dt_info *dti, int version)
+{
+ struct version_info *vi = NULL;
+ int i;
+ struct data strbuf = empty_data;
+ struct reserve_info *re;
+ const char *symprefix = "dt";
+
+ for (i = 0; i < ARRAY_SIZE(version_table); i++) {
+ if (version_table[i].version == version)
+ vi = &version_table[i];
+ }
+ if (!vi)
+ die("Unknown device tree blob version %d\n", version);
+
+ fprintf(f, "/* autogenerated by dtc, do not edit */\n\n");
+
+ emit_label(f, symprefix, "blob_start");
+ emit_label(f, symprefix, "header");
+ fprintf(f, "\t/* magic */\n");
+ asm_emit_cell(f, FDT_MAGIC);
+ fprintf(f, "\t/* totalsize */\n");
+ ASM_EMIT_BELONG(f, "_%s_blob_abs_end - _%s_blob_start",
+ symprefix, symprefix);
+ fprintf(f, "\t/* off_dt_struct */\n");
+ ASM_EMIT_BELONG(f, "_%s_struct_start - _%s_blob_start",
+ symprefix, symprefix);
+ fprintf(f, "\t/* off_dt_strings */\n");
+ ASM_EMIT_BELONG(f, "_%s_strings_start - _%s_blob_start",
+ symprefix, symprefix);
+ fprintf(f, "\t/* off_mem_rsvmap */\n");
+ ASM_EMIT_BELONG(f, "_%s_reserve_map - _%s_blob_start",
+ symprefix, symprefix);
+ fprintf(f, "\t/* version */\n");
+ asm_emit_cell(f, vi->version);
+ fprintf(f, "\t/* last_comp_version */\n");
+ asm_emit_cell(f, vi->last_comp_version);
+
+ if (vi->flags & FTF_BOOTCPUID) {
+ fprintf(f, "\t/* boot_cpuid_phys */\n");
+ asm_emit_cell(f, dti->boot_cpuid_phys);
+ }
+
+ if (vi->flags & FTF_STRTABSIZE) {
+ fprintf(f, "\t/* size_dt_strings */\n");
+ ASM_EMIT_BELONG(f, "_%s_strings_end - _%s_strings_start",
+ symprefix, symprefix);
+ }
+
+ if (vi->flags & FTF_STRUCTSIZE) {
+ fprintf(f, "\t/* size_dt_struct */\n");
+ ASM_EMIT_BELONG(f, "_%s_struct_end - _%s_struct_start",
+ symprefix, symprefix);
+ }
+
+ /*
+ * Reserve map entries.
+ * Align the reserve map to a doubleword boundary.
+ * Each entry is an (address, size) pair of u64 values.
+ * Always supply a zero-sized temination entry.
+ */
+ asm_emit_align(f, 8);
+ emit_label(f, symprefix, "reserve_map");
+
+ fprintf(f, "/* Memory reserve map from source file */\n");
+
+ /*
+ * Use .long on high and low halfs of u64s to avoid .quad
+ * as it appears .quad isn't available in some assemblers.
+ */
+ for (re = dti->reservelist; re; re = re->next) {
+ struct label *l;
+
+ for_each_label(re->labels, l) {
+ fprintf(f, "\t.globl\t%s\n", l->label);
+ fprintf(f, "%s:\n", l->label);
+ }
+ ASM_EMIT_BELONG(f, "0x%08x", (unsigned int)(re->address >> 32));
+ ASM_EMIT_BELONG(f, "0x%08x",
+ (unsigned int)(re->address & 0xffffffff));
+ ASM_EMIT_BELONG(f, "0x%08x", (unsigned int)(re->size >> 32));
+ ASM_EMIT_BELONG(f, "0x%08x", (unsigned int)(re->size & 0xffffffff));
+ }
+ for (i = 0; i < reservenum; i++) {
+ fprintf(f, "\t.long\t0, 0\n\t.long\t0, 0\n");
+ }
+
+ fprintf(f, "\t.long\t0, 0\n\t.long\t0, 0\n");
+
+ emit_label(f, symprefix, "struct_start");
+ flatten_tree(dti->dt, &asm_emitter, f, &strbuf, vi);
+
+ fprintf(f, "\t/* FDT_END */\n");
+ asm_emit_cell(f, FDT_END);
+ emit_label(f, symprefix, "struct_end");
+
+ emit_label(f, symprefix, "strings_start");
+ dump_stringtable_asm(f, strbuf);
+ emit_label(f, symprefix, "strings_end");
+
+ emit_label(f, symprefix, "blob_end");
+
+ /*
+ * If the user asked for more space than is used, pad it out.
+ */
+ if (minsize > 0) {
+ fprintf(f, "\t.space\t%d - (_%s_blob_end - _%s_blob_start), 0\n",
+ minsize, symprefix, symprefix);
+ }
+ if (padsize > 0) {
+ fprintf(f, "\t.space\t%d, 0\n", padsize);
+ }
+ if (alignsize > 0)
+ asm_emit_align(f, alignsize);
+ emit_label(f, symprefix, "blob_abs_end");
+
+ data_free(strbuf);
+}
+
+struct inbuf {
+ char *base, *limit, *ptr;
+};
+
+static void inbuf_init(struct inbuf *inb, void *base, void *limit)
+{
+ inb->base = base;
+ inb->limit = limit;
+ inb->ptr = inb->base;
+}
+
+static void flat_read_chunk(struct inbuf *inb, void *p, int len)
+{
+ if ((inb->ptr + len) > inb->limit)
+ die("Premature end of data parsing flat device tree\n");
+
+ memcpy(p, inb->ptr, len);
+
+ inb->ptr += len;
+}
+
+static uint32_t flat_read_word(struct inbuf *inb)
+{
+ fdt32_t val;
+
+ assert(((inb->ptr - inb->base) % sizeof(val)) == 0);
+
+ flat_read_chunk(inb, &val, sizeof(val));
+
+ return fdt32_to_cpu(val);
+}
+
+static void flat_realign(struct inbuf *inb, int align)
+{
+ int off = inb->ptr - inb->base;
+
+ inb->ptr = inb->base + ALIGN(off, align);
+ if (inb->ptr > inb->limit)
+ die("Premature end of data parsing flat device tree\n");
+}
+
+static char *flat_read_string(struct inbuf *inb)
+{
+ int len = 0;
+ const char *p = inb->ptr;
+ char *str;
+
+ do {
+ if (p >= inb->limit)
+ die("Premature end of data parsing flat device tree\n");
+ len++;
+ } while ((*p++) != '\0');
+
+ str = xstrdup(inb->ptr);
+
+ inb->ptr += len;
+
+ flat_realign(inb, sizeof(uint32_t));
+
+ return str;
+}
+
+static struct data flat_read_data(struct inbuf *inb, int len)
+{
+ struct data d = empty_data;
+
+ if (len == 0)
+ return empty_data;
+
+ d = data_grow_for(d, len);
+ d.len = len;
+
+ flat_read_chunk(inb, d.val, len);
+
+ flat_realign(inb, sizeof(uint32_t));
+
+ return d;
+}
+
+static char *flat_read_stringtable(struct inbuf *inb, int offset)
+{
+ const char *p;
+
+ p = inb->base + offset;
+ while (1) {
+ if (p >= inb->limit || p < inb->base)
+ die("String offset %d overruns string table\n",
+ offset);
+
+ if (*p == '\0')
+ break;
+
+ p++;
+ }
+
+ return xstrdup(inb->base + offset);
+}
+
+static struct property *flat_read_property(struct inbuf *dtbuf,
+ struct inbuf *strbuf, int flags)
+{
+ uint32_t proplen, stroff;
+ char *name;
+ struct data val;
+
+ proplen = flat_read_word(dtbuf);
+ stroff = flat_read_word(dtbuf);
+
+ name = flat_read_stringtable(strbuf, stroff);
+
+ if ((flags & FTF_VARALIGN) && (proplen >= 8))
+ flat_realign(dtbuf, 8);
+
+ val = flat_read_data(dtbuf, proplen);
+
+ return build_property(name, val);
+}
+
+
+static struct reserve_info *flat_read_mem_reserve(struct inbuf *inb)
+{
+ struct reserve_info *reservelist = NULL;
+ struct reserve_info *new;
+ struct fdt_reserve_entry re;
+
+ /*
+ * Each entry is a pair of u64 (addr, size) values for 4 cell_t's.
+ * List terminates at an entry with size equal to zero.
+ *
+ * First pass, count entries.
+ */
+ while (1) {
+ uint64_t address, size;
+
+ flat_read_chunk(inb, &re, sizeof(re));
+ address = fdt64_to_cpu(re.address);
+ size = fdt64_to_cpu(re.size);
+ if (size == 0)
+ break;
+
+ new = build_reserve_entry(address, size);
+ reservelist = add_reserve_entry(reservelist, new);
+ }
+
+ return reservelist;
+}
+
+
+static char *nodename_from_path(const char *ppath, const char *cpath)
+{
+ int plen;
+
+ plen = strlen(ppath);
+
+ if (!strneq(ppath, cpath, plen))
+ die("Path \"%s\" is not valid as a child of \"%s\"\n",
+ cpath, ppath);
+
+ /* root node is a special case */
+ if (!streq(ppath, "/"))
+ plen++;
+
+ return xstrdup(cpath + plen);
+}
+
+static struct node *unflatten_tree(struct inbuf *dtbuf,
+ struct inbuf *strbuf,
+ const char *parent_flatname, int flags)
+{
+ struct node *node;
+ char *flatname;
+ uint32_t val;
+
+ node = build_node(NULL, NULL);
+
+ flatname = flat_read_string(dtbuf);
+
+ if (flags & FTF_FULLPATH)
+ node->name = nodename_from_path(parent_flatname, flatname);
+ else
+ node->name = flatname;
+
+ do {
+ struct property *prop;
+ struct node *child;
+
+ val = flat_read_word(dtbuf);
+ switch (val) {
+ case FDT_PROP:
+ if (node->children)
+ fprintf(stderr, "Warning: Flat tree input has "
+ "subnodes preceding a property.\n");
+ prop = flat_read_property(dtbuf, strbuf, flags);
+ add_property(node, prop);
+ break;
+
+ case FDT_BEGIN_NODE:
+ child = unflatten_tree(dtbuf,strbuf, flatname, flags);
+ add_child(node, child);
+ break;
+
+ case FDT_END_NODE:
+ break;
+
+ case FDT_END:
+ die("Premature FDT_END in device tree blob\n");
+ break;
+
+ case FDT_NOP:
+ if (!(flags & FTF_NOPS))
+ fprintf(stderr, "Warning: NOP tag found in flat tree"
+ " version <16\n");
+
+ /* Ignore */
+ break;
+
+ default:
+ die("Invalid opcode word %08x in device tree blob\n",
+ val);
+ }
+ } while (val != FDT_END_NODE);
+
+ if (node->name != flatname) {
+ free(flatname);
+ }
+
+ return node;
+}
+
+
+struct dt_info *dt_from_blob(const char *fname)
+{
+ FILE *f;
+ fdt32_t magic_buf, totalsize_buf;
+ uint32_t magic, totalsize, version, size_dt, boot_cpuid_phys;
+ uint32_t off_dt, off_str, off_mem_rsvmap;
+ int rc;
+ char *blob;
+ struct fdt_header *fdt;
+ char *p;
+ struct inbuf dtbuf, strbuf;
+ struct inbuf memresvbuf;
+ int sizeleft;
+ struct reserve_info *reservelist;
+ struct node *tree;
+ uint32_t val;
+ int flags = 0;
+
+ f = srcfile_relative_open(fname, NULL);
+
+ rc = fread(&magic_buf, sizeof(magic_buf), 1, f);
+ if (ferror(f))
+ die("Error reading DT blob magic number: %s\n",
+ strerror(errno));
+ if (rc < 1) {
+ if (feof(f))
+ die("EOF reading DT blob magic number\n");
+ else
+ die("Mysterious short read reading magic number\n");
+ }
+
+ magic = fdt32_to_cpu(magic_buf);
+ if (magic != FDT_MAGIC)
+ die("Blob has incorrect magic number\n");
+
+ rc = fread(&totalsize_buf, sizeof(totalsize_buf), 1, f);
+ if (ferror(f))
+ die("Error reading DT blob size: %s\n", strerror(errno));
+ if (rc < 1) {
+ if (feof(f))
+ die("EOF reading DT blob size\n");
+ else
+ die("Mysterious short read reading blob size\n");
+ }
+
+ totalsize = fdt32_to_cpu(totalsize_buf);
+ if (totalsize < FDT_V1_SIZE)
+ die("DT blob size (%d) is too small\n", totalsize);
+
+ blob = xmalloc(totalsize);
+
+ fdt = (struct fdt_header *)blob;
+ fdt->magic = cpu_to_fdt32(magic);
+ fdt->totalsize = cpu_to_fdt32(totalsize);
+
+ sizeleft = totalsize - sizeof(magic) - sizeof(totalsize);
+ p = blob + sizeof(magic) + sizeof(totalsize);
+
+ while (sizeleft) {
+ if (feof(f))
+ die("EOF before reading %d bytes of DT blob\n",
+ totalsize);
+
+ rc = fread(p, 1, sizeleft, f);
+ if (ferror(f))
+ die("Error reading DT blob: %s\n",
+ strerror(errno));
+
+ sizeleft -= rc;
+ p += rc;
+ }
+
+ off_dt = fdt32_to_cpu(fdt->off_dt_struct);
+ off_str = fdt32_to_cpu(fdt->off_dt_strings);
+ off_mem_rsvmap = fdt32_to_cpu(fdt->off_mem_rsvmap);
+ version = fdt32_to_cpu(fdt->version);
+ boot_cpuid_phys = fdt32_to_cpu(fdt->boot_cpuid_phys);
+
+ if (off_mem_rsvmap >= totalsize)
+ die("Mem Reserve structure offset exceeds total size\n");
+
+ if (off_dt >= totalsize)
+ die("DT structure offset exceeds total size\n");
+
+ if (off_str > totalsize)
+ die("String table offset exceeds total size\n");
+
+ if (version >= 3) {
+ uint32_t size_str = fdt32_to_cpu(fdt->size_dt_strings);
+ if ((off_str+size_str < off_str) || (off_str+size_str > totalsize))
+ die("String table extends past total size\n");
+ inbuf_init(&strbuf, blob + off_str, blob + off_str + size_str);
+ } else {
+ inbuf_init(&strbuf, blob + off_str, blob + totalsize);
+ }
+
+ if (version >= 17) {
+ size_dt = fdt32_to_cpu(fdt->size_dt_struct);
+ if ((off_dt+size_dt < off_dt) || (off_dt+size_dt > totalsize))
+ die("Structure block extends past total size\n");
+ }
+
+ if (version < 16) {
+ flags |= FTF_FULLPATH | FTF_NAMEPROPS | FTF_VARALIGN;
+ } else {
+ flags |= FTF_NOPS;
+ }
+
+ inbuf_init(&memresvbuf,
+ blob + off_mem_rsvmap, blob + totalsize);
+ inbuf_init(&dtbuf, blob + off_dt, blob + totalsize);
+
+ reservelist = flat_read_mem_reserve(&memresvbuf);
+
+ val = flat_read_word(&dtbuf);
+
+ if (val != FDT_BEGIN_NODE)
+ die("Device tree blob doesn't begin with FDT_BEGIN_NODE (begins with 0x%08x)\n", val);
+
+ tree = unflatten_tree(&dtbuf, &strbuf, "", flags);
+
+ val = flat_read_word(&dtbuf);
+ if (val != FDT_END)
+ die("Device tree blob doesn't end with FDT_END\n");
+
+ free(blob);
+
+ fclose(f);
+
+ return build_dt_info(DTSF_V1, reservelist, tree, boot_cpuid_phys);
+}
diff --git a/scripts/dtc/fstree.c b/scripts/dtc/fstree.c
new file mode 100644
index 0000000000..ae7d06c3c4
--- /dev/null
+++ b/scripts/dtc/fstree.c
@@ -0,0 +1,90 @@
+/*
+ * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2005.
+ *
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ */
+
+#include "dtc.h"
+
+#include <dirent.h>
+#include <sys/stat.h>
+
+static struct node *read_fstree(const char *dirname)
+{
+ DIR *d;
+ struct dirent *de;
+ struct stat st;
+ struct node *tree;
+
+ d = opendir(dirname);
+ if (!d)
+ die("Couldn't opendir() \"%s\": %s\n", dirname, strerror(errno));
+
+ tree = build_node(NULL, NULL);
+
+ while ((de = readdir(d)) != NULL) {
+ char *tmpname;
+
+ if (streq(de->d_name, ".")
+ || streq(de->d_name, ".."))
+ continue;
+
+ tmpname = join_path(dirname, de->d_name);
+
+ if (lstat(tmpname, &st) < 0)
+ die("stat(%s): %s\n", tmpname, strerror(errno));
+
+ if (S_ISREG(st.st_mode)) {
+ struct property *prop;
+ FILE *pfile;
+
+ pfile = fopen(tmpname, "rb");
+ if (! pfile) {
+ fprintf(stderr,
+ "WARNING: Cannot open %s: %s\n",
+ tmpname, strerror(errno));
+ } else {
+ prop = build_property(xstrdup(de->d_name),
+ data_copy_file(pfile,
+ st.st_size));
+ add_property(tree, prop);
+ fclose(pfile);
+ }
+ } else if (S_ISDIR(st.st_mode)) {
+ struct node *newchild;
+
+ newchild = read_fstree(tmpname);
+ newchild = name_node(newchild, xstrdup(de->d_name));
+ add_child(tree, newchild);
+ }
+
+ free(tmpname);
+ }
+
+ closedir(d);
+ return tree;
+}
+
+struct dt_info *dt_from_fs(const char *dirname)
+{
+ struct node *tree;
+
+ tree = read_fstree(dirname);
+ tree = name_node(tree, "");
+
+ return build_dt_info(DTSF_V1, NULL, tree, guess_boot_cpuid(tree));
+}
diff --git a/scripts/dtc/libfdt/Makefile.libfdt b/scripts/dtc/libfdt/Makefile.libfdt
new file mode 100644
index 0000000000..098b3f36e6
--- /dev/null
+++ b/scripts/dtc/libfdt/Makefile.libfdt
@@ -0,0 +1,11 @@
+# Makefile.libfdt
+#
+# This is not a complete Makefile of itself. Instead, it is designed to
+# be easily embeddable into other systems of Makefiles.
+#
+LIBFDT_soname = libfdt.$(SHAREDLIB_EXT).1
+LIBFDT_INCLUDES = fdt.h libfdt.h libfdt_env.h
+LIBFDT_VERSION = version.lds
+LIBFDT_SRCS = fdt.c fdt_ro.c fdt_wip.c fdt_sw.c fdt_rw.c fdt_strerror.c fdt_empty_tree.c \
+ fdt_addresses.c fdt_overlay.c
+LIBFDT_OBJS = $(LIBFDT_SRCS:%.c=%.o)
diff --git a/scripts/dtc/libfdt/fdt.c b/scripts/dtc/libfdt/fdt.c
new file mode 100644
index 0000000000..22286a1aae
--- /dev/null
+++ b/scripts/dtc/libfdt/fdt.c
@@ -0,0 +1,251 @@
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Copyright (C) 2006 David Gibson, IBM Corporation.
+ *
+ * libfdt is dual licensed: you can use it either under the terms of
+ * the GPL, or the BSD license, at your option.
+ *
+ * a) This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Alternatively,
+ *
+ * b) Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "libfdt_env.h"
+
+#include <fdt.h>
+#include <libfdt.h>
+
+#include "libfdt_internal.h"
+
+int fdt_check_header(const void *fdt)
+{
+ if (fdt_magic(fdt) == FDT_MAGIC) {
+ /* Complete tree */
+ if (fdt_version(fdt) < FDT_FIRST_SUPPORTED_VERSION)
+ return -FDT_ERR_BADVERSION;
+ if (fdt_last_comp_version(fdt) > FDT_LAST_SUPPORTED_VERSION)
+ return -FDT_ERR_BADVERSION;
+ } else if (fdt_magic(fdt) == FDT_SW_MAGIC) {
+ /* Unfinished sequential-write blob */
+ if (fdt_size_dt_struct(fdt) == 0)
+ return -FDT_ERR_BADSTATE;
+ } else {
+ return -FDT_ERR_BADMAGIC;
+ }
+
+ return 0;
+}
+
+const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int len)
+{
+ unsigned absoffset = offset + fdt_off_dt_struct(fdt);
+
+ if ((absoffset < offset)
+ || ((absoffset + len) < absoffset)
+ || (absoffset + len) > fdt_totalsize(fdt))
+ return NULL;
+
+ if (fdt_version(fdt) >= 0x11)
+ if (((offset + len) < offset)
+ || ((offset + len) > fdt_size_dt_struct(fdt)))
+ return NULL;
+
+ return _fdt_offset_ptr(fdt, offset);
+}
+
+uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset)
+{
+ const fdt32_t *tagp, *lenp;
+ uint32_t tag;
+ int offset = startoffset;
+ const char *p;
+
+ *nextoffset = -FDT_ERR_TRUNCATED;
+ tagp = fdt_offset_ptr(fdt, offset, FDT_TAGSIZE);
+ if (!tagp)
+ return FDT_END; /* premature end */
+ tag = fdt32_to_cpu(*tagp);
+ offset += FDT_TAGSIZE;
+
+ *nextoffset = -FDT_ERR_BADSTRUCTURE;
+ switch (tag) {
+ case FDT_BEGIN_NODE:
+ /* skip name */
+ do {
+ p = fdt_offset_ptr(fdt, offset++, 1);
+ } while (p && (*p != '\0'));
+ if (!p)
+ return FDT_END; /* premature end */
+ break;
+
+ case FDT_PROP:
+ lenp = fdt_offset_ptr(fdt, offset, sizeof(*lenp));
+ if (!lenp)
+ return FDT_END; /* premature end */
+ /* skip-name offset, length and value */
+ offset += sizeof(struct fdt_property) - FDT_TAGSIZE
+ + fdt32_to_cpu(*lenp);
+ break;
+
+ case FDT_END:
+ case FDT_END_NODE:
+ case FDT_NOP:
+ break;
+
+ default:
+ return FDT_END;
+ }
+
+ if (!fdt_offset_ptr(fdt, startoffset, offset - startoffset))
+ return FDT_END; /* premature end */
+
+ *nextoffset = FDT_TAGALIGN(offset);
+ return tag;
+}
+
+int _fdt_check_node_offset(const void *fdt, int offset)
+{
+ if ((offset < 0) || (offset % FDT_TAGSIZE)
+ || (fdt_next_tag(fdt, offset, &offset) != FDT_BEGIN_NODE))
+ return -FDT_ERR_BADOFFSET;
+
+ return offset;
+}
+
+int _fdt_check_prop_offset(const void *fdt, int offset)
+{
+ if ((offset < 0) || (offset % FDT_TAGSIZE)
+ || (fdt_next_tag(fdt, offset, &offset) != FDT_PROP))
+ return -FDT_ERR_BADOFFSET;
+
+ return offset;
+}
+
+int fdt_next_node(const void *fdt, int offset, int *depth)
+{
+ int nextoffset = 0;
+ uint32_t tag;
+
+ if (offset >= 0)
+ if ((nextoffset = _fdt_check_node_offset(fdt, offset)) < 0)
+ return nextoffset;
+
+ do {
+ offset = nextoffset;
+ tag = fdt_next_tag(fdt, offset, &nextoffset);
+
+ switch (tag) {
+ case FDT_PROP:
+ case FDT_NOP:
+ break;
+
+ case FDT_BEGIN_NODE:
+ if (depth)
+ (*depth)++;
+ break;
+
+ case FDT_END_NODE:
+ if (depth && ((--(*depth)) < 0))
+ return nextoffset;
+ break;
+
+ case FDT_END:
+ if ((nextoffset >= 0)
+ || ((nextoffset == -FDT_ERR_TRUNCATED) && !depth))
+ return -FDT_ERR_NOTFOUND;
+ else
+ return nextoffset;
+ }
+ } while (tag != FDT_BEGIN_NODE);
+
+ return offset;
+}
+
+int fdt_first_subnode(const void *fdt, int offset)
+{
+ int depth = 0;
+
+ offset = fdt_next_node(fdt, offset, &depth);
+ if (offset < 0 || depth != 1)
+ return -FDT_ERR_NOTFOUND;
+
+ return offset;
+}
+
+int fdt_next_subnode(const void *fdt, int offset)
+{
+ int depth = 1;
+
+ /*
+ * With respect to the parent, the depth of the next subnode will be
+ * the same as the last.
+ */
+ do {
+ offset = fdt_next_node(fdt, offset, &depth);
+ if (offset < 0 || depth < 1)
+ return -FDT_ERR_NOTFOUND;
+ } while (depth > 1);
+
+ return offset;
+}
+
+const char *_fdt_find_string(const char *strtab, int tabsize, const char *s)
+{
+ int len = strlen(s) + 1;
+ const char *last = strtab + tabsize - len;
+ const char *p;
+
+ for (p = strtab; p <= last; p++)
+ if (memcmp(p, s, len) == 0)
+ return p;
+ return NULL;
+}
+
+int fdt_move(const void *fdt, void *buf, int bufsize)
+{
+ FDT_CHECK_HEADER(fdt);
+
+ if (fdt_totalsize(fdt) > bufsize)
+ return -FDT_ERR_NOSPACE;
+
+ memmove(buf, fdt, fdt_totalsize(fdt));
+ return 0;
+}
diff --git a/scripts/dtc/libfdt/fdt.h b/scripts/dtc/libfdt/fdt.h
new file mode 100644
index 0000000000..526aedb515
--- /dev/null
+++ b/scripts/dtc/libfdt/fdt.h
@@ -0,0 +1,111 @@
+#ifndef _FDT_H
+#define _FDT_H
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Copyright (C) 2006 David Gibson, IBM Corporation.
+ * Copyright 2012 Kim Phillips, Freescale Semiconductor.
+ *
+ * libfdt is dual licensed: you can use it either under the terms of
+ * the GPL, or the BSD license, at your option.
+ *
+ * a) This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Alternatively,
+ *
+ * b) Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __ASSEMBLY__
+
+struct fdt_header {
+ fdt32_t magic; /* magic word FDT_MAGIC */
+ fdt32_t totalsize; /* total size of DT block */
+ fdt32_t off_dt_struct; /* offset to structure */
+ fdt32_t off_dt_strings; /* offset to strings */
+ fdt32_t off_mem_rsvmap; /* offset to memory reserve map */
+ fdt32_t version; /* format version */
+ fdt32_t last_comp_version; /* last compatible version */
+
+ /* version 2 fields below */
+ fdt32_t boot_cpuid_phys; /* Which physical CPU id we're
+ booting on */
+ /* version 3 fields below */
+ fdt32_t size_dt_strings; /* size of the strings block */
+
+ /* version 17 fields below */
+ fdt32_t size_dt_struct; /* size of the structure block */
+};
+
+struct fdt_reserve_entry {
+ fdt64_t address;
+ fdt64_t size;
+};
+
+struct fdt_node_header {
+ fdt32_t tag;
+ char name[0];
+};
+
+struct fdt_property {
+ fdt32_t tag;
+ fdt32_t len;
+ fdt32_t nameoff;
+ char data[0];
+};
+
+#endif /* !__ASSEMBLY */
+
+#define FDT_MAGIC 0xd00dfeed /* 4: version, 4: total size */
+#define FDT_TAGSIZE sizeof(fdt32_t)
+
+#define FDT_BEGIN_NODE 0x1 /* Start node: full name */
+#define FDT_END_NODE 0x2 /* End node */
+#define FDT_PROP 0x3 /* Property: name off,
+ size, content */
+#define FDT_NOP 0x4 /* nop */
+#define FDT_END 0x9
+
+#define FDT_V1_SIZE (7*sizeof(fdt32_t))
+#define FDT_V2_SIZE (FDT_V1_SIZE + sizeof(fdt32_t))
+#define FDT_V3_SIZE (FDT_V2_SIZE + sizeof(fdt32_t))
+#define FDT_V16_SIZE FDT_V3_SIZE
+#define FDT_V17_SIZE (FDT_V16_SIZE + sizeof(fdt32_t))
+
+#endif /* _FDT_H */
diff --git a/scripts/dtc/libfdt/fdt_empty_tree.c b/scripts/dtc/libfdt/fdt_empty_tree.c
new file mode 100644
index 0000000000..f2ae9b77c2
--- /dev/null
+++ b/scripts/dtc/libfdt/fdt_empty_tree.c
@@ -0,0 +1,83 @@
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Copyright (C) 2012 David Gibson, IBM Corporation.
+ *
+ * libfdt is dual licensed: you can use it either under the terms of
+ * the GPL, or the BSD license, at your option.
+ *
+ * a) This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Alternatively,
+ *
+ * b) Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "libfdt_env.h"
+
+#include <fdt.h>
+#include <libfdt.h>
+
+#include "libfdt_internal.h"
+
+int fdt_create_empty_tree(void *buf, int bufsize)
+{
+ int err;
+
+ err = fdt_create(buf, bufsize);
+ if (err)
+ return err;
+
+ err = fdt_finish_reservemap(buf);
+ if (err)
+ return err;
+
+ err = fdt_begin_node(buf, "");
+ if (err)
+ return err;
+
+ err = fdt_end_node(buf);
+ if (err)
+ return err;
+
+ err = fdt_finish(buf);
+ if (err)
+ return err;
+
+ return fdt_open_into(buf, buf, bufsize);
+}
diff --git a/scripts/dtc/libfdt/fdt_ro.c b/scripts/dtc/libfdt/fdt_ro.c
new file mode 100644
index 0000000000..08de2cce67
--- /dev/null
+++ b/scripts/dtc/libfdt/fdt_ro.c
@@ -0,0 +1,703 @@
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Copyright (C) 2006 David Gibson, IBM Corporation.
+ *
+ * libfdt is dual licensed: you can use it either under the terms of
+ * the GPL, or the BSD license, at your option.
+ *
+ * a) This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Alternatively,
+ *
+ * b) Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "libfdt_env.h"
+
+#include <fdt.h>
+#include <libfdt.h>
+
+#include "libfdt_internal.h"
+
+static int _fdt_nodename_eq(const void *fdt, int offset,
+ const char *s, int len)
+{
+ const char *p = fdt_offset_ptr(fdt, offset + FDT_TAGSIZE, len+1);
+
+ if (!p)
+ /* short match */
+ return 0;
+
+ if (memcmp(p, s, len) != 0)
+ return 0;
+
+ if (p[len] == '\0')
+ return 1;
+ else if (!memchr(s, '@', len) && (p[len] == '@'))
+ return 1;
+ else
+ return 0;
+}
+
+const char *fdt_string(const void *fdt, int stroffset)
+{
+ return (const char *)fdt + fdt_off_dt_strings(fdt) + stroffset;
+}
+
+static int _fdt_string_eq(const void *fdt, int stroffset,
+ const char *s, int len)
+{
+ const char *p = fdt_string(fdt, stroffset);
+
+ return (strlen(p) == len) && (memcmp(p, s, len) == 0);
+}
+
+uint32_t fdt_get_max_phandle(const void *fdt)
+{
+ uint32_t max_phandle = 0;
+ int offset;
+
+ for (offset = fdt_next_node(fdt, -1, NULL);;
+ offset = fdt_next_node(fdt, offset, NULL)) {
+ uint32_t phandle;
+
+ if (offset == -FDT_ERR_NOTFOUND)
+ return max_phandle;
+
+ if (offset < 0)
+ return (uint32_t)-1;
+
+ phandle = fdt_get_phandle(fdt, offset);
+ if (phandle == (uint32_t)-1)
+ continue;
+
+ if (phandle > max_phandle)
+ max_phandle = phandle;
+ }
+
+ return 0;
+}
+
+int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size)
+{
+ FDT_CHECK_HEADER(fdt);
+ *address = fdt64_to_cpu(_fdt_mem_rsv(fdt, n)->address);
+ *size = fdt64_to_cpu(_fdt_mem_rsv(fdt, n)->size);
+ return 0;
+}
+
+int fdt_num_mem_rsv(const void *fdt)
+{
+ int i = 0;
+
+ while (fdt64_to_cpu(_fdt_mem_rsv(fdt, i)->size) != 0)
+ i++;
+ return i;
+}
+
+static int _nextprop(const void *fdt, int offset)
+{
+ uint32_t tag;
+ int nextoffset;
+
+ do {
+ tag = fdt_next_tag(fdt, offset, &nextoffset);
+
+ switch (tag) {
+ case FDT_END:
+ if (nextoffset >= 0)
+ return -FDT_ERR_BADSTRUCTURE;
+ else
+ return nextoffset;
+
+ case FDT_PROP:
+ return offset;
+ }
+ offset = nextoffset;
+ } while (tag == FDT_NOP);
+
+ return -FDT_ERR_NOTFOUND;
+}
+
+int fdt_subnode_offset_namelen(const void *fdt, int offset,
+ const char *name, int namelen)
+{
+ int depth;
+
+ FDT_CHECK_HEADER(fdt);
+
+ for (depth = 0;
+ (offset >= 0) && (depth >= 0);
+ offset = fdt_next_node(fdt, offset, &depth))
+ if ((depth == 1)
+ && _fdt_nodename_eq(fdt, offset, name, namelen))
+ return offset;
+
+ if (depth < 0)
+ return -FDT_ERR_NOTFOUND;
+ return offset; /* error */
+}
+
+int fdt_subnode_offset(const void *fdt, int parentoffset,
+ const char *name)
+{
+ return fdt_subnode_offset_namelen(fdt, parentoffset, name, strlen(name));
+}
+
+int fdt_path_offset_namelen(const void *fdt, const char *path, int namelen)
+{
+ const char *end = path + namelen;
+ const char *p = path;
+ int offset = 0;
+
+ FDT_CHECK_HEADER(fdt);
+
+ /* see if we have an alias */
+ if (*path != '/') {
+ const char *q = memchr(path, '/', end - p);
+
+ if (!q)
+ q = end;
+
+ p = fdt_get_alias_namelen(fdt, p, q - p);
+ if (!p)
+ return -FDT_ERR_BADPATH;
+ offset = fdt_path_offset(fdt, p);
+
+ p = q;
+ }
+
+ while (p < end) {
+ const char *q;
+
+ while (*p == '/') {
+ p++;
+ if (p == end)
+ return offset;
+ }
+ q = memchr(p, '/', end - p);
+ if (! q)
+ q = end;
+
+ offset = fdt_subnode_offset_namelen(fdt, offset, p, q-p);
+ if (offset < 0)
+ return offset;
+
+ p = q;
+ }
+
+ return offset;
+}
+
+int fdt_path_offset(const void *fdt, const char *path)
+{
+ return fdt_path_offset_namelen(fdt, path, strlen(path));
+}
+
+const char *fdt_get_name(const void *fdt, int nodeoffset, int *len)
+{
+ const struct fdt_node_header *nh = _fdt_offset_ptr(fdt, nodeoffset);
+ int err;
+
+ if (((err = fdt_check_header(fdt)) != 0)
+ || ((err = _fdt_check_node_offset(fdt, nodeoffset)) < 0))
+ goto fail;
+
+ if (len)
+ *len = strlen(nh->name);
+
+ return nh->name;
+
+ fail:
+ if (len)
+ *len = err;
+ return NULL;
+}
+
+int fdt_first_property_offset(const void *fdt, int nodeoffset)
+{
+ int offset;
+
+ if ((offset = _fdt_check_node_offset(fdt, nodeoffset)) < 0)
+ return offset;
+
+ return _nextprop(fdt, offset);
+}
+
+int fdt_next_property_offset(const void *fdt, int offset)
+{
+ if ((offset = _fdt_check_prop_offset(fdt, offset)) < 0)
+ return offset;
+
+ return _nextprop(fdt, offset);
+}
+
+const struct fdt_property *fdt_get_property_by_offset(const void *fdt,
+ int offset,
+ int *lenp)
+{
+ int err;
+ const struct fdt_property *prop;
+
+ if ((err = _fdt_check_prop_offset(fdt, offset)) < 0) {
+ if (lenp)
+ *lenp = err;
+ return NULL;
+ }
+
+ prop = _fdt_offset_ptr(fdt, offset);
+
+ if (lenp)
+ *lenp = fdt32_to_cpu(prop->len);
+
+ return prop;
+}
+
+const struct fdt_property *fdt_get_property_namelen(const void *fdt,
+ int offset,
+ const char *name,
+ int namelen, int *lenp)
+{
+ for (offset = fdt_first_property_offset(fdt, offset);
+ (offset >= 0);
+ (offset = fdt_next_property_offset(fdt, offset))) {
+ const struct fdt_property *prop;
+
+ if (!(prop = fdt_get_property_by_offset(fdt, offset, lenp))) {
+ offset = -FDT_ERR_INTERNAL;
+ break;
+ }
+ if (_fdt_string_eq(fdt, fdt32_to_cpu(prop->nameoff),
+ name, namelen))
+ return prop;
+ }
+
+ if (lenp)
+ *lenp = offset;
+ return NULL;
+}
+
+const struct fdt_property *fdt_get_property(const void *fdt,
+ int nodeoffset,
+ const char *name, int *lenp)
+{
+ return fdt_get_property_namelen(fdt, nodeoffset, name,
+ strlen(name), lenp);
+}
+
+const void *fdt_getprop_namelen(const void *fdt, int nodeoffset,
+ const char *name, int namelen, int *lenp)
+{
+ const struct fdt_property *prop;
+
+ prop = fdt_get_property_namelen(fdt, nodeoffset, name, namelen, lenp);
+ if (!prop)
+ return NULL;
+
+ return prop->data;
+}
+
+const void *fdt_getprop_by_offset(const void *fdt, int offset,
+ const char **namep, int *lenp)
+{
+ const struct fdt_property *prop;
+
+ prop = fdt_get_property_by_offset(fdt, offset, lenp);
+ if (!prop)
+ return NULL;
+ if (namep)
+ *namep = fdt_string(fdt, fdt32_to_cpu(prop->nameoff));
+ return prop->data;
+}
+
+const void *fdt_getprop(const void *fdt, int nodeoffset,
+ const char *name, int *lenp)
+{
+ return fdt_getprop_namelen(fdt, nodeoffset, name, strlen(name), lenp);
+}
+
+uint32_t fdt_get_phandle(const void *fdt, int nodeoffset)
+{
+ const fdt32_t *php;
+ int len;
+
+ /* FIXME: This is a bit sub-optimal, since we potentially scan
+ * over all the properties twice. */
+ php = fdt_getprop(fdt, nodeoffset, "phandle", &len);
+ if (!php || (len != sizeof(*php))) {
+ php = fdt_getprop(fdt, nodeoffset, "linux,phandle", &len);
+ if (!php || (len != sizeof(*php)))
+ return 0;
+ }
+
+ return fdt32_to_cpu(*php);
+}
+
+const char *fdt_get_alias_namelen(const void *fdt,
+ const char *name, int namelen)
+{
+ int aliasoffset;
+
+ aliasoffset = fdt_path_offset(fdt, "/aliases");
+ if (aliasoffset < 0)
+ return NULL;
+
+ return fdt_getprop_namelen(fdt, aliasoffset, name, namelen, NULL);
+}
+
+const char *fdt_get_alias(const void *fdt, const char *name)
+{
+ return fdt_get_alias_namelen(fdt, name, strlen(name));
+}
+
+int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen)
+{
+ int pdepth = 0, p = 0;
+ int offset, depth, namelen;
+ const char *name;
+
+ FDT_CHECK_HEADER(fdt);
+
+ if (buflen < 2)
+ return -FDT_ERR_NOSPACE;
+
+ for (offset = 0, depth = 0;
+ (offset >= 0) && (offset <= nodeoffset);
+ offset = fdt_next_node(fdt, offset, &depth)) {
+ while (pdepth > depth) {
+ do {
+ p--;
+ } while (buf[p-1] != '/');
+ pdepth--;
+ }
+
+ if (pdepth >= depth) {
+ name = fdt_get_name(fdt, offset, &namelen);
+ if (!name)
+ return namelen;
+ if ((p + namelen + 1) <= buflen) {
+ memcpy(buf + p, name, namelen);
+ p += namelen;
+ buf[p++] = '/';
+ pdepth++;
+ }
+ }
+
+ if (offset == nodeoffset) {
+ if (pdepth < (depth + 1))
+ return -FDT_ERR_NOSPACE;
+
+ if (p > 1) /* special case so that root path is "/", not "" */
+ p--;
+ buf[p] = '\0';
+ return 0;
+ }
+ }
+
+ if ((offset == -FDT_ERR_NOTFOUND) || (offset >= 0))
+ return -FDT_ERR_BADOFFSET;
+ else if (offset == -FDT_ERR_BADOFFSET)
+ return -FDT_ERR_BADSTRUCTURE;
+
+ return offset; /* error from fdt_next_node() */
+}
+
+int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset,
+ int supernodedepth, int *nodedepth)
+{
+ int offset, depth;
+ int supernodeoffset = -FDT_ERR_INTERNAL;
+
+ FDT_CHECK_HEADER(fdt);
+
+ if (supernodedepth < 0)
+ return -FDT_ERR_NOTFOUND;
+
+ for (offset = 0, depth = 0;
+ (offset >= 0) && (offset <= nodeoffset);
+ offset = fdt_next_node(fdt, offset, &depth)) {
+ if (depth == supernodedepth)
+ supernodeoffset = offset;
+
+ if (offset == nodeoffset) {
+ if (nodedepth)
+ *nodedepth = depth;
+
+ if (supernodedepth > depth)
+ return -FDT_ERR_NOTFOUND;
+ else
+ return supernodeoffset;
+ }
+ }
+
+ if ((offset == -FDT_ERR_NOTFOUND) || (offset >= 0))
+ return -FDT_ERR_BADOFFSET;
+ else if (offset == -FDT_ERR_BADOFFSET)
+ return -FDT_ERR_BADSTRUCTURE;
+
+ return offset; /* error from fdt_next_node() */
+}
+
+int fdt_node_depth(const void *fdt, int nodeoffset)
+{
+ int nodedepth;
+ int err;
+
+ err = fdt_supernode_atdepth_offset(fdt, nodeoffset, 0, &nodedepth);
+ if (err)
+ return (err < 0) ? err : -FDT_ERR_INTERNAL;
+ return nodedepth;
+}
+
+int fdt_parent_offset(const void *fdt, int nodeoffset)
+{
+ int nodedepth = fdt_node_depth(fdt, nodeoffset);
+
+ if (nodedepth < 0)
+ return nodedepth;
+ return fdt_supernode_atdepth_offset(fdt, nodeoffset,
+ nodedepth - 1, NULL);
+}
+
+int fdt_node_offset_by_prop_value(const void *fdt, int startoffset,
+ const char *propname,
+ const void *propval, int proplen)
+{
+ int offset;
+ const void *val;
+ int len;
+
+ FDT_CHECK_HEADER(fdt);
+
+ /* FIXME: The algorithm here is pretty horrible: we scan each
+ * property of a node in fdt_getprop(), then if that didn't
+ * find what we want, we scan over them again making our way
+ * to the next node. Still it's the easiest to implement
+ * approach; performance can come later. */
+ for (offset = fdt_next_node(fdt, startoffset, NULL);
+ offset >= 0;
+ offset = fdt_next_node(fdt, offset, NULL)) {
+ val = fdt_getprop(fdt, offset, propname, &len);
+ if (val && (len == proplen)
+ && (memcmp(val, propval, len) == 0))
+ return offset;
+ }
+
+ return offset; /* error from fdt_next_node() */
+}
+
+int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle)
+{
+ int offset;
+
+ if ((phandle == 0) || (phandle == -1))
+ return -FDT_ERR_BADPHANDLE;
+
+ FDT_CHECK_HEADER(fdt);
+
+ /* FIXME: The algorithm here is pretty horrible: we
+ * potentially scan each property of a node in
+ * fdt_get_phandle(), then if that didn't find what
+ * we want, we scan over them again making our way to the next
+ * node. Still it's the easiest to implement approach;
+ * performance can come later. */
+ for (offset = fdt_next_node(fdt, -1, NULL);
+ offset >= 0;
+ offset = fdt_next_node(fdt, offset, NULL)) {
+ if (fdt_get_phandle(fdt, offset) == phandle)
+ return offset;
+ }
+
+ return offset; /* error from fdt_next_node() */
+}
+
+int fdt_stringlist_contains(const char *strlist, int listlen, const char *str)
+{
+ int len = strlen(str);
+ const char *p;
+
+ while (listlen >= len) {
+ if (memcmp(str, strlist, len+1) == 0)
+ return 1;
+ p = memchr(strlist, '\0', listlen);
+ if (!p)
+ return 0; /* malformed strlist.. */
+ listlen -= (p-strlist) + 1;
+ strlist = p + 1;
+ }
+ return 0;
+}
+
+int fdt_stringlist_count(const void *fdt, int nodeoffset, const char *property)
+{
+ const char *list, *end;
+ int length, count = 0;
+
+ list = fdt_getprop(fdt, nodeoffset, property, &length);
+ if (!list)
+ return length;
+
+ end = list + length;
+
+ while (list < end) {
+ length = strnlen(list, end - list) + 1;
+
+ /* Abort if the last string isn't properly NUL-terminated. */
+ if (list + length > end)
+ return -FDT_ERR_BADVALUE;
+
+ list += length;
+ count++;
+ }
+
+ return count;
+}
+
+int fdt_stringlist_search(const void *fdt, int nodeoffset, const char *property,
+ const char *string)
+{
+ int length, len, idx = 0;
+ const char *list, *end;
+
+ list = fdt_getprop(fdt, nodeoffset, property, &length);
+ if (!list)
+ return length;
+
+ len = strlen(string) + 1;
+ end = list + length;
+
+ while (list < end) {
+ length = strnlen(list, end - list) + 1;
+
+ /* Abort if the last string isn't properly NUL-terminated. */
+ if (list + length > end)
+ return -FDT_ERR_BADVALUE;
+
+ if (length == len && memcmp(list, string, length) == 0)
+ return idx;
+
+ list += length;
+ idx++;
+ }
+
+ return -FDT_ERR_NOTFOUND;
+}
+
+const char *fdt_stringlist_get(const void *fdt, int nodeoffset,
+ const char *property, int idx,
+ int *lenp)
+{
+ const char *list, *end;
+ int length;
+
+ list = fdt_getprop(fdt, nodeoffset, property, &length);
+ if (!list) {
+ if (lenp)
+ *lenp = length;
+
+ return NULL;
+ }
+
+ end = list + length;
+
+ while (list < end) {
+ length = strnlen(list, end - list) + 1;
+
+ /* Abort if the last string isn't properly NUL-terminated. */
+ if (list + length > end) {
+ if (lenp)
+ *lenp = -FDT_ERR_BADVALUE;
+
+ return NULL;
+ }
+
+ if (idx == 0) {
+ if (lenp)
+ *lenp = length - 1;
+
+ return list;
+ }
+
+ list += length;
+ idx--;
+ }
+
+ if (lenp)
+ *lenp = -FDT_ERR_NOTFOUND;
+
+ return NULL;
+}
+
+int fdt_node_check_compatible(const void *fdt, int nodeoffset,
+ const char *compatible)
+{
+ const void *prop;
+ int len;
+
+ prop = fdt_getprop(fdt, nodeoffset, "compatible", &len);
+ if (!prop)
+ return len;
+
+ return !fdt_stringlist_contains(prop, len, compatible);
+}
+
+int fdt_node_offset_by_compatible(const void *fdt, int startoffset,
+ const char *compatible)
+{
+ int offset, err;
+
+ FDT_CHECK_HEADER(fdt);
+
+ /* FIXME: The algorithm here is pretty horrible: we scan each
+ * property of a node in fdt_node_check_compatible(), then if
+ * that didn't find what we want, we scan over them again
+ * making our way to the next node. Still it's the easiest to
+ * implement approach; performance can come later. */
+ for (offset = fdt_next_node(fdt, startoffset, NULL);
+ offset >= 0;
+ offset = fdt_next_node(fdt, offset, NULL)) {
+ err = fdt_node_check_compatible(fdt, offset, compatible);
+ if ((err < 0) && (err != -FDT_ERR_NOTFOUND))
+ return err;
+ else if (err == 0)
+ return offset;
+ }
+
+ return offset; /* error from fdt_next_node() */
+}
diff --git a/scripts/dtc/libfdt/fdt_rw.c b/scripts/dtc/libfdt/fdt_rw.c
new file mode 100644
index 0000000000..5c3a2bb0bc
--- /dev/null
+++ b/scripts/dtc/libfdt/fdt_rw.c
@@ -0,0 +1,505 @@
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Copyright (C) 2006 David Gibson, IBM Corporation.
+ *
+ * libfdt is dual licensed: you can use it either under the terms of
+ * the GPL, or the BSD license, at your option.
+ *
+ * a) This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Alternatively,
+ *
+ * b) Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "libfdt_env.h"
+
+#include <fdt.h>
+#include <libfdt.h>
+
+#include "libfdt_internal.h"
+
+static int _fdt_blocks_misordered(const void *fdt,
+ int mem_rsv_size, int struct_size)
+{
+ return (fdt_off_mem_rsvmap(fdt) < FDT_ALIGN(sizeof(struct fdt_header), 8))
+ || (fdt_off_dt_struct(fdt) <
+ (fdt_off_mem_rsvmap(fdt) + mem_rsv_size))
+ || (fdt_off_dt_strings(fdt) <
+ (fdt_off_dt_struct(fdt) + struct_size))
+ || (fdt_totalsize(fdt) <
+ (fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt)));
+}
+
+static int _fdt_rw_check_header(void *fdt)
+{
+ FDT_CHECK_HEADER(fdt);
+
+ if (fdt_version(fdt) < 17)
+ return -FDT_ERR_BADVERSION;
+ if (_fdt_blocks_misordered(fdt, sizeof(struct fdt_reserve_entry),
+ fdt_size_dt_struct(fdt)))
+ return -FDT_ERR_BADLAYOUT;
+ if (fdt_version(fdt) > 17)
+ fdt_set_version(fdt, 17);
+
+ return 0;
+}
+
+#define FDT_RW_CHECK_HEADER(fdt) \
+ { \
+ int __err; \
+ if ((__err = _fdt_rw_check_header(fdt)) != 0) \
+ return __err; \
+ }
+
+static inline int _fdt_data_size(void *fdt)
+{
+ return fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt);
+}
+
+static int _fdt_splice(void *fdt, void *splicepoint, int oldlen, int newlen)
+{
+ char *p = splicepoint;
+ char *end = (char *)fdt + _fdt_data_size(fdt);
+
+ if (((p + oldlen) < p) || ((p + oldlen) > end))
+ return -FDT_ERR_BADOFFSET;
+ if ((p < (char *)fdt) || ((end - oldlen + newlen) < (char *)fdt))
+ return -FDT_ERR_BADOFFSET;
+ if ((end - oldlen + newlen) > ((char *)fdt + fdt_totalsize(fdt)))
+ return -FDT_ERR_NOSPACE;
+ memmove(p + newlen, p + oldlen, end - p - oldlen);
+ return 0;
+}
+
+static int _fdt_splice_mem_rsv(void *fdt, struct fdt_reserve_entry *p,
+ int oldn, int newn)
+{
+ int delta = (newn - oldn) * sizeof(*p);
+ int err;
+ err = _fdt_splice(fdt, p, oldn * sizeof(*p), newn * sizeof(*p));
+ if (err)
+ return err;
+ fdt_set_off_dt_struct(fdt, fdt_off_dt_struct(fdt) + delta);
+ fdt_set_off_dt_strings(fdt, fdt_off_dt_strings(fdt) + delta);
+ return 0;
+}
+
+static int _fdt_splice_struct(void *fdt, void *p,
+ int oldlen, int newlen)
+{
+ int delta = newlen - oldlen;
+ int err;
+
+ if ((err = _fdt_splice(fdt, p, oldlen, newlen)))
+ return err;
+
+ fdt_set_size_dt_struct(fdt, fdt_size_dt_struct(fdt) + delta);
+ fdt_set_off_dt_strings(fdt, fdt_off_dt_strings(fdt) + delta);
+ return 0;
+}
+
+static int _fdt_splice_string(void *fdt, int newlen)
+{
+ void *p = (char *)fdt
+ + fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt);
+ int err;
+
+ if ((err = _fdt_splice(fdt, p, 0, newlen)))
+ return err;
+
+ fdt_set_size_dt_strings(fdt, fdt_size_dt_strings(fdt) + newlen);
+ return 0;
+}
+
+static int _fdt_find_add_string(void *fdt, const char *s)
+{
+ char *strtab = (char *)fdt + fdt_off_dt_strings(fdt);
+ const char *p;
+ char *new;
+ int len = strlen(s) + 1;
+ int err;
+
+ p = _fdt_find_string(strtab, fdt_size_dt_strings(fdt), s);
+ if (p)
+ /* found it */
+ return (p - strtab);
+
+ new = strtab + fdt_size_dt_strings(fdt);
+ err = _fdt_splice_string(fdt, len);
+ if (err)
+ return err;
+
+ memcpy(new, s, len);
+ return (new - strtab);
+}
+
+int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size)
+{
+ struct fdt_reserve_entry *re;
+ int err;
+
+ FDT_RW_CHECK_HEADER(fdt);
+
+ re = _fdt_mem_rsv_w(fdt, fdt_num_mem_rsv(fdt));
+ err = _fdt_splice_mem_rsv(fdt, re, 0, 1);
+ if (err)
+ return err;
+
+ re->address = cpu_to_fdt64(address);
+ re->size = cpu_to_fdt64(size);
+ return 0;
+}
+
+int fdt_del_mem_rsv(void *fdt, int n)
+{
+ struct fdt_reserve_entry *re = _fdt_mem_rsv_w(fdt, n);
+
+ FDT_RW_CHECK_HEADER(fdt);
+
+ if (n >= fdt_num_mem_rsv(fdt))
+ return -FDT_ERR_NOTFOUND;
+
+ return _fdt_splice_mem_rsv(fdt, re, 1, 0);
+}
+
+static int _fdt_resize_property(void *fdt, int nodeoffset, const char *name,
+ int len, struct fdt_property **prop)
+{
+ int oldlen;
+ int err;
+
+ *prop = fdt_get_property_w(fdt, nodeoffset, name, &oldlen);
+ if (!*prop)
+ return oldlen;
+
+ if ((err = _fdt_splice_struct(fdt, (*prop)->data, FDT_TAGALIGN(oldlen),
+ FDT_TAGALIGN(len))))
+ return err;
+
+ (*prop)->len = cpu_to_fdt32(len);
+ return 0;
+}
+
+static int _fdt_add_property(void *fdt, int nodeoffset, const char *name,
+ int len, struct fdt_property **prop)
+{
+ int proplen;
+ int nextoffset;
+ int namestroff;
+ int err;
+
+ if ((nextoffset = _fdt_check_node_offset(fdt, nodeoffset)) < 0)
+ return nextoffset;
+
+ namestroff = _fdt_find_add_string(fdt, name);
+ if (namestroff < 0)
+ return namestroff;
+
+ *prop = _fdt_offset_ptr_w(fdt, nextoffset);
+ proplen = sizeof(**prop) + FDT_TAGALIGN(len);
+
+ err = _fdt_splice_struct(fdt, *prop, 0, proplen);
+ if (err)
+ return err;
+
+ (*prop)->tag = cpu_to_fdt32(FDT_PROP);
+ (*prop)->nameoff = cpu_to_fdt32(namestroff);
+ (*prop)->len = cpu_to_fdt32(len);
+ return 0;
+}
+
+int fdt_set_name(void *fdt, int nodeoffset, const char *name)
+{
+ char *namep;
+ int oldlen, newlen;
+ int err;
+
+ FDT_RW_CHECK_HEADER(fdt);
+
+ namep = (char *)(uintptr_t)fdt_get_name(fdt, nodeoffset, &oldlen);
+ if (!namep)
+ return oldlen;
+
+ newlen = strlen(name);
+
+ err = _fdt_splice_struct(fdt, namep, FDT_TAGALIGN(oldlen+1),
+ FDT_TAGALIGN(newlen+1));
+ if (err)
+ return err;
+
+ memcpy(namep, name, newlen+1);
+ return 0;
+}
+
+int fdt_setprop_placeholder(void *fdt, int nodeoffset, const char *name,
+ int len, void **prop_data)
+{
+ struct fdt_property *prop;
+ int err;
+
+ FDT_RW_CHECK_HEADER(fdt);
+
+ err = _fdt_resize_property(fdt, nodeoffset, name, len, &prop);
+ if (err == -FDT_ERR_NOTFOUND)
+ err = _fdt_add_property(fdt, nodeoffset, name, len, &prop);
+ if (err)
+ return err;
+
+ *prop_data = prop->data;
+ return 0;
+}
+
+int fdt_setprop(void *fdt, int nodeoffset, const char *name,
+ const void *val, int len)
+{
+ void *prop_data;
+ int err;
+
+ err = fdt_setprop_placeholder(fdt, nodeoffset, name, len, &prop_data);
+ if (err)
+ return err;
+
+ if (len)
+ memcpy(prop_data, val, len);
+ return 0;
+}
+
+int fdt_appendprop(void *fdt, int nodeoffset, const char *name,
+ const void *val, int len)
+{
+ struct fdt_property *prop;
+ int err, oldlen, newlen;
+
+ FDT_RW_CHECK_HEADER(fdt);
+
+ prop = fdt_get_property_w(fdt, nodeoffset, name, &oldlen);
+ if (prop) {
+ newlen = len + oldlen;
+ err = _fdt_splice_struct(fdt, prop->data,
+ FDT_TAGALIGN(oldlen),
+ FDT_TAGALIGN(newlen));
+ if (err)
+ return err;
+ prop->len = cpu_to_fdt32(newlen);
+ memcpy(prop->data + oldlen, val, len);
+ } else {
+ err = _fdt_add_property(fdt, nodeoffset, name, len, &prop);
+ if (err)
+ return err;
+ memcpy(prop->data, val, len);
+ }
+ return 0;
+}
+
+int fdt_delprop(void *fdt, int nodeoffset, const char *name)
+{
+ struct fdt_property *prop;
+ int len, proplen;
+
+ FDT_RW_CHECK_HEADER(fdt);
+
+ prop = fdt_get_property_w(fdt, nodeoffset, name, &len);
+ if (!prop)
+ return len;
+
+ proplen = sizeof(*prop) + FDT_TAGALIGN(len);
+ return _fdt_splice_struct(fdt, prop, proplen, 0);
+}
+
+int fdt_add_subnode_namelen(void *fdt, int parentoffset,
+ const char *name, int namelen)
+{
+ struct fdt_node_header *nh;
+ int offset, nextoffset;
+ int nodelen;
+ int err;
+ uint32_t tag;
+ fdt32_t *endtag;
+
+ FDT_RW_CHECK_HEADER(fdt);
+
+ offset = fdt_subnode_offset_namelen(fdt, parentoffset, name, namelen);
+ if (offset >= 0)
+ return -FDT_ERR_EXISTS;
+ else if (offset != -FDT_ERR_NOTFOUND)
+ return offset;
+
+ /* Try to place the new node after the parent's properties */
+ fdt_next_tag(fdt, parentoffset, &nextoffset); /* skip the BEGIN_NODE */
+ do {
+ offset = nextoffset;
+ tag = fdt_next_tag(fdt, offset, &nextoffset);
+ } while ((tag == FDT_PROP) || (tag == FDT_NOP));
+
+ nh = _fdt_offset_ptr_w(fdt, offset);
+ nodelen = sizeof(*nh) + FDT_TAGALIGN(namelen+1) + FDT_TAGSIZE;
+
+ err = _fdt_splice_struct(fdt, nh, 0, nodelen);
+ if (err)
+ return err;
+
+ nh->tag = cpu_to_fdt32(FDT_BEGIN_NODE);
+ memset(nh->name, 0, FDT_TAGALIGN(namelen+1));
+ memcpy(nh->name, name, namelen);
+ endtag = (fdt32_t *)((char *)nh + nodelen - FDT_TAGSIZE);
+ *endtag = cpu_to_fdt32(FDT_END_NODE);
+
+ return offset;
+}
+
+int fdt_add_subnode(void *fdt, int parentoffset, const char *name)
+{
+ return fdt_add_subnode_namelen(fdt, parentoffset, name, strlen(name));
+}
+
+int fdt_del_node(void *fdt, int nodeoffset)
+{
+ int endoffset;
+
+ FDT_RW_CHECK_HEADER(fdt);
+
+ endoffset = _fdt_node_end_offset(fdt, nodeoffset);
+ if (endoffset < 0)
+ return endoffset;
+
+ return _fdt_splice_struct(fdt, _fdt_offset_ptr_w(fdt, nodeoffset),
+ endoffset - nodeoffset, 0);
+}
+
+static void _fdt_packblocks(const char *old, char *new,
+ int mem_rsv_size, int struct_size)
+{
+ int mem_rsv_off, struct_off, strings_off;
+
+ mem_rsv_off = FDT_ALIGN(sizeof(struct fdt_header), 8);
+ struct_off = mem_rsv_off + mem_rsv_size;
+ strings_off = struct_off + struct_size;
+
+ memmove(new + mem_rsv_off, old + fdt_off_mem_rsvmap(old), mem_rsv_size);
+ fdt_set_off_mem_rsvmap(new, mem_rsv_off);
+
+ memmove(new + struct_off, old + fdt_off_dt_struct(old), struct_size);
+ fdt_set_off_dt_struct(new, struct_off);
+ fdt_set_size_dt_struct(new, struct_size);
+
+ memmove(new + strings_off, old + fdt_off_dt_strings(old),
+ fdt_size_dt_strings(old));
+ fdt_set_off_dt_strings(new, strings_off);
+ fdt_set_size_dt_strings(new, fdt_size_dt_strings(old));
+}
+
+int fdt_open_into(const void *fdt, void *buf, int bufsize)
+{
+ int err;
+ int mem_rsv_size, struct_size;
+ int newsize;
+ const char *fdtstart = fdt;
+ const char *fdtend = fdtstart + fdt_totalsize(fdt);
+ char *tmp;
+
+ FDT_CHECK_HEADER(fdt);
+
+ mem_rsv_size = (fdt_num_mem_rsv(fdt)+1)
+ * sizeof(struct fdt_reserve_entry);
+
+ if (fdt_version(fdt) >= 17) {
+ struct_size = fdt_size_dt_struct(fdt);
+ } else {
+ struct_size = 0;
+ while (fdt_next_tag(fdt, struct_size, &struct_size) != FDT_END)
+ ;
+ if (struct_size < 0)
+ return struct_size;
+ }
+
+ if (!_fdt_blocks_misordered(fdt, mem_rsv_size, struct_size)) {
+ /* no further work necessary */
+ err = fdt_move(fdt, buf, bufsize);
+ if (err)
+ return err;
+ fdt_set_version(buf, 17);
+ fdt_set_size_dt_struct(buf, struct_size);
+ fdt_set_totalsize(buf, bufsize);
+ return 0;
+ }
+
+ /* Need to reorder */
+ newsize = FDT_ALIGN(sizeof(struct fdt_header), 8) + mem_rsv_size
+ + struct_size + fdt_size_dt_strings(fdt);
+
+ if (bufsize < newsize)
+ return -FDT_ERR_NOSPACE;
+
+ /* First attempt to build converted tree at beginning of buffer */
+ tmp = buf;
+ /* But if that overlaps with the old tree... */
+ if (((tmp + newsize) > fdtstart) && (tmp < fdtend)) {
+ /* Try right after the old tree instead */
+ tmp = (char *)(uintptr_t)fdtend;
+ if ((tmp + newsize) > ((char *)buf + bufsize))
+ return -FDT_ERR_NOSPACE;
+ }
+
+ _fdt_packblocks(fdt, tmp, mem_rsv_size, struct_size);
+ memmove(buf, tmp, newsize);
+
+ fdt_set_magic(buf, FDT_MAGIC);
+ fdt_set_totalsize(buf, bufsize);
+ fdt_set_version(buf, 17);
+ fdt_set_last_comp_version(buf, 16);
+ fdt_set_boot_cpuid_phys(buf, fdt_boot_cpuid_phys(fdt));
+
+ return 0;
+}
+
+int fdt_pack(void *fdt)
+{
+ int mem_rsv_size;
+
+ FDT_RW_CHECK_HEADER(fdt);
+
+ mem_rsv_size = (fdt_num_mem_rsv(fdt)+1)
+ * sizeof(struct fdt_reserve_entry);
+ _fdt_packblocks(fdt, fdt, mem_rsv_size, fdt_size_dt_struct(fdt));
+ fdt_set_totalsize(fdt, _fdt_data_size(fdt));
+
+ return 0;
+}
diff --git a/scripts/dtc/libfdt/fdt_strerror.c b/scripts/dtc/libfdt/fdt_strerror.c
new file mode 100644
index 0000000000..9677a1887e
--- /dev/null
+++ b/scripts/dtc/libfdt/fdt_strerror.c
@@ -0,0 +1,102 @@
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Copyright (C) 2006 David Gibson, IBM Corporation.
+ *
+ * libfdt is dual licensed: you can use it either under the terms of
+ * the GPL, or the BSD license, at your option.
+ *
+ * a) This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Alternatively,
+ *
+ * b) Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "libfdt_env.h"
+
+#include <fdt.h>
+#include <libfdt.h>
+
+#include "libfdt_internal.h"
+
+struct fdt_errtabent {
+ const char *str;
+};
+
+#define FDT_ERRTABENT(val) \
+ [(val)] = { .str = #val, }
+
+static struct fdt_errtabent fdt_errtable[] = {
+ FDT_ERRTABENT(FDT_ERR_NOTFOUND),
+ FDT_ERRTABENT(FDT_ERR_EXISTS),
+ FDT_ERRTABENT(FDT_ERR_NOSPACE),
+
+ FDT_ERRTABENT(FDT_ERR_BADOFFSET),
+ FDT_ERRTABENT(FDT_ERR_BADPATH),
+ FDT_ERRTABENT(FDT_ERR_BADPHANDLE),
+ FDT_ERRTABENT(FDT_ERR_BADSTATE),
+
+ FDT_ERRTABENT(FDT_ERR_TRUNCATED),
+ FDT_ERRTABENT(FDT_ERR_BADMAGIC),
+ FDT_ERRTABENT(FDT_ERR_BADVERSION),
+ FDT_ERRTABENT(FDT_ERR_BADSTRUCTURE),
+ FDT_ERRTABENT(FDT_ERR_BADLAYOUT),
+ FDT_ERRTABENT(FDT_ERR_INTERNAL),
+ FDT_ERRTABENT(FDT_ERR_BADNCELLS),
+ FDT_ERRTABENT(FDT_ERR_BADVALUE),
+ FDT_ERRTABENT(FDT_ERR_BADOVERLAY),
+ FDT_ERRTABENT(FDT_ERR_NOPHANDLES),
+};
+#define FDT_ERRTABSIZE (sizeof(fdt_errtable) / sizeof(fdt_errtable[0]))
+
+const char *fdt_strerror(int errval)
+{
+ if (errval > 0)
+ return "<valid offset/length>";
+ else if (errval == 0)
+ return "<no error>";
+ else if (errval > -FDT_ERRTABSIZE) {
+ const char *s = fdt_errtable[-errval].str;
+
+ if (s)
+ return s;
+ }
+
+ return "<unknown error>";
+}
diff --git a/scripts/dtc/libfdt/fdt_sw.c b/scripts/dtc/libfdt/fdt_sw.c
new file mode 100644
index 0000000000..2bd15e7aef
--- /dev/null
+++ b/scripts/dtc/libfdt/fdt_sw.c
@@ -0,0 +1,300 @@
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Copyright (C) 2006 David Gibson, IBM Corporation.
+ *
+ * libfdt is dual licensed: you can use it either under the terms of
+ * the GPL, or the BSD license, at your option.
+ *
+ * a) This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Alternatively,
+ *
+ * b) Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "libfdt_env.h"
+
+#include <fdt.h>
+#include <libfdt.h>
+
+#include "libfdt_internal.h"
+
+static int _fdt_sw_check_header(void *fdt)
+{
+ if (fdt_magic(fdt) != FDT_SW_MAGIC)
+ return -FDT_ERR_BADMAGIC;
+ /* FIXME: should check more details about the header state */
+ return 0;
+}
+
+#define FDT_SW_CHECK_HEADER(fdt) \
+ { \
+ int err; \
+ if ((err = _fdt_sw_check_header(fdt)) != 0) \
+ return err; \
+ }
+
+static void *_fdt_grab_space(void *fdt, size_t len)
+{
+ int offset = fdt_size_dt_struct(fdt);
+ int spaceleft;
+
+ spaceleft = fdt_totalsize(fdt) - fdt_off_dt_struct(fdt)
+ - fdt_size_dt_strings(fdt);
+
+ if ((offset + len < offset) || (offset + len > spaceleft))
+ return NULL;
+
+ fdt_set_size_dt_struct(fdt, offset + len);
+ return _fdt_offset_ptr_w(fdt, offset);
+}
+
+int fdt_create(void *buf, int bufsize)
+{
+ void *fdt = buf;
+
+ if (bufsize < sizeof(struct fdt_header))
+ return -FDT_ERR_NOSPACE;
+
+ memset(buf, 0, bufsize);
+
+ fdt_set_magic(fdt, FDT_SW_MAGIC);
+ fdt_set_version(fdt, FDT_LAST_SUPPORTED_VERSION);
+ fdt_set_last_comp_version(fdt, FDT_FIRST_SUPPORTED_VERSION);
+ fdt_set_totalsize(fdt, bufsize);
+
+ fdt_set_off_mem_rsvmap(fdt, FDT_ALIGN(sizeof(struct fdt_header),
+ sizeof(struct fdt_reserve_entry)));
+ fdt_set_off_dt_struct(fdt, fdt_off_mem_rsvmap(fdt));
+ fdt_set_off_dt_strings(fdt, bufsize);
+
+ return 0;
+}
+
+int fdt_resize(void *fdt, void *buf, int bufsize)
+{
+ size_t headsize, tailsize;
+ char *oldtail, *newtail;
+
+ FDT_SW_CHECK_HEADER(fdt);
+
+ headsize = fdt_off_dt_struct(fdt);
+ tailsize = fdt_size_dt_strings(fdt);
+
+ if ((headsize + tailsize) > bufsize)
+ return -FDT_ERR_NOSPACE;
+
+ oldtail = (char *)fdt + fdt_totalsize(fdt) - tailsize;
+ newtail = (char *)buf + bufsize - tailsize;
+
+ /* Two cases to avoid clobbering data if the old and new
+ * buffers partially overlap */
+ if (buf <= fdt) {
+ memmove(buf, fdt, headsize);
+ memmove(newtail, oldtail, tailsize);
+ } else {
+ memmove(newtail, oldtail, tailsize);
+ memmove(buf, fdt, headsize);
+ }
+
+ fdt_set_off_dt_strings(buf, bufsize);
+ fdt_set_totalsize(buf, bufsize);
+
+ return 0;
+}
+
+int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size)
+{
+ struct fdt_reserve_entry *re;
+ int offset;
+
+ FDT_SW_CHECK_HEADER(fdt);
+
+ if (fdt_size_dt_struct(fdt))
+ return -FDT_ERR_BADSTATE;
+
+ offset = fdt_off_dt_struct(fdt);
+ if ((offset + sizeof(*re)) > fdt_totalsize(fdt))
+ return -FDT_ERR_NOSPACE;
+
+ re = (struct fdt_reserve_entry *)((char *)fdt + offset);
+ re->address = cpu_to_fdt64(addr);
+ re->size = cpu_to_fdt64(size);
+
+ fdt_set_off_dt_struct(fdt, offset + sizeof(*re));
+
+ return 0;
+}
+
+int fdt_finish_reservemap(void *fdt)
+{
+ return fdt_add_reservemap_entry(fdt, 0, 0);
+}
+
+int fdt_begin_node(void *fdt, const char *name)
+{
+ struct fdt_node_header *nh;
+ int namelen = strlen(name) + 1;
+
+ FDT_SW_CHECK_HEADER(fdt);
+
+ nh = _fdt_grab_space(fdt, sizeof(*nh) + FDT_TAGALIGN(namelen));
+ if (! nh)
+ return -FDT_ERR_NOSPACE;
+
+ nh->tag = cpu_to_fdt32(FDT_BEGIN_NODE);
+ memcpy(nh->name, name, namelen);
+ return 0;
+}
+
+int fdt_end_node(void *fdt)
+{
+ fdt32_t *en;
+
+ FDT_SW_CHECK_HEADER(fdt);
+
+ en = _fdt_grab_space(fdt, FDT_TAGSIZE);
+ if (! en)
+ return -FDT_ERR_NOSPACE;
+
+ *en = cpu_to_fdt32(FDT_END_NODE);
+ return 0;
+}
+
+static int _fdt_find_add_string(void *fdt, const char *s)
+{
+ char *strtab = (char *)fdt + fdt_totalsize(fdt);
+ const char *p;
+ int strtabsize = fdt_size_dt_strings(fdt);
+ int len = strlen(s) + 1;
+ int struct_top, offset;
+
+ p = _fdt_find_string(strtab - strtabsize, strtabsize, s);
+ if (p)
+ return p - strtab;
+
+ /* Add it */
+ offset = -strtabsize - len;
+ struct_top = fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt);
+ if (fdt_totalsize(fdt) + offset < struct_top)
+ return 0; /* no more room :( */
+
+ memcpy(strtab + offset, s, len);
+ fdt_set_size_dt_strings(fdt, strtabsize + len);
+ return offset;
+}
+
+int fdt_property_placeholder(void *fdt, const char *name, int len, void **valp)
+{
+ struct fdt_property *prop;
+ int nameoff;
+
+ FDT_SW_CHECK_HEADER(fdt);
+
+ nameoff = _fdt_find_add_string(fdt, name);
+ if (nameoff == 0)
+ return -FDT_ERR_NOSPACE;
+
+ prop = _fdt_grab_space(fdt, sizeof(*prop) + FDT_TAGALIGN(len));
+ if (! prop)
+ return -FDT_ERR_NOSPACE;
+
+ prop->tag = cpu_to_fdt32(FDT_PROP);
+ prop->nameoff = cpu_to_fdt32(nameoff);
+ prop->len = cpu_to_fdt32(len);
+ *valp = prop->data;
+ return 0;
+}
+
+int fdt_property(void *fdt, const char *name, const void *val, int len)
+{
+ void *ptr;
+ int ret;
+
+ ret = fdt_property_placeholder(fdt, name, len, &ptr);
+ if (ret)
+ return ret;
+ memcpy(ptr, val, len);
+ return 0;
+}
+
+int fdt_finish(void *fdt)
+{
+ char *p = (char *)fdt;
+ fdt32_t *end;
+ int oldstroffset, newstroffset;
+ uint32_t tag;
+ int offset, nextoffset;
+
+ FDT_SW_CHECK_HEADER(fdt);
+
+ /* Add terminator */
+ end = _fdt_grab_space(fdt, sizeof(*end));
+ if (! end)
+ return -FDT_ERR_NOSPACE;
+ *end = cpu_to_fdt32(FDT_END);
+
+ /* Relocate the string table */
+ oldstroffset = fdt_totalsize(fdt) - fdt_size_dt_strings(fdt);
+ newstroffset = fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt);
+ memmove(p + newstroffset, p + oldstroffset, fdt_size_dt_strings(fdt));
+ fdt_set_off_dt_strings(fdt, newstroffset);
+
+ /* Walk the structure, correcting string offsets */
+ offset = 0;
+ while ((tag = fdt_next_tag(fdt, offset, &nextoffset)) != FDT_END) {
+ if (tag == FDT_PROP) {
+ struct fdt_property *prop =
+ _fdt_offset_ptr_w(fdt, offset);
+ int nameoff;
+
+ nameoff = fdt32_to_cpu(prop->nameoff);
+ nameoff += fdt_size_dt_strings(fdt);
+ prop->nameoff = cpu_to_fdt32(nameoff);
+ }
+ offset = nextoffset;
+ }
+ if (nextoffset < 0)
+ return nextoffset;
+
+ /* Finally, adjust the header */
+ fdt_set_totalsize(fdt, newstroffset + fdt_size_dt_strings(fdt));
+ fdt_set_magic(fdt, FDT_MAGIC);
+ return 0;
+}
diff --git a/scripts/dtc/libfdt/fdt_wip.c b/scripts/dtc/libfdt/fdt_wip.c
new file mode 100644
index 0000000000..5e85919862
--- /dev/null
+++ b/scripts/dtc/libfdt/fdt_wip.c
@@ -0,0 +1,139 @@
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Copyright (C) 2006 David Gibson, IBM Corporation.
+ *
+ * libfdt is dual licensed: you can use it either under the terms of
+ * the GPL, or the BSD license, at your option.
+ *
+ * a) This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Alternatively,
+ *
+ * b) Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "libfdt_env.h"
+
+#include <fdt.h>
+#include <libfdt.h>
+
+#include "libfdt_internal.h"
+
+int fdt_setprop_inplace_namelen_partial(void *fdt, int nodeoffset,
+ const char *name, int namelen,
+ uint32_t idx, const void *val,
+ int len)
+{
+ void *propval;
+ int proplen;
+
+ propval = fdt_getprop_namelen_w(fdt, nodeoffset, name, namelen,
+ &proplen);
+ if (!propval)
+ return proplen;
+
+ if (proplen < (len + idx))
+ return -FDT_ERR_NOSPACE;
+
+ memcpy((char *)propval + idx, val, len);
+ return 0;
+}
+
+int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,
+ const void *val, int len)
+{
+ const void *propval;
+ int proplen;
+
+ propval = fdt_getprop(fdt, nodeoffset, name, &proplen);
+ if (!propval)
+ return proplen;
+
+ if (proplen != len)
+ return -FDT_ERR_NOSPACE;
+
+ return fdt_setprop_inplace_namelen_partial(fdt, nodeoffset, name,
+ strlen(name), 0,
+ val, len);
+}
+
+static void _fdt_nop_region(void *start, int len)
+{
+ fdt32_t *p;
+
+ for (p = start; (char *)p < ((char *)start + len); p++)
+ *p = cpu_to_fdt32(FDT_NOP);
+}
+
+int fdt_nop_property(void *fdt, int nodeoffset, const char *name)
+{
+ struct fdt_property *prop;
+ int len;
+
+ prop = fdt_get_property_w(fdt, nodeoffset, name, &len);
+ if (!prop)
+ return len;
+
+ _fdt_nop_region(prop, len + sizeof(*prop));
+
+ return 0;
+}
+
+int _fdt_node_end_offset(void *fdt, int offset)
+{
+ int depth = 0;
+
+ while ((offset >= 0) && (depth >= 0))
+ offset = fdt_next_node(fdt, offset, &depth);
+
+ return offset;
+}
+
+int fdt_nop_node(void *fdt, int nodeoffset)
+{
+ int endoffset;
+
+ endoffset = _fdt_node_end_offset(fdt, nodeoffset);
+ if (endoffset < 0)
+ return endoffset;
+
+ _fdt_nop_region(fdt_offset_ptr_w(fdt, nodeoffset, 0),
+ endoffset - nodeoffset);
+ return 0;
+}
diff --git a/scripts/dtc/libfdt/libfdt.h b/scripts/dtc/libfdt/libfdt.h
new file mode 100644
index 0000000000..7f83023ee1
--- /dev/null
+++ b/scripts/dtc/libfdt/libfdt.h
@@ -0,0 +1,1899 @@
+#ifndef _LIBFDT_H
+#define _LIBFDT_H
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Copyright (C) 2006 David Gibson, IBM Corporation.
+ *
+ * libfdt is dual licensed: you can use it either under the terms of
+ * the GPL, or the BSD license, at your option.
+ *
+ * a) This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Alternatively,
+ *
+ * b) Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "libfdt_env.h"
+#include "fdt.h"
+
+#define FDT_FIRST_SUPPORTED_VERSION 0x10
+#define FDT_LAST_SUPPORTED_VERSION 0x11
+
+/* Error codes: informative error codes */
+#define FDT_ERR_NOTFOUND 1
+ /* FDT_ERR_NOTFOUND: The requested node or property does not exist */
+#define FDT_ERR_EXISTS 2
+ /* FDT_ERR_EXISTS: Attempted to create a node or property which
+ * already exists */
+#define FDT_ERR_NOSPACE 3
+ /* FDT_ERR_NOSPACE: Operation needed to expand the device
+ * tree, but its buffer did not have sufficient space to
+ * contain the expanded tree. Use fdt_open_into() to move the
+ * device tree to a buffer with more space. */
+
+/* Error codes: codes for bad parameters */
+#define FDT_ERR_BADOFFSET 4
+ /* FDT_ERR_BADOFFSET: Function was passed a structure block
+ * offset which is out-of-bounds, or which points to an
+ * unsuitable part of the structure for the operation. */
+#define FDT_ERR_BADPATH 5
+ /* FDT_ERR_BADPATH: Function was passed a badly formatted path
+ * (e.g. missing a leading / for a function which requires an
+ * absolute path) */
+#define FDT_ERR_BADPHANDLE 6
+ /* FDT_ERR_BADPHANDLE: Function was passed an invalid phandle.
+ * This can be caused either by an invalid phandle property
+ * length, or the phandle value was either 0 or -1, which are
+ * not permitted. */
+#define FDT_ERR_BADSTATE 7
+ /* FDT_ERR_BADSTATE: Function was passed an incomplete device
+ * tree created by the sequential-write functions, which is
+ * not sufficiently complete for the requested operation. */
+
+/* Error codes: codes for bad device tree blobs */
+#define FDT_ERR_TRUNCATED 8
+ /* FDT_ERR_TRUNCATED: Structure block of the given device tree
+ * ends without an FDT_END tag. */
+#define FDT_ERR_BADMAGIC 9
+ /* FDT_ERR_BADMAGIC: Given "device tree" appears not to be a
+ * device tree at all - it is missing the flattened device
+ * tree magic number. */
+#define FDT_ERR_BADVERSION 10
+ /* FDT_ERR_BADVERSION: Given device tree has a version which
+ * can't be handled by the requested operation. For
+ * read-write functions, this may mean that fdt_open_into() is
+ * required to convert the tree to the expected version. */
+#define FDT_ERR_BADSTRUCTURE 11
+ /* FDT_ERR_BADSTRUCTURE: Given device tree has a corrupt
+ * structure block or other serious error (e.g. misnested
+ * nodes, or subnodes preceding properties). */
+#define FDT_ERR_BADLAYOUT 12
+ /* FDT_ERR_BADLAYOUT: For read-write functions, the given
+ * device tree has it's sub-blocks in an order that the
+ * function can't handle (memory reserve map, then structure,
+ * then strings). Use fdt_open_into() to reorganize the tree
+ * into a form suitable for the read-write operations. */
+
+/* "Can't happen" error indicating a bug in libfdt */
+#define FDT_ERR_INTERNAL 13
+ /* FDT_ERR_INTERNAL: libfdt has failed an internal assertion.
+ * Should never be returned, if it is, it indicates a bug in
+ * libfdt itself. */
+
+/* Errors in device tree content */
+#define FDT_ERR_BADNCELLS 14
+ /* FDT_ERR_BADNCELLS: Device tree has a #address-cells, #size-cells
+ * or similar property with a bad format or value */
+
+#define FDT_ERR_BADVALUE 15
+ /* FDT_ERR_BADVALUE: Device tree has a property with an unexpected
+ * value. For example: a property expected to contain a string list
+ * is not NUL-terminated within the length of its value. */
+
+#define FDT_ERR_BADOVERLAY 16
+ /* FDT_ERR_BADOVERLAY: The device tree overlay, while
+ * correctly structured, cannot be applied due to some
+ * unexpected or missing value, property or node. */
+
+#define FDT_ERR_NOPHANDLES 17
+ /* FDT_ERR_NOPHANDLES: The device tree doesn't have any
+ * phandle available anymore without causing an overflow */
+
+#define FDT_ERR_MAX 17
+
+/**********************************************************************/
+/* Low-level functions (you probably don't need these) */
+/**********************************************************************/
+
+#ifndef SWIG /* This function is not useful in Python */
+const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int checklen);
+#endif
+static inline void *fdt_offset_ptr_w(void *fdt, int offset, int checklen)
+{
+ return (void *)(uintptr_t)fdt_offset_ptr(fdt, offset, checklen);
+}
+
+uint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset);
+
+/**********************************************************************/
+/* Traversal functions */
+/**********************************************************************/
+
+int fdt_next_node(const void *fdt, int offset, int *depth);
+
+/**
+ * fdt_first_subnode() - get offset of first direct subnode
+ *
+ * @fdt: FDT blob
+ * @offset: Offset of node to check
+ * @return offset of first subnode, or -FDT_ERR_NOTFOUND if there is none
+ */
+int fdt_first_subnode(const void *fdt, int offset);
+
+/**
+ * fdt_next_subnode() - get offset of next direct subnode
+ *
+ * After first calling fdt_first_subnode(), call this function repeatedly to
+ * get direct subnodes of a parent node.
+ *
+ * @fdt: FDT blob
+ * @offset: Offset of previous subnode
+ * @return offset of next subnode, or -FDT_ERR_NOTFOUND if there are no more
+ * subnodes
+ */
+int fdt_next_subnode(const void *fdt, int offset);
+
+/**
+ * fdt_for_each_subnode - iterate over all subnodes of a parent
+ *
+ * @node: child node (int, lvalue)
+ * @fdt: FDT blob (const void *)
+ * @parent: parent node (int)
+ *
+ * This is actually a wrapper around a for loop and would be used like so:
+ *
+ * fdt_for_each_subnode(node, fdt, parent) {
+ * Use node
+ * ...
+ * }
+ *
+ * if ((node < 0) && (node != -FDT_ERR_NOT_FOUND)) {
+ * Error handling
+ * }
+ *
+ * Note that this is implemented as a macro and @node is used as
+ * iterator in the loop. The parent variable be constant or even a
+ * literal.
+ *
+ */
+#define fdt_for_each_subnode(node, fdt, parent) \
+ for (node = fdt_first_subnode(fdt, parent); \
+ node >= 0; \
+ node = fdt_next_subnode(fdt, node))
+
+/**********************************************************************/
+/* General functions */
+/**********************************************************************/
+#define fdt_get_header(fdt, field) \
+ (fdt32_to_cpu(((const struct fdt_header *)(fdt))->field))
+#define fdt_magic(fdt) (fdt_get_header(fdt, magic))
+#define fdt_totalsize(fdt) (fdt_get_header(fdt, totalsize))
+#define fdt_off_dt_struct(fdt) (fdt_get_header(fdt, off_dt_struct))
+#define fdt_off_dt_strings(fdt) (fdt_get_header(fdt, off_dt_strings))
+#define fdt_off_mem_rsvmap(fdt) (fdt_get_header(fdt, off_mem_rsvmap))
+#define fdt_version(fdt) (fdt_get_header(fdt, version))
+#define fdt_last_comp_version(fdt) (fdt_get_header(fdt, last_comp_version))
+#define fdt_boot_cpuid_phys(fdt) (fdt_get_header(fdt, boot_cpuid_phys))
+#define fdt_size_dt_strings(fdt) (fdt_get_header(fdt, size_dt_strings))
+#define fdt_size_dt_struct(fdt) (fdt_get_header(fdt, size_dt_struct))
+
+#define __fdt_set_hdr(name) \
+ static inline void fdt_set_##name(void *fdt, uint32_t val) \
+ { \
+ struct fdt_header *fdth = (struct fdt_header *)fdt; \
+ fdth->name = cpu_to_fdt32(val); \
+ }
+__fdt_set_hdr(magic);
+__fdt_set_hdr(totalsize);
+__fdt_set_hdr(off_dt_struct);
+__fdt_set_hdr(off_dt_strings);
+__fdt_set_hdr(off_mem_rsvmap);
+__fdt_set_hdr(version);
+__fdt_set_hdr(last_comp_version);
+__fdt_set_hdr(boot_cpuid_phys);
+__fdt_set_hdr(size_dt_strings);
+__fdt_set_hdr(size_dt_struct);
+#undef __fdt_set_hdr
+
+/**
+ * fdt_check_header - sanity check a device tree or possible device tree
+ * @fdt: pointer to data which might be a flattened device tree
+ *
+ * fdt_check_header() checks that the given buffer contains what
+ * appears to be a flattened device tree with sane information in its
+ * header.
+ *
+ * returns:
+ * 0, if the buffer appears to contain a valid device tree
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE, standard meanings, as above
+ */
+int fdt_check_header(const void *fdt);
+
+/**
+ * fdt_move - move a device tree around in memory
+ * @fdt: pointer to the device tree to move
+ * @buf: pointer to memory where the device is to be moved
+ * @bufsize: size of the memory space at buf
+ *
+ * fdt_move() relocates, if possible, the device tree blob located at
+ * fdt to the buffer at buf of size bufsize. The buffer may overlap
+ * with the existing device tree blob at fdt. Therefore,
+ * fdt_move(fdt, fdt, fdt_totalsize(fdt))
+ * should always succeed.
+ *
+ * returns:
+ * 0, on success
+ * -FDT_ERR_NOSPACE, bufsize is insufficient to contain the device tree
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE, standard meanings
+ */
+int fdt_move(const void *fdt, void *buf, int bufsize);
+
+/**********************************************************************/
+/* Read-only functions */
+/**********************************************************************/
+
+/**
+ * fdt_string - retrieve a string from the strings block of a device tree
+ * @fdt: pointer to the device tree blob
+ * @stroffset: offset of the string within the strings block (native endian)
+ *
+ * fdt_string() retrieves a pointer to a single string from the
+ * strings block of the device tree blob at fdt.
+ *
+ * returns:
+ * a pointer to the string, on success
+ * NULL, if stroffset is out of bounds
+ */
+const char *fdt_string(const void *fdt, int stroffset);
+
+/**
+ * fdt_get_max_phandle - retrieves the highest phandle in a tree
+ * @fdt: pointer to the device tree blob
+ *
+ * fdt_get_max_phandle retrieves the highest phandle in the given
+ * device tree. This will ignore badly formatted phandles, or phandles
+ * with a value of 0 or -1.
+ *
+ * returns:
+ * the highest phandle on success
+ * 0, if no phandle was found in the device tree
+ * -1, if an error occurred
+ */
+uint32_t fdt_get_max_phandle(const void *fdt);
+
+/**
+ * fdt_num_mem_rsv - retrieve the number of memory reserve map entries
+ * @fdt: pointer to the device tree blob
+ *
+ * Returns the number of entries in the device tree blob's memory
+ * reservation map. This does not include the terminating 0,0 entry
+ * or any other (0,0) entries reserved for expansion.
+ *
+ * returns:
+ * the number of entries
+ */
+int fdt_num_mem_rsv(const void *fdt);
+
+/**
+ * fdt_get_mem_rsv - retrieve one memory reserve map entry
+ * @fdt: pointer to the device tree blob
+ * @address, @size: pointers to 64-bit variables
+ *
+ * On success, *address and *size will contain the address and size of
+ * the n-th reserve map entry from the device tree blob, in
+ * native-endian format.
+ *
+ * returns:
+ * 0, on success
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE, standard meanings
+ */
+int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size);
+
+/**
+ * fdt_subnode_offset_namelen - find a subnode based on substring
+ * @fdt: pointer to the device tree blob
+ * @parentoffset: structure block offset of a node
+ * @name: name of the subnode to locate
+ * @namelen: number of characters of name to consider
+ *
+ * Identical to fdt_subnode_offset(), but only examine the first
+ * namelen characters of name for matching the subnode name. This is
+ * useful for finding subnodes based on a portion of a larger string,
+ * such as a full path.
+ */
+#ifndef SWIG /* Not available in Python */
+int fdt_subnode_offset_namelen(const void *fdt, int parentoffset,
+ const char *name, int namelen);
+#endif
+/**
+ * fdt_subnode_offset - find a subnode of a given node
+ * @fdt: pointer to the device tree blob
+ * @parentoffset: structure block offset of a node
+ * @name: name of the subnode to locate
+ *
+ * fdt_subnode_offset() finds a subnode of the node at structure block
+ * offset parentoffset with the given name. name may include a unit
+ * address, in which case fdt_subnode_offset() will find the subnode
+ * with that unit address, or the unit address may be omitted, in
+ * which case fdt_subnode_offset() will find an arbitrary subnode
+ * whose name excluding unit address matches the given name.
+ *
+ * returns:
+ * structure block offset of the requested subnode (>=0), on success
+ * -FDT_ERR_NOTFOUND, if the requested subnode does not exist
+ * -FDT_ERR_BADOFFSET, if parentoffset did not point to an FDT_BEGIN_NODE
+ * tag
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_TRUNCATED, standard meanings.
+ */
+int fdt_subnode_offset(const void *fdt, int parentoffset, const char *name);
+
+/**
+ * fdt_path_offset_namelen - find a tree node by its full path
+ * @fdt: pointer to the device tree blob
+ * @path: full path of the node to locate
+ * @namelen: number of characters of path to consider
+ *
+ * Identical to fdt_path_offset(), but only consider the first namelen
+ * characters of path as the path name.
+ */
+#ifndef SWIG /* Not available in Python */
+int fdt_path_offset_namelen(const void *fdt, const char *path, int namelen);
+#endif
+
+/**
+ * fdt_path_offset - find a tree node by its full path
+ * @fdt: pointer to the device tree blob
+ * @path: full path of the node to locate
+ *
+ * fdt_path_offset() finds a node of a given path in the device tree.
+ * Each path component may omit the unit address portion, but the
+ * results of this are undefined if any such path component is
+ * ambiguous (that is if there are multiple nodes at the relevant
+ * level matching the given component, differentiated only by unit
+ * address).
+ *
+ * returns:
+ * structure block offset of the node with the requested path (>=0), on
+ * success
+ * -FDT_ERR_BADPATH, given path does not begin with '/' or is invalid
+ * -FDT_ERR_NOTFOUND, if the requested node does not exist
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_TRUNCATED, standard meanings.
+ */
+int fdt_path_offset(const void *fdt, const char *path);
+
+/**
+ * fdt_get_name - retrieve the name of a given node
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: structure block offset of the starting node
+ * @lenp: pointer to an integer variable (will be overwritten) or NULL
+ *
+ * fdt_get_name() retrieves the name (including unit address) of the
+ * device tree node at structure block offset nodeoffset. If lenp is
+ * non-NULL, the length of this name is also returned, in the integer
+ * pointed to by lenp.
+ *
+ * returns:
+ * pointer to the node's name, on success
+ * If lenp is non-NULL, *lenp contains the length of that name
+ * (>=0)
+ * NULL, on error
+ * if lenp is non-NULL *lenp contains an error code (<0):
+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE
+ * tag
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE, standard meanings
+ */
+const char *fdt_get_name(const void *fdt, int nodeoffset, int *lenp);
+
+/**
+ * fdt_first_property_offset - find the offset of a node's first property
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: structure block offset of a node
+ *
+ * fdt_first_property_offset() finds the first property of the node at
+ * the given structure block offset.
+ *
+ * returns:
+ * structure block offset of the property (>=0), on success
+ * -FDT_ERR_NOTFOUND, if the requested node has no properties
+ * -FDT_ERR_BADOFFSET, if nodeoffset did not point to an FDT_BEGIN_NODE tag
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_TRUNCATED, standard meanings.
+ */
+int fdt_first_property_offset(const void *fdt, int nodeoffset);
+
+/**
+ * fdt_next_property_offset - step through a node's properties
+ * @fdt: pointer to the device tree blob
+ * @offset: structure block offset of a property
+ *
+ * fdt_next_property_offset() finds the property immediately after the
+ * one at the given structure block offset. This will be a property
+ * of the same node as the given property.
+ *
+ * returns:
+ * structure block offset of the next property (>=0), on success
+ * -FDT_ERR_NOTFOUND, if the given property is the last in its node
+ * -FDT_ERR_BADOFFSET, if nodeoffset did not point to an FDT_PROP tag
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_TRUNCATED, standard meanings.
+ */
+int fdt_next_property_offset(const void *fdt, int offset);
+
+/**
+ * fdt_for_each_property_offset - iterate over all properties of a node
+ *
+ * @property_offset: property offset (int, lvalue)
+ * @fdt: FDT blob (const void *)
+ * @node: node offset (int)
+ *
+ * This is actually a wrapper around a for loop and would be used like so:
+ *
+ * fdt_for_each_property_offset(property, fdt, node) {
+ * Use property
+ * ...
+ * }
+ *
+ * if ((property < 0) && (property != -FDT_ERR_NOT_FOUND)) {
+ * Error handling
+ * }
+ *
+ * Note that this is implemented as a macro and property is used as
+ * iterator in the loop. The node variable can be constant or even a
+ * literal.
+ */
+#define fdt_for_each_property_offset(property, fdt, node) \
+ for (property = fdt_first_property_offset(fdt, node); \
+ property >= 0; \
+ property = fdt_next_property_offset(fdt, property))
+
+/**
+ * fdt_get_property_by_offset - retrieve the property at a given offset
+ * @fdt: pointer to the device tree blob
+ * @offset: offset of the property to retrieve
+ * @lenp: pointer to an integer variable (will be overwritten) or NULL
+ *
+ * fdt_get_property_by_offset() retrieves a pointer to the
+ * fdt_property structure within the device tree blob at the given
+ * offset. If lenp is non-NULL, the length of the property value is
+ * also returned, in the integer pointed to by lenp.
+ *
+ * returns:
+ * pointer to the structure representing the property
+ * if lenp is non-NULL, *lenp contains the length of the property
+ * value (>=0)
+ * NULL, on error
+ * if lenp is non-NULL, *lenp contains an error code (<0):
+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_PROP tag
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_TRUNCATED, standard meanings
+ */
+const struct fdt_property *fdt_get_property_by_offset(const void *fdt,
+ int offset,
+ int *lenp);
+
+/**
+ * fdt_get_property_namelen - find a property based on substring
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose property to find
+ * @name: name of the property to find
+ * @namelen: number of characters of name to consider
+ * @lenp: pointer to an integer variable (will be overwritten) or NULL
+ *
+ * Identical to fdt_get_property(), but only examine the first namelen
+ * characters of name for matching the property name.
+ */
+#ifndef SWIG /* Not available in Python */
+const struct fdt_property *fdt_get_property_namelen(const void *fdt,
+ int nodeoffset,
+ const char *name,
+ int namelen, int *lenp);
+#endif
+
+/**
+ * fdt_get_property - find a given property in a given node
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose property to find
+ * @name: name of the property to find
+ * @lenp: pointer to an integer variable (will be overwritten) or NULL
+ *
+ * fdt_get_property() retrieves a pointer to the fdt_property
+ * structure within the device tree blob corresponding to the property
+ * named 'name' of the node at offset nodeoffset. If lenp is
+ * non-NULL, the length of the property value is also returned, in the
+ * integer pointed to by lenp.
+ *
+ * returns:
+ * pointer to the structure representing the property
+ * if lenp is non-NULL, *lenp contains the length of the property
+ * value (>=0)
+ * NULL, on error
+ * if lenp is non-NULL, *lenp contains an error code (<0):
+ * -FDT_ERR_NOTFOUND, node does not have named property
+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE
+ * tag
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_TRUNCATED, standard meanings
+ */
+const struct fdt_property *fdt_get_property(const void *fdt, int nodeoffset,
+ const char *name, int *lenp);
+static inline struct fdt_property *fdt_get_property_w(void *fdt, int nodeoffset,
+ const char *name,
+ int *lenp)
+{
+ return (struct fdt_property *)(uintptr_t)
+ fdt_get_property(fdt, nodeoffset, name, lenp);
+}
+
+/**
+ * fdt_getprop_by_offset - retrieve the value of a property at a given offset
+ * @fdt: pointer to the device tree blob
+ * @ffset: offset of the property to read
+ * @namep: pointer to a string variable (will be overwritten) or NULL
+ * @lenp: pointer to an integer variable (will be overwritten) or NULL
+ *
+ * fdt_getprop_by_offset() retrieves a pointer to the value of the
+ * property at structure block offset 'offset' (this will be a pointer
+ * to within the device blob itself, not a copy of the value). If
+ * lenp is non-NULL, the length of the property value is also
+ * returned, in the integer pointed to by lenp. If namep is non-NULL,
+ * the property's namne will also be returned in the char * pointed to
+ * by namep (this will be a pointer to within the device tree's string
+ * block, not a new copy of the name).
+ *
+ * returns:
+ * pointer to the property's value
+ * if lenp is non-NULL, *lenp contains the length of the property
+ * value (>=0)
+ * if namep is non-NULL *namep contiains a pointer to the property
+ * name.
+ * NULL, on error
+ * if lenp is non-NULL, *lenp contains an error code (<0):
+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_PROP tag
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_TRUNCATED, standard meanings
+ */
+#ifndef SWIG /* This function is not useful in Python */
+const void *fdt_getprop_by_offset(const void *fdt, int offset,
+ const char **namep, int *lenp);
+#endif
+
+/**
+ * fdt_getprop_namelen - get property value based on substring
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose property to find
+ * @name: name of the property to find
+ * @namelen: number of characters of name to consider
+ * @lenp: pointer to an integer variable (will be overwritten) or NULL
+ *
+ * Identical to fdt_getprop(), but only examine the first namelen
+ * characters of name for matching the property name.
+ */
+#ifndef SWIG /* Not available in Python */
+const void *fdt_getprop_namelen(const void *fdt, int nodeoffset,
+ const char *name, int namelen, int *lenp);
+static inline void *fdt_getprop_namelen_w(void *fdt, int nodeoffset,
+ const char *name, int namelen,
+ int *lenp)
+{
+ return (void *)(uintptr_t)fdt_getprop_namelen(fdt, nodeoffset, name,
+ namelen, lenp);
+}
+#endif
+
+/**
+ * fdt_getprop - retrieve the value of a given property
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose property to find
+ * @name: name of the property to find
+ * @lenp: pointer to an integer variable (will be overwritten) or NULL
+ *
+ * fdt_getprop() retrieves a pointer to the value of the property
+ * named 'name' of the node at offset nodeoffset (this will be a
+ * pointer to within the device blob itself, not a copy of the value).
+ * If lenp is non-NULL, the length of the property value is also
+ * returned, in the integer pointed to by lenp.
+ *
+ * returns:
+ * pointer to the property's value
+ * if lenp is non-NULL, *lenp contains the length of the property
+ * value (>=0)
+ * NULL, on error
+ * if lenp is non-NULL, *lenp contains an error code (<0):
+ * -FDT_ERR_NOTFOUND, node does not have named property
+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE
+ * tag
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_TRUNCATED, standard meanings
+ */
+const void *fdt_getprop(const void *fdt, int nodeoffset,
+ const char *name, int *lenp);
+static inline void *fdt_getprop_w(void *fdt, int nodeoffset,
+ const char *name, int *lenp)
+{
+ return (void *)(uintptr_t)fdt_getprop(fdt, nodeoffset, name, lenp);
+}
+
+/**
+ * fdt_get_phandle - retrieve the phandle of a given node
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: structure block offset of the node
+ *
+ * fdt_get_phandle() retrieves the phandle of the device tree node at
+ * structure block offset nodeoffset.
+ *
+ * returns:
+ * the phandle of the node at nodeoffset, on success (!= 0, != -1)
+ * 0, if the node has no phandle, or another error occurs
+ */
+uint32_t fdt_get_phandle(const void *fdt, int nodeoffset);
+
+/**
+ * fdt_get_alias_namelen - get alias based on substring
+ * @fdt: pointer to the device tree blob
+ * @name: name of the alias th look up
+ * @namelen: number of characters of name to consider
+ *
+ * Identical to fdt_get_alias(), but only examine the first namelen
+ * characters of name for matching the alias name.
+ */
+#ifndef SWIG /* Not available in Python */
+const char *fdt_get_alias_namelen(const void *fdt,
+ const char *name, int namelen);
+#endif
+
+/**
+ * fdt_get_alias - retrieve the path referenced by a given alias
+ * @fdt: pointer to the device tree blob
+ * @name: name of the alias th look up
+ *
+ * fdt_get_alias() retrieves the value of a given alias. That is, the
+ * value of the property named 'name' in the node /aliases.
+ *
+ * returns:
+ * a pointer to the expansion of the alias named 'name', if it exists
+ * NULL, if the given alias or the /aliases node does not exist
+ */
+const char *fdt_get_alias(const void *fdt, const char *name);
+
+/**
+ * fdt_get_path - determine the full path of a node
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose path to find
+ * @buf: character buffer to contain the returned path (will be overwritten)
+ * @buflen: size of the character buffer at buf
+ *
+ * fdt_get_path() computes the full path of the node at offset
+ * nodeoffset, and records that path in the buffer at buf.
+ *
+ * NOTE: This function is expensive, as it must scan the device tree
+ * structure from the start to nodeoffset.
+ *
+ * returns:
+ * 0, on success
+ * buf contains the absolute path of the node at
+ * nodeoffset, as a NUL-terminated string.
+ * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
+ * -FDT_ERR_NOSPACE, the path of the given node is longer than (bufsize-1)
+ * characters and will not fit in the given buffer.
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE, standard meanings
+ */
+int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen);
+
+/**
+ * fdt_supernode_atdepth_offset - find a specific ancestor of a node
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose parent to find
+ * @supernodedepth: depth of the ancestor to find
+ * @nodedepth: pointer to an integer variable (will be overwritten) or NULL
+ *
+ * fdt_supernode_atdepth_offset() finds an ancestor of the given node
+ * at a specific depth from the root (where the root itself has depth
+ * 0, its immediate subnodes depth 1 and so forth). So
+ * fdt_supernode_atdepth_offset(fdt, nodeoffset, 0, NULL);
+ * will always return 0, the offset of the root node. If the node at
+ * nodeoffset has depth D, then:
+ * fdt_supernode_atdepth_offset(fdt, nodeoffset, D, NULL);
+ * will return nodeoffset itself.
+ *
+ * NOTE: This function is expensive, as it must scan the device tree
+ * structure from the start to nodeoffset.
+ *
+ * returns:
+ * structure block offset of the node at node offset's ancestor
+ * of depth supernodedepth (>=0), on success
+ * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
+ * -FDT_ERR_NOTFOUND, supernodedepth was greater than the depth of
+ * nodeoffset
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE, standard meanings
+ */
+int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset,
+ int supernodedepth, int *nodedepth);
+
+/**
+ * fdt_node_depth - find the depth of a given node
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose parent to find
+ *
+ * fdt_node_depth() finds the depth of a given node. The root node
+ * has depth 0, its immediate subnodes depth 1 and so forth.
+ *
+ * NOTE: This function is expensive, as it must scan the device tree
+ * structure from the start to nodeoffset.
+ *
+ * returns:
+ * depth of the node at nodeoffset (>=0), on success
+ * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE, standard meanings
+ */
+int fdt_node_depth(const void *fdt, int nodeoffset);
+
+/**
+ * fdt_parent_offset - find the parent of a given node
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose parent to find
+ *
+ * fdt_parent_offset() locates the parent node of a given node (that
+ * is, it finds the offset of the node which contains the node at
+ * nodeoffset as a subnode).
+ *
+ * NOTE: This function is expensive, as it must scan the device tree
+ * structure from the start to nodeoffset, *twice*.
+ *
+ * returns:
+ * structure block offset of the parent of the node at nodeoffset
+ * (>=0), on success
+ * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE, standard meanings
+ */
+int fdt_parent_offset(const void *fdt, int nodeoffset);
+
+/**
+ * fdt_node_offset_by_prop_value - find nodes with a given property value
+ * @fdt: pointer to the device tree blob
+ * @startoffset: only find nodes after this offset
+ * @propname: property name to check
+ * @propval: property value to search for
+ * @proplen: length of the value in propval
+ *
+ * fdt_node_offset_by_prop_value() returns the offset of the first
+ * node after startoffset, which has a property named propname whose
+ * value is of length proplen and has value equal to propval; or if
+ * startoffset is -1, the very first such node in the tree.
+ *
+ * To iterate through all nodes matching the criterion, the following
+ * idiom can be used:
+ * offset = fdt_node_offset_by_prop_value(fdt, -1, propname,
+ * propval, proplen);
+ * while (offset != -FDT_ERR_NOTFOUND) {
+ * // other code here
+ * offset = fdt_node_offset_by_prop_value(fdt, offset, propname,
+ * propval, proplen);
+ * }
+ *
+ * Note the -1 in the first call to the function, if 0 is used here
+ * instead, the function will never locate the root node, even if it
+ * matches the criterion.
+ *
+ * returns:
+ * structure block offset of the located node (>= 0, >startoffset),
+ * on success
+ * -FDT_ERR_NOTFOUND, no node matching the criterion exists in the
+ * tree after startoffset
+ * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE, standard meanings
+ */
+int fdt_node_offset_by_prop_value(const void *fdt, int startoffset,
+ const char *propname,
+ const void *propval, int proplen);
+
+/**
+ * fdt_node_offset_by_phandle - find the node with a given phandle
+ * @fdt: pointer to the device tree blob
+ * @phandle: phandle value
+ *
+ * fdt_node_offset_by_phandle() returns the offset of the node
+ * which has the given phandle value. If there is more than one node
+ * in the tree with the given phandle (an invalid tree), results are
+ * undefined.
+ *
+ * returns:
+ * structure block offset of the located node (>= 0), on success
+ * -FDT_ERR_NOTFOUND, no node with that phandle exists
+ * -FDT_ERR_BADPHANDLE, given phandle value was invalid (0 or -1)
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE, standard meanings
+ */
+int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle);
+
+/**
+ * fdt_node_check_compatible: check a node's compatible property
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of a tree node
+ * @compatible: string to match against
+ *
+ *
+ * fdt_node_check_compatible() returns 0 if the given node contains a
+ * 'compatible' property with the given string as one of its elements,
+ * it returns non-zero otherwise, or on error.
+ *
+ * returns:
+ * 0, if the node has a 'compatible' property listing the given string
+ * 1, if the node has a 'compatible' property, but it does not list
+ * the given string
+ * -FDT_ERR_NOTFOUND, if the given node has no 'compatible' property
+ * -FDT_ERR_BADOFFSET, if nodeoffset does not refer to a BEGIN_NODE tag
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE, standard meanings
+ */
+int fdt_node_check_compatible(const void *fdt, int nodeoffset,
+ const char *compatible);
+
+/**
+ * fdt_node_offset_by_compatible - find nodes with a given 'compatible' value
+ * @fdt: pointer to the device tree blob
+ * @startoffset: only find nodes after this offset
+ * @compatible: 'compatible' string to match against
+ *
+ * fdt_node_offset_by_compatible() returns the offset of the first
+ * node after startoffset, which has a 'compatible' property which
+ * lists the given compatible string; or if startoffset is -1, the
+ * very first such node in the tree.
+ *
+ * To iterate through all nodes matching the criterion, the following
+ * idiom can be used:
+ * offset = fdt_node_offset_by_compatible(fdt, -1, compatible);
+ * while (offset != -FDT_ERR_NOTFOUND) {
+ * // other code here
+ * offset = fdt_node_offset_by_compatible(fdt, offset, compatible);
+ * }
+ *
+ * Note the -1 in the first call to the function, if 0 is used here
+ * instead, the function will never locate the root node, even if it
+ * matches the criterion.
+ *
+ * returns:
+ * structure block offset of the located node (>= 0, >startoffset),
+ * on success
+ * -FDT_ERR_NOTFOUND, no node matching the criterion exists in the
+ * tree after startoffset
+ * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE, standard meanings
+ */
+int fdt_node_offset_by_compatible(const void *fdt, int startoffset,
+ const char *compatible);
+
+/**
+ * fdt_stringlist_contains - check a string list property for a string
+ * @strlist: Property containing a list of strings to check
+ * @listlen: Length of property
+ * @str: String to search for
+ *
+ * This is a utility function provided for convenience. The list contains
+ * one or more strings, each terminated by \0, as is found in a device tree
+ * "compatible" property.
+ *
+ * @return: 1 if the string is found in the list, 0 not found, or invalid list
+ */
+int fdt_stringlist_contains(const char *strlist, int listlen, const char *str);
+
+/**
+ * fdt_stringlist_count - count the number of strings in a string list
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of a tree node
+ * @property: name of the property containing the string list
+ * @return:
+ * the number of strings in the given property
+ * -FDT_ERR_BADVALUE if the property value is not NUL-terminated
+ * -FDT_ERR_NOTFOUND if the property does not exist
+ */
+int fdt_stringlist_count(const void *fdt, int nodeoffset, const char *property);
+
+/**
+ * fdt_stringlist_search - find a string in a string list and return its index
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of a tree node
+ * @property: name of the property containing the string list
+ * @string: string to look up in the string list
+ *
+ * Note that it is possible for this function to succeed on property values
+ * that are not NUL-terminated. That's because the function will stop after
+ * finding the first occurrence of @string. This can for example happen with
+ * small-valued cell properties, such as #address-cells, when searching for
+ * the empty string.
+ *
+ * @return:
+ * the index of the string in the list of strings
+ * -FDT_ERR_BADVALUE if the property value is not NUL-terminated
+ * -FDT_ERR_NOTFOUND if the property does not exist or does not contain
+ * the given string
+ */
+int fdt_stringlist_search(const void *fdt, int nodeoffset, const char *property,
+ const char *string);
+
+/**
+ * fdt_stringlist_get() - obtain the string at a given index in a string list
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of a tree node
+ * @property: name of the property containing the string list
+ * @index: index of the string to return
+ * @lenp: return location for the string length or an error code on failure
+ *
+ * Note that this will successfully extract strings from properties with
+ * non-NUL-terminated values. For example on small-valued cell properties
+ * this function will return the empty string.
+ *
+ * If non-NULL, the length of the string (on success) or a negative error-code
+ * (on failure) will be stored in the integer pointer to by lenp.
+ *
+ * @return:
+ * A pointer to the string at the given index in the string list or NULL on
+ * failure. On success the length of the string will be stored in the memory
+ * location pointed to by the lenp parameter, if non-NULL. On failure one of
+ * the following negative error codes will be returned in the lenp parameter
+ * (if non-NULL):
+ * -FDT_ERR_BADVALUE if the property value is not NUL-terminated
+ * -FDT_ERR_NOTFOUND if the property does not exist
+ */
+const char *fdt_stringlist_get(const void *fdt, int nodeoffset,
+ const char *property, int index,
+ int *lenp);
+
+/**********************************************************************/
+/* Read-only functions (addressing related) */
+/**********************************************************************/
+
+/**
+ * FDT_MAX_NCELLS - maximum value for #address-cells and #size-cells
+ *
+ * This is the maximum value for #address-cells, #size-cells and
+ * similar properties that will be processed by libfdt. IEE1275
+ * requires that OF implementations handle values up to 4.
+ * Implementations may support larger values, but in practice higher
+ * values aren't used.
+ */
+#define FDT_MAX_NCELLS 4
+
+/**
+ * fdt_address_cells - retrieve address size for a bus represented in the tree
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node to find the address size for
+ *
+ * When the node has a valid #address-cells property, returns its value.
+ *
+ * returns:
+ * 0 <= n < FDT_MAX_NCELLS, on success
+ * 2, if the node has no #address-cells property
+ * -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid
+ * #address-cells property
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_TRUNCATED, standard meanings
+ */
+int fdt_address_cells(const void *fdt, int nodeoffset);
+
+/**
+ * fdt_size_cells - retrieve address range size for a bus represented in the
+ * tree
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node to find the address range size for
+ *
+ * When the node has a valid #size-cells property, returns its value.
+ *
+ * returns:
+ * 0 <= n < FDT_MAX_NCELLS, on success
+ * 2, if the node has no #address-cells property
+ * -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid
+ * #size-cells property
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_TRUNCATED, standard meanings
+ */
+int fdt_size_cells(const void *fdt, int nodeoffset);
+
+
+/**********************************************************************/
+/* Write-in-place functions */
+/**********************************************************************/
+
+/**
+ * fdt_setprop_inplace_namelen_partial - change a property's value,
+ * but not its size
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose property to change
+ * @name: name of the property to change
+ * @namelen: number of characters of name to consider
+ * @idx: index of the property to change in the array
+ * @val: pointer to data to replace the property value with
+ * @len: length of the property value
+ *
+ * Identical to fdt_setprop_inplace(), but modifies the given property
+ * starting from the given index, and using only the first characters
+ * of the name. It is useful when you want to manipulate only one value of
+ * an array and you have a string that doesn't end with \0.
+ */
+#ifndef SWIG /* Not available in Python */
+int fdt_setprop_inplace_namelen_partial(void *fdt, int nodeoffset,
+ const char *name, int namelen,
+ uint32_t idx, const void *val,
+ int len);
+#endif
+
+/**
+ * fdt_setprop_inplace - change a property's value, but not its size
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose property to change
+ * @name: name of the property to change
+ * @val: pointer to data to replace the property value with
+ * @len: length of the property value
+ *
+ * fdt_setprop_inplace() replaces the value of a given property with
+ * the data in val, of length len. This function cannot change the
+ * size of a property, and so will only work if len is equal to the
+ * current length of the property.
+ *
+ * This function will alter only the bytes in the blob which contain
+ * the given property value, and will not alter or move any other part
+ * of the tree.
+ *
+ * returns:
+ * 0, on success
+ * -FDT_ERR_NOSPACE, if len is not equal to the property's current length
+ * -FDT_ERR_NOTFOUND, node does not have the named property
+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_TRUNCATED, standard meanings
+ */
+#ifndef SWIG /* Not available in Python */
+int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,
+ const void *val, int len);
+#endif
+
+/**
+ * fdt_setprop_inplace_u32 - change the value of a 32-bit integer property
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose property to change
+ * @name: name of the property to change
+ * @val: 32-bit integer value to replace the property with
+ *
+ * fdt_setprop_inplace_u32() replaces the value of a given property
+ * with the 32-bit integer value in val, converting val to big-endian
+ * if necessary. This function cannot change the size of a property,
+ * and so will only work if the property already exists and has length
+ * 4.
+ *
+ * This function will alter only the bytes in the blob which contain
+ * the given property value, and will not alter or move any other part
+ * of the tree.
+ *
+ * returns:
+ * 0, on success
+ * -FDT_ERR_NOSPACE, if the property's length is not equal to 4
+ * -FDT_ERR_NOTFOUND, node does not have the named property
+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_TRUNCATED, standard meanings
+ */
+static inline int fdt_setprop_inplace_u32(void *fdt, int nodeoffset,
+ const char *name, uint32_t val)
+{
+ fdt32_t tmp = cpu_to_fdt32(val);
+ return fdt_setprop_inplace(fdt, nodeoffset, name, &tmp, sizeof(tmp));
+}
+
+/**
+ * fdt_setprop_inplace_u64 - change the value of a 64-bit integer property
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose property to change
+ * @name: name of the property to change
+ * @val: 64-bit integer value to replace the property with
+ *
+ * fdt_setprop_inplace_u64() replaces the value of a given property
+ * with the 64-bit integer value in val, converting val to big-endian
+ * if necessary. This function cannot change the size of a property,
+ * and so will only work if the property already exists and has length
+ * 8.
+ *
+ * This function will alter only the bytes in the blob which contain
+ * the given property value, and will not alter or move any other part
+ * of the tree.
+ *
+ * returns:
+ * 0, on success
+ * -FDT_ERR_NOSPACE, if the property's length is not equal to 8
+ * -FDT_ERR_NOTFOUND, node does not have the named property
+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_TRUNCATED, standard meanings
+ */
+static inline int fdt_setprop_inplace_u64(void *fdt, int nodeoffset,
+ const char *name, uint64_t val)
+{
+ fdt64_t tmp = cpu_to_fdt64(val);
+ return fdt_setprop_inplace(fdt, nodeoffset, name, &tmp, sizeof(tmp));
+}
+
+/**
+ * fdt_setprop_inplace_cell - change the value of a single-cell property
+ *
+ * This is an alternative name for fdt_setprop_inplace_u32()
+ */
+static inline int fdt_setprop_inplace_cell(void *fdt, int nodeoffset,
+ const char *name, uint32_t val)
+{
+ return fdt_setprop_inplace_u32(fdt, nodeoffset, name, val);
+}
+
+/**
+ * fdt_nop_property - replace a property with nop tags
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose property to nop
+ * @name: name of the property to nop
+ *
+ * fdt_nop_property() will replace a given property's representation
+ * in the blob with FDT_NOP tags, effectively removing it from the
+ * tree.
+ *
+ * This function will alter only the bytes in the blob which contain
+ * the property, and will not alter or move any other part of the
+ * tree.
+ *
+ * returns:
+ * 0, on success
+ * -FDT_ERR_NOTFOUND, node does not have the named property
+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_TRUNCATED, standard meanings
+ */
+int fdt_nop_property(void *fdt, int nodeoffset, const char *name);
+
+/**
+ * fdt_nop_node - replace a node (subtree) with nop tags
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node to nop
+ *
+ * fdt_nop_node() will replace a given node's representation in the
+ * blob, including all its subnodes, if any, with FDT_NOP tags,
+ * effectively removing it from the tree.
+ *
+ * This function will alter only the bytes in the blob which contain
+ * the node and its properties and subnodes, and will not alter or
+ * move any other part of the tree.
+ *
+ * returns:
+ * 0, on success
+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_TRUNCATED, standard meanings
+ */
+int fdt_nop_node(void *fdt, int nodeoffset);
+
+/**********************************************************************/
+/* Sequential write functions */
+/**********************************************************************/
+
+int fdt_create(void *buf, int bufsize);
+int fdt_resize(void *fdt, void *buf, int bufsize);
+int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size);
+int fdt_finish_reservemap(void *fdt);
+int fdt_begin_node(void *fdt, const char *name);
+int fdt_property(void *fdt, const char *name, const void *val, int len);
+static inline int fdt_property_u32(void *fdt, const char *name, uint32_t val)
+{
+ fdt32_t tmp = cpu_to_fdt32(val);
+ return fdt_property(fdt, name, &tmp, sizeof(tmp));
+}
+static inline int fdt_property_u64(void *fdt, const char *name, uint64_t val)
+{
+ fdt64_t tmp = cpu_to_fdt64(val);
+ return fdt_property(fdt, name, &tmp, sizeof(tmp));
+}
+static inline int fdt_property_cell(void *fdt, const char *name, uint32_t val)
+{
+ return fdt_property_u32(fdt, name, val);
+}
+
+/**
+ * fdt_property_placeholder - add a new property and return a ptr to its value
+ *
+ * @fdt: pointer to the device tree blob
+ * @name: name of property to add
+ * @len: length of property value in bytes
+ * @valp: returns a pointer to where where the value should be placed
+ *
+ * returns:
+ * 0, on success
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_NOSPACE, standard meanings
+ */
+int fdt_property_placeholder(void *fdt, const char *name, int len, void **valp);
+
+#define fdt_property_string(fdt, name, str) \
+ fdt_property(fdt, name, str, strlen(str)+1)
+int fdt_end_node(void *fdt);
+int fdt_finish(void *fdt);
+
+/**********************************************************************/
+/* Read-write functions */
+/**********************************************************************/
+
+int fdt_create_empty_tree(void *buf, int bufsize);
+int fdt_open_into(const void *fdt, void *buf, int bufsize);
+int fdt_pack(void *fdt);
+
+/**
+ * fdt_add_mem_rsv - add one memory reserve map entry
+ * @fdt: pointer to the device tree blob
+ * @address, @size: 64-bit values (native endian)
+ *
+ * Adds a reserve map entry to the given blob reserving a region at
+ * address address of length size.
+ *
+ * This function will insert data into the reserve map and will
+ * therefore change the indexes of some entries in the table.
+ *
+ * returns:
+ * 0, on success
+ * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
+ * contain the new reservation entry
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_BADLAYOUT,
+ * -FDT_ERR_TRUNCATED, standard meanings
+ */
+int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size);
+
+/**
+ * fdt_del_mem_rsv - remove a memory reserve map entry
+ * @fdt: pointer to the device tree blob
+ * @n: entry to remove
+ *
+ * fdt_del_mem_rsv() removes the n-th memory reserve map entry from
+ * the blob.
+ *
+ * This function will delete data from the reservation table and will
+ * therefore change the indexes of some entries in the table.
+ *
+ * returns:
+ * 0, on success
+ * -FDT_ERR_NOTFOUND, there is no entry of the given index (i.e. there
+ * are less than n+1 reserve map entries)
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_BADLAYOUT,
+ * -FDT_ERR_TRUNCATED, standard meanings
+ */
+int fdt_del_mem_rsv(void *fdt, int n);
+
+/**
+ * fdt_set_name - change the name of a given node
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: structure block offset of a node
+ * @name: name to give the node
+ *
+ * fdt_set_name() replaces the name (including unit address, if any)
+ * of the given node with the given string. NOTE: this function can't
+ * efficiently check if the new name is unique amongst the given
+ * node's siblings; results are undefined if this function is invoked
+ * with a name equal to one of the given node's siblings.
+ *
+ * This function may insert or delete data from the blob, and will
+ * therefore change the offsets of some existing nodes.
+ *
+ * returns:
+ * 0, on success
+ * -FDT_ERR_NOSPACE, there is insufficient free space in the blob
+ * to contain the new name
+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE, standard meanings
+ */
+int fdt_set_name(void *fdt, int nodeoffset, const char *name);
+
+/**
+ * fdt_setprop - create or change a property
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose property to change
+ * @name: name of the property to change
+ * @val: pointer to data to set the property value to
+ * @len: length of the property value
+ *
+ * fdt_setprop() sets the value of the named property in the given
+ * node to the given value and length, creating the property if it
+ * does not already exist.
+ *
+ * This function may insert or delete data from the blob, and will
+ * therefore change the offsets of some existing nodes.
+ *
+ * returns:
+ * 0, on success
+ * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
+ * contain the new property value
+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
+ * -FDT_ERR_BADLAYOUT,
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_BADLAYOUT,
+ * -FDT_ERR_TRUNCATED, standard meanings
+ */
+int fdt_setprop(void *fdt, int nodeoffset, const char *name,
+ const void *val, int len);
+
+/**
+ * fdt_setprop _placeholder - allocate space for a property
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose property to change
+ * @name: name of the property to change
+ * @len: length of the property value
+ * @prop_data: return pointer to property data
+ *
+ * fdt_setprop_placeholer() allocates the named property in the given node.
+ * If the property exists it is resized. In either case a pointer to the
+ * property data is returned.
+ *
+ * This function may insert or delete data from the blob, and will
+ * therefore change the offsets of some existing nodes.
+ *
+ * returns:
+ * 0, on success
+ * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
+ * contain the new property value
+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
+ * -FDT_ERR_BADLAYOUT,
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_BADLAYOUT,
+ * -FDT_ERR_TRUNCATED, standard meanings
+ */
+int fdt_setprop_placeholder(void *fdt, int nodeoffset, const char *name,
+ int len, void **prop_data);
+
+/**
+ * fdt_setprop_u32 - set a property to a 32-bit integer
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose property to change
+ * @name: name of the property to change
+ * @val: 32-bit integer value for the property (native endian)
+ *
+ * fdt_setprop_u32() sets the value of the named property in the given
+ * node to the given 32-bit integer value (converting to big-endian if
+ * necessary), or creates a new property with that value if it does
+ * not already exist.
+ *
+ * This function may insert or delete data from the blob, and will
+ * therefore change the offsets of some existing nodes.
+ *
+ * returns:
+ * 0, on success
+ * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
+ * contain the new property value
+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
+ * -FDT_ERR_BADLAYOUT,
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_BADLAYOUT,
+ * -FDT_ERR_TRUNCATED, standard meanings
+ */
+static inline int fdt_setprop_u32(void *fdt, int nodeoffset, const char *name,
+ uint32_t val)
+{
+ fdt32_t tmp = cpu_to_fdt32(val);
+ return fdt_setprop(fdt, nodeoffset, name, &tmp, sizeof(tmp));
+}
+
+/**
+ * fdt_setprop_u64 - set a property to a 64-bit integer
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose property to change
+ * @name: name of the property to change
+ * @val: 64-bit integer value for the property (native endian)
+ *
+ * fdt_setprop_u64() sets the value of the named property in the given
+ * node to the given 64-bit integer value (converting to big-endian if
+ * necessary), or creates a new property with that value if it does
+ * not already exist.
+ *
+ * This function may insert or delete data from the blob, and will
+ * therefore change the offsets of some existing nodes.
+ *
+ * returns:
+ * 0, on success
+ * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
+ * contain the new property value
+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
+ * -FDT_ERR_BADLAYOUT,
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_BADLAYOUT,
+ * -FDT_ERR_TRUNCATED, standard meanings
+ */
+static inline int fdt_setprop_u64(void *fdt, int nodeoffset, const char *name,
+ uint64_t val)
+{
+ fdt64_t tmp = cpu_to_fdt64(val);
+ return fdt_setprop(fdt, nodeoffset, name, &tmp, sizeof(tmp));
+}
+
+/**
+ * fdt_setprop_cell - set a property to a single cell value
+ *
+ * This is an alternative name for fdt_setprop_u32()
+ */
+static inline int fdt_setprop_cell(void *fdt, int nodeoffset, const char *name,
+ uint32_t val)
+{
+ return fdt_setprop_u32(fdt, nodeoffset, name, val);
+}
+
+/**
+ * fdt_setprop_string - set a property to a string value
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose property to change
+ * @name: name of the property to change
+ * @str: string value for the property
+ *
+ * fdt_setprop_string() sets the value of the named property in the
+ * given node to the given string value (using the length of the
+ * string to determine the new length of the property), or creates a
+ * new property with that value if it does not already exist.
+ *
+ * This function may insert or delete data from the blob, and will
+ * therefore change the offsets of some existing nodes.
+ *
+ * returns:
+ * 0, on success
+ * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
+ * contain the new property value
+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
+ * -FDT_ERR_BADLAYOUT,
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_BADLAYOUT,
+ * -FDT_ERR_TRUNCATED, standard meanings
+ */
+#define fdt_setprop_string(fdt, nodeoffset, name, str) \
+ fdt_setprop((fdt), (nodeoffset), (name), (str), strlen(str)+1)
+
+
+/**
+ * fdt_setprop_empty - set a property to an empty value
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose property to change
+ * @name: name of the property to change
+ *
+ * fdt_setprop_empty() sets the value of the named property in the
+ * given node to an empty (zero length) value, or creates a new empty
+ * property if it does not already exist.
+ *
+ * This function may insert or delete data from the blob, and will
+ * therefore change the offsets of some existing nodes.
+ *
+ * returns:
+ * 0, on success
+ * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
+ * contain the new property value
+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
+ * -FDT_ERR_BADLAYOUT,
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_BADLAYOUT,
+ * -FDT_ERR_TRUNCATED, standard meanings
+ */
+#define fdt_setprop_empty(fdt, nodeoffset, name) \
+ fdt_setprop((fdt), (nodeoffset), (name), NULL, 0)
+
+/**
+ * fdt_appendprop - append to or create a property
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose property to change
+ * @name: name of the property to append to
+ * @val: pointer to data to append to the property value
+ * @len: length of the data to append to the property value
+ *
+ * fdt_appendprop() appends the value to the named property in the
+ * given node, creating the property if it does not already exist.
+ *
+ * This function may insert data into the blob, and will therefore
+ * change the offsets of some existing nodes.
+ *
+ * returns:
+ * 0, on success
+ * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
+ * contain the new property value
+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
+ * -FDT_ERR_BADLAYOUT,
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_BADLAYOUT,
+ * -FDT_ERR_TRUNCATED, standard meanings
+ */
+int fdt_appendprop(void *fdt, int nodeoffset, const char *name,
+ const void *val, int len);
+
+/**
+ * fdt_appendprop_u32 - append a 32-bit integer value to a property
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose property to change
+ * @name: name of the property to change
+ * @val: 32-bit integer value to append to the property (native endian)
+ *
+ * fdt_appendprop_u32() appends the given 32-bit integer value
+ * (converting to big-endian if necessary) to the value of the named
+ * property in the given node, or creates a new property with that
+ * value if it does not already exist.
+ *
+ * This function may insert data into the blob, and will therefore
+ * change the offsets of some existing nodes.
+ *
+ * returns:
+ * 0, on success
+ * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
+ * contain the new property value
+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
+ * -FDT_ERR_BADLAYOUT,
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_BADLAYOUT,
+ * -FDT_ERR_TRUNCATED, standard meanings
+ */
+static inline int fdt_appendprop_u32(void *fdt, int nodeoffset,
+ const char *name, uint32_t val)
+{
+ fdt32_t tmp = cpu_to_fdt32(val);
+ return fdt_appendprop(fdt, nodeoffset, name, &tmp, sizeof(tmp));
+}
+
+/**
+ * fdt_appendprop_u64 - append a 64-bit integer value to a property
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose property to change
+ * @name: name of the property to change
+ * @val: 64-bit integer value to append to the property (native endian)
+ *
+ * fdt_appendprop_u64() appends the given 64-bit integer value
+ * (converting to big-endian if necessary) to the value of the named
+ * property in the given node, or creates a new property with that
+ * value if it does not already exist.
+ *
+ * This function may insert data into the blob, and will therefore
+ * change the offsets of some existing nodes.
+ *
+ * returns:
+ * 0, on success
+ * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
+ * contain the new property value
+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
+ * -FDT_ERR_BADLAYOUT,
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_BADLAYOUT,
+ * -FDT_ERR_TRUNCATED, standard meanings
+ */
+static inline int fdt_appendprop_u64(void *fdt, int nodeoffset,
+ const char *name, uint64_t val)
+{
+ fdt64_t tmp = cpu_to_fdt64(val);
+ return fdt_appendprop(fdt, nodeoffset, name, &tmp, sizeof(tmp));
+}
+
+/**
+ * fdt_appendprop_cell - append a single cell value to a property
+ *
+ * This is an alternative name for fdt_appendprop_u32()
+ */
+static inline int fdt_appendprop_cell(void *fdt, int nodeoffset,
+ const char *name, uint32_t val)
+{
+ return fdt_appendprop_u32(fdt, nodeoffset, name, val);
+}
+
+/**
+ * fdt_appendprop_string - append a string to a property
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose property to change
+ * @name: name of the property to change
+ * @str: string value to append to the property
+ *
+ * fdt_appendprop_string() appends the given string to the value of
+ * the named property in the given node, or creates a new property
+ * with that value if it does not already exist.
+ *
+ * This function may insert data into the blob, and will therefore
+ * change the offsets of some existing nodes.
+ *
+ * returns:
+ * 0, on success
+ * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
+ * contain the new property value
+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
+ * -FDT_ERR_BADLAYOUT,
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_BADLAYOUT,
+ * -FDT_ERR_TRUNCATED, standard meanings
+ */
+#define fdt_appendprop_string(fdt, nodeoffset, name, str) \
+ fdt_appendprop((fdt), (nodeoffset), (name), (str), strlen(str)+1)
+
+/**
+ * fdt_delprop - delete a property
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose property to nop
+ * @name: name of the property to nop
+ *
+ * fdt_del_property() will delete the given property.
+ *
+ * This function will delete data from the blob, and will therefore
+ * change the offsets of some existing nodes.
+ *
+ * returns:
+ * 0, on success
+ * -FDT_ERR_NOTFOUND, node does not have the named property
+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
+ * -FDT_ERR_BADLAYOUT,
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_TRUNCATED, standard meanings
+ */
+int fdt_delprop(void *fdt, int nodeoffset, const char *name);
+
+/**
+ * fdt_add_subnode_namelen - creates a new node based on substring
+ * @fdt: pointer to the device tree blob
+ * @parentoffset: structure block offset of a node
+ * @name: name of the subnode to locate
+ * @namelen: number of characters of name to consider
+ *
+ * Identical to fdt_add_subnode(), but use only the first namelen
+ * characters of name as the name of the new node. This is useful for
+ * creating subnodes based on a portion of a larger string, such as a
+ * full path.
+ */
+#ifndef SWIG /* Not available in Python */
+int fdt_add_subnode_namelen(void *fdt, int parentoffset,
+ const char *name, int namelen);
+#endif
+
+/**
+ * fdt_add_subnode - creates a new node
+ * @fdt: pointer to the device tree blob
+ * @parentoffset: structure block offset of a node
+ * @name: name of the subnode to locate
+ *
+ * fdt_add_subnode() creates a new node as a subnode of the node at
+ * structure block offset parentoffset, with the given name (which
+ * should include the unit address, if any).
+ *
+ * This function will insert data into the blob, and will therefore
+ * change the offsets of some existing nodes.
+
+ * returns:
+ * structure block offset of the created nodeequested subnode (>=0), on
+ * success
+ * -FDT_ERR_NOTFOUND, if the requested subnode does not exist
+ * -FDT_ERR_BADOFFSET, if parentoffset did not point to an FDT_BEGIN_NODE
+ * tag
+ * -FDT_ERR_EXISTS, if the node at parentoffset already has a subnode of
+ * the given name
+ * -FDT_ERR_NOSPACE, if there is insufficient free space in the
+ * blob to contain the new node
+ * -FDT_ERR_NOSPACE
+ * -FDT_ERR_BADLAYOUT
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_TRUNCATED, standard meanings.
+ */
+int fdt_add_subnode(void *fdt, int parentoffset, const char *name);
+
+/**
+ * fdt_del_node - delete a node (subtree)
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node to nop
+ *
+ * fdt_del_node() will remove the given node, including all its
+ * subnodes if any, from the blob.
+ *
+ * This function will delete data from the blob, and will therefore
+ * change the offsets of some existing nodes.
+ *
+ * returns:
+ * 0, on success
+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
+ * -FDT_ERR_BADLAYOUT,
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_TRUNCATED, standard meanings
+ */
+int fdt_del_node(void *fdt, int nodeoffset);
+
+/**
+ * fdt_overlay_apply - Applies a DT overlay on a base DT
+ * @fdt: pointer to the base device tree blob
+ * @fdto: pointer to the device tree overlay blob
+ *
+ * fdt_overlay_apply() will apply the given device tree overlay on the
+ * given base device tree.
+ *
+ * Expect the base device tree to be modified, even if the function
+ * returns an error.
+ *
+ * returns:
+ * 0, on success
+ * -FDT_ERR_NOSPACE, there's not enough space in the base device tree
+ * -FDT_ERR_NOTFOUND, the overlay points to some inexistant nodes or
+ * properties in the base DT
+ * -FDT_ERR_BADPHANDLE,
+ * -FDT_ERR_BADOVERLAY,
+ * -FDT_ERR_NOPHANDLES,
+ * -FDT_ERR_INTERNAL,
+ * -FDT_ERR_BADLAYOUT,
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADOFFSET,
+ * -FDT_ERR_BADPATH,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_TRUNCATED, standard meanings
+ */
+int fdt_overlay_apply(void *fdt, void *fdto);
+
+/**********************************************************************/
+/* Debugging / informational functions */
+/**********************************************************************/
+
+const char *fdt_strerror(int errval);
+
+#endif /* _LIBFDT_H */
diff --git a/scripts/dtc/libfdt/libfdt_env.h b/scripts/dtc/libfdt/libfdt_env.h
new file mode 100644
index 0000000000..952056cddf
--- /dev/null
+++ b/scripts/dtc/libfdt/libfdt_env.h
@@ -0,0 +1,112 @@
+#ifndef _LIBFDT_ENV_H
+#define _LIBFDT_ENV_H
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Copyright (C) 2006 David Gibson, IBM Corporation.
+ * Copyright 2012 Kim Phillips, Freescale Semiconductor.
+ *
+ * libfdt is dual licensed: you can use it either under the terms of
+ * the GPL, or the BSD license, at your option.
+ *
+ * a) This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Alternatively,
+ *
+ * b) Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stddef.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef __CHECKER__
+#define FDT_FORCE __attribute__((force))
+#define FDT_BITWISE __attribute__((bitwise))
+#else
+#define FDT_FORCE
+#define FDT_BITWISE
+#endif
+
+typedef uint16_t FDT_BITWISE fdt16_t;
+typedef uint32_t FDT_BITWISE fdt32_t;
+typedef uint64_t FDT_BITWISE fdt64_t;
+
+#define EXTRACT_BYTE(x, n) ((unsigned long long)((uint8_t *)&x)[n])
+#define CPU_TO_FDT16(x) ((EXTRACT_BYTE(x, 0) << 8) | EXTRACT_BYTE(x, 1))
+#define CPU_TO_FDT32(x) ((EXTRACT_BYTE(x, 0) << 24) | (EXTRACT_BYTE(x, 1) << 16) | \
+ (EXTRACT_BYTE(x, 2) << 8) | EXTRACT_BYTE(x, 3))
+#define CPU_TO_FDT64(x) ((EXTRACT_BYTE(x, 0) << 56) | (EXTRACT_BYTE(x, 1) << 48) | \
+ (EXTRACT_BYTE(x, 2) << 40) | (EXTRACT_BYTE(x, 3) << 32) | \
+ (EXTRACT_BYTE(x, 4) << 24) | (EXTRACT_BYTE(x, 5) << 16) | \
+ (EXTRACT_BYTE(x, 6) << 8) | EXTRACT_BYTE(x, 7))
+
+static inline uint16_t fdt16_to_cpu(fdt16_t x)
+{
+ return (FDT_FORCE uint16_t)CPU_TO_FDT16(x);
+}
+static inline fdt16_t cpu_to_fdt16(uint16_t x)
+{
+ return (FDT_FORCE fdt16_t)CPU_TO_FDT16(x);
+}
+
+static inline uint32_t fdt32_to_cpu(fdt32_t x)
+{
+ return (FDT_FORCE uint32_t)CPU_TO_FDT32(x);
+}
+static inline fdt32_t cpu_to_fdt32(uint32_t x)
+{
+ return (FDT_FORCE fdt32_t)CPU_TO_FDT32(x);
+}
+
+static inline uint64_t fdt64_to_cpu(fdt64_t x)
+{
+ return (FDT_FORCE uint64_t)CPU_TO_FDT64(x);
+}
+static inline fdt64_t cpu_to_fdt64(uint64_t x)
+{
+ return (FDT_FORCE fdt64_t)CPU_TO_FDT64(x);
+}
+#undef CPU_TO_FDT64
+#undef CPU_TO_FDT32
+#undef CPU_TO_FDT16
+#undef EXTRACT_BYTE
+
+#endif /* _LIBFDT_ENV_H */
diff --git a/scripts/dtc/libfdt/libfdt_internal.h b/scripts/dtc/libfdt/libfdt_internal.h
new file mode 100644
index 0000000000..02cfa6fb61
--- /dev/null
+++ b/scripts/dtc/libfdt/libfdt_internal.h
@@ -0,0 +1,95 @@
+#ifndef _LIBFDT_INTERNAL_H
+#define _LIBFDT_INTERNAL_H
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Copyright (C) 2006 David Gibson, IBM Corporation.
+ *
+ * libfdt is dual licensed: you can use it either under the terms of
+ * the GPL, or the BSD license, at your option.
+ *
+ * a) This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Alternatively,
+ *
+ * b) Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <fdt.h>
+
+#define FDT_ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
+#define FDT_TAGALIGN(x) (FDT_ALIGN((x), FDT_TAGSIZE))
+
+#define FDT_CHECK_HEADER(fdt) \
+ { \
+ int __err; \
+ if ((__err = fdt_check_header(fdt)) != 0) \
+ return __err; \
+ }
+
+int _fdt_check_node_offset(const void *fdt, int offset);
+int _fdt_check_prop_offset(const void *fdt, int offset);
+const char *_fdt_find_string(const char *strtab, int tabsize, const char *s);
+int _fdt_node_end_offset(void *fdt, int nodeoffset);
+
+static inline const void *_fdt_offset_ptr(const void *fdt, int offset)
+{
+ return (const char *)fdt + fdt_off_dt_struct(fdt) + offset;
+}
+
+static inline void *_fdt_offset_ptr_w(void *fdt, int offset)
+{
+ return (void *)(uintptr_t)_fdt_offset_ptr(fdt, offset);
+}
+
+static inline const struct fdt_reserve_entry *_fdt_mem_rsv(const void *fdt, int n)
+{
+ const struct fdt_reserve_entry *rsv_table =
+ (const struct fdt_reserve_entry *)
+ ((const char *)fdt + fdt_off_mem_rsvmap(fdt));
+
+ return rsv_table + n;
+}
+static inline struct fdt_reserve_entry *_fdt_mem_rsv_w(void *fdt, int n)
+{
+ return (void *)(uintptr_t)_fdt_mem_rsv(fdt, n);
+}
+
+#define FDT_SW_MAGIC (~FDT_MAGIC)
+
+#endif /* _LIBFDT_INTERNAL_H */
diff --git a/scripts/dtc/livetree.c b/scripts/dtc/livetree.c
new file mode 100644
index 0000000000..aecd27875f
--- /dev/null
+++ b/scripts/dtc/livetree.c
@@ -0,0 +1,981 @@
+/*
+ * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2005.
+ *
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ */
+
+#include "dtc.h"
+
+/*
+ * Tree building functions
+ */
+
+void add_label(struct label **labels, char *label)
+{
+ struct label *new;
+
+ /* Make sure the label isn't already there */
+ for_each_label_withdel(*labels, new)
+ if (streq(new->label, label)) {
+ new->deleted = 0;
+ return;
+ }
+
+ new = xmalloc(sizeof(*new));
+ memset(new, 0, sizeof(*new));
+ new->label = label;
+ new->next = *labels;
+ *labels = new;
+}
+
+void delete_labels(struct label **labels)
+{
+ struct label *label;
+
+ for_each_label(*labels, label)
+ label->deleted = 1;
+}
+
+struct property *build_property(char *name, struct data val)
+{
+ struct property *new = xmalloc(sizeof(*new));
+
+ memset(new, 0, sizeof(*new));
+
+ new->name = name;
+ new->val = val;
+
+ return new;
+}
+
+struct property *build_property_delete(char *name)
+{
+ struct property *new = xmalloc(sizeof(*new));
+
+ memset(new, 0, sizeof(*new));
+
+ new->name = name;
+ new->deleted = 1;
+
+ return new;
+}
+
+struct property *chain_property(struct property *first, struct property *list)
+{
+ assert(first->next == NULL);
+
+ first->next = list;
+ return first;
+}
+
+struct property *reverse_properties(struct property *first)
+{
+ struct property *p = first;
+ struct property *head = NULL;
+ struct property *next;
+
+ while (p) {
+ next = p->next;
+ p->next = head;
+ head = p;
+ p = next;
+ }
+ return head;
+}
+
+struct node *build_node(struct property *proplist, struct node *children)
+{
+ struct node *new = xmalloc(sizeof(*new));
+ struct node *child;
+
+ memset(new, 0, sizeof(*new));
+
+ new->proplist = reverse_properties(proplist);
+ new->children = children;
+
+ for_each_child(new, child) {
+ child->parent = new;
+ }
+
+ return new;
+}
+
+struct node *build_node_delete(void)
+{
+ struct node *new = xmalloc(sizeof(*new));
+
+ memset(new, 0, sizeof(*new));
+
+ new->deleted = 1;
+
+ return new;
+}
+
+struct node *name_node(struct node *node, char *name)
+{
+ assert(node->name == NULL);
+
+ node->name = name;
+
+ return node;
+}
+
+struct node *merge_nodes(struct node *old_node, struct node *new_node)
+{
+ struct property *new_prop, *old_prop;
+ struct node *new_child, *old_child;
+ struct label *l;
+
+ old_node->deleted = 0;
+
+ /* Add new node labels to old node */
+ for_each_label_withdel(new_node->labels, l)
+ add_label(&old_node->labels, l->label);
+
+ /* Move properties from the new node to the old node. If there
+ * is a collision, replace the old value with the new */
+ while (new_node->proplist) {
+ /* Pop the property off the list */
+ new_prop = new_node->proplist;
+ new_node->proplist = new_prop->next;
+ new_prop->next = NULL;
+
+ if (new_prop->deleted) {
+ delete_property_by_name(old_node, new_prop->name);
+ free(new_prop);
+ continue;
+ }
+
+ /* Look for a collision, set new value if there is */
+ for_each_property_withdel(old_node, old_prop) {
+ if (streq(old_prop->name, new_prop->name)) {
+ /* Add new labels to old property */
+ for_each_label_withdel(new_prop->labels, l)
+ add_label(&old_prop->labels, l->label);
+
+ old_prop->val = new_prop->val;
+ old_prop->deleted = 0;
+ free(new_prop);
+ new_prop = NULL;
+ break;
+ }
+ }
+
+ /* if no collision occurred, add property to the old node. */
+ if (new_prop)
+ add_property(old_node, new_prop);
+ }
+
+ /* Move the override child nodes into the primary node. If
+ * there is a collision, then merge the nodes. */
+ while (new_node->children) {
+ /* Pop the child node off the list */
+ new_child = new_node->children;
+ new_node->children = new_child->next_sibling;
+ new_child->parent = NULL;
+ new_child->next_sibling = NULL;
+
+ if (new_child->deleted) {
+ delete_node_by_name(old_node, new_child->name);
+ free(new_child);
+ continue;
+ }
+
+ /* Search for a collision. Merge if there is */
+ for_each_child_withdel(old_node, old_child) {
+ if (streq(old_child->name, new_child->name)) {
+ merge_nodes(old_child, new_child);
+ new_child = NULL;
+ break;
+ }
+ }
+
+ /* if no collision occurred, add child to the old node. */
+ if (new_child)
+ add_child(old_node, new_child);
+ }
+
+ /* The new node contents are now merged into the old node. Free
+ * the new node. */
+ free(new_node);
+
+ return old_node;
+}
+
+struct node *chain_node(struct node *first, struct node *list)
+{
+ assert(first->next_sibling == NULL);
+
+ first->next_sibling = list;
+ return first;
+}
+
+void add_property(struct node *node, struct property *prop)
+{
+ struct property **p;
+
+ prop->next = NULL;
+
+ p = &node->proplist;
+ while (*p)
+ p = &((*p)->next);
+
+ *p = prop;
+}
+
+void delete_property_by_name(struct node *node, char *name)
+{
+ struct property *prop = node->proplist;
+
+ while (prop) {
+ if (streq(prop->name, name)) {
+ delete_property(prop);
+ return;
+ }
+ prop = prop->next;
+ }
+}
+
+void delete_property(struct property *prop)
+{
+ prop->deleted = 1;
+ delete_labels(&prop->labels);
+}
+
+void add_child(struct node *parent, struct node *child)
+{
+ struct node **p;
+
+ child->next_sibling = NULL;
+ child->parent = parent;
+
+ p = &parent->children;
+ while (*p)
+ p = &((*p)->next_sibling);
+
+ *p = child;
+}
+
+void delete_node_by_name(struct node *parent, char *name)
+{
+ struct node *node = parent->children;
+
+ while (node) {
+ if (streq(node->name, name)) {
+ delete_node(node);
+ return;
+ }
+ node = node->next_sibling;
+ }
+}
+
+void delete_node(struct node *node)
+{
+ struct property *prop;
+ struct node *child;
+
+ node->deleted = 1;
+ for_each_child(node, child)
+ delete_node(child);
+ for_each_property(node, prop)
+ delete_property(prop);
+ delete_labels(&node->labels);
+}
+
+void append_to_property(struct node *node,
+ char *name, const void *data, int len)
+{
+ struct data d;
+ struct property *p;
+
+ p = get_property(node, name);
+ if (p) {
+ d = data_append_data(p->val, data, len);
+ p->val = d;
+ } else {
+ d = data_append_data(empty_data, data, len);
+ p = build_property(name, d);
+ add_property(node, p);
+ }
+}
+
+struct reserve_info *build_reserve_entry(uint64_t address, uint64_t size)
+{
+ struct reserve_info *new = xmalloc(sizeof(*new));
+
+ memset(new, 0, sizeof(*new));
+
+ new->address = address;
+ new->size = size;
+
+ return new;
+}
+
+struct reserve_info *chain_reserve_entry(struct reserve_info *first,
+ struct reserve_info *list)
+{
+ assert(first->next == NULL);
+
+ first->next = list;
+ return first;
+}
+
+struct reserve_info *add_reserve_entry(struct reserve_info *list,
+ struct reserve_info *new)
+{
+ struct reserve_info *last;
+
+ new->next = NULL;
+
+ if (! list)
+ return new;
+
+ for (last = list; last->next; last = last->next)
+ ;
+
+ last->next = new;
+
+ return list;
+}
+
+struct dt_info *build_dt_info(unsigned int dtsflags,
+ struct reserve_info *reservelist,
+ struct node *tree, uint32_t boot_cpuid_phys)
+{
+ struct dt_info *dti;
+
+ dti = xmalloc(sizeof(*dti));
+ dti->dtsflags = dtsflags;
+ dti->reservelist = reservelist;
+ dti->dt = tree;
+ dti->boot_cpuid_phys = boot_cpuid_phys;
+
+ return dti;
+}
+
+/*
+ * Tree accessor functions
+ */
+
+const char *get_unitname(struct node *node)
+{
+ if (node->name[node->basenamelen] == '\0')
+ return "";
+ else
+ return node->name + node->basenamelen + 1;
+}
+
+struct property *get_property(struct node *node, const char *propname)
+{
+ struct property *prop;
+
+ for_each_property(node, prop)
+ if (streq(prop->name, propname))
+ return prop;
+
+ return NULL;
+}
+
+cell_t propval_cell(struct property *prop)
+{
+ assert(prop->val.len == sizeof(cell_t));
+ return fdt32_to_cpu(*((fdt32_t *)prop->val.val));
+}
+
+struct property *get_property_by_label(struct node *tree, const char *label,
+ struct node **node)
+{
+ struct property *prop;
+ struct node *c;
+
+ *node = tree;
+
+ for_each_property(tree, prop) {
+ struct label *l;
+
+ for_each_label(prop->labels, l)
+ if (streq(l->label, label))
+ return prop;
+ }
+
+ for_each_child(tree, c) {
+ prop = get_property_by_label(c, label, node);
+ if (prop)
+ return prop;
+ }
+
+ *node = NULL;
+ return NULL;
+}
+
+struct marker *get_marker_label(struct node *tree, const char *label,
+ struct node **node, struct property **prop)
+{
+ struct marker *m;
+ struct property *p;
+ struct node *c;
+
+ *node = tree;
+
+ for_each_property(tree, p) {
+ *prop = p;
+ m = p->val.markers;
+ for_each_marker_of_type(m, LABEL)
+ if (streq(m->ref, label))
+ return m;
+ }
+
+ for_each_child(tree, c) {
+ m = get_marker_label(c, label, node, prop);
+ if (m)
+ return m;
+ }
+
+ *prop = NULL;
+ *node = NULL;
+ return NULL;
+}
+
+struct node *get_subnode(struct node *node, const char *nodename)
+{
+ struct node *child;
+
+ for_each_child(node, child)
+ if (streq(child->name, nodename))
+ return child;
+
+ return NULL;
+}
+
+struct node *get_node_by_path(struct node *tree, const char *path)
+{
+ const char *p;
+ struct node *child;
+
+ if (!path || ! (*path)) {
+ if (tree->deleted)
+ return NULL;
+ return tree;
+ }
+
+ while (path[0] == '/')
+ path++;
+
+ p = strchr(path, '/');
+
+ for_each_child(tree, child) {
+ if (p && (strlen(child->name) == p-path) &&
+ strneq(path, child->name, p-path))
+ return get_node_by_path(child, p+1);
+ else if (!p && streq(path, child->name))
+ return child;
+ }
+
+ return NULL;
+}
+
+struct node *get_node_by_label(struct node *tree, const char *label)
+{
+ struct node *child, *node;
+ struct label *l;
+
+ assert(label && (strlen(label) > 0));
+
+ for_each_label(tree->labels, l)
+ if (streq(l->label, label))
+ return tree;
+
+ for_each_child(tree, child) {
+ node = get_node_by_label(child, label);
+ if (node)
+ return node;
+ }
+
+ return NULL;
+}
+
+struct node *get_node_by_phandle(struct node *tree, cell_t phandle)
+{
+ struct node *child, *node;
+
+ assert((phandle != 0) && (phandle != -1));
+
+ if (tree->phandle == phandle) {
+ if (tree->deleted)
+ return NULL;
+ return tree;
+ }
+
+ for_each_child(tree, child) {
+ node = get_node_by_phandle(child, phandle);
+ if (node)
+ return node;
+ }
+
+ return NULL;
+}
+
+struct node *get_node_by_ref(struct node *tree, const char *ref)
+{
+ if (streq(ref, "/"))
+ return tree;
+ else if (ref[0] == '/')
+ return get_node_by_path(tree, ref);
+ else
+ return get_node_by_label(tree, ref);
+}
+
+cell_t get_node_phandle(struct node *root, struct node *node)
+{
+ static cell_t phandle = 1; /* FIXME: ick, static local */
+
+ if ((node->phandle != 0) && (node->phandle != -1))
+ return node->phandle;
+
+ while (get_node_by_phandle(root, phandle))
+ phandle++;
+
+ node->phandle = phandle;
+
+ if (!get_property(node, "linux,phandle")
+ && (phandle_format & PHANDLE_LEGACY))
+ add_property(node,
+ build_property("linux,phandle",
+ data_append_cell(empty_data, phandle)));
+
+ if (!get_property(node, "phandle")
+ && (phandle_format & PHANDLE_EPAPR))
+ add_property(node,
+ build_property("phandle",
+ data_append_cell(empty_data, phandle)));
+
+ /* If the node *does* have a phandle property, we must
+ * be dealing with a self-referencing phandle, which will be
+ * fixed up momentarily in the caller */
+
+ return node->phandle;
+}
+
+uint32_t guess_boot_cpuid(struct node *tree)
+{
+ struct node *cpus, *bootcpu;
+ struct property *reg;
+
+ cpus = get_node_by_path(tree, "/cpus");
+ if (!cpus)
+ return 0;
+
+
+ bootcpu = cpus->children;
+ if (!bootcpu)
+ return 0;
+
+ reg = get_property(bootcpu, "reg");
+ if (!reg || (reg->val.len != sizeof(uint32_t)))
+ return 0;
+
+ /* FIXME: Sanity check node? */
+
+ return propval_cell(reg);
+}
+
+static int cmp_reserve_info(const void *ax, const void *bx)
+{
+ const struct reserve_info *a, *b;
+
+ a = *((const struct reserve_info * const *)ax);
+ b = *((const struct reserve_info * const *)bx);
+
+ if (a->address < b->address)
+ return -1;
+ else if (a->address > b->address)
+ return 1;
+ else if (a->size < b->size)
+ return -1;
+ else if (a->size > b->size)
+ return 1;
+ else
+ return 0;
+}
+
+static void sort_reserve_entries(struct dt_info *dti)
+{
+ struct reserve_info *ri, **tbl;
+ int n = 0, i = 0;
+
+ for (ri = dti->reservelist;
+ ri;
+ ri = ri->next)
+ n++;
+
+ if (n == 0)
+ return;
+
+ tbl = xmalloc(n * sizeof(*tbl));
+
+ for (ri = dti->reservelist;
+ ri;
+ ri = ri->next)
+ tbl[i++] = ri;
+
+ qsort(tbl, n, sizeof(*tbl), cmp_reserve_info);
+
+ dti->reservelist = tbl[0];
+ for (i = 0; i < (n-1); i++)
+ tbl[i]->next = tbl[i+1];
+ tbl[n-1]->next = NULL;
+
+ free(tbl);
+}
+
+static int cmp_prop(const void *ax, const void *bx)
+{
+ const struct property *a, *b;
+
+ a = *((const struct property * const *)ax);
+ b = *((const struct property * const *)bx);
+
+ return strcmp(a->name, b->name);
+}
+
+static void sort_properties(struct node *node)
+{
+ int n = 0, i = 0;
+ struct property *prop, **tbl;
+
+ for_each_property_withdel(node, prop)
+ n++;
+
+ if (n == 0)
+ return;
+
+ tbl = xmalloc(n * sizeof(*tbl));
+
+ for_each_property_withdel(node, prop)
+ tbl[i++] = prop;
+
+ qsort(tbl, n, sizeof(*tbl), cmp_prop);
+
+ node->proplist = tbl[0];
+ for (i = 0; i < (n-1); i++)
+ tbl[i]->next = tbl[i+1];
+ tbl[n-1]->next = NULL;
+
+ free(tbl);
+}
+
+static int cmp_subnode(const void *ax, const void *bx)
+{
+ const struct node *a, *b;
+
+ a = *((const struct node * const *)ax);
+ b = *((const struct node * const *)bx);
+
+ return strcmp(a->name, b->name);
+}
+
+static void sort_subnodes(struct node *node)
+{
+ int n = 0, i = 0;
+ struct node *subnode, **tbl;
+
+ for_each_child_withdel(node, subnode)
+ n++;
+
+ if (n == 0)
+ return;
+
+ tbl = xmalloc(n * sizeof(*tbl));
+
+ for_each_child_withdel(node, subnode)
+ tbl[i++] = subnode;
+
+ qsort(tbl, n, sizeof(*tbl), cmp_subnode);
+
+ node->children = tbl[0];
+ for (i = 0; i < (n-1); i++)
+ tbl[i]->next_sibling = tbl[i+1];
+ tbl[n-1]->next_sibling = NULL;
+
+ free(tbl);
+}
+
+static void sort_node(struct node *node)
+{
+ struct node *c;
+
+ sort_properties(node);
+ sort_subnodes(node);
+ for_each_child_withdel(node, c)
+ sort_node(c);
+}
+
+void sort_tree(struct dt_info *dti)
+{
+ sort_reserve_entries(dti);
+ sort_node(dti->dt);
+}
+
+/* utility helper to avoid code duplication */
+static struct node *build_and_name_child_node(struct node *parent, char *name)
+{
+ struct node *node;
+
+ node = build_node(NULL, NULL);
+ name_node(node, xstrdup(name));
+ add_child(parent, node);
+
+ return node;
+}
+
+static struct node *build_root_node(struct node *dt, char *name)
+{
+ struct node *an;
+
+ an = get_subnode(dt, name);
+ if (!an)
+ an = build_and_name_child_node(dt, name);
+
+ if (!an)
+ die("Could not build root node /%s\n", name);
+
+ return an;
+}
+
+static bool any_label_tree(struct dt_info *dti, struct node *node)
+{
+ struct node *c;
+
+ if (node->labels)
+ return true;
+
+ for_each_child(node, c)
+ if (any_label_tree(dti, c))
+ return true;
+
+ return false;
+}
+
+static void generate_label_tree_internal(struct dt_info *dti,
+ struct node *an, struct node *node,
+ bool allocph)
+{
+ struct node *dt = dti->dt;
+ struct node *c;
+ struct property *p;
+ struct label *l;
+
+ /* if there are labels */
+ if (node->labels) {
+
+ /* now add the label in the node */
+ for_each_label(node->labels, l) {
+
+ /* check whether the label already exists */
+ p = get_property(an, l->label);
+ if (p) {
+ fprintf(stderr, "WARNING: label %s already"
+ " exists in /%s", l->label,
+ an->name);
+ continue;
+ }
+
+ /* insert it */
+ p = build_property(l->label,
+ data_copy_mem(node->fullpath,
+ strlen(node->fullpath) + 1));
+ add_property(an, p);
+ }
+
+ /* force allocation of a phandle for this node */
+ if (allocph)
+ (void)get_node_phandle(dt, node);
+ }
+
+ for_each_child(node, c)
+ generate_label_tree_internal(dti, an, c, allocph);
+}
+
+static bool any_fixup_tree(struct dt_info *dti, struct node *node)
+{
+ struct node *c;
+ struct property *prop;
+ struct marker *m;
+
+ for_each_property(node, prop) {
+ m = prop->val.markers;
+ for_each_marker_of_type(m, REF_PHANDLE) {
+ if (!get_node_by_ref(dti->dt, m->ref))
+ return true;
+ }
+ }
+
+ for_each_child(node, c) {
+ if (any_fixup_tree(dti, c))
+ return true;
+ }
+
+ return false;
+}
+
+static void add_fixup_entry(struct dt_info *dti, struct node *fn,
+ struct node *node, struct property *prop,
+ struct marker *m)
+{
+ char *entry;
+
+ /* m->ref can only be a REF_PHANDLE, but check anyway */
+ assert(m->type == REF_PHANDLE);
+
+ /* there shouldn't be any ':' in the arguments */
+ if (strchr(node->fullpath, ':') || strchr(prop->name, ':'))
+ die("arguments should not contain ':'\n");
+
+ xasprintf(&entry, "%s:%s:%u",
+ node->fullpath, prop->name, m->offset);
+ append_to_property(fn, m->ref, entry, strlen(entry) + 1);
+
+ free(entry);
+}
+
+static void generate_fixups_tree_internal(struct dt_info *dti,
+ struct node *fn,
+ struct node *node)
+{
+ struct node *dt = dti->dt;
+ struct node *c;
+ struct property *prop;
+ struct marker *m;
+ struct node *refnode;
+
+ for_each_property(node, prop) {
+ m = prop->val.markers;
+ for_each_marker_of_type(m, REF_PHANDLE) {
+ refnode = get_node_by_ref(dt, m->ref);
+ if (!refnode)
+ add_fixup_entry(dti, fn, node, prop, m);
+ }
+ }
+
+ for_each_child(node, c)
+ generate_fixups_tree_internal(dti, fn, c);
+}
+
+static bool any_local_fixup_tree(struct dt_info *dti, struct node *node)
+{
+ struct node *c;
+ struct property *prop;
+ struct marker *m;
+
+ for_each_property(node, prop) {
+ m = prop->val.markers;
+ for_each_marker_of_type(m, REF_PHANDLE) {
+ if (get_node_by_ref(dti->dt, m->ref))
+ return true;
+ }
+ }
+
+ for_each_child(node, c) {
+ if (any_local_fixup_tree(dti, c))
+ return true;
+ }
+
+ return false;
+}
+
+static void add_local_fixup_entry(struct dt_info *dti,
+ struct node *lfn, struct node *node,
+ struct property *prop, struct marker *m,
+ struct node *refnode)
+{
+ struct node *wn, *nwn; /* local fixup node, walk node, new */
+ fdt32_t value_32;
+ char **compp;
+ int i, depth;
+
+ /* walk back retreiving depth */
+ depth = 0;
+ for (wn = node; wn; wn = wn->parent)
+ depth++;
+
+ /* allocate name array */
+ compp = xmalloc(sizeof(*compp) * depth);
+
+ /* store names in the array */
+ for (wn = node, i = depth - 1; wn; wn = wn->parent, i--)
+ compp[i] = wn->name;
+
+ /* walk the path components creating nodes if they don't exist */
+ for (wn = lfn, i = 1; i < depth; i++, wn = nwn) {
+ /* if no node exists, create it */
+ nwn = get_subnode(wn, compp[i]);
+ if (!nwn)
+ nwn = build_and_name_child_node(wn, compp[i]);
+ }
+
+ free(compp);
+
+ value_32 = cpu_to_fdt32(m->offset);
+ append_to_property(wn, prop->name, &value_32, sizeof(value_32));
+}
+
+static void generate_local_fixups_tree_internal(struct dt_info *dti,
+ struct node *lfn,
+ struct node *node)
+{
+ struct node *dt = dti->dt;
+ struct node *c;
+ struct property *prop;
+ struct marker *m;
+ struct node *refnode;
+
+ for_each_property(node, prop) {
+ m = prop->val.markers;
+ for_each_marker_of_type(m, REF_PHANDLE) {
+ refnode = get_node_by_ref(dt, m->ref);
+ if (refnode)
+ add_local_fixup_entry(dti, lfn, node, prop, m, refnode);
+ }
+ }
+
+ for_each_child(node, c)
+ generate_local_fixups_tree_internal(dti, lfn, c);
+}
+
+void generate_label_tree(struct dt_info *dti, char *name, bool allocph)
+{
+ if (!any_label_tree(dti, dti->dt))
+ return;
+ generate_label_tree_internal(dti, build_root_node(dti->dt, name),
+ dti->dt, allocph);
+}
+
+void generate_fixups_tree(struct dt_info *dti, char *name)
+{
+ if (!any_fixup_tree(dti, dti->dt))
+ return;
+ generate_fixups_tree_internal(dti, build_root_node(dti->dt, name),
+ dti->dt);
+}
+
+void generate_local_fixups_tree(struct dt_info *dti, char *name)
+{
+ if (!any_local_fixup_tree(dti, dti->dt))
+ return;
+ generate_local_fixups_tree_internal(dti, build_root_node(dti->dt, name),
+ dti->dt);
+}
diff --git a/scripts/dtc/srcpos.c b/scripts/dtc/srcpos.c
new file mode 100644
index 0000000000..9d38459902
--- /dev/null
+++ b/scripts/dtc/srcpos.c
@@ -0,0 +1,302 @@
+/*
+ * Copyright 2007 Jon Loeliger, Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ */
+
+#define _GNU_SOURCE
+
+#include <stdio.h>
+
+#include "dtc.h"
+#include "srcpos.h"
+
+/* A node in our list of directories to search for source/include files */
+struct search_path {
+ struct search_path *next; /* next node in list, NULL for end */
+ const char *dirname; /* name of directory to search */
+};
+
+/* This is the list of directories that we search for source files */
+static struct search_path *search_path_head, **search_path_tail;
+
+
+static char *get_dirname(const char *path)
+{
+ const char *slash = strrchr(path, '/');
+
+ if (slash) {
+ int len = slash - path;
+ char *dir = xmalloc(len + 1);
+
+ memcpy(dir, path, len);
+ dir[len] = '\0';
+ return dir;
+ }
+ return NULL;
+}
+
+FILE *depfile; /* = NULL */
+struct srcfile_state *current_srcfile; /* = NULL */
+
+/* Detect infinite include recursion. */
+#define MAX_SRCFILE_DEPTH (100)
+static int srcfile_depth; /* = 0 */
+
+
+/**
+ * Try to open a file in a given directory.
+ *
+ * If the filename is an absolute path, then dirname is ignored. If it is a
+ * relative path, then we look in that directory for the file.
+ *
+ * @param dirname Directory to look in, or NULL for none
+ * @param fname Filename to look for
+ * @param fp Set to NULL if file did not open
+ * @return allocated filename on success (caller must free), NULL on failure
+ */
+static char *try_open(const char *dirname, const char *fname, FILE **fp)
+{
+ char *fullname;
+
+ if (!dirname || fname[0] == '/')
+ fullname = xstrdup(fname);
+ else
+ fullname = join_path(dirname, fname);
+
+ *fp = fopen(fullname, "rb");
+ if (!*fp) {
+ free(fullname);
+ fullname = NULL;
+ }
+
+ return fullname;
+}
+
+/**
+ * Open a file for read access
+ *
+ * If it is a relative filename, we search the full search path for it.
+ *
+ * @param fname Filename to open
+ * @param fp Returns pointer to opened FILE, or NULL on failure
+ * @return pointer to allocated filename, which caller must free
+ */
+static char *fopen_any_on_path(const char *fname, FILE **fp)
+{
+ const char *cur_dir = NULL;
+ struct search_path *node;
+ char *fullname;
+
+ /* Try current directory first */
+ assert(fp);
+ if (current_srcfile)
+ cur_dir = current_srcfile->dir;
+ fullname = try_open(cur_dir, fname, fp);
+
+ /* Failing that, try each search path in turn */
+ for (node = search_path_head; !*fp && node; node = node->next)
+ fullname = try_open(node->dirname, fname, fp);
+
+ return fullname;
+}
+
+FILE *srcfile_relative_open(const char *fname, char **fullnamep)
+{
+ FILE *f;
+ char *fullname;
+
+ if (streq(fname, "-")) {
+ f = stdin;
+ fullname = xstrdup("<stdin>");
+ } else {
+ fullname = fopen_any_on_path(fname, &f);
+ if (!f)
+ die("Couldn't open \"%s\": %s\n", fname,
+ strerror(errno));
+ }
+
+ if (depfile)
+ fprintf(depfile, " %s", fullname);
+
+ if (fullnamep)
+ *fullnamep = fullname;
+ else
+ free(fullname);
+
+ return f;
+}
+
+void srcfile_push(const char *fname)
+{
+ struct srcfile_state *srcfile;
+
+ if (srcfile_depth++ >= MAX_SRCFILE_DEPTH)
+ die("Includes nested too deeply");
+
+ srcfile = xmalloc(sizeof(*srcfile));
+
+ srcfile->f = srcfile_relative_open(fname, &srcfile->name);
+ srcfile->dir = get_dirname(srcfile->name);
+ srcfile->prev = current_srcfile;
+
+ srcfile->lineno = 1;
+ srcfile->colno = 1;
+
+ current_srcfile = srcfile;
+}
+
+bool srcfile_pop(void)
+{
+ struct srcfile_state *srcfile = current_srcfile;
+
+ assert(srcfile);
+
+ current_srcfile = srcfile->prev;
+
+ if (fclose(srcfile->f))
+ die("Error closing \"%s\": %s\n", srcfile->name,
+ strerror(errno));
+
+ /* FIXME: We allow the srcfile_state structure to leak,
+ * because it could still be referenced from a location
+ * variable being carried through the parser somewhere. To
+ * fix this we could either allocate all the files from a
+ * table, or use a pool allocator. */
+
+ return current_srcfile ? true : false;
+}
+
+void srcfile_add_search_path(const char *dirname)
+{
+ struct search_path *node;
+
+ /* Create the node */
+ node = xmalloc(sizeof(*node));
+ node->next = NULL;
+ node->dirname = xstrdup(dirname);
+
+ /* Add to the end of our list */
+ if (search_path_tail)
+ *search_path_tail = node;
+ else
+ search_path_head = node;
+ search_path_tail = &node->next;
+}
+
+/*
+ * The empty source position.
+ */
+
+struct srcpos srcpos_empty = {
+ .first_line = 0,
+ .first_column = 0,
+ .last_line = 0,
+ .last_column = 0,
+ .file = NULL,
+};
+
+#define TAB_SIZE 8
+
+void srcpos_update(struct srcpos *pos, const char *text, int len)
+{
+ int i;
+
+ pos->file = current_srcfile;
+
+ pos->first_line = current_srcfile->lineno;
+ pos->first_column = current_srcfile->colno;
+
+ for (i = 0; i < len; i++)
+ if (text[i] == '\n') {
+ current_srcfile->lineno++;
+ current_srcfile->colno = 1;
+ } else if (text[i] == '\t') {
+ current_srcfile->colno =
+ ALIGN(current_srcfile->colno, TAB_SIZE);
+ } else {
+ current_srcfile->colno++;
+ }
+
+ pos->last_line = current_srcfile->lineno;
+ pos->last_column = current_srcfile->colno;
+}
+
+struct srcpos *
+srcpos_copy(struct srcpos *pos)
+{
+ struct srcpos *pos_new;
+
+ pos_new = xmalloc(sizeof(struct srcpos));
+ memcpy(pos_new, pos, sizeof(struct srcpos));
+
+ return pos_new;
+}
+
+char *
+srcpos_string(struct srcpos *pos)
+{
+ const char *fname = "<no-file>";
+ char *pos_str;
+
+ if (pos->file && pos->file->name)
+ fname = pos->file->name;
+
+
+ if (pos->first_line != pos->last_line)
+ xasprintf(&pos_str, "%s:%d.%d-%d.%d", fname,
+ pos->first_line, pos->first_column,
+ pos->last_line, pos->last_column);
+ else if (pos->first_column != pos->last_column)
+ xasprintf(&pos_str, "%s:%d.%d-%d", fname,
+ pos->first_line, pos->first_column,
+ pos->last_column);
+ else
+ xasprintf(&pos_str, "%s:%d.%d", fname,
+ pos->first_line, pos->first_column);
+
+ return pos_str;
+}
+
+void srcpos_verror(struct srcpos *pos, const char *prefix,
+ const char *fmt, va_list va)
+{
+ char *srcstr;
+
+ srcstr = srcpos_string(pos);
+
+ fprintf(stderr, "%s: %s ", prefix, srcstr);
+ vfprintf(stderr, fmt, va);
+ fprintf(stderr, "\n");
+
+ free(srcstr);
+}
+
+void srcpos_error(struct srcpos *pos, const char *prefix,
+ const char *fmt, ...)
+{
+ va_list va;
+
+ va_start(va, fmt);
+ srcpos_verror(pos, prefix, fmt, va);
+ va_end(va);
+}
+
+void srcpos_set_line(char *f, int l)
+{
+ current_srcfile->name = f;
+ current_srcfile->lineno = l;
+}
diff --git a/scripts/dtc/srcpos.h b/scripts/dtc/srcpos.h
new file mode 100644
index 0000000000..7caca8257c
--- /dev/null
+++ b/scripts/dtc/srcpos.h
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2007 Jon Loeliger, Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ */
+
+#ifndef _SRCPOS_H_
+#define _SRCPOS_H_
+
+#include <stdio.h>
+#include <stdbool.h>
+#include "util.h"
+
+struct srcfile_state {
+ FILE *f;
+ char *name;
+ char *dir;
+ int lineno, colno;
+ struct srcfile_state *prev;
+};
+
+extern FILE *depfile; /* = NULL */
+extern struct srcfile_state *current_srcfile; /* = NULL */
+
+/**
+ * Open a source file.
+ *
+ * If the source file is a relative pathname, then it is searched for in the
+ * current directory (the directory of the last source file read) and after
+ * that in the search path.
+ *
+ * We work through the search path in order from the first path specified to
+ * the last.
+ *
+ * If the file is not found, then this function does not return, but calls
+ * die().
+ *
+ * @param fname Filename to search
+ * @param fullnamep If non-NULL, it is set to the allocated filename of the
+ * file that was opened. The caller is then responsible
+ * for freeing the pointer.
+ * @return pointer to opened FILE
+ */
+FILE *srcfile_relative_open(const char *fname, char **fullnamep);
+
+void srcfile_push(const char *fname);
+bool srcfile_pop(void);
+
+/**
+ * Add a new directory to the search path for input files
+ *
+ * The new path is added at the end of the list.
+ *
+ * @param dirname Directory to add
+ */
+void srcfile_add_search_path(const char *dirname);
+
+struct srcpos {
+ int first_line;
+ int first_column;
+ int last_line;
+ int last_column;
+ struct srcfile_state *file;
+};
+
+#define YYLTYPE struct srcpos
+
+#define YYLLOC_DEFAULT(Current, Rhs, N) \
+ do { \
+ if (N) { \
+ (Current).first_line = YYRHSLOC(Rhs, 1).first_line; \
+ (Current).first_column = YYRHSLOC(Rhs, 1).first_column; \
+ (Current).last_line = YYRHSLOC(Rhs, N).last_line; \
+ (Current).last_column = YYRHSLOC (Rhs, N).last_column; \
+ (Current).file = YYRHSLOC(Rhs, N).file; \
+ } else { \
+ (Current).first_line = (Current).last_line = \
+ YYRHSLOC(Rhs, 0).last_line; \
+ (Current).first_column = (Current).last_column = \
+ YYRHSLOC(Rhs, 0).last_column; \
+ (Current).file = YYRHSLOC (Rhs, 0).file; \
+ } \
+ } while (0)
+
+
+/*
+ * Fictional source position used for IR nodes that are
+ * created without otherwise knowing a true source position.
+ * For example,constant definitions from the command line.
+ */
+extern struct srcpos srcpos_empty;
+
+extern void srcpos_update(struct srcpos *pos, const char *text, int len);
+extern struct srcpos *srcpos_copy(struct srcpos *pos);
+extern char *srcpos_string(struct srcpos *pos);
+
+extern void PRINTF(3, 0) srcpos_verror(struct srcpos *pos, const char *prefix,
+ const char *fmt, va_list va);
+extern void PRINTF(3, 4) srcpos_error(struct srcpos *pos, const char *prefix,
+ const char *fmt, ...);
+
+extern void srcpos_set_line(char *f, int l);
+
+#endif /* _SRCPOS_H_ */
diff --git a/scripts/dtc/treesource.c b/scripts/dtc/treesource.c
new file mode 100644
index 0000000000..2461a3d068
--- /dev/null
+++ b/scripts/dtc/treesource.c
@@ -0,0 +1,284 @@
+/*
+ * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2005.
+ *
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ */
+
+#include "dtc.h"
+#include "srcpos.h"
+
+extern FILE *yyin;
+extern int yyparse(void);
+extern YYLTYPE yylloc;
+
+struct dt_info *parser_output;
+bool treesource_error;
+
+struct dt_info *dt_from_source(const char *fname)
+{
+ parser_output = NULL;
+ treesource_error = false;
+
+ srcfile_push(fname);
+ yyin = current_srcfile->f;
+ yylloc.file = current_srcfile;
+
+ if (yyparse() != 0)
+ die("Unable to parse input tree\n");
+
+ if (treesource_error)
+ die("Syntax error parsing input tree\n");
+
+ return parser_output;
+}
+
+static void write_prefix(FILE *f, int level)
+{
+ int i;
+
+ for (i = 0; i < level; i++)
+ fputc('\t', f);
+}
+
+static bool isstring(char c)
+{
+ return (isprint((unsigned char)c)
+ || (c == '\0')
+ || strchr("\a\b\t\n\v\f\r", c));
+}
+
+static void write_propval_string(FILE *f, struct data val)
+{
+ const char *str = val.val;
+ int i;
+ struct marker *m = val.markers;
+
+ assert(str[val.len-1] == '\0');
+
+ while (m && (m->offset == 0)) {
+ if (m->type == LABEL)
+ fprintf(f, "%s: ", m->ref);
+ m = m->next;
+ }
+ fprintf(f, "\"");
+
+ for (i = 0; i < (val.len-1); i++) {
+ char c = str[i];
+
+ switch (c) {
+ case '\a':
+ fprintf(f, "\\a");
+ break;
+ case '\b':
+ fprintf(f, "\\b");
+ break;
+ case '\t':
+ fprintf(f, "\\t");
+ break;
+ case '\n':
+ fprintf(f, "\\n");
+ break;
+ case '\v':
+ fprintf(f, "\\v");
+ break;
+ case '\f':
+ fprintf(f, "\\f");
+ break;
+ case '\r':
+ fprintf(f, "\\r");
+ break;
+ case '\\':
+ fprintf(f, "\\\\");
+ break;
+ case '\"':
+ fprintf(f, "\\\"");
+ break;
+ case '\0':
+ fprintf(f, "\", ");
+ while (m && (m->offset <= (i + 1))) {
+ if (m->type == LABEL) {
+ assert(m->offset == (i+1));
+ fprintf(f, "%s: ", m->ref);
+ }
+ m = m->next;
+ }
+ fprintf(f, "\"");
+ break;
+ default:
+ if (isprint((unsigned char)c))
+ fprintf(f, "%c", c);
+ else
+ fprintf(f, "\\x%02hhx", c);
+ }
+ }
+ fprintf(f, "\"");
+
+ /* Wrap up any labels at the end of the value */
+ for_each_marker_of_type(m, LABEL) {
+ assert (m->offset == val.len);
+ fprintf(f, " %s:", m->ref);
+ }
+}
+
+static void write_propval_cells(FILE *f, struct data val)
+{
+ void *propend = val.val + val.len;
+ fdt32_t *cp = (fdt32_t *)val.val;
+ struct marker *m = val.markers;
+
+ fprintf(f, "<");
+ for (;;) {
+ while (m && (m->offset <= ((char *)cp - val.val))) {
+ if (m->type == LABEL) {
+ assert(m->offset == ((char *)cp - val.val));
+ fprintf(f, "%s: ", m->ref);
+ }
+ m = m->next;
+ }
+
+ fprintf(f, "0x%x", fdt32_to_cpu(*cp++));
+ if ((void *)cp >= propend)
+ break;
+ fprintf(f, " ");
+ }
+
+ /* Wrap up any labels at the end of the value */
+ for_each_marker_of_type(m, LABEL) {
+ assert (m->offset == val.len);
+ fprintf(f, " %s:", m->ref);
+ }
+ fprintf(f, ">");
+}
+
+static void write_propval_bytes(FILE *f, struct data val)
+{
+ void *propend = val.val + val.len;
+ const char *bp = val.val;
+ struct marker *m = val.markers;
+
+ fprintf(f, "[");
+ for (;;) {
+ while (m && (m->offset == (bp-val.val))) {
+ if (m->type == LABEL)
+ fprintf(f, "%s: ", m->ref);
+ m = m->next;
+ }
+
+ fprintf(f, "%02hhx", (unsigned char)(*bp++));
+ if ((const void *)bp >= propend)
+ break;
+ fprintf(f, " ");
+ }
+
+ /* Wrap up any labels at the end of the value */
+ for_each_marker_of_type(m, LABEL) {
+ assert (m->offset == val.len);
+ fprintf(f, " %s:", m->ref);
+ }
+ fprintf(f, "]");
+}
+
+static void write_propval(FILE *f, struct property *prop)
+{
+ int len = prop->val.len;
+ const char *p = prop->val.val;
+ struct marker *m = prop->val.markers;
+ int nnotstring = 0, nnul = 0;
+ int nnotstringlbl = 0, nnotcelllbl = 0;
+ int i;
+
+ if (len == 0) {
+ fprintf(f, ";\n");
+ return;
+ }
+
+ for (i = 0; i < len; i++) {
+ if (! isstring(p[i]))
+ nnotstring++;
+ if (p[i] == '\0')
+ nnul++;
+ }
+
+ for_each_marker_of_type(m, LABEL) {
+ if ((m->offset > 0) && (prop->val.val[m->offset - 1] != '\0'))
+ nnotstringlbl++;
+ if ((m->offset % sizeof(cell_t)) != 0)
+ nnotcelllbl++;
+ }
+
+ fprintf(f, " = ");
+ if ((p[len-1] == '\0') && (nnotstring == 0) && (nnul < (len-nnul))
+ && (nnotstringlbl == 0)) {
+ write_propval_string(f, prop->val);
+ } else if (((len % sizeof(cell_t)) == 0) && (nnotcelllbl == 0)) {
+ write_propval_cells(f, prop->val);
+ } else {
+ write_propval_bytes(f, prop->val);
+ }
+
+ fprintf(f, ";\n");
+}
+
+static void write_tree_source_node(FILE *f, struct node *tree, int level)
+{
+ struct property *prop;
+ struct node *child;
+ struct label *l;
+
+ write_prefix(f, level);
+ for_each_label(tree->labels, l)
+ fprintf(f, "%s: ", l->label);
+ if (tree->name && (*tree->name))
+ fprintf(f, "%s {\n", tree->name);
+ else
+ fprintf(f, "/ {\n");
+
+ for_each_property(tree, prop) {
+ write_prefix(f, level+1);
+ for_each_label(prop->labels, l)
+ fprintf(f, "%s: ", l->label);
+ fprintf(f, "%s", prop->name);
+ write_propval(f, prop);
+ }
+ for_each_child(tree, child) {
+ fprintf(f, "\n");
+ write_tree_source_node(f, child, level+1);
+ }
+ write_prefix(f, level);
+ fprintf(f, "};\n");
+}
+
+
+void dt_to_source(FILE *f, struct dt_info *dti)
+{
+ struct reserve_info *re;
+
+ fprintf(f, "/dts-v1/;\n\n");
+
+ for (re = dti->reservelist; re; re = re->next) {
+ struct label *l;
+
+ for_each_label(re->labels, l)
+ fprintf(f, "%s: ", l->label);
+ fprintf(f, "/memreserve/\t0x%016llx 0x%016llx;\n",
+ (unsigned long long)re->address,
+ (unsigned long long)re->size);
+ }
+
+ write_tree_source_node(f, dti->dt, 0);
+}
+
diff --git a/scripts/dtc/update-dtc-source.sh b/scripts/dtc/update-dtc-source.sh
new file mode 100755
index 0000000000..b8ebcc6722
--- /dev/null
+++ b/scripts/dtc/update-dtc-source.sh
@@ -0,0 +1,81 @@
+#!/bin/sh
+# Simple script to update the version of DTC carried by the Linux kernel
+#
+# This script assumes that the dtc and the linux git trees are in the
+# same directory. After building dtc in the dtc directory, it copies the
+# source files and generated source files into the scripts/dtc directory
+# in the kernel and creates a git commit updating them to the new
+# version.
+#
+# Usage: from the top level Linux source tree, run:
+# $ ./scripts/dtc/update-dtc-source.sh
+#
+# The script will change into the dtc tree, build and test dtc, copy the
+# relevant files into the kernel tree and create a git commit. The commit
+# message will need to be modified to reflect the version of DTC being
+# imported
+#
+# TODO:
+# This script is pretty basic, but it is seldom used so a few manual tasks
+# aren't a big deal. If anyone is interested in making it more robust, the
+# the following would be nice:
+# * Actually fail to complete if any testcase fails.
+# - The dtc "make check" target needs to return a failure
+# * Extract the version number from the dtc repo for the commit message
+# * Build dtc in the kernel tree
+# * run 'make check" on dtc built from the kernel tree
+
+set -ev
+
+DTC_UPSTREAM_PATH=`pwd`/../dtc
+DTC_LINUX_PATH=`pwd`/scripts/dtc
+
+DTC_SOURCE="checks.c data.c dtc.c dtc.h flattree.c fstree.c livetree.c srcpos.c \
+ srcpos.h treesource.c util.c util.h version_gen.h Makefile.dtc \
+ dtc-lexer.l dtc-parser.y"
+DTC_GENERATED="dtc-lexer.lex.c dtc-parser.tab.c dtc-parser.tab.h"
+LIBFDT_SOURCE="Makefile.libfdt fdt.c fdt.h fdt_empty_tree.c fdt_ro.c fdt_rw.c fdt_strerror.c fdt_sw.c fdt_wip.c libfdt.h libfdt_env.h libfdt_internal.h"
+
+get_last_dtc_version() {
+ git log --oneline scripts/dtc/ | grep 'upstream' | head -1 | sed -e 's/^.* \(.*\)/\1/'
+}
+
+last_dtc_ver=$(get_last_dtc_version)
+
+# Build DTC
+cd $DTC_UPSTREAM_PATH
+make clean
+make check
+dtc_version=$(git describe HEAD)
+dtc_log=$(git log --oneline ${last_dtc_ver}..)
+
+
+# Copy the files into the Linux tree
+cd $DTC_LINUX_PATH
+for f in $DTC_SOURCE; do
+ cp ${DTC_UPSTREAM_PATH}/${f} ${f}
+ git add ${f}
+done
+for f in $DTC_GENERATED; do
+ cp ${DTC_UPSTREAM_PATH}/$f ${f}_shipped
+ git add ${f}_shipped
+done
+for f in $LIBFDT_SOURCE; do
+ cp ${DTC_UPSTREAM_PATH}/libfdt/${f} libfdt/${f}
+ git add libfdt/${f}
+done
+
+sed -i -- 's/#include <libfdt_env.h>/#include "libfdt_env.h"/g' ./libfdt/libfdt.h
+sed -i -- 's/#include <fdt.h>/#include "fdt.h"/g' ./libfdt/libfdt.h
+git add ./libfdt/libfdt.h
+
+commit_msg=$(cat << EOF
+scripts/dtc: Update to upstream version ${dtc_version}
+
+This adds the following commits from upstream:
+
+${dtc_log}
+EOF
+)
+
+git commit -e -v -s -m "${commit_msg}"
diff --git a/scripts/dtc/util.c b/scripts/dtc/util.c
new file mode 100644
index 0000000000..9953c32a02
--- /dev/null
+++ b/scripts/dtc/util.c
@@ -0,0 +1,474 @@
+/*
+ * Copyright 2011 The Chromium Authors, All Rights Reserved.
+ * Copyright 2008 Jon Loeliger, Freescale Semiconductor, Inc.
+ *
+ * util_is_printable_string contributed by
+ * Pantelis Antoniou <pantelis.antoniou AT gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ */
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <assert.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include "libfdt.h"
+#include "util.h"
+#include "version_gen.h"
+
+char *xstrdup(const char *s)
+{
+ int len = strlen(s) + 1;
+ char *d = xmalloc(len);
+
+ memcpy(d, s, len);
+
+ return d;
+}
+
+/* based in part from (3) vsnprintf */
+int xasprintf(char **strp, const char *fmt, ...)
+{
+ int n, size = 128; /* start with 128 bytes */
+ char *p;
+ va_list ap;
+
+ /* initial pointer is NULL making the fist realloc to be malloc */
+ p = NULL;
+ while (1) {
+ p = xrealloc(p, size);
+
+ /* Try to print in the allocated space. */
+ va_start(ap, fmt);
+ n = vsnprintf(p, size, fmt, ap);
+ va_end(ap);
+
+ /* If that worked, return the string. */
+ if (n > -1 && n < size)
+ break;
+ /* Else try again with more space. */
+ if (n > -1) /* glibc 2.1 */
+ size = n + 1; /* precisely what is needed */
+ else /* glibc 2.0 */
+ size *= 2; /* twice the old size */
+ }
+ *strp = p;
+ return strlen(p);
+}
+
+char *join_path(const char *path, const char *name)
+{
+ int lenp = strlen(path);
+ int lenn = strlen(name);
+ int len;
+ int needslash = 1;
+ char *str;
+
+ len = lenp + lenn + 2;
+ if ((lenp > 0) && (path[lenp-1] == '/')) {
+ needslash = 0;
+ len--;
+ }
+
+ str = xmalloc(len);
+ memcpy(str, path, lenp);
+ if (needslash) {
+ str[lenp] = '/';
+ lenp++;
+ }
+ memcpy(str+lenp, name, lenn+1);
+ return str;
+}
+
+bool util_is_printable_string(const void *data, int len)
+{
+ const char *s = data;
+ const char *ss, *se;
+
+ /* zero length is not */
+ if (len == 0)
+ return 0;
+
+ /* must terminate with zero */
+ if (s[len - 1] != '\0')
+ return 0;
+
+ se = s + len;
+
+ while (s < se) {
+ ss = s;
+ while (s < se && *s && isprint((unsigned char)*s))
+ s++;
+
+ /* not zero, or not done yet */
+ if (*s != '\0' || s == ss)
+ return 0;
+
+ s++;
+ }
+
+ return 1;
+}
+
+/*
+ * Parse a octal encoded character starting at index i in string s. The
+ * resulting character will be returned and the index i will be updated to
+ * point at the character directly after the end of the encoding, this may be
+ * the '\0' terminator of the string.
+ */
+static char get_oct_char(const char *s, int *i)
+{
+ char x[4];
+ char *endx;
+ long val;
+
+ x[3] = '\0';
+ strncpy(x, s + *i, 3);
+
+ val = strtol(x, &endx, 8);
+
+ assert(endx > x);
+
+ (*i) += endx - x;
+ return val;
+}
+
+/*
+ * Parse a hexadecimal encoded character starting at index i in string s. The
+ * resulting character will be returned and the index i will be updated to
+ * point at the character directly after the end of the encoding, this may be
+ * the '\0' terminator of the string.
+ */
+static char get_hex_char(const char *s, int *i)
+{
+ char x[3];
+ char *endx;
+ long val;
+
+ x[2] = '\0';
+ strncpy(x, s + *i, 2);
+
+ val = strtol(x, &endx, 16);
+ if (!(endx > x))
+ die("\\x used with no following hex digits\n");
+
+ (*i) += endx - x;
+ return val;
+}
+
+char get_escape_char(const char *s, int *i)
+{
+ char c = s[*i];
+ int j = *i + 1;
+ char val;
+
+ switch (c) {
+ case 'a':
+ val = '\a';
+ break;
+ case 'b':
+ val = '\b';
+ break;
+ case 't':
+ val = '\t';
+ break;
+ case 'n':
+ val = '\n';
+ break;
+ case 'v':
+ val = '\v';
+ break;
+ case 'f':
+ val = '\f';
+ break;
+ case 'r':
+ val = '\r';
+ break;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ j--; /* need to re-read the first digit as
+ * part of the octal value */
+ val = get_oct_char(s, &j);
+ break;
+ case 'x':
+ val = get_hex_char(s, &j);
+ break;
+ default:
+ val = c;
+ }
+
+ (*i) = j;
+ return val;
+}
+
+int utilfdt_read_err_len(const char *filename, char **buffp, off_t *len)
+{
+ int fd = 0; /* assume stdin */
+ char *buf = NULL;
+ off_t bufsize = 1024, offset = 0;
+ int ret = 0;
+
+ *buffp = NULL;
+ if (strcmp(filename, "-") != 0) {
+ fd = open(filename, O_RDONLY);
+ if (fd < 0)
+ return errno;
+ }
+
+ /* Loop until we have read everything */
+ buf = xmalloc(bufsize);
+ do {
+ /* Expand the buffer to hold the next chunk */
+ if (offset == bufsize) {
+ bufsize *= 2;
+ buf = xrealloc(buf, bufsize);
+ }
+
+ ret = read(fd, &buf[offset], bufsize - offset);
+ if (ret < 0) {
+ ret = errno;
+ break;
+ }
+ offset += ret;
+ } while (ret != 0);
+
+ /* Clean up, including closing stdin; return errno on error */
+ close(fd);
+ if (ret)
+ free(buf);
+ else
+ *buffp = buf;
+ *len = bufsize;
+ return ret;
+}
+
+int utilfdt_read_err(const char *filename, char **buffp)
+{
+ off_t len;
+ return utilfdt_read_err_len(filename, buffp, &len);
+}
+
+char *utilfdt_read_len(const char *filename, off_t *len)
+{
+ char *buff;
+ int ret = utilfdt_read_err_len(filename, &buff, len);
+
+ if (ret) {
+ fprintf(stderr, "Couldn't open blob from '%s': %s\n", filename,
+ strerror(ret));
+ return NULL;
+ }
+ /* Successful read */
+ return buff;
+}
+
+char *utilfdt_read(const char *filename)
+{
+ off_t len;
+ return utilfdt_read_len(filename, &len);
+}
+
+int utilfdt_write_err(const char *filename, const void *blob)
+{
+ int fd = 1; /* assume stdout */
+ int totalsize;
+ int offset;
+ int ret = 0;
+ const char *ptr = blob;
+
+ if (strcmp(filename, "-") != 0) {
+ fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0666);
+ if (fd < 0)
+ return errno;
+ }
+
+ totalsize = fdt_totalsize(blob);
+ offset = 0;
+
+ while (offset < totalsize) {
+ ret = write(fd, ptr + offset, totalsize - offset);
+ if (ret < 0) {
+ ret = -errno;
+ break;
+ }
+ offset += ret;
+ }
+ /* Close the file/stdin; return errno on error */
+ if (fd != 1)
+ close(fd);
+ return ret < 0 ? -ret : 0;
+}
+
+
+int utilfdt_write(const char *filename, const void *blob)
+{
+ int ret = utilfdt_write_err(filename, blob);
+
+ if (ret) {
+ fprintf(stderr, "Couldn't write blob to '%s': %s\n", filename,
+ strerror(ret));
+ }
+ return ret ? -1 : 0;
+}
+
+int utilfdt_decode_type(const char *fmt, int *type, int *size)
+{
+ int qualifier = 0;
+
+ if (!*fmt)
+ return -1;
+
+ /* get the conversion qualifier */
+ *size = -1;
+ if (strchr("hlLb", *fmt)) {
+ qualifier = *fmt++;
+ if (qualifier == *fmt) {
+ switch (*fmt++) {
+/* TODO: case 'l': qualifier = 'L'; break;*/
+ case 'h':
+ qualifier = 'b';
+ break;
+ }
+ }
+ }
+
+ /* we should now have a type */
+ if ((*fmt == '\0') || !strchr("iuxs", *fmt))
+ return -1;
+
+ /* convert qualifier (bhL) to byte size */
+ if (*fmt != 's')
+ *size = qualifier == 'b' ? 1 :
+ qualifier == 'h' ? 2 :
+ qualifier == 'l' ? 4 : -1;
+ *type = *fmt++;
+
+ /* that should be it! */
+ if (*fmt)
+ return -1;
+ return 0;
+}
+
+void utilfdt_print_data(const char *data, int len)
+{
+ int i;
+ const char *s;
+
+ /* no data, don't print */
+ if (len == 0)
+ return;
+
+ if (util_is_printable_string(data, len)) {
+ printf(" = ");
+
+ s = data;
+ do {
+ printf("\"%s\"", s);
+ s += strlen(s) + 1;
+ if (s < data + len)
+ printf(", ");
+ } while (s < data + len);
+
+ } else if ((len % 4) == 0) {
+ const fdt32_t *cell = (const fdt32_t *)data;
+
+ printf(" = <");
+ for (i = 0, len /= 4; i < len; i++)
+ printf("0x%08x%s", fdt32_to_cpu(cell[i]),
+ i < (len - 1) ? " " : "");
+ printf(">");
+ } else {
+ const unsigned char *p = (const unsigned char *)data;
+ printf(" = [");
+ for (i = 0; i < len; i++)
+ printf("%02x%s", *p++, i < len - 1 ? " " : "");
+ printf("]");
+ }
+}
+
+void NORETURN util_version(void)
+{
+ printf("Version: %s\n", DTC_VERSION);
+ exit(0);
+}
+
+void NORETURN util_usage(const char *errmsg, const char *synopsis,
+ const char *short_opts,
+ struct option const long_opts[],
+ const char * const opts_help[])
+{
+ FILE *fp = errmsg ? stderr : stdout;
+ const char a_arg[] = "<arg>";
+ size_t a_arg_len = strlen(a_arg) + 1;
+ size_t i;
+ int optlen;
+
+ fprintf(fp,
+ "Usage: %s\n"
+ "\n"
+ "Options: -[%s]\n", synopsis, short_opts);
+
+ /* prescan the --long opt length to auto-align */
+ optlen = 0;
+ for (i = 0; long_opts[i].name; ++i) {
+ /* +1 is for space between --opt and help text */
+ int l = strlen(long_opts[i].name) + 1;
+ if (long_opts[i].has_arg == a_argument)
+ l += a_arg_len;
+ if (optlen < l)
+ optlen = l;
+ }
+
+ for (i = 0; long_opts[i].name; ++i) {
+ /* helps when adding new applets or options */
+ assert(opts_help[i] != NULL);
+
+ /* first output the short flag if it has one */
+ if (long_opts[i].val > '~')
+ fprintf(fp, " ");
+ else
+ fprintf(fp, " -%c, ", long_opts[i].val);
+
+ /* then the long flag */
+ if (long_opts[i].has_arg == no_argument)
+ fprintf(fp, "--%-*s", optlen, long_opts[i].name);
+ else
+ fprintf(fp, "--%s %s%*s", long_opts[i].name, a_arg,
+ (int)(optlen - strlen(long_opts[i].name) - a_arg_len), "");
+
+ /* finally the help text */
+ fprintf(fp, "%s\n", opts_help[i]);
+ }
+
+ if (errmsg) {
+ fprintf(fp, "\nError: %s\n", errmsg);
+ exit(EXIT_FAILURE);
+ } else
+ exit(EXIT_SUCCESS);
+}
diff --git a/scripts/dtc/util.h b/scripts/dtc/util.h
new file mode 100644
index 0000000000..ad5f41199e
--- /dev/null
+++ b/scripts/dtc/util.h
@@ -0,0 +1,263 @@
+#ifndef _UTIL_H
+#define _UTIL_H
+
+#include <stdarg.h>
+#include <stdbool.h>
+#include <getopt.h>
+
+/*
+ * Copyright 2011 The Chromium Authors, All Rights Reserved.
+ * Copyright 2008 Jon Loeliger, Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ */
+
+#ifdef __GNUC__
+#define PRINTF(i, j) __attribute__((format (printf, i, j)))
+#define NORETURN __attribute__((noreturn))
+#else
+#define PRINTF(i, j)
+#define NORETURN
+#endif
+
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+
+static inline void NORETURN PRINTF(1, 2) die(const char *str, ...)
+{
+ va_list ap;
+
+ va_start(ap, str);
+ fprintf(stderr, "FATAL ERROR: ");
+ vfprintf(stderr, str, ap);
+ va_end(ap);
+ exit(1);
+}
+
+static inline void *xmalloc(size_t len)
+{
+ void *new = malloc(len);
+
+ if (!new)
+ die("malloc() failed\n");
+
+ return new;
+}
+
+static inline void *xrealloc(void *p, size_t len)
+{
+ void *new = realloc(p, len);
+
+ if (!new)
+ die("realloc() failed (len=%zd)\n", len);
+
+ return new;
+}
+
+extern char *xstrdup(const char *s);
+
+extern int PRINTF(2, 3) xasprintf(char **strp, const char *fmt, ...);
+extern char *join_path(const char *path, const char *name);
+
+/**
+ * Check a property of a given length to see if it is all printable and
+ * has a valid terminator. The property can contain either a single string,
+ * or multiple strings each of non-zero length.
+ *
+ * @param data The string to check
+ * @param len The string length including terminator
+ * @return 1 if a valid printable string, 0 if not
+ */
+bool util_is_printable_string(const void *data, int len);
+
+/*
+ * Parse an escaped character starting at index i in string s. The resulting
+ * character will be returned and the index i will be updated to point at the
+ * character directly after the end of the encoding, this may be the '\0'
+ * terminator of the string.
+ */
+char get_escape_char(const char *s, int *i);
+
+/**
+ * Read a device tree file into a buffer. This will report any errors on
+ * stderr.
+ *
+ * @param filename The filename to read, or - for stdin
+ * @return Pointer to allocated buffer containing fdt, or NULL on error
+ */
+char *utilfdt_read(const char *filename);
+
+/**
+ * Like utilfdt_read(), but also passes back the size of the file read.
+ *
+ * @param len If non-NULL, the amount of data we managed to read
+ */
+char *utilfdt_read_len(const char *filename, off_t *len);
+
+/**
+ * Read a device tree file into a buffer. Does not report errors, but only
+ * returns them. The value returned can be passed to strerror() to obtain
+ * an error message for the user.
+ *
+ * @param filename The filename to read, or - for stdin
+ * @param buffp Returns pointer to buffer containing fdt
+ * @return 0 if ok, else an errno value representing the error
+ */
+int utilfdt_read_err(const char *filename, char **buffp);
+
+/**
+ * Like utilfdt_read_err(), but also passes back the size of the file read.
+ *
+ * @param len If non-NULL, the amount of data we managed to read
+ */
+int utilfdt_read_err_len(const char *filename, char **buffp, off_t *len);
+
+/**
+ * Write a device tree buffer to a file. This will report any errors on
+ * stderr.
+ *
+ * @param filename The filename to write, or - for stdout
+ * @param blob Poiner to buffer containing fdt
+ * @return 0 if ok, -1 on error
+ */
+int utilfdt_write(const char *filename, const void *blob);
+
+/**
+ * Write a device tree buffer to a file. Does not report errors, but only
+ * returns them. The value returned can be passed to strerror() to obtain
+ * an error message for the user.
+ *
+ * @param filename The filename to write, or - for stdout
+ * @param blob Poiner to buffer containing fdt
+ * @return 0 if ok, else an errno value representing the error
+ */
+int utilfdt_write_err(const char *filename, const void *blob);
+
+/**
+ * Decode a data type string. The purpose of this string
+ *
+ * The string consists of an optional character followed by the type:
+ * Modifier characters:
+ * hh or b 1 byte
+ * h 2 byte
+ * l 4 byte, default
+ *
+ * Type character:
+ * s string
+ * i signed integer
+ * u unsigned integer
+ * x hex
+ *
+ * TODO: Implement ll modifier (8 bytes)
+ * TODO: Implement o type (octal)
+ *
+ * @param fmt Format string to process
+ * @param type Returns type found(s/d/u/x), or 0 if none
+ * @param size Returns size found(1,2,4,8) or 4 if none
+ * @return 0 if ok, -1 on error (no type given, or other invalid format)
+ */
+int utilfdt_decode_type(const char *fmt, int *type, int *size);
+
+/*
+ * This is a usage message fragment for the -t option. It is the format
+ * supported by utilfdt_decode_type.
+ */
+
+#define USAGE_TYPE_MSG \
+ "<type>\ts=string, i=int, u=unsigned, x=hex\n" \
+ "\tOptional modifier prefix:\n" \
+ "\t\thh or b=byte, h=2 byte, l=4 byte (default)";
+
+/**
+ * Print property data in a readable format to stdout
+ *
+ * Properties that look like strings will be printed as strings. Otherwise
+ * the data will be displayed either as cells (if len is a multiple of 4
+ * bytes) or bytes.
+ *
+ * If len is 0 then this function does nothing.
+ *
+ * @param data Pointers to property data
+ * @param len Length of property data
+ */
+void utilfdt_print_data(const char *data, int len);
+
+/**
+ * Show source version and exit
+ */
+void NORETURN util_version(void);
+
+/**
+ * Show usage and exit
+ *
+ * This helps standardize the output of various utils. You most likely want
+ * to use the usage() helper below rather than call this.
+ *
+ * @param errmsg If non-NULL, an error message to display
+ * @param synopsis The initial example usage text (and possible examples)
+ * @param short_opts The string of short options
+ * @param long_opts The structure of long options
+ * @param opts_help An array of help strings (should align with long_opts)
+ */
+void NORETURN util_usage(const char *errmsg, const char *synopsis,
+ const char *short_opts,
+ struct option const long_opts[],
+ const char * const opts_help[]);
+
+/**
+ * Show usage and exit
+ *
+ * If you name all your usage variables with usage_xxx, then you can call this
+ * help macro rather than expanding all arguments yourself.
+ *
+ * @param errmsg If non-NULL, an error message to display
+ */
+#define usage(errmsg) \
+ util_usage(errmsg, usage_synopsis, usage_short_opts, \
+ usage_long_opts, usage_opts_help)
+
+/**
+ * Call getopt_long() with standard options
+ *
+ * Since all util code runs getopt in the same way, provide a helper.
+ */
+#define util_getopt_long() getopt_long(argc, argv, usage_short_opts, \
+ usage_long_opts, NULL)
+
+/* Helper for aligning long_opts array */
+#define a_argument required_argument
+
+/* Helper for usage_short_opts string constant */
+#define USAGE_COMMON_SHORT_OPTS "hV"
+
+/* Helper for usage_long_opts option array */
+#define USAGE_COMMON_LONG_OPTS \
+ {"help", no_argument, NULL, 'h'}, \
+ {"version", no_argument, NULL, 'V'}, \
+ {NULL, no_argument, NULL, 0x0}
+
+/* Helper for usage_opts_help array */
+#define USAGE_COMMON_OPTS_HELP \
+ "Print this help and exit", \
+ "Print version and exit", \
+ NULL
+
+/* Helper for getopt case statements */
+#define case_USAGE_COMMON_FLAGS \
+ case 'h': usage(NULL); \
+ case 'V': util_version(); \
+ case '?': usage("unknown option");
+
+#endif /* _UTIL_H */
diff --git a/scripts/dtc/version_gen.h b/scripts/dtc/version_gen.h
new file mode 100644
index 0000000000..b5ed715ecc
--- /dev/null
+++ b/scripts/dtc/version_gen.h
@@ -0,0 +1 @@
+#define DTC_VERSION "DTC 1.4.4-gfe50bd1e"
diff --git a/scripts/spelling.txt b/scripts/spelling.txt
new file mode 100644
index 0000000000..400ef35169
--- /dev/null
+++ b/scripts/spelling.txt
@@ -0,0 +1,1217 @@
+# Originally from Debian's Lintian tool. Various false positives have been
+# removed, and various additions have been made as they've been discovered
+# in the kernel source.
+#
+# License: GPLv2
+#
+# The format of each line is:
+# mistake||correction
+#
+abandonning||abandoning
+abigious||ambiguous
+abitrate||arbitrate
+abov||above
+abreviated||abbreviated
+absense||absence
+absolut||absolute
+absoulte||absolute
+acccess||access
+acceess||access
+acceleratoin||acceleration
+accelleration||acceleration
+accesing||accessing
+accesnt||accent
+accessable||accessible
+accesss||access
+accidentaly||accidentally
+accidentually||accidentally
+accoding||according
+accomodate||accommodate
+accomodates||accommodates
+accordign||according
+accoring||according
+accout||account
+accquire||acquire
+accquired||acquired
+accross||across
+acessable||accessible
+acess||access
+achitecture||architecture
+acient||ancient
+acitions||actions
+acitve||active
+acknowldegement||acknowledgment
+acknowledgement||acknowledgment
+ackowledge||acknowledge
+ackowledged||acknowledged
+acording||according
+activete||activate
+actived||activated
+actualy||actually
+acumulating||accumulating
+acumulator||accumulator
+adapater||adapter
+addional||additional
+additionaly||additionally
+addres||address
+adddress||address
+addreses||addresses
+addresss||address
+aditional||additional
+aditionally||additionally
+aditionaly||additionally
+adminstrative||administrative
+adress||address
+adresses||addresses
+adviced||advised
+afecting||affecting
+againt||against
+agaist||against
+albumns||albums
+alegorical||allegorical
+algined||aligned
+algorith||algorithm
+algorithmical||algorithmically
+algoritm||algorithm
+algoritms||algorithms
+algorrithm||algorithm
+algorritm||algorithm
+aligment||alignment
+alignement||alignment
+allign||align
+alligned||aligned
+allocatote||allocate
+allocatrd||allocated
+allocte||allocate
+allpication||application
+alocate||allocate
+alogirhtms||algorithms
+alogrithm||algorithm
+alot||a lot
+alow||allow
+alows||allows
+altough||although
+alue||value
+ambigious||ambiguous
+amoung||among
+amout||amount
+an union||a union
+an user||a user
+an userspace||a userspace
+an one||a one
+analysator||analyzer
+ang||and
+anniversery||anniversary
+annoucement||announcement
+anomolies||anomalies
+anomoly||anomaly
+anway||anyway
+aplication||application
+appearence||appearance
+applicaion||application
+appliction||application
+applictions||applications
+applys||applies
+appplications||applications
+appropiate||appropriate
+appropriatly||appropriately
+approriate||appropriate
+approriately||appropriately
+apropriate||appropriate
+aquainted||acquainted
+aquired||acquired
+aquisition||acquisition
+arbitary||arbitrary
+architechture||architecture
+arguement||argument
+arguements||arguments
+aritmetic||arithmetic
+arne't||aren't
+arraival||arrival
+artifical||artificial
+artillary||artillery
+asign||assign
+asser||assert
+assertation||assertion
+assiged||assigned
+assigment||assignment
+assigments||assignments
+assistent||assistant
+assocation||association
+associcated||associated
+assotiated||associated
+assum||assume
+assumtpion||assumption
+asuming||assuming
+asycronous||asynchronous
+asynchnous||asynchronous
+atomatically||automatically
+atomicly||atomically
+atempt||attempt
+attachement||attachment
+attched||attached
+attemps||attempts
+attemping||attempting
+attruibutes||attributes
+authentification||authentication
+automaticaly||automatically
+automaticly||automatically
+automatize||automate
+automatized||automated
+automatizes||automates
+autonymous||autonomous
+auxillary||auxiliary
+auxilliary||auxiliary
+avaiable||available
+avaible||available
+availabe||available
+availabled||available
+availablity||availability
+availale||available
+availavility||availability
+availble||available
+availiable||available
+avalable||available
+avaliable||available
+aysnc||async
+backgroud||background
+backword||backward
+backwords||backwards
+bahavior||behavior
+bakup||backup
+baloon||balloon
+baloons||balloons
+bandwith||bandwidth
+banlance||balance
+batery||battery
+beacuse||because
+becasue||because
+becomming||becoming
+becuase||because
+beeing||being
+befor||before
+begining||beginning
+beter||better
+betweeen||between
+bianries||binaries
+bitmast||bitmask
+boardcast||broadcast
+borad||board
+boundry||boundary
+brievely||briefly
+broadcat||broadcast
+cacluated||calculated
+caculation||calculation
+calender||calendar
+calle||called
+callibration||calibration
+calucate||calculate
+calulate||calculate
+cancelation||cancellation
+cancle||cancel
+capabilites||capabilities
+capabitilies||capabilities
+capatibilities||capabilities
+capapbilities||capabilities
+carefuly||carefully
+cariage||carriage
+catagory||category
+cehck||check
+challange||challenge
+challanges||challenges
+chanell||channel
+changable||changeable
+chanined||chained
+channle||channel
+channnel||channel
+charachter||character
+charachters||characters
+charactor||character
+charater||character
+charaters||characters
+charcter||character
+chcek||check
+chck||check
+checksuming||checksumming
+childern||children
+childs||children
+chiled||child
+chked||checked
+chnage||change
+chnages||changes
+chnnel||channel
+choosen||chosen
+chouse||chose
+circumvernt||circumvent
+claread||cleared
+clared||cleared
+closeing||closing
+clustred||clustered
+coexistance||coexistence
+collapsable||collapsible
+colorfull||colorful
+comand||command
+comit||commit
+commerical||commercial
+comming||coming
+comminucation||communication
+commited||committed
+commiting||committing
+committ||commit
+commoditiy||commodity
+comsume||consume
+comsumer||consumer
+comsuming||consuming
+compability||compatibility
+compaibility||compatibility
+compatability||compatibility
+compatable||compatible
+compatibiliy||compatibility
+compatibilty||compatibility
+compatiblity||compatibility
+competion||completion
+compilant||compliant
+compleatly||completely
+completition||completion
+completly||completely
+complient||compliant
+componnents||components
+compoment||component
+compres||compress
+compresion||compression
+comression||compression
+comunication||communication
+conbination||combination
+conditionaly||conditionally
+conected||connected
+connecetd||connected
+configuartion||configuration
+configuratoin||configuration
+configuraton||configuration
+configuretion||configuration
+configutation||configuration
+conider||consider
+conjuction||conjunction
+connectinos||connections
+connnection||connection
+connnections||connections
+consistancy||consistency
+consistant||consistent
+containes||contains
+containts||contains
+contaisn||contains
+contant||contact
+contence||contents
+continous||continuous
+continously||continuously
+continueing||continuing
+contraints||constraints
+contol||control
+contoller||controller
+controled||controlled
+controler||controller
+controll||control
+contruction||construction
+contry||country
+conuntry||country
+convertion||conversion
+convertor||converter
+convienient||convenient
+convinient||convenient
+corected||corrected
+correponding||corresponding
+correponds||corresponds
+correspoding||corresponding
+cotrol||control
+cound||could
+couter||counter
+coutner||counter
+cryptocraphic||cryptographic
+cunter||counter
+curently||currently
+cylic||cyclic
+dafault||default
+deafult||default
+deamon||daemon
+decompres||decompress
+decription||description
+dectected||detected
+defailt||default
+defferred||deferred
+definate||definite
+definately||definitely
+defintion||definition
+defintions||definitions
+defualt||default
+defult||default
+deintializing||deinitializing
+deintialize||deinitialize
+deintialized||deinitialized
+deivce||device
+delared||declared
+delare||declare
+delares||declares
+delaring||declaring
+delemiter||delimiter
+demodualtor||demodulator
+demension||dimension
+dependancies||dependencies
+dependancy||dependency
+dependant||dependent
+depreacted||deprecated
+depreacte||deprecate
+desactivate||deactivate
+desciptor||descriptor
+desciptors||descriptors
+descripton||description
+descrition||description
+descritptor||descriptor
+desctiptor||descriptor
+desriptor||descriptor
+desriptors||descriptors
+destionation||destination
+destory||destroy
+destoryed||destroyed
+destorys||destroys
+destroied||destroyed
+detabase||database
+deteced||detected
+develope||develop
+developement||development
+developped||developed
+developpement||development
+developper||developer
+developpment||development
+deveolpment||development
+devided||divided
+deviece||device
+diable||disable
+dictionnary||dictionary
+didnt||didn't
+diferent||different
+differrence||difference
+diffrent||different
+diffrentiate||differentiate
+difinition||definition
+diplay||display
+direectly||directly
+disassocation||disassociation
+disapear||disappear
+disapeared||disappeared
+disappared||disappeared
+disble||disable
+disbled||disabled
+disconnet||disconnect
+discontinous||discontinuous
+dispertion||dispersion
+dissapears||disappears
+distiction||distinction
+docuentation||documentation
+documantation||documentation
+documentaion||documentation
+documment||document
+doesnt||doesn't
+dorp||drop
+dosen||doesn
+downlad||download
+downlads||downloads
+druing||during
+dynmaic||dynamic
+easilly||easily
+ecspecially||especially
+edditable||editable
+editting||editing
+efective||effective
+efficently||efficiently
+ehther||ether
+eigth||eight
+elementry||elementary
+eletronic||electronic
+embeded||embedded
+enabledi||enabled
+enchanced||enhanced
+encorporating||incorporating
+encrupted||encrypted
+encrypiton||encryption
+encryptio||encryption
+endianess||endianness
+enhaced||enhanced
+enlightnment||enlightenment
+entrys||entries
+enocded||encoded
+enterily||entirely
+enviroiment||environment
+enviroment||environment
+environement||environment
+environent||environment
+eqivalent||equivalent
+equiped||equipped
+equivelant||equivalent
+equivilant||equivalent
+eror||error
+estbalishment||establishment
+etsablishment||establishment
+etsbalishment||establishment
+excecutable||executable
+exceded||exceeded
+excellant||excellent
+exeed||exceed
+existance||existence
+existant||existent
+exixt||exist
+exlcude||exclude
+exlcusive||exclusive
+exmaple||example
+expecially||especially
+explicite||explicit
+explicitely||explicitly
+explict||explicit
+explictely||explicitly
+explictly||explicitly
+expresion||expression
+exprimental||experimental
+extened||extended
+extensability||extensibility
+extention||extension
+extracter||extractor
+falied||failed
+faild||failed
+faill||fail
+failied||failed
+faillure||failure
+failue||failure
+failuer||failure
+faireness||fairness
+falied||failed
+faliure||failure
+fallbck||fallback
+familar||familiar
+fatser||faster
+feauture||feature
+feautures||features
+fetaure||feature
+fetaures||features
+fileystem||filesystem
+fimware||firmware
+finanize||finalize
+findn||find
+finilizes||finalizes
+finsih||finish
+flusing||flushing
+folloing||following
+followign||following
+followings||following
+follwing||following
+forseeable||foreseeable
+forse||force
+fortan||fortran
+forwardig||forwarding
+framming||framing
+framwork||framework
+frequncy||frequency
+frome||from
+fucntion||function
+fuction||function
+fuctions||functions
+funcion||function
+functionallity||functionality
+functionaly||functionally
+functionnality||functionality
+functonality||functionality
+funtion||function
+funtions||functions
+furthur||further
+futhermore||furthermore
+futrue||future
+gaurenteed||guaranteed
+generiously||generously
+genereate||generate
+genric||generic
+globel||global
+grabing||grabbing
+grahical||graphical
+grahpical||graphical
+grapic||graphic
+guage||gauge
+guarenteed||guaranteed
+guarentee||guarantee
+halfs||halves
+hander||handler
+handfull||handful
+hanled||handled
+happend||happened
+harware||hardware
+heirarchically||hierarchically
+helpfull||helpful
+hierachy||hierarchy
+hierarchie||hierarchy
+howver||however
+hsould||should
+hypervior||hypervisor
+hypter||hyper
+identidier||identifier
+iligal||illegal
+illigal||illegal
+imblance||imbalance
+immeadiately||immediately
+immedaite||immediate
+immediatelly||immediately
+immediatly||immediately
+immidiate||immediate
+impelentation||implementation
+impementated||implemented
+implemantation||implementation
+implemenation||implementation
+implementaiton||implementation
+implementated||implemented
+implemention||implementation
+implemetation||implementation
+implemntation||implementation
+implentation||implementation
+implmentation||implementation
+implmenting||implementing
+incomming||incoming
+incompatabilities||incompatibilities
+incompatable||incompatible
+inconsistant||inconsistent
+increas||increase
+incrment||increment
+indendation||indentation
+indended||intended
+independant||independent
+independantly||independently
+independed||independent
+indiate||indicate
+indicat||indicate
+inexpect||inexpected
+infomation||information
+informatiom||information
+informations||information
+informtion||information
+infromation||information
+ingore||ignore
+inital||initial
+initalized||initialized
+initalised||initialized
+initalise||initialize
+initalize||initialize
+initation||initiation
+initators||initiators
+initialiazation||initialization
+initializiation||initialization
+initialzed||initialized
+initilization||initialization
+initilize||initialize
+inofficial||unofficial
+insititute||institute
+instal||install
+instanciated||instantiated
+inteface||interface
+integreated||integrated
+integrety||integrity
+integrey||integrity
+intendet||intended
+intented||intended
+interanl||internal
+interchangable||interchangeable
+interferring||interfering
+interger||integer
+intermittant||intermittent
+internel||internal
+interoprability||interoperability
+interrface||interface
+interrrupt||interrupt
+interrup||interrupt
+interrups||interrupts
+interruptted||interrupted
+interupted||interrupted
+interupt||interrupt
+intial||initial
+intialisation||initialisation
+intialised||initialised
+intialise||initialise
+intialization||initialization
+intialized||initialized
+intialize||initialize
+intregral||integral
+intrrupt||interrupt
+intterrupt||interrupt
+intuative||intuitive
+invaid||invalid
+invalde||invalid
+invalide||invalid
+invalud||invalid
+invididual||individual
+invokation||invocation
+invokations||invocations
+irrelevent||irrelevant
+isnt||isn't
+isssue||issue
+iternations||iterations
+itertation||iteration
+itslef||itself
+jave||java
+jeffies||jiffies
+juse||just
+jus||just
+kown||known
+langage||language
+langauage||language
+langauge||language
+langugage||language
+lauch||launch
+layed||laid
+leightweight||lightweight
+lengh||length
+lenght||length
+lenth||length
+lesstiff||lesstif
+libaries||libraries
+libary||library
+librairies||libraries
+libraris||libraries
+licenceing||licencing
+loggging||logging
+loggin||login
+logile||logfile
+loosing||losing
+losted||lost
+machinary||machinery
+maintainance||maintenance
+maintainence||maintenance
+maintan||maintain
+makeing||making
+malplaced||misplaced
+malplace||misplace
+managable||manageable
+managment||management
+mangement||management
+manoeuvering||maneuvering
+mappping||mapping
+mathimatical||mathematical
+mathimatic||mathematic
+mathimatics||mathematics
+maxium||maximum
+mechamism||mechanism
+meetign||meeting
+ment||meant
+mergable||mergeable
+mesage||message
+messags||messages
+messgaes||messages
+messsage||message
+messsages||messages
+micropone||microphone
+microprocesspr||microprocessor
+milliseonds||milliseconds
+minium||minimum
+minimam||minimum
+minumum||minimum
+misalinged||misaligned
+miscelleneous||miscellaneous
+misformed||malformed
+mispelled||misspelled
+mispelt||misspelt
+mising||missing
+missmanaged||mismanaged
+missmatch||mismatch
+miximum||maximum
+mmnemonic||mnemonic
+mnay||many
+modulues||modules
+momery||memory
+memomry||memory
+monochorome||monochrome
+monochromo||monochrome
+monocrome||monochrome
+mopdule||module
+mroe||more
+mulitplied||multiplied
+multidimensionnal||multidimensional
+multple||multiple
+mumber||number
+muticast||multicast
+mutiple||multiple
+mutli||multi
+nams||names
+navagating||navigating
+nead||need
+neccecary||necessary
+neccesary||necessary
+neccessary||necessary
+necesary||necessary
+neded||needed
+negaive||negative
+negoitation||negotiation
+negotation||negotiation
+nerver||never
+nescessary||necessary
+nessessary||necessary
+noticable||noticeable
+notications||notifications
+notifed||notified
+numebr||number
+numner||number
+obtaion||obtain
+occassionally||occasionally
+occationally||occasionally
+occurance||occurrence
+occurances||occurrences
+occured||occurred
+occurence||occurrence
+occure||occurred
+occured||occurred
+occuring||occurring
+offet||offset
+omited||omitted
+omiting||omitting
+omitt||omit
+ommiting||omitting
+ommitted||omitted
+onself||oneself
+ony||only
+operatione||operation
+opertaions||operations
+optionnal||optional
+optmizations||optimizations
+orientatied||orientated
+orientied||oriented
+orignal||original
+otherise||otherwise
+ouput||output
+oustanding||outstanding
+overaall||overall
+overhread||overhead
+overlaping||overlapping
+overide||override
+overrided||overridden
+overriden||overridden
+overun||overrun
+overwritting||overwriting
+overwriten||overwritten
+pacakge||package
+pachage||package
+packacge||package
+packege||package
+packge||package
+packtes||packets
+pakage||package
+pallette||palette
+paln||plan
+paramameters||parameters
+paramaters||parameters
+paramater||parameter
+parametes||parameters
+parametised||parametrised
+paramter||parameter
+paramters||parameters
+particuarly||particularly
+particularily||particularly
+partiton||partition
+pased||passed
+passin||passing
+pathes||paths
+pecularities||peculiarities
+peformance||performance
+peice||piece
+pendantic||pedantic
+peprocessor||preprocessor
+perfoming||performing
+permissons||permissions
+peroid||period
+persistance||persistence
+persistant||persistent
+plalform||platform
+platfrom||platform
+plattform||platform
+pleaes||please
+ploting||plotting
+plugable||pluggable
+poinnter||pointer
+pointeur||pointer
+poiter||pointer
+posible||possible
+positon||position
+possibilites||possibilities
+powerfull||powerful
+preapre||prepare
+preceeded||preceded
+preceeding||preceding
+preceed||precede
+precendence||precedence
+precission||precision
+preemptable||preemptible
+prefered||preferred
+prefferably||preferably
+premption||preemption
+prepaired||prepared
+pressre||pressure
+primative||primitive
+princliple||principle
+priorty||priority
+privilaged||privileged
+privilage||privilege
+priviledge||privilege
+priviledges||privileges
+probaly||probably
+procceed||proceed
+proccesors||processors
+procesed||processed
+proces||process
+procesing||processing
+processessing||processing
+processess||processes
+processpr||processor
+processsed||processed
+processsing||processing
+procteted||protected
+prodecure||procedure
+progams||programs
+progess||progress
+programers||programmers
+programm||program
+programms||programs
+progresss||progress
+promiscous||promiscuous
+promps||prompts
+pronnounced||pronounced
+prononciation||pronunciation
+pronouce||pronounce
+pronunce||pronounce
+propery||property
+propigate||propagate
+propigation||propagation
+propogate||propagate
+prosess||process
+protable||portable
+protcol||protocol
+protecion||protection
+protocoll||protocol
+promixity||proximity
+psudo||pseudo
+psuedo||pseudo
+psychadelic||psychedelic
+pwoer||power
+quering||querying
+randomally||randomly
+raoming||roaming
+reasearcher||researcher
+reasearchers||researchers
+reasearch||research
+recepient||recipient
+receving||receiving
+recieved||received
+recieve||receive
+reciever||receiver
+recieves||receives
+recogniced||recognised
+recognizeable||recognizable
+recommanded||recommended
+recyle||recycle
+redircet||redirect
+redirectrion||redirection
+reename||rename
+refcounf||refcount
+refence||reference
+refered||referred
+referenace||reference
+refering||referring
+refernces||references
+refernnce||reference
+refrence||reference
+registerd||registered
+registeresd||registered
+registerred||registered
+registes||registers
+registraration||registration
+regsiter||register
+regster||register
+regualar||regular
+reguator||regulator
+regulamentations||regulations
+reigstration||registration
+releated||related
+relevent||relevant
+remoote||remote
+remore||remote
+removeable||removable
+repectively||respectively
+replacable||replaceable
+replacments||replacements
+replys||replies
+reponse||response
+representaion||representation
+reqeust||request
+requestied||requested
+requiere||require
+requirment||requirement
+requred||required
+requried||required
+requst||request
+reseting||resetting
+resizeable||resizable
+resouce||resource
+resouces||resources
+resoures||resources
+responce||response
+ressizes||resizes
+ressource||resource
+ressources||resources
+retransmited||retransmitted
+retreived||retrieved
+retreive||retrieve
+retrive||retrieve
+retuned||returned
+reudce||reduce
+reuest||request
+reuqest||request
+reutnred||returned
+revsion||revision
+rmeoved||removed
+rmeove||remove
+rmeoves||removes
+rountine||routine
+routins||routines
+rquest||request
+runing||running
+runned||ran
+runnning||running
+runtine||runtime
+sacrifying||sacrificing
+safly||safely
+safty||safety
+savable||saveable
+scaned||scanned
+scaning||scanning
+scarch||search
+seach||search
+searchs||searches
+secquence||sequence
+secund||second
+segement||segment
+senarios||scenarios
+sentivite||sensitive
+separatly||separately
+sepcify||specify
+sepc||spec
+seperated||separated
+seperately||separately
+seperate||separate
+seperatly||separately
+seperator||separator
+sepperate||separate
+sequece||sequence
+sequencial||sequential
+serveral||several
+setts||sets
+settting||setting
+shotdown||shutdown
+shoud||should
+shouldnt||shouldn't
+shoule||should
+shrinked||shrunk
+siginificantly||significantly
+signabl||signal
+similary||similarly
+similiar||similar
+simlar||similar
+simliar||similar
+simpified||simplified
+singaled||signaled
+singal||signal
+singed||signed
+sleeped||slept
+softwares||software
+speach||speech
+specfic||specific
+speciefied||specified
+specifc||specific
+specifed||specified
+specificatin||specification
+specificaton||specification
+specifing||specifying
+specifiying||specifying
+speficied||specified
+speicify||specify
+speling||spelling
+spinlcok||spinlock
+spinock||spinlock
+splitted||split
+spreaded||spread
+spurrious||spurious
+sructure||structure
+stablilization||stabilization
+staically||statically
+staion||station
+standardss||standards
+standartization||standardization
+standart||standard
+staticly||statically
+stoped||stopped
+stoppped||stopped
+straming||streaming
+struc||struct
+structres||structures
+stuct||struct
+strucuture||structure
+stucture||structure
+sturcture||structure
+subdirectoires||subdirectories
+suble||subtle
+substract||subtract
+succesfully||successfully
+succesful||successful
+successed||succeeded
+successfull||successful
+successfuly||successfully
+sucessfully||successfully
+sucess||success
+superflous||superfluous
+superseeded||superseded
+suplied||supplied
+suported||supported
+suport||support
+supportet||supported
+suppored||supported
+supportin||supporting
+suppoted||supported
+suppported||supported
+suppport||support
+supress||suppress
+surpresses||suppresses
+susbsystem||subsystem
+suspeneded||suspended
+suspicously||suspiciously
+swaping||swapping
+switchs||switches
+swith||switch
+swithable||switchable
+swithc||switch
+swithced||switched
+swithcing||switching
+swithed||switched
+swithing||switching
+symetric||symmetric
+synax||syntax
+synchonized||synchronized
+syncronize||synchronize
+syncronized||synchronized
+syncronizing||synchronizing
+syncronus||synchronous
+syste||system
+sytem||system
+sythesis||synthesis
+taht||that
+targetted||targeted
+targetting||targeting
+teh||the
+temorary||temporary
+temproarily||temporarily
+therfore||therefore
+thier||their
+threds||threads
+threshhold||threshold
+throught||through
+thses||these
+tiggered||triggered
+tipically||typically
+timout||timeout
+tmis||this
+torerable||tolerable
+tramsmitted||transmitted
+tramsmit||transmit
+tranfer||transfer
+transciever||transceiver
+transferd||transferred
+transfered||transferred
+transfering||transferring
+transision||transition
+transmittd||transmitted
+transormed||transformed
+trasfer||transfer
+trasmission||transmission
+treshold||threshold
+trigerring||triggering
+trun||turn
+ture||true
+tyep||type
+udpate||update
+uesd||used
+uncommited||uncommitted
+unconditionaly||unconditionally
+underun||underrun
+unecessary||unnecessary
+unexecpted||unexpected
+unexepected||unexpected
+unexpcted||unexpected
+unexpectd||unexpected
+unexpeted||unexpected
+unexpexted||unexpected
+unfortunatelly||unfortunately
+unifiy||unify
+unintialized||uninitialized
+unkmown||unknown
+unknonw||unknown
+unknow||unknown
+unkown||unknown
+unneded||unneeded
+unneedingly||unnecessarily
+unnsupported||unsupported
+unmached||unmatched
+unregester||unregister
+unresgister||unregister
+unrgesiter||unregister
+unsinged||unsigned
+unstabel||unstable
+unsolicitied||unsolicited
+unsuccessfull||unsuccessful
+unsuported||unsupported
+untill||until
+unuseful||useless
+upate||update
+usefule||useful
+usefull||useful
+usege||usage
+usera||users
+usualy||usually
+utilites||utilities
+utillities||utilities
+utilties||utilities
+utiltity||utility
+utitity||utility
+utitlty||utility
+vaid||valid
+vaild||valid
+valide||valid
+variantions||variations
+varible||variable
+varient||variant
+vaule||value
+verbse||verbose
+verisons||versions
+verison||version
+verson||version
+vicefersa||vice-versa
+virtal||virtual
+virtaul||virtual
+virtiual||virtual
+visiters||visitors
+vitual||virtual
+wakeus||wakeups
+wating||waiting
+wether||whether
+whataver||whatever
+whcih||which
+whenver||whenever
+wheter||whether
+whe||when
+wierd||weird
+wiil||will
+wirte||write
+withing||within
+wnat||want
+workarould||workaround
+writeing||writing
+writting||writing
+zombe||zombie
+zomebie||zombie
diff --git a/test/py/README.md b/test/py/README.md
index 829c7efbb2..ea4b66a41c 100644
--- a/test/py/README.md
+++ b/test/py/README.md
@@ -22,12 +22,17 @@ need to implement various "hook" scripts that are called by the test suite at
the appropriate time.
On Debian or Debian-like distributions, the following packages are required.
-Similar package names should exist in other distributions.
+Some packages are required to execute any test, and others only for specific
+tests. Similar package names should exist in other distributions.
| Package | Version tested (Ubuntu 14.04) |
| -------------- | ----------------------------- |
| python | 2.7.5-5ubuntu3 |
| python-pytest | 2.5.1-1 |
+| gdisk | 0.8.8-1ubuntu0.1 |
+| dfu-util | 0.5-1 |
+| dtc | 1.4.0+dfsg-1 |
+| openssl | 1.0.1f-1ubuntu2.22 |
The test script supports either:
diff --git a/test/py/conftest.py b/test/py/conftest.py
index 65e1d75626..6e66a48c15 100644
--- a/test/py/conftest.py
+++ b/test/py/conftest.py
@@ -429,12 +429,12 @@ def setup_boardspec(item):
for board in mark.args:
if board.startswith('!'):
if ubconfig.board_type == board[1:]:
- pytest.skip('board not supported')
+ pytest.skip('board "%s" not supported' % ubconfig.board_type)
return
else:
required_boards.append(board)
if required_boards and ubconfig.board_type not in required_boards:
- pytest.skip('board not supported')
+ pytest.skip('board "%s" not supported' % ubconfig.board_type)
def setup_buildconfigspec(item):
"""Process any 'buildconfigspec' marker for a test.
@@ -455,7 +455,35 @@ def setup_buildconfigspec(item):
return
for option in mark.args:
if not ubconfig.buildconfig.get('config_' + option.lower(), None):
- pytest.skip('.config feature not enabled')
+ pytest.skip('.config feature "%s" not enabled' % option.lower())
+
+def tool_is_in_path(tool):
+ for path in os.environ["PATH"].split(os.pathsep):
+ fn = os.path.join(path, tool)
+ if os.path.isfile(fn) and os.access(fn, os.X_OK):
+ return True
+ return False
+
+def setup_requiredtool(item):
+ """Process any 'requiredtool' marker for a test.
+
+ Such a marker lists some external tool (binary, executable, application)
+ that the test requires. If tests are being executed on a system that
+ doesn't have the required tool, the test is marked to be skipped.
+
+ Args:
+ item: The pytest test item.
+
+ Returns:
+ Nothing.
+ """
+
+ mark = item.get_marker('requiredtool')
+ if not mark:
+ return
+ for tool in mark.args:
+ if not tool_is_in_path(tool):
+ pytest.skip('tool "%s" not in $PATH' % tool)
def start_test_section(item):
anchors[item.name] = log.start_section(item.name)
@@ -476,6 +504,7 @@ def pytest_runtest_setup(item):
start_test_section(item)
setup_boardspec(item)
setup_buildconfigspec(item)
+ setup_requiredtool(item)
def pytest_runtest_protocol(item, nextitem):
"""pytest hook: Called to execute a test.
diff --git a/test/py/multiplexed_log.py b/test/py/multiplexed_log.py
index bf926c3e77..5bc1bc49d4 100644
--- a/test/py/multiplexed_log.py
+++ b/test/py/multiplexed_log.py
@@ -365,13 +365,13 @@ $(document).ready(function () {
self._terminate_stream()
self.f.write('<div class="' + note_type + '">\n')
- if anchor:
- self.f.write('<a href="#%s">\n' % anchor)
self.f.write('<pre>')
+ if anchor:
+ self.f.write('<a href="#%s">' % anchor)
self.f.write(self._escape(msg))
- self.f.write('\n</pre>\n')
if anchor:
- self.f.write('</a>\n')
+ self.f.write('</a>')
+ self.f.write('\n</pre>\n')
self.f.write('</div>\n')
def start_section(self, marker, anchor=None):
diff --git a/test/py/tests/test_dfu.py b/test/py/tests/test_dfu.py
index fba67d585b..8f6877c5c2 100644
--- a/test/py/tests/test_dfu.py
+++ b/test/py/tests/test_dfu.py
@@ -113,6 +113,7 @@ test_sizes_default = (
first_usb_dev_port = None
@pytest.mark.buildconfigspec('cmd_dfu')
+@pytest.mark.requiredtool('dfu-util')
def test_dfu(u_boot_console, env__usb_dev_port, env__dfu_config):
"""Test the "dfu" command; the host system must be able to enumerate a USB
device when "dfu" is running, various DFU transfers are tested, and the
diff --git a/test/py/tests/test_fit.py b/test/py/tests/test_fit.py
index 7e6b96dae4..4b32bb18b8 100755
--- a/test/py/tests/test_fit.py
+++ b/test/py/tests/test_fit.py
@@ -111,6 +111,7 @@ sb save hostfs 0 %(loadables2_addr)x %(loadables2_out)s %(loadables2_size)x
@pytest.mark.boardspec('sandbox')
@pytest.mark.buildconfigspec('fit_signature')
+@pytest.mark.requiredtool('dtc')
def test_fit(u_boot_console):
def make_fname(leaf):
"""Make a temporary filename
diff --git a/test/py/tests/test_gpt.py b/test/py/tests/test_gpt.py
index e2bbd08e6d..ec25fbbc5a 100644
--- a/test/py/tests/test_gpt.py
+++ b/test/py/tests/test_gpt.py
@@ -38,15 +38,14 @@ class GptTestDiskImage(object):
fd = os.open(self.path, os.O_RDWR | os.O_CREAT)
os.ftruncate(fd, 4194304)
os.close(fd)
- sgdisk = '/sbin/sgdisk'
- cmd = (sgdisk, '-U', '375a56f7-d6c9-4e81-b5f0-09d41ca89efe',
+ cmd = ('sgdisk', '-U', '375a56f7-d6c9-4e81-b5f0-09d41ca89efe',
self.path)
u_boot_utils.run_and_log(u_boot_console, cmd)
- cmd = (sgdisk, '--new=1:2048:2560', self.path)
+ cmd = ('sgdisk', '--new=1:2048:2560', self.path)
u_boot_utils.run_and_log(u_boot_console, cmd)
- cmd = (sgdisk, '--new=2:4096:4608', self.path)
+ cmd = ('sgdisk', '--new=2:4096:4608', self.path)
u_boot_utils.run_and_log(u_boot_console, cmd)
- cmd = (sgdisk, '-l', self.path)
+ cmd = ('sgdisk', '-l', self.path)
u_boot_utils.run_and_log(u_boot_console, cmd)
gtdi = None
@@ -64,6 +63,7 @@ def state_disk_image(u_boot_console):
@pytest.mark.boardspec('sandbox')
@pytest.mark.buildconfigspec('cmd_gpt')
+@pytest.mark.requiredtool('sgdisk')
def test_gpt_guid(state_disk_image, u_boot_console):
"""Test the gpt guid command."""
@@ -73,6 +73,7 @@ def test_gpt_guid(state_disk_image, u_boot_console):
@pytest.mark.boardspec('sandbox')
@pytest.mark.buildconfigspec('cmd_gpt')
+@pytest.mark.requiredtool('sgdisk')
def test_gpt_save_guid(state_disk_image, u_boot_console):
"""Test the gpt guid command to save GUID into a string."""
@@ -86,6 +87,7 @@ def test_gpt_save_guid(state_disk_image, u_boot_console):
@pytest.mark.boardspec('sandbox')
@pytest.mark.buildconfigspec('cmd_gpt')
@pytest.mark.buildconfigspec('cmd_gpt_rename')
+@pytest.mark.requiredtool('sgdisk')
def test_gpt_rename_partition(state_disk_image, u_boot_console):
"""Test the gpt rename command to write partition names."""
@@ -101,6 +103,7 @@ def test_gpt_rename_partition(state_disk_image, u_boot_console):
@pytest.mark.buildconfigspec('cmd_gpt')
@pytest.mark.buildconfigspec('cmd_gpt_rename')
@pytest.mark.buildconfigspec('cmd_part')
+@pytest.mark.requiredtool('sgdisk')
def test_gpt_swap_partitions(state_disk_image, u_boot_console):
"""Test the gpt swap command to exchange two partition names."""
diff --git a/test/py/tests/test_vboot.py b/test/py/tests/test_vboot.py
index 6e62820743..c4da79d114 100644
--- a/test/py/tests/test_vboot.py
+++ b/test/py/tests/test_vboot.py
@@ -31,6 +31,10 @@ import u_boot_utils as util
@pytest.mark.boardspec('sandbox')
@pytest.mark.buildconfigspec('fit_signature')
+@pytest.mark.requiredtool('dtc')
+@pytest.mark.requiredtool('fdtget')
+@pytest.mark.requiredtool('fdtput')
+@pytest.mark.requiredtool('openssl')
def test_vboot(u_boot_console):
"""Test verified boot signing with mkimage and verification with 'bootm'.
diff --git a/tools/Makefile b/tools/Makefile
index a0db19d6b0..c16477459d 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -175,7 +175,7 @@ HOSTCFLAGS_rsa-sign.o += -Wno-deprecated-declarations
endif
endif
-HOSTCFLAGS_fit_image.o += -DMKIMAGE_DTC=\"$(DTC)\"
+HOSTCFLAGS_fit_image.o += -DMKIMAGE_DTC=\"$(CONFIG_MKIMAGE_DTC_PATH)\"
HOSTLOADLIBES_dumpimage := $(HOSTLOADLIBES_mkimage)
HOSTLOADLIBES_fit_info := $(HOSTLOADLIBES_mkimage)
diff --git a/tools/buildman/kconfiglib.py b/tools/buildman/kconfiglib.py
index 352ad438ee..68b470a3a7 100644
--- a/tools/buildman/kconfiglib.py
+++ b/tools/buildman/kconfiglib.py
@@ -73,6 +73,7 @@ email service. Don't wrestle with internal APIs. Tell me what you need and I
might add it in a safe way as a client API instead."""
import os
+import platform
import re
import sys
@@ -137,10 +138,8 @@ class Config(object):
# The set of all symbols, indexed by name (a string)
self.syms = {}
# Python 2/3 compatibility hack. This is the only one needed.
- if sys.version_info[0] >= 3:
- self.syms_iter = self.syms.values
- else:
- self.syms_iter = self.syms.itervalues
+ self.syms_iter = self.syms.values if sys.version_info[0] >= 3 else \
+ self.syms.itervalues
# The set of all defined symbols in the configuration in the order they
# appear in the Kconfig files. This excludes the special symbols n, m,
@@ -173,7 +172,7 @@ class Config(object):
self.m = register_special_symbol(TRISTATE, "m", "m")
self.y = register_special_symbol(TRISTATE, "y", "y")
# DEFCONFIG_LIST uses this
- register_special_symbol(STRING, "UNAME_RELEASE", os.uname()[2])
+ register_special_symbol(STRING, "UNAME_RELEASE", platform.uname()[2])
# The symbol with "option defconfig_list" set, containing a list of
# default .config files
@@ -183,16 +182,20 @@ class Config(object):
self.arch = os.environ.get("ARCH")
self.srcarch = os.environ.get("SRCARCH")
+ # If you set CONFIG_ in the environment, Kconfig will prefix all symbols
+ # with its value when saving the configuration, instead of using the default, "CONFIG_".
+ self.config_prefix = os.environ.get("CONFIG_")
+ if self.config_prefix is None:
+ self.config_prefix = "CONFIG_"
+
# See Config.__init__(). We need this for get_defconfig_filename().
self.srctree = os.environ.get("srctree")
if self.srctree is None:
self.srctree = "."
self.filename = filename
- if base_dir is None:
- self.base_dir = self.srctree
- else:
- self.base_dir = os.path.expandvars(base_dir)
+ self.base_dir = self.srctree if base_dir is None else \
+ os.path.expandvars(base_dir)
# The 'mainmenu' text
self.mainmenu_text = None
@@ -222,7 +225,8 @@ class Config(object):
self._transform_m = None
# Parse the Kconfig files
- self.top_block = self._parse_file(filename, None, None, None)
+ self.top_block = []
+ self._parse_file(filename, None, None, None, self.top_block)
# Build Symbol.dep for all symbols
self._build_dep()
@@ -405,6 +409,10 @@ class Config(object):
"""
self._warnings = []
+ # Regular expressions for parsing .config files
+ _set_re_match = re.compile(r"{}(\w+)=(.*)".format(self.config_prefix)).match
+ _unset_re_match = re.compile(r"# {}(\w+) is not set".format(self.config_prefix)).match
+
# Put this first so that a missing file doesn't screw up our state
filename = os.path.expandvars(filename)
line_feeder = _FileFeed(filename)
@@ -524,14 +532,12 @@ class Config(object):
with open(filename, "w") as f:
# Write header
if header is not None:
- f.write(_comment(header))
- f.write("\n")
+ f.write(_comment(header) + "\n")
# Build and write configuration
conf_strings = []
_make_block_conf(self.top_block, conf_strings.append)
- f.write("\n".join(conf_strings))
- f.write("\n")
+ f.write("\n".join(conf_strings) + "\n")
def eval(self, s):
"""Returns the value of the expression 's' -- where 's' is represented
@@ -609,16 +615,18 @@ class Config(object):
# Kconfig parsing
#
- def _parse_file(self, filename, parent, deps, visible_if_deps, res=None):
- """Parses the Kconfig file 'filename'. Returns a list with the Items in
- the file. See _parse_block() for the meaning of the parameters."""
- return self._parse_block(_FileFeed(filename), None, parent, deps,
- visible_if_deps, res)
+ def _parse_file(self, filename, parent, deps, visible_if_deps, block):
+ """Parses the Kconfig file 'filename'. Appends the Items in the file
+ (and any file it sources) to the list passed in the 'block' parameter.
+ See _parse_block() for the meaning of the parameters."""
+ self._parse_block(_FileFeed(filename), None, parent, deps,
+ visible_if_deps, block)
def _parse_block(self, line_feeder, end_marker, parent, deps,
- visible_if_deps, res=None):
+ visible_if_deps, block):
"""Parses a block, which is the contents of either a file or an if,
- menu, or choice statement. Returns a list with the Items in the block.
+ menu, or choice statement. Appends the Items to the list passed in the
+ 'block' parameter.
line_feeder: A _FileFeed instance feeding lines from a file. The
Kconfig language is line-based in practice.
@@ -634,10 +642,7 @@ class Config(object):
visible_if_deps (default: None): 'visible if' dependencies from
enclosing menus.
- res (default: None): The list to add items to. If None, a new list is
- created to hold the items."""
-
- block = [] if res is None else res
+ block: The list to add items to."""
while 1:
# Do we already have a tokenized line that we determined wasn't
@@ -656,7 +661,7 @@ class Config(object):
if end_marker is not None:
raise Kconfig_Syntax_Error("Unexpected end of file {0}"
.format(line_feeder.filename))
- return block
+ return
tokens = self._tokenize(line, False, line_feeder.filename,
line_feeder.linenr)
@@ -679,14 +684,13 @@ class Config(object):
# choice statements, the choice statement takes precedence.
if not sym.is_defined_ or isinstance(parent, Choice):
sym.parent = parent
-
sym.is_defined_ = True
+ self._parse_properties(line_feeder, sym, deps, visible_if_deps)
+
self.kconfig_syms.append(sym)
block.append(sym)
- self._parse_properties(line_feeder, sym, deps, visible_if_deps)
-
elif t0 == T_SOURCE:
kconfig_file = tokens.get_next()
exp_kconfig_file = self._expand_sym_refs(kconfig_file)
@@ -705,7 +709,7 @@ class Config(object):
elif t0 == end_marker:
# We have reached the end of the block
- return block
+ return
elif t0 == T_IF:
# If statements are treated as syntactic sugar for adding
@@ -722,38 +726,39 @@ class Config(object):
elif t0 == T_COMMENT:
comment = Comment()
-
comment.config = self
comment.parent = parent
comment.filename = line_feeder.filename
comment.linenr = line_feeder.linenr
comment.text = tokens.get_next()
- self.comments.append(comment)
- block.append(comment)
-
self._parse_properties(line_feeder, comment, deps,
visible_if_deps)
+ self.comments.append(comment)
+ block.append(comment)
+
elif t0 == T_MENU:
menu = Menu()
-
menu.config = self
menu.parent = parent
menu.filename = line_feeder.filename
menu.linenr = line_feeder.linenr
menu.title = tokens.get_next()
- self.menus.append(menu)
- block.append(menu)
-
- # Parse properties and contents
self._parse_properties(line_feeder, menu, deps,
visible_if_deps)
- menu.block = self._parse_block(line_feeder, T_ENDMENU, menu,
- menu.dep_expr,
- _make_and(visible_if_deps,
- menu.visible_if_expr))
+
+ # This needs to go before _parse_block() so that we get the
+ # proper menu ordering in the case of nested functions
+ self.menus.append(menu)
+ # Parse contents and put Items in menu.block
+ self._parse_block(line_feeder, T_ENDMENU, menu, menu.dep_expr,
+ _make_and(visible_if_deps,
+ menu.visible_if_expr),
+ menu.block)
+
+ block.append(menu)
elif t0 == T_CHOICE:
name = tokens.get_next()
@@ -775,11 +780,12 @@ class Config(object):
choice.def_locations.append((line_feeder.filename,
line_feeder.linenr))
- # Parse properties and contents
self._parse_properties(line_feeder, choice, deps,
visible_if_deps)
- choice.block = self._parse_block(line_feeder, T_ENDCHOICE,
- choice, deps, visible_if_deps)
+
+ # Parse contents and put Items in choice.block
+ self._parse_block(line_feeder, T_ENDCHOICE, choice, deps,
+ visible_if_deps, choice.block)
choice._determine_actual_symbols()
@@ -819,19 +825,19 @@ class Config(object):
"""Parses '<expr1> if <expr2>' constructs, where the 'if' part is
optional. Returns a tuple containing the parsed expressions, with
None as the second element if the 'if' part is missing."""
- val = self._parse_expr(tokens, stmt, line, filename, linenr, False)
- if tokens.check(T_IF):
- return (val, self._parse_expr(tokens, stmt, line, filename,
- linenr))
- return (val, None)
+ return (self._parse_expr(tokens, stmt, line, filename, linenr,
+ False),
+ self._parse_expr(tokens, stmt, line, filename, linenr)
+ if tokens.check(T_IF) else None)
# In case the symbol is defined in multiple locations, we need to
- # remember what prompts, defaults, and selects are new for this
- # definition, as "depends on" should only apply to the local
+ # remember what prompts, defaults, selects, and implies are new for
+ # this definition, as "depends on" should only apply to the local
# definition.
new_prompt = None
new_def_exprs = []
new_selects = []
+ new_implies = []
# Dependencies from 'depends on' statements
depends_on_expr = None
@@ -897,18 +903,27 @@ class Config(object):
line_feeder.unget()
- elif t0 == T_SELECT or t0 == T_IMPLY:
+ elif t0 == T_SELECT:
target = tokens.get_next()
stmt.referenced_syms.add(target)
stmt.selected_syms.add(target)
- if tokens.check(T_IF):
- new_selects.append((target,
- self._parse_expr(tokens, stmt, line,
- filename, linenr)))
- else:
- new_selects.append((target, None))
+ new_selects.append(
+ (target,
+ self._parse_expr(tokens, stmt, line, filename, linenr)
+ if tokens.check(T_IF) else None))
+
+ elif t0 == T_IMPLY:
+ target = tokens.get_next()
+
+ stmt.referenced_syms.add(target)
+ stmt.implied_syms.add(target)
+
+ new_implies.append(
+ (target,
+ self._parse_expr(tokens, stmt, line, filename, linenr)
+ if tokens.check(T_IF) else None))
elif t0 in (T_BOOL, T_TRISTATE, T_INT, T_HEX, T_STRING):
stmt.type = TOKEN_TO_TYPE[t0]
@@ -939,12 +954,10 @@ class Config(object):
stmt.referenced_syms.add(low)
stmt.referenced_syms.add(high)
- if tokens.check(T_IF):
- stmt.ranges.append((low, high,
- self._parse_expr(tokens, stmt, line,
- filename, linenr)))
- else:
- stmt.ranges.append((low, high, None))
+ stmt.ranges.append(
+ (low, high,
+ self._parse_expr(tokens, stmt, line, filename, linenr)
+ if tokens.check(T_IF) else None))
elif t0 == T_DEF_TRISTATE:
stmt.type = TRISTATE
@@ -1051,21 +1064,20 @@ class Config(object):
# Symbol or Choice
# See comment for 'menu_dep'
- stmt.menu_dep = depends_on_expr
+ stmt.menu_dep = _make_and(deps, depends_on_expr)
# Propagate dependencies to prompts
if new_prompt is not None:
- # Propagate 'visible if' dependencies from enclosing menus
prompt, cond_expr = new_prompt
- cond_expr = _make_and(cond_expr, visible_if_deps)
- # Propagate 'depends on' dependencies
- new_prompt = (prompt, _make_and(cond_expr, depends_on_expr))
+ # Propagate 'visible if' dependencies from menus and local
+ # 'depends on' dependencies
+ cond_expr = _make_and(_make_and(cond_expr, visible_if_deps),
+ depends_on_expr)
# Save original
- stmt.orig_prompts.append(new_prompt)
+ stmt.orig_prompts.append((prompt, cond_expr))
# Finalize with dependencies from enclosing menus and ifs
- stmt.prompts.append((new_prompt[0],
- _make_and(new_prompt[1], deps)))
+ stmt.prompts.append((prompt, _make_and(cond_expr, deps)))
# Propagate dependencies to defaults
@@ -1078,20 +1090,27 @@ class Config(object):
stmt.def_exprs.extend([(val_expr, _make_and(cond_expr, deps))
for val_expr, cond_expr in new_def_exprs])
- # Propagate dependencies to selects
+ # Propagate dependencies to selects and implies
- # Only symbols can select
+ # Only symbols can select and imply
if isinstance(stmt, Symbol):
# Propagate 'depends on' dependencies
new_selects = [(target, _make_and(cond_expr, depends_on_expr))
for target, cond_expr in new_selects]
+ new_implies = [(target, _make_and(cond_expr, depends_on_expr))
+ for target, cond_expr in new_implies]
# Save original
stmt.orig_selects.extend(new_selects)
+ stmt.orig_implies.extend(new_implies)
# Finalize with dependencies from enclosing menus and ifs
for target, cond in new_selects:
- target.rev_dep = _make_or(target.rev_dep,
- _make_and(stmt,
- _make_and(cond, deps)))
+ target.rev_dep = \
+ _make_or(target.rev_dep,
+ _make_and(stmt, _make_and(cond, deps)))
+ for target, cond in new_implies:
+ target.weak_rev_dep = \
+ _make_or(target.weak_rev_dep,
+ _make_and(stmt, _make_and(cond, deps)))
def _parse_expr(self, feed, cur_item, line, filename=None, linenr=None,
transform_m=True):
@@ -1483,7 +1502,8 @@ class Config(object):
# The directly dependent symbols of a symbol are:
# - Any symbols whose prompts, default values, rev_dep (select
- # condition), or ranges depend on the symbol
+ # condition), weak_rev_dep (imply condition) or ranges depend on the
+ # symbol
# - Any symbols that belong to the same choice statement as the symbol
# (these won't be included in 'dep' as that makes the dependency
# graph unwieldy, but Symbol._get_dependent() will include them)
@@ -1497,6 +1517,7 @@ class Config(object):
add_expr_deps(e, sym)
add_expr_deps(sym.rev_dep, sym)
+ add_expr_deps(sym.weak_rev_dep, sym)
for l, u, e in sym.ranges:
add_expr_deps(l, sym)
@@ -1625,20 +1646,16 @@ class Config(object):
else:
prompts_str_rows = []
for prompt, cond_expr in sc.orig_prompts:
- if cond_expr is None:
- prompts_str_rows.append(' "{0}"'.format(prompt))
- else:
- prompts_str_rows.append(
- ' "{0}" if {1}'.format(prompt,
- self._expr_val_str(cond_expr)))
+ prompts_str_rows.append(
+ ' "{0}"'.format(prompt) if cond_expr is None else
+ ' "{0}" if {1}'.format(prompt,
+ self._expr_val_str(cond_expr)))
prompts_str = "\n".join(prompts_str_rows)
# Build locations string
- if not sc.def_locations:
- locations_str = "(no locations)"
- else:
- locations_str = " ".join(["{0}:{1}".format(filename, linenr) for
- (filename, linenr) in sc.def_locations])
+ locations_str = "(no locations)" if not sc.def_locations else \
+ " ".join(["{0}:{1}".format(filename, linenr) for
+ filename, linenr in sc.def_locations])
# Build additional-dependencies-from-menus-and-ifs string
additional_deps_str = " " + \
@@ -1657,13 +1674,11 @@ class Config(object):
else:
ranges_str_rows = []
for l, u, cond_expr in sc.ranges:
- if cond_expr is None:
- ranges_str_rows.append(" [{0}, {1}]".format(s(l),
- s(u)))
- else:
- ranges_str_rows.append(" [{0}, {1}] if {2}"
- .format(s(l), s(u),
- self._expr_val_str(cond_expr)))
+ ranges_str_rows.append(
+ " [{0}, {1}]".format(s(l), s(u))
+ if cond_expr is None else
+ " [{0}, {1}] if {2}"
+ .format(s(l), s(u), self._expr_val_str(cond_expr)))
ranges_str = "\n".join(ranges_str_rows)
# Build default values string
@@ -1685,14 +1700,24 @@ class Config(object):
else:
selects_str_rows = []
for target, cond_expr in sc.orig_selects:
- if cond_expr is None:
- selects_str_rows.append(" {0}".format(target.name))
- else:
- selects_str_rows.append(
- " {0} if {1}".format(target.name,
- self._expr_val_str(cond_expr)))
+ selects_str_rows.append(
+ " {0}".format(target.name) if cond_expr is None else
+ " {0} if {1}".format(target.name,
+ self._expr_val_str(cond_expr)))
selects_str = "\n".join(selects_str_rows)
+ # Build implies string
+ if not sc.orig_implies:
+ implies_str = " (no implies)"
+ else:
+ implies_str_rows = []
+ for target, cond_expr in sc.orig_implies:
+ implies_str_rows.append(
+ " {0}".format(target.name) if cond_expr is None else
+ " {0} if {1}".format(target.name,
+ self._expr_val_str(cond_expr)))
+ implies_str = "\n".join(implies_str_rows)
+
res = _lines("Symbol " +
("(no name)" if sc.name is None else sc.name),
"Type : " + TYPENAME[sc.type],
@@ -1711,9 +1736,16 @@ class Config(object):
defaults_str,
"Selects:",
selects_str,
+ "Implies:",
+ implies_str,
"Reverse (select-related) dependencies:",
- " (no reverse dependencies)" if sc.rev_dep == "n"
- else " " + self._expr_val_str(sc.rev_dep),
+ " (no reverse dependencies)"
+ if sc.rev_dep == "n"
+ else " " + self._expr_val_str(sc.rev_dep),
+ "Weak reverse (imply-related) dependencies:",
+ " (no weak reverse dependencies)"
+ if sc.weak_rev_dep == "n"
+ else " " + self._expr_val_str(sc.weak_rev_dep),
"Additional dependencies from enclosing menus "
"and ifs:",
additional_deps_str,
@@ -1735,11 +1767,10 @@ class Config(object):
else:
defaults_str_rows = []
for sym, cond_expr in sc.orig_def_exprs:
- if cond_expr is None:
- defaults_str_rows.append(" {0}".format(sym.name))
- else:
- defaults_str_rows.append(" {0} if {1}".format(sym.name,
- self._expr_val_str(cond_expr)))
+ defaults_str_rows.append(
+ " {0}".format(sym.name) if cond_expr is None else
+ " {0} if {1}".format(sym.name,
+ self._expr_val_str(cond_expr)))
defaults_str = "\n".join(defaults_str_rows)
# Build contained symbols string
@@ -1919,26 +1950,25 @@ class Symbol(Item):
self.write_to_conf = (mode != "n")
if mode == "y":
- if choice.get_selection() is self:
- new_val = "y"
- else:
- new_val = "n"
+ new_val = "y" if choice.get_selection() is self \
+ else "n"
elif mode == "m":
if self.user_val == "m" or self.user_val == "y":
new_val = "m"
else:
# If the symbol is visible and has a user value, use that.
- # Otherwise, look at defaults.
- use_defaults = True
+ # Otherwise, look at defaults and weak reverse dependencies
+ # (implies).
+ use_defaults_and_weak_rev_deps = True
if vis != "n":
self.write_to_conf = True
if self.user_val is not None:
new_val = self.config._eval_min(self.user_val, vis)
- use_defaults = False
+ use_defaults_and_weak_rev_deps = False
- if use_defaults:
+ if use_defaults_and_weak_rev_deps:
for val_expr, cond_expr in self.def_exprs:
cond_eval = self.config._eval_expr(cond_expr)
if cond_eval != "n":
@@ -1947,14 +1977,25 @@ class Symbol(Item):
cond_eval)
break
+ weak_rev_dep_val = \
+ self.config._eval_expr(self.weak_rev_dep)
+ if weak_rev_dep_val != "n":
+ self.write_to_conf = True
+ new_val = self.config._eval_max(new_val,
+ weak_rev_dep_val)
+
# Reverse (select-related) dependencies take precedence
rev_dep_val = self.config._eval_expr(self.rev_dep)
if rev_dep_val != "n":
self.write_to_conf = True
new_val = self.config._eval_max(new_val, rev_dep_val)
- # Promote "m" to "y" for booleans
- if new_val == "m" and self.type == BOOL:
+ # We need to promote "m" to "y" in two circumstances:
+ # 1) If our type is boolean
+ # 2) If our weak_rev_dep (from IMPLY) is "y"
+ if new_val == "m" and \
+ (self.type == BOOL or
+ self.config._eval_expr(self.weak_rev_dep) == "y"):
new_val = "y"
elif self.type == INT or self.type == HEX:
@@ -2189,6 +2230,13 @@ class Symbol(Item):
get_referenced_symbols()."""
return self.selected_syms
+ def get_implied_symbols(self):
+ """Returns the set() of all symbols X for which this symbol has an
+ 'imply X' or 'imply X if Y' (regardless of whether Y is satisfied or
+ not). This is a subset of the symbols returned by
+ get_referenced_symbols()."""
+ return self.implied_syms
+
def set_user_value(self, v):
"""Sets the user value of the symbol.
@@ -2304,16 +2352,18 @@ class Symbol(Item):
self.ranges = [] # 'range' properties (for int and hex)
self.help = None # Help text
self.rev_dep = "n" # Reverse (select-related) dependencies
+ self.weak_rev_dep = "n" # Weak reverse (imply-related) dependencies
self.config = None
self.parent = None
self.user_val = None # Value set by user
- # The prompt, default value and select conditions without any
+ # The prompt, default value, select, and imply conditions without any
# dependencies from menus and ifs propagated to them
self.orig_prompts = []
self.orig_def_exprs = []
self.orig_selects = []
+ self.orig_implies = []
# Dependencies inherited from containing menus and ifs
self.deps_from_containing = None
@@ -2323,13 +2373,15 @@ class Symbol(Item):
# The set of symbols selected by this symbol (see
# get_selected_symbols())
self.selected_syms = set()
+ # The set of symbols implied by this symbol (see get_implied_symbols())
+ self.implied_syms = set()
# Like 'referenced_syms', but includes symbols from
# dependencies inherited from enclosing menus and ifs
self.all_referenced_syms = set()
- # This records only dependencies specified with 'depends on'. Needed
- # when determining actual choice items (hrrrr...). See also
- # Choice._determine_actual_symbols().
+ # This records only dependencies from enclosing ifs and menus together
+ # with local 'depends on' dependencies. Needed when determining actual
+ # choice items (hrrrr...). See Choice._determine_actual_symbols().
self.menu_dep = None
# See Symbol.get_ref/def_locations().
@@ -2470,18 +2522,17 @@ class Symbol(Item):
return
if self.type == BOOL or self.type == TRISTATE:
- if val == "y" or val == "m":
- append_fn("CONFIG_{0}={1}".format(self.name, val))
- else:
- append_fn("# CONFIG_{0} is not set".format(self.name))
+ append_fn("{0}{1}={2}".format(self.config.config_prefix, self.name, val)
+ if val == "y" or val == "m" else
+ "# {0}{1} is not set".format(self.config.config_prefix, self.name))
elif self.type == INT or self.type == HEX:
- append_fn("CONFIG_{0}={1}".format(self.name, val))
+ append_fn("{0}{1}={2}".format(self.config.config_prefix, self.name, val))
elif self.type == STRING:
# Escape \ and "
- append_fn('CONFIG_{0}="{1}"'
- .format(self.name,
+ append_fn('{0}{1}="{2}"'
+ .format(self.config.config_prefix, self.name,
val.replace("\\", "\\\\").replace('"', '\\"')))
else:
@@ -2635,7 +2686,7 @@ class Menu(Item):
self.title = None
self.dep_expr = None
self.visible_if_expr = None
- self.block = None
+ self.block = [] # List of contained items
self.config = None
self.parent = None
@@ -2852,7 +2903,7 @@ class Choice(Item):
self.prompts = []
self.def_exprs = [] # 'default' properties
self.help = None # Help text
- self.block = None # List of contained items
+ self.block = [] # List of contained items
self.config = None
self.parent = None
@@ -3177,7 +3228,13 @@ def _get_visibility(sc):
vis = sc.config._eval_max(vis, cond_expr)
if isinstance(sc, Symbol) and sc.is_choice_sym:
- vis = sc.config._eval_min(vis, _get_visibility(sc.parent))
+ if sc.type == TRISTATE and vis == "m" and \
+ sc.parent.get_mode() == "y":
+ # Choice symbols with visibility "m" are not visible if the
+ # choice has mode "y"
+ vis = "n"
+ else:
+ vis = sc.config._eval_min(vis, _get_visibility(sc.parent))
# Promote "m" to "y" if we're dealing with a non-tristate
if vis == "m" and sc.type != TRISTATE:
@@ -3434,7 +3491,7 @@ _get_keyword = \
"prompt": T_PROMPT, "default": T_DEFAULT, "bool": T_BOOL, "boolean": T_BOOL,
"tristate": T_TRISTATE, "int": T_INT, "hex": T_HEX, "def_bool": T_DEF_BOOL,
"def_tristate": T_DEF_TRISTATE, "string": T_STRING, "select": T_SELECT,
- "imply": T_IMPLY, "range": T_RANGE, "option": T_OPTION,
+ "imply" : T_IMPLY, "range": T_RANGE, "option": T_OPTION,
"allnoconfig_y": T_ALLNOCONFIG_Y, "env": T_ENV,
"defconfig_list": T_DEFCONFIG_LIST, "modules": T_MODULES,
"visible": T_VISIBLE}.get
@@ -3455,10 +3512,6 @@ _initial_token_re_match = re.compile(r"[^\w]*(\w+)\s*").match
# trailing whitespace as an optimization.
_id_keyword_re_match = re.compile(r"\s*([\w./-]+)\s*").match
-# Regular expressions for parsing .config files
-_set_re_match = re.compile(r"CONFIG_(\w+)=(.*)").match
-_unset_re_match = re.compile(r"# CONFIG_(\w+) is not set").match
-
# Regular expression for finding $-references to symbols in strings
_sym_ref_re_search = re.compile(r"\$[A-Za-z0-9_]+").search
diff --git a/tools/moveconfig.py b/tools/moveconfig.py
index 6f549a51c1..e3116461ba 100755
--- a/tools/moveconfig.py
+++ b/tools/moveconfig.py
@@ -1472,7 +1472,7 @@ def find_kconfig_rules(kconf, config, imply_config):
"""
sym = kconf.get_symbol(imply_config)
if sym:
- for sel in sym.get_selected_symbols():
+ for sel in sym.get_selected_symbols() | sym.get_implied_symbols():
if sel.get_name() == config:
return sym
return None