summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Kconfig23
-rw-r--r--Makefile10
-rw-r--r--README8
-rw-r--r--arch/Kconfig5
-rw-r--r--arch/arm/Kconfig11
-rw-r--r--arch/arm/config.mk4
-rw-r--r--arch/arm/cpu/arm11/cpu.c17
-rw-r--r--arch/arm/cpu/arm926ejs/cache.c17
-rw-r--r--arch/arm/cpu/armv7/Kconfig2
-rw-r--r--arch/arm/cpu/armv7/Makefile2
-rw-r--r--arch/arm/cpu/armv7/am33xx/config.mk1
-rw-r--r--arch/arm/cpu/armv7/cache_v7.c48
-rw-r--r--arch/arm/cpu/armv7/ls102xa/psci.S26
-rw-r--r--arch/arm/cpu/armv7/mx7/psci-mx7.c2
-rw-r--r--arch/arm/cpu/armv7/mx7/psci.S31
-rw-r--r--arch/arm/cpu/armv7/nonsec_virt.S7
-rw-r--r--arch/arm/cpu/armv7/omap-common/Makefile2
-rw-r--r--arch/arm/cpu/armv7/omap-common/config_secure.mk75
-rw-r--r--arch/arm/cpu/armv7/omap-common/emif-common.c3
-rw-r--r--arch/arm/cpu/armv7/omap-common/hwinit-common.c3
-rw-r--r--arch/arm/cpu/armv7/omap-common/lowlevel_init.S45
-rw-r--r--arch/arm/cpu/armv7/omap-common/sec-common.c139
-rw-r--r--arch/arm/cpu/armv7/omap5/config.mk3
-rw-r--r--arch/arm/cpu/armv7/psci-common.c39
-rw-r--r--arch/arm/cpu/armv7/psci.S55
-rw-r--r--arch/arm/cpu/armv7/sunxi/Makefile1
-rw-r--r--arch/arm/cpu/armv7/sunxi/psci.c9
-rw-r--r--arch/arm/cpu/armv7/sunxi/psci_head.S66
-rw-r--r--arch/arm/cpu/armv7/virt-dt.c63
-rw-r--r--arch/arm/cpu/armv7m/config.mk2
-rw-r--r--arch/arm/cpu/armv8/Kconfig18
-rw-r--r--arch/arm/cpu/armv8/Makefile5
-rw-r--r--arch/arm/cpu/armv8/cache_v8.c112
-rw-r--r--arch/arm/cpu/armv8/cpu-dt.c31
-rw-r--r--arch/arm/cpu/armv8/fsl-layerscape/Makefile1
-rw-r--r--arch/arm/cpu/armv8/fsl-layerscape/cpu.c396
-rw-r--r--arch/arm/cpu/armv8/fsl-layerscape/doc/README.lsch32
-rw-r--r--arch/arm/cpu/armv8/fsl-layerscape/fdt.c33
-rw-r--r--arch/arm/cpu/armv8/fsl-layerscape/ppa.c48
-rw-r--r--arch/arm/cpu/armv8/s32v234/cpu.c12
-rw-r--r--arch/arm/cpu/armv8/sec_firmware.c270
-rw-r--r--arch/arm/cpu/armv8/sec_firmware_asm.S53
-rw-r--r--arch/arm/cpu/armv8/spin_table.c63
-rw-r--r--arch/arm/cpu/armv8/spin_table_v8.S23
-rw-r--r--arch/arm/cpu/armv8/start.S10
-rw-r--r--arch/arm/cpu/armv8/zynqmp/cpu.c21
-rw-r--r--arch/arm/cpu/armv8/zynqmp/mp.c2
-rw-r--r--arch/arm/cpu/u-boot.lds60
-rw-r--r--arch/arm/dts/Makefile1
-rw-r--r--arch/arm/dts/dra7-evm.dts6
-rw-r--r--arch/arm/dts/dra72-evm.dts6
-rw-r--r--arch/arm/dts/exynos4210-origen.dts2
-rw-r--r--arch/arm/dts/exynos4210-trats.dts4
-rw-r--r--arch/arm/dts/exynos4210-universal_c210.dts4
-rw-r--r--arch/arm/dts/exynos4412-odroid.dts4
-rw-r--r--arch/arm/dts/exynos4412-trats2.dts6
-rw-r--r--arch/arm/dts/k2e-evm.dts3
-rw-r--r--arch/arm/dts/k2g-evm.dts69
-rw-r--r--arch/arm/dts/k2g.dtsi61
-rw-r--r--arch/arm/dts/k2hk-evm.dts3
-rw-r--r--arch/arm/dts/k2l-evm.dts3
-rw-r--r--arch/arm/dts/keystone.dtsi3
-rw-r--r--arch/arm/dts/rk3288-firefly.dts3
-rw-r--r--arch/arm/dts/sun50i-a64-pine64-plus.dts13
-rw-r--r--arch/arm/dts/sun50i-a64.dtsi33
-rw-r--r--arch/arm/dts/sun8i-h3-orangepi-2.dts13
-rw-r--r--arch/arm/dts/sun8i-h3-orangepi-lite.dts178
-rw-r--r--arch/arm/dts/sun8i-h3-orangepi-pc.dts12
-rw-r--r--arch/arm/dts/sun8i-h3-orangepi-plus.dts127
-rw-r--r--arch/arm/dts/sun8i-h3.dtsi35
-rw-r--r--arch/arm/imx-common/ddrmc-vf610.c2
-rw-r--r--arch/arm/include/asm/arch-fsl-layerscape/cpu.h310
-rw-r--r--arch/arm/include/asm/arch-fsl-layerscape/ppa.h16
-rw-r--r--arch/arm/include/asm/arch-rockchip/sdram.h14
-rw-r--r--arch/arm/include/asm/arch-stm32f7/fmc.h75
-rw-r--r--arch/arm/include/asm/arch-stm32f7/stm32.h46
-rw-r--r--arch/arm/include/asm/arch-stm32f7/stm32_periph.h2
-rw-r--r--arch/arm/include/asm/arch-sunxi/clock_sun6i.h4
-rw-r--r--arch/arm/include/asm/arch-sunxi/cpu_sun4i.h3
-rw-r--r--arch/arm/include/asm/arch-sunxi/gpio.h3
-rw-r--r--arch/arm/include/asm/arch-sunxi/mmc.h1
-rw-r--r--arch/arm/include/asm/arch-sunxi/spl.h9
-rw-r--r--arch/arm/include/asm/arch-tegra/board.h2
-rw-r--r--arch/arm/include/asm/arch-tegra/clock.h2
-rw-r--r--arch/arm/include/asm/arch-tegra124/display.h2
-rw-r--r--arch/arm/include/asm/armv7.h2
-rw-r--r--arch/arm/include/asm/armv7m.h11
-rw-r--r--arch/arm/include/asm/armv8/mmu.h5
-rw-r--r--arch/arm/include/asm/armv8/sec_firmware.h22
-rw-r--r--arch/arm/include/asm/cache.h2
-rw-r--r--arch/arm/include/asm/global_data.h15
-rw-r--r--arch/arm/include/asm/io.h34
-rw-r--r--arch/arm/include/asm/omap_common.h6
-rw-r--r--arch/arm/include/asm/omap_sec_common.h30
-rw-r--r--arch/arm/include/asm/psci.h10
-rw-r--r--arch/arm/include/asm/secure.h3
-rw-r--r--arch/arm/include/asm/setjmp.h4
-rw-r--r--arch/arm/include/asm/spin_table.h14
-rw-r--r--arch/arm/include/asm/types.h1
-rw-r--r--arch/arm/lib/Makefile2
-rw-r--r--arch/arm/lib/bootm-fdt.c9
-rw-r--r--arch/arm/lib/cache.c22
-rw-r--r--arch/arm/lib/psci-dt.c123
-rw-r--r--arch/arm/lib/sections.c2
-rw-r--r--arch/arm/mach-exynos/include/mach/dwmmc.h1
-rw-r--r--arch/arm/mach-exynos/mmu-arm64.c9
-rw-r--r--arch/arm/mach-meson/board.c6
-rw-r--r--arch/arm/mach-rockchip/Kconfig27
-rw-r--r--arch/arm/mach-rockchip/rk3288-board-spl.c25
-rw-r--r--arch/arm/mach-rockchip/rk3288/sdram_rk3288.c130
-rw-r--r--arch/arm/mach-rockchip/rk3288/syscon_rk3288.c38
-rw-r--r--arch/arm/mach-snapdragon/sysmap-apq8016.c6
-rw-r--r--arch/arm/mach-stm32/stm32f7/Makefile2
-rw-r--r--arch/arm/mach-stm32/stm32f7/clock.c231
-rw-r--r--arch/arm/mach-stm32/stm32f7/soc.c76
-rw-r--r--arch/arm/mach-sunxi/board.c35
-rw-r--r--arch/arm/mach-tegra/arm64-mmu.c6
-rw-r--r--arch/arm/mach-tegra/clock.c2
-rw-r--r--arch/arm/mach-tegra/psci.S16
-rw-r--r--arch/arm/mach-uniphier/arm64/mem_map.c6
-rw-r--r--arch/nds32/include/asm/io.h34
-rw-r--r--arch/powerpc/cpu/mpc85xx/mp.c2
-rw-r--r--arch/powerpc/cpu/ppc4xx/start.S2
-rw-r--r--arch/powerpc/include/asm/arch-mpc85xx/gpio.h6
-rw-r--r--arch/powerpc/include/asm/status_led.h2
-rw-r--r--arch/sandbox/Kconfig7
-rw-r--r--arch/sandbox/config.mk5
-rw-r--r--arch/sandbox/cpu/Makefile1
-rw-r--r--arch/sandbox/cpu/cpu.c6
-rw-r--r--arch/sandbox/cpu/os.c51
-rw-r--r--arch/sandbox/cpu/spl.c68
-rw-r--r--arch/sandbox/cpu/start.c2
-rw-r--r--arch/sandbox/cpu/u-boot-spl.lds24
-rw-r--r--arch/sandbox/dts/sandbox.dts31
-rw-r--r--arch/sandbox/include/asm/spl.h23
-rw-r--r--arch/sandbox/lib/Makefile2
-rw-r--r--arch/sandbox/lib/bootm.c2
-rw-r--r--arch/sh/include/asm/io.h33
-rw-r--r--arch/x86/Kconfig4
-rw-r--r--arch/x86/cpu/baytrail/Kconfig11
-rw-r--r--arch/x86/cpu/baytrail/acpi.c26
-rw-r--r--arch/x86/cpu/ivybridge/lpc.c6
-rw-r--r--arch/x86/cpu/ivybridge/sdram.c5
-rw-r--r--arch/x86/cpu/quark/acpi.c7
-rw-r--r--arch/x86/dts/Makefile3
-rw-r--r--arch/x86/dts/baytrail_som-db5800-som-6867.dts289
-rw-r--r--arch/x86/include/asm/acpi/global_nvs.h19
-rw-r--r--arch/x86/include/asm/acpi_table.h4
-rw-r--r--arch/x86/include/asm/arch-baytrail/acpi/global_nvs.asl15
-rw-r--r--arch/x86/include/asm/arch-baytrail/acpi/lpc.asl19
-rw-r--r--arch/x86/include/asm/arch-baytrail/acpi/platform.asl3
-rw-r--r--arch/x86/include/asm/arch-baytrail/global_nvs.h21
-rw-r--r--arch/x86/include/asm/arch-quark/acpi/global_nvs.asl14
-rw-r--r--arch/x86/include/asm/arch-quark/acpi/platform.asl3
-rw-r--r--arch/x86/include/asm/arch-quark/global_nvs.h20
-rw-r--r--arch/x86/lib/acpi_table.c22
-rw-r--r--arch/x86/lib/fsp/fsp_support.c2
-rw-r--r--board/advantech/Kconfig28
-rw-r--r--board/advantech/som-db5800-som-6867/.gitignore3
-rw-r--r--board/advantech/som-db5800-som-6867/Kconfig28
-rw-r--r--board/advantech/som-db5800-som-6867/MAINTAINERS7
-rw-r--r--board/advantech/som-db5800-som-6867/Makefile8
-rw-r--r--board/advantech/som-db5800-som-6867/acpi/mainboard.asl11
-rw-r--r--board/advantech/som-db5800-som-6867/dsdt.asl14
-rw-r--r--board/advantech/som-db5800-som-6867/som-db5800-som-6867.c24
-rw-r--r--board/advantech/som-db5800-som-6867/start.S9
-rw-r--r--board/armltd/vexpress64/vexpress64.c6
-rw-r--r--board/cavium/thunderx/thunderx.c9
-rw-r--r--board/congatec/conga-qeval20-qa3-e3845/conga-qeval20-qa3.c2
-rw-r--r--board/evb_rk3036/evb_rk3036/MAINTAINERS6
-rw-r--r--board/freescale/ls1043aqds/ddr.c15
-rw-r--r--board/freescale/ls1043ardb/ddr.c15
-rw-r--r--board/freescale/ls1043ardb/ls1043ardb.c8
-rw-r--r--board/freescale/ls2080a/ddr.c15
-rw-r--r--board/freescale/ls2080aqds/ddr.c15
-rw-r--r--board/freescale/ls2080ardb/ddr.c15
-rw-r--r--board/hisilicon/hikey/hikey.c6
-rw-r--r--board/keymile/common/common.c2
-rw-r--r--board/keymile/kmp204x/ddr.c2
-rw-r--r--board/kylin/kylin_rk3036/MAINTAINERS6
-rw-r--r--board/raspberrypi/rpi/rpi.c6
-rw-r--r--board/sandbox/MAINTAINERS7
-rw-r--r--board/st/stm32f746-disco/stm32f746-disco.c239
-rw-r--r--board/sunxi/MAINTAINERS1
-rw-r--r--board/sunxi/README.pine6498
-rw-r--r--board/sunxi/board.c98
-rw-r--r--board/ti/am43xx/board.c8
-rw-r--r--board/ti/am57xx/board.c8
-rw-r--r--board/ti/dra7xx/evm.c9
-rw-r--r--cmd/bdinfo.c4
-rw-r--r--cmd/i2c.c2
-rw-r--r--cmd/sf.c2
-rw-r--r--common/board_f.c14
-rw-r--r--common/bootm.c12
-rw-r--r--common/bootm_os.c1
-rw-r--r--common/env_common.c2
-rw-r--r--common/env_sf.c8
-rw-r--r--common/fb_mmc.c2
-rw-r--r--common/image.c87
-rw-r--r--common/spl/spl.c10
-rw-r--r--common/spl/spl_fit.c21
-rw-r--r--common/spl/spl_mmc.c6
-rw-r--r--configs/am43xx_hs_evm_defconfig1
-rw-r--r--configs/am57xx_hs_evm_defconfig1
-rw-r--r--configs/bayleybay_defconfig1
-rw-r--r--configs/conga-qeval20-qa3-e3845-internal-uart_defconfig63
-rw-r--r--configs/da850evm_defconfig1
-rw-r--r--configs/dra7xx_hs_evm_defconfig1
-rw-r--r--configs/dragonboard410c_defconfig2
-rw-r--r--configs/firefly-rk3288_defconfig3
-rw-r--r--configs/k2e_evm_defconfig2
-rw-r--r--configs/k2g_evm_defconfig4
-rw-r--r--configs/k2hk_evm_defconfig2
-rw-r--r--configs/k2l_evm_defconfig2
-rw-r--r--configs/minnowmax_defconfig1
-rw-r--r--configs/orangepi_lite_defconfig15
-rw-r--r--configs/orangepi_pc_defconfig3
-rw-r--r--configs/pine64_plus_defconfig1
-rw-r--r--configs/sandbox_defconfig4
-rw-r--r--configs/sandbox_spl_defconfig183
-rw-r--r--configs/som-db5800-som-6867_defconfig61
-rw-r--r--doc/README.gpt2
-rw-r--r--doc/README.scrapyard2
-rw-r--r--doc/README.ti-secure177
-rw-r--r--doc/README.x862
-rw-r--r--doc/driver-model/of-plat.txt310
-rw-r--r--doc/feature-removal-schedule.txt2
-rw-r--r--doc/git-mailrc2
-rw-r--r--drivers/bios_emulator/x86emu/sys.c2
-rw-r--r--drivers/clk/clk-uclass.c22
-rw-r--r--drivers/clk/clk_fixed_rate.c2
-rw-r--r--drivers/clk/clk_rk3288.c33
-rw-r--r--drivers/core/device-remove.c2
-rw-r--r--drivers/core/device.c58
-rw-r--r--drivers/core/lists.c2
-rw-r--r--drivers/core/regmap.c57
-rw-r--r--drivers/core/root.c4
-rw-r--r--drivers/core/syscon-uclass.c13
-rw-r--r--drivers/crypto/fsl/desc.h2
-rw-r--r--drivers/ddr/fsl/ctrl_regs.c2
-rw-r--r--drivers/dfu/dfu_mmc.c11
-rw-r--r--drivers/fpga/fpga.c2
-rw-r--r--drivers/gpio/mpc85xx_gpio.c37
-rw-r--r--drivers/misc/Makefile7
-rw-r--r--drivers/misc/cros_ec_sandbox.c11
-rw-r--r--drivers/misc/spltest_sandbox.c53
-rw-r--r--drivers/mmc/Kconfig13
-rw-r--r--drivers/mmc/Makefile3
-rw-r--r--drivers/mmc/dw_mmc.c33
-rw-r--r--drivers/mmc/exynos_dw_mmc.c148
-rw-r--r--drivers/mmc/mmc-uclass.c146
-rw-r--r--drivers/mmc/mmc.c371
-rw-r--r--drivers/mmc/mmc_boot.c131
-rw-r--r--drivers/mmc/mmc_legacy.c91
-rw-r--r--drivers/mmc/mmc_private.h47
-rw-r--r--drivers/mmc/msm_sdhci.c35
-rw-r--r--drivers/mmc/rockchip_dw_mmc.c73
-rw-r--r--drivers/mmc/sandbox_mmc.c17
-rw-r--r--drivers/mmc/sdhci.c147
-rw-r--r--drivers/mmc/sunxi_mmc.c27
-rw-r--r--drivers/mtd/cfi_flash.c2
-rw-r--r--drivers/mtd/nand/mxs_nand.c2
-rw-r--r--drivers/mtd/nand/tegra_nand.c2
-rw-r--r--drivers/mtd/spi/Kconfig12
-rw-r--r--drivers/mtd/spi/Makefile1
-rw-r--r--drivers/mtd/spi/sunxi_spi_spl.c283
-rw-r--r--drivers/net/Kconfig9
-rw-r--r--drivers/net/Makefile1
-rw-r--r--drivers/net/sun8i_emac.c789
-rw-r--r--drivers/pci/pci_rom.c11
-rw-r--r--drivers/pinctrl/rockchip/pinctrl_rk3288.c8
-rw-r--r--drivers/rtc/date.c71
-rw-r--r--drivers/serial/Kconfig9
-rw-r--r--drivers/serial/Makefile3
-rw-r--r--drivers/serial/ns16550.c4
-rw-r--r--drivers/serial/sandbox.c2
-rw-r--r--drivers/serial/serial-uclass.c8
-rw-r--r--drivers/serial/serial_rockchip.c43
-rw-r--r--drivers/serial/serial_stm32x7.c16
-rw-r--r--drivers/spi/cadence_qspi.c3
-rw-r--r--drivers/spi/cadence_qspi.h2
-rw-r--r--drivers/spi/cadence_qspi_apb.c15
-rw-r--r--drivers/spi/davinci_spi.c329
-rw-r--r--drivers/spi/spi-uclass.c10
-rw-r--r--drivers/usb/musb-new/musb_dsps.c2
-rw-r--r--drivers/video/tegra.c2
-rw-r--r--dts/Kconfig21
-rw-r--r--include/asm-generic/global_data.h14
-rw-r--r--include/clk.h4
-rw-r--r--include/common.h12
-rw-r--r--include/configs/arndale.h1
-rw-r--r--include/configs/bcm_ep_board.h1
-rw-r--r--include/configs/dragonboard410c.h4
-rw-r--r--include/configs/jetson-tk1.h1
-rw-r--r--include/configs/k2g_evm.h6
-rw-r--r--include/configs/ls1021aqds.h1
-rw-r--r--include/configs/ls1021atwr.h1
-rw-r--r--include/configs/ls1043ardb.h11
-rw-r--r--include/configs/mxs.h2
-rw-r--r--include/configs/rk3036_common.h1
-rw-r--r--include/configs/rk3288_common.h1
-rw-r--r--include/configs/sandbox.h4
-rw-r--r--include/configs/sandbox_spl.h20
-rw-r--r--include/configs/som-db5800-som-6867.h36
-rw-r--r--include/configs/stm32f746-disco.h11
-rw-r--r--include/configs/sun6i.h1
-rw-r--r--include/configs/sun7i.h2
-rw-r--r--include/configs/sunxi-common.h5
-rw-r--r--include/configs/ti_armv7_keystone2.h4
-rw-r--r--include/configs/v38b.h2
-rw-r--r--include/configs/vexpress_ca15_tc2.h1
-rw-r--r--include/dm/device.h19
-rw-r--r--include/dm/platdata.h5
-rw-r--r--include/dm/uclass-id.h4
-rw-r--r--include/dt-structs.h19
-rw-r--r--include/dwmmc.h73
-rw-r--r--include/fdtdec.h8
-rw-r--r--include/image.h247
-rw-r--r--include/linux/io.h16
-rw-r--r--include/linux/types.h4
-rw-r--r--include/mmc.h66
-rw-r--r--include/net.h2
-rw-r--r--include/os.h25
-rw-r--r--include/regmap.h16
-rw-r--r--include/sdhci.h80
-rw-r--r--include/syscon.h11
-rw-r--r--lib/Makefile5
-rw-r--r--lib/fdtdec.c19
-rw-r--r--lib/hashtable.c2
-rw-r--r--lib/libfdt/libfdt.swig89
-rw-r--r--lib/libfdt/setup.py38
-rw-r--r--lib/libfdt/test_libfdt.py14
-rw-r--r--lib/tiny-printf.c9
-rw-r--r--net/eth_internal.h2
-rw-r--r--post/cpu/ppc4xx/ether.c2
-rw-r--r--scripts/Makefile.host9
-rw-r--r--scripts/Makefile.spl47
-rw-r--r--test/README92
-rw-r--r--test/py/conftest.py3
-rw-r--r--test/py/multiplexed_log.py10
-rw-r--r--test/py/tests/test_ofplatdata.py42
-rw-r--r--test/py/tests/test_vboot.py185
-rw-r--r--test/py/tests/vboot/sandbox-kernel.dts (renamed from test/vboot/sandbox-kernel.dts)0
-rw-r--r--test/py/tests/vboot/sandbox-u-boot.dts (renamed from test/vboot/sandbox-u-boot.dts)0
-rw-r--r--test/py/tests/vboot/sign-configs-sha1.its (renamed from test/vboot/sign-configs-sha1.its)0
-rw-r--r--test/py/tests/vboot/sign-configs-sha256.its (renamed from test/vboot/sign-configs-sha256.its)0
-rw-r--r--test/py/tests/vboot/sign-images-sha1.its (renamed from test/vboot/sign-images-sha1.its)0
-rw-r--r--test/py/tests/vboot/sign-images-sha256.its (renamed from test/vboot/sign-images-sha256.its)0
-rw-r--r--test/py/u_boot_console_base.py28
-rw-r--r--test/py/u_boot_console_sandbox.py8
-rw-r--r--test/py/u_boot_spawn.py22
-rw-r--r--test/py/u_boot_utils.py41
-rwxr-xr-xtest/run4
-rw-r--r--test/vboot/.gitignore3
-rwxr-xr-xtest/vboot/vboot_test.sh151
-rw-r--r--tools/Makefile18
-rw-r--r--tools/dtoc/.gitignore1
l---------tools/dtoc/dtoc1
-rwxr-xr-xtools/dtoc/dtoc.py394
-rw-r--r--tools/dtoc/fdt.py180
-rw-r--r--tools/dtoc/fdt_fallback.py207
-rw-r--r--tools/dtoc/fdt_util.py86
-rw-r--r--tools/env/fw_env.config2
-rw-r--r--tools/fit_image.c7
-rw-r--r--tools/image-host.c14
-rw-r--r--tools/mkimage.c70
-rw-r--r--tools/patman/patchstream.py38
367 files changed, 9815 insertions, 2464 deletions
diff --git a/Kconfig b/Kconfig
index 3ceff25..ef12f9f 100644
--- a/Kconfig
+++ b/Kconfig
@@ -114,6 +114,15 @@ if EXPERT
Warning:
When disabling this, please check if malloc calls, maybe
should be replaced by calloc - if one expects zeroed memory.
+
+config TOOLS_DEBUG
+ bool "Enable debug information for tools"
+ help
+ Enable generation of debug information for tools such as mkimage.
+ This can be used for debugging purposes. With debug information
+ it is possible to set breakpoints on particular lines, single-step
+ debug through the source code, etc.
+
endif
endmenu # General setup
@@ -313,6 +322,20 @@ config SPL_LOAD_FIT
particular it can handle selecting from multiple device tree
and passing the correct one to U-Boot.
+config SPL_FIT_IMAGE_POST_PROCESS
+ bool "Enable post-processing of FIT artifacts after loading by the SPL"
+ depends on SPL_LOAD_FIT && TI_SECURE_DEVICE
+ help
+ Allows doing any sort of manipulation to blobs after they got extracted
+ from the U-Boot FIT image like stripping off headers or modifying the
+ size of the blob, verification, authentication, decryption etc. in a
+ platform or board specific way. In order to use this feature a platform
+ or board-specific implementation of board_fit_image_post_process() must
+ be provided. Also, anything done during this post-processing step would
+ need to be comprehended in how the images were prepared before being
+ injected into the FIT creation (i.e. the blobs would have been pre-
+ processed before being added to the FIT image).
+
config SYS_CLK_FREQ
depends on ARC || ARCH_SUNXI
int "CPU clock frequency"
diff --git a/Makefile b/Makefile
index 09a18e1..7ce933c 100644
--- a/Makefile
+++ b/Makefile
@@ -5,7 +5,7 @@
VERSION = 2016
PATCHLEVEL = 07
SUBLEVEL =
-EXTRAVERSION = -rc3
+EXTRAVERSION =
NAME =
# *DOCUMENTATION*
@@ -256,7 +256,8 @@ CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
HOSTCC = cc
HOSTCXX = c++
-HOSTCFLAGS = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer
+HOSTCFLAGS = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer \
+ $(if $(CONFIG_TOOLS_DEBUG),-g)
HOSTCXXFLAGS = -O2
ifeq ($(HOSTOS),cygwin)
@@ -801,7 +802,7 @@ quiet_cmd_pad_cat = CAT $@
cmd_pad_cat = $(cmd_objcopy) && $(append) || rm -f $@
all: $(ALL-y)
-ifeq ($(CONFIG_DM_I2C_COMPAT),y)
+ifeq ($(CONFIG_DM_I2C_COMPAT)$(CONFIG_SANDBOX),y)
@echo "===================== WARNING ======================"
@echo "This board uses CONFIG_DM_I2C_COMPAT. Please remove"
@echo "(possibly in a subsequent patch in your series)"
@@ -1318,7 +1319,8 @@ u-boot.lds: $(LDSCRIPT) prepare FORCE
spl/u-boot-spl.bin: spl/u-boot-spl
@:
-spl/u-boot-spl: tools prepare $(if $(CONFIG_OF_SEPARATE),dts/dt.dtb)
+spl/u-boot-spl: tools prepare \
+ $(if $(CONFIG_OF_SEPARATE)$(CONFIG_SPL_OF_PLATDATA),dts/dt.dtb)
$(Q)$(MAKE) obj=spl -f $(srctree)/scripts/Makefile.spl all
spl/sunxi-spl.bin: spl/u-boot-spl
diff --git a/README b/README
index 26d5ad2..9e8f55d 100644
--- a/README
+++ b/README
@@ -511,7 +511,7 @@ The following options need to be configured:
implemetation.
CONFIG_SYS_FSL_DDR2
- Board config to use DDR2. It can be eanbeld for SoCs with
+ Board config to use DDR2. It can be enabled for SoCs with
Freescale DDR2 or DDR3 controllers, depending on the board
implementation.
@@ -3766,10 +3766,11 @@ Configuration Settings:
You only need to set this if address zero isn't writeable
- CONFIG_SYS_MEM_RESERVE_SECURE
+ Only implemented for ARMv8 for now.
If defined, the size of CONFIG_SYS_MEM_RESERVE_SECURE memory
is substracted from total RAM and won't be reported to OS.
This memory can be used as secure memory. A variable
- gd->secure_ram is used to track the location. In systems
+ gd->arch.secure_ram is used to track the location. In systems
the RAM base is not zero, or RAM is divided into banks,
this variable needs to be recalcuated to get the address.
@@ -3835,9 +3836,6 @@ Configuration Settings:
The memory will be freed (or in fact just forgotten) when
U-Boot relocates itself.
- Pre-relocation malloc() is only supported on ARM and sandbox
- at present but is fairly easy to enable for other archs.
-
- CONFIG_SYS_MALLOC_SIMPLE
Provides a simple and small malloc() and calloc() for those
boards which do not use the full malloc in SPL (which is
diff --git a/arch/Kconfig b/arch/Kconfig
index 566f044..92d4b97 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -1,6 +1,9 @@
config CREATE_ARCH_SYMLINK
bool
+config HAVE_ARCH_IOREMAP
+ bool
+
choice
prompt "Architecture select"
default SANDBOX
@@ -33,6 +36,7 @@ config MICROBLAZE
config MIPS
bool "MIPS architecture"
+ select HAVE_ARCH_IOREMAP
select HAVE_PRIVATE_LIBGCC
select SUPPORT_OF_CONTROL
@@ -63,6 +67,7 @@ config SANDBOX
select DM_I2C
select DM_SPI
select DM_GPIO
+ select DM_MMC
config SH
bool "SuperH architecture"
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 3237a74..585b408 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -842,7 +842,18 @@ config ARCH_ROCKCHIP
select SPL
select OF_CONTROL
select CPU_V7
+ select BLK
select DM
+ select SPL_DM
+ select SYS_MALLOC_F
+ select SPL_SYS_MALLOC_SIMPLE
+ select DM_GPIO
+ select DM_I2C
+ select DM_MMC
+ select DM_MMC_OPS
+ select DM_SERIAL
+ select DM_SPI
+ select DM_SPI_FLASH
config TARGET_THUNDERX_88XX
bool "Support ThunderX 88xx"
diff --git a/arch/arm/config.mk b/arch/arm/config.mk
index 9a5a974..8f85862 100644
--- a/arch/arm/config.mk
+++ b/arch/arm/config.mk
@@ -120,8 +120,8 @@ endif
ifdef CONFIG_ARM64
OBJCOPYFLAGS += -j .text -j .rodata -j .data -j .u_boot_list -j .rela.dyn
else
-OBJCOPYFLAGS += -j .text -j .secure_text -j .rodata -j .hash -j .data -j \
- .got -j .got.plt -j .u_boot_list -j .rel.dyn
+OBJCOPYFLAGS += -j .text -j .secure_text -j .secure_data -j .rodata -j .hash \
+ -j .data -j .got -j .got.plt -j .u_boot_list -j .rel.dyn
endif
ifdef CONFIG_OF_EMBED
diff --git a/arch/arm/cpu/arm11/cpu.c b/arch/arm/cpu/arm11/cpu.c
index 1e4c214..7244c2e 100644
--- a/arch/arm/cpu/arm11/cpu.c
+++ b/arch/arm/cpu/arm11/cpu.c
@@ -69,23 +69,6 @@ void flush_dcache_all(void)
asm volatile("mcr p15, 0, %0, c7, c10, 4" : : "r" (0));
}
-static int check_cache_range(unsigned long start, unsigned long stop)
-{
- int ok = 1;
-
- if (start & (CONFIG_SYS_CACHELINE_SIZE - 1))
- ok = 0;
-
- if (stop & (CONFIG_SYS_CACHELINE_SIZE - 1))
- ok = 0;
-
- if (!ok)
- debug("CACHE: Misaligned operation at range [%08lx, %08lx]\n",
- start, stop);
-
- return ok;
-}
-
void invalidate_dcache_range(unsigned long start, unsigned long stop)
{
if (!check_cache_range(start, stop))
diff --git a/arch/arm/cpu/arm926ejs/cache.c b/arch/arm/cpu/arm926ejs/cache.c
index 2839c86..2119382 100644
--- a/arch/arm/cpu/arm926ejs/cache.c
+++ b/arch/arm/cpu/arm926ejs/cache.c
@@ -29,23 +29,6 @@ void flush_dcache_all(void)
);
}
-static int check_cache_range(unsigned long start, unsigned long stop)
-{
- int ok = 1;
-
- if (start & (CONFIG_SYS_CACHELINE_SIZE - 1))
- ok = 0;
-
- if (stop & (CONFIG_SYS_CACHELINE_SIZE - 1))
- ok = 0;
-
- if (!ok)
- debug("CACHE: Misaligned operation at range [%08lx, %08lx]\n",
- start, stop);
-
- return ok;
-}
-
void invalidate_dcache_range(unsigned long start, unsigned long stop)
{
if (!check_cache_range(start, stop))
diff --git a/arch/arm/cpu/armv7/Kconfig b/arch/arm/cpu/armv7/Kconfig
index afeaac8..bd6108e 100644
--- a/arch/arm/cpu/armv7/Kconfig
+++ b/arch/arm/cpu/armv7/Kconfig
@@ -21,7 +21,7 @@ config ARMV7_BOOT_SEC_DEFAULT
Say Y here to boot in secure mode by default even if non-secure mode
is supported. This option is useful to boot kernels which do not
suppport booting in non-secure mode. Only set this if you need it.
- This can be overriden at run-time by setting the bootm_boot_mode env.
+ This can be overridden at run-time by setting the bootm_boot_mode env.
variable to "sec" or "nonsec".
config ARMV7_VIRT
diff --git a/arch/arm/cpu/armv7/Makefile b/arch/arm/cpu/armv7/Makefile
index ddd8d12..0d4bfbc 100644
--- a/arch/arm/cpu/armv7/Makefile
+++ b/arch/arm/cpu/armv7/Makefile
@@ -19,7 +19,7 @@ endif
endif
obj-$(CONFIG_ARMV7_NONSEC) += nonsec_virt.o virt-v7.o virt-dt.o
-obj-$(CONFIG_ARMV7_PSCI) += psci.o
+obj-$(CONFIG_ARMV7_PSCI) += psci.o psci-common.o
obj-$(CONFIG_IPROC) += iproc-common/
obj-$(CONFIG_KONA) += kona-common/
diff --git a/arch/arm/cpu/armv7/am33xx/config.mk b/arch/arm/cpu/armv7/am33xx/config.mk
index 6d95d32..ab94708 100644
--- a/arch/arm/cpu/armv7/am33xx/config.mk
+++ b/arch/arm/cpu/armv7/am33xx/config.mk
@@ -26,6 +26,7 @@ endif
else
ifeq ($(CONFIG_TI_SECURE_DEVICE),y)
ALL-$(CONFIG_QSPI_BOOT) += u-boot_HS_XIP_X-LOADER
+ALL-y += u-boot_HS.img
endif
ALL-y += u-boot.img
endif
diff --git a/arch/arm/cpu/armv7/cache_v7.c b/arch/arm/cpu/armv7/cache_v7.c
index dc309da..52f1856 100644
--- a/arch/arm/cpu/armv7/cache_v7.c
+++ b/arch/arm/cpu/armv7/cache_v7.c
@@ -19,23 +19,6 @@
void v7_flush_dcache_all(void);
void v7_invalidate_dcache_all(void);
-static int check_cache_range(unsigned long start, unsigned long stop)
-{
- int ok = 1;
-
- if (start & (CONFIG_SYS_CACHELINE_SIZE - 1))
- ok = 0;
-
- if (stop & (CONFIG_SYS_CACHELINE_SIZE - 1))
- ok = 0;
-
- if (!ok)
- debug("CACHE: Misaligned operation at range [%08lx, %08lx]\n",
- start, stop);
-
- return ok;
-}
-
static u32 get_ccsidr(void)
{
u32 ccsidr;
@@ -61,27 +44,8 @@ static void v7_dcache_inval_range(u32 start, u32 stop, u32 line_len)
{
u32 mva;
- /*
- * If start address is not aligned to cache-line do not
- * invalidate the first cache-line
- */
- if (start & (line_len - 1)) {
- printf("ERROR: %s - start address is not aligned - 0x%08x\n",
- __func__, start);
- /* move to next cache line */
- start = (start + line_len - 1) & ~(line_len - 1);
- }
-
- /*
- * If stop address is not aligned to cache-line do not
- * invalidate the last cache-line
- */
- if (stop & (line_len - 1)) {
- printf("ERROR: %s - stop address is not aligned - 0x%08x\n",
- __func__, stop);
- /* align to the beginning of this cache line */
- stop &= ~(line_len - 1);
- }
+ if (!check_cache_range(start, stop))
+ return;
for (mva = start; mva < stop; mva = mva + line_len) {
/* DCIMVAC - Invalidate data cache by MVA to PoC */
@@ -195,6 +159,14 @@ void flush_dcache_all(void)
{
}
+void invalidate_dcache_range(unsigned long start, unsigned long stop)
+{
+}
+
+void flush_dcache_range(unsigned long start, unsigned long stop)
+{
+}
+
void arm_init_before_mmu(void)
{
}
diff --git a/arch/arm/cpu/armv7/ls102xa/psci.S b/arch/arm/cpu/armv7/ls102xa/psci.S
index cf5cd48..f9b26b4 100644
--- a/arch/arm/cpu/armv7/ls102xa/psci.S
+++ b/arch/arm/cpu/armv7/ls102xa/psci.S
@@ -29,16 +29,16 @@
@ r2 = target PC
.globl psci_cpu_on
psci_cpu_on:
- push {lr}
+ push {r4, r5, r6, lr}
@ Clear and Get the correct CPU number
@ r1 = 0xf01
- and r1, r1, #0xff
+ and r4, r1, #0xff
- mov r0, r1
- bl psci_get_cpu_stack_top
- str r2, [r0]
- dsb
+ mov r0, r4
+ mov r1, r2
+ bl psci_save_target_pc
+ mov r1, r4
@ Get DCFG base address
movw r4, #(CONFIG_SYS_FSL_GUTS_ADDR & 0xffff)
@@ -101,7 +101,7 @@ holdoff_release:
@ Return
mov r0, #ARM_PSCI_RET_SUCCESS
- pop {lr}
+ pop {r4, r5, r6, lr}
bx lr
.globl psci_cpu_off
@@ -111,16 +111,4 @@ psci_cpu_off:
1: wfi
b 1b
-.globl psci_arch_init
-psci_arch_init:
- mov r6, lr
-
- bl psci_get_cpu_id
- bl psci_get_cpu_stack_top
- mov sp, r0
-
- bx r6
-
- .globl psci_text_end
-psci_text_end:
.popsection
diff --git a/arch/arm/cpu/armv7/mx7/psci-mx7.c b/arch/arm/cpu/armv7/mx7/psci-mx7.c
index 9a33047..502552d 100644
--- a/arch/arm/cpu/armv7/mx7/psci-mx7.c
+++ b/arch/arm/cpu/armv7/mx7/psci-mx7.c
@@ -1,9 +1,9 @@
#include <asm/io.h>
#include <asm/psci.h>
+#include <asm/secure.h>
#include <asm/arch/imx-regs.h>
#include <common.h>
-#define __secure __attribute__((section("._secure.text")))
#define GPC_CPU_PGC_SW_PDN_REQ 0xfc
#define GPC_CPU_PGC_SW_PUP_REQ 0xf0
diff --git a/arch/arm/cpu/armv7/mx7/psci.S b/arch/arm/cpu/armv7/mx7/psci.S
index 34c6ab3..96e88d6 100644
--- a/arch/arm/cpu/armv7/mx7/psci.S
+++ b/arch/arm/cpu/armv7/mx7/psci.S
@@ -9,35 +9,22 @@
.arch_extension sec
- @ r1 = target CPU
- @ r2 = target PC
-
-.globl psci_arch_init
-psci_arch_init:
- mov r6, lr
-
- bl psci_get_cpu_id
- bl psci_get_cpu_stack_top
- mov sp, r0
-
- bx r6
-
- @ r1 = target CPU
- @ r2 = target PC
-
.globl psci_cpu_on
psci_cpu_on:
- push {lr}
+ push {r4, r5, lr}
+ mov r4, r0
+ mov r5, r1
mov r0, r1
- bl psci_get_cpu_stack_top
- str r2, [r0]
- dsb
+ mov r1, r2
+ bl psci_save_target_pc
+ mov r0, r4
+ mov r1, r5
ldr r2, =psci_cpu_entry
bl imx_cpu_on
- pop {pc}
+ pop {r4, r5, pc}
.globl psci_cpu_off
psci_cpu_off:
@@ -49,6 +36,4 @@ psci_cpu_off:
1: wfi
b 1b
- .globl psci_text_end
-psci_text_end:
.popsection
diff --git a/arch/arm/cpu/armv7/nonsec_virt.S b/arch/arm/cpu/armv7/nonsec_virt.S
index b7563ed..95ce938 100644
--- a/arch/arm/cpu/armv7/nonsec_virt.S
+++ b/arch/arm/cpu/armv7/nonsec_virt.S
@@ -49,8 +49,13 @@ _secure_monitor:
mcr p15, 0, r5, c12, c0, 1
isb
- @ Obtain a secure stack, and configure the PSCI backend
+ @ Obtain a secure stack
+ bl psci_stack_setup
+
+ @ Configure the PSCI backend
+ push {r0, r1, r2, ip}
bl psci_arch_init
+ pop {r0, r1, r2, ip}
#endif
#ifdef CONFIG_ARM_ERRATA_773022
diff --git a/arch/arm/cpu/armv7/omap-common/Makefile b/arch/arm/cpu/armv7/omap-common/Makefile
index 87a7ac0..3172bae 100644
--- a/arch/arm/cpu/armv7/omap-common/Makefile
+++ b/arch/arm/cpu/armv7/omap-common/Makefile
@@ -36,3 +36,5 @@ obj-y += boot-common.o
obj-y += lowlevel_init.o
obj-y += mem-common.o
+
+obj-$(CONFIG_TI_SECURE_DEVICE) += sec-common.o
diff --git a/arch/arm/cpu/armv7/omap-common/config_secure.mk b/arch/arm/cpu/armv7/omap-common/config_secure.mk
index c7bb101..1122439 100644
--- a/arch/arm/cpu/armv7/omap-common/config_secure.mk
+++ b/arch/arm/cpu/armv7/omap-common/config_secure.mk
@@ -12,8 +12,8 @@ cmd_mkomapsecimg = $(TI_SECURE_DEV_PKG)/scripts/create-boot-image.sh \
$(if $(KBUILD_VERBOSE:1=), >/dev/null)
else
cmd_mkomapsecimg = $(TI_SECURE_DEV_PKG)/scripts/create-boot-image.sh \
- $(patsubst u-boot_HS_%,%,$(@F)) $< $@ $(CONFIG_ISW_ENTRY_ADDR) \
- $(if $(KBUILD_VERBOSE:1=), >/dev/null)
+ $(patsubst u-boot_HS_%,%,$(@F)) $< $@ $(CONFIG_ISW_ENTRY_ADDR) \
+ $(if $(KBUILD_VERBOSE:1=), >/dev/null)
endif
else
cmd_mkomapsecimg = echo "WARNING:" \
@@ -25,14 +25,33 @@ cmd_mkomapsecimg = echo "WARNING: TI_SECURE_DEV_PKG environment" \
"variable must be defined for TI secure devices. $@ was NOT created!"
endif
+ifdef CONFIG_SPL_LOAD_FIT
+quiet_cmd_omapsecureimg = SECURE $@
+ifneq ($(TI_SECURE_DEV_PKG),)
+ifneq ($(wildcard $(TI_SECURE_DEV_PKG)/scripts/secure-binary-image.sh),)
+cmd_omapsecureimg = $(TI_SECURE_DEV_PKG)/scripts/secure-binary-image.sh \
+ $< $@ \
+ $(if $(KBUILD_VERBOSE:1=), >/dev/null)
+else
+cmd_omapsecureimg = echo "WARNING:" \
+ "$(TI_SECURE_DEV_PKG)/scripts/secure-binary-image.sh not found." \
+ "$@ was NOT created!"; cp $< $@
+endif
+else
+cmd_omapsecureimg = echo "WARNING: TI_SECURE_DEV_PKG environment" \
+ "variable must be defined for TI secure devices." \
+ "$@ was NOT created!"; cp $< $@
+endif
+endif
+
+
# Standard X-LOADER target (QPSI, NOR flash)
u-boot-spl_HS_X-LOADER: $(obj)/u-boot-spl.bin
$(call if_changed,mkomapsecimg)
-# For MLO targets (SD card boot) the final file name
-# that is copied to the SD card fAT partition must
-# be MLO, so we make a copy of the output file to a
-# new file with that name
+# For MLO targets (SD card boot) the final file name that is copied to the SD
+# card FAT partition must be MLO, so we make a copy of the output file to a new
+# file with that name
u-boot-spl_HS_MLO: $(obj)/u-boot-spl.bin
$(call if_changed,mkomapsecimg)
@if [ -f $@ ]; then \
@@ -51,16 +70,44 @@ u-boot-spl_HS_ULO: $(obj)/u-boot-spl.bin
u-boot-spl_HS_ISSW: $(obj)/u-boot-spl.bin
$(call if_changed,mkomapsecimg)
-# For SPI flash on AM335x and AM43xx, these
-# require special byte swap handling so we use
-# the SPI_X-LOADER target instead of X-LOADER
-# and let the create-boot-image.sh script handle
-# that
+# For SPI flash on AM335x and AM43xx, these require special byte swap handling
+# so we use the SPI_X-LOADER target instead of X-LOADER and let the
+# create-boot-image.sh script handle that
u-boot-spl_HS_SPI_X-LOADER: $(obj)/u-boot-spl.bin
$(call if_changed,mkomapsecimg)
-# For supporting single stage XiP QSPI on AM43xx, the
-# image is a full u-boot file, not an SPL. In this case
-# the mkomapsecimg command looks for a u-boot-HS_* prefix
+# For supporting single stage XiP QSPI on AM43xx, the image is a full u-boot
+# file, not an SPL. In this case the mkomapsecimg command looks for a
+# u-boot-HS_* prefix
u-boot_HS_XIP_X-LOADER: $(obj)/u-boot.bin
$(call if_changed,mkomapsecimg)
+
+# For supporting the SPL loading and interpreting of FIT images whose
+# components are pre-processed before being integrated into the FIT image in
+# order to secure them in some way
+ifdef CONFIG_SPL_LOAD_FIT
+
+MKIMAGEFLAGS_u-boot_HS.img = -f auto -A $(ARCH) -T firmware -C none -O u-boot \
+ -a $(CONFIG_SYS_TEXT_BASE) -e $(CONFIG_SYS_UBOOT_START) \
+ -n "U-Boot $(UBOOTRELEASE) for $(BOARD) board" -E \
+ $(patsubst %,-b arch/$(ARCH)/dts/%.dtb,$(subst ",,$(CONFIG_OF_LIST)))
+
+OF_LIST_TARGETS = $(patsubst %,arch/$(ARCH)/dts/%.dtb,$(subst ",,$(CONFIG_OF_LIST)))
+$(OF_LIST_TARGETS): dtbs
+
+%_HS.dtb: %.dtb
+ $(call if_changed,omapsecureimg)
+ $(Q)if [ -f $@ ]; then \
+ cp -f $@ $<; \
+ fi
+
+u-boot-nodtb_HS.bin: u-boot-nodtb.bin
+ $(call if_changed,omapsecureimg)
+
+u-boot_HS.img: u-boot-nodtb_HS.bin u-boot.img $(patsubst %.dtb,%_HS.dtb,$(OF_LIST_TARGETS))
+ $(call if_changed,mkimage)
+ $(Q)if [ -f $@ ]; then \
+ cp -f $@ u-boot.img; \
+ fi
+
+endif
diff --git a/arch/arm/cpu/armv7/omap-common/emif-common.c b/arch/arm/cpu/armv7/omap-common/emif-common.c
index 9a9c764..2b79010 100644
--- a/arch/arm/cpu/armv7/omap-common/emif-common.c
+++ b/arch/arm/cpu/armv7/omap-common/emif-common.c
@@ -37,7 +37,8 @@ void set_lpmode_selfrefresh(u32 base)
void force_emif_self_refresh()
{
set_lpmode_selfrefresh(EMIF1_BASE);
- set_lpmode_selfrefresh(EMIF2_BASE);
+ if (!is_dra72x())
+ set_lpmode_selfrefresh(EMIF2_BASE);
}
inline u32 emif_num(u32 base)
diff --git a/arch/arm/cpu/armv7/omap-common/hwinit-common.c b/arch/arm/cpu/armv7/omap-common/hwinit-common.c
index 2f9693f..f317293 100644
--- a/arch/arm/cpu/armv7/omap-common/hwinit-common.c
+++ b/arch/arm/cpu/armv7/omap-common/hwinit-common.c
@@ -147,8 +147,7 @@ void early_system_init(void)
hw_data_init();
#ifdef CONFIG_SPL_BUILD
- if (warm_reset() &&
- (is_omap44xx() || (omap_revision() == OMAP5430_ES1_0)))
+ if (warm_reset())
force_emif_self_refresh();
#endif
watchdog_init();
diff --git a/arch/arm/cpu/armv7/omap-common/lowlevel_init.S b/arch/arm/cpu/armv7/omap-common/lowlevel_init.S
index 5283135..66a3b3d 100644
--- a/arch/arm/cpu/armv7/omap-common/lowlevel_init.S
+++ b/arch/arm/cpu/armv7/omap-common/lowlevel_init.S
@@ -16,9 +16,10 @@
#include <asm/arch/spl.h>
#include <linux/linkage.h>
+.arch_extension sec
+
#ifdef CONFIG_SPL
ENTRY(save_boot_params)
-
ldr r1, =OMAP_SRAM_SCRATCH_BOOT_PARAMS
str r0, [r1]
b save_boot_params_ret
@@ -26,14 +27,40 @@ ENDPROC(save_boot_params)
#endif
ENTRY(omap_smc1)
- PUSH {r4-r12, lr} @ save registers - ROM code may pollute
+ push {r4-r12, lr} @ save registers - ROM code may pollute
@ our registers
- MOV r12, r0 @ Service
- MOV r0, r1 @ Argument
- DSB
- DMB
- .word 0xe1600070 @ SMC #0 - hand assembled for GCC versions
- @ call ROM Code API for the service requested
+ mov r12, r0 @ Service
+ mov r0, r1 @ Argument
- POP {r4-r12, pc}
+ dsb
+ dmb
+ smc 0 @ SMC #0 to enter monitor mode
+ @ call ROM Code API for the service requested
+ pop {r4-r12, pc}
ENDPROC(omap_smc1)
+
+ENTRY(omap_smc_sec)
+ push {r4-r12, lr} @ save registers - ROM code may pollute
+ @ our registers
+ mov r6, #0xFF @ Indicate new Task call
+ mov r12, #0x00 @ Secure Service ID in R12
+
+ dsb
+ dmb
+ smc 0 @ SMC #0 to enter monitor mode
+
+ b omap_smc_sec_end @ exit at end of the service execution
+ nop
+
+ @ In case of IRQ happening in Secure, then ARM will branch here.
+ @ At that moment, IRQ will be pending and ARM will jump to Non Secure
+ @ IRQ handler
+ mov r12, #0xFE
+
+ dsb
+ dmb
+ smc 0 @ SMC #0 to enter monitor mode
+
+omap_smc_sec_end:
+ pop {r4-r12, pc}
+ENDPROC(omap_smc_sec)
diff --git a/arch/arm/cpu/armv7/omap-common/sec-common.c b/arch/arm/cpu/armv7/omap-common/sec-common.c
new file mode 100644
index 0000000..246a239
--- /dev/null
+++ b/arch/arm/cpu/armv7/omap-common/sec-common.c
@@ -0,0 +1,139 @@
+/*
+ *
+ * Common security related functions for OMAP devices
+ *
+ * (C) Copyright 2016
+ * Texas Instruments, <www.ti.com>
+ *
+ * Daniel Allred <d-allred@ti.com>
+ * Andreas Dannenberg <dannenberg@ti.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <stdarg.h>
+
+#include <asm/arch/sys_proto.h>
+#include <asm/omap_common.h>
+#include <asm/omap_sec_common.h>
+#include <asm/spl.h>
+#include <spl.h>
+
+/* Index for signature verify ROM API */
+#define API_HAL_KM_VERIFYCERTIFICATESIGNATURE_INDEX (0x0000000E)
+
+static uint32_t secure_rom_call_args[5] __aligned(ARCH_DMA_MINALIGN);
+
+u32 secure_rom_call(u32 service, u32 proc_id, u32 flag, ...)
+{
+ int i;
+ u32 num_args;
+ va_list ap;
+
+ va_start(ap, flag);
+
+ num_args = va_arg(ap, u32);
+
+ if (num_args > 4)
+ return 1;
+
+ /* Copy args to aligned args structure */
+ for (i = 0; i < num_args; i++)
+ secure_rom_call_args[i + 1] = va_arg(ap, u32);
+
+ secure_rom_call_args[0] = num_args;
+
+ va_end(ap);
+
+ /* if data cache is enabled, flush the aligned args structure */
+ flush_dcache_range(
+ (unsigned int)&secure_rom_call_args[0],
+ (unsigned int)&secure_rom_call_args[0] +
+ roundup(sizeof(secure_rom_call_args), ARCH_DMA_MINALIGN));
+
+ return omap_smc_sec(service, proc_id, flag, secure_rom_call_args);
+}
+
+static u32 find_sig_start(char *image, size_t size)
+{
+ char *image_end = image + size;
+ char *sig_start_magic = "CERT_";
+ int magic_str_len = strlen(sig_start_magic);
+ char *ch;
+
+ while (--image_end > image) {
+ if (*image_end == '_') {
+ ch = image_end - magic_str_len + 1;
+ if (!strncmp(ch, sig_start_magic, magic_str_len))
+ return (u32)ch;
+ }
+ }
+ return 0;
+}
+
+int secure_boot_verify_image(void **image, size_t *size)
+{
+ int result = 1;
+ u32 cert_addr, sig_addr;
+ size_t cert_size;
+
+ /* Perform cache writeback on input buffer */
+ flush_dcache_range(
+ (u32)*image,
+ (u32)*image + roundup(*size, ARCH_DMA_MINALIGN));
+
+ cert_addr = (uint32_t)*image;
+ sig_addr = find_sig_start((char *)*image, *size);
+
+ if (sig_addr == 0) {
+ printf("No signature found in image!\n");
+ result = 1;
+ goto auth_exit;
+ }
+
+ *size = sig_addr - cert_addr; /* Subtract out the signature size */
+ cert_size = *size;
+
+ /* Check if image load address is 32-bit aligned */
+ if (!IS_ALIGNED(cert_addr, 4)) {
+ printf("Image is not 4-byte aligned!\n");
+ result = 1;
+ goto auth_exit;
+ }
+
+ /* Image size also should be multiple of 4 */
+ if (!IS_ALIGNED(cert_size, 4)) {
+ printf("Image size is not 4-byte aligned!\n");
+ result = 1;
+ goto auth_exit;
+ }
+
+ /* Call ROM HAL API to verify certificate signature */
+ debug("%s: load_addr = %x, size = %x, sig_addr = %x\n", __func__,
+ cert_addr, cert_size, sig_addr);
+
+ result = secure_rom_call(
+ API_HAL_KM_VERIFYCERTIFICATESIGNATURE_INDEX, 0, 0,
+ 4, cert_addr, cert_size, sig_addr, 0xFFFFFFFF);
+auth_exit:
+ if (result != 0) {
+ printf("Authentication failed!\n");
+ printf("Return Value = %08X\n", result);
+ hang();
+ }
+
+ /*
+ * Output notification of successful authentication as well the name of
+ * the signing certificate used to re-assure the user that the secure
+ * code is being processed as expected. However suppress any such log
+ * output in case of building for SPL and booting via YMODEM. This is
+ * done to avoid disturbing the YMODEM serial protocol transactions.
+ */
+ if (!(IS_ENABLED(CONFIG_SPL_BUILD) &&
+ IS_ENABLED(CONFIG_SPL_YMODEM_SUPPORT) &&
+ spl_boot_device() == BOOT_DEVICE_UART))
+ printf("Authentication passed: %s\n", (char *)sig_addr);
+
+ return result;
+}
diff --git a/arch/arm/cpu/armv7/omap5/config.mk b/arch/arm/cpu/armv7/omap5/config.mk
index a7e55a5..d245572 100644
--- a/arch/arm/cpu/armv7/omap5/config.mk
+++ b/arch/arm/cpu/armv7/omap5/config.mk
@@ -15,5 +15,8 @@ else
ALL-y += MLO
endif
else
+ifeq ($(CONFIG_TI_SECURE_DEVICE),y)
+ALL-y += u-boot_HS.img
+endif
ALL-y += u-boot.img
endif
diff --git a/arch/arm/cpu/armv7/psci-common.c b/arch/arm/cpu/armv7/psci-common.c
new file mode 100644
index 0000000..d14b693
--- /dev/null
+++ b/arch/arm/cpu/armv7/psci-common.c
@@ -0,0 +1,39 @@
+/*
+ * Common PSCI functions
+ *
+ * Copyright (C) 2016 Chen-Yu Tsai
+ * Author: Chen-Yu Tsai <wens@csie.org>
+ *
+ * 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.
+ *
+ * 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/>.
+ */
+
+#include <config.h>
+#include <asm/armv7.h>
+#include <asm/macro.h>
+#include <asm/psci.h>
+#include <asm/secure.h>
+#include <linux/linkage.h>
+
+static u32 psci_target_pc[CONFIG_ARMV7_PSCI_NR_CPUS] __secure_data = { 0 };
+
+void __secure psci_save_target_pc(int cpu, u32 pc)
+{
+ psci_target_pc[cpu] = pc;
+ DSB;
+}
+
+u32 __secure psci_get_target_pc(int cpu)
+{
+ return psci_target_pc[cpu];
+}
+
diff --git a/arch/arm/cpu/armv7/psci.S b/arch/arm/cpu/armv7/psci.S
index ab40837..350b75c 100644
--- a/arch/arm/cpu/armv7/psci.S
+++ b/arch/arm/cpu/armv7/psci.S
@@ -196,29 +196,56 @@ ENTRY(psci_cpu_off_common)
bx lr
ENDPROC(psci_cpu_off_common)
-@ expects CPU ID in r0 and returns stack top in r0
-ENTRY(psci_get_cpu_stack_top)
- mov r3, #0x400 @ 1kB of stack per CPU
- mul r0, r0, r3
-
- ldr r3, =psci_text_end @ end of monitor text
- add r3, r3, #0x2000 @ Skip two pages
- lsr r3, r3, #12 @ Align to start of page
- lsl r3, r3, #12
- sub r3, r3, #4 @ reserve 1 word for target PC
- sub r0, r3, r0 @ here's our stack!
-
+@ The stacks are allocated in reverse order, i.e.
+@ the stack for CPU0 has the highest memory address.
+@
+@ -------------------- __secure_stack_end
+@ | CPU0 target PC |
+@ |------------------|
+@ | |
+@ | CPU0 stack |
+@ | |
+@ |------------------| __secure_stack_end - 1KB
+@ | . |
+@ | . |
+@ | . |
+@ | . |
+@ -------------------- __secure_stack_start
+@
+@ This expects CPU ID in r0 and returns stack top in r0
+LENTRY(psci_get_cpu_stack_top)
+ @ stack top = __secure_stack_end - (cpuid << ARM_PSCI_STACK_SHIFT)
+ ldr r3, =__secure_stack_end
+ sub r0, r3, r0, LSL #ARM_PSCI_STACK_SHIFT
+ sub r0, r0, #4 @ Save space for target PC
bx lr
ENDPROC(psci_get_cpu_stack_top)
+@ {r0, r1, r2, ip} from _do_nonsec_entry(kernel_entry, 0, machid, r2) in
+@ arch/arm/lib/bootm.c:boot_jump_linux() must remain unchanged across
+@ this function.
+ENTRY(psci_stack_setup)
+ mov r6, lr
+ mov r7, r0
+ bl psci_get_cpu_id @ CPU ID => r0
+ bl psci_get_cpu_stack_top @ stack top => r0
+ mov sp, r0
+ mov r0, r7
+ bx r6
+ENDPROC(psci_stack_setup)
+
+ENTRY(psci_arch_init)
+ mov pc, lr
+ENDPROC(psci_arch_init)
+.weak psci_arch_init
+
ENTRY(psci_cpu_entry)
bl psci_enable_smp
bl _nonsec_init
bl psci_get_cpu_id @ CPU ID => r0
- bl psci_get_cpu_stack_top @ stack top => r0
- ldr r0, [r0] @ target PC at stack top
+ bl psci_get_target_pc @ target PC => r0
b _do_nonsec_entry
ENDPROC(psci_cpu_entry)
diff --git a/arch/arm/cpu/armv7/sunxi/Makefile b/arch/arm/cpu/armv7/sunxi/Makefile
index c208510..b35b9df 100644
--- a/arch/arm/cpu/armv7/sunxi/Makefile
+++ b/arch/arm/cpu/armv7/sunxi/Makefile
@@ -14,7 +14,6 @@ obj-$(CONFIG_MACH_SUN8I_H3) += tzpc.o
ifndef CONFIG_SPL_BUILD
obj-$(CONFIG_ARMV7_PSCI) += psci.o
-obj-$(CONFIG_ARMV7_PSCI) += psci_head.o
endif
ifdef CONFIG_SPL_BUILD
diff --git a/arch/arm/cpu/armv7/sunxi/psci.c b/arch/arm/cpu/armv7/sunxi/psci.c
index a118e9d..7ac8406 100644
--- a/arch/arm/cpu/armv7/sunxi/psci.c
+++ b/arch/arm/cpu/armv7/sunxi/psci.c
@@ -17,11 +17,11 @@
#include <asm/gic.h>
#include <asm/io.h>
#include <asm/psci.h>
+#include <asm/secure.h>
#include <asm/system.h>
#include <linux/bitops.h>
-#define __secure __attribute__ ((section ("._secure.text")))
#define __irq __attribute__ ((interrupt ("IRQ")))
#define GICD_BASE (SUNXI_GIC400_BASE + GIC_DIST_OFFSET)
@@ -209,9 +209,8 @@ int __secure psci_cpu_on(u32 __always_unused unused, u32 mpidr, u32 pc)
(struct sunxi_cpucfg_reg *)SUNXI_CPUCFG_BASE;
u32 cpu = (mpidr & 0x3);
- /* store target PC at target CPU stack top */
- writel(pc, psci_get_cpu_stack_top(cpu));
- DSB;
+ /* store target PC */
+ psci_save_target_pc(cpu, pc);
/* Set secondary core power on PC */
writel((u32)&psci_cpu_entry, &cpucfg->priv0);
@@ -250,7 +249,7 @@ void __secure psci_cpu_off(void)
wfi();
}
-void __secure sunxi_gic_init(void)
+void __secure psci_arch_init(void)
{
u32 reg;
diff --git a/arch/arm/cpu/armv7/sunxi/psci_head.S b/arch/arm/cpu/armv7/sunxi/psci_head.S
deleted file mode 100644
index 8fa823d..0000000
--- a/arch/arm/cpu/armv7/sunxi/psci_head.S
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2013 - ARM Ltd
- * Author: Marc Zyngier <marc.zyngier@arm.com>
- *
- * Based on code by Carl van Schaik <carl@ok-labs.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.
- *
- * 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/>.
- */
-
-#include <config.h>
-#include <linux/linkage.h>
-
-#include <asm/arch-armv7/generictimer.h>
-#include <asm/gic.h>
-#include <asm/macro.h>
-#include <asm/psci.h>
-#include <asm/arch/cpu.h>
-
-/*
- * Memory layout:
- *
- * SECURE_RAM to text_end :
- * ._secure_text section
- * text_end to ALIGN_PAGE(text_end):
- * nothing
- * ALIGN_PAGE(text_end) to ALIGN_PAGE(text_end) + 0x1000)
- * 1kB of stack per CPU (4 CPUs max).
- */
-
- .pushsection ._secure.text, "ax"
-
- .arch_extension sec
-
-#define GICD_BASE (SUNXI_GIC400_BASE + 0x1000)
-#define GICC_BASE (SUNXI_GIC400_BASE + 0x2000)
-
-@ {r0, r1, r2, ip} from _do_nonsec_entry(kernel_entry, 0, machid, r2) in
-@ arch/arm/lib/bootm.c:boot_jump_linux() must remain unchanged across
-@ this function.
-ENTRY(psci_arch_init)
- mov r6, lr
- mov r7, r0
- bl psci_get_cpu_id @ CPU ID => r0
- bl psci_get_cpu_stack_top @ stack top => r0
- sub r0, r0, #4 @ Save space for target PC
- mov sp, r0
- mov r0, r7
- mov lr, r6
-
- push {r0, r1, r2, ip, lr}
- bl sunxi_gic_init
- pop {r0, r1, r2, ip, pc}
-ENDPROC(psci_arch_init)
-
-ENTRY(psci_text_end)
- .popsection
diff --git a/arch/arm/cpu/armv7/virt-dt.c b/arch/arm/cpu/armv7/virt-dt.c
index 32c368f..707dad4 100644
--- a/arch/arm/cpu/armv7/virt-dt.c
+++ b/arch/arm/cpu/armv7/virt-dt.c
@@ -26,69 +26,6 @@
#include <asm/armv7.h>
#include <asm/psci.h>
-static int fdt_psci(void *fdt)
-{
-#ifdef CONFIG_ARMV7_PSCI
- int nodeoff;
- int tmp;
-
- nodeoff = fdt_path_offset(fdt, "/cpus");
- if (nodeoff < 0) {
- printf("couldn't find /cpus\n");
- return nodeoff;
- }
-
- /* add 'enable-method = "psci"' to each cpu node */
- for (tmp = fdt_first_subnode(fdt, nodeoff);
- tmp >= 0;
- tmp = fdt_next_subnode(fdt, tmp)) {
- const struct fdt_property *prop;
- int len;
-
- prop = fdt_get_property(fdt, tmp, "device_type", &len);
- if (!prop)
- continue;
- if (len < 4)
- continue;
- if (strcmp(prop->data, "cpu"))
- continue;
-
- fdt_setprop_string(fdt, tmp, "enable-method", "psci");
- }
-
- nodeoff = fdt_path_offset(fdt, "/psci");
- if (nodeoff < 0) {
- nodeoff = fdt_path_offset(fdt, "/");
- if (nodeoff < 0)
- return nodeoff;
-
- nodeoff = fdt_add_subnode(fdt, nodeoff, "psci");
- if (nodeoff < 0)
- return nodeoff;
- }
-
- tmp = fdt_setprop_string(fdt, nodeoff, "compatible", "arm,psci");
- if (tmp)
- return tmp;
- tmp = fdt_setprop_string(fdt, nodeoff, "method", "smc");
- if (tmp)
- return tmp;
- tmp = fdt_setprop_u32(fdt, nodeoff, "cpu_suspend", ARM_PSCI_FN_CPU_SUSPEND);
- if (tmp)
- return tmp;
- tmp = fdt_setprop_u32(fdt, nodeoff, "cpu_off", ARM_PSCI_FN_CPU_OFF);
- if (tmp)
- return tmp;
- tmp = fdt_setprop_u32(fdt, nodeoff, "cpu_on", ARM_PSCI_FN_CPU_ON);
- if (tmp)
- return tmp;
- tmp = fdt_setprop_u32(fdt, nodeoff, "migrate", ARM_PSCI_FN_MIGRATE);
- if (tmp)
- return tmp;
-#endif
- return 0;
-}
-
int armv7_apply_memory_carveout(u64 *start, u64 *size)
{
#ifdef CONFIG_ARMV7_SECURE_RESERVE_SIZE
diff --git a/arch/arm/cpu/armv7m/config.mk b/arch/arm/cpu/armv7m/config.mk
index 4a53006..db4660e 100644
--- a/arch/arm/cpu/armv7m/config.mk
+++ b/arch/arm/cpu/armv7m/config.mk
@@ -5,4 +5,4 @@
# SPDX-License-Identifier: GPL-2.0+
#
-PLATFORM_CPPFLAGS += -march=armv7-m -mthumb
+PLATFORM_CPPFLAGS += -march=armv7-m -mthumb -mno-unaligned-access
diff --git a/arch/arm/cpu/armv8/Kconfig b/arch/arm/cpu/armv8/Kconfig
index 3d19bbf..acf2460 100644
--- a/arch/arm/cpu/armv8/Kconfig
+++ b/arch/arm/cpu/armv8/Kconfig
@@ -3,4 +3,22 @@ if ARM64
config ARMV8_MULTIENTRY
boolean "Enable multiple CPUs to enter into U-Boot"
+config ARMV8_SPIN_TABLE
+ bool "Support spin-table enable method"
+ depends on ARMV8_MULTIENTRY && OF_LIBFDT
+ help
+ Say Y here to support "spin-table" enable method for booting Linux.
+
+ To use this feature, you must do:
+ - Specify enable-method = "spin-table" in each CPU node in the
+ Device Tree you are using to boot the kernel
+ - Let secondary CPUs in U-Boot (in a board specific manner)
+ before the master CPU jumps to the kernel
+
+ U-Boot automatically does:
+ - Set "cpu-release-addr" property of each CPU node
+ (overwrites it if already exists).
+ - Reserve the code for the spin-table and the release address
+ via a /memreserve/ region in the Device Tree.
+
endif
diff --git a/arch/arm/cpu/armv8/Makefile b/arch/arm/cpu/armv8/Makefile
index bf8644c..dea1465 100644
--- a/arch/arm/cpu/armv8/Makefile
+++ b/arch/arm/cpu/armv8/Makefile
@@ -15,6 +15,11 @@ obj-y += cache.o
obj-y += tlb.o
obj-y += transition.o
obj-y += fwcall.o
+obj-y += cpu-dt.o
+ifndef CONFIG_SPL_BUILD
+obj-$(CONFIG_ARMV8_SPIN_TABLE) += spin_table.o spin_table_v8.o
+endif
+obj-$(CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT) += sec_firmware.o sec_firmware_asm.o
obj-$(CONFIG_FSL_LAYERSCAPE) += fsl-layerscape/
obj-$(CONFIG_S32V234) += s32v234/
diff --git a/arch/arm/cpu/armv8/cache_v8.c b/arch/arm/cpu/armv8/cache_v8.c
index 1615542..ac909a1 100644
--- a/arch/arm/cpu/armv8/cache_v8.c
+++ b/arch/arm/cpu/armv8/cache_v8.c
@@ -35,7 +35,7 @@ DECLARE_GLOBAL_DATA_PTR;
* off: FFF
*/
-static u64 get_tcr(int el, u64 *pips, u64 *pva_bits)
+u64 get_tcr(int el, u64 *pips, u64 *pva_bits)
{
u64 max_addr = 0;
u64 ips, va_bits;
@@ -44,7 +44,7 @@ static u64 get_tcr(int el, u64 *pips, u64 *pva_bits)
/* Find the largest address we need to support */
for (i = 0; mem_map[i].size || mem_map[i].attrs; i++)
- max_addr = max(max_addr, mem_map[i].base + mem_map[i].size);
+ max_addr = max(max_addr, mem_map[i].virt + mem_map[i].size);
/* Calculate the maximum physical (and thus virtual) address */
if (max_addr > (1ULL << 44)) {
@@ -167,49 +167,6 @@ static void set_pte_table(u64 *pte, u64 *table)
*pte = PTE_TYPE_TABLE | (ulong)table;
}
-/* Add one mm_region map entry to the page tables */
-static void add_map(struct mm_region *map)
-{
- u64 *pte;
- u64 addr = map->base;
- u64 size = map->size;
- u64 attrs = map->attrs | PTE_TYPE_BLOCK | PTE_BLOCK_AF;
- u64 blocksize;
- int level;
- u64 *new_table;
-
- while (size) {
- pte = find_pte(addr, 0);
- if (pte && (pte_type(pte) == PTE_TYPE_FAULT)) {
- debug("Creating table for addr 0x%llx\n", addr);
- new_table = create_table();
- set_pte_table(pte, new_table);
- }
-
- for (level = 1; level < 4; level++) {
- pte = find_pte(addr, level);
- blocksize = 1ULL << level2shift(level);
- debug("Checking if pte fits for addr=%llx size=%llx "
- "blocksize=%llx\n", addr, size, blocksize);
- if (size >= blocksize && !(addr & (blocksize - 1))) {
- /* Page fits, create block PTE */
- debug("Setting PTE %p to block addr=%llx\n",
- pte, addr);
- *pte = addr | attrs;
- addr += blocksize;
- size -= blocksize;
- break;
- } else if ((pte_type(pte) == PTE_TYPE_FAULT)) {
- /* Page doesn't fit, create subpages */
- debug("Creating subtable for addr 0x%llx "
- "blksize=%llx\n", addr, blocksize);
- new_table = create_table();
- set_pte_table(pte, new_table);
- }
- }
- }
-}
-
/* Splits a block PTE into table with subpages spanning the old block */
static void split_block(u64 *pte, int level)
{
@@ -241,6 +198,58 @@ static void split_block(u64 *pte, int level)
set_pte_table(pte, new_table);
}
+/* Add one mm_region map entry to the page tables */
+static void add_map(struct mm_region *map)
+{
+ u64 *pte;
+ u64 virt = map->virt;
+ u64 phys = map->phys;
+ u64 size = map->size;
+ u64 attrs = map->attrs | PTE_TYPE_BLOCK | PTE_BLOCK_AF;
+ u64 blocksize;
+ int level;
+ u64 *new_table;
+
+ while (size) {
+ pte = find_pte(virt, 0);
+ if (pte && (pte_type(pte) == PTE_TYPE_FAULT)) {
+ debug("Creating table for virt 0x%llx\n", virt);
+ new_table = create_table();
+ set_pte_table(pte, new_table);
+ }
+
+ for (level = 1; level < 4; level++) {
+ pte = find_pte(virt, level);
+ if (!pte)
+ panic("pte not found\n");
+
+ blocksize = 1ULL << level2shift(level);
+ debug("Checking if pte fits for virt=%llx size=%llx blocksize=%llx\n",
+ virt, size, blocksize);
+ if (size >= blocksize && !(virt & (blocksize - 1))) {
+ /* Page fits, create block PTE */
+ debug("Setting PTE %p to block virt=%llx\n",
+ pte, virt);
+ *pte = phys | attrs;
+ virt += blocksize;
+ phys += blocksize;
+ size -= blocksize;
+ break;
+ } else if (pte_type(pte) == PTE_TYPE_FAULT) {
+ /* Page doesn't fit, create subpages */
+ debug("Creating subtable for virt 0x%llx blksize=%llx\n",
+ virt, blocksize);
+ new_table = create_table();
+ set_pte_table(pte, new_table);
+ } else if (pte_type(pte) == PTE_TYPE_BLOCK) {
+ debug("Split block into subtable for virt 0x%llx blksize=0x%llx\n",
+ virt, blocksize);
+ split_block(pte, level);
+ }
+ }
+ }
+}
+
enum pte_type {
PTE_INVAL,
PTE_BLOCK,
@@ -265,7 +274,7 @@ static int count_required_pts(u64 addr, int level, u64 maxaddr)
for (i = 0; mem_map[i].size || mem_map[i].attrs; i++) {
struct mm_region *map = &mem_map[i];
- u64 start = map->base;
+ u64 start = map->virt;
u64 end = start + map->size;
/* Check if the PTE would overlap with the map */
@@ -349,10 +358,13 @@ __weak u64 get_page_table_size(void)
return size;
}
-static void setup_pgtables(void)
+void setup_pgtables(void)
{
int i;
+ if (!gd->arch.tlb_fillptr || !gd->arch.tlb_addr)
+ panic("Page table pointer not setup.");
+
/*
* Allocate the first level we're on with invalidate entries.
* If the starting level is 0 (va_bits >= 39), then this is our
@@ -363,9 +375,6 @@ static void setup_pgtables(void)
/* Now add all MMU table entries one after another to the table */
for (i = 0; mem_map[i].size || mem_map[i].attrs; i++)
add_map(&mem_map[i]);
-
- /* Create the same thing once more for our emergency page table */
- create_table();
}
static void setup_all_pgtables(void)
@@ -527,6 +536,9 @@ void mmu_set_region_dcache_behaviour(phys_addr_t start, size_t size,
debug("start=%lx size=%lx\n", (ulong)start, (ulong)size);
+ if (!gd->arch.tlb_emerg)
+ panic("Emergency page table not setup.");
+
/*
* We can not modify page tables that we're currently running on,
* so we first need to switch to the "emergency" page tables where
diff --git a/arch/arm/cpu/armv8/cpu-dt.c b/arch/arm/cpu/armv8/cpu-dt.c
new file mode 100644
index 0000000..9ffb49c
--- /dev/null
+++ b/arch/arm/cpu/armv8/cpu-dt.c
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2016 NXP Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/psci.h>
+#ifdef CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT
+#include <asm/armv8/sec_firmware.h>
+#endif
+
+int psci_update_dt(void *fdt)
+{
+#ifdef CONFIG_MP
+#if defined(CONFIG_ARMV8_PSCI)
+#ifdef CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT
+ /*
+ * If the PSCI in SEC Firmware didn't work, avoid to update the
+ * device node of PSCI. But still return 0 instead of an error
+ * number to support detecting PSCI dynamically and then switching
+ * the SMP boot method between PSCI and spin-table.
+ */
+ if (sec_firmware_support_psci_version() == 0xffffffff)
+ return 0;
+#endif
+ fdt_psci(fdt);
+#endif
+#endif
+ return 0;
+}
diff --git a/arch/arm/cpu/armv8/fsl-layerscape/Makefile b/arch/arm/cpu/armv8/fsl-layerscape/Makefile
index eb2cbc3..bcf6b48 100644
--- a/arch/arm/cpu/armv8/fsl-layerscape/Makefile
+++ b/arch/arm/cpu/armv8/fsl-layerscape/Makefile
@@ -10,6 +10,7 @@ obj-y += soc.o
obj-$(CONFIG_MP) += mp.o
obj-$(CONFIG_OF_LIBFDT) += fdt.o
obj-$(CONFIG_SPL) += spl.o
+obj-$(CONFIG_FSL_LS_PPA) += ppa.o
ifneq ($(CONFIG_FSL_LSCH3),)
obj-y += fsl_lsch3_speed.o
diff --git a/arch/arm/cpu/armv8/fsl-layerscape/cpu.c b/arch/arm/cpu/armv8/fsl-layerscape/cpu.c
index 8062106..7a2ec6b 100644
--- a/arch/arm/cpu/armv8/fsl-layerscape/cpu.c
+++ b/arch/arm/cpu/armv8/fsl-layerscape/cpu.c
@@ -23,16 +23,13 @@
#ifdef CONFIG_FSL_ESDHC
#include <fsl_esdhc.h>
#endif
+#ifdef CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT
+#include <asm/armv8/sec_firmware.h>
+#endif
DECLARE_GLOBAL_DATA_PTR;
-static struct mm_region layerscape_mem_map[] = {
- {
- /* List terminator */
- 0,
- }
-};
-struct mm_region *mem_map = layerscape_mem_map;
+struct mm_region *mem_map = early_map;
void cpu_name(char *name)
{
@@ -56,348 +53,96 @@ void cpu_name(char *name)
}
#ifndef CONFIG_SYS_DCACHE_OFF
-static void set_pgtable_section(u64 *page_table, u64 index, u64 section,
- u64 memory_type, u64 attribute)
-{
- u64 value;
-
- value = section | PTE_TYPE_BLOCK | PTE_BLOCK_AF;
- value |= PMD_ATTRINDX(memory_type);
- value |= attribute;
- page_table[index] = value;
-}
-
-static void set_pgtable_table(u64 *page_table, u64 index, u64 *table_addr)
-{
- u64 value;
-
- value = (u64)table_addr | PTE_TYPE_TABLE;
- page_table[index] = value;
-}
-
-/*
- * Set the block entries according to the information of the table.
- */
-static int set_block_entry(const struct sys_mmu_table *list,
- struct table_info *table)
-{
- u64 block_size = 0, block_shift = 0;
- u64 block_addr, index;
- int j;
-
- if (table->entry_size == BLOCK_SIZE_L1) {
- block_size = BLOCK_SIZE_L1;
- block_shift = SECTION_SHIFT_L1;
- } else if (table->entry_size == BLOCK_SIZE_L2) {
- block_size = BLOCK_SIZE_L2;
- block_shift = SECTION_SHIFT_L2;
- } else {
- return -EINVAL;
- }
-
- block_addr = list->phys_addr;
- index = (list->virt_addr - table->table_base) >> block_shift;
-
- for (j = 0; j < (list->size >> block_shift); j++) {
- set_pgtable_section(table->ptr,
- index,
- block_addr,
- list->memory_type,
- list->attribute);
- block_addr += block_size;
- index++;
- }
-
- return 0;
-}
-
-/*
- * Find the corresponding table entry for the list.
- */
-static int find_table(const struct sys_mmu_table *list,
- struct table_info *table, u64 *level0_table)
-{
- u64 index = 0, level = 0;
- u64 *level_table = level0_table;
- u64 temp_base = 0, block_size = 0, block_shift = 0;
-
- while (level < 3) {
- if (level == 0) {
- block_size = BLOCK_SIZE_L0;
- block_shift = SECTION_SHIFT_L0;
- } else if (level == 1) {
- block_size = BLOCK_SIZE_L1;
- block_shift = SECTION_SHIFT_L1;
- } else if (level == 2) {
- block_size = BLOCK_SIZE_L2;
- block_shift = SECTION_SHIFT_L2;
- }
-
- index = 0;
- while (list->virt_addr >= temp_base) {
- index++;
- temp_base += block_size;
- }
-
- temp_base -= block_size;
-
- if ((level_table[index - 1] & PTE_TYPE_MASK) ==
- PTE_TYPE_TABLE) {
- level_table = (u64 *)(level_table[index - 1] &
- ~PTE_TYPE_MASK);
- level++;
- continue;
- } else {
- if (level == 0)
- return -EINVAL;
-
- if ((list->phys_addr + list->size) >
- (temp_base + block_size * NUM_OF_ENTRY))
- return -EINVAL;
-
- /*
- * Check the address and size of the list member is
- * aligned with the block size.
- */
- if (((list->phys_addr & (block_size - 1)) != 0) ||
- ((list->size & (block_size - 1)) != 0))
- return -EINVAL;
-
- table->ptr = level_table;
- table->table_base = temp_base -
- ((index - 1) << block_shift);
- table->entry_size = block_size;
-
- return 0;
- }
- }
- return -EINVAL;
-}
-
/*
* To start MMU before DDR is available, we create MMU table in SRAM.
* The base address of SRAM is CONFIG_SYS_FSL_OCRAM_BASE. We use three
* levels of translation tables here to cover 40-bit address space.
* We use 4KB granule size, with 40 bits physical address, T0SZ=24
- * Level 0 IA[39], table address @0
- * Level 1 IA[38:30], table address @0x1000, 0x2000
- * Level 2 IA[29:21], table address @0x3000, 0x4000
- * Address above 0x5000 is free for other purpose.
+ * Address above EARLY_PGTABLE_SIZE (0x5000) is free for other purpose.
+ * Note, the debug print in cache_v8.c is not usable for debugging
+ * these early MMU tables because UART is not yet available.
*/
static inline void early_mmu_setup(void)
{
- unsigned int el, i;
- u64 *level0_table = (u64 *)CONFIG_SYS_FSL_OCRAM_BASE;
- u64 *level1_table0 = (u64 *)(CONFIG_SYS_FSL_OCRAM_BASE + 0x1000);
- u64 *level1_table1 = (u64 *)(CONFIG_SYS_FSL_OCRAM_BASE + 0x2000);
- u64 *level2_table0 = (u64 *)(CONFIG_SYS_FSL_OCRAM_BASE + 0x3000);
- u64 *level2_table1 = (u64 *)(CONFIG_SYS_FSL_OCRAM_BASE + 0x4000);
-
- struct table_info table = {level0_table, 0, BLOCK_SIZE_L0};
-
- /* Invalidate all table entries */
- memset(level0_table, 0, 0x5000);
-
- /* Fill in the table entries */
- set_pgtable_table(level0_table, 0, level1_table0);
- set_pgtable_table(level0_table, 1, level1_table1);
- set_pgtable_table(level1_table0, 0, level2_table0);
+ unsigned int el = current_el();
-#ifdef CONFIG_FSL_LSCH3
- set_pgtable_table(level1_table0,
- CONFIG_SYS_FLASH_BASE >> SECTION_SHIFT_L1,
- level2_table1);
-#elif defined(CONFIG_FSL_LSCH2)
- set_pgtable_table(level1_table0, 1, level2_table1);
-#endif
- /* Find the table and fill in the block entries */
- for (i = 0; i < ARRAY_SIZE(early_mmu_table); i++) {
- if (find_table(&early_mmu_table[i],
- &table, level0_table) == 0) {
- /*
- * If find_table() returns error, it cannot be dealt
- * with here. Breakpoint can be added for debugging.
- */
- set_block_entry(&early_mmu_table[i], &table);
- /*
- * If set_block_entry() returns error, it cannot be
- * dealt with here too.
- */
- }
- }
+ /* global data is already setup, no allocation yet */
+ gd->arch.tlb_addr = CONFIG_SYS_FSL_OCRAM_BASE;
+ gd->arch.tlb_fillptr = gd->arch.tlb_addr;
+ gd->arch.tlb_size = EARLY_PGTABLE_SIZE;
- el = current_el();
+ /* Create early page tables */
+ setup_pgtables();
- set_ttbr_tcr_mair(el, (u64)level0_table, LAYERSCAPE_TCR,
+ /* point TTBR to the new table */
+ set_ttbr_tcr_mair(el, gd->arch.tlb_addr,
+ get_tcr(el, NULL, NULL) &
+ ~(TCR_ORGN_MASK | TCR_IRGN_MASK),
MEMORY_ATTRIBUTES);
- set_sctlr(get_sctlr() | CR_M);
-}
-#ifdef CONFIG_SYS_MEM_RESERVE_SECURE
-/*
- * Called from final mmu setup. The phys_addr is new, non-existing
- * address. A new sub table is created @level2_table_secure to cover
- * size of CONFIG_SYS_MEM_RESERVE_SECURE memory.
- */
-static inline int final_secure_ddr(u64 *level0_table,
- u64 *level2_table_secure,
- phys_addr_t phys_addr)
-{
- int ret = -EINVAL;
- struct table_info table = {};
- struct sys_mmu_table ddr_entry = {
- 0, 0, BLOCK_SIZE_L1, MT_NORMAL,
- PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS
- };
- u64 index;
-
- /* Need to create a new table */
- ddr_entry.virt_addr = phys_addr & ~(BLOCK_SIZE_L1 - 1);
- ddr_entry.phys_addr = phys_addr & ~(BLOCK_SIZE_L1 - 1);
- ret = find_table(&ddr_entry, &table, level0_table);
- if (ret)
- return ret;
- index = (ddr_entry.virt_addr - table.table_base) >> SECTION_SHIFT_L1;
- set_pgtable_table(table.ptr, index, level2_table_secure);
- table.ptr = level2_table_secure;
- table.table_base = ddr_entry.virt_addr;
- table.entry_size = BLOCK_SIZE_L2;
- ret = set_block_entry(&ddr_entry, &table);
- if (ret) {
- printf("MMU error: could not fill non-secure ddr block entries\n");
- return ret;
- }
- ddr_entry.virt_addr = phys_addr;
- ddr_entry.phys_addr = phys_addr;
- ddr_entry.size = CONFIG_SYS_MEM_RESERVE_SECURE;
- ddr_entry.attribute = PTE_BLOCK_OUTER_SHARE;
- ret = find_table(&ddr_entry, &table, level0_table);
- if (ret) {
- printf("MMU error: could not find secure ddr table\n");
- return ret;
- }
- ret = set_block_entry(&ddr_entry, &table);
- if (ret)
- printf("MMU error: could not set secure ddr block entry\n");
-
- return ret;
+ set_sctlr(get_sctlr() | CR_M);
}
-#endif
/*
* The final tables look similar to early tables, but different in detail.
* These tables are in DRAM. Sub tables are added to enable cache for
* QBMan and OCRAM.
*
- * Put the MMU table in secure memory if gd->secure_ram is valid.
- * OCRAM will be not used for this purpose so gd->secure_ram can't be 0.
- *
- * Level 1 table 0 contains 512 entries for each 1GB from 0 to 512GB.
- * Level 1 table 1 contains 512 entries for each 1GB from 512GB to 1TB.
- * Level 2 table 0 contains 512 entries for each 2MB from 0 to 1GB.
- *
- * For LSCH3:
- * Level 2 table 1 contains 512 entries for each 2MB from 32GB to 33GB.
- * For LSCH2:
- * Level 2 table 1 contains 512 entries for each 2MB from 1GB to 2GB.
- * Level 2 table 2 contains 512 entries for each 2MB from 20GB to 21GB.
+ * Put the MMU table in secure memory if gd->arch.secure_ram is valid.
+ * OCRAM will be not used for this purpose so gd->arch.secure_ram can't be 0.
*/
static inline void final_mmu_setup(void)
{
+ u64 tlb_addr_save = gd->arch.tlb_addr;
unsigned int el = current_el();
- unsigned int i;
- u64 *level0_table = (u64 *)gd->arch.tlb_addr;
- u64 *level1_table0;
- u64 *level1_table1;
- u64 *level2_table0;
- u64 *level2_table1;
-#ifdef CONFIG_FSL_LSCH2
- u64 *level2_table2;
-#endif
- struct table_info table = {NULL, 0, BLOCK_SIZE_L0};
-
#ifdef CONFIG_SYS_MEM_RESERVE_SECURE
- u64 *level2_table_secure;
-
- if (el == 3) {
- /*
- * Only use gd->secure_ram if the address is recalculated
- * Align to 4KB for MMU table
- */
- if (gd->secure_ram & MEM_RESERVE_SECURE_MAINTAINED)
- level0_table = (u64 *)(gd->secure_ram & ~0xfff);
- else
- printf("MMU warning: gd->secure_ram is not maintained, disabled.\n");
- }
-#endif
- level1_table0 = level0_table + 512;
- level1_table1 = level1_table0 + 512;
- level2_table0 = level1_table1 + 512;
- level2_table1 = level2_table0 + 512;
-#ifdef CONFIG_FSL_LSCH2
- level2_table2 = level2_table1 + 512;
+ int index;
#endif
- table.ptr = level0_table;
- /* Invalidate all table entries */
- memset(level0_table, 0, PGTABLE_SIZE);
+ mem_map = final_map;
- /* Fill in the table entries */
- set_pgtable_table(level0_table, 0, level1_table0);
- set_pgtable_table(level0_table, 1, level1_table1);
- set_pgtable_table(level1_table0, 0, level2_table0);
-#ifdef CONFIG_FSL_LSCH3
- set_pgtable_table(level1_table0,
- CONFIG_SYS_FSL_QBMAN_BASE >> SECTION_SHIFT_L1,
- level2_table1);
-#elif defined(CONFIG_FSL_LSCH2)
- set_pgtable_table(level1_table0, 1, level2_table1);
- set_pgtable_table(level1_table0,
- CONFIG_SYS_FSL_QBMAN_BASE >> SECTION_SHIFT_L1,
- level2_table2);
-#endif
-
- /* Find the table and fill in the block entries */
- for (i = 0; i < ARRAY_SIZE(final_mmu_table); i++) {
- if (find_table(&final_mmu_table[i],
- &table, level0_table) == 0) {
- if (set_block_entry(&final_mmu_table[i],
- &table) != 0) {
- printf("MMU error: could not set block entry for %p\n",
- &final_mmu_table[i]);
- }
-
- } else {
- printf("MMU error: could not find the table for %p\n",
- &final_mmu_table[i]);
- }
- }
- /* Set the secure memory to secure in MMU */
#ifdef CONFIG_SYS_MEM_RESERVE_SECURE
- if (el == 3 && gd->secure_ram & MEM_RESERVE_SECURE_MAINTAINED) {
-#ifdef CONFIG_FSL_LSCH3
- level2_table_secure = level2_table1 + 512;
-#elif defined(CONFIG_FSL_LSCH2)
- level2_table_secure = level2_table2 + 512;
-#endif
- if (!final_secure_ddr(level0_table,
- level2_table_secure,
- gd->secure_ram & ~0x3)) {
- gd->secure_ram |= MEM_RESERVE_SECURE_SECURED;
- debug("Now MMU table is in secured memory at 0x%llx\n",
- gd->secure_ram & ~0x3);
+ if (gd->arch.secure_ram & MEM_RESERVE_SECURE_MAINTAINED) {
+ if (el == 3) {
+ /*
+ * Only use gd->arch.secure_ram if the address is
+ * recalculated. Align to 4KB for MMU table.
+ */
+ /* put page tables in secure ram */
+ index = ARRAY_SIZE(final_map) - 2;
+ gd->arch.tlb_addr = gd->arch.secure_ram & ~0xfff;
+ final_map[index].virt = gd->arch.secure_ram & ~0x3;
+ final_map[index].phys = final_map[index].virt;
+ final_map[index].size = CONFIG_SYS_MEM_RESERVE_SECURE;
+ final_map[index].attrs = PTE_BLOCK_OUTER_SHARE;
+ gd->arch.secure_ram |= MEM_RESERVE_SECURE_SECURED;
+ tlb_addr_save = gd->arch.tlb_addr;
} else {
- printf("MMU warning: Failed to secure DDR\n");
+ /* Use allocated (board_f.c) memory for TLB */
+ tlb_addr_save = gd->arch.tlb_allocated;
+ gd->arch.tlb_addr = tlb_addr_save;
}
}
#endif
+ /* Reset the fill ptr */
+ gd->arch.tlb_fillptr = tlb_addr_save;
+
+ /* Create normal system page tables */
+ setup_pgtables();
+
+ /* Create emergency page tables */
+ gd->arch.tlb_addr = gd->arch.tlb_fillptr;
+ gd->arch.tlb_emerg = gd->arch.tlb_addr;
+ setup_pgtables();
+ gd->arch.tlb_addr = tlb_addr_save;
+
/* flush new MMU table */
- flush_dcache_range((ulong)level0_table,
- (ulong)level0_table + gd->arch.tlb_size);
+ flush_dcache_range(gd->arch.tlb_addr,
+ gd->arch.tlb_addr + gd->arch.tlb_size);
/* point TTBR to the new table */
- set_ttbr_tcr_mair(el, (u64)level0_table, LAYERSCAPE_TCR_FINAL,
+ set_ttbr_tcr_mair(el, gd->arch.tlb_addr, get_tcr(el, NULL, NULL),
MEMORY_ATTRIBUTES);
/*
* MMU is already enabled, just need to invalidate TLB to load the
@@ -422,15 +167,21 @@ int arch_cpu_init(void)
return 0;
}
+void mmu_setup(void)
+{
+ final_mmu_setup();
+}
+
/*
- * This function is called from lib/board.c.
- * It recreates MMU table in main memory. MMU and d-cache are enabled earlier.
- * There is no need to disable d-cache for this operation.
+ * This function is called from common/board_r.c.
+ * It recreates MMU table in main memory.
*/
void enable_caches(void)
{
- final_mmu_setup();
+ mmu_setup();
__asm_invalidate_tlb_all();
+ icache_enable();
+ dcache_enable();
}
#endif
@@ -616,6 +367,7 @@ int arch_early_init_r(void)
{
#ifdef CONFIG_MP
int rv = 1;
+ u32 psci_ver = 0xffffffff;
#endif
#ifdef CONFIG_SYS_FSL_ERRATUM_A009635
@@ -623,9 +375,15 @@ int arch_early_init_r(void)
#endif
#ifdef CONFIG_MP
- rv = fsl_layerscape_wake_seconday_cores();
- if (rv)
- printf("Did not wake secondary cores\n");
+#if defined(CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT) && defined(CONFIG_ARMV8_PSCI)
+ /* Check the psci version to determine if the psci is supported */
+ psci_ver = sec_firmware_support_psci_version();
+#endif
+ if (psci_ver == 0xffffffff) {
+ rv = fsl_layerscape_wake_seconday_cores();
+ if (rv)
+ printf("Did not wake secondary cores\n");
+ }
#endif
#ifdef CONFIG_SYS_HAS_SERDES
diff --git a/arch/arm/cpu/armv8/fsl-layerscape/doc/README.lsch3 b/arch/arm/cpu/armv8/fsl-layerscape/doc/README.lsch3
index da5e052..7867c37 100644
--- a/arch/arm/cpu/armv8/fsl-layerscape/doc/README.lsch3
+++ b/arch/arm/cpu/armv8/fsl-layerscape/doc/README.lsch3
@@ -128,7 +128,7 @@ mcinitcmd: This environment variable is defined to initiate MC and DPL deploymen
during U-boot booting.However the MC, DPC and DPL can be applied from
console independently.
The variable needs to be set from the console once and then on
- rebooting the parameters set in the varible will automatically be
+ rebooting the parameters set in the variable will automatically be
executed. The commmand is demostrated taking an example of mc boot
using NOR Flash i.e. MC, DPL, and DPC is stored in the NOR flash:
diff --git a/arch/arm/cpu/armv8/fsl-layerscape/fdt.c b/arch/arm/cpu/armv8/fsl-layerscape/fdt.c
index d17227a..40d6a76 100644
--- a/arch/arm/cpu/armv8/fsl-layerscape/fdt.c
+++ b/arch/arm/cpu/armv8/fsl-layerscape/fdt.c
@@ -22,6 +22,9 @@
#endif
#include <fsl_sec.h>
#include <asm/arch-fsl-layerscape/soc.h>
+#ifdef CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT
+#include <asm/armv8/sec_firmware.h>
+#endif
int fdt_fixup_phy_connection(void *blob, int offset, phy_interface_t phyc)
{
@@ -38,7 +41,37 @@ void ft_fixup_cpu(void *blob)
int addr_cells;
u64 val, core_id;
size_t *boot_code_size = &(__secondary_boot_code_size);
+#if defined(CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT) && defined(CONFIG_ARMV8_PSCI)
+ int node;
+ u32 psci_ver;
+
+ /* Check the psci version to determine if the psci is supported */
+ psci_ver = sec_firmware_support_psci_version();
+ if (psci_ver == 0xffffffff) {
+ /* remove psci DT node */
+ node = fdt_path_offset(blob, "/psci");
+ if (node >= 0)
+ goto remove_psci_node;
+
+ node = fdt_node_offset_by_compatible(blob, -1, "arm,psci");
+ if (node >= 0)
+ goto remove_psci_node;
+
+ node = fdt_node_offset_by_compatible(blob, -1, "arm,psci-0.2");
+ if (node >= 0)
+ goto remove_psci_node;
+ node = fdt_node_offset_by_compatible(blob, -1, "arm,psci-1.0");
+ if (node >= 0)
+ goto remove_psci_node;
+
+remove_psci_node:
+ if (node >= 0)
+ fdt_del_node(blob, node);
+ } else {
+ return;
+ }
+#endif
off = fdt_path_offset(blob, "/cpus");
if (off < 0) {
puts("couldn't find /cpus node\n");
diff --git a/arch/arm/cpu/armv8/fsl-layerscape/ppa.c b/arch/arm/cpu/armv8/fsl-layerscape/ppa.c
new file mode 100644
index 0000000..541b251
--- /dev/null
+++ b/arch/arm/cpu/armv8/fsl-layerscape/ppa.c
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2016 NXP Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+#include <common.h>
+#include <config.h>
+#include <errno.h>
+#include <asm/system.h>
+#include <asm/types.h>
+#include <asm/arch/soc.h>
+#ifdef CONFIG_FSL_LSCH3
+#include <asm/arch/immap_lsch3.h>
+#elif defined(CONFIG_FSL_LSCH2)
+#include <asm/arch/immap_lsch2.h>
+#endif
+#ifdef CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT
+#include <asm/armv8/sec_firmware.h>
+#endif
+
+int ppa_init(void)
+{
+ const void *ppa_fit_addr;
+ u32 *boot_loc_ptr_l, *boot_loc_ptr_h;
+ int ret;
+
+#ifdef CONFIG_SYS_LS_PPA_FW_IN_NOR
+ ppa_fit_addr = (void *)CONFIG_SYS_LS_PPA_FW_ADDR;
+#else
+#error "No CONFIG_SYS_LS_PPA_FW_IN_xxx defined"
+#endif
+
+#ifdef CONFIG_FSL_LSCH3
+ struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
+ boot_loc_ptr_l = &gur->bootlocptrl;
+ boot_loc_ptr_h = &gur->bootlocptrh;
+#elif defined(CONFIG_FSL_LSCH2)
+ struct ccsr_scfg __iomem *scfg = (void *)(CONFIG_SYS_FSL_SCFG_ADDR);
+ boot_loc_ptr_l = &scfg->scratchrw[1];
+ boot_loc_ptr_h = &scfg->scratchrw[0];
+#endif
+
+ debug("fsl-ppa: boot_loc_ptr_l = 0x%p, boot_loc_ptr_h =0x%p\n",
+ boot_loc_ptr_l, boot_loc_ptr_h);
+ ret = sec_firmware_init(ppa_fit_addr, boot_loc_ptr_l, boot_loc_ptr_h);
+
+ return ret;
+}
diff --git a/arch/arm/cpu/armv8/s32v234/cpu.c b/arch/arm/cpu/armv8/s32v234/cpu.c
index dac12a2..5c97e0e 100644
--- a/arch/arm/cpu/armv8/s32v234/cpu.c
+++ b/arch/arm/cpu/armv8/s32v234/cpu.c
@@ -32,24 +32,28 @@ u32 cpu_mask(void)
static struct mm_region s32v234_mem_map[] = {
{
- .base = S32V234_IRAM_BASE,
+ .virt = S32V234_IRAM_BASE,
+ .phys = S32V234_IRAM_BASE,
.size = S32V234_IRAM_SIZE,
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
PTE_BLOCK_OUTER_SHARE
}, {
- .base = S32V234_DRAM_BASE1,
+ .virt = S32V234_DRAM_BASE1,
+ .phys = S32V234_DRAM_BASE1,
.size = S32V234_DRAM_SIZE1,
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
PTE_BLOCK_OUTER_SHARE
}, {
- .base = S32V234_PERIPH_BASE,
+ .virt = S32V234_PERIPH_BASE,
+ .phys = S32V234_PERIPH_BASE,
.size = S32V234_PERIPH_SIZE,
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
PTE_BLOCK_NON_SHARE
/* TODO: Do we need these? */
/* | PTE_BLOCK_PXN | PTE_BLOCK_UXN */
}, {
- .base = S32V234_DRAM_BASE2,
+ .virt = S32V234_DRAM_BASE2,
+ .phys = S32V234_DRAM_BASE2,
.size = S32V234_DRAM_SIZE2,
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL_NC) |
PTE_BLOCK_OUTER_SHARE
diff --git a/arch/arm/cpu/armv8/sec_firmware.c b/arch/arm/cpu/armv8/sec_firmware.c
new file mode 100644
index 0000000..e21e199
--- /dev/null
+++ b/arch/arm/cpu/armv8/sec_firmware.c
@@ -0,0 +1,270 @@
+/*
+ * Copyright 2016 NXP Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <linux/kernel.h>
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/types.h>
+#include <asm/macro.h>
+#include <asm/armv8/sec_firmware.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+extern void c_runtime_cpu_setup(void);
+
+#define SEC_FIRMWARE_LOADED 0x1
+#define SEC_FIRMWARE_RUNNING 0x2
+#define SEC_FIRMWARE_ADDR_MASK (~0x3)
+ /*
+ * Secure firmware load addr
+ * Flags used: 0x1 secure firmware has been loaded to secure memory
+ * 0x2 secure firmware is running
+ */
+ phys_addr_t sec_firmware_addr;
+
+static int sec_firmware_get_data(const void *sec_firmware_img,
+ const void **data, size_t *size)
+{
+ int conf_node_off, fw_node_off;
+ char *conf_node_name = NULL;
+ char *desc;
+ int ret;
+
+ conf_node_name = SEC_FIRMEWARE_FIT_CNF_NAME;
+
+ conf_node_off = fit_conf_get_node(sec_firmware_img, conf_node_name);
+ if (conf_node_off < 0) {
+ printf("SEC Firmware: %s: no such config\n", conf_node_name);
+ return -ENOENT;
+ }
+
+ fw_node_off = fit_conf_get_prop_node(sec_firmware_img, conf_node_off,
+ SEC_FIRMWARE_FIT_IMAGE);
+ if (fw_node_off < 0) {
+ printf("SEC Firmware: No '%s' in config\n",
+ SEC_FIRMWARE_FIT_IMAGE);
+ return -ENOLINK;
+ }
+
+ /* Verify secure firmware image */
+ if (!(fit_image_verify(sec_firmware_img, fw_node_off))) {
+ printf("SEC Firmware: Bad firmware image (bad CRC)\n");
+ return -EINVAL;
+ }
+
+ if (fit_image_get_data(sec_firmware_img, fw_node_off, data, size)) {
+ printf("SEC Firmware: Can't get %s subimage data/size",
+ SEC_FIRMWARE_FIT_IMAGE);
+ return -ENOENT;
+ }
+
+ ret = fit_get_desc(sec_firmware_img, fw_node_off, &desc);
+ if (ret)
+ printf("SEC Firmware: Can't get description\n");
+ else
+ printf("%s\n", desc);
+
+ return ret;
+}
+
+/*
+ * SEC Firmware FIT image parser checks if the image is in FIT
+ * format, verifies integrity of the image and calculates raw
+ * image address and size values.
+ *
+ * Returns 0 on success and a negative errno on error task fail.
+ */
+static int sec_firmware_parse_image(const void *sec_firmware_img,
+ const void **raw_image_addr,
+ size_t *raw_image_size)
+{
+ int ret;
+
+ ret = sec_firmware_get_data(sec_firmware_img, raw_image_addr,
+ raw_image_size);
+ if (ret)
+ return ret;
+
+ debug("SEC Firmware: raw_image_addr = 0x%p, raw_image_size = 0x%lx\n",
+ *raw_image_addr, *raw_image_size);
+
+ return 0;
+}
+
+static int sec_firmware_copy_image(const char *title,
+ u64 image_addr, u32 image_size, u64 sec_firmware)
+{
+ debug("%s copied to address 0x%p\n", title, (void *)sec_firmware);
+ memcpy((void *)sec_firmware, (void *)image_addr, image_size);
+ flush_dcache_range(sec_firmware, sec_firmware + image_size);
+
+ return 0;
+}
+
+/*
+ * This function will parse the SEC Firmware image, and then load it
+ * to secure memory.
+ */
+static int sec_firmware_load_image(const void *sec_firmware_img)
+{
+ const void *raw_image_addr;
+ size_t raw_image_size = 0;
+ int ret;
+
+ /*
+ * The Excetpion Level must be EL3 to load and initialize
+ * the SEC Firmware.
+ */
+ if (current_el() != 3) {
+ ret = -EACCES;
+ goto out;
+ }
+
+#ifdef CONFIG_SYS_MEM_RESERVE_SECURE
+ /*
+ * The SEC Firmware must be stored in secure memory.
+ * Append SEC Firmware to secure mmu table.
+ */
+ if (!(gd->arch.secure_ram & MEM_RESERVE_SECURE_MAINTAINED)) {
+ ret = -ENXIO;
+ goto out;
+ }
+
+ sec_firmware_addr = (gd->arch.secure_ram & MEM_RESERVE_SECURE_ADDR_MASK) +
+ gd->arch.tlb_size;
+#else
+#error "The CONFIG_SYS_MEM_RESERVE_SECURE must be defined when enabled SEC Firmware support"
+#endif
+
+ /* Align SEC Firmware base address to 4K */
+ sec_firmware_addr = (sec_firmware_addr + 0xfff) & ~0xfff;
+ debug("SEC Firmware: Load address: 0x%llx\n",
+ sec_firmware_addr & SEC_FIRMWARE_ADDR_MASK);
+
+ ret = sec_firmware_parse_image(sec_firmware_img, &raw_image_addr,
+ &raw_image_size);
+ if (ret)
+ goto out;
+
+ /* TODO:
+ * Check if the end addr of SEC Firmware has been extend the secure
+ * memory.
+ */
+
+ /* Copy the secure firmware to secure memory */
+ ret = sec_firmware_copy_image("SEC Firmware", (u64)raw_image_addr,
+ raw_image_size, sec_firmware_addr &
+ SEC_FIRMWARE_ADDR_MASK);
+ if (ret)
+ goto out;
+
+ sec_firmware_addr |= SEC_FIRMWARE_LOADED;
+ debug("SEC Firmware: Entry point: 0x%llx\n",
+ sec_firmware_addr & SEC_FIRMWARE_ADDR_MASK);
+
+ return 0;
+
+out:
+ printf("SEC Firmware: error (%d)\n", ret);
+ sec_firmware_addr = 0;
+
+ return ret;
+}
+
+static int sec_firmware_entry(u32 *eret_hold_l, u32 *eret_hold_h)
+{
+ const void *entry = (void *)(sec_firmware_addr &
+ SEC_FIRMWARE_ADDR_MASK);
+
+ return _sec_firmware_entry(entry, eret_hold_l, eret_hold_h);
+}
+
+/* Check the secure firmware FIT image */
+__weak bool sec_firmware_is_valid(const void *sec_firmware_img)
+{
+ if (fdt_check_header(sec_firmware_img)) {
+ printf("SEC Firmware: Bad firmware image (not a FIT image)\n");
+ return false;
+ }
+
+ if (!fit_check_format(sec_firmware_img)) {
+ printf("SEC Firmware: Bad firmware image (bad FIT header)\n");
+ return false;
+ }
+
+ return true;
+}
+
+#ifdef CONFIG_ARMV8_PSCI
+/*
+ * The PSCI_VERSION function is added from PSCI v0.2. When the PSCI
+ * v0.1 received this function, the NOT_SUPPORTED (0xffff_ffff) error
+ * number will be returned according to SMC Calling Conventions. But
+ * when getting the NOT_SUPPORTED error number, we cannot ensure if
+ * the PSCI version is v0.1 or other error occurred. So, PSCI v0.1
+ * won't be supported by this framework.
+ * And if the secure firmware isn't running, return NOT_SUPPORTED.
+ *
+ * The return value on success is PSCI version in format
+ * major[31:16]:minor[15:0].
+ */
+unsigned int sec_firmware_support_psci_version(void)
+{
+ if (sec_firmware_addr & SEC_FIRMWARE_RUNNING)
+ return _sec_firmware_support_psci_version();
+
+ return 0xffffffff;
+}
+#endif
+
+/*
+ * sec_firmware_init - Initialize the SEC Firmware
+ * @sec_firmware_img: the SEC Firmware image address
+ * @eret_hold_l: the address to hold exception return address low
+ * @eret_hold_h: the address to hold exception return address high
+ */
+int sec_firmware_init(const void *sec_firmware_img,
+ u32 *eret_hold_l,
+ u32 *eret_hold_h)
+{
+ int ret;
+
+ if (!sec_firmware_is_valid(sec_firmware_img))
+ return -EINVAL;
+
+ ret = sec_firmware_load_image(sec_firmware_img);
+ if (ret) {
+ printf("SEC Firmware: Failed to load image\n");
+ return ret;
+ } else if (sec_firmware_addr & SEC_FIRMWARE_LOADED) {
+ ret = sec_firmware_entry(eret_hold_l, eret_hold_h);
+ if (ret) {
+ printf("SEC Firmware: Failed to initialize\n");
+ return ret;
+ }
+ }
+
+ debug("SEC Firmware: Return from SEC Firmware: current_el = %d\n",
+ current_el());
+
+ /*
+ * The PE will be turned into target EL when returned from
+ * SEC Firmware.
+ */
+ if (current_el() != SEC_FIRMWARE_TARGET_EL)
+ return -EACCES;
+
+ sec_firmware_addr |= SEC_FIRMWARE_RUNNING;
+
+ /* Set exception table and enable caches if it isn't EL3 */
+ if (current_el() != 3) {
+ c_runtime_cpu_setup();
+ enable_caches();
+ }
+
+ return 0;
+}
diff --git a/arch/arm/cpu/armv8/sec_firmware_asm.S b/arch/arm/cpu/armv8/sec_firmware_asm.S
new file mode 100644
index 0000000..0c6a462
--- /dev/null
+++ b/arch/arm/cpu/armv8/sec_firmware_asm.S
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2016 NXP Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <config.h>
+#include <linux/linkage.h>
+#include <asm/system.h>
+#include <asm/macro.h>
+
+WEAK(_sec_firmware_entry)
+ /*
+ * x0: Secure Firmware entry point
+ * x1: Exception return address Low
+ * x2: Exception return address High
+ */
+
+ /* Save stack pointer for EL2 */
+ mov x3, sp
+ msr sp_el2, x3
+
+ /* Set exception return address hold pointer */
+ adr x4, 1f
+ mov x3, x4
+#ifdef SEC_FIRMWARE_ERET_ADDR_REVERT
+ rev w3, w3
+#endif
+ str w3, [x1]
+ lsr x3, x4, #32
+#ifdef SEC_FIRMWARE_ERET_ADDR_REVERT
+ rev w3, w3
+#endif
+ str w3, [x2]
+
+ /* Call SEC monitor */
+ br x0
+
+1:
+ mov x0, #0
+ ret
+ENDPROC(_sec_firmware_entry)
+
+#ifdef CONFIG_ARMV8_PSCI
+ENTRY(_sec_firmware_support_psci_version)
+ mov x0, 0x84000000
+ mov x1, 0x0
+ mov x2, 0x0
+ mov x3, 0x0
+ smc #0
+ ret
+ENDPROC(_sec_firmware_support_psci_version)
+#endif
diff --git a/arch/arm/cpu/armv8/spin_table.c b/arch/arm/cpu/armv8/spin_table.c
new file mode 100644
index 0000000..ec1c9b8
--- /dev/null
+++ b/arch/arm/cpu/armv8/spin_table.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2016 Socionext Inc.
+ * Author: Masahiro Yamada <yamada.masahiro@socionext.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <libfdt.h>
+#include <asm/spin_table.h>
+
+int spin_table_update_dt(void *fdt)
+{
+ int cpus_offset, offset;
+ const char *prop;
+ int ret;
+ unsigned long rsv_addr = (unsigned long)&spin_table_reserve_begin;
+ unsigned long rsv_size = &spin_table_reserve_end -
+ &spin_table_reserve_begin;
+
+ cpus_offset = fdt_path_offset(fdt, "/cpus");
+ if (cpus_offset < 0)
+ return -ENODEV;
+
+ for (offset = fdt_first_subnode(fdt, cpus_offset);
+ offset >= 0;
+ offset = fdt_next_subnode(fdt, offset)) {
+ prop = fdt_getprop(fdt, offset, "device_type", NULL);
+ if (!prop || strcmp(prop, "cpu"))
+ continue;
+
+ /*
+ * In the first loop, we check if every CPU node specifies
+ * spin-table. Otherwise, just return successfully to not
+ * disturb other methods, like psci.
+ */
+ prop = fdt_getprop(fdt, offset, "enable-method", NULL);
+ if (!prop || strcmp(prop, "spin-table"))
+ return 0;
+ }
+
+ for (offset = fdt_first_subnode(fdt, cpus_offset);
+ offset >= 0;
+ offset = fdt_next_subnode(fdt, offset)) {
+ prop = fdt_getprop(fdt, offset, "device_type", NULL);
+ if (!prop || strcmp(prop, "cpu"))
+ continue;
+
+ ret = fdt_setprop_u64(fdt, offset, "cpu-release-addr",
+ (unsigned long)&spin_table_cpu_release_addr);
+ if (ret)
+ return -ENOSPC;
+ }
+
+ ret = fdt_add_mem_rsv(fdt, rsv_addr, rsv_size);
+ if (ret)
+ return -ENOSPC;
+
+ printf(" Reserved memory region for spin-table: addr=%lx size=%lx\n",
+ rsv_addr, rsv_size);
+
+ return 0;
+}
diff --git a/arch/arm/cpu/armv8/spin_table_v8.S b/arch/arm/cpu/armv8/spin_table_v8.S
new file mode 100644
index 0000000..d7f78a6
--- /dev/null
+++ b/arch/arm/cpu/armv8/spin_table_v8.S
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2016 Socionext Inc.
+ * Author: Masahiro Yamada <yamada.masahiro@socionext.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <linux/linkage.h>
+
+ENTRY(spin_table_secondary_jump)
+.globl spin_table_reserve_begin
+spin_table_reserve_begin:
+0: wfe
+ ldr x0, spin_table_cpu_release_addr
+ cbz x0, 0b
+ br x0
+.globl spin_table_cpu_release_addr
+ .align 3
+spin_table_cpu_release_addr:
+ .quad 0
+.globl spin_table_reserve_end
+spin_table_reserve_end:
+ENDPROC(spin_table_secondary_jump)
diff --git a/arch/arm/cpu/armv8/start.S b/arch/arm/cpu/armv8/start.S
index 670e323..67edf94 100644
--- a/arch/arm/cpu/armv8/start.S
+++ b/arch/arm/cpu/armv8/start.S
@@ -94,7 +94,11 @@ reset:
/* Processor specific initialization */
bl lowlevel_init
-#ifdef CONFIG_ARMV8_MULTIENTRY
+#if CONFIG_IS_ENABLED(ARMV8_SPIN_TABLE)
+ branch_if_master x0, x1, master_cpu
+ b spin_table_secondary_jump
+ /* never return */
+#elif defined(CONFIG_ARMV8_MULTIENTRY)
branch_if_master x0, x1, master_cpu
/*
@@ -106,10 +110,8 @@ slave_cpu:
ldr x0, [x1]
cbz x0, slave_cpu
br x0 /* branch to the given address */
-master_cpu:
- /* On the master CPU */
#endif /* CONFIG_ARMV8_MULTIENTRY */
-
+master_cpu:
bl _main
#ifdef CONFIG_SYS_RESET_SCTRL
diff --git a/arch/arm/cpu/armv8/zynqmp/cpu.c b/arch/arm/cpu/armv8/zynqmp/cpu.c
index 509f0aa..b0f1295 100644
--- a/arch/arm/cpu/armv8/zynqmp/cpu.c
+++ b/arch/arm/cpu/armv8/zynqmp/cpu.c
@@ -18,40 +18,47 @@ DECLARE_GLOBAL_DATA_PTR;
static struct mm_region zynqmp_mem_map[] = {
{
- .base = 0x0UL,
+ .virt = 0x0UL,
+ .phys = 0x0UL,
.size = 0x80000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
PTE_BLOCK_INNER_SHARE
}, {
- .base = 0x80000000UL,
+ .virt = 0x80000000UL,
+ .phys = 0x80000000UL,
.size = 0x70000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
PTE_BLOCK_NON_SHARE |
PTE_BLOCK_PXN | PTE_BLOCK_UXN
}, {
- .base = 0xf8000000UL,
+ .virt = 0xf8000000UL,
+ .phys = 0xf8000000UL,
.size = 0x07e00000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
PTE_BLOCK_NON_SHARE |
PTE_BLOCK_PXN | PTE_BLOCK_UXN
}, {
- .base = 0xffe00000UL,
+ .virt = 0xffe00000UL,
+ .phys = 0xffe00000UL,
.size = 0x00200000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
PTE_BLOCK_INNER_SHARE
}, {
- .base = 0x400000000UL,
+ .virt = 0x400000000UL,
+ .phys = 0x400000000UL,
.size = 0x200000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
PTE_BLOCK_NON_SHARE |
PTE_BLOCK_PXN | PTE_BLOCK_UXN
}, {
- .base = 0x600000000UL,
+ .virt = 0x600000000UL,
+ .phys = 0x600000000UL,
.size = 0x800000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
PTE_BLOCK_INNER_SHARE
}, {
- .base = 0xe00000000UL,
+ .virt = 0xe00000000UL,
+ .phys = 0xe00000000UL,
.size = 0xf200000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
PTE_BLOCK_NON_SHARE |
diff --git a/arch/arm/cpu/armv8/zynqmp/mp.c b/arch/arm/cpu/armv8/zynqmp/mp.c
index 58312a7..e10fc31 100644
--- a/arch/arm/cpu/armv8/zynqmp/mp.c
+++ b/arch/arm/cpu/armv8/zynqmp/mp.c
@@ -128,7 +128,7 @@ static void enable_clock_r5(void)
writel(tmp, &crlapb_base->cpu_r5_ctrl);
/* Give some delay for clock
- * to propogate */
+ * to propagate */
udelay(0x500);
}
diff --git a/arch/arm/cpu/u-boot.lds b/arch/arm/cpu/u-boot.lds
index 1769b6e..36c9fd0 100644
--- a/arch/arm/cpu/u-boot.lds
+++ b/arch/arm/cpu/u-boot.lds
@@ -8,6 +8,7 @@
*/
#include <config.h>
+#include <asm/psci.h>
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
@@ -48,34 +49,67 @@ SECTIONS
#ifdef CONFIG_ARMV7_NONSEC
+ /* Align the secure section only if we're going to use it in situ */
+ .__secure_start :
+#ifndef CONFIG_ARMV7_SECURE_BASE
+ ALIGN(CONSTANT(COMMONPAGESIZE))
+#endif
+ {
+ KEEP(*(.__secure_start))
+ }
+
#ifndef CONFIG_ARMV7_SECURE_BASE
#define CONFIG_ARMV7_SECURE_BASE
#define __ARMV7_PSCI_STACK_IN_RAM
#endif
- .__secure_start : {
- . = ALIGN(0x1000);
- *(.__secure_start)
- }
-
.secure_text CONFIG_ARMV7_SECURE_BASE :
AT(ADDR(.__secure_start) + SIZEOF(.__secure_start))
{
*(._secure.text)
}
- . = LOADADDR(.__secure_start) +
- SIZEOF(.__secure_start) +
- SIZEOF(.secure_text);
+ .secure_data : AT(LOADADDR(.secure_text) + SIZEOF(.secure_text))
+ {
+ *(._secure.data)
+ }
+ .secure_stack ALIGN(ADDR(.secure_data) + SIZEOF(.secure_data),
+ CONSTANT(COMMONPAGESIZE)) (NOLOAD) :
#ifdef __ARMV7_PSCI_STACK_IN_RAM
- /* Align to page boundary and skip 2 pages */
- . = (. & ~ 0xfff) + 0x2000;
-#undef __ARMV7_PSCI_STACK_IN_RAM
+ AT(ADDR(.secure_stack))
+#else
+ AT(LOADADDR(.secure_data) + SIZEOF(.secure_data))
+#endif
+ {
+ KEEP(*(.__secure_stack_start))
+
+ /* Skip addreses for stack */
+ . = . + CONFIG_ARMV7_PSCI_NR_CPUS * ARM_PSCI_STACK_SIZE;
+
+ /* Align end of stack section to page boundary */
+ . = ALIGN(CONSTANT(COMMONPAGESIZE));
+
+ KEEP(*(.__secure_stack_end))
+
+#ifdef CONFIG_ARMV7_SECURE_MAX_SIZE
+ /*
+ * We are not checking (__secure_end - __secure_start) here,
+ * as these are the load addresses, and do not include the
+ * stack section. Instead, use the end of the stack section
+ * and the start of the text section.
+ */
+ ASSERT((. - ADDR(.secure_text)) <= CONFIG_ARMV7_SECURE_MAX_SIZE,
+ "Error: secure section exceeds secure memory size");
+#endif
+ }
+
+#ifndef __ARMV7_PSCI_STACK_IN_RAM
+ /* Reset VMA but don't allocate space if we have secure SRAM */
+ . = LOADADDR(.secure_stack);
#endif
- __secure_end_lma = .;
- .__secure_end : AT(__secure_end_lma) {
+ .__secure_end : AT(ADDR(.__secure_end)) {
*(.__secure_end)
LONG(0x1d1071c); /* Must output something to reset LMA */
}
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index ef573ec..acecb7c 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -242,6 +242,7 @@ dtb-$(CONFIG_MACH_SUN8I_A83T) += \
sun8i-a83t-sinovoip-bpi-m3.dtb
dtb-$(CONFIG_MACH_SUN8I_H3) += \
sun8i-h3-orangepi-2.dtb \
+ sun8i-h3-orangepi-lite.dtb \
sun8i-h3-orangepi-one.dtb \
sun8i-h3-orangepi-pc.dtb \
sun8i-h3-orangepi-plus.dtb
diff --git a/arch/arm/dts/dra7-evm.dts b/arch/arm/dts/dra7-evm.dts
index 08ef04e..429b9ed 100644
--- a/arch/arm/dts/dra7-evm.dts
+++ b/arch/arm/dts/dra7-evm.dts
@@ -491,15 +491,13 @@
pinctrl-names = "default";
pinctrl-0 = <&qspi1_pins>;
- spi-max-frequency = <48000000>;
+ spi-max-frequency = <64000000>;
m25p80@0 {
compatible = "s25fl256s1","spi-flash";
- spi-max-frequency = <48000000>;
+ spi-max-frequency = <64000000>;
reg = <0>;
spi-tx-bus-width = <1>;
spi-rx-bus-width = <4>;
- spi-cpol;
- spi-cpha;
#address-cells = <1>;
#size-cells = <1>;
diff --git a/arch/arm/dts/dra72-evm.dts b/arch/arm/dts/dra72-evm.dts
index 205103e..ced2f11 100644
--- a/arch/arm/dts/dra72-evm.dts
+++ b/arch/arm/dts/dra72-evm.dts
@@ -603,15 +603,13 @@
pinctrl-names = "default";
pinctrl-0 = <&qspi1_pins>;
- spi-max-frequency = <48000000>;
+ spi-max-frequency = <64000000>;
m25p80@0 {
compatible = "s25fl256s1","spi-flash";
- spi-max-frequency = <48000000>;
+ spi-max-frequency = <64000000>;
reg = <0>;
spi-tx-bus-width = <1>;
spi-rx-bus-width = <4>;
- spi-cpol;
- spi-cpha;
#address-cells = <1>;
#size-cells = <1>;
diff --git a/arch/arm/dts/exynos4210-origen.dts b/arch/arm/dts/exynos4210-origen.dts
index 3f87761..26c4d7f 100644
--- a/arch/arm/dts/exynos4210-origen.dts
+++ b/arch/arm/dts/exynos4210-origen.dts
@@ -22,7 +22,7 @@
aliases {
serial0 = "/serial@13800000";
console = "/serial@13820000";
- mmc2 = "sdhci@12530000";
+ mmc2 = "/sdhci@12530000";
};
sdhci@12510000 {
diff --git a/arch/arm/dts/exynos4210-trats.dts b/arch/arm/dts/exynos4210-trats.dts
index f3fac80..2ed38f3 100644
--- a/arch/arm/dts/exynos4210-trats.dts
+++ b/arch/arm/dts/exynos4210-trats.dts
@@ -29,8 +29,8 @@
i2c7 = "/i2c@138d0000";
serial0 = "/serial@13800000";
console = "/serial@13820000";
- mmc0 = "sdhci@12510000";
- mmc2 = "sdhci@12530000";
+ mmc0 = "/sdhci@12510000";
+ mmc2 = "/sdhci@12530000";
};
fimd@11c00000 {
diff --git a/arch/arm/dts/exynos4210-universal_c210.dts b/arch/arm/dts/exynos4210-universal_c210.dts
index ad3527e..8cac7dd 100644
--- a/arch/arm/dts/exynos4210-universal_c210.dts
+++ b/arch/arm/dts/exynos4210-universal_c210.dts
@@ -17,8 +17,8 @@
aliases {
serial0 = "/serial@13800000";
console = "/serial@13820000";
- mmc0 = "sdhci@12510000";
- mmc2 = "sdhci@12530000";
+ mmc0 = "/sdhci@12510000";
+ mmc2 = "/sdhci@12530000";
};
sdhci@12510000 {
diff --git a/arch/arm/dts/exynos4412-odroid.dts b/arch/arm/dts/exynos4412-odroid.dts
index a63e8ab..188cb93 100644
--- a/arch/arm/dts/exynos4412-odroid.dts
+++ b/arch/arm/dts/exynos4412-odroid.dts
@@ -25,8 +25,8 @@
i2c7 = "/i2c@138d0000";
serial0 = "/serial@13800000";
console = "/serial@13810000";
- mmc2 = "sdhci@12530000";
- mmc4 = "dwmmc@12550000";
+ mmc2 = "/sdhci@12530000";
+ mmc4 = "/dwmmc@12550000";
};
i2c@13860000 {
diff --git a/arch/arm/dts/exynos4412-trats2.dts b/arch/arm/dts/exynos4412-trats2.dts
index 2d4e522..1fbcf89 100644
--- a/arch/arm/dts/exynos4412-trats2.dts
+++ b/arch/arm/dts/exynos4412-trats2.dts
@@ -29,9 +29,9 @@
i2c7 = "/i2c@138d0000";
serial0 = "/serial@13800000";
console = "/serial@13820000";
- mmc0 = "sdhci@12510000";
- mmc2 = "sdhci@12530000";
- mmc4 = "dwmmc@12550000";
+ mmc0 = "/sdhci@12510000";
+ mmc2 = "/sdhci@12530000";
+ mshc0 = "/dwmmc@12550000";
};
i2c@138d0000 {
diff --git a/arch/arm/dts/k2e-evm.dts b/arch/arm/dts/k2e-evm.dts
index 50c83c2..e2c3fb4 100644
--- a/arch/arm/dts/k2e-evm.dts
+++ b/arch/arm/dts/k2e-evm.dts
@@ -119,10 +119,11 @@
};
&spi0 {
+ status = "okay";
nor_flash: n25q128a11@0 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "Micron,n25q128a11";
+ compatible = "Micron,n25q128a11", "spi-flash";
spi-max-frequency = <54000000>;
m25p,fast-read;
reg = <0>;
diff --git a/arch/arm/dts/k2g-evm.dts b/arch/arm/dts/k2g-evm.dts
index 0ca36ef..e95efd4 100644
--- a/arch/arm/dts/k2g-evm.dts
+++ b/arch/arm/dts/k2g-evm.dts
@@ -31,3 +31,72 @@
&gbe0 {
phy-handle = <&ethphy0>;
};
+
+&spi1 {
+ status = "okay";
+
+ spi_nor: flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "spi-flash";
+ spi-max-frequency = <50000000>;
+ m25p,fast-read;
+ reg = <0>;
+
+ partition@0 {
+ label = "u-boot-spl";
+ reg = <0x0 0x80000>;
+ read-only;
+ };
+
+ partition@1 {
+ label = "misc";
+ reg = <0x80000 0xf80000>;
+ };
+ };
+};
+
+&qspi {
+ status = "okay";
+
+ flash0: m25p80@0 {
+ compatible = "s25fl512s","spi-flash";
+ reg = <0>;
+ spi-tx-bus-width = <1>;
+ spi-rx-bus-width = <4>;
+ spi-max-frequency = <96000000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ tshsl-ns = <392>;
+ tsd2d-ns = <392>;
+ tchsh-ns = <100>;
+ tslch-ns = <100>;
+ block-size = <18>;
+
+
+ partition@0 {
+ label = "QSPI.u-boot-spl-os";
+ reg = <0x00000000 0x00100000>;
+ };
+ partition@1 {
+ label = "QSPI.u-boot-env";
+ reg = <0x00100000 0x00040000>;
+ };
+ partition@2 {
+ label = "QSPI.skern";
+ reg = <0x00140000 0x0040000>;
+ };
+ partition@3 {
+ label = "QSPI.pmmc-firmware";
+ reg = <0x00180000 0x0040000>;
+ };
+ partition@4 {
+ label = "QSPI.kernel";
+ reg = <0x001C0000 0x0800000>;
+ };
+ partition@5 {
+ label = "QSPI.file-system";
+ reg = <0x009C0000 0x3640000>;
+ };
+ };
+};
diff --git a/arch/arm/dts/k2g.dtsi b/arch/arm/dts/k2g.dtsi
index a3ed444..00cd492 100644
--- a/arch/arm/dts/k2g.dtsi
+++ b/arch/arm/dts/k2g.dtsi
@@ -19,6 +19,11 @@
aliases {
serial0 = &uart0;
+ spi0 = &spi0;
+ spi1 = &spi1;
+ spi2 = &spi2;
+ spi3 = &spi3;
+ spi4 = &qspi;
};
memory {
@@ -80,6 +85,19 @@
bus_freq = <2500000>;
};
+ qspi: qspi@2940000 {
+ compatible = "cadence,qspi";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x02940000 0x1000>,
+ <0x24000000 0x4000000>;
+ interrupts = <GIC_SPI 198 IRQ_TYPE_EDGE_RISING>;
+ num-cs = <4>;
+ fifo-depth = <256>;
+ sram-size = <256>;
+ status = "disabled";
+ };
+
#include "k2g-netcp.dtsi"
pmmc: pmmc@2900000 {
@@ -88,5 +106,48 @@
ti,lpsc_module = <1>;
};
+ spi0: spi@21805400 {
+ compatible = "ti,keystone-spi", "ti,dm6441-spi";
+ reg = <0x21805400 0x200>;
+ num-cs = <4>;
+ ti,davinci-spi-intr-line = <0>;
+ interrupts = <GIC_SPI 64 IRQ_TYPE_EDGE_RISING>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ spi1: spi@21805800 {
+ compatible = "ti,keystone-spi", "ti,dm6441-spi";
+ reg = <0x21805800 0x200>;
+ num-cs = <4>;
+ ti,davinci-spi-intr-line = <0>;
+ interrupts = <GIC_SPI 66 IRQ_TYPE_EDGE_RISING>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ spi2: spi@21805c00 {
+ compatible = "ti,keystone-spi", "ti,dm6441-spi";
+ reg = <0x21805C00 0x200>;
+ num-cs = <4>;
+ ti,davinci-spi-intr-line = <0>;
+ interrupts = <GIC_SPI 68 IRQ_TYPE_EDGE_RISING>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ spi3: spi@21806000 {
+ compatible = "ti,keystone-spi", "ti,dm6441-spi";
+ reg = <0x21806000 0x200>;
+ num-cs = <4>;
+ ti,davinci-spi-intr-line = <0>;
+ interrupts = <GIC_SPI 70 IRQ_TYPE_EDGE_RISING>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
};
};
diff --git a/arch/arm/dts/k2hk-evm.dts b/arch/arm/dts/k2hk-evm.dts
index 660ebf5..c5cad2c 100644
--- a/arch/arm/dts/k2hk-evm.dts
+++ b/arch/arm/dts/k2hk-evm.dts
@@ -147,10 +147,11 @@
};
&spi0 {
+ status = "okay";
nor_flash: n25q128a11@0 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "Micron,n25q128a11";
+ compatible = "Micron,n25q128a11", "spi-flash";
spi-max-frequency = <54000000>;
m25p,fast-read;
reg = <0>;
diff --git a/arch/arm/dts/k2l-evm.dts b/arch/arm/dts/k2l-evm.dts
index 9a69a6b..da0661b 100644
--- a/arch/arm/dts/k2l-evm.dts
+++ b/arch/arm/dts/k2l-evm.dts
@@ -96,10 +96,11 @@
};
&spi0 {
+ status ="okay";
nor_flash: n25q128a11@0 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "Micron,n25q128a11";
+ compatible = "Micron,n25q128a11", "spi-flash";
spi-max-frequency = <54000000>;
m25p,fast-read;
reg = <0>;
diff --git a/arch/arm/dts/keystone.dtsi b/arch/arm/dts/keystone.dtsi
index f39b969..be97f3f 100644
--- a/arch/arm/dts/keystone.dtsi
+++ b/arch/arm/dts/keystone.dtsi
@@ -19,6 +19,9 @@
aliases {
serial0 = &uart0;
+ spi0 = &spi0;
+ spi1 = &spi1;
+ spi2 = &spi2;
};
chosen {
diff --git a/arch/arm/dts/rk3288-firefly.dts b/arch/arm/dts/rk3288-firefly.dts
index aed8d3a..3176d50 100644
--- a/arch/arm/dts/rk3288-firefly.dts
+++ b/arch/arm/dts/rk3288-firefly.dts
@@ -30,7 +30,8 @@
0x5 0x0>;
rockchip,phy-timing = <0x48f9aab4 0xea0910 0x1002c200
0xa60 0x40 0x10 0x0>;
- rockchip,sdram-channel = /bits/ 8 <0x1 0xa 0x3 0x2 0x1 0x0 0xf 0xf>;
+ /* Add a dummy value to cause of-platdata think this is bytes */
+ rockchip,sdram-channel = /bits/ 8 <0x1 0xa 0x3 0x2 0x1 0x0 0xf 0xf 0xff>;
rockchip,sdram-params = <0x30B25564 0x627 3 666000000 3 9 1>;
};
diff --git a/arch/arm/dts/sun50i-a64-pine64-plus.dts b/arch/arm/dts/sun50i-a64-pine64-plus.dts
index 549dc15..389c609 100644
--- a/arch/arm/dts/sun50i-a64-pine64-plus.dts
+++ b/arch/arm/dts/sun50i-a64-pine64-plus.dts
@@ -57,3 +57,16 @@
reg = <0x40000000 0x40000000>;
};
};
+
+&emac {
+ pinctrl-names = "default";
+ pinctrl-0 = <&rgmii_pins>;
+ phy-mode = "rgmii";
+ phy = <&phy1>;
+ status = "okay";
+
+ phy1: ethernet-phy@1 {
+ reg = <1>;
+ };
+};
+
diff --git a/arch/arm/dts/sun50i-a64.dtsi b/arch/arm/dts/sun50i-a64.dtsi
index 1bd436f..7d0dc76 100644
--- a/arch/arm/dts/sun50i-a64.dtsi
+++ b/arch/arm/dts/sun50i-a64.dtsi
@@ -506,6 +506,25 @@
allwinner,drive = <SUN4I_PINCTRL_10_MA>;
allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
+
+ rmii_pins: rmii_pins {
+ allwinner,pins = "PD10", "PD11", "PD13", "PD14",
+ "PD17", "PD18", "PD19", "PD20",
+ "PD22", "PD23";
+ allwinner,function = "emac";
+ allwinner,drive = <SUN4I_PINCTRL_40_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ rgmii_pins: rgmii_pins {
+ allwinner,pins = "PD8", "PD9", "PD10", "PD11",
+ "PD12", "PD13", "PD15",
+ "PD16", "PD17", "PD18", "PD19",
+ "PD20", "PD21", "PD22", "PD23";
+ allwinner,function = "emac";
+ allwinner,drive = <SUN4I_PINCTRL_40_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
};
ahb_rst: reset@1c202c0 {
@@ -620,5 +639,19 @@
#address-cells = <1>;
#size-cells = <0>;
};
+
+ emac: ethernet@01c30000 {
+ compatible = "allwinner,sun50i-a64-emac";
+ reg = <0x01c30000 0x2000>, <0x01c00030 0x4>;
+ reg-names = "emac", "syscon";
+ interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>;
+ resets = <&ahb_rst 17>;
+ reset-names = "ahb";
+ clocks = <&bus_gates 17>;
+ clock-names = "ahb";
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
};
};
diff --git a/arch/arm/dts/sun8i-h3-orangepi-2.dts b/arch/arm/dts/sun8i-h3-orangepi-2.dts
index f93f5d1..d3f8f55 100644
--- a/arch/arm/dts/sun8i-h3-orangepi-2.dts
+++ b/arch/arm/dts/sun8i-h3-orangepi-2.dts
@@ -184,3 +184,16 @@
usb1_vbus-supply = <&reg_usb1_vbus>;
status = "okay";
};
+
+&emac {
+ pinctrl-names = "default";
+ pinctrl-0 = <&rgmii_pins>;
+ phy-mode = "rgmii";
+ phy = <&phy1>;
+ status = "okay";
+
+ phy1: ethernet-phy@1 {
+ reg = <1>;
+ };
+};
+
diff --git a/arch/arm/dts/sun8i-h3-orangepi-lite.dts b/arch/arm/dts/sun8i-h3-orangepi-lite.dts
new file mode 100644
index 0000000..ac71749
--- /dev/null
+++ b/arch/arm/dts/sun8i-h3-orangepi-lite.dts
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2016 Hans de Goede <hdegoede@redhat.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 "sun8i-h3.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
+
+/ {
+ model = "Xunlong Orange Pi Lite";
+ compatible = "xunlong,orangepi-lite", "allwinner,sun8i-h3";
+
+ aliases {
+ /* The H3 emac is not used so the wifi is ethernet0 */
+ ethernet1 = &rtl8189ftv;
+ serial0 = &uart0;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&leds_opc>, <&leds_r_opc>;
+
+ pwr_led {
+ label = "orangepi:green:pwr";
+ gpios = <&r_pio 0 10 GPIO_ACTIVE_HIGH>;
+ default-state = "on";
+ };
+
+ status_led {
+ label = "orangepi:red:status";
+ gpios = <&pio 0 15 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ r_gpio_keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&sw_r_opc>;
+
+ sw4 {
+ label = "sw4";
+ linux,code = <BTN_0>;
+ gpios = <&r_pio 0 3 GPIO_ACTIVE_LOW>;
+ };
+ };
+};
+
+&ehci1 {
+ status = "okay";
+};
+
+&ehci2 {
+ status = "okay";
+};
+
+&ir {
+ pinctrl-names = "default";
+ pinctrl-0 = <&ir_pins_a>;
+ status = "okay";
+};
+
+&mmc0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin>;
+ vmmc-supply = <&reg_vcc3v3>;
+ bus-width = <4>;
+ cd-gpios = <&pio 5 6 GPIO_ACTIVE_HIGH>; /* PF6 */
+ cd-inverted;
+ status = "okay";
+};
+
+&mmc1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc1_pins_a>;
+ vmmc-supply = <&reg_vcc3v3>;
+ bus-width = <4>;
+ non-removable;
+ status = "okay";
+
+ /*
+ * Explicitly define the sdio device, so that we can add an ethernet
+ * alias for it (which e.g. makes u-boot set a mac-address).
+ */
+ rtl8189ftv: sdio_wifi@1 {
+ reg = <1>;
+ };
+};
+
+&ohci1 {
+ status = "okay";
+};
+
+&ohci2 {
+ status = "okay";
+};
+
+&pio {
+ leds_opc: led_pins@0 {
+ allwinner,pins = "PA15";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+};
+
+&r_pio {
+ leds_r_opc: led_pins@0 {
+ allwinner,pins = "PL10";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ sw_r_opc: key_pins@0 {
+ allwinner,pins = "PL3";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins_a>;
+ status = "okay";
+};
+
+&usbphy {
+ /* USB VBUS is always on */
+ status = "okay";
+};
diff --git a/arch/arm/dts/sun8i-h3-orangepi-pc.dts b/arch/arm/dts/sun8i-h3-orangepi-pc.dts
index 30ccca0..0a74a91 100644
--- a/arch/arm/dts/sun8i-h3-orangepi-pc.dts
+++ b/arch/arm/dts/sun8i-h3-orangepi-pc.dts
@@ -173,3 +173,15 @@
/* USB VBUS is always on */
status = "okay";
};
+
+&emac {
+ phy = <&phy1>;
+ phy-mode = "mii";
+ allwinner,use-internal-phy;
+ allwinner,leds-active-low;
+ status = "okay";
+
+ phy1: ethernet-phy@1 {
+ reg = <1>;
+ };
+};
diff --git a/arch/arm/dts/sun8i-h3-orangepi-plus.dts b/arch/arm/dts/sun8i-h3-orangepi-plus.dts
index 900ec4f..28f74f6 100644
--- a/arch/arm/dts/sun8i-h3-orangepi-plus.dts
+++ b/arch/arm/dts/sun8i-h3-orangepi-plus.dts
@@ -40,26 +40,13 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
-/dts-v1/;
-#include "sun8i-h3.dtsi"
-#include "sunxi-common-regulators.dtsi"
-
-#include <dt-bindings/gpio/gpio.h>
-#include <dt-bindings/input/input.h>
-#include <dt-bindings/pinctrl/sun4i-a10.h>
+/* The Orange Pi Plus is an extended version of the Orange Pi 2 */
+#include "sun8i-h3-orangepi-2.dts"
/ {
- model = "Xunlong Orange Pi Plus";
+ model = "Xunlong Orange Pi Plus / Plus 2 / Plus 2E";
compatible = "xunlong,orangepi-plus", "allwinner,sun8i-h3";
- aliases {
- serial0 = &uart0;
- };
-
- chosen {
- stdout-path = "serial0:115200n8";
- };
-
reg_usb3_vbus: usb3-vbus {
compatible = "regulator-fixed";
pinctrl-names = "default";
@@ -71,75 +58,42 @@
enable-active-high;
gpio = <&pio 6 11 GPIO_ACTIVE_HIGH>;
};
+};
- leds {
- compatible = "gpio-leds";
- pinctrl-names = "default";
- pinctrl-0 = <&leds_opc>;
-
- status_led {
- label = "status:red:user";
- gpios = <&pio 0 15 GPIO_ACTIVE_HIGH>;
- };
- };
-
- r_leds {
- compatible = "gpio-leds";
- pinctrl-names = "default";
- pinctrl-0 = <&leds_r_opc>;
-
- tx {
- label = "pwr:green:user";
- gpios = <&r_pio 0 10 GPIO_ACTIVE_HIGH>;
- default-state = "on";
- };
- };
-
- r_gpio_keys {
- compatible = "gpio-keys";
- input-name = "sw4";
-
- pinctrl-names = "default";
- pinctrl-0 = <&sw_r_opc>;
+&ehci2 {
+ status = "okay";
+};
- sw4@0 {
- label = "sw4";
- linux,code = <BTN_0>;
- gpios = <&r_pio 0 3 GPIO_ACTIVE_LOW>;
- };
- };
+&ehci3 {
+ status = "okay";
};
-&pio {
- leds_opc: led_pins@0 {
- allwinner,pins = "PA15";
- allwinner,function = "gpio_out";
- allwinner,drive = <SUN4I_PINCTRL_10_MA>;
- allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
- };
+&mmc2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc2_8bit_pins>;
+ vmmc-supply = <&reg_vcc3v3>;
+ bus-width = <8>;
+ non-removable;
+ cap-mmc-hw-reset;
+ status = "okay";
};
-&r_pio {
- leds_r_opc: led_pins@0 {
- allwinner,pins = "PL10";
- allwinner,function = "gpio_out";
- allwinner,drive = <SUN4I_PINCTRL_10_MA>;
- allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
- };
+&mmc2_8bit_pins {
+ /* Increase drive strength for DDR modes */
+ allwinner,drive = <SUN4I_PINCTRL_40_MA>;
+ /* eMMC is missing pull-ups */
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+};
- sw_r_opc: key_pins@0 {
- allwinner,pins = "PL03";
- allwinner,function = "gpio_in";
- allwinner,drive = <SUN4I_PINCTRL_10_MA>;
- allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
- };
+&ohci1 {
+ status = "okay";
};
-&ehci1 {
+&ohci2 {
status = "okay";
};
-&ehci3 {
+&ohci3 {
status = "okay";
};
@@ -152,33 +106,6 @@
};
};
-&mmc0 {
- pinctrl-names = "default";
- pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin>;
- vmmc-supply = <&reg_vcc3v3>;
- bus-width = <4>;
- cd-gpios = <&pio 5 6 GPIO_ACTIVE_HIGH>; /* PF6 */
- cd-inverted;
- status = "okay";
-};
-
-&reg_usb1_vbus {
- gpio = <&pio 6 13 GPIO_ACTIVE_HIGH>;
- status = "okay";
-};
-
-&uart0 {
- pinctrl-names = "default";
- pinctrl-0 = <&uart0_pins_a>;
- status = "okay";
-};
-
-&usb1_vbus_pin_a {
- allwinner,pins = "PG13";
-};
-
&usbphy {
- usb1_vbus-supply = <&reg_usb1_vbus>;
usb3_vbus-supply = <&reg_usb3_vbus>;
- status = "okay";
};
diff --git a/arch/arm/dts/sun8i-h3.dtsi b/arch/arm/dts/sun8i-h3.dtsi
index c2f63c5..72c0920 100644
--- a/arch/arm/dts/sun8i-h3.dtsi
+++ b/arch/arm/dts/sun8i-h3.dtsi
@@ -501,6 +501,17 @@
interrupt-controller;
#interrupt-cells = <3>;
+ rgmii_pins: rgmii_pins {
+ allwinner,pins = "PD0", "PD1", "PD2", "PD3",
+ "PD4", "PD5", "PD7",
+ "PD8", "PD9", "PD10",
+ "PD12", "PD13", "PD15",
+ "PD16", "PD17";
+ allwinner,function = "emac";
+ allwinner,drive = <SUN4I_PINCTRL_40_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
uart0_pins_a: uart0@0 {
allwinner,pins = "PA4", "PA5";
allwinner,function = "uart0";
@@ -530,6 +541,16 @@
allwinner,drive = <SUN4I_PINCTRL_30_MA>;
allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
+
+ mmc2_8bit_pins: mmc2_8bit {
+ allwinner,pins = "PC5", "PC6", "PC8",
+ "PC9", "PC10", "PC11",
+ "PC12", "PC13", "PC14",
+ "PC15", "PC16";
+ allwinner,function = "mmc2";
+ allwinner,drive = <SUN4I_PINCTRL_30_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
};
ahb_rst: reset@01c202c0 {
@@ -616,6 +637,20 @@
status = "disabled";
};
+ emac: ethernet@01c30000 {
+ compatible = "allwinner,sun8i-h3-emac";
+ reg = <0x01c30000 0x2000>, <0x01c00030 0x4>;
+ reg-names = "emac", "syscon";
+ interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>;
+ resets = <&ahb_rst 17>, <&ahb_rst 66>;
+ reset-names = "ahb", "ephy";
+ clocks = <&bus_gates 17>, <&bus_gates 128>;
+ clock-names = "ahb", "ephy";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
gic: interrupt-controller@01c81000 {
compatible = "arm,cortex-a7-gic", "arm,cortex-a15-gic";
reg = <0x01c81000 0x1000>,
diff --git a/arch/arm/imx-common/ddrmc-vf610.c b/arch/arm/imx-common/ddrmc-vf610.c
index daf3c7e..9bc56f6 100644
--- a/arch/arm/imx-common/ddrmc-vf610.c
+++ b/arch/arm/imx-common/ddrmc-vf610.c
@@ -212,7 +212,7 @@ void ddrmc_ctrl_init_ddr3(struct ddr3_jedec_timings const *timings,
cr_setting++;
}
- /* perform default PHY settings (may be overriden by custom settings */
+ /* perform default PHY settings (may be overridden by custom settings */
phy_setting = default_phy_settings;
while (phy_setting->phy_rnum >= 0) {
writel(phy_setting->setting,
diff --git a/arch/arm/include/asm/arch-fsl-layerscape/cpu.h b/arch/arm/include/asm/arch-fsl-layerscape/cpu.h
index 197b0eb..5fd5e87 100644
--- a/arch/arm/include/asm/arch-fsl-layerscape/cpu.h
+++ b/arch/arm/include/asm/arch-fsl-layerscape/cpu.h
@@ -19,29 +19,6 @@ static struct cpu_type cpu_type_list[] = {
#ifndef CONFIG_SYS_DCACHE_OFF
-#define SECTION_SHIFT_L0 39UL
-#define SECTION_SHIFT_L1 30UL
-#define SECTION_SHIFT_L2 21UL
-#define BLOCK_SIZE_L0 0x8000000000
-#define BLOCK_SIZE_L1 0x40000000
-#define BLOCK_SIZE_L2 0x200000
-#define NUM_OF_ENTRY 512
-#define TCR_EL2_PS_40BIT (2 << 16)
-
-#define LAYERSCAPE_VA_BITS (40)
-#define LAYERSCAPE_TCR (TCR_TG0_4K | \
- TCR_EL2_PS_40BIT | \
- TCR_SHARED_NON | \
- TCR_ORGN_NC | \
- TCR_IRGN_NC | \
- TCR_T0SZ(LAYERSCAPE_VA_BITS))
-#define LAYERSCAPE_TCR_FINAL (TCR_TG0_4K | \
- TCR_EL2_PS_40BIT | \
- TCR_SHARED_OUTER | \
- TCR_ORGN_WBWA | \
- TCR_IRGN_WBWA | \
- TCR_T0SZ(LAYERSCAPE_VA_BITS))
-
#ifdef CONFIG_FSL_LSCH3
#define CONFIG_SYS_FSL_CCSR_BASE 0x00000000
#define CONFIG_SYS_FSL_CCSR_SIZE 0x10000000
@@ -101,174 +78,261 @@ static struct cpu_type cpu_type_list[] = {
#define CONFIG_SYS_FSL_DRAM_SIZE3 0x7800000000 /* 480GB */
#endif
-struct sys_mmu_table {
- u64 virt_addr;
- u64 phys_addr;
- u64 size;
- u64 memory_type;
- u64 attribute;
-};
-
-struct table_info {
- u64 *ptr;
- u64 table_base;
- u64 entry_size;
-};
-
-static const struct sys_mmu_table early_mmu_table[] = {
+#define EARLY_PGTABLE_SIZE 0x5000
+static struct mm_region early_map[] = {
#ifdef CONFIG_FSL_LSCH3
{ CONFIG_SYS_FSL_CCSR_BASE, CONFIG_SYS_FSL_CCSR_BASE,
- CONFIG_SYS_FSL_CCSR_SIZE, MT_DEVICE_NGNRNE,
- PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN },
+ CONFIG_SYS_FSL_CCSR_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ },
{ CONFIG_SYS_FSL_OCRAM_BASE, CONFIG_SYS_FSL_OCRAM_BASE,
- CONFIG_SYS_FSL_OCRAM_SIZE, MT_NORMAL, PTE_BLOCK_NON_SHARE },
+ CONFIG_SYS_FSL_OCRAM_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_NON_SHARE
+ },
{ CONFIG_SYS_FSL_QSPI_BASE1, CONFIG_SYS_FSL_QSPI_BASE1,
- CONFIG_SYS_FSL_QSPI_SIZE1, MT_NORMAL, PTE_BLOCK_NON_SHARE},
+ CONFIG_SYS_FSL_QSPI_SIZE1,
+ PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_NON_SHARE},
/* 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, MT_NORMAL, PTE_BLOCK_NON_SHARE },
+ CONFIG_SYS_FSL_IFC_SIZE1_1,
+ PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_NON_SHARE
+ },
{ CONFIG_SYS_FSL_IFC_BASE1 + CONFIG_SYS_FSL_IFC_SIZE1_1,
CONFIG_SYS_FSL_IFC_BASE1 + CONFIG_SYS_FSL_IFC_SIZE1_1,
CONFIG_SYS_FSL_IFC_SIZE1 - CONFIG_SYS_FSL_IFC_SIZE1_1,
- MT_DEVICE_NGNRNE, PTE_BLOCK_NON_SHARE },
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE
+ },
{ CONFIG_SYS_FLASH_BASE, CONFIG_SYS_FSL_IFC_BASE1,
- CONFIG_SYS_FSL_IFC_SIZE1, MT_DEVICE_NGNRNE, PTE_BLOCK_NON_SHARE },
+ CONFIG_SYS_FSL_IFC_SIZE1,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE
+ },
{ CONFIG_SYS_FSL_DRAM_BASE1, CONFIG_SYS_FSL_DRAM_BASE1,
- CONFIG_SYS_FSL_DRAM_SIZE1, MT_NORMAL,
- PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS },
+ CONFIG_SYS_FSL_DRAM_SIZE1,
+ PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+ PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS
+ },
/* 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,
- MT_DEVICE_NGNRNE, PTE_BLOCK_NON_SHARE },
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE
+ },
{ CONFIG_SYS_FSL_DCSR_BASE, CONFIG_SYS_FSL_DCSR_BASE,
- CONFIG_SYS_FSL_DCSR_SIZE, MT_DEVICE_NGNRNE,
- PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN },
+ CONFIG_SYS_FSL_DCSR_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ },
{ CONFIG_SYS_FSL_DRAM_BASE2, CONFIG_SYS_FSL_DRAM_BASE2,
- CONFIG_SYS_FSL_DRAM_SIZE2, MT_NORMAL,
- PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS },
+ CONFIG_SYS_FSL_DRAM_SIZE2,
+ PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+ PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS
+ },
#elif defined(CONFIG_FSL_LSCH2)
{ CONFIG_SYS_FSL_CCSR_BASE, CONFIG_SYS_FSL_CCSR_BASE,
- CONFIG_SYS_FSL_CCSR_SIZE, MT_DEVICE_NGNRNE,
- PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN },
+ CONFIG_SYS_FSL_CCSR_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ },
{ CONFIG_SYS_FSL_OCRAM_BASE, CONFIG_SYS_FSL_OCRAM_BASE,
- CONFIG_SYS_FSL_OCRAM_SIZE, MT_NORMAL, PTE_BLOCK_NON_SHARE },
+ CONFIG_SYS_FSL_OCRAM_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_NON_SHARE
+ },
{ CONFIG_SYS_FSL_DCSR_BASE, CONFIG_SYS_FSL_DCSR_BASE,
- CONFIG_SYS_FSL_DCSR_SIZE, MT_DEVICE_NGNRNE,
- PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN },
+ CONFIG_SYS_FSL_DCSR_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ },
{ CONFIG_SYS_FSL_QSPI_BASE, CONFIG_SYS_FSL_QSPI_BASE,
- CONFIG_SYS_FSL_QSPI_SIZE, MT_DEVICE_NGNRNE, PTE_BLOCK_NON_SHARE },
+ CONFIG_SYS_FSL_QSPI_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE
+ },
{ CONFIG_SYS_FSL_IFC_BASE, CONFIG_SYS_FSL_IFC_BASE,
- CONFIG_SYS_FSL_IFC_SIZE, MT_DEVICE_NGNRNE, PTE_BLOCK_NON_SHARE },
+ CONFIG_SYS_FSL_IFC_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE
+ },
{ CONFIG_SYS_FSL_DRAM_BASE1, CONFIG_SYS_FSL_DRAM_BASE1,
- CONFIG_SYS_FSL_DRAM_SIZE1, MT_NORMAL,
- PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS },
+ CONFIG_SYS_FSL_DRAM_SIZE1,
+ PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+ PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS
+ },
{ CONFIG_SYS_FSL_DRAM_BASE2, CONFIG_SYS_FSL_DRAM_BASE2,
- CONFIG_SYS_FSL_DRAM_SIZE2, MT_NORMAL,
- PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS },
+ CONFIG_SYS_FSL_DRAM_SIZE2,
+ PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+ PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS
+ },
#endif
+ {}, /* list terminator */
};
-static const struct sys_mmu_table final_mmu_table[] = {
+static struct mm_region final_map[] = {
#ifdef CONFIG_FSL_LSCH3
{ CONFIG_SYS_FSL_CCSR_BASE, CONFIG_SYS_FSL_CCSR_BASE,
- CONFIG_SYS_FSL_CCSR_SIZE, MT_DEVICE_NGNRNE,
- PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN },
+ CONFIG_SYS_FSL_CCSR_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ },
{ CONFIG_SYS_FSL_OCRAM_BASE, CONFIG_SYS_FSL_OCRAM_BASE,
- CONFIG_SYS_FSL_OCRAM_SIZE, MT_NORMAL, PTE_BLOCK_NON_SHARE },
+ CONFIG_SYS_FSL_OCRAM_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_NON_SHARE
+ },
{ CONFIG_SYS_FSL_DRAM_BASE1, CONFIG_SYS_FSL_DRAM_BASE1,
- CONFIG_SYS_FSL_DRAM_SIZE1, MT_NORMAL,
- PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS },
+ CONFIG_SYS_FSL_DRAM_SIZE1,
+ PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+ PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS
+ },
{ CONFIG_SYS_FSL_QSPI_BASE1, CONFIG_SYS_FSL_QSPI_BASE1,
- CONFIG_SYS_FSL_QSPI_SIZE1, MT_NORMAL, PTE_BLOCK_NON_SHARE},
+ CONFIG_SYS_FSL_QSPI_SIZE1,
+ PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_NON_SHARE
+ },
{ CONFIG_SYS_FSL_QSPI_BASE2, CONFIG_SYS_FSL_QSPI_BASE2,
- CONFIG_SYS_FSL_QSPI_SIZE2, MT_DEVICE_NGNRNE,
- PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN },
+ CONFIG_SYS_FSL_QSPI_SIZE2,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ },
{ CONFIG_SYS_FSL_IFC_BASE2, CONFIG_SYS_FSL_IFC_BASE2,
- CONFIG_SYS_FSL_IFC_SIZE2, MT_DEVICE_NGNRNE, PTE_BLOCK_NON_SHARE },
+ CONFIG_SYS_FSL_IFC_SIZE2,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE
+ },
{ CONFIG_SYS_FSL_DCSR_BASE, CONFIG_SYS_FSL_DCSR_BASE,
- CONFIG_SYS_FSL_DCSR_SIZE, MT_DEVICE_NGNRNE,
- PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN },
+ CONFIG_SYS_FSL_DCSR_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ },
{ CONFIG_SYS_FSL_MC_BASE, CONFIG_SYS_FSL_MC_BASE,
- CONFIG_SYS_FSL_MC_SIZE, MT_DEVICE_NGNRNE,
- PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN },
+ CONFIG_SYS_FSL_MC_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ },
{ CONFIG_SYS_FSL_NI_BASE, CONFIG_SYS_FSL_NI_BASE,
- CONFIG_SYS_FSL_NI_SIZE, MT_DEVICE_NGNRNE,
- PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN },
+ CONFIG_SYS_FSL_NI_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ },
/* For QBMAN portal, only the first 64MB is cache-enabled */
{ CONFIG_SYS_FSL_QBMAN_BASE, CONFIG_SYS_FSL_QBMAN_BASE,
- CONFIG_SYS_FSL_QBMAN_SIZE_1, MT_NORMAL,
- PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN | PTE_BLOCK_NS },
+ CONFIG_SYS_FSL_QBMAN_SIZE_1,
+ PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN | PTE_BLOCK_NS
+ },
{ CONFIG_SYS_FSL_QBMAN_BASE + CONFIG_SYS_FSL_QBMAN_SIZE_1,
CONFIG_SYS_FSL_QBMAN_BASE + CONFIG_SYS_FSL_QBMAN_SIZE_1,
CONFIG_SYS_FSL_QBMAN_SIZE - CONFIG_SYS_FSL_QBMAN_SIZE_1,
- MT_DEVICE_NGNRNE, PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN },
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ },
{ CONFIG_SYS_PCIE1_PHYS_ADDR, CONFIG_SYS_PCIE1_PHYS_ADDR,
- CONFIG_SYS_PCIE1_PHYS_SIZE, MT_DEVICE_NGNRNE,
- PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN },
+ CONFIG_SYS_PCIE1_PHYS_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ },
{ CONFIG_SYS_PCIE2_PHYS_ADDR, CONFIG_SYS_PCIE2_PHYS_ADDR,
- CONFIG_SYS_PCIE2_PHYS_SIZE, MT_DEVICE_NGNRNE,
- PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN },
+ CONFIG_SYS_PCIE2_PHYS_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ },
{ CONFIG_SYS_PCIE3_PHYS_ADDR, CONFIG_SYS_PCIE3_PHYS_ADDR,
- CONFIG_SYS_PCIE3_PHYS_SIZE, MT_DEVICE_NGNRNE,
- PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN },
+ CONFIG_SYS_PCIE3_PHYS_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ },
#ifdef CONFIG_LS2080A
{ CONFIG_SYS_PCIE4_PHYS_ADDR, CONFIG_SYS_PCIE4_PHYS_ADDR,
- CONFIG_SYS_PCIE4_PHYS_SIZE, MT_DEVICE_NGNRNE,
- PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN },
+ CONFIG_SYS_PCIE4_PHYS_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ },
#endif
{ CONFIG_SYS_FSL_WRIOP1_BASE, CONFIG_SYS_FSL_WRIOP1_BASE,
- CONFIG_SYS_FSL_WRIOP1_SIZE, MT_DEVICE_NGNRNE,
- PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN },
+ CONFIG_SYS_FSL_WRIOP1_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ },
{ CONFIG_SYS_FSL_AIOP1_BASE, CONFIG_SYS_FSL_AIOP1_BASE,
- CONFIG_SYS_FSL_AIOP1_SIZE, MT_DEVICE_NGNRNE,
- PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN },
+ CONFIG_SYS_FSL_AIOP1_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ },
{ CONFIG_SYS_FSL_PEBUF_BASE, CONFIG_SYS_FSL_PEBUF_BASE,
- CONFIG_SYS_FSL_PEBUF_SIZE, MT_DEVICE_NGNRNE,
- PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN },
+ CONFIG_SYS_FSL_PEBUF_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ },
{ CONFIG_SYS_FSL_DRAM_BASE2, CONFIG_SYS_FSL_DRAM_BASE2,
- CONFIG_SYS_FSL_DRAM_SIZE2, MT_NORMAL,
- PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS },
+ CONFIG_SYS_FSL_DRAM_SIZE2,
+ PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+ PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS
+ },
#elif defined(CONFIG_FSL_LSCH2)
{ CONFIG_SYS_FSL_BOOTROM_BASE, CONFIG_SYS_FSL_BOOTROM_BASE,
- CONFIG_SYS_FSL_BOOTROM_SIZE, MT_DEVICE_NGNRNE,
- PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN },
+ CONFIG_SYS_FSL_BOOTROM_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ },
{ CONFIG_SYS_FSL_CCSR_BASE, CONFIG_SYS_FSL_CCSR_BASE,
- CONFIG_SYS_FSL_CCSR_SIZE, MT_DEVICE_NGNRNE,
- PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN },
+ CONFIG_SYS_FSL_CCSR_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ },
{ CONFIG_SYS_FSL_OCRAM_BASE, CONFIG_SYS_FSL_OCRAM_BASE,
- CONFIG_SYS_FSL_OCRAM_SIZE, MT_NORMAL, PTE_BLOCK_NON_SHARE },
+ CONFIG_SYS_FSL_OCRAM_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_NON_SHARE
+ },
{ CONFIG_SYS_FSL_DCSR_BASE, CONFIG_SYS_FSL_DCSR_BASE,
- CONFIG_SYS_FSL_DCSR_SIZE, MT_DEVICE_NGNRNE,
- PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN },
+ CONFIG_SYS_FSL_DCSR_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ },
{ CONFIG_SYS_FSL_QSPI_BASE, CONFIG_SYS_FSL_QSPI_BASE,
- CONFIG_SYS_FSL_QSPI_SIZE, MT_DEVICE_NGNRNE,
- PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN },
+ CONFIG_SYS_FSL_QSPI_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ },
{ CONFIG_SYS_FSL_IFC_BASE, CONFIG_SYS_FSL_IFC_BASE,
- CONFIG_SYS_FSL_IFC_SIZE, MT_DEVICE_NGNRNE, PTE_BLOCK_NON_SHARE },
+ CONFIG_SYS_FSL_IFC_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE
+ },
{ CONFIG_SYS_FSL_DRAM_BASE1, CONFIG_SYS_FSL_DRAM_BASE1,
- CONFIG_SYS_FSL_DRAM_SIZE1, MT_NORMAL,
- PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS },
+ CONFIG_SYS_FSL_DRAM_SIZE1,
+ PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+ PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS
+ },
{ CONFIG_SYS_FSL_QBMAN_BASE, CONFIG_SYS_FSL_QBMAN_BASE,
- CONFIG_SYS_FSL_QBMAN_SIZE, MT_DEVICE_NGNRNE,
- PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN },
+ CONFIG_SYS_FSL_QBMAN_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ },
{ CONFIG_SYS_FSL_DRAM_BASE2, CONFIG_SYS_FSL_DRAM_BASE2,
- CONFIG_SYS_FSL_DRAM_SIZE2, MT_NORMAL,
- PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS },
+ CONFIG_SYS_FSL_DRAM_SIZE2,
+ PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+ PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS
+ },
{ CONFIG_SYS_PCIE1_PHYS_ADDR, CONFIG_SYS_PCIE1_PHYS_ADDR,
- CONFIG_SYS_PCIE1_PHYS_SIZE, MT_DEVICE_NGNRNE,
- PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN },
+ CONFIG_SYS_PCIE1_PHYS_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ },
{ CONFIG_SYS_PCIE2_PHYS_ADDR, CONFIG_SYS_PCIE2_PHYS_ADDR,
- CONFIG_SYS_PCIE2_PHYS_SIZE, MT_DEVICE_NGNRNE,
- PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN },
+ CONFIG_SYS_PCIE2_PHYS_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ },
{ CONFIG_SYS_PCIE3_PHYS_ADDR, CONFIG_SYS_PCIE3_PHYS_ADDR,
- CONFIG_SYS_PCIE3_PHYS_SIZE, MT_DEVICE_NGNRNE,
- PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN },
+ CONFIG_SYS_PCIE3_PHYS_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ },
{ CONFIG_SYS_FSL_DRAM_BASE3, CONFIG_SYS_FSL_DRAM_BASE3,
- CONFIG_SYS_FSL_DRAM_SIZE3, MT_NORMAL,
- PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS },
+ CONFIG_SYS_FSL_DRAM_SIZE3,
+ PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+ PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS
+ },
#endif
-};
+#ifdef CONFIG_SYS_MEM_RESERVE_SECURE
+ {}, /* space holder for secure mem */
#endif
+ {},
+};
+#endif /* !CONFIG_SYS_DCACHE_OFF */
int fsl_qoriq_core_to_cluster(unsigned int core);
u32 cpu_mask(void);
diff --git a/arch/arm/include/asm/arch-fsl-layerscape/ppa.h b/arch/arm/include/asm/arch-fsl-layerscape/ppa.h
new file mode 100644
index 0000000..1f1442b
--- /dev/null
+++ b/arch/arm/include/asm/arch-fsl-layerscape/ppa.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright 2016 NXP Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __FSL_PPA_H_
+#define __FSL_PPA_H_
+
+#define SEC_FIRMWARE_FIT_IMAGE "firmware"
+#define SEC_FIRMEWARE_FIT_CNF_NAME "config@1"
+#define SEC_FIRMWARE_TARGET_EL 2
+
+int ppa_init(void);
+
+#endif
diff --git a/arch/arm/include/asm/arch-rockchip/sdram.h b/arch/arm/include/asm/arch-rockchip/sdram.h
index d3de42d..e08e28f 100644
--- a/arch/arm/include/asm/arch-rockchip/sdram.h
+++ b/arch/arm/include/asm/arch-rockchip/sdram.h
@@ -24,6 +24,12 @@ struct rk3288_sdram_channel {
u8 row_3_4;
u8 cs0_row;
u8 cs1_row;
+ /*
+ * For of-platdata, which would otherwise convert this into two
+ * byte-swapped integers. With a size of 9 bytes, this struct will
+ * appear in of-platdata as a byte array.
+ */
+ u8 dummy;
};
struct rk3288_sdram_pctl_timing {
@@ -81,12 +87,4 @@ struct rk3288_base_params {
u32 odt;
};
-struct rk3288_sdram_params {
- struct rk3288_sdram_channel ch[2];
- struct rk3288_sdram_pctl_timing pctl_timing;
- struct rk3288_sdram_phy_timing phy_timing;
- struct rk3288_base_params base;
- int num_channels;
-};
-
#endif
diff --git a/arch/arm/include/asm/arch-stm32f7/fmc.h b/arch/arm/include/asm/arch-stm32f7/fmc.h
new file mode 100644
index 0000000..7dd5077
--- /dev/null
+++ b/arch/arm/include/asm/arch-stm32f7/fmc.h
@@ -0,0 +1,75 @@
+/*
+ * (C) Copyright 2013
+ * Pavel Boldin, Emcraft Systems, paboldin@emcraft.com
+ *
+ * (C) Copyright 2015
+ * Kamil Lulko, <kamil.lulko@gmail.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _MACH_FMC_H_
+#define _MACH_FMC_H_
+
+struct stm32_fmc_regs {
+ u32 sdcr1; /* Control register 1 */
+ u32 sdcr2; /* Control register 2 */
+ u32 sdtr1; /* Timing register 1 */
+ u32 sdtr2; /* Timing register 2 */
+ u32 sdcmr; /* Mode register */
+ u32 sdrtr; /* Refresh timing register */
+ u32 sdsr; /* Status register */
+};
+
+/*
+ * FMC registers base
+ */
+#define STM32_SDRAM_FMC_BASE 0xA0000140
+#define STM32_SDRAM_FMC ((struct stm32_fmc_regs *)STM32_SDRAM_FMC_BASE)
+
+/* Control register SDCR */
+#define FMC_SDCR_RPIPE_SHIFT 13 /* RPIPE bit shift */
+#define FMC_SDCR_RBURST_SHIFT 12 /* RBURST bit shift */
+#define FMC_SDCR_SDCLK_SHIFT 10 /* SDRAM clock divisor shift */
+#define FMC_SDCR_WP_SHIFT 9 /* Write protection shift */
+#define FMC_SDCR_CAS_SHIFT 7 /* CAS latency shift */
+#define FMC_SDCR_NB_SHIFT 6 /* Number of banks shift */
+#define FMC_SDCR_MWID_SHIFT 4 /* Memory width shift */
+#define FMC_SDCR_NR_SHIFT 2 /* Number of row address bits shift */
+#define FMC_SDCR_NC_SHIFT 0 /* Number of col address bits shift */
+
+/* Timings register SDTR */
+#define FMC_SDTR_TMRD_SHIFT 0 /* Load mode register to active */
+#define FMC_SDTR_TXSR_SHIFT 4 /* Exit self-refresh time */
+#define FMC_SDTR_TRAS_SHIFT 8 /* Self-refresh time */
+#define FMC_SDTR_TRC_SHIFT 12 /* Row cycle delay */
+#define FMC_SDTR_TWR_SHIFT 16 /* Recovery delay */
+#define FMC_SDTR_TRP_SHIFT 20 /* Row precharge delay */
+#define FMC_SDTR_TRCD_SHIFT 24 /* Row-to-column delay */
+
+
+#define FMC_SDCMR_NRFS_SHIFT 5
+
+#define FMC_SDCMR_MODE_NORMAL 0
+#define FMC_SDCMR_MODE_START_CLOCK 1
+#define FMC_SDCMR_MODE_PRECHARGE 2
+#define FMC_SDCMR_MODE_AUTOREFRESH 3
+#define FMC_SDCMR_MODE_WRITE_MODE 4
+#define FMC_SDCMR_MODE_SELFREFRESH 5
+#define FMC_SDCMR_MODE_POWERDOWN 6
+
+#define FMC_SDCMR_BANK_1 (1 << 4)
+#define FMC_SDCMR_BANK_2 (1 << 3)
+
+#define FMC_SDCMR_MODE_REGISTER_SHIFT 9
+
+#define FMC_SDSR_BUSY (1 << 5)
+
+#define FMC_BUSY_WAIT() do { \
+ __asm__ __volatile__ ("dsb" : : : "memory"); \
+ while (STM32_SDRAM_FMC->sdsr & FMC_SDSR_BUSY) \
+ ; \
+ } while (0)
+
+
+#endif /* _MACH_FMC_H_ */
diff --git a/arch/arm/include/asm/arch-stm32f7/stm32.h b/arch/arm/include/asm/arch-stm32f7/stm32.h
index 68bdab0..de55ae5 100644
--- a/arch/arm/include/asm/arch-stm32f7/stm32.h
+++ b/arch/arm/include/asm/arch-stm32f7/stm32.h
@@ -64,6 +64,52 @@ enum clock {
};
#define STM32_BUS_MASK 0xFFFF0000
+struct stm32_rcc_regs {
+ u32 cr; /* RCC clock control */
+ u32 pllcfgr; /* RCC PLL configuration */
+ u32 cfgr; /* RCC clock configuration */
+ u32 cir; /* RCC clock interrupt */
+ u32 ahb1rstr; /* RCC AHB1 peripheral reset */
+ u32 ahb2rstr; /* RCC AHB2 peripheral reset */
+ u32 ahb3rstr; /* RCC AHB3 peripheral reset */
+ u32 rsv0;
+ u32 apb1rstr; /* RCC APB1 peripheral reset */
+ u32 apb2rstr; /* RCC APB2 peripheral reset */
+ u32 rsv1[2];
+ u32 ahb1enr; /* RCC AHB1 peripheral clock enable */
+ u32 ahb2enr; /* RCC AHB2 peripheral clock enable */
+ u32 ahb3enr; /* RCC AHB3 peripheral clock enable */
+ u32 rsv2;
+ u32 apb1enr; /* RCC APB1 peripheral clock enable */
+ u32 apb2enr; /* RCC APB2 peripheral clock enable */
+ u32 rsv3[2];
+ u32 ahb1lpenr; /* RCC AHB1 periph clk enable in low pwr mode */
+ u32 ahb2lpenr; /* RCC AHB2 periph clk enable in low pwr mode */
+ u32 ahb3lpenr; /* RCC AHB3 periph clk enable in low pwr mode */
+ u32 rsv4;
+ u32 apb1lpenr; /* RCC APB1 periph clk enable in low pwr mode */
+ u32 apb2lpenr; /* RCC APB2 periph clk enable in low pwr mode */
+ u32 rsv5[2];
+ u32 bdcr; /* RCC Backup domain control */
+ u32 csr; /* RCC clock control & status */
+ u32 rsv6[2];
+ u32 sscgr; /* RCC spread spectrum clock generation */
+ u32 plli2scfgr; /* RCC PLLI2S configuration */
+ u32 pllsaicfgr;
+ u32 dckcfgr;
+};
+#define STM32_RCC ((struct stm32_rcc_regs *)RCC_BASE)
+
+struct stm32_pwr_regs {
+ u32 cr1; /* power control register 1 */
+ u32 csr1; /* power control/status register 2 */
+ u32 cr2; /* power control register 2 */
+ u32 csr2; /* power control/status register 2 */
+};
+#define STM32_PWR ((struct stm32_pwr_regs *)PWR_BASE)
+
int configure_clocks(void);
+unsigned long clock_get(enum clock clck);
+void stm32_flash_latency_cfg(int latency);
#endif /* _ASM_ARCH_HARDWARE_H */
diff --git a/arch/arm/include/asm/arch-stm32f7/stm32_periph.h b/arch/arm/include/asm/arch-stm32f7/stm32_periph.h
index 38adc4e..0bd4695 100644
--- a/arch/arm/include/asm/arch-stm32f7/stm32_periph.h
+++ b/arch/arm/include/asm/arch-stm32f7/stm32_periph.h
@@ -17,11 +17,13 @@
enum periph_id {
UART1_GPIOA_9_10 = 0,
UART2_GPIOD_5_6,
+ UART6_GPIOC_6_7,
};
enum periph_clock {
USART1_CLOCK_CFG = 0,
USART2_CLOCK_CFG,
+ USART6_CLOCK_CFG,
GPIO_A_CLOCK_CFG,
GPIO_B_CLOCK_CFG,
GPIO_C_CLOCK_CFG,
diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h
index c2e72f5..d4dff1e 100644
--- a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h
+++ b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h
@@ -40,7 +40,8 @@ struct sunxi_ccm_reg {
u32 ahb_gate1; /* 0x64 ahb module clock gating 1 */
u32 apb1_gate; /* 0x68 apb1 module clock gating */
u32 apb2_gate; /* 0x6c apb2 module clock gating */
- u32 reserved9[4];
+ u32 bus_gate4; /* 0x70 gate 4 module clock gating */
+ u8 res3[0xc];
u32 nand0_clk_cfg; /* 0x80 nand0 clock control */
u32 nand1_clk_cfg; /* 0x84 nand1 clock control */
u32 sd0_clk_cfg; /* 0x88 sd0 clock control */
@@ -387,6 +388,7 @@ struct sunxi_ccm_reg {
#define AHB_RESET_OFFSET_LCD0 4
/* ahb_reset2 offsets */
+#define AHB_RESET_OFFSET_EPHY 2
#define AHB_RESET_OFFSET_LVDS 0
/* apb2 reset */
diff --git a/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h b/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h
index c5e9d88..cd009d7 100644
--- a/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h
+++ b/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h
@@ -87,7 +87,8 @@
#define SUNXI_KEYPAD_BASE 0x01c23000
#define SUNXI_TZPC_BASE 0x01c23400
-#if defined(CONFIG_MACH_SUN8I_A83T) || defined(CONFIG_MACH_SUN8I_H3)
+#if defined(CONFIG_MACH_SUN8I_A83T) || defined(CONFIG_MACH_SUN8I_H3) || \
+defined(CONFIG_MACH_SUN50I)
/* SID address space starts at 0x01c1400, but e-fuse is at offset 0x200 */
#define SUNXI_SID_BASE 0x01c14200
#else
diff --git a/arch/arm/include/asm/arch-sunxi/gpio.h b/arch/arm/include/asm/arch-sunxi/gpio.h
index 1ace548..bff7d14 100644
--- a/arch/arm/include/asm/arch-sunxi/gpio.h
+++ b/arch/arm/include/asm/arch-sunxi/gpio.h
@@ -141,6 +141,7 @@ enum sunxi_gpio_number {
/* GPIO pin function config */
#define SUNXI_GPIO_INPUT 0
#define SUNXI_GPIO_OUTPUT 1
+#define SUNXI_GPIO_DISABLE 7
#define SUNXI_GPA_EMAC 2
#define SUN6I_GPA_GMAC 2
@@ -162,8 +163,10 @@ enum sunxi_gpio_number {
#define SUN50I_GPB_UART0 4
#define SUNXI_GPC_NAND 2
+#define SUNXI_GPC_SPI0 3
#define SUNXI_GPC_SDC2 3
#define SUN6I_GPC_SDC3 4
+#define SUN50I_GPC_SPI0 4
#define SUN8I_GPD_SDC1 3
#define SUNXI_GPD_LCD0 2
diff --git a/arch/arm/include/asm/arch-sunxi/mmc.h b/arch/arm/include/asm/arch-sunxi/mmc.h
index 3da360b..cb52e64 100644
--- a/arch/arm/include/asm/arch-sunxi/mmc.h
+++ b/arch/arm/include/asm/arch-sunxi/mmc.h
@@ -127,5 +127,4 @@ struct sunxi_mmc {
#define SUNXI_MMC_COMMON_RESET (1 << 18)
struct mmc *sunxi_mmc_init(int sdc_no);
-int sunxi_mmc_has_egon_boot_signature(struct mmc *mmc);
#endif /* _SUNXI_MMC_H */
diff --git a/arch/arm/include/asm/arch-sunxi/spl.h b/arch/arm/include/asm/arch-sunxi/spl.h
index ec73379..5d7ab55 100644
--- a/arch/arm/include/asm/arch-sunxi/spl.h
+++ b/arch/arm/include/asm/arch-sunxi/spl.h
@@ -51,7 +51,14 @@ struct boot_file_head {
uint8_t spl_signature[4];
};
uint32_t fel_script_address;
- uint32_t reserved1[3];
+ /*
+ * If the fel_uEnv_length member below is set to a non-zero value,
+ * it specifies the size (byte count) of data at fel_script_address.
+ * At the same time this indicates that the data is in uEnv.txt
+ * compatible format, ready to be imported via "env import -t".
+ */
+ uint32_t fel_uEnv_length;
+ uint32_t reserved1[2];
uint32_t boot_media; /* written here by the boot ROM */
uint32_t reserved2[5]; /* padding, align to 64 bytes */
};
diff --git a/arch/arm/include/asm/arch-tegra/board.h b/arch/arm/include/asm/arch-tegra/board.h
index 783bb3c..a3db7ed 100644
--- a/arch/arm/include/asm/arch-tegra/board.h
+++ b/arch/arm/include/asm/arch-tegra/board.h
@@ -20,7 +20,7 @@ void gpio_early_init(void); /* overrideable GPIO config */
/*
* Hooks to allow boards to set up the pinmux for a specific function.
* Has to be implemented in the board files as we don't yet support pinmux
- * setup from FTD. If a board file does not implement one of those functions
+ * setup from FDT. If a board file does not implement one of those functions
* an empty stub function will be called.
*/
diff --git a/arch/arm/include/asm/arch-tegra/clock.h b/arch/arm/include/asm/arch-tegra/clock.h
index e56031d..7daf8bc 100644
--- a/arch/arm/include/asm/arch-tegra/clock.h
+++ b/arch/arm/include/asm/arch-tegra/clock.h
@@ -324,7 +324,7 @@ enum periph_id clk_id_to_periph_id(int clk_id);
* @param p post divider(DIVP)
* @param cpcon base PLL charge pump(CPCON)
* @return 0 if ok, -1 on error (the requested PLL is incorrect and cannot
- * be overriden), 1 if PLL is already correct
+ * be overridden), 1 if PLL is already correct
*/
int clock_set_rate(enum clock_id clkid, u32 n, u32 m, u32 p, u32 cpcon);
diff --git a/arch/arm/include/asm/arch-tegra124/display.h b/arch/arm/include/asm/arch-tegra124/display.h
index ca6644a..c522faa 100644
--- a/arch/arm/include/asm/arch-tegra124/display.h
+++ b/arch/arm/include/asm/arch-tegra124/display.h
@@ -11,7 +11,7 @@
/**
* Register a new display based on device tree configuration.
*
- * The frame buffer can be positioned by U-Boot or overriden by the fdt.
+ * The frame buffer can be positioned by U-Boot or overridden by the fdt.
* You should pass in the U-Boot address here, and check the contents of
* struct fdt_disp_config to see what was actually chosen.
*
diff --git a/arch/arm/include/asm/armv7.h b/arch/arm/include/asm/armv7.h
index 423fc70..a20702e 100644
--- a/arch/arm/include/asm/armv7.h
+++ b/arch/arm/include/asm/armv7.h
@@ -126,6 +126,8 @@ void _smp_pen(void);
extern char __secure_start[];
extern char __secure_end[];
+extern char __secure_stack_start[];
+extern char __secure_stack_end[];
#endif /* CONFIG_ARMV7_NONSEC */
diff --git a/arch/arm/include/asm/armv7m.h b/arch/arm/include/asm/armv7m.h
index 200444d..54d8a2b 100644
--- a/arch/arm/include/asm/armv7m.h
+++ b/arch/arm/include/asm/armv7m.h
@@ -51,10 +51,21 @@ struct v7m_mpu {
#define V7M_MPU_CTRL_ENABLE (1 << 0)
#define V7M_MPU_CTRL_HFNMIENA (1 << 1)
+#define V7M_MPU_CTRL_ENABLE (1 << 0)
+#define V7M_MPU_CTRL_DISABLE (0 << 0)
+#define V7M_MPU_CTRL_HFNMIENA (1 << 1)
+
#define V7M_MPU_RASR_EN (1 << 0)
#define V7M_MPU_RASR_SIZE_BITS 1
#define V7M_MPU_RASR_SIZE_4GB (31 << V7M_MPU_RASR_SIZE_BITS)
+#define V7M_MPU_RASR_SIZE_8MB (24 << V7M_MPU_RASR_SIZE_BITS)
+#define V7M_MPU_RASR_TEX_SHIFT 19
+#define V7M_MPU_RASR_S_SHIFT 18
+#define V7M_MPU_RASR_C_SHIFT 17
+#define V7M_MPU_RASR_B_SHIFT 16
#define V7M_MPU_RASR_AP_RW_RW (3 << 24)
+#define V7M_MPU_RASR_XN_ENABLE (0 << 28)
+#define V7M_MPU_RASR_XN_DISABLE (1 << 28)
#endif /* !defined(__ASSEMBLY__) */
#endif /* ARMV7M_H */
diff --git a/arch/arm/include/asm/armv8/mmu.h b/arch/arm/include/asm/armv8/mmu.h
index 0d08ed3..aa0f3c4 100644
--- a/arch/arm/include/asm/armv8/mmu.h
+++ b/arch/arm/include/asm/armv8/mmu.h
@@ -135,12 +135,15 @@ static inline void set_ttbr_tcr_mair(int el, u64 table, u64 tcr, u64 attr)
}
struct mm_region {
- u64 base;
+ u64 virt;
+ u64 phys;
u64 size;
u64 attrs;
};
extern struct mm_region *mem_map;
+void setup_pgtables(void);
+u64 get_tcr(int el, u64 *pips, u64 *pva_bits);
#endif
#endif /* _ASM_ARMV8_MMU_H_ */
diff --git a/arch/arm/include/asm/armv8/sec_firmware.h b/arch/arm/include/asm/armv8/sec_firmware.h
new file mode 100644
index 0000000..eb68185
--- /dev/null
+++ b/arch/arm/include/asm/armv8/sec_firmware.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2016 NXP Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __SEC_FIRMWARE_H_
+#define __SEC_FIRMWARE_H_
+
+#ifdef CONFIG_FSL_LS_PPA
+#include <asm/arch/ppa.h>
+#endif
+
+int sec_firmware_init(const void *, u32 *, u32 *);
+int _sec_firmware_entry(const void *, u32 *, u32 *);
+bool sec_firmware_is_valid(const void *);
+#ifdef CONFIG_ARMV8_PSCI
+unsigned int sec_firmware_support_psci_version(void);
+unsigned int _sec_firmware_support_psci_version(void);
+#endif
+
+#endif /* __SEC_FIRMWARE_H_ */
diff --git a/arch/arm/include/asm/cache.h b/arch/arm/include/asm/cache.h
index 1f63127..16e65c3 100644
--- a/arch/arm/include/asm/cache.h
+++ b/arch/arm/include/asm/cache.h
@@ -29,6 +29,8 @@ static inline void invalidate_l2_cache(void)
}
#endif
+int check_cache_range(unsigned long start, unsigned long stop);
+
void l2_cache_enable(void);
void l2_cache_disable(void);
void set_section_dcache(int section, enum dcache_option option);
diff --git a/arch/arm/include/asm/global_data.h b/arch/arm/include/asm/global_data.h
index 77d2653..1055017 100644
--- a/arch/arm/include/asm/global_data.h
+++ b/arch/arm/include/asm/global_data.h
@@ -44,6 +44,21 @@ struct arch_global_data {
unsigned long tlb_emerg;
#endif
#endif
+#ifdef CONFIG_SYS_MEM_RESERVE_SECURE
+#define MEM_RESERVE_SECURE_SECURED 0x1
+#define MEM_RESERVE_SECURE_MAINTAINED 0x2
+#define MEM_RESERVE_SECURE_ADDR_MASK (~0x3)
+ /*
+ * Secure memory addr
+ * This variable needs maintenance if the RAM base is not zero,
+ * or if RAM splits into non-consecutive banks. It also has a
+ * flag indicating the secure memory is marked as secure by MMU.
+ * Flags used: 0x1 secured
+ * 0x2 maintained
+ */
+ phys_addr_t secure_ram;
+ unsigned long tlb_allocated;
+#endif
#ifdef CONFIG_OMAP_COMMON
u32 omap_boot_device;
diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h
index 9d185a6..6121f1d 100644
--- a/arch/arm/include/asm/io.h
+++ b/arch/arm/include/asm/io.h
@@ -292,40 +292,6 @@ static inline void __raw_readsl(unsigned long addr, void *data, int longlen)
#define readsb(a, d, s) __raw_readsb((unsigned long)a, d, s)
/*
- * ioremap and friends.
- *
- * ioremap takes a PCI memory address, as specified in
- * linux/Documentation/IO-mapping.txt. If you want a
- * physical address, use __ioremap instead.
- */
-extern void * __ioremap(unsigned long offset, size_t size, unsigned long flags);
-extern void __iounmap(void *addr);
-
-/*
- * Generic ioremap support.
- *
- * Define:
- * iomem_valid_addr(off,size)
- * iomem_to_phys(off)
- */
-#ifdef iomem_valid_addr
-#define __arch_ioremap(off,sz,nocache) \
- ({ \
- unsigned long _off = (off), _size = (sz); \
- void *_ret = (void *)0; \
- if (iomem_valid_addr(_off, _size)) \
- _ret = __ioremap(iomem_to_phys(_off),_size,nocache); \
- _ret; \
- })
-
-#define __arch_iounmap __iounmap
-#endif
-
-#define ioremap(off,sz) __arch_ioremap((off),(sz),0)
-#define ioremap_nocache(off,sz) __arch_ioremap((off),(sz),1)
-#define iounmap(_addr) __arch_iounmap(_addr)
-
-/*
* DMA-consistent mapping functions. These allocate/free a region of
* uncached, unwrite-buffered mapped memory space for use with DMA
* devices. This is the "generic" version. The PCI specific version
diff --git a/arch/arm/include/asm/omap_common.h b/arch/arm/include/asm/omap_common.h
index 07f3848..605c549 100644
--- a/arch/arm/include/asm/omap_common.h
+++ b/arch/arm/include/asm/omap_common.h
@@ -627,6 +627,12 @@ void recalibrate_iodelay(void);
void omap_smc1(u32 service, u32 val);
+/*
+ * Low-level helper function used when performing secure ROM calls on high-
+ * security (HS) device variants by doing a specially-formed smc entry.
+ */
+u32 omap_smc_sec(u32 service, u32 proc_id, u32 flag, u32 *params);
+
void enable_edma3_clocks(void);
void disable_edma3_clocks(void);
diff --git a/arch/arm/include/asm/omap_sec_common.h b/arch/arm/include/asm/omap_sec_common.h
new file mode 100644
index 0000000..842f2af
--- /dev/null
+++ b/arch/arm/include/asm/omap_sec_common.h
@@ -0,0 +1,30 @@
+/*
+ * (C) Copyright 2016
+ * Texas Instruments, <www.ti.com>
+ *
+ * Andreas Dannenberg <dannenberg@ti.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+#ifndef _OMAP_SEC_COMMON_H_
+#define _OMAP_SEC_COMMON_H_
+
+#include <common.h>
+
+/*
+ * Invoke secure ROM API on high-security (HS) device variants. It formats
+ * the variable argument list into the format expected by the ROM code before
+ * triggering the actual low-level smc entry.
+ */
+u32 secure_rom_call(u32 service, u32 proc_id, u32 flag, ...);
+
+/*
+ * Invoke a secure ROM API on high-secure (HS) device variants that can be used
+ * to verify a secure blob by authenticating and optionally decrypting it. The
+ * exact operation performed depends on how the certificate that was embedded
+ * into the blob during the signing/encryption step when the secure blob was
+ * first created.
+ */
+int secure_boot_verify_image(void **p_image, size_t *p_size);
+
+#endif /* _OMAP_SEC_COMMON_H_ */
diff --git a/arch/arm/include/asm/psci.h b/arch/arm/include/asm/psci.h
index bc5edda..e76ecb2 100644
--- a/arch/arm/include/asm/psci.h
+++ b/arch/arm/include/asm/psci.h
@@ -47,16 +47,24 @@
#define ARM_PSCI_0_2_FN_SYSTEM_OFF ARM_PSCI_0_2_FN(8)
#define ARM_PSCI_0_2_FN_SYSTEM_RESET ARM_PSCI_0_2_FN(9)
+/* 1KB stack per core */
+#define ARM_PSCI_STACK_SHIFT 10
+#define ARM_PSCI_STACK_SIZE (1 << ARM_PSCI_STACK_SHIFT)
+
#ifndef __ASSEMBLY__
#include <asm/types.h>
+/* These 2 helper functions assume cpu < CONFIG_ARMV7_PSCI_NR_CPUS */
+u32 psci_get_target_pc(int cpu);
+void psci_save_target_pc(int cpu, u32 pc);
+
void psci_cpu_entry(void);
u32 psci_get_cpu_id(void);
-u32 psci_get_cpu_stack_top(int cpu);
void psci_cpu_off_common(void);
int psci_update_dt(void *fdt);
void psci_board_init(void);
+int fdt_psci(void *fdt);
#endif /* ! __ASSEMBLY__ */
#endif /* __ARM_PSCI_H__ */
diff --git a/arch/arm/include/asm/secure.h b/arch/arm/include/asm/secure.h
index effdb18..5a403bc 100644
--- a/arch/arm/include/asm/secure.h
+++ b/arch/arm/include/asm/secure.h
@@ -3,6 +3,9 @@
#include <config.h>
+#define __secure __attribute__ ((section ("._secure.text")))
+#define __secure_data __attribute__ ((section ("._secure.data")))
+
#ifdef CONFIG_ARMV7_SECURE_BASE
/*
* Warning, horror ahead.
diff --git a/arch/arm/include/asm/setjmp.h b/arch/arm/include/asm/setjmp.h
index ae738b2..f7b97ef 100644
--- a/arch/arm/include/asm/setjmp.h
+++ b/arch/arm/include/asm/setjmp.h
@@ -43,6 +43,7 @@ static inline int setjmp(jmp_buf jmp)
#else
asm volatile(
#ifdef CONFIG_SYS_THUMB_BUILD
+ ".align 2\n"
"adr r0, jmp_target\n"
"add r0, r0, $1\n"
#else
@@ -52,7 +53,8 @@ static inline int setjmp(jmp_buf jmp)
"mov r2, sp\n"
"stm r1!, {r0, r2, r4, r5, r6, r7}\n"
"b 2f\n"
- "jmp_target: "
+ ".align 2\n"
+ "jmp_target: \n"
"mov %0, #1\n"
"2:\n"
: "+l" (r)
diff --git a/arch/arm/include/asm/spin_table.h b/arch/arm/include/asm/spin_table.h
new file mode 100644
index 0000000..8b57539
--- /dev/null
+++ b/arch/arm/include/asm/spin_table.h
@@ -0,0 +1,14 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __ASM_SPIN_TABLE_H__
+#define __ASM_SPIN_TABLE_H__
+
+extern u64 spin_table_cpu_release_addr;
+extern char spin_table_reserve_begin;
+extern char spin_table_reserve_end;
+
+int spin_table_update_dt(void *fdt);
+
+#endif /* __ASM_SPIN_TABLE_H__ */
diff --git a/arch/arm/include/asm/types.h b/arch/arm/include/asm/types.h
index d108915..9af7353 100644
--- a/arch/arm/include/asm/types.h
+++ b/arch/arm/include/asm/types.h
@@ -71,5 +71,4 @@ typedef u32 dma_addr_t;
#endif /* __KERNEL__ */
-typedef unsigned long resource_size_t;
#endif
diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile
index 0e05e87..f406419 100644
--- a/arch/arm/lib/Makefile
+++ b/arch/arm/lib/Makefile
@@ -55,6 +55,8 @@ ifndef CONFIG_ARM64
obj-y += cache-cp15.o
endif
+obj-y += psci-dt.o
+
obj-$(CONFIG_DEBUG_LL) += debug.o
# For EABI conformant tool chains, provide eabi_compat()
diff --git a/arch/arm/lib/bootm-fdt.c b/arch/arm/lib/bootm-fdt.c
index 76b75d8..4481f9e 100644
--- a/arch/arm/lib/bootm-fdt.c
+++ b/arch/arm/lib/bootm-fdt.c
@@ -21,6 +21,7 @@
#include <asm/armv7.h>
#endif
#include <asm/psci.h>
+#include <asm/spin_table.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -45,7 +46,13 @@ int arch_fixup_fdt(void *blob)
if (ret)
return ret;
-#ifdef CONFIG_ARMV7_NONSEC
+#ifdef CONFIG_ARMV8_SPIN_TABLE
+ ret = spin_table_update_dt(blob);
+ if (ret)
+ return ret;
+#endif
+
+#if defined(CONFIG_ARMV7_NONSEC) || defined(CONFIG_ARMV8_PSCI)
ret = psci_update_dt(blob);
if (ret)
return ret;
diff --git a/arch/arm/lib/cache.c b/arch/arm/lib/cache.c
index 3bd8710..d330b09 100644
--- a/arch/arm/lib/cache.c
+++ b/arch/arm/lib/cache.c
@@ -10,6 +10,10 @@
#include <common.h>
#include <malloc.h>
+#ifndef CONFIG_SYS_CACHELINE_SIZE
+#define CONFIG_SYS_CACHELINE_SIZE 32
+#endif
+
/*
* Flush range from all levels of d-cache/unified-cache.
* Affects the range [start, start + size - 1].
@@ -46,6 +50,24 @@ __weak void flush_dcache_range(unsigned long start, unsigned long stop)
/* An empty stub, real implementation should be in platform code */
}
+int check_cache_range(unsigned long start, unsigned long stop)
+{
+ int ok = 1;
+
+ if (start & (CONFIG_SYS_CACHELINE_SIZE - 1))
+ ok = 0;
+
+ if (stop & (CONFIG_SYS_CACHELINE_SIZE - 1))
+ ok = 0;
+
+ if (!ok) {
+ warn_non_spl("CACHE: Misaligned operation at range [%08lx, %08lx]\n",
+ start, stop);
+ }
+
+ return ok;
+}
+
#ifdef CONFIG_SYS_NONCACHED_MEMORY
/*
* Reserve one MMU section worth of address space below the malloc() area that
diff --git a/arch/arm/lib/psci-dt.c b/arch/arm/lib/psci-dt.c
new file mode 100644
index 0000000..8dc31d4
--- /dev/null
+++ b/arch/arm/lib/psci-dt.c
@@ -0,0 +1,123 @@
+/*
+ * Copyright 2016 NXP Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <libfdt.h>
+#include <fdt_support.h>
+#include <linux/sizes.h>
+#include <linux/kernel.h>
+#include <asm/psci.h>
+#ifdef CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT
+#include <asm/armv8/sec_firmware.h>
+#endif
+
+int fdt_psci(void *fdt)
+{
+#if defined(CONFIG_ARMV8_PSCI) || defined(CONFIG_ARMV7_PSCI)
+ int nodeoff;
+ unsigned int psci_ver = 0;
+ char *psci_compt;
+ int tmp;
+
+ nodeoff = fdt_path_offset(fdt, "/cpus");
+ if (nodeoff < 0) {
+ printf("couldn't find /cpus\n");
+ return nodeoff;
+ }
+
+ /* add 'enable-method = "psci"' to each cpu node */
+ for (tmp = fdt_first_subnode(fdt, nodeoff);
+ tmp >= 0;
+ tmp = fdt_next_subnode(fdt, tmp)) {
+ const struct fdt_property *prop;
+ int len;
+
+ prop = fdt_get_property(fdt, tmp, "device_type", &len);
+ if (!prop)
+ continue;
+ if (len < 4)
+ continue;
+ if (strcmp(prop->data, "cpu"))
+ continue;
+
+ /*
+ * Not checking rv here, our approach is to skip over errors in
+ * individual cpu nodes, hopefully some of the nodes are
+ * processed correctly and those will boot
+ */
+ fdt_setprop_string(fdt, tmp, "enable-method", "psci");
+ }
+
+ /*
+ * The PSCI node might be called "/psci" or might be called something
+ * else but contain either of the compatible strings
+ * "arm,psci"/"arm,psci-0.2"
+ */
+ nodeoff = fdt_path_offset(fdt, "/psci");
+ if (nodeoff >= 0)
+ goto init_psci_node;
+
+ nodeoff = fdt_node_offset_by_compatible(fdt, -1, "arm,psci");
+ if (nodeoff >= 0)
+ goto init_psci_node;
+
+ nodeoff = fdt_node_offset_by_compatible(fdt, -1, "arm,psci-0.2");
+ if (nodeoff >= 0)
+ goto init_psci_node;
+
+ nodeoff = fdt_node_offset_by_compatible(fdt, -1, "arm,psci-1.0");
+ if (nodeoff >= 0)
+ goto init_psci_node;
+
+ nodeoff = fdt_path_offset(fdt, "/");
+ if (nodeoff < 0)
+ return nodeoff;
+
+ nodeoff = fdt_add_subnode(fdt, nodeoff, "psci");
+ if (nodeoff < 0)
+ return nodeoff;
+
+init_psci_node:
+#ifdef CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT
+ psci_ver = sec_firmware_support_psci_version();
+#endif
+ switch (psci_ver) {
+ case 0x00010000:
+ psci_compt = "arm,psci-1.0";
+ break;
+ case 0x00000002:
+ psci_compt = "arm,psci-0.2";
+ break;
+ default:
+ psci_compt = "arm,psci";
+ break;
+ }
+
+ tmp = fdt_setprop_string(fdt, nodeoff, "compatible", psci_compt);
+ if (tmp)
+ return tmp;
+ tmp = fdt_setprop_string(fdt, nodeoff, "method", "smc");
+ if (tmp)
+ return tmp;
+
+#ifdef CONFIG_ARMV7_PSCI
+ tmp = fdt_setprop_u32(fdt, nodeoff, "cpu_suspend",
+ ARM_PSCI_FN_CPU_SUSPEND);
+ if (tmp)
+ return tmp;
+ tmp = fdt_setprop_u32(fdt, nodeoff, "cpu_off", ARM_PSCI_FN_CPU_OFF);
+ if (tmp)
+ return tmp;
+ tmp = fdt_setprop_u32(fdt, nodeoff, "cpu_on", ARM_PSCI_FN_CPU_ON);
+ if (tmp)
+ return tmp;
+ tmp = fdt_setprop_u32(fdt, nodeoff, "migrate", ARM_PSCI_FN_MIGRATE);
+ if (tmp)
+ return tmp;
+#endif
+#endif
+ return 0;
+}
diff --git a/arch/arm/lib/sections.c b/arch/arm/lib/sections.c
index 6a94522..952e8ae 100644
--- a/arch/arm/lib/sections.c
+++ b/arch/arm/lib/sections.c
@@ -27,6 +27,8 @@ char __rel_dyn_start[0] __attribute__((section(".__rel_dyn_start")));
char __rel_dyn_end[0] __attribute__((section(".__rel_dyn_end")));
char __secure_start[0] __attribute__((section(".__secure_start")));
char __secure_end[0] __attribute__((section(".__secure_end")));
+char __secure_stack_start[0] __attribute__((section(".__secure_stack_start")));
+char __secure_stack_end[0] __attribute__((section(".__secure_stack_end")));
char __efi_runtime_start[0] __attribute__((section(".__efi_runtime_start")));
char __efi_runtime_stop[0] __attribute__((section(".__efi_runtime_stop")));
char __efi_runtime_rel_start[0] __attribute__((section(".__efi_runtime_rel_start")));
diff --git a/arch/arm/mach-exynos/include/mach/dwmmc.h b/arch/arm/mach-exynos/include/mach/dwmmc.h
index bd997ad..ab8361f 100644
--- a/arch/arm/mach-exynos/include/mach/dwmmc.h
+++ b/arch/arm/mach-exynos/include/mach/dwmmc.h
@@ -28,4 +28,3 @@
#define DWMCI_DIVRATIO_MASK 0x7
int exynos_dwmmc_init(const void *blob);
-int exynos_dwmci_add_port(int index, u32 regbase, int bus_width, u32 clksel);
diff --git a/arch/arm/mach-exynos/mmu-arm64.c b/arch/arm/mach-exynos/mmu-arm64.c
index ba6d99d..2381422 100644
--- a/arch/arm/mach-exynos/mmu-arm64.c
+++ b/arch/arm/mach-exynos/mmu-arm64.c
@@ -13,21 +13,20 @@ DECLARE_GLOBAL_DATA_PTR;
#ifdef CONFIG_EXYNOS7420
static struct mm_region exynos7420_mem_map[] = {
{
- .base = 0x10000000UL,
+ .virt = 0x10000000UL,
+ .phys = 0x10000000UL,
.size = 0x10000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
PTE_BLOCK_NON_SHARE |
PTE_BLOCK_PXN | PTE_BLOCK_UXN,
}, {
- .base = 0x40000000UL,
+ .virt = 0x40000000UL,
+ .phys = 0x40000000UL,
.size = 0x80000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
PTE_BLOCK_INNER_SHARE,
}, {
/* List terminator */
- .base = 0,
- .size = 0,
- .attrs = 0,
},
};
diff --git a/arch/arm/mach-meson/board.c b/arch/arm/mach-meson/board.c
index 64fa3c1..1dd53e2 100644
--- a/arch/arm/mach-meson/board.c
+++ b/arch/arm/mach-meson/board.c
@@ -48,12 +48,14 @@ void reset_cpu(ulong addr)
static struct mm_region gxbb_mem_map[] = {
{
- .base = 0x0UL,
+ .virt = 0x0UL,
+ .phys = 0x0UL,
.size = 0x80000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
PTE_BLOCK_INNER_SHARE
}, {
- .base = 0x80000000UL,
+ .virt = 0x80000000UL,
+ .phys = 0x80000000UL,
.size = 0x80000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
PTE_BLOCK_NON_SHARE |
diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig
index 2a8afac..c49cc19 100644
--- a/arch/arm/mach-rockchip/Kconfig
+++ b/arch/arm/mach-rockchip/Kconfig
@@ -17,33 +17,6 @@ config ROCKCHIP_RK3036
and video codec support. Peripherals include Gigabit Ethernet,
USB2 host and OTG, SDIO, I2S, UART, SPI, I2C and PWMs.
-config SYS_MALLOC_F
- default y
-
-config SPL_SYS_MALLOC_SIMPLE
- default y
-
-config SPL_DM
- default y
-
-config DM_SERIAL
- default y
-
-config DM_SPI
- default y
-
-config DM_SPI_FLASH
- default y
-
-config DM_I2C
- default y
-
-config DM_GPIO
- default y
-
-config BLK
- default y
-
source "arch/arm/mach-rockchip/rk3288/Kconfig"
source "arch/arm/mach-rockchip/rk3036/Kconfig"
endif
diff --git a/arch/arm/mach-rockchip/rk3288-board-spl.c b/arch/arm/mach-rockchip/rk3288-board-spl.c
index 15f1266..123f58b 100644
--- a/arch/arm/mach-rockchip/rk3288-board-spl.c
+++ b/arch/arm/mach-rockchip/rk3288-board-spl.c
@@ -29,6 +29,7 @@ DECLARE_GLOBAL_DATA_PTR;
u32 spl_boot_device(void)
{
+#if !CONFIG_IS_ENABLED(OF_PLATDATA)
const void *blob = gd->fdt_blob;
struct udevice *dev;
const char *bootdev;
@@ -63,6 +64,7 @@ u32 spl_boot_device(void)
}
fallback:
+#endif
return BOOT_DEVICE_MMC1;
}
@@ -114,7 +116,6 @@ static void configure_l2ctlr(void)
#ifdef CONFIG_SPL_MMC_SUPPORT
static int configure_emmc(struct udevice *pinctrl)
{
-#if !defined(CONFIG_TARGET_ROCK2) && !defined(CONFIG_TARGET_FIREFLY_RK3288)
struct gpio_desc desc;
int ret;
@@ -144,7 +145,6 @@ static int configure_emmc(struct udevice *pinctrl)
debug("gpio value ret=%d\n", ret);
return ret;
}
-#endif
return 0;
}
@@ -247,15 +247,18 @@ void spl_board_init(void)
goto err;
}
#ifdef CONFIG_SPL_MMC_SUPPORT
- ret = pinctrl_request_noflags(pinctrl, PERIPH_ID_SDCARD);
- if (ret) {
- debug("%s: Failed to set up SD card\n", __func__);
- goto err;
- }
- ret = configure_emmc(pinctrl);
- if (ret) {
- debug("%s: Failed to set up eMMC\n", __func__);
- goto err;
+ if (!IS_ENABLED(CONFIG_TARGET_ROCK2) &&
+ !IS_ENABLED(CONFIG_TARGET_FIREFLY_RK3288)) {
+ ret = pinctrl_request_noflags(pinctrl, PERIPH_ID_SDCARD);
+ if (ret) {
+ debug("%s: Failed to set up SD card\n", __func__);
+ goto err;
+ }
+ ret = configure_emmc(pinctrl);
+ if (ret) {
+ debug("%s: Failed to set up eMMC\n", __func__);
+ goto err;
+ }
}
#endif
diff --git a/arch/arm/mach-rockchip/rk3288/sdram_rk3288.c b/arch/arm/mach-rockchip/rk3288/sdram_rk3288.c
index 55ac73e..b36b6af 100644
--- a/arch/arm/mach-rockchip/rk3288/sdram_rk3288.c
+++ b/arch/arm/mach-rockchip/rk3288/sdram_rk3288.c
@@ -10,6 +10,7 @@
#include <common.h>
#include <clk.h>
#include <dm.h>
+#include <dt-structs.h>
#include <errno.h>
#include <ram.h>
#include <regmap.h>
@@ -41,6 +42,19 @@ struct dram_info {
struct rk3288_grf *grf;
struct rk3288_sgrf *sgrf;
struct rk3288_pmu *pmu;
+ bool is_veyron;
+};
+
+struct rk3288_sdram_params {
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+ struct dtd_rockchip_rk3288_dmc of_plat;
+#endif
+ struct rk3288_sdram_channel ch[2];
+ struct rk3288_sdram_pctl_timing pctl_timing;
+ struct rk3288_sdram_phy_timing phy_timing;
+ struct rk3288_base_params base;
+ int num_channels;
+ struct regmap *map;
};
#ifdef CONFIG_SPL_BUILD
@@ -703,7 +717,7 @@ static int sdram_init(struct dram_info *dram,
return 0;
}
-#endif
+#endif /* CONFIG_SPL_BUILD */
size_t sdram_size_mb(struct rk3288_pmu *pmu)
{
@@ -779,18 +793,36 @@ static int veyron_init(struct dram_info *priv)
static int setup_sdram(struct udevice *dev)
{
struct dram_info *priv = dev_get_priv(dev);
- struct rk3288_sdram_params params;
+ struct rk3288_sdram_params *params = dev_get_platdata(dev);
+
+# ifdef CONFIG_ROCKCHIP_FAST_SPL
+ if (priv->is_veyron) {
+ int ret;
+
+ ret = veyron_init(priv);
+ if (ret)
+ return ret;
+ }
+# endif
+
+ return sdram_init(priv, params);
+}
+
+static int rk3288_dmc_ofdata_to_platdata(struct udevice *dev)
+{
+#if !CONFIG_IS_ENABLED(OF_PLATDATA)
+ struct rk3288_sdram_params *params = dev_get_platdata(dev);
const void *blob = gd->fdt_blob;
int node = dev->of_offset;
int i, ret;
- params.num_channels = fdtdec_get_int(blob, node,
- "rockchip,num-channels", 1);
- for (i = 0; i < params.num_channels; i++) {
+ params->num_channels = fdtdec_get_int(blob, node,
+ "rockchip,num-channels", 1);
+ for (i = 0; i < params->num_channels; i++) {
ret = fdtdec_get_byte_array(blob, node,
"rockchip,sdram-channel",
- (u8 *)&params.ch[i],
- sizeof(params.ch[i]));
+ (u8 *)&params->ch[i],
+ sizeof(params->ch[i]));
if (ret) {
debug("%s: Cannot read rockchip,sdram-channel\n",
__func__);
@@ -798,46 +830,82 @@ static int setup_sdram(struct udevice *dev)
}
}
ret = fdtdec_get_int_array(blob, node, "rockchip,pctl-timing",
- (u32 *)&params.pctl_timing,
- sizeof(params.pctl_timing) / sizeof(u32));
+ (u32 *)&params->pctl_timing,
+ sizeof(params->pctl_timing) / sizeof(u32));
if (ret) {
debug("%s: Cannot read rockchip,pctl-timing\n", __func__);
return -EINVAL;
}
ret = fdtdec_get_int_array(blob, node, "rockchip,phy-timing",
- (u32 *)&params.phy_timing,
- sizeof(params.phy_timing) / sizeof(u32));
+ (u32 *)&params->phy_timing,
+ sizeof(params->phy_timing) / sizeof(u32));
if (ret) {
debug("%s: Cannot read rockchip,phy-timing\n", __func__);
return -EINVAL;
}
ret = fdtdec_get_int_array(blob, node, "rockchip,sdram-params",
- (u32 *)&params.base,
- sizeof(params.base) / sizeof(u32));
+ (u32 *)&params->base,
+ sizeof(params->base) / sizeof(u32));
if (ret) {
debug("%s: Cannot read rockchip,sdram-params\n", __func__);
return -EINVAL;
}
+#ifdef CONFIG_ROCKCHIP_FAST_SPL
+ struct dram_info *priv = dev_get_priv(dev);
-# ifdef CONFIG_ROCKCHIP_FAST_SPL
- if (!fdt_node_check_compatible(blob, 0, "google,veyron")) {
- ret = veyron_init(priv);
- if (ret)
- return ret;
+ priv->is_veyron = !fdt_node_check_compatible(blob, 0, "google,veyron");
+#endif
+ ret = regmap_init_mem(dev, &params->map);
+ if (ret)
+ return ret;
+#endif
+
+ return 0;
+}
+#endif /* CONFIG_SPL_BUILD */
+
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+static int conv_of_platdata(struct udevice *dev)
+{
+ struct rk3288_sdram_params *plat = dev_get_platdata(dev);
+ struct dtd_rockchip_rk3288_dmc *of_plat = &plat->of_plat;
+ int i, ret;
+
+ for (i = 0; i < 2; i++) {
+ memcpy(&plat->ch[i], of_plat->rockchip_sdram_channel,
+ sizeof(plat->ch[i]));
}
-# endif
+ memcpy(&plat->pctl_timing, of_plat->rockchip_pctl_timing,
+ sizeof(plat->pctl_timing));
+ memcpy(&plat->phy_timing, of_plat->rockchip_phy_timing,
+ sizeof(plat->phy_timing));
+ memcpy(&plat->base, of_plat->rockchip_sdram_params, sizeof(plat->base));
+ plat->num_channels = of_plat->rockchip_num_channels;
+ ret = regmap_init_mem_platdata(dev, of_plat->reg,
+ ARRAY_SIZE(of_plat->reg) / 2,
+ &plat->map);
+ if (ret)
+ return ret;
- return sdram_init(priv, &params);
+ return 0;
}
#endif
static int rk3288_dmc_probe(struct udevice *dev)
{
+#ifdef CONFIG_SPL_BUILD
+ struct rk3288_sdram_params *plat = dev_get_platdata(dev);
+#endif
struct dram_info *priv = dev_get_priv(dev);
struct regmap *map;
int ret;
struct udevice *dev_clk;
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+ ret = conv_of_platdata(dev);
+ if (ret)
+ return ret;
+#endif
map = syscon_get_regmap_by_driver_data(ROCKCHIP_SYSCON_NOC);
if (IS_ERR(map))
return PTR_ERR(map);
@@ -849,14 +917,12 @@ static int rk3288_dmc_probe(struct udevice *dev)
priv->sgrf = syscon_get_first_range(ROCKCHIP_SYSCON_SGRF);
priv->pmu = syscon_get_first_range(ROCKCHIP_SYSCON_PMU);
- ret = regmap_init_mem(dev, &map);
- if (ret)
- return ret;
- priv->chan[0].pctl = regmap_get_range(map, 0);
- priv->chan[0].publ = regmap_get_range(map, 1);
- priv->chan[1].pctl = regmap_get_range(map, 2);
- priv->chan[1].publ = regmap_get_range(map, 3);
-
+#ifdef CONFIG_SPL_BUILD
+ priv->chan[0].pctl = regmap_get_range(plat->map, 0);
+ priv->chan[0].publ = regmap_get_range(plat->map, 1);
+ priv->chan[1].pctl = regmap_get_range(plat->map, 2);
+ priv->chan[1].publ = regmap_get_range(plat->map, 3);
+#endif
ret = uclass_get_device(UCLASS_CLK, 0, &dev_clk);
if (ret)
return ret;
@@ -898,10 +964,16 @@ static const struct udevice_id rk3288_dmc_ids[] = {
};
U_BOOT_DRIVER(dmc_rk3288) = {
- .name = "rk3288_dmc",
+ .name = "rockchip_rk3288_dmc",
.id = UCLASS_RAM,
.of_match = rk3288_dmc_ids,
.ops = &rk3288_dmc_ops,
+#ifdef CONFIG_SPL_BUILD
+ .ofdata_to_platdata = rk3288_dmc_ofdata_to_platdata,
+#endif
.probe = rk3288_dmc_probe,
.priv_auto_alloc_size = sizeof(struct dram_info),
+#ifdef CONFIG_SPL_BUILD
+ .platdata_auto_alloc_size = sizeof(struct rk3288_sdram_params),
+#endif
};
diff --git a/arch/arm/mach-rockchip/rk3288/syscon_rk3288.c b/arch/arm/mach-rockchip/rk3288/syscon_rk3288.c
index c9f7c4e..be4b2b0 100644
--- a/arch/arm/mach-rockchip/rk3288/syscon_rk3288.c
+++ b/arch/arm/mach-rockchip/rk3288/syscon_rk3288.c
@@ -23,3 +23,41 @@ U_BOOT_DRIVER(syscon_rk3288) = {
.id = UCLASS_SYSCON,
.of_match = rk3288_syscon_ids,
};
+
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+static int rk3288_syscon_bind_of_platdata(struct udevice *dev)
+{
+ dev->driver_data = dev->driver->of_match->data;
+ debug("syscon: %s %d\n", dev->name, (uint)dev->driver_data);
+
+ return 0;
+}
+
+U_BOOT_DRIVER(rockchip_rk3288_noc) = {
+ .name = "rockchip_rk3288_noc",
+ .id = UCLASS_SYSCON,
+ .of_match = rk3288_syscon_ids,
+ .bind = rk3288_syscon_bind_of_platdata,
+};
+
+U_BOOT_DRIVER(rockchip_rk3288_grf) = {
+ .name = "rockchip_rk3288_grf",
+ .id = UCLASS_SYSCON,
+ .of_match = rk3288_syscon_ids + 1,
+ .bind = rk3288_syscon_bind_of_platdata,
+};
+
+U_BOOT_DRIVER(rockchip_rk3288_sgrf) = {
+ .name = "rockchip_rk3288_sgrf",
+ .id = UCLASS_SYSCON,
+ .of_match = rk3288_syscon_ids + 2,
+ .bind = rk3288_syscon_bind_of_platdata,
+};
+
+U_BOOT_DRIVER(rockchip_rk3288_pmu) = {
+ .name = "rockchip_rk3288_pmu",
+ .id = UCLASS_SYSCON,
+ .of_match = rk3288_syscon_ids + 3,
+ .bind = rk3288_syscon_bind_of_platdata,
+};
+#endif
diff --git a/arch/arm/mach-snapdragon/sysmap-apq8016.c b/arch/arm/mach-snapdragon/sysmap-apq8016.c
index ef0db2a..580b9c7 100644
--- a/arch/arm/mach-snapdragon/sysmap-apq8016.c
+++ b/arch/arm/mach-snapdragon/sysmap-apq8016.c
@@ -11,13 +11,15 @@
static struct mm_region apq8016_mem_map[] = {
{
- .base = 0x0UL, /* Peripheral block */
+ .virt = 0x0UL, /* Peripheral block */
+ .phys = 0x0UL, /* Peripheral block */
.size = 0x8000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
PTE_BLOCK_NON_SHARE |
PTE_BLOCK_PXN | PTE_BLOCK_UXN
}, {
- .base = 0x80000000UL, /* DDR */
+ .virt = 0x80000000UL, /* DDR */
+ .phys = 0x80000000UL, /* DDR */
.size = 0x80000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
PTE_BLOCK_INNER_SHARE
diff --git a/arch/arm/mach-stm32/stm32f7/Makefile b/arch/arm/mach-stm32/stm32f7/Makefile
index 40f1ad3..643d4d9 100644
--- a/arch/arm/mach-stm32/stm32f7/Makefile
+++ b/arch/arm/mach-stm32/stm32f7/Makefile
@@ -5,4 +5,4 @@
# SPDX-License-Identifier: GPL-2.0+
#
-obj-y += timer.o clock.o
+obj-y += timer.o clock.o soc.o
diff --git a/arch/arm/mach-stm32/stm32f7/clock.c b/arch/arm/mach-stm32/stm32f7/clock.c
index 17a715b..ac47850 100644
--- a/arch/arm/mach-stm32/stm32f7/clock.c
+++ b/arch/arm/mach-stm32/stm32f7/clock.c
@@ -11,12 +11,243 @@
#include <asm/arch/stm32.h>
#include <asm/arch/stm32_periph.h>
+#define RCC_CR_HSION (1 << 0)
+#define RCC_CR_HSEON (1 << 16)
+#define RCC_CR_HSERDY (1 << 17)
+#define RCC_CR_HSEBYP (1 << 18)
+#define RCC_CR_CSSON (1 << 19)
+#define RCC_CR_PLLON (1 << 24)
+#define RCC_CR_PLLRDY (1 << 25)
+
+#define RCC_PLLCFGR_PLLM_MASK 0x3F
+#define RCC_PLLCFGR_PLLN_MASK 0x7FC0
+#define RCC_PLLCFGR_PLLP_MASK 0x30000
+#define RCC_PLLCFGR_PLLQ_MASK 0xF000000
+#define RCC_PLLCFGR_PLLSRC (1 << 22)
+#define RCC_PLLCFGR_PLLM_SHIFT 0
+#define RCC_PLLCFGR_PLLN_SHIFT 6
+#define RCC_PLLCFGR_PLLP_SHIFT 16
+#define RCC_PLLCFGR_PLLQ_SHIFT 24
+
+#define RCC_CFGR_AHB_PSC_MASK 0xF0
+#define RCC_CFGR_APB1_PSC_MASK 0x1C00
+#define RCC_CFGR_APB2_PSC_MASK 0xE000
+#define RCC_CFGR_SW0 (1 << 0)
+#define RCC_CFGR_SW1 (1 << 1)
+#define RCC_CFGR_SW_MASK 0x3
+#define RCC_CFGR_SW_HSI 0
+#define RCC_CFGR_SW_HSE RCC_CFGR_SW0
+#define RCC_CFGR_SW_PLL RCC_CFGR_SW1
+#define RCC_CFGR_SWS0 (1 << 2)
+#define RCC_CFGR_SWS1 (1 << 3)
+#define RCC_CFGR_SWS_MASK 0xC
+#define RCC_CFGR_SWS_HSI 0
+#define RCC_CFGR_SWS_HSE RCC_CFGR_SWS0
+#define RCC_CFGR_SWS_PLL RCC_CFGR_SWS1
+#define RCC_CFGR_HPRE_SHIFT 4
+#define RCC_CFGR_PPRE1_SHIFT 10
+#define RCC_CFGR_PPRE2_SHIFT 13
+
+#define RCC_APB1ENR_PWREN (1 << 28)
+
+/*
+ * RCC USART specific definitions
+ */
+#define RCC_ENR_USART1EN (1 << 4)
+#define RCC_ENR_USART2EN (1 << 17)
+#define RCC_ENR_USART3EN (1 << 18)
+#define RCC_ENR_USART6EN (1 << 5)
+
+/*
+ * Offsets of some PWR registers
+ */
+#define PWR_CR1_ODEN (1 << 16)
+#define PWR_CR1_ODSWEN (1 << 17)
+#define PWR_CSR1_ODRDY (1 << 16)
+#define PWR_CSR1_ODSWRDY (1 << 17)
+
+
+/*
+ * RCC GPIO specific definitions
+ */
+#define RCC_ENR_GPIO_A_EN (1 << 0)
+#define RCC_ENR_GPIO_B_EN (1 << 1)
+#define RCC_ENR_GPIO_C_EN (1 << 2)
+#define RCC_ENR_GPIO_D_EN (1 << 3)
+#define RCC_ENR_GPIO_E_EN (1 << 4)
+#define RCC_ENR_GPIO_F_EN (1 << 5)
+#define RCC_ENR_GPIO_G_EN (1 << 6)
+#define RCC_ENR_GPIO_H_EN (1 << 7)
+#define RCC_ENR_GPIO_I_EN (1 << 8)
+#define RCC_ENR_GPIO_J_EN (1 << 9)
+#define RCC_ENR_GPIO_K_EN (1 << 10)
+
+struct pll_psc {
+ u8 pll_m;
+ u16 pll_n;
+ u8 pll_p;
+ u8 pll_q;
+ u8 ahb_psc;
+ u8 apb1_psc;
+ u8 apb2_psc;
+};
+
+#define AHB_PSC_1 0
+#define AHB_PSC_2 0x8
+#define AHB_PSC_4 0x9
+#define AHB_PSC_8 0xA
+#define AHB_PSC_16 0xB
+#define AHB_PSC_64 0xC
+#define AHB_PSC_128 0xD
+#define AHB_PSC_256 0xE
+#define AHB_PSC_512 0xF
+
+#define APB_PSC_1 0
+#define APB_PSC_2 0x4
+#define APB_PSC_4 0x5
+#define APB_PSC_8 0x6
+#define APB_PSC_16 0x7
+
+#if !defined(CONFIG_STM32_HSE_HZ)
+#error "CONFIG_STM32_HSE_HZ not defined!"
+#else
+#if (CONFIG_STM32_HSE_HZ == 25000000)
+#if (CONFIG_SYS_CLK_FREQ == 200000000)
+/* 200 MHz */
+struct pll_psc sys_pll_psc = {
+ .pll_m = 25,
+ .pll_n = 400,
+ .pll_p = 2,
+ .pll_q = 8,
+ .ahb_psc = AHB_PSC_1,
+ .apb1_psc = APB_PSC_4,
+ .apb2_psc = APB_PSC_2
+};
+#endif
+#else
+#error "No PLL/Prescaler configuration for given CONFIG_STM32_HSE_HZ exists"
+#endif
+#endif
+
+int configure_clocks(void)
+{
+ /* Reset RCC configuration */
+ setbits_le32(&STM32_RCC->cr, RCC_CR_HSION);
+ writel(0, &STM32_RCC->cfgr); /* Reset CFGR */
+ clrbits_le32(&STM32_RCC->cr, (RCC_CR_HSEON | RCC_CR_CSSON
+ | RCC_CR_PLLON));
+ writel(0x24003010, &STM32_RCC->pllcfgr); /* Reset value from RM */
+ clrbits_le32(&STM32_RCC->cr, RCC_CR_HSEBYP);
+ writel(0, &STM32_RCC->cir); /* Disable all interrupts */
+
+ /* Configure for HSE+PLL operation */
+ setbits_le32(&STM32_RCC->cr, RCC_CR_HSEON);
+ while (!(readl(&STM32_RCC->cr) & RCC_CR_HSERDY))
+ ;
+
+ setbits_le32(&STM32_RCC->cfgr, ((
+ sys_pll_psc.ahb_psc << RCC_CFGR_HPRE_SHIFT)
+ | (sys_pll_psc.apb1_psc << RCC_CFGR_PPRE1_SHIFT)
+ | (sys_pll_psc.apb2_psc << RCC_CFGR_PPRE2_SHIFT)));
+
+ /* Configure the main PLL */
+ uint32_t pllcfgr = 0;
+ pllcfgr = RCC_PLLCFGR_PLLSRC; /* pll source HSE */
+ pllcfgr |= sys_pll_psc.pll_m << RCC_PLLCFGR_PLLM_SHIFT;
+ pllcfgr |= sys_pll_psc.pll_n << RCC_PLLCFGR_PLLN_SHIFT;
+ pllcfgr |= ((sys_pll_psc.pll_p >> 1) - 1) << RCC_PLLCFGR_PLLP_SHIFT;
+ pllcfgr |= sys_pll_psc.pll_q << RCC_PLLCFGR_PLLQ_SHIFT;
+ writel(pllcfgr, &STM32_RCC->pllcfgr);
+
+ /* Enable the main PLL */
+ setbits_le32(&STM32_RCC->cr, RCC_CR_PLLON);
+ while (!(readl(&STM32_RCC->cr) & RCC_CR_PLLRDY))
+ ;
+
+ /* Enable high performance mode, System frequency up to 200 MHz */
+ setbits_le32(&STM32_RCC->apb1enr, RCC_APB1ENR_PWREN);
+ setbits_le32(&STM32_PWR->cr1, PWR_CR1_ODEN);
+ /* Infinite wait! */
+ while (!(readl(&STM32_PWR->csr1) & PWR_CSR1_ODRDY))
+ ;
+ /* Enable the Over-drive switch */
+ setbits_le32(&STM32_PWR->cr1, PWR_CR1_ODSWEN);
+ /* Infinite wait! */
+ while (!(readl(&STM32_PWR->csr1) & PWR_CSR1_ODSWRDY))
+ ;
+
+ stm32_flash_latency_cfg(5);
+ clrbits_le32(&STM32_RCC->cfgr, (RCC_CFGR_SW0 | RCC_CFGR_SW1));
+ setbits_le32(&STM32_RCC->cfgr, RCC_CFGR_SW_PLL);
+
+ while ((readl(&STM32_RCC->cfgr) & RCC_CFGR_SWS_MASK) !=
+ RCC_CFGR_SWS_PLL)
+ ;
+
+ return 0;
+}
+
+unsigned long clock_get(enum clock clck)
+{
+ u32 sysclk = 0;
+ u32 shift = 0;
+ /* Prescaler table lookups for clock computation */
+ u8 ahb_psc_table[16] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9
+ };
+ u8 apb_psc_table[8] = {
+ 0, 0, 0, 0, 1, 2, 3, 4
+ };
+
+ if ((readl(&STM32_RCC->cfgr) & RCC_CFGR_SWS_MASK) ==
+ RCC_CFGR_SWS_PLL) {
+ u16 pllm, plln, pllp;
+ pllm = (readl(&STM32_RCC->pllcfgr) & RCC_PLLCFGR_PLLM_MASK);
+ plln = ((readl(&STM32_RCC->pllcfgr) & RCC_PLLCFGR_PLLN_MASK)
+ >> RCC_PLLCFGR_PLLN_SHIFT);
+ pllp = ((((readl(&STM32_RCC->pllcfgr) & RCC_PLLCFGR_PLLP_MASK)
+ >> RCC_PLLCFGR_PLLP_SHIFT) + 1) << 1);
+ sysclk = ((CONFIG_STM32_HSE_HZ / pllm) * plln) / pllp;
+ }
+
+ switch (clck) {
+ case CLOCK_CORE:
+ return sysclk;
+ break;
+ case CLOCK_AHB:
+ shift = ahb_psc_table[(
+ (readl(&STM32_RCC->cfgr) & RCC_CFGR_AHB_PSC_MASK)
+ >> RCC_CFGR_HPRE_SHIFT)];
+ return sysclk >>= shift;
+ break;
+ case CLOCK_APB1:
+ shift = apb_psc_table[(
+ (readl(&STM32_RCC->cfgr) & RCC_CFGR_APB1_PSC_MASK)
+ >> RCC_CFGR_PPRE1_SHIFT)];
+ return sysclk >>= shift;
+ break;
+ case CLOCK_APB2:
+ shift = apb_psc_table[(
+ (readl(&STM32_RCC->cfgr) & RCC_CFGR_APB2_PSC_MASK)
+ >> RCC_CFGR_PPRE2_SHIFT)];
+ return sysclk >>= shift;
+ break;
+ default:
+ return 0;
+ break;
+ }
+}
+
+
void clock_setup(int peripheral)
{
switch (peripheral) {
case USART1_CLOCK_CFG:
setbits_le32(RCC_BASE + RCC_APB2ENR, RCC_ENR_USART1EN);
break;
+ case USART6_CLOCK_CFG:
+ setbits_le32(RCC_BASE + RCC_APB2ENR, RCC_ENR_USART6EN);
+ break;
case GPIO_A_CLOCK_CFG:
setbits_le32(RCC_BASE + RCC_AHB1ENR, RCC_ENR_GPIO_A_EN);
break;
diff --git a/arch/arm/mach-stm32/stm32f7/soc.c b/arch/arm/mach-stm32/stm32f7/soc.c
new file mode 100644
index 0000000..8baee99
--- /dev/null
+++ b/arch/arm/mach-stm32/stm32f7/soc.c
@@ -0,0 +1,76 @@
+/*
+ * (C) Copyright 2015
+ * Kamil Lulko, <kamil.lulko@gmail.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/armv7m.h>
+#include <asm/arch/stm32.h>
+
+u32 get_cpu_rev(void)
+{
+ return 0;
+}
+
+int arch_cpu_init(void)
+{
+ configure_clocks();
+
+ /*
+ * Configure the memory protection unit (MPU)
+ * 0x00000000 - 0xffffffff: Strong-order, Shareable
+ * 0xC0000000 - 0xC0800000: Normal, Outer and inner Non-cacheable
+ */
+
+ /* Disable MPU */
+ writel(0, &V7M_MPU->ctrl);
+
+ writel(
+ 0x00000000 /* address */
+ | 1 << 4 /* VALID */
+ | 0 << 0 /* REGION */
+ , &V7M_MPU->rbar
+ );
+
+ /* Strong-order, Shareable */
+ /* TEX=000, S=1, C=0, B=0*/
+ writel(
+ (V7M_MPU_RASR_XN_ENABLE
+ | V7M_MPU_RASR_AP_RW_RW
+ | 0x01 << V7M_MPU_RASR_S_SHIFT
+ | 0x00 << V7M_MPU_RASR_TEX_SHIFT
+ | V7M_MPU_RASR_SIZE_4GB
+ | V7M_MPU_RASR_EN)
+ , &V7M_MPU->rasr
+ );
+
+ writel(
+ 0xC0000000 /* address */
+ | 1 << 4 /* VALID */
+ | 1 << 0 /* REGION */
+ , &V7M_MPU->rbar
+ );
+
+ /* Normal, Outer and inner Non-cacheable */
+ /* TEX=001, S=0, C=0, B=0*/
+ writel(
+ (V7M_MPU_RASR_XN_ENABLE
+ | V7M_MPU_RASR_AP_RW_RW
+ | 0x01 << V7M_MPU_RASR_TEX_SHIFT
+ | V7M_MPU_RASR_SIZE_8MB
+ | V7M_MPU_RASR_EN)
+ , &V7M_MPU->rasr
+ );
+
+ /* Enable MPU */
+ writel(V7M_MPU_CTRL_ENABLE | V7M_MPU_CTRL_HFNMIENA, &V7M_MPU->ctrl);
+
+ return 0;
+}
+
+void s_init(void)
+{
+}
diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c
index 66e028e..6d9518d 100644
--- a/arch/arm/mach-sunxi/board.c
+++ b/arch/arm/mach-sunxi/board.c
@@ -46,13 +46,15 @@ struct fel_stash fel_stash __attribute__((section(".data")));
static struct mm_region sunxi_mem_map[] = {
{
/* SRAM, MMIO regions */
- .base = 0x0UL,
+ .virt = 0x0UL,
+ .phys = 0x0UL,
.size = 0x40000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
PTE_BLOCK_NON_SHARE
}, {
/* RAM */
- .base = 0x40000000UL,
+ .virt = 0x40000000UL,
+ .phys = 0x40000000UL,
.size = 0x80000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
PTE_BLOCK_INNER_SHARE
@@ -203,7 +205,8 @@ DECLARE_GLOBAL_DATA_PTR;
*/
u32 spl_boot_device(void)
{
- __maybe_unused struct mmc *mmc0, *mmc1;
+ int boot_source;
+
/*
* When booting from the SD card or NAND memory, the "eGON.BT0"
* signature is expected to be found in memory at the address 0x0004
@@ -223,27 +226,19 @@ u32 spl_boot_device(void)
if (!is_boot0_magic(SPL_ADDR + 4)) /* eGON.BT0 */
return BOOT_DEVICE_BOARD;
- /* The BROM will try to boot from mmc0 first, so try that first. */
-#ifdef CONFIG_MMC
- mmc_initialize(gd->bd);
- mmc0 = find_mmc_device(0);
- if (sunxi_mmc_has_egon_boot_signature(mmc0))
+ boot_source = readb(SPL_ADDR + 0x28);
+ switch (boot_source) {
+ case SUNXI_BOOTED_FROM_MMC0:
return BOOT_DEVICE_MMC1;
-#endif
-
- /* Fallback to booting NAND if enabled. */
- if (IS_ENABLED(CONFIG_SPL_NAND_SUPPORT))
+ case SUNXI_BOOTED_FROM_NAND:
return BOOT_DEVICE_NAND;
-
-#ifdef CONFIG_MMC
- if (CONFIG_MMC_SUNXI_SLOT_EXTRA == 2) {
- mmc1 = find_mmc_device(1);
- if (sunxi_mmc_has_egon_boot_signature(mmc1))
- return BOOT_DEVICE_MMC2;
+ case SUNXI_BOOTED_FROM_MMC2:
+ return BOOT_DEVICE_MMC2;
+ case SUNXI_BOOTED_FROM_SPI:
+ return BOOT_DEVICE_SPI;
}
-#endif
- panic("Could not determine boot source\n");
+ panic("Unknown boot source %d\n", boot_source);
return -1; /* Never reached */
}
diff --git a/arch/arm/mach-tegra/arm64-mmu.c b/arch/arm/mach-tegra/arm64-mmu.c
index 501c4f0..7b1d258 100644
--- a/arch/arm/mach-tegra/arm64-mmu.c
+++ b/arch/arm/mach-tegra/arm64-mmu.c
@@ -14,13 +14,15 @@
static struct mm_region tegra_mem_map[] = {
{
- .base = 0x0UL,
+ .virt = 0x0UL,
+ .phys = 0x0UL,
.size = 0x80000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
PTE_BLOCK_NON_SHARE |
PTE_BLOCK_PXN | PTE_BLOCK_UXN
}, {
- .base = 0x80000000UL,
+ .virt = 0x80000000UL,
+ .phys = 0x80000000UL,
.size = 0xff80000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
PTE_BLOCK_INNER_SHARE
diff --git a/arch/arm/mach-tegra/clock.c b/arch/arm/mach-tegra/clock.c
index c50d56d..36eabc8 100644
--- a/arch/arm/mach-tegra/clock.c
+++ b/arch/arm/mach-tegra/clock.c
@@ -510,7 +510,7 @@ unsigned clock_get_rate(enum clock_id clkid)
* @param p post divider(DIVP)
* @param cpcon base PLL charge pump(CPCON)
* @return 0 if ok, -1 on error (the requested PLL is incorrect and cannot
- * be overriden), 1 if PLL is already correct
+ * be overridden), 1 if PLL is already correct
*/
int clock_set_rate(enum clock_id clkid, u32 n, u32 m, u32 p, u32 cpcon)
{
diff --git a/arch/arm/mach-tegra/psci.S b/arch/arm/mach-tegra/psci.S
index b836da1..645d08f 100644
--- a/arch/arm/mach-tegra/psci.S
+++ b/arch/arm/mach-tegra/psci.S
@@ -61,9 +61,6 @@ ENTRY(psci_arch_init)
ldrne r7, [r5]
mcrne p15, 0, r7, c14, c0, 0 @ write CNTFRQ to CPU1..3
- bl psci_get_cpu_stack_top @ stack top => r0
- mov sp, r0
-
bx r6
ENDPROC(psci_arch_init)
@@ -88,12 +85,13 @@ _loop: wfi
ENDPROC(psci_cpu_off)
ENTRY(psci_cpu_on)
- push {lr}
+ push {r4, r5, r6, lr}
+ mov r4, r1
mov r0, r1
- bl psci_get_cpu_stack_top @ get stack top of target CPU
- str r2, [r0] @ store target PC at stack top
- dsb
+ mov r1, r2
+ bl psci_save_target_pc @ store target PC
+ mov r1, r4
ldr r6, =TEGRA_RESET_EXCEPTION_VECTOR
ldr r5, =psci_cpu_entry
@@ -106,9 +104,7 @@ ENTRY(psci_cpu_on)
str r5, [r6, r2]
mov r0, #ARM_PSCI_RET_SUCCESS @ Return PSCI_RET_SUCCESS
- pop {pc}
+ pop {r4, r5, r6, pc}
ENDPROC(psci_cpu_on)
- .globl psci_text_end
-psci_text_end:
.popsection
diff --git a/arch/arm/mach-uniphier/arm64/mem_map.c b/arch/arm/mach-uniphier/arm64/mem_map.c
index 74ef919..67bc4f1 100644
--- a/arch/arm/mach-uniphier/arm64/mem_map.c
+++ b/arch/arm/mach-uniphier/arm64/mem_map.c
@@ -10,14 +10,16 @@
static struct mm_region uniphier_mem_map[] = {
{
- .base = 0x00000000,
+ .virt = 0x00000000,
+ .phys = 0x00000000,
.size = 0x80000000,
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
PTE_BLOCK_NON_SHARE |
PTE_BLOCK_PXN | PTE_BLOCK_UXN
},
{
- .base = 0x80000000,
+ .virt = 0x80000000,
+ .phys = 0x80000000,
.size = 0xc0000000,
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
PTE_BLOCK_INNER_SHARE
diff --git a/arch/nds32/include/asm/io.h b/arch/nds32/include/asm/io.h
index 04708e9..b2c4d0e 100644
--- a/arch/nds32/include/asm/io.h
+++ b/arch/nds32/include/asm/io.h
@@ -344,40 +344,6 @@ static inline void writesl(unsigned int *addr, const void * data, int longlen)
#define insl_p(port, to, len) insl(port, to, len)
/*
- * ioremap and friends.
- *
- * ioremap takes a PCI memory address, as specified in
- * linux/Documentation/IO-mapping.txt. If you want a
- * physical address, use __ioremap instead.
- */
-extern void *__ioremap(unsigned long offset, size_t size, unsigned long flags);
-extern void __iounmap(void *addr);
-
-/*
- * Generic ioremap support.
- *
- * Define:
- * iomem_valid_addr(off,size)
- * iomem_to_phys(off)
- */
-#ifdef iomem_valid_addr
-#define __arch_ioremap(off, sz, nocache) \
-({ \
- unsigned long _off = (off), _size = (sz); \
- void *_ret = (void *)0; \
- if (iomem_valid_addr(_off, _size)) \
- _ret = __ioremap(iomem_to_phys(_off), _size, 0); \
- _ret; \
-})
-
-#define __arch_iounmap __iounmap
-#endif
-
-#define ioremap(off, sz) __arch_ioremap((off), (sz), 0)
-#define ioremap_nocache(off, sz) __arch_ioremap((off), (sz), 1)
-#define iounmap(_addr) __arch_iounmap(_addr)
-
-/*
* DMA-consistent mapping functions. These allocate/free a region of
* uncached, unwrite-buffered mapped memory space for use with DMA
* devices. This is the "generic" version. The PCI specific version
diff --git a/arch/powerpc/cpu/mpc85xx/mp.c b/arch/powerpc/cpu/mpc85xx/mp.c
index 88c8e65..0addf84 100644
--- a/arch/powerpc/cpu/mpc85xx/mp.c
+++ b/arch/powerpc/cpu/mpc85xx/mp.c
@@ -30,7 +30,7 @@ u32 get_my_id()
*/
int hold_cores_in_reset(int verbose)
{
- /* Default to no, overriden by 'y', 'yes', 'Y', 'Yes', or '1' */
+ /* Default to no, overridden by 'y', 'yes', 'Y', 'Yes', or '1' */
if (getenv_yesno("mp_holdoff") == 1) {
if (verbose) {
puts("Secondary cores are being held in reset.\n");
diff --git a/arch/powerpc/cpu/ppc4xx/start.S b/arch/powerpc/cpu/ppc4xx/start.S
index b432b18..5647d71 100644
--- a/arch/powerpc/cpu/ppc4xx/start.S
+++ b/arch/powerpc/cpu/ppc4xx/start.S
@@ -144,7 +144,7 @@
#endif
/*
- * Unless otherwise overriden, enable two 128MB cachable instruction regions
+ * Unless otherwise overridden, enable two 128MB cachable instruction regions
* at CONFIG_SYS_SDRAM_BASE and another 128MB cacheable instruction region covering
* NOR flash at CONFIG_SYS_FLASH_BASE. Disable all cacheable data regions.
*/
diff --git a/arch/powerpc/include/asm/arch-mpc85xx/gpio.h b/arch/powerpc/include/asm/arch-mpc85xx/gpio.h
index 41b6677..76faa22 100644
--- a/arch/powerpc/include/asm/arch-mpc85xx/gpio.h
+++ b/arch/powerpc/include/asm/arch-mpc85xx/gpio.h
@@ -18,4 +18,10 @@
#include <asm/mpc85xx_gpio.h>
#endif
+struct mpc85xx_gpio_plat {
+ ulong addr;
+ unsigned long size;
+ uint ngpios;
+};
+
#endif
diff --git a/arch/powerpc/include/asm/status_led.h b/arch/powerpc/include/asm/status_led.h
index 4416190..260a831 100644
--- a/arch/powerpc/include/asm/status_led.h
+++ b/arch/powerpc/include/asm/status_led.h
@@ -7,7 +7,7 @@
#ifndef __ASM_STATUS_LED_H__
#define __ASM_STATUS_LED_H__
-/* if not overriden */
+/* if not overridden */
#ifndef CONFIG_BOARD_SPECIFIC_LED
# if defined(CONFIG_8xx)
# include <mpc8xx.h>
diff --git a/arch/sandbox/Kconfig b/arch/sandbox/Kconfig
index a8a90cb..d4c1ee0 100644
--- a/arch/sandbox/Kconfig
+++ b/arch/sandbox/Kconfig
@@ -10,8 +10,13 @@ config SYS_BOARD
config SYS_CPU
default "sandbox"
+config SANDBOX_SPL
+ bool "Enable SPL for sandbox"
+ select SUPPORT_SPL
+
config SYS_CONFIG_NAME
- default "sandbox"
+ default "sandbox_spl" if SANDBOX_SPL
+ default "sandbox" if !SANDBOX_SPL
config PCI
bool "PCI support"
diff --git a/arch/sandbox/config.mk b/arch/sandbox/config.mk
index 16fd6d5..6d62abb 100644
--- a/arch/sandbox/config.mk
+++ b/arch/sandbox/config.mk
@@ -20,4 +20,9 @@ cmd_u-boot__ = $(CC) -o $@ -Wl,-T u-boot.lds \
-Wl,--start-group $(u-boot-main) -Wl,--end-group \
$(PLATFORM_LIBS) -Wl,-Map -Wl,u-boot.map
+cmd_u-boot-spl = (cd $(obj) && $(CC) -o $(SPL_BIN) -Wl,-T u-boot-spl.lds \
+ -Wl,--start-group $(patsubst $(obj)/%,%,$(u-boot-spl-main)) \
+ $(patsubst $(obj)/%,%,$(u-boot-spl-platdata)) -Wl,--end-group \
+ $(PLATFORM_LIBS) -Wl,-Map -Wl,u-boot-spl.map -Wl,--gc-sections)
+
CONFIG_ARCH_DEVICE_TREE := sandbox
diff --git a/arch/sandbox/cpu/Makefile b/arch/sandbox/cpu/Makefile
index 1b42fee..db43633 100644
--- a/arch/sandbox/cpu/Makefile
+++ b/arch/sandbox/cpu/Makefile
@@ -8,6 +8,7 @@
#
obj-y := cpu.o os.o start.o state.o
+obj-$(CONFIG_SPL_BUILD) += spl.o
obj-$(CONFIG_ETH_SANDBOX_RAW) += eth-raw-os.o
obj-$(CONFIG_SANDBOX_SDL) += sdl.o
diff --git a/arch/sandbox/cpu/cpu.c b/arch/sandbox/cpu/cpu.c
index 196f3e1..2def722 100644
--- a/arch/sandbox/cpu/cpu.c
+++ b/arch/sandbox/cpu/cpu.c
@@ -4,10 +4,12 @@
*/
#define DEBUG
#include <common.h>
-#include <dm/root.h>
+#include <errno.h>
+#include <libfdt.h>
#include <os.h>
#include <asm/io.h>
#include <asm/state.h>
+#include <dm/root.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -55,7 +57,7 @@ int cleanup_before_linux_select(int flags)
void *map_physmem(phys_addr_t paddr, unsigned long len, unsigned long flags)
{
-#ifdef CONFIG_PCI
+#if defined(CONFIG_PCI) && !defined(CONFIG_SPL_BUILD)
unsigned long plen = len;
void *ptr;
diff --git a/arch/sandbox/cpu/os.c b/arch/sandbox/cpu/os.c
index 8a4d719..2d63dd8 100644
--- a/arch/sandbox/cpu/os.c
+++ b/arch/sandbox/cpu/os.c
@@ -541,6 +541,57 @@ int os_jump_to_image(const void *dest, int size)
return unlink(fname);
}
+int os_find_u_boot(char *fname, int maxlen)
+{
+ struct sandbox_state *state = state_get_current();
+ const char *progname = state->argv[0];
+ int len = strlen(progname);
+ char *p;
+ int fd;
+
+ if (len >= maxlen || len < 4)
+ return -ENOSPC;
+
+ /* Look for 'u-boot' in the same directory as 'u-boot-spl' */
+ strcpy(fname, progname);
+ if (!strcmp(fname + len - 4, "-spl")) {
+ fname[len - 4] = '\0';
+ fd = os_open(fname, O_RDONLY);
+ if (fd >= 0) {
+ close(fd);
+ return 0;
+ }
+ }
+
+ /* Look for 'u-boot' in the parent directory of spl/ */
+ p = strstr(fname, "/spl/");
+ if (p) {
+ strcpy(p, p + 4);
+ fd = os_open(fname, O_RDONLY);
+ if (fd >= 0) {
+ close(fd);
+ return 0;
+ }
+ }
+
+ return -ENOENT;
+}
+
+int os_spl_to_uboot(const char *fname)
+{
+ struct sandbox_state *state = state_get_current();
+ char *argv[state->argc + 1];
+ int ret;
+
+ memcpy(argv, state->argv, sizeof(char *) * (state->argc + 1));
+ argv[0] = (char *)fname;
+ ret = execv(fname, argv);
+ if (ret)
+ return ret;
+
+ return unlink(fname);
+}
+
void os_localtime(struct rtc_time *rt)
{
time_t t = time(NULL);
diff --git a/arch/sandbox/cpu/spl.c b/arch/sandbox/cpu/spl.c
new file mode 100644
index 0000000..e8349c0
--- /dev/null
+++ b/arch/sandbox/cpu/spl.c
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2016 Google, Inc
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <os.h>
+#include <spl.h>
+#include <asm/spl.h>
+#include <asm/state.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+void board_init_f(ulong flag)
+{
+ struct sandbox_state *state = state_get_current();
+
+ gd->arch.ram_buf = state->ram_buf;
+ gd->ram_size = state->ram_size;
+}
+
+u32 spl_boot_device(void)
+{
+ return BOOT_DEVICE_BOARD;
+}
+
+void spl_board_announce_boot_device(void)
+{
+ char fname[256];
+ int ret;
+
+ ret = os_find_u_boot(fname, sizeof(fname));
+ if (ret) {
+ printf("(%s not found, error %d)\n", fname, ret);
+ return;
+ }
+ printf("%s\n", fname);
+}
+
+int spl_board_load_image(void)
+{
+ char fname[256];
+ int ret;
+
+ ret = os_find_u_boot(fname, sizeof(fname));
+ if (ret)
+ return ret;
+
+ /* Hopefully this will not return */
+ return os_spl_to_uboot(fname);
+}
+
+void spl_board_init(void)
+{
+ struct udevice *dev;
+
+ preloader_console_init();
+
+ /*
+ * Scan all the devices so that we can output their platform data. See
+ * sandbox_spl_probe().
+ */
+ for (uclass_first_device(UCLASS_MISC, &dev);
+ dev;
+ uclass_next_device(&dev))
+ ;
+}
diff --git a/arch/sandbox/cpu/start.c b/arch/sandbox/cpu/start.c
index 969618e..6e4ec01 100644
--- a/arch/sandbox/cpu/start.c
+++ b/arch/sandbox/cpu/start.c
@@ -73,6 +73,7 @@ static int sandbox_cmdline_cb_help(struct sandbox_state *state, const char *arg)
}
SANDBOX_CMDLINE_OPT_SHORT(help, 'h', 0, "Display help");
+#ifndef CONFIG_SPL_BUILD
int sandbox_main_loop_init(void)
{
struct sandbox_state *state = state_get_current();
@@ -97,6 +98,7 @@ int sandbox_main_loop_init(void)
return 0;
}
+#endif
static int sandbox_cmdline_cb_boot(struct sandbox_state *state,
const char *arg)
diff --git a/arch/sandbox/cpu/u-boot-spl.lds b/arch/sandbox/cpu/u-boot-spl.lds
new file mode 100644
index 0000000..7e92b4a
--- /dev/null
+++ b/arch/sandbox/cpu/u-boot-spl.lds
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2011-2012 The Chromium OS Authors.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+SECTIONS
+{
+
+ . = ALIGN(4);
+ .u_boot_list : {
+ KEEP(*(SORT(.u_boot_list*)));
+ }
+
+ __u_boot_sandbox_option_start = .;
+ _u_boot_sandbox_getopt : { *(.u_boot_sandbox_getopt) }
+ __u_boot_sandbox_option_end = .;
+
+ __bss_start = .;
+}
+
+INSERT BEFORE .data;
diff --git a/arch/sandbox/dts/sandbox.dts b/arch/sandbox/dts/sandbox.dts
index 2ae4014..e6d336f 100644
--- a/arch/sandbox/dts/sandbox.dts
+++ b/arch/sandbox/dts/sandbox.dts
@@ -172,6 +172,37 @@
};
};
+ spl-test {
+ u-boot,dm-pre-reloc;
+ compatible = "sandbox,spl-test";
+ boolval;
+ intval = <1>;
+ intarray = <2 3 4>;
+ byteval = [05];
+ bytearray = [06];
+ longbytearray = [09 0a 0b 0c 0d 0e 0f 10 11];
+ stringval = "message";
+ stringarray = "multi-word", "message";
+ };
+
+ spl-test2 {
+ u-boot,dm-pre-reloc;
+ compatible = "sandbox,spl-test";
+ intval = <3>;
+ intarray = <5>;
+ byteval = [08];
+ bytearray = [01 23 34];
+ longbytearray = [09 0a 0b 0c];
+ stringval = "message2";
+ stringarray = "another", "multi-word", "message";
+ };
+
+ spl-test3 {
+ u-boot,dm-pre-reloc;
+ compatible = "sandbox,spl-test";
+ stringarray = "one";
+ };
+
square {
compatible = "demo-shape";
colour = "blue";
diff --git a/arch/sandbox/include/asm/spl.h b/arch/sandbox/include/asm/spl.h
new file mode 100644
index 0000000..59f2401
--- /dev/null
+++ b/arch/sandbox/include/asm/spl.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2016 Google, Inc
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __asm_spl_h
+#define __asm_spl_h
+
+#define CONFIG_SPL_BOARD_LOAD_IMAGE
+
+/**
+ * Board-specific load method for boards that have a special way of loading
+ * U-Boot, which does not fit with the existing SPL code.
+ *
+ * @return 0 on success, negative errno value on failure.
+ */
+int spl_board_load_image(void);
+
+enum {
+ BOOT_DEVICE_BOARD,
+};
+
+#endif
diff --git a/arch/sandbox/lib/Makefile b/arch/sandbox/lib/Makefile
index 96761e2..7820c55 100644
--- a/arch/sandbox/lib/Makefile
+++ b/arch/sandbox/lib/Makefile
@@ -8,5 +8,7 @@
#
obj-y += interrupts.o
+ifndef CONFIG_SPL_BUILD
obj-$(CONFIG_PCI) += pci_io.o
+endif
obj-$(CONFIG_CMD_BOOTM) += bootm.o
diff --git a/arch/sandbox/lib/bootm.c b/arch/sandbox/lib/bootm.c
index d49c927..0c9a797 100644
--- a/arch/sandbox/lib/bootm.c
+++ b/arch/sandbox/lib/bootm.c
@@ -56,7 +56,7 @@ int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images)
bootstage_mark(BOOTSTAGE_ID_RUN_OS);
printf("## Transferring control to Linux (at address %08lx)...\n",
images->ep);
- reset_cpu(0);
+ printf("sandbox: continuing, as we cannot run Linux\n");
}
return 0;
diff --git a/arch/sh/include/asm/io.h b/arch/sh/include/asm/io.h
index 0a00db3..5dc27be 100644
--- a/arch/sh/include/asm/io.h
+++ b/arch/sh/include/asm/io.h
@@ -128,39 +128,6 @@ extern void __raw_readsl(unsigned int addr, void *data, int longlen);
#define in_8(port) inb(port)
#define in_le16(port) inw(port)
#define in_le32(port) inl(port)
-/*
- * ioremap and friends.
- *
- * ioremap takes a PCI memory address, as specified in
- * linux/Documentation/IO-mapping.txt. If you want a
- * physical address, use __ioremap instead.
- */
-extern void *__ioremap(unsigned long offset, size_t size, unsigned long flags);
-extern void __iounmap(void *addr);
-
-/*
- * Generic ioremap support.
- *
- * Define:
- * iomem_valid_addr(off,size)
- * iomem_to_phys(off)
- */
-#ifdef iomem_valid_addr
-#define __arch_ioremap(off, sz, nocache) \
-({ \
- unsigned long _off = (off), _size = (sz); \
- void *_ret = (void *)0; \
- if (iomem_valid_addr(_off, _size)) \
- _ret = __ioremap(iomem_to_phys(_off), _size, 0); \
- _ret; \
-})
-
-#define __arch_iounmap __iounmap
-#endif
-
-#define ioremap(off, sz) __arch_ioremap((off), (sz), 0)
-#define ioremap_nocache(off, sz) __arch_ioremap((off), (sz), 1)
-#define iounmap(_addr) __arch_iounmap(_addr)
/*
* DMA-consistent mapping functions. These allocate/free a region of
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 29d2307..29d1120 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -8,6 +8,9 @@ choice
prompt "Mainboard vendor"
default VENDOR_EMULATION
+config VENDOR_ADVANTECH
+ bool "advantech"
+
config VENDOR_CONGATEC
bool "congatec"
@@ -29,6 +32,7 @@ config VENDOR_INTEL
endchoice
# board-specific options below
+source "board/advantech/Kconfig"
source "board/congatec/Kconfig"
source "board/coreboot/Kconfig"
source "board/efi/Kconfig"
diff --git a/arch/x86/cpu/baytrail/Kconfig b/arch/x86/cpu/baytrail/Kconfig
index 407feb2..1c8ac37 100644
--- a/arch/x86/cpu/baytrail/Kconfig
+++ b/arch/x86/cpu/baytrail/Kconfig
@@ -7,3 +7,14 @@
config INTEL_BAYTRAIL
bool
select HAVE_FSP if !EFI
+
+if INTEL_BAYTRAIL
+config INTERNAL_UART
+ bool "Enable the SoC integrated legacy UART"
+ help
+ There is a legacy UART integrated into the Bay Trail SoC.
+ A maximum baud rate of 115200 bps is supported. For this
+ reason, it is recommended that the UART port be used for
+ debug purposes only, eg: U-Boot console.
+
+endif
diff --git a/arch/x86/cpu/baytrail/acpi.c b/arch/x86/cpu/baytrail/acpi.c
index 5ee4868..fa92d88 100644
--- a/arch/x86/cpu/baytrail/acpi.c
+++ b/arch/x86/cpu/baytrail/acpi.c
@@ -5,10 +5,14 @@
*/
#include <common.h>
+#include <cpu.h>
+#include <dm.h>
+#include <dm/uclass-internal.h>
#include <asm/acpi_table.h>
#include <asm/ioapic.h>
#include <asm/mpspec.h>
#include <asm/tables.h>
+#include <asm/arch/global_nvs.h>
#include <asm/arch/iomap.h>
void acpi_create_fadt(struct acpi_fadt *fadt, struct acpi_facs *facs,
@@ -161,3 +165,25 @@ u32 acpi_fill_madt(u32 current)
return current;
}
+
+void acpi_create_gnvs(struct acpi_global_nvs *gnvs)
+{
+ struct udevice *dev;
+ int ret;
+
+ /* at least we have one processor */
+ gnvs->pcnt = 1;
+ /* override the processor count with actual number */
+ ret = uclass_find_first_device(UCLASS_CPU, &dev);
+ if (ret == 0 && dev != NULL) {
+ ret = cpu_get_count(dev);
+ if (ret > 0)
+ gnvs->pcnt = ret;
+ }
+
+ /* determine whether internal uart is on */
+ if (IS_ENABLED(CONFIG_INTERNAL_UART))
+ gnvs->iuart_en = 1;
+ else
+ gnvs->iuart_en = 0;
+}
diff --git a/arch/x86/cpu/ivybridge/lpc.c b/arch/x86/cpu/ivybridge/lpc.c
index ff1faa5..4e0be2a 100644
--- a/arch/x86/cpu/ivybridge/lpc.c
+++ b/arch/x86/cpu/ivybridge/lpc.c
@@ -424,8 +424,6 @@ static void set_spi_speed(void)
static int lpc_init_extra(struct udevice *dev)
{
struct udevice *pch = dev->parent;
- const void *blob = gd->fdt_blob;
- int node;
debug("pch: lpc_init\n");
dm_pci_write_bar32(pch, 0, 0);
@@ -434,10 +432,6 @@ static int lpc_init_extra(struct udevice *dev)
dm_pci_write_bar32(pch, 3, 0x800);
dm_pci_write_bar32(pch, 4, 0x900);
- node = fdtdec_next_compatible(blob, 0, COMPAT_INTEL_PCH);
- if (node < 0)
- return -ENOENT;
-
/* Set the value for PCI command register. */
dm_pci_write_config16(pch, PCI_COMMAND, 0x000f);
diff --git a/arch/x86/cpu/ivybridge/sdram.c b/arch/x86/cpu/ivybridge/sdram.c
index 9d9f63d..e0b06b5 100644
--- a/arch/x86/cpu/ivybridge/sdram.c
+++ b/arch/x86/cpu/ivybridge/sdram.c
@@ -458,6 +458,11 @@ int dram_init(void)
struct udevice *dev, *me_dev;
int ret;
+ /* We need the pinctrl set up early */
+ ret = syscon_get_by_driver_data(X86_SYSCON_PINCONF, &dev);
+ if (ret)
+ return ret;
+
ret = uclass_first_device_err(UCLASS_NORTHBRIDGE, &dev);
if (ret)
return ret;
diff --git a/arch/x86/cpu/quark/acpi.c b/arch/x86/cpu/quark/acpi.c
index 8f69829..3968f7a 100644
--- a/arch/x86/cpu/quark/acpi.c
+++ b/arch/x86/cpu/quark/acpi.c
@@ -9,6 +9,7 @@
#include <asm/ioapic.h>
#include <asm/mpspec.h>
#include <asm/tables.h>
+#include <asm/arch/global_nvs.h>
#include <asm/arch/iomap.h>
void acpi_create_fadt(struct acpi_fadt *fadt, struct acpi_facs *facs,
@@ -161,3 +162,9 @@ u32 acpi_fill_madt(u32 current)
return current;
}
+
+void acpi_create_gnvs(struct acpi_global_nvs *gnvs)
+{
+ /* quark is a uni-processor */
+ gnvs->pcnt = 1;
+}
diff --git a/arch/x86/dts/Makefile b/arch/x86/dts/Makefile
index 23156bb..4f07f41 100644
--- a/arch/x86/dts/Makefile
+++ b/arch/x86/dts/Makefile
@@ -14,7 +14,8 @@ dtb-y += bayleybay.dtb \
minnowmax.dtb \
qemu-x86_i440fx.dtb \
qemu-x86_q35.dtb \
- broadwell_som-6896.dtb
+ broadwell_som-6896.dtb \
+ baytrail_som-db5800-som-6867.dtb
targets += $(dtb-y)
diff --git a/arch/x86/dts/baytrail_som-db5800-som-6867.dts b/arch/x86/dts/baytrail_som-db5800-som-6867.dts
new file mode 100644
index 0000000..64e2e52
--- /dev/null
+++ b/arch/x86/dts/baytrail_som-db5800-som-6867.dts
@@ -0,0 +1,289 @@
+/*
+ * Copyright (C) 2014, Bin Meng <bmeng.cn@gmail.com>
+ * Copyright (C) 2016, George McCollister <george.mccollister@gmail.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/x86-gpio.h>
+#include <dt-bindings/interrupt-router/intel-irq.h>
+
+/include/ "skeleton.dtsi"
+/include/ "serial.dtsi"
+/include/ "rtc.dtsi"
+/include/ "tsc_timer.dtsi"
+
+/ {
+ model = "Advantech SOM-DB5800-SOM-6867";
+ compatible = "advantech,som-db5800-som-6867", "intel,baytrail";
+
+ aliases {
+ serial0 = &serial;
+ spi0 = &spi;
+ };
+
+ config {
+ silent_console = <0>;
+ };
+
+ pch_pinctrl {
+ compatible = "intel,x86-pinctrl";
+ reg = <0 0>;
+
+ /* HDA_RSTB */
+ soc_gpio_s0_8@0 {
+ pad-offset = <0x220>;
+ mode-func = <2>;
+ };
+
+ /* HDA_SYNC */
+ soc_gpio_s0_9@0 {
+ pad-offset = <0x250>;
+ mode-func = <2>;
+ pull-assign = <1>;
+ };
+
+ /* HDA_CLK */
+ soc_gpio_s0_10@0 {
+ pad-offset = <0x240>;
+ mode-func = <2>;
+ };
+
+ /* HDA_SDO */
+ soc_gpio_s0_11@0 {
+ pad-offset = <0x260>;
+ mode-func = <2>;
+ pull-assign = <1>;
+ };
+
+ /* HDA_SDI0 */
+ soc_gpio_s0_12@0 {
+ pad-offset = <0x270>;
+ mode-func = <2>;
+ };
+ };
+
+ chosen {
+ stdout-path = "/serial";
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "intel,baytrail-cpu";
+ reg = <0>;
+ intel,apic-id = <0>;
+ };
+
+ cpu@1 {
+ device_type = "cpu";
+ compatible = "intel,baytrail-cpu";
+ reg = <1>;
+ intel,apic-id = <2>;
+ };
+
+ cpu@2 {
+ device_type = "cpu";
+ compatible = "intel,baytrail-cpu";
+ reg = <2>;
+ intel,apic-id = <4>;
+ };
+
+ cpu@3 {
+ device_type = "cpu";
+ compatible = "intel,baytrail-cpu";
+ reg = <3>;
+ intel,apic-id = <6>;
+ };
+
+ };
+
+ pci {
+ compatible = "intel,pci-baytrail", "pci-x86";
+ #address-cells = <3>;
+ #size-cells = <2>;
+ u-boot,dm-pre-reloc;
+ ranges = <0x02000000 0x0 0x80000000 0x80000000 0 0x40000000
+ 0x42000000 0x0 0xc0000000 0xc0000000 0 0x20000000
+ 0x01000000 0x0 0x2000 0x2000 0 0xe000>;
+
+ pch@1f,0 {
+ reg = <0x0000f800 0 0 0 0>;
+ compatible = "pci8086,0f1c", "intel,pch9";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ irq-router {
+ compatible = "intel,irq-router";
+ intel,pirq-config = "ibase";
+ intel,ibase-offset = <0x50>;
+ intel,actl-addr = <0>;
+ intel,pirq-link = <8 8>;
+ intel,pirq-mask = <0xdee0>;
+ intel,pirq-routing = <
+ /* BayTrail PCI devices */
+ PCI_BDF(0, 2, 0) INTA PIRQA
+ PCI_BDF(0, 3, 0) INTA PIRQA
+ PCI_BDF(0, 16, 0) INTA PIRQA
+ PCI_BDF(0, 17, 0) INTA PIRQA
+ PCI_BDF(0, 18, 0) INTA PIRQA
+ PCI_BDF(0, 19, 0) INTA PIRQA
+ PCI_BDF(0, 20, 0) INTA PIRQA
+ PCI_BDF(0, 21, 0) INTA PIRQA
+ PCI_BDF(0, 22, 0) INTA PIRQA
+ PCI_BDF(0, 23, 0) INTA PIRQA
+ PCI_BDF(0, 24, 0) INTA PIRQA
+ PCI_BDF(0, 24, 1) INTC PIRQC
+ PCI_BDF(0, 24, 2) INTD PIRQD
+ PCI_BDF(0, 24, 3) INTB PIRQB
+ PCI_BDF(0, 24, 4) INTA PIRQA
+ PCI_BDF(0, 24, 5) INTC PIRQC
+ PCI_BDF(0, 24, 6) INTD PIRQD
+ PCI_BDF(0, 24, 7) INTB PIRQB
+ PCI_BDF(0, 26, 0) INTA PIRQA
+ PCI_BDF(0, 27, 0) INTA PIRQA
+ PCI_BDF(0, 28, 0) INTA PIRQA
+ PCI_BDF(0, 28, 1) INTB PIRQB
+ PCI_BDF(0, 28, 2) INTC PIRQC
+ PCI_BDF(0, 28, 3) INTD PIRQD
+ PCI_BDF(0, 29, 0) INTA PIRQA
+ PCI_BDF(0, 30, 0) INTA PIRQA
+ PCI_BDF(0, 30, 1) INTD PIRQD
+ PCI_BDF(0, 30, 2) INTB PIRQB
+ PCI_BDF(0, 30, 3) INTC PIRQC
+ PCI_BDF(0, 30, 4) INTD PIRQD
+ PCI_BDF(0, 30, 5) INTB PIRQB
+ PCI_BDF(0, 31, 3) INTB PIRQB
+
+ /*
+ * PCIe root ports downstream
+ * interrupts
+ */
+ PCI_BDF(1, 0, 0) INTA PIRQA
+ PCI_BDF(1, 0, 0) INTB PIRQB
+ PCI_BDF(1, 0, 0) INTC PIRQC
+ PCI_BDF(1, 0, 0) INTD PIRQD
+ PCI_BDF(2, 0, 0) INTA PIRQB
+ PCI_BDF(2, 0, 0) INTB PIRQC
+ PCI_BDF(2, 0, 0) INTC PIRQD
+ PCI_BDF(2, 0, 0) INTD PIRQA
+ PCI_BDF(3, 0, 0) INTA PIRQC
+ PCI_BDF(3, 0, 0) INTB PIRQD
+ PCI_BDF(3, 0, 0) INTC PIRQA
+ PCI_BDF(3, 0, 0) INTD PIRQB
+ PCI_BDF(4, 0, 0) INTA PIRQD
+ PCI_BDF(4, 0, 0) INTB PIRQA
+ PCI_BDF(4, 0, 0) INTC PIRQB
+ PCI_BDF(4, 0, 0) INTD PIRQC
+ >;
+ };
+
+ spi: spi {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "intel,ich9-spi";
+ spi-flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0>;
+ compatible = "macronix,mx25l6405d",
+ "spi-flash";
+ memory-map = <0xff800000 0x00800000>;
+ rw-mrc-cache {
+ label = "rw-mrc-cache";
+ reg = <0x006f0000 0x00010000>;
+ };
+ };
+ };
+
+ gpioa {
+ compatible = "intel,ich6-gpio";
+ u-boot,dm-pre-reloc;
+ reg = <0 0x20>;
+ bank-name = "A";
+ };
+
+ gpiob {
+ compatible = "intel,ich6-gpio";
+ u-boot,dm-pre-reloc;
+ reg = <0x20 0x20>;
+ bank-name = "B";
+ };
+
+ gpioc {
+ compatible = "intel,ich6-gpio";
+ u-boot,dm-pre-reloc;
+ reg = <0x40 0x20>;
+ bank-name = "C";
+ };
+
+ gpiod {
+ compatible = "intel,ich6-gpio";
+ u-boot,dm-pre-reloc;
+ reg = <0x60 0x20>;
+ bank-name = "D";
+ };
+
+ gpioe {
+ compatible = "intel,ich6-gpio";
+ u-boot,dm-pre-reloc;
+ reg = <0x80 0x20>;
+ bank-name = "E";
+ };
+
+ gpiof {
+ compatible = "intel,ich6-gpio";
+ u-boot,dm-pre-reloc;
+ reg = <0xA0 0x20>;
+ bank-name = "F";
+ };
+ };
+ };
+
+ fsp {
+ compatible = "intel,baytrail-fsp";
+ fsp,mrc-init-tseg-size = <0>;
+ fsp,mrc-init-mmio-size = <0x800>;
+ fsp,mrc-init-spd-addr1 = <0xa0>;
+ fsp,mrc-init-spd-addr2 = <0xa2>;
+ fsp,enable-spi;
+ fsp,enable-sata;
+ fsp,sata-mode = <1>;
+ fsp,enable-azalia;
+ fsp,lpss-sio-enable-pci-mode;
+ fsp,enable-dma0;
+ fsp,enable-dma1;
+ fsp,enable-i2c0;
+ fsp,enable-i2c1;
+ fsp,enable-i2c2;
+ fsp,enable-i2c3;
+ fsp,enable-i2c4;
+ fsp,enable-i2c5;
+ fsp,enable-i2c6;
+ fsp,enable-pwm0;
+ fsp,enable-pwm1;
+ fsp,igd-dvmt50-pre-alloc = <2>;
+ fsp,aperture-size = <2>;
+ fsp,gtt-size = <2>;
+ fsp,scc-enable-pci-mode;
+ fsp,os-selection = <4>;
+ fsp,enable-igd;
+ fsp,serial-debug-port-address = <0x3f8>;
+ fsp,serial-debug-port-type = <1>;
+ };
+
+ microcode {
+ update@0 {
+#include "microcode/m0130673325.dtsi"
+ };
+ update@1 {
+#include "microcode/m0130679907.dtsi"
+ };
+ };
+
+};
diff --git a/arch/x86/include/asm/acpi/global_nvs.h b/arch/x86/include/asm/acpi/global_nvs.h
new file mode 100644
index 0000000..7f2ffd4
--- /dev/null
+++ b/arch/x86/include/asm/acpi/global_nvs.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2016, Bin Meng <bmeng.cn@gmail.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _ACPI_GNVS_H_
+#define _ACPI_GNVS_H_
+
+/*
+ * This file provides two ACPI global NVS macros: ACPI_GNVS_ADDR and
+ * ACPI_GNVS_SIZE. They are to be used in platform's global_nvs.asl file
+ * to declare the GNVS OperationRegion, as well as write_acpi_tables()
+ * for the GNVS address runtime fix up.
+ */
+#define ACPI_GNVS_ADDR 0xdeadbeef
+#define ACPI_GNVS_SIZE 0x100
+
+#endif /* _ACPI_GNVS_H_ */
diff --git a/arch/x86/include/asm/acpi_table.h b/arch/x86/include/asm/acpi_table.h
index 56aa282..caff4d8 100644
--- a/arch/x86/include/asm/acpi_table.h
+++ b/arch/x86/include/asm/acpi_table.h
@@ -299,6 +299,9 @@ struct acpi_mcfg_mmconfig {
/* PM1_CNT bit defines */
#define PM1_CNT_SCI_EN (1 << 0)
+/* ACPI global NVS structure */
+struct acpi_global_nvs;
+
/* These can be used by the target port */
void acpi_fill_header(struct acpi_table_header *header, char *signature);
@@ -312,4 +315,5 @@ int acpi_create_madt_irqoverride(struct acpi_madt_irqoverride *irqoverride,
int acpi_create_madt_lapic_nmi(struct acpi_madt_lapic_nmi *lapic_nmi,
u8 cpu, u16 flags, u8 lint);
u32 acpi_fill_madt(u32 current);
+void acpi_create_gnvs(struct acpi_global_nvs *gnvs);
u32 write_acpi_tables(u32 start);
diff --git a/arch/x86/include/asm/arch-baytrail/acpi/global_nvs.asl b/arch/x86/include/asm/arch-baytrail/acpi/global_nvs.asl
new file mode 100644
index 0000000..a28d4df
--- /dev/null
+++ b/arch/x86/include/asm/arch-baytrail/acpi/global_nvs.asl
@@ -0,0 +1,15 @@
+/*
+ * Copyright (C) 2016 Bin Meng <bmeng.cn@gmail.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <asm/acpi/global_nvs.h>
+
+OperationRegion(GNVS, SystemMemory, ACPI_GNVS_ADDR, ACPI_GNVS_SIZE)
+Field(GNVS, ByteAcc, NoLock, Preserve)
+{
+ Offset (0x00),
+ PCNT, 8, /* processor count */
+ IURE, 8, /* internal UART enabled */
+}
diff --git a/arch/x86/include/asm/arch-baytrail/acpi/lpc.asl b/arch/x86/include/asm/arch-baytrail/acpi/lpc.asl
index 22f0d68..fe34d32 100644
--- a/arch/x86/include/asm/arch-baytrail/acpi/lpc.asl
+++ b/arch/x86/include/asm/arch-baytrail/acpi/lpc.asl
@@ -119,17 +119,14 @@ Device (LPCB)
Method(_STA, 0, Serialized)
{
- /*
- * TODO:
- *
- * Need to hide the internal UART depending on whether
- * internal UART is enabled or not so that external
- * SuperIO UART can be exposed to system.
- */
- Store(1, UI3E)
- Store(1, UI4E)
- Store(1, C1EN)
- Return (STA_VISIBLE)
+ If (LEqual(IURE, 1)) {
+ Store(1, UI3E)
+ Store(1, UI4E)
+ Store(1, C1EN)
+ Return (STA_VISIBLE)
+ } Else {
+ Return (STA_MISSING)
+ }
}
diff --git a/arch/x86/include/asm/arch-baytrail/acpi/platform.asl b/arch/x86/include/asm/arch-baytrail/acpi/platform.asl
index 6bc82ec..a80d2c0 100644
--- a/arch/x86/include/asm/arch-baytrail/acpi/platform.asl
+++ b/arch/x86/include/asm/arch-baytrail/acpi/platform.asl
@@ -22,6 +22,9 @@ Method(_WAK, 1)
Return (Package() {0, 0})
}
+/* ACPI global NVS */
+#include "global_nvs.asl"
+
/* TODO: add CPU ASL support */
Scope (\_SB)
diff --git a/arch/x86/include/asm/arch-baytrail/global_nvs.h b/arch/x86/include/asm/arch-baytrail/global_nvs.h
new file mode 100644
index 0000000..56e3626
--- /dev/null
+++ b/arch/x86/include/asm/arch-baytrail/global_nvs.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2016, Bin Meng <bmeng.cn@gmail.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _GLOBAL_NVS_H_
+#define _GLOBAL_NVS_H_
+
+struct __packed acpi_global_nvs {
+ u8 pcnt; /* processor count */
+ u8 iuart_en; /* internal UART enabled */
+
+ /*
+ * Add padding so sizeof(struct acpi_global_nvs) == 0x100.
+ * This must match the size defined in the global_nvs.asl.
+ */
+ u8 rsvd[254];
+};
+
+#endif /* _GLOBAL_NVS_H_ */
diff --git a/arch/x86/include/asm/arch-quark/acpi/global_nvs.asl b/arch/x86/include/asm/arch-quark/acpi/global_nvs.asl
new file mode 100644
index 0000000..6f0435e
--- /dev/null
+++ b/arch/x86/include/asm/arch-quark/acpi/global_nvs.asl
@@ -0,0 +1,14 @@
+/*
+ * Copyright (C) 2016 Bin Meng <bmeng.cn@gmail.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <asm/acpi/global_nvs.h>
+
+OperationRegion(GNVS, SystemMemory, ACPI_GNVS_ADDR, ACPI_GNVS_SIZE)
+Field(GNVS, ByteAcc, NoLock, Preserve)
+{
+ Offset (0x00),
+ PCNT, 8, /* processor count */
+}
diff --git a/arch/x86/include/asm/arch-quark/acpi/platform.asl b/arch/x86/include/asm/arch-quark/acpi/platform.asl
index bd72842..1ecf153 100644
--- a/arch/x86/include/asm/arch-quark/acpi/platform.asl
+++ b/arch/x86/include/asm/arch-quark/acpi/platform.asl
@@ -22,6 +22,9 @@ Method(_WAK, 1)
Return (Package() {0, 0})
}
+/* ACPI global NVS */
+#include "global_nvs.asl"
+
/* TODO: add CPU ASL support */
Scope (\_SB)
diff --git a/arch/x86/include/asm/arch-quark/global_nvs.h b/arch/x86/include/asm/arch-quark/global_nvs.h
new file mode 100644
index 0000000..0231da0
--- /dev/null
+++ b/arch/x86/include/asm/arch-quark/global_nvs.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2016, Bin Meng <bmeng.cn@gmail.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _GLOBAL_NVS_H_
+#define _GLOBAL_NVS_H_
+
+struct __packed acpi_global_nvs {
+ u8 pcnt; /* processor count */
+
+ /*
+ * Add padding so sizeof(struct acpi_global_nvs) == 0x100.
+ * This must match the size defined in the global_nvs.asl.
+ */
+ u8 rsvd[255];
+};
+
+#endif /* _GLOBAL_NVS_H_ */
diff --git a/arch/x86/lib/acpi_table.c b/arch/x86/lib/acpi_table.c
index bb71286..7001e8b 100644
--- a/arch/x86/lib/acpi_table.c
+++ b/arch/x86/lib/acpi_table.c
@@ -11,10 +11,12 @@
#include <cpu.h>
#include <dm.h>
#include <dm/uclass-internal.h>
+#include <asm/acpi/global_nvs.h>
#include <asm/acpi_table.h>
#include <asm/io.h>
#include <asm/lapic.h>
#include <asm/tables.h>
+#include <asm/arch/global_nvs.h>
/*
* IASL compiles the dsdt entries and writes the hex values
@@ -336,6 +338,7 @@ u32 write_acpi_tables(u32 start)
struct acpi_fadt *fadt;
struct acpi_mcfg *mcfg;
struct acpi_madt *madt;
+ int i;
current = start;
@@ -383,6 +386,25 @@ u32 write_acpi_tables(u32 start)
current += dsdt->length - sizeof(struct acpi_table_header);
current = ALIGN(current, 16);
+ /* Pack GNVS into the ACPI table area */
+ for (i = 0; i < dsdt->length; i++) {
+ u32 *gnvs = (u32 *)((u32)dsdt + i);
+ if (*gnvs == ACPI_GNVS_ADDR) {
+ debug("Fix up global NVS in DSDT to 0x%08x\n", current);
+ *gnvs = current;
+ break;
+ }
+ }
+
+ /* Update DSDT checksum since we patched the GNVS address */
+ dsdt->checksum = 0;
+ dsdt->checksum = table_compute_checksum((void *)dsdt, dsdt->length);
+
+ /* Fill in platform-specific global NVS variables */
+ acpi_create_gnvs((struct acpi_global_nvs *)current);
+ current += sizeof(struct acpi_global_nvs);
+ current = ALIGN(current, 16);
+
debug("ACPI: * FADT\n");
fadt = (struct acpi_fadt *)current;
current += sizeof(struct acpi_fadt);
diff --git a/arch/x86/lib/fsp/fsp_support.c b/arch/x86/lib/fsp/fsp_support.c
index b05dced..a480361 100644
--- a/arch/x86/lib/fsp/fsp_support.c
+++ b/arch/x86/lib/fsp/fsp_support.c
@@ -110,7 +110,7 @@ void fsp_init(u32 stack_top, u32 boot_mode, void *nvs_buf)
struct upd_region *fsp_upd;
#endif
-#ifdef CONFIG_DEBUG_UART
+#ifdef CONFIG_INTERNAL_UART
setup_internal_uart(1);
#endif
diff --git a/board/advantech/Kconfig b/board/advantech/Kconfig
new file mode 100644
index 0000000..a8d4969
--- /dev/null
+++ b/board/advantech/Kconfig
@@ -0,0 +1,28 @@
+if VENDOR_ADVANTECH
+
+choice
+ prompt "Mainboard model"
+ optional
+
+config TARGET_SOM_DB5800_SOM_6867
+ bool "Advantech SOM-DB5800 & SOM-6867"
+ help
+ Advantech SOM-DB5800 COM Express development board with SOM-6867
+ installed.
+
+ SOM-6867 is a COM Express Type 6 Compact Module with either an Intel
+ Atom E3845 or Celeron N2920 processor.
+
+ SOM-DB5800 is a COM Express Development board with:
+ 10/100/1000 Ethernet
+ PCIe slots
+ 4x USB ports
+ HDMI/DisplayPort/DVI, LVDS, VGA
+ SATA ports
+ ALC892 HD Audio Codec
+
+endchoice
+
+source "board/advantech/som-db5800-som-6867/Kconfig"
+
+endif
diff --git a/board/advantech/som-db5800-som-6867/.gitignore b/board/advantech/som-db5800-som-6867/.gitignore
new file mode 100644
index 0000000..6eb8a54
--- /dev/null
+++ b/board/advantech/som-db5800-som-6867/.gitignore
@@ -0,0 +1,3 @@
+dsdt.aml
+dsdt.asl.tmp
+dsdt.c
diff --git a/board/advantech/som-db5800-som-6867/Kconfig b/board/advantech/som-db5800-som-6867/Kconfig
new file mode 100644
index 0000000..f6f3748
--- /dev/null
+++ b/board/advantech/som-db5800-som-6867/Kconfig
@@ -0,0 +1,28 @@
+if TARGET_SOM_DB5800_SOM_6867
+
+config SYS_BOARD
+ default "som-db5800-som-6867"
+
+config SYS_VENDOR
+ default "advantech"
+
+config SYS_SOC
+ default "baytrail"
+
+config SYS_CONFIG_NAME
+ default "som-db5800-som-6867"
+
+config SYS_TEXT_BASE
+ default 0xfff00000 if !EFI_STUB
+ default 0x01110000 if EFI_STUB
+
+config BOARD_SPECIFIC_OPTIONS # dummy
+ def_bool y
+ select X86_RESET_VECTOR if !EFI_STUB
+ select INTEL_BAYTRAIL
+ select BOARD_ROMSIZE_KB_8192
+
+config PCIE_ECAM_BASE
+ default 0xe0000000
+
+endif
diff --git a/board/advantech/som-db5800-som-6867/MAINTAINERS b/board/advantech/som-db5800-som-6867/MAINTAINERS
new file mode 100644
index 0000000..92989bf
--- /dev/null
+++ b/board/advantech/som-db5800-som-6867/MAINTAINERS
@@ -0,0 +1,7 @@
+Advantech SOM-DB5800-SOM-6867
+M: George McCollister <george.mccollister@gmail.com>
+S: Maintained
+F: board/advantech/som-db5800-som-6867
+F: include/configs/som-db5800-som-6867.h
+F: configs/som-db5800-som-6867_defconfig
+F: arch/x86/dts/baytrail_som-db5800-som-6867.dts
diff --git a/board/advantech/som-db5800-som-6867/Makefile b/board/advantech/som-db5800-som-6867/Makefile
new file mode 100644
index 0000000..9837aa0
--- /dev/null
+++ b/board/advantech/som-db5800-som-6867/Makefile
@@ -0,0 +1,8 @@
+#
+# Copyright (C) 2015, Google, Inc
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+obj-y += som-db5800-som-6867.o start.o
+obj-$(CONFIG_GENERATE_ACPI_TABLE) += dsdt.o
diff --git a/board/advantech/som-db5800-som-6867/acpi/mainboard.asl b/board/advantech/som-db5800-som-6867/acpi/mainboard.asl
new file mode 100644
index 0000000..21785ea
--- /dev/null
+++ b/board/advantech/som-db5800-som-6867/acpi/mainboard.asl
@@ -0,0 +1,11 @@
+/*
+ * Copyright (C) 2016, Bin Meng <bmeng.cn@gmail.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+/* Power Button */
+Device (PWRB)
+{
+ Name(_HID, EISAID("PNP0C0C"))
+}
diff --git a/board/advantech/som-db5800-som-6867/dsdt.asl b/board/advantech/som-db5800-som-6867/dsdt.asl
new file mode 100644
index 0000000..6042011
--- /dev/null
+++ b/board/advantech/som-db5800-som-6867/dsdt.asl
@@ -0,0 +1,14 @@
+/*
+ * Copyright (C) 2016, Bin Meng <bmeng.cn@gmail.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+DefinitionBlock("dsdt.aml", "DSDT", 2, "U-BOOT", "U-BOOTBL", 0x00010000)
+{
+ /* platform specific */
+ #include <asm/arch/acpi/platform.asl>
+
+ /* board specific */
+ #include "acpi/mainboard.asl"
+}
diff --git a/board/advantech/som-db5800-som-6867/som-db5800-som-6867.c b/board/advantech/som-db5800-som-6867/som-db5800-som-6867.c
new file mode 100644
index 0000000..5bed2c1
--- /dev/null
+++ b/board/advantech/som-db5800-som-6867/som-db5800-som-6867.c
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2016 Stefan Roese <sr@denx.de>
+ * Copyright (C) 2016 George McCollister <george.mccollister@gmail.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+
+int board_early_init_f(void)
+{
+ /*
+ * The FSP enables the BayTrail internal legacy UART (again).
+ * Disable it again, so that the one on the EC can be used.
+ */
+ setup_internal_uart(0);
+
+ return 0;
+}
+
+int arch_early_init_r(void)
+{
+ return 0;
+}
diff --git a/board/advantech/som-db5800-som-6867/start.S b/board/advantech/som-db5800-som-6867/start.S
new file mode 100644
index 0000000..2c941a4
--- /dev/null
+++ b/board/advantech/som-db5800-som-6867/start.S
@@ -0,0 +1,9 @@
+/*
+ * Copyright (C) 2015, Google, Inc
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+.globl early_board_init
+early_board_init:
+ jmp early_board_init_ret
diff --git a/board/armltd/vexpress64/vexpress64.c b/board/armltd/vexpress64/vexpress64.c
index 973b579..e34af6c 100644
--- a/board/armltd/vexpress64/vexpress64.c
+++ b/board/armltd/vexpress64/vexpress64.c
@@ -31,13 +31,15 @@ U_BOOT_DEVICE(vexpress_serials) = {
static struct mm_region vexpress64_mem_map[] = {
{
- .base = 0x0UL,
+ .virt = 0x0UL,
+ .phys = 0x0UL,
.size = 0x80000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
PTE_BLOCK_NON_SHARE |
PTE_BLOCK_PXN | PTE_BLOCK_UXN
}, {
- .base = 0x80000000UL,
+ .virt = 0x80000000UL,
+ .phys = 0x80000000UL,
.size = 0xff80000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
PTE_BLOCK_INNER_SHARE
diff --git a/board/cavium/thunderx/thunderx.c b/board/cavium/thunderx/thunderx.c
index 9131a38..960ca53 100644
--- a/board/cavium/thunderx/thunderx.c
+++ b/board/cavium/thunderx/thunderx.c
@@ -45,16 +45,19 @@ DECLARE_GLOBAL_DATA_PTR;
static struct mm_region thunderx_mem_map[] = {
{
- .base = 0x000000000000UL,
+ .virt = 0x000000000000UL,
+ .phys = 0x000000000000UL,
.size = 0x40000000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_NON_SHARE,
}, {
- .base = 0x800000000000UL,
+ .virt = 0x800000000000UL,
+ .phys = 0x800000000000UL,
.size = 0x40000000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
PTE_BLOCK_NON_SHARE,
}, {
- .base = 0x840000000000UL,
+ .virt = 0x840000000000UL,
+ .phys = 0x840000000000UL,
.size = 0x40000000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
PTE_BLOCK_NON_SHARE,
diff --git a/board/congatec/conga-qeval20-qa3-e3845/conga-qeval20-qa3.c b/board/congatec/conga-qeval20-qa3-e3845/conga-qeval20-qa3.c
index 6a946d5..737e610 100644
--- a/board/congatec/conga-qeval20-qa3-e3845/conga-qeval20-qa3.c
+++ b/board/congatec/conga-qeval20-qa3-e3845/conga-qeval20-qa3.c
@@ -12,6 +12,7 @@
int board_early_init_f(void)
{
+#ifndef CONFIG_INTERNAL_UART
/*
* The FSP enables the BayTrail internal legacy UART (again).
* Disable it again, so that the Winbond one can be used.
@@ -21,6 +22,7 @@ int board_early_init_f(void)
/* Enable the legacy UART in the Winbond W83627 Super IO chip */
winbond_enable_serial(PNP_DEV(WINBOND_IO_PORT, W83627DHG_SP1),
UART0_BASE, UART0_IRQ);
+#endif
return 0;
}
diff --git a/board/evb_rk3036/evb_rk3036/MAINTAINERS b/board/evb_rk3036/evb_rk3036/MAINTAINERS
index e69de29..152d31c 100644
--- a/board/evb_rk3036/evb_rk3036/MAINTAINERS
+++ b/board/evb_rk3036/evb_rk3036/MAINTAINERS
@@ -0,0 +1,6 @@
+EVB-RK3036
+M: huang lin <hl@rock-chips.com>
+S: Maintained
+F: board/evb/evb-rk3036
+F: include/configs/evb-rk3036.h
+F: configs/evb-rk3036_defconfig
diff --git a/board/freescale/ls1043aqds/ddr.c b/board/freescale/ls1043aqds/ddr.c
index 0fd835d..d4540d0 100644
--- a/board/freescale/ls1043aqds/ddr.c
+++ b/board/freescale/ls1043aqds/ddr.c
@@ -128,7 +128,7 @@ phys_size_t initdram(int board_type)
void dram_init_banksize(void)
{
/*
- * gd->secure_ram tracks the location of secure memory.
+ * gd->arch.secure_ram tracks the location of secure memory.
* It was set as if the memory starts from 0.
* The address needs to add the offset of its bank.
*/
@@ -139,16 +139,17 @@ void dram_init_banksize(void)
gd->bd->bi_dram[1].size = gd->ram_size -
CONFIG_SYS_DDR_BLOCK1_SIZE;
#ifdef CONFIG_SYS_MEM_RESERVE_SECURE
- gd->secure_ram = gd->bd->bi_dram[1].start +
- gd->secure_ram -
- CONFIG_SYS_DDR_BLOCK1_SIZE;
- gd->secure_ram |= MEM_RESERVE_SECURE_MAINTAINED;
+ gd->arch.secure_ram = gd->bd->bi_dram[1].start +
+ gd->arch.secure_ram -
+ CONFIG_SYS_DDR_BLOCK1_SIZE;
+ gd->arch.secure_ram |= MEM_RESERVE_SECURE_MAINTAINED;
#endif
} else {
gd->bd->bi_dram[0].size = gd->ram_size;
#ifdef CONFIG_SYS_MEM_RESERVE_SECURE
- gd->secure_ram = gd->bd->bi_dram[0].start + gd->secure_ram;
- gd->secure_ram |= MEM_RESERVE_SECURE_MAINTAINED;
+ gd->arch.secure_ram = gd->bd->bi_dram[0].start +
+ gd->arch.secure_ram;
+ gd->arch.secure_ram |= MEM_RESERVE_SECURE_MAINTAINED;
#endif
}
}
diff --git a/board/freescale/ls1043ardb/ddr.c b/board/freescale/ls1043ardb/ddr.c
index 1e2fd2e..61b1cc4 100644
--- a/board/freescale/ls1043ardb/ddr.c
+++ b/board/freescale/ls1043ardb/ddr.c
@@ -189,7 +189,7 @@ phys_size_t initdram(int board_type)
void dram_init_banksize(void)
{
/*
- * gd->secure_ram tracks the location of secure memory.
+ * gd->arch.secure_ram tracks the location of secure memory.
* It was set as if the memory starts from 0.
* The address needs to add the offset of its bank.
*/
@@ -200,16 +200,17 @@ void dram_init_banksize(void)
gd->bd->bi_dram[1].size = gd->ram_size -
CONFIG_SYS_DDR_BLOCK1_SIZE;
#ifdef CONFIG_SYS_MEM_RESERVE_SECURE
- gd->secure_ram = gd->bd->bi_dram[1].start +
- gd->secure_ram -
- CONFIG_SYS_DDR_BLOCK1_SIZE;
- gd->secure_ram |= MEM_RESERVE_SECURE_MAINTAINED;
+ gd->arch.secure_ram = gd->bd->bi_dram[1].start +
+ gd->arch.secure_ram -
+ CONFIG_SYS_DDR_BLOCK1_SIZE;
+ gd->arch.secure_ram |= MEM_RESERVE_SECURE_MAINTAINED;
#endif
} else {
gd->bd->bi_dram[0].size = gd->ram_size;
#ifdef CONFIG_SYS_MEM_RESERVE_SECURE
- gd->secure_ram = gd->bd->bi_dram[0].start + gd->secure_ram;
- gd->secure_ram |= MEM_RESERVE_SECURE_MAINTAINED;
+ gd->arch.secure_ram = gd->bd->bi_dram[0].start +
+ gd->arch.secure_ram;
+ gd->arch.secure_ram |= MEM_RESERVE_SECURE_MAINTAINED;
#endif
}
}
diff --git a/board/freescale/ls1043ardb/ls1043ardb.c b/board/freescale/ls1043ardb/ls1043ardb.c
index 1436520..d3e37b4 100644
--- a/board/freescale/ls1043ardb/ls1043ardb.c
+++ b/board/freescale/ls1043ardb/ls1043ardb.c
@@ -24,7 +24,9 @@
#ifdef CONFIG_U_QE
#include <fsl_qe.h>
#endif
-
+#ifdef CONFIG_FSL_LS_PPA
+#include <asm/arch/ppa.h>
+#endif
DECLARE_GLOBAL_DATA_PTR;
@@ -92,6 +94,10 @@ int board_init(void)
enable_layerscape_ns_access();
#endif
+#ifdef CONFIG_FSL_LS_PPA
+ ppa_init();
+#endif
+
#ifdef CONFIG_U_QE
u_qe_init();
#endif
diff --git a/board/freescale/ls2080a/ddr.c b/board/freescale/ls2080a/ddr.c
index 1827ddc..e6130ec 100644
--- a/board/freescale/ls2080a/ddr.c
+++ b/board/freescale/ls2080a/ddr.c
@@ -177,7 +177,7 @@ void dram_init_banksize(void)
#endif
/*
- * gd->secure_ram tracks the location of secure memory.
+ * gd->arch.secure_ram tracks the location of secure memory.
* It was set as if the memory starts from 0.
* The address needs to add the offset of its bank.
*/
@@ -188,16 +188,17 @@ void dram_init_banksize(void)
gd->bd->bi_dram[1].size = gd->ram_size -
CONFIG_SYS_LS2_DDR_BLOCK1_SIZE;
#ifdef CONFIG_SYS_MEM_RESERVE_SECURE
- gd->secure_ram = gd->bd->bi_dram[1].start +
- gd->secure_ram -
- CONFIG_SYS_LS2_DDR_BLOCK1_SIZE;
- gd->secure_ram |= MEM_RESERVE_SECURE_MAINTAINED;
+ gd->arch.secure_ram = gd->bd->bi_dram[1].start +
+ gd->arch.secure_ram -
+ CONFIG_SYS_LS2_DDR_BLOCK1_SIZE;
+ gd->arch.secure_ram |= MEM_RESERVE_SECURE_MAINTAINED;
#endif
} else {
gd->bd->bi_dram[0].size = gd->ram_size;
#ifdef CONFIG_SYS_MEM_RESERVE_SECURE
- gd->secure_ram = gd->bd->bi_dram[0].start + gd->secure_ram;
- gd->secure_ram |= MEM_RESERVE_SECURE_MAINTAINED;
+ gd->arch.secure_ram = gd->bd->bi_dram[0].start +
+ gd->arch.secure_ram;
+ gd->arch.secure_ram |= MEM_RESERVE_SECURE_MAINTAINED;
#endif
}
diff --git a/board/freescale/ls2080aqds/ddr.c b/board/freescale/ls2080aqds/ddr.c
index fcb0366..9c6f477 100644
--- a/board/freescale/ls2080aqds/ddr.c
+++ b/board/freescale/ls2080aqds/ddr.c
@@ -177,7 +177,7 @@ void dram_init_banksize(void)
#endif
/*
- * gd->secure_ram tracks the location of secure memory.
+ * gd->arch.secure_ram tracks the location of secure memory.
* It was set as if the memory starts from 0.
* The address needs to add the offset of its bank.
*/
@@ -188,16 +188,17 @@ void dram_init_banksize(void)
gd->bd->bi_dram[1].size = gd->ram_size -
CONFIG_SYS_LS2_DDR_BLOCK1_SIZE;
#ifdef CONFIG_SYS_MEM_RESERVE_SECURE
- gd->secure_ram = gd->bd->bi_dram[1].start +
- gd->secure_ram -
- CONFIG_SYS_LS2_DDR_BLOCK1_SIZE;
- gd->secure_ram |= MEM_RESERVE_SECURE_MAINTAINED;
+ gd->arch.secure_ram = gd->bd->bi_dram[1].start +
+ gd->arch.secure_ram -
+ CONFIG_SYS_LS2_DDR_BLOCK1_SIZE;
+ gd->arch.secure_ram |= MEM_RESERVE_SECURE_MAINTAINED;
#endif
} else {
gd->bd->bi_dram[0].size = gd->ram_size;
#ifdef CONFIG_SYS_MEM_RESERVE_SECURE
- gd->secure_ram = gd->bd->bi_dram[0].start + gd->secure_ram;
- gd->secure_ram |= MEM_RESERVE_SECURE_MAINTAINED;
+ gd->arch.secure_ram = gd->bd->bi_dram[0].start +
+ gd->arch.secure_ram;
+ gd->arch.secure_ram |= MEM_RESERVE_SECURE_MAINTAINED;
#endif
}
diff --git a/board/freescale/ls2080ardb/ddr.c b/board/freescale/ls2080ardb/ddr.c
index a04d21b..ecd1e71 100644
--- a/board/freescale/ls2080ardb/ddr.c
+++ b/board/freescale/ls2080ardb/ddr.c
@@ -177,7 +177,7 @@ void dram_init_banksize(void)
#endif
/*
- * gd->secure_ram tracks the location of secure memory.
+ * gd->arch.secure_ram tracks the location of secure memory.
* It was set as if the memory starts from 0.
* The address needs to add the offset of its bank.
*/
@@ -188,16 +188,17 @@ void dram_init_banksize(void)
gd->bd->bi_dram[1].size = gd->ram_size -
CONFIG_SYS_LS2_DDR_BLOCK1_SIZE;
#ifdef CONFIG_SYS_MEM_RESERVE_SECURE
- gd->secure_ram = gd->bd->bi_dram[1].start +
- gd->secure_ram -
- CONFIG_SYS_LS2_DDR_BLOCK1_SIZE;
- gd->secure_ram |= MEM_RESERVE_SECURE_MAINTAINED;
+ gd->arch.secure_ram = gd->bd->bi_dram[1].start +
+ gd->arch.secure_ram -
+ CONFIG_SYS_LS2_DDR_BLOCK1_SIZE;
+ gd->arch.secure_ram |= MEM_RESERVE_SECURE_MAINTAINED;
#endif
} else {
gd->bd->bi_dram[0].size = gd->ram_size;
#ifdef CONFIG_SYS_MEM_RESERVE_SECURE
- gd->secure_ram = gd->bd->bi_dram[0].start + gd->secure_ram;
- gd->secure_ram |= MEM_RESERVE_SECURE_MAINTAINED;
+ gd->arch.secure_ram = gd->bd->bi_dram[0].start +
+ gd->arch.secure_ram;
+ gd->arch.secure_ram |= MEM_RESERVE_SECURE_MAINTAINED;
#endif
}
diff --git a/board/hisilicon/hikey/hikey.c b/board/hisilicon/hikey/hikey.c
index 7abc678..72d6334 100644
--- a/board/hisilicon/hikey/hikey.c
+++ b/board/hisilicon/hikey/hikey.c
@@ -93,12 +93,14 @@ U_BOOT_DEVICE(hikey_seriala) = {
static struct mm_region hikey_mem_map[] = {
{
- .base = 0x0UL,
+ .virt = 0x0UL,
+ .phys = 0x0UL,
.size = 0x80000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
PTE_BLOCK_INNER_SHARE
}, {
- .base = 0x80000000UL,
+ .virt = 0x80000000UL,
+ .phys = 0x80000000UL,
.size = 0x80000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
PTE_BLOCK_NON_SHARE |
diff --git a/board/keymile/common/common.c b/board/keymile/common/common.c
index a42f3ec..0829b7f 100644
--- a/board/keymile/common/common.c
+++ b/board/keymile/common/common.c
@@ -53,7 +53,7 @@ int set_km_env(void)
sprintf((char *)buf, "0x%x", pnvramaddr);
setenv("pnvramaddr", (char *)buf);
- /* try to read rootfssize (ram image) from envrionment */
+ /* try to read rootfssize (ram image) from environment */
p = getenv("rootfssize");
if (p != NULL)
strict_strtoul(p, 16, &rootfssize);
diff --git a/board/keymile/kmp204x/ddr.c b/board/keymile/kmp204x/ddr.c
index 34ac697..77af184 100644
--- a/board/keymile/kmp204x/ddr.c
+++ b/board/keymile/kmp204x/ddr.c
@@ -36,7 +36,7 @@ void fsl_ddr_board_options(memctl_options_t *popts,
/* we have only one module, half str should be OK */
popts->half_strength_driver_enable = 1;
- /* wrlvl values overriden as recommended by ddr init func */
+ /* wrlvl values overridden as recommended by ddr init func */
popts->wrlvl_override = 1;
popts->wrlvl_sample = 0xf;
popts->wrlvl_start = 0x6;
diff --git a/board/kylin/kylin_rk3036/MAINTAINERS b/board/kylin/kylin_rk3036/MAINTAINERS
index e69de29..f8ee834 100644
--- a/board/kylin/kylin_rk3036/MAINTAINERS
+++ b/board/kylin/kylin_rk3036/MAINTAINERS
@@ -0,0 +1,6 @@
+KYLIN-RK3036
+M: huang lin <hl@rock-chips.com>
+S: Maintained
+F: board/kylin/kylin-rk3036
+F: include/configs/kylin-rk3036.h
+F: configs/kylin-rk3036_defconfig
diff --git a/board/raspberrypi/rpi/rpi.c b/board/raspberrypi/rpi/rpi.c
index c45ddb1..fbfbf6c 100644
--- a/board/raspberrypi/rpi/rpi.c
+++ b/board/raspberrypi/rpi/rpi.c
@@ -234,12 +234,14 @@ static const struct rpi_model *model;
#ifdef CONFIG_ARM64
static struct mm_region bcm2837_mem_map[] = {
{
- .base = 0x00000000UL,
+ .virt = 0x00000000UL,
+ .phys = 0x00000000UL,
.size = 0x3f000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
PTE_BLOCK_INNER_SHARE
}, {
- .base = 0x3f000000UL,
+ .virt = 0x3f000000UL,
+ .phys = 0x3f000000UL,
.size = 0x01000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
PTE_BLOCK_NON_SHARE |
diff --git a/board/sandbox/MAINTAINERS b/board/sandbox/MAINTAINERS
index f5db773..4dcbf4b 100644
--- a/board/sandbox/MAINTAINERS
+++ b/board/sandbox/MAINTAINERS
@@ -11,3 +11,10 @@ S: Maintained
F: board/sandbox/
F: include/configs/sandbox.h
F: configs/sandbox_noblk_defconfig
+
+SANDBOX SPL BOARD
+M: Simon Glass <sjg@chromium.org>
+S: Maintained
+F: board/sandbox/
+F: include/configs/sandbox_spl.h
+F: configs/sandbox_spl_defconfig
diff --git a/board/st/stm32f746-disco/stm32f746-disco.c b/board/st/stm32f746-disco/stm32f746-disco.c
index 0e04d14..47aa058 100644
--- a/board/st/stm32f746-disco/stm32f746-disco.c
+++ b/board/st/stm32f746-disco/stm32f746-disco.c
@@ -10,6 +10,8 @@
#include <asm/armv7m.h>
#include <asm/arch/stm32.h>
#include <asm/arch/gpio.h>
+#include <asm/arch/rcc.h>
+#include <asm/arch/fmc.h>
#include <dm/platdata.h>
#include <dm/platform_data/serial_stm32x7.h>
#include <asm/arch/stm32_periph.h>
@@ -30,12 +32,227 @@ const struct stm32_gpio_ctl gpio_ctl_usart = {
.otype = STM32_GPIO_OTYPE_PP,
.speed = STM32_GPIO_SPEED_50M,
.pupd = STM32_GPIO_PUPD_UP,
- .af = STM32_GPIO_AF7
+ .af = STM32_GPIO_AF8
};
+const struct stm32_gpio_ctl gpio_ctl_fmc = {
+ .mode = STM32_GPIO_MODE_AF,
+ .otype = STM32_GPIO_OTYPE_PP,
+ .speed = STM32_GPIO_SPEED_100M,
+ .pupd = STM32_GPIO_PUPD_NO,
+ .af = STM32_GPIO_AF12
+};
+
+static const struct stm32_gpio_dsc ext_ram_fmc_gpio[] = {
+ /* Chip is LQFP144, see DM00077036.pdf for details */
+ {STM32_GPIO_PORT_D, STM32_GPIO_PIN_10}, /* 79, FMC_D15 */
+ {STM32_GPIO_PORT_D, STM32_GPIO_PIN_9}, /* 78, FMC_D14 */
+ {STM32_GPIO_PORT_D, STM32_GPIO_PIN_8}, /* 77, FMC_D13 */
+ {STM32_GPIO_PORT_E, STM32_GPIO_PIN_15}, /* 68, FMC_D12 */
+ {STM32_GPIO_PORT_E, STM32_GPIO_PIN_14}, /* 67, FMC_D11 */
+ {STM32_GPIO_PORT_E, STM32_GPIO_PIN_13}, /* 66, FMC_D10 */
+ {STM32_GPIO_PORT_E, STM32_GPIO_PIN_12}, /* 65, FMC_D9 */
+ {STM32_GPIO_PORT_E, STM32_GPIO_PIN_11}, /* 64, FMC_D8 */
+ {STM32_GPIO_PORT_E, STM32_GPIO_PIN_10}, /* 63, FMC_D7 */
+ {STM32_GPIO_PORT_E, STM32_GPIO_PIN_9}, /* 60, FMC_D6 */
+ {STM32_GPIO_PORT_E, STM32_GPIO_PIN_8}, /* 59, FMC_D5 */
+ {STM32_GPIO_PORT_E, STM32_GPIO_PIN_7}, /* 58, FMC_D4 */
+ {STM32_GPIO_PORT_D, STM32_GPIO_PIN_1}, /* 115, FMC_D3 */
+ {STM32_GPIO_PORT_D, STM32_GPIO_PIN_0}, /* 114, FMC_D2 */
+ {STM32_GPIO_PORT_D, STM32_GPIO_PIN_15}, /* 86, FMC_D1 */
+ {STM32_GPIO_PORT_D, STM32_GPIO_PIN_14}, /* 85, FMC_D0 */
+
+ {STM32_GPIO_PORT_E, STM32_GPIO_PIN_1}, /* 142, FMC_NBL1 */
+ {STM32_GPIO_PORT_E, STM32_GPIO_PIN_0}, /* 141, FMC_NBL0 */
+
+ {STM32_GPIO_PORT_G, STM32_GPIO_PIN_5}, /* 90, FMC_A15, BA1 */
+ {STM32_GPIO_PORT_G, STM32_GPIO_PIN_4}, /* 89, FMC_A14, BA0 */
+
+ {STM32_GPIO_PORT_G, STM32_GPIO_PIN_1}, /* 57, FMC_A11 */
+ {STM32_GPIO_PORT_G, STM32_GPIO_PIN_0}, /* 56, FMC_A10 */
+ {STM32_GPIO_PORT_F, STM32_GPIO_PIN_15}, /* 55, FMC_A9 */
+ {STM32_GPIO_PORT_F, STM32_GPIO_PIN_14}, /* 54, FMC_A8 */
+ {STM32_GPIO_PORT_F, STM32_GPIO_PIN_13}, /* 53, FMC_A7 */
+ {STM32_GPIO_PORT_F, STM32_GPIO_PIN_12}, /* 50, FMC_A6 */
+ {STM32_GPIO_PORT_F, STM32_GPIO_PIN_5}, /* 15, FMC_A5 */
+ {STM32_GPIO_PORT_F, STM32_GPIO_PIN_4}, /* 14, FMC_A4 */
+ {STM32_GPIO_PORT_F, STM32_GPIO_PIN_3}, /* 13, FMC_A3 */
+ {STM32_GPIO_PORT_F, STM32_GPIO_PIN_2}, /* 12, FMC_A2 */
+ {STM32_GPIO_PORT_F, STM32_GPIO_PIN_1}, /* 11, FMC_A1 */
+ {STM32_GPIO_PORT_F, STM32_GPIO_PIN_0}, /* 10, FMC_A0 */
+
+ {STM32_GPIO_PORT_H, STM32_GPIO_PIN_3}, /* 136, SDRAM_NE */
+ {STM32_GPIO_PORT_F, STM32_GPIO_PIN_11}, /* 49, SDRAM_NRAS */
+ {STM32_GPIO_PORT_G, STM32_GPIO_PIN_15}, /* 132, SDRAM_NCAS */
+ {STM32_GPIO_PORT_H, STM32_GPIO_PIN_5}, /* 26, SDRAM_NWE */
+ {STM32_GPIO_PORT_C, STM32_GPIO_PIN_3}, /* 135, SDRAM_CKE */
+
+ {STM32_GPIO_PORT_G, STM32_GPIO_PIN_8}, /* 93, SDRAM_CLK */
+};
+
+static int fmc_setup_gpio(void)
+{
+ int rv = 0;
+ int i;
+
+ clock_setup(GPIO_B_CLOCK_CFG);
+ clock_setup(GPIO_C_CLOCK_CFG);
+ clock_setup(GPIO_D_CLOCK_CFG);
+ clock_setup(GPIO_E_CLOCK_CFG);
+ clock_setup(GPIO_F_CLOCK_CFG);
+ clock_setup(GPIO_G_CLOCK_CFG);
+ clock_setup(GPIO_H_CLOCK_CFG);
+
+ for (i = 0; i < ARRAY_SIZE(ext_ram_fmc_gpio); i++) {
+ rv = stm32_gpio_config(&ext_ram_fmc_gpio[i],
+ &gpio_ctl_fmc);
+ if (rv)
+ goto out;
+ }
+
+out:
+ return rv;
+}
+
+/*
+ * STM32 RCC FMC specific definitions
+ */
+#define RCC_ENR_FMC (1 << 0) /* FMC module clock */
+
+static inline u32 _ns2clk(u32 ns, u32 freq)
+{
+ u32 tmp = freq/1000000;
+ return (tmp * ns) / 1000;
+}
+
+#define NS2CLK(ns) (_ns2clk(ns, freq))
+
+/*
+ * Following are timings for IS42S16400J, from corresponding datasheet
+ */
+#define SDRAM_CAS 3 /* 3 cycles */
+#define SDRAM_NB 1 /* Number of banks */
+#define SDRAM_MWID 1 /* 16 bit memory */
+
+#define SDRAM_NR 0x1 /* 12-bit row */
+#define SDRAM_NC 0x0 /* 8-bit col */
+#define SDRAM_RBURST 0x1 /* Single read requests always as bursts */
+#define SDRAM_RPIPE 0x0 /* No HCLK clock cycle delay */
+
+#define SDRAM_TRRD NS2CLK(12)
+#define SDRAM_TRCD NS2CLK(18)
+#define SDRAM_TRP NS2CLK(18)
+#define SDRAM_TRAS NS2CLK(42)
+#define SDRAM_TRC NS2CLK(60)
+#define SDRAM_TRFC NS2CLK(60)
+#define SDRAM_TCDL (1 - 1)
+#define SDRAM_TRDL NS2CLK(12)
+#define SDRAM_TBDL (1 - 1)
+#define SDRAM_TREF (NS2CLK(64000000 / 8192) - 20)
+#define SDRAM_TCCD (1 - 1)
+
+#define SDRAM_TXSR SDRAM_TRFC /* Row cycle time after precharge */
+#define SDRAM_TMRD 1 /* Page 10, Mode Register Set */
+
+
+/* Last data in to row precharge, need also comply ineq on page 1648 */
+#define SDRAM_TWR max(\
+ (int)max((int)SDRAM_TRDL, (int)(SDRAM_TRAS - SDRAM_TRCD)), \
+ (int)(SDRAM_TRC - SDRAM_TRCD - SDRAM_TRP)\
+)
+
+
+#define SDRAM_MODE_BL_SHIFT 0
+#define SDRAM_MODE_CAS_SHIFT 4
+#define SDRAM_MODE_BL 0
+#define SDRAM_MODE_CAS SDRAM_CAS
+
+int dram_init(void)
+{
+ u32 freq;
+ int rv;
+
+ rv = fmc_setup_gpio();
+ if (rv)
+ return rv;
+
+ setbits_le32(RCC_BASE + RCC_AHB3ENR, RCC_ENR_FMC);
+
+ /*
+ * Get frequency for NS2CLK calculation.
+ */
+ freq = clock_get(CLOCK_AHB) / CONFIG_SYS_RAM_FREQ_DIV;
+
+ writel(
+ CONFIG_SYS_RAM_FREQ_DIV << FMC_SDCR_SDCLK_SHIFT
+ | SDRAM_CAS << FMC_SDCR_CAS_SHIFT
+ | SDRAM_NB << FMC_SDCR_NB_SHIFT
+ | SDRAM_MWID << FMC_SDCR_MWID_SHIFT
+ | SDRAM_NR << FMC_SDCR_NR_SHIFT
+ | SDRAM_NC << FMC_SDCR_NC_SHIFT
+ | SDRAM_RPIPE << FMC_SDCR_RPIPE_SHIFT
+ | SDRAM_RBURST << FMC_SDCR_RBURST_SHIFT,
+ &STM32_SDRAM_FMC->sdcr1);
+
+ writel(
+ SDRAM_TRCD << FMC_SDTR_TRCD_SHIFT
+ | SDRAM_TRP << FMC_SDTR_TRP_SHIFT
+ | SDRAM_TWR << FMC_SDTR_TWR_SHIFT
+ | SDRAM_TRC << FMC_SDTR_TRC_SHIFT
+ | SDRAM_TRAS << FMC_SDTR_TRAS_SHIFT
+ | SDRAM_TXSR << FMC_SDTR_TXSR_SHIFT
+ | SDRAM_TMRD << FMC_SDTR_TMRD_SHIFT,
+ &STM32_SDRAM_FMC->sdtr1);
+
+ writel(FMC_SDCMR_BANK_1 | FMC_SDCMR_MODE_START_CLOCK,
+ &STM32_SDRAM_FMC->sdcmr);
+
+ udelay(200); /* 200 us delay, page 10, "Power-Up" */
+ FMC_BUSY_WAIT();
+
+ writel(FMC_SDCMR_BANK_1 | FMC_SDCMR_MODE_PRECHARGE,
+ &STM32_SDRAM_FMC->sdcmr);
+
+ udelay(100);
+ FMC_BUSY_WAIT();
+
+ writel((FMC_SDCMR_BANK_1 | FMC_SDCMR_MODE_AUTOREFRESH
+ | 7 << FMC_SDCMR_NRFS_SHIFT), &STM32_SDRAM_FMC->sdcmr);
+
+ udelay(100);
+ FMC_BUSY_WAIT();
+
+ writel(FMC_SDCMR_BANK_1 | (SDRAM_MODE_BL << SDRAM_MODE_BL_SHIFT
+ | SDRAM_MODE_CAS << SDRAM_MODE_CAS_SHIFT)
+ << FMC_SDCMR_MODE_REGISTER_SHIFT | FMC_SDCMR_MODE_WRITE_MODE,
+ &STM32_SDRAM_FMC->sdcmr);
+
+ udelay(100);
+
+ FMC_BUSY_WAIT();
+
+ writel(FMC_SDCMR_BANK_1 | FMC_SDCMR_MODE_NORMAL,
+ &STM32_SDRAM_FMC->sdcmr);
+
+ FMC_BUSY_WAIT();
+
+ /* Refresh timer */
+ writel(SDRAM_TREF, &STM32_SDRAM_FMC->sdrtr);
+
+ /*
+ * Fill in global info with description of SRAM configuration
+ */
+ gd->bd->bi_dram[0].start = CONFIG_SYS_RAM_BASE;
+ gd->bd->bi_dram[0].size = CONFIG_SYS_RAM_SIZE;
+
+ gd->ram_size = CONFIG_SYS_RAM_SIZE;
+
+ return rv;
+}
+
static const struct stm32_gpio_dsc usart_gpio[] = {
- {STM32_GPIO_PORT_A, STM32_GPIO_PIN_9}, /* TX */
- {STM32_GPIO_PORT_B, STM32_GPIO_PIN_7}, /* RX */
+ {STM32_GPIO_PORT_C, STM32_GPIO_PIN_6}, /* TX */
+ {STM32_GPIO_PORT_C, STM32_GPIO_PIN_7}, /* RX */
};
int uart_setup_gpio(void)
@@ -43,8 +260,7 @@ int uart_setup_gpio(void)
int i;
int rv = 0;
- clock_setup(GPIO_A_CLOCK_CFG);
- clock_setup(GPIO_B_CLOCK_CFG);
+ clock_setup(GPIO_C_CLOCK_CFG);
for (i = 0; i < ARRAY_SIZE(usart_gpio); i++) {
rv = stm32_gpio_config(&usart_gpio[i], &gpio_ctl_usart);
if (rv)
@@ -56,7 +272,7 @@ out:
}
static const struct stm32x7_serial_platdata serial_platdata = {
- .base = (struct stm32_usart *)USART1_BASE,
+ .base = (struct stm32_usart *)USART6_BASE,
.clock = CONFIG_SYS_CLK_FREQ,
};
@@ -75,7 +291,7 @@ int board_early_init_f(void)
int res;
res = uart_setup_gpio();
- clock_setup(USART1_CLOCK_CFG);
+ clock_setup(USART6_CLOCK_CFG);
if (res)
return res;
@@ -88,12 +304,3 @@ int board_init(void)
return 0;
}
-
-int dram_init(void)
-{
- gd->bd->bi_dram[0].start = CONFIG_SYS_RAM_BASE;
- gd->bd->bi_dram[0].size = CONFIG_SYS_RAM_SIZE;
-
- gd->ram_size = CONFIG_SYS_RAM_SIZE;
- return 0;
-}
diff --git a/board/sunxi/MAINTAINERS b/board/sunxi/MAINTAINERS
index d2dfebe..0dc84f6 100644
--- a/board/sunxi/MAINTAINERS
+++ b/board/sunxi/MAINTAINERS
@@ -56,6 +56,7 @@ F: configs/ga10h_v1_1_defconfig
F: configs/gt90h_v4_defconfig
F: configs/inet86dz_defconfig
F: configs/orangepi_2_defconfig
+F: configs/orangepi_lite_defconfig
F: configs/orangepi_one_defconfig
F: configs/orangepi_pc_defconfig
F: configs/orangepi_plus_defconfig
diff --git a/board/sunxi/README.pine64 b/board/sunxi/README.pine64
new file mode 100644
index 0000000..5553415
--- /dev/null
+++ b/board/sunxi/README.pine64
@@ -0,0 +1,98 @@
+Pine64 board README
+====================
+
+The Pine64(+) is a single board computer equipped with an AArch64 capable ARMv8
+compliant Allwinner A64 SoC.
+This chip has ARM Cortex A-53 cores and thus can run both in AArch32
+(compatible to 32-bit ARMv7) and AArch64 modes. Upon reset the SoC starts
+in AArch32 mode and executes 32-bit code from the Boot ROM (BROM).
+This has some implications on U-Boot.
+
+Quick start
+============
+- Get hold of a boot0.img file (see below for more details).
+- Get the boot0img tool source from the tools directory in [1] and compile
+ that on your host.
+- Build U-Boot:
+$ export CROSS_COMPILE=aarch64-linux-gnu-
+$ make pine64_plus_defconfig
+$ make
+- You also need a compiled ARM Trusted Firmware (ATF) binary. Checkout the
+ "allwinner" branch from the github repository [2] and build it:
+$ export CROSS_COMPILE=aarch64-linux-gnu-
+$ make PLAT=sun50iw1p1 DEBUG=1 bl31
+ The resulting binary is build/sun50iw1p1/debug/bl31.bin.
+
+Now put an empty (or disposable) micro SD card in your card reader and learn
+its device file name, replacing /dev/sd<x> below with the result (that could
+be /dev/mmcblk<x> as well):
+
+$ ./boot0img --device /dev/sd<x> -e -u u-boot.bin -B boot0.img \
+ -d trampoline64:0x44000 -s bl31.bin -a 0x44008 -p 100
+(either copying the respective files to the working directory or specifying
+the paths directly)
+
+This will create a new partition table (with a 100 MB FAT boot partition),
+copies boot0.img, ATF and U-Boot to the proper locations on the SD card and
+will fill in the magic Allwinner header to be recognized by boot0.
+Prefix the above call with "sudo" if you don't have write access to the
+uSD card. You can also use "-o output.img" instead of "--device /dev/sd<x>"
+to create an image file and "dd" that to the uSD card.
+Omitting the "-p" option will skip the partition table.
+
+Now put this uSD card in the board and power it on. You should be greeted by
+the U-Boot prompt.
+
+
+Main U-Boot
+============
+The main U-Boot proper is a real 64-bit ARMv8 port and runs entirely in the
+64-bit AArch64 mode. It can load any AArch64 code, EFI applications or arm64
+Linux kernel images (often named "Image") using the booti command.
+Launching 32-bit code and kernels is technically possible, though not without
+drawbacks (or hacks to avoid them) and currently not implemented.
+
+SPL support
+============
+The main task of the SPL support is to bring up the DRAM controller and make
+DRAM actually accessible. At the moment there is no documentation or source
+code available which would do this.
+There are currently two ways to overcome this situation: using a tainted 32-bit
+SPL (involving some hacks and resulting in a non-redistributable binary, thus
+not described here) or using the Allwinner boot0 blob.
+
+boot0 method
+-------------
+boot0 is Allwiner's secondary program loader and it can be used as some kind
+of SPL replacement to get U-Boot up and running.
+The binary is a 32 KByte blob and contained on every Pine64 image distributed
+so far. It can be easily extracted from a micro SD card or an image file:
+# dd if=/dev/sd<x> of=boot0.bin bs=8k skip=1 count=4
+where /dev/sd<x> is the device name of the uSD card or the name of the image
+file. Apparently Allwinner allows re-distribution of this proprietary code
+as-is.
+For the time being this boot0 blob is the only redistributable way of making
+U-Boot work on the Pine64. Beside loading the various parts of the (original)
+firmware it also switches the core into AArch64 mode.
+The original boot0 code looks for U-Boot at a certain place on an uSD card
+(at 19096 KB), also it expects a header with magic bytes and a checksum.
+There is a tool called boot0img[1] which takes a boot0.bin image and a compiled
+U-Boot binary (plus other binaries) and will populate that header accordingly.
+To make space for the magic header, the pine64_plus_defconfig will make sure
+there is sufficient space at the beginning of the U-Boot binary.
+boot0img will also take care of putting the different binaries at the right
+places on the uSD card and works around unused, but mandatory parts by using
+trampoline code. See the output of "boot0img -h" for more information.
+boot0img can also patch boot0 to avoid loading U-Boot from 19MB, instead
+fetching it from just behind the boot0 binary (-B option).
+
+FEL boot
+=========
+FEL is the name of the Allwinner defined USB boot protocol built-in the
+mask ROM of most Allwinner SoCs. It allows to bootstrap a board solely
+by using the USB-OTG interface and a host port on another computer.
+Since FEL boot does not work with boot0, it requires the libdram hack, which
+is not described here.
+
+[1] https://github.com/apritzel/pine64/
+[2] https://github.com/apritzel/arm-trusted-firmware.git
diff --git a/board/sunxi/board.c b/board/sunxi/board.c
index c8bf316..f6e28b0 100644
--- a/board/sunxi/board.c
+++ b/board/sunxi/board.c
@@ -20,12 +20,15 @@
#include <asm/arch/dram.h>
#include <asm/arch/gpio.h>
#include <asm/arch/mmc.h>
+#include <asm/arch/spl.h>
#include <asm/arch/usb_phy.h>
#ifndef CONFIG_ARM64
#include <asm/armv7.h>
#endif
#include <asm/gpio.h>
#include <asm/io.h>
+#include <environment.h>
+#include <libfdt.h>
#include <nand.h>
#include <net.h>
#include <sy8106a.h>
@@ -366,8 +369,7 @@ int board_mmc_init(bd_t *bis)
* are searched there first. Note we only do this for u-boot proper,
* not for the SPL, see spl_boot_device().
*/
- if (!sunxi_mmc_has_egon_boot_signature(mmc0) &&
- sunxi_mmc_has_egon_boot_signature(mmc1)) {
+ if (readb(SPL_ADDR + 0x28) == SUNXI_BOOTED_FROM_MMC2) {
/* Booting from emmc / mmc2, swap */
mmc0->block_dev.devnum = 1;
mmc1->block_dev.devnum = 0;
@@ -571,9 +573,6 @@ void get_board_serial(struct tag_serialnr *serialnr)
}
#endif
-#if !defined(CONFIG_SPL_BUILD)
-#include <asm/arch/spl.h>
-
/*
* Check the SPL header for the "sunxi" variant. If found: parse values
* that might have been passed by the loader ("fel" utility), and update
@@ -582,50 +581,67 @@ void get_board_serial(struct tag_serialnr *serialnr)
static void parse_spl_header(const uint32_t spl_addr)
{
struct boot_file_head *spl = (void *)(ulong)spl_addr;
- if (memcmp(spl->spl_signature, SPL_SIGNATURE, 3) == 0) {
- uint8_t spl_header_version = spl->spl_signature[3];
- if (spl_header_version == SPL_HEADER_VERSION) {
- if (spl->fel_script_address)
- setenv_hex("fel_scriptaddr",
- spl->fel_script_address);
- return;
- }
+ if (memcmp(spl->spl_signature, SPL_SIGNATURE, 3) != 0)
+ return; /* signature mismatch, no usable header */
+
+ uint8_t spl_header_version = spl->spl_signature[3];
+ if (spl_header_version != SPL_HEADER_VERSION) {
printf("sunxi SPL version mismatch: expected %u, got %u\n",
SPL_HEADER_VERSION, spl_header_version);
+ return;
}
+ if (!spl->fel_script_address)
+ return;
+
+ if (spl->fel_uEnv_length != 0) {
+ /*
+ * data is expected in uEnv.txt compatible format, so "env
+ * import -t" the string(s) at fel_script_address right away.
+ */
+ himport_r(&env_htab, (char *)spl->fel_script_address,
+ spl->fel_uEnv_length, '\n', H_NOCLEAR, 0, 0, NULL);
+ return;
+ }
+ /* otherwise assume .scr format (mkimage-type script) */
+ setenv_hex("fel_scriptaddr", spl->fel_script_address);
}
-#endif
-#ifdef CONFIG_MISC_INIT_R
-int misc_init_r(void)
+/*
+ * Note this function gets called multiple times.
+ * It must not make any changes to env variables which already exist.
+ */
+static void setup_environment(const void *fdt)
{
char serial_string[17] = { 0 };
unsigned int sid[4];
uint8_t mac_addr[6];
- int ret;
-
-#if !defined(CONFIG_SPL_BUILD)
- setenv("fel_booted", NULL);
- setenv("fel_scriptaddr", NULL);
- /* determine if we are running in FEL mode */
- if (!is_boot0_magic(SPL_ADDR + 4)) { /* eGON.BT0 */
- setenv("fel_booted", "1");
- parse_spl_header(SPL_ADDR);
- }
-#endif
+ char ethaddr[16];
+ int i, ret;
ret = sunxi_get_sid(sid);
if (ret == 0 && sid[0] != 0 && sid[3] != 0) {
- if (!getenv("ethaddr")) {
+ for (i = 0; i < 4; i++) {
+ sprintf(ethaddr, "ethernet%d", i);
+ if (!fdt_get_alias(fdt, ethaddr))
+ continue;
+
+ if (i == 0)
+ strcpy(ethaddr, "ethaddr");
+ else
+ sprintf(ethaddr, "eth%daddr", i);
+
+ if (getenv(ethaddr))
+ continue;
+
/* Non OUI / registered MAC address */
- mac_addr[0] = 0x02;
+ mac_addr[0] = (i << 4) | 0x02;
mac_addr[1] = (sid[0] >> 0) & 0xff;
mac_addr[2] = (sid[3] >> 24) & 0xff;
mac_addr[3] = (sid[3] >> 16) & 0xff;
mac_addr[4] = (sid[3] >> 8) & 0xff;
mac_addr[5] = (sid[3] >> 0) & 0xff;
- eth_setenv_enetaddr("ethaddr", mac_addr);
+ eth_setenv_enetaddr(ethaddr, mac_addr);
}
if (!getenv("serial#")) {
@@ -635,6 +651,21 @@ int misc_init_r(void)
setenv("serial#", serial_string);
}
}
+}
+
+int misc_init_r(void)
+{
+ __maybe_unused int ret;
+
+ setenv("fel_booted", NULL);
+ setenv("fel_scriptaddr", NULL);
+ /* determine if we are running in FEL mode */
+ if (!is_boot0_magic(SPL_ADDR + 4)) { /* eGON.BT0 */
+ setenv("fel_booted", "1");
+ parse_spl_header(SPL_ADDR);
+ }
+
+ setup_environment(gd->fdt_blob);
#ifndef CONFIG_MACH_SUN9I
ret = sunxi_usb_phy_probe();
@@ -645,12 +676,17 @@ int misc_init_r(void)
return 0;
}
-#endif
int ft_board_setup(void *blob, bd_t *bd)
{
int __maybe_unused r;
+ /*
+ * Call setup_environment again in case the boot fdt has
+ * ethernet aliases the u-boot copy does not have.
+ */
+ setup_environment(blob);
+
#ifdef CONFIG_VIDEO_DT_SIMPLEFB
r = sunxi_simplefb_setup(blob);
if (r)
diff --git a/board/ti/am43xx/board.c b/board/ti/am43xx/board.c
index f005762..27c311e 100644
--- a/board/ti/am43xx/board.c
+++ b/board/ti/am43xx/board.c
@@ -13,6 +13,7 @@
#include <asm/errno.h>
#include <spl.h>
#include <usb.h>
+#include <asm/omap_sec_common.h>
#include <asm/arch/clock.h>
#include <asm/arch/sys_proto.h>
#include <asm/arch/mux.h>
@@ -862,3 +863,10 @@ int board_fit_config_name_match(const char *name)
return -1;
}
#endif
+
+#ifdef CONFIG_TI_SECURE_DEVICE
+void board_fit_image_post_process(void **p_image, size_t *p_size)
+{
+ secure_boot_verify_image(p_image, p_size);
+}
+#endif
diff --git a/board/ti/am57xx/board.c b/board/ti/am57xx/board.c
index 08cf14d..927d136 100644
--- a/board/ti/am57xx/board.c
+++ b/board/ti/am57xx/board.c
@@ -13,6 +13,7 @@
#include <sata.h>
#include <usb.h>
#include <asm/omap_common.h>
+#include <asm/omap_sec_common.h>
#include <asm/emif.h>
#include <asm/gpio.h>
#include <asm/arch/gpio.h>
@@ -750,3 +751,10 @@ int board_fit_config_name_match(const char *name)
return -1;
}
#endif
+
+#ifdef CONFIG_TI_SECURE_DEVICE
+void board_fit_image_post_process(void **p_image, size_t *p_size)
+{
+ secure_boot_verify_image(p_image, p_size);
+}
+#endif
diff --git a/board/ti/dra7xx/evm.c b/board/ti/dra7xx/evm.c
index 6a4d027..99e8254 100644
--- a/board/ti/dra7xx/evm.c
+++ b/board/ti/dra7xx/evm.c
@@ -17,6 +17,8 @@
#include <asm/gpio.h>
#include <usb.h>
#include <linux/usb/gadget.h>
+#include <asm/omap_common.h>
+#include <asm/omap_sec_common.h>
#include <asm/arch/gpio.h>
#include <asm/arch/dra7xx_iodelay.h>
#include <asm/emif.h>
@@ -834,3 +836,10 @@ int board_fit_config_name_match(const char *name)
return -1;
}
#endif
+
+#ifdef CONFIG_TI_SECURE_DEVICE
+void board_fit_image_post_process(void **p_image, size_t *p_size)
+{
+ secure_boot_verify_image(p_image, p_size);
+}
+#endif
diff --git a/cmd/bdinfo.c b/cmd/bdinfo.c
index 1c4bed9..f2435ab 100644
--- a/cmd/bdinfo.c
+++ b/cmd/bdinfo.c
@@ -385,9 +385,9 @@ static int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc,
}
#ifdef CONFIG_SYS_MEM_RESERVE_SECURE
- if (gd->secure_ram & MEM_RESERVE_SECURE_SECURED) {
+ if (gd->arch.secure_ram & MEM_RESERVE_SECURE_SECURED) {
print_num("Secure ram",
- gd->secure_ram & MEM_RESERVE_SECURE_ADDR_MASK);
+ gd->arch.secure_ram & MEM_RESERVE_SECURE_ADDR_MASK);
}
#endif
#if defined(CONFIG_CMD_NET) && !defined(CONFIG_DM_ETH)
diff --git a/cmd/i2c.c b/cmd/i2c.c
index 18ce789..473153f 100644
--- a/cmd/i2c.c
+++ b/cmd/i2c.c
@@ -178,7 +178,7 @@ static int i2c_get_cur_bus_chip(uint chip_addr, struct udevice **devp)
* i2c_init_board() - Board-specific I2C bus init
*
* This function is the default no-op implementation of I2C bus
- * initialization. This function can be overriden by board-specific
+ * initialization. This function can be overridden by board-specific
* implementation if needed.
*/
__weak
diff --git a/cmd/sf.c b/cmd/sf.c
index 42862d9..286906c 100644
--- a/cmd/sf.c
+++ b/cmd/sf.c
@@ -88,6 +88,8 @@ static int do_spi_flash_probe(int argc, char * const argv[])
#ifdef CONFIG_DM_SPI_FLASH
struct udevice *new, *bus_dev;
int ret;
+ /* In DM mode defaults will be taken from DT */
+ speed = 0, mode = 0;
#else
struct spi_flash *new;
#endif
diff --git a/common/board_f.c b/common/board_f.c
index d405b5b..c4501af 100644
--- a/common/board_f.c
+++ b/common/board_f.c
@@ -117,10 +117,11 @@ static int init_func_watchdog_init(void)
# if defined(CONFIG_HW_WATCHDOG) && (defined(CONFIG_BLACKFIN) || \
defined(CONFIG_M68K) || defined(CONFIG_MICROBLAZE) || \
defined(CONFIG_SH) || defined(CONFIG_AT91SAM9_WATCHDOG) || \
+ defined(CONFIG_DESIGNWARE_WATCHDOG) || \
defined(CONFIG_IMX_WATCHDOG))
hw_watchdog_init();
-# endif
puts(" Watchdog enabled\n");
+# endif
WATCHDOG_RESET();
return 0;
@@ -339,7 +340,7 @@ static int setup_dest_addr(void)
* Record secure memory location. Need recalcuate if memory splits
* into banks, or the ram base is not zero.
*/
- gd->secure_ram = gd->ram_size;
+ gd->arch.secure_ram = gd->ram_size;
#endif
/*
* Subtract specified amount of memory to hide so that it won't
@@ -432,6 +433,15 @@ static int reserve_mmu(void)
gd->arch.tlb_addr = gd->relocaddr;
debug("TLB table from %08lx to %08lx\n", gd->arch.tlb_addr,
gd->arch.tlb_addr + gd->arch.tlb_size);
+
+#ifdef CONFIG_SYS_MEM_RESERVE_SECURE
+ /*
+ * Record allocated tlb_addr in case gd->tlb_addr to be overwritten
+ * with location within secure ram.
+ */
+ gd->arch.tlb_allocated = gd->arch.tlb_addr;
+#endif
+
return 0;
}
#endif
diff --git a/common/bootm.c b/common/bootm.c
index 2431019..9ed6428 100644
--- a/common/bootm.c
+++ b/common/bootm.c
@@ -635,10 +635,6 @@ int do_bootm_states(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
goto err;
else if (ret == BOOTM_ERR_OVERLAP)
ret = 0;
-#if defined(CONFIG_SILENT_CONSOLE) && !defined(CONFIG_SILENT_U_BOOT_ONLY)
- if (images->os.os == IH_OS_LINUX)
- fixup_silent_linux();
-#endif
}
/* Relocate the ramdisk */
@@ -678,13 +674,19 @@ int do_bootm_states(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
return 1;
}
+
/* Call various other states that are not generally used */
if (!ret && (states & BOOTM_STATE_OS_CMDLINE))
ret = boot_fn(BOOTM_STATE_OS_CMDLINE, argc, argv, images);
if (!ret && (states & BOOTM_STATE_OS_BD_T))
ret = boot_fn(BOOTM_STATE_OS_BD_T, argc, argv, images);
- if (!ret && (states & BOOTM_STATE_OS_PREP))
+ if (!ret && (states & BOOTM_STATE_OS_PREP)) {
+#if defined(CONFIG_SILENT_CONSOLE) && !defined(CONFIG_SILENT_U_BOOT_ONLY)
+ if (images->os.os == IH_OS_LINUX)
+ fixup_silent_linux();
+#endif
ret = boot_fn(BOOTM_STATE_OS_PREP, argc, argv, images);
+ }
#ifdef CONFIG_TRACE
/* Pretend to run the OS, then run a user command */
diff --git a/common/bootm_os.c b/common/bootm_os.c
index 9ec84bd..e3f5a46 100644
--- a/common/bootm_os.c
+++ b/common/bootm_os.c
@@ -481,6 +481,7 @@ int boot_selected_os(int argc, char * const argv[], int state,
/* Stand-alone may return when 'autostart' is 'no' */
if (images->os.type == IH_TYPE_STANDALONE ||
+ IS_ENABLED(CONFIG_SANDBOX) ||
state == BOOTM_STATE_OS_FAKE_GO) /* We expect to return */
return 0;
bootstage_error(BOOTSTAGE_ID_BOOT_OS_RETURNED);
diff --git a/common/env_common.c b/common/env_common.c
index 13db7dc..560cad0 100644
--- a/common/env_common.c
+++ b/common/env_common.c
@@ -145,7 +145,7 @@ int set_default_vars(int nvars, char * const vars[])
* env_aes_cbc_get_key() - Get AES-128-CBC key for the environment
*
* This function shall return 16-byte array containing AES-128 key used
- * to encrypt and decrypt the environment. This function must be overriden
+ * to encrypt and decrypt the environment. This function must be overridden
* by the implementer as otherwise the environment encryption will not
* work.
*/
diff --git a/common/env_sf.c b/common/env_sf.c
index 273098c..c53200f 100644
--- a/common/env_sf.c
+++ b/common/env_sf.c
@@ -55,9 +55,9 @@ int saveenv(void)
#ifdef CONFIG_DM_SPI_FLASH
struct udevice *new;
+ /* speed and mode will be read from DT */
ret = spi_flash_probe_bus_cs(CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS,
- CONFIG_ENV_SPI_MAX_HZ,
- CONFIG_ENV_SPI_MODE, &new);
+ 0, 0, &new);
if (ret) {
set_default_env("!spi_flash_probe_bus_cs() failed");
return 1;
@@ -245,9 +245,9 @@ int saveenv(void)
#ifdef CONFIG_DM_SPI_FLASH
struct udevice *new;
+ /* speed and mode will be read from DT */
ret = spi_flash_probe_bus_cs(CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS,
- CONFIG_ENV_SPI_MAX_HZ,
- CONFIG_ENV_SPI_MODE, &new);
+ 0, 0, &new);
if (ret) {
set_default_env("!spi_flash_probe_bus_cs() failed");
return 1;
diff --git a/common/fb_mmc.c b/common/fb_mmc.c
index c739651..8d0524d 100644
--- a/common/fb_mmc.c
+++ b/common/fb_mmc.c
@@ -191,7 +191,7 @@ void fb_mmc_erase(const char *cmd)
printf("Erasing blocks " LBAFU " to " LBAFU " due to alignment\n",
blks_start, blks_start + blks_size);
- blks = dev_desc->block_erase(dev_desc, blks_start, blks_size);
+ blks = blk_derase(dev_desc, blks_start, blks_size);
if (blks != blks_size) {
error("failed erasing from device %d", dev_desc->devnum);
fastboot_fail("failed erasing from device");
diff --git a/common/image.c b/common/image.c
index 0be09e5..af155b2 100644
--- a/common/image.c
+++ b/common/image.c
@@ -69,7 +69,7 @@ static const image_header_t *image_get_ramdisk(ulong rd_addr, uint8_t arch,
#endif
static const table_entry_t uimage_arch[] = {
- { IH_ARCH_INVALID, NULL, "Invalid ARCH", },
+ { IH_ARCH_INVALID, "invalid", "Invalid ARCH", },
{ IH_ARCH_ALPHA, "alpha", "Alpha", },
{ IH_ARCH_ARM, "arm", "ARM", },
{ IH_ARCH_I386, "x86", "Intel x86", },
@@ -97,7 +97,7 @@ static const table_entry_t uimage_arch[] = {
};
static const table_entry_t uimage_os[] = {
- { IH_OS_INVALID, NULL, "Invalid OS", },
+ { IH_OS_INVALID, "invalid", "Invalid OS", },
{ IH_OS_LINUX, "linux", "Linux", },
#if defined(CONFIG_LYNXKDI) || defined(USE_HOSTCC)
{ IH_OS_LYNXOS, "lynxos", "LynxOS", },
@@ -144,7 +144,7 @@ static const table_entry_t uimage_type[] = {
{ IH_TYPE_KERNEL_NOLOAD, "kernel_noload", "Kernel Image (no loading done)", },
{ IH_TYPE_KWBIMAGE, "kwbimage", "Kirkwood Boot Image",},
{ IH_TYPE_IMXIMAGE, "imximage", "Freescale i.MX Boot Image",},
- { IH_TYPE_INVALID, NULL, "Invalid Image", },
+ { IH_TYPE_INVALID, "invalid", "Invalid Image", },
{ IH_TYPE_MULTI, "multi", "Multi-File Image", },
{ IH_TYPE_OMAPIMAGE, "omapimage", "TI OMAP SPL With GP CH",},
{ IH_TYPE_PBLIMAGE, "pblimage", "Freescale PBL Boot Image",},
@@ -176,6 +176,19 @@ static const table_entry_t uimage_comp[] = {
{ -1, "", "", },
};
+struct table_info {
+ const char *desc;
+ int count;
+ const table_entry_t *table;
+};
+
+static const struct table_info table_info[IH_COUNT] = {
+ { "architecture", IH_ARCH_COUNT, uimage_arch },
+ { "compression", IH_COMP_COUNT, uimage_comp },
+ { "operating system", IH_OS_COUNT, uimage_os },
+ { "image type", IH_TYPE_COUNT, uimage_type },
+};
+
/*****************************************************************************/
/* Legacy format routines */
/*****************************************************************************/
@@ -570,6 +583,74 @@ const table_entry_t *get_table_entry(const table_entry_t *table, int id)
return NULL;
}
+static const char *unknown_msg(enum ih_category category)
+{
+ static char msg[30];
+
+ strcpy(msg, "Unknown ");
+ strcat(msg, table_info[category].desc);
+
+ return msg;
+}
+
+/**
+ * get_cat_table_entry_name - translate entry id to long name
+ * @category: category to look up (enum ih_category)
+ * @id: entry id to be translated
+ *
+ * This will scan the translation table trying to find the entry that matches
+ * the given id.
+ *
+ * @retur long entry name if translation succeeds; error string on failure
+ */
+const char *genimg_get_cat_name(enum ih_category category, uint id)
+{
+ const table_entry_t *entry;
+
+ entry = get_table_entry(table_info[category].table, id);
+ if (!entry)
+ return unknown_msg(category);
+#if defined(USE_HOSTCC) || !defined(CONFIG_NEEDS_MANUAL_RELOC)
+ return entry->lname;
+#else
+ return entry->lname + gd->reloc_off;
+#endif
+}
+
+/**
+ * get_cat_table_entry_short_name - translate entry id to short name
+ * @category: category to look up (enum ih_category)
+ * @id: entry id to be translated
+ *
+ * This will scan the translation table trying to find the entry that matches
+ * the given id.
+ *
+ * @retur short entry name if translation succeeds; error string on failure
+ */
+const char *genimg_get_cat_short_name(enum ih_category category, uint id)
+{
+ const table_entry_t *entry;
+
+ entry = get_table_entry(table_info[category].table, id);
+ if (!entry)
+ return unknown_msg(category);
+#if defined(USE_HOSTCC) || !defined(CONFIG_NEEDS_MANUAL_RELOC)
+ return entry->sname;
+#else
+ return entry->sname + gd->reloc_off;
+#endif
+}
+
+int genimg_get_cat_count(enum ih_category category)
+{
+ return table_info[category].count;
+}
+
+const char *genimg_get_cat_desc(enum ih_category category)
+{
+ return table_info[category].desc;
+}
+
/**
* get_table_entry_name - translate entry id to long name
* @table: pointer to a translation table for entries of a specific type
diff --git a/common/spl/spl.c b/common/spl/spl.c
index 840910a..14320fe 100644
--- a/common/spl/spl.c
+++ b/common/spl/spl.c
@@ -13,7 +13,6 @@
#include <nand.h>
#include <fat.h>
#include <version.h>
-#include <i2c.h>
#include <image.h>
#include <malloc.h>
#include <dm/root.h>
@@ -203,7 +202,7 @@ int spl_init(void)
gd->malloc_limit = CONFIG_SYS_MALLOC_F_LEN;
gd->malloc_ptr = 0;
#endif
- if (CONFIG_IS_ENABLED(OF_CONTROL)) {
+ if (CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)) {
ret = fdtdec_setup();
if (ret) {
debug("fdtdec_setup() returned error %d\n", ret);
@@ -211,7 +210,8 @@ int spl_init(void)
}
}
if (IS_ENABLED(CONFIG_SPL_DM)) {
- ret = dm_init_and_scan(true);
+ /* With CONFIG_OF_PLATDATA, bring in all devices */
+ ret = dm_init_and_scan(!CONFIG_IS_ENABLED(OF_PLATDATA));
if (ret) {
debug("dm_init_and_scan() returned error %d\n", ret);
return ret;
@@ -270,7 +270,7 @@ struct boot_device_name boot_name_table[] = {
#ifdef CONFIG_SPL_YMODEM_SUPPORT
{ BOOT_DEVICE_UART, "UART" },
#endif
-#ifdef CONFIG_SPL_SPI_SUPPORT
+#if defined(CONFIG_SPL_SPI_SUPPORT) || defined(CONFIG_SPL_SPI_FLASH_SUPPORT)
{ BOOT_DEVICE_SPI, "SPI" },
#endif
#ifdef CONFIG_SPL_ETH_SUPPORT
@@ -346,7 +346,7 @@ static int spl_load_image(u32 boot_device)
case BOOT_DEVICE_UART:
return spl_ymodem_load_image();
#endif
-#ifdef CONFIG_SPL_SPI_SUPPORT
+#if defined(CONFIG_SPL_SPI_SUPPORT) || defined(CONFIG_SPL_SPI_FLASH_SUPPORT)
case BOOT_DEVICE_SPI:
return spl_spi_load_image();
#endif
diff --git a/common/spl/spl_fit.c b/common/spl/spl_fit.c
index 9874708..069e94d 100644
--- a/common/spl/spl_fit.c
+++ b/common/spl/spl_fit.c
@@ -132,7 +132,7 @@ int spl_load_simple_fit(struct spl_load_info *info, ulong sector, void *fit)
int data_offset, data_size;
int base_offset, align_len = ARCH_DMA_MINALIGN - 1;
int src_sector;
- void *dst;
+ void *dst, *src;
/*
* Figure out where the external images start. This is the base for the
@@ -206,8 +206,13 @@ int spl_load_simple_fit(struct spl_load_info *info, ulong sector, void *fit)
return -EIO;
debug("image: dst=%p, data_offset=%x, size=%x\n", dst, data_offset,
data_size);
- memcpy(dst, dst + get_aligned_image_overhead(info, data_offset),
- data_size);
+ src = dst + get_aligned_image_overhead(info, data_offset);
+
+#ifdef CONFIG_SPL_FIT_IMAGE_POST_PROCESS
+ board_fit_image_post_process((void **)&src, (size_t *)&data_size);
+#endif
+
+ memcpy(dst, src, data_size);
/* Figure out which device tree the board wants to use */
fdt_len = spl_fit_select_fdt(fit, images, &fdt_offset);
@@ -236,8 +241,14 @@ int spl_load_simple_fit(struct spl_load_info *info, ulong sector, void *fit)
*/
debug("fdt: dst=%p, data_offset=%x, size=%x\n", dst, fdt_offset,
fdt_len);
- memcpy(load_ptr + data_size,
- dst + get_aligned_image_overhead(info, fdt_offset), fdt_len);
+ src = dst + get_aligned_image_overhead(info, fdt_offset);
+ dst = load_ptr + data_size;
+
+#ifdef CONFIG_SPL_FIT_IMAGE_POST_PROCESS
+ board_fit_image_post_process((void **)&src, (size_t *)&fdt_len);
+#endif
+
+ memcpy(dst, src, fdt_len);
return 0;
}
diff --git a/common/spl/spl_mmc.c b/common/spl/spl_mmc.c
index c44f1b5..6b3e9e4 100644
--- a/common/spl/spl_mmc.c
+++ b/common/spl/spl_mmc.c
@@ -184,7 +184,7 @@ static int mmc_load_image_raw_os(struct mmc *mmc)
unsigned long count;
int ret;
- count = mmc->block_dev.block_read(&mmc->block_dev,
+ count = blk_dread(mmc_get_blk_desc(mmc),
CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTOR,
CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTORS,
(void *) CONFIG_SYS_SPL_ARGS_ADDR);
@@ -225,13 +225,13 @@ int spl_mmc_do_fs_boot(struct mmc *mmc)
#ifdef CONFIG_SPL_FAT_SUPPORT
if (!spl_start_uboot()) {
- err = spl_load_image_fat_os(&mmc->block_dev,
+ err = spl_load_image_fat_os(mmc_get_blk_desc(mmc),
CONFIG_SYS_MMCSD_FS_BOOT_PARTITION);
if (!err)
return err;
}
#ifdef CONFIG_SPL_FS_LOAD_PAYLOAD_NAME
- err = spl_load_image_fat(&mmc->block_dev,
+ err = spl_load_image_fat(mmc_get_blk_desc(mmc),
CONFIG_SYS_MMCSD_FS_BOOT_PARTITION,
CONFIG_SPL_FS_LOAD_PAYLOAD_NAME);
if (!err)
diff --git a/configs/am43xx_hs_evm_defconfig b/configs/am43xx_hs_evm_defconfig
index 4856a19..68dfb6c 100644
--- a/configs/am43xx_hs_evm_defconfig
+++ b/configs/am43xx_hs_evm_defconfig
@@ -13,6 +13,7 @@ CONFIG_SPL_STACK_R=y
CONFIG_FIT=y
CONFIG_SYS_EXTRA_OPTIONS="CONS_INDEX=1, NAND"
CONFIG_SPL_LOAD_FIT=y
+CONFIG_SPL_FIT_IMAGE_POST_PROCESS=y
CONFIG_HUSH_PARSER=y
CONFIG_CMD_BOOTZ=y
# CONFIG_CMD_IMLS is not set
diff --git a/configs/am57xx_hs_evm_defconfig b/configs/am57xx_hs_evm_defconfig
index e01e504..01a4701 100644
--- a/configs/am57xx_hs_evm_defconfig
+++ b/configs/am57xx_hs_evm_defconfig
@@ -40,4 +40,5 @@ CONFIG_USB_XHCI_DWC3=y
CONFIG_FIT=y
CONFIG_SPL_OF_LIBFDT=y
CONFIG_SPL_LOAD_FIT=y
+CONFIG_SPL_FIT_IMAGE_POST_PROCESS=y
CONFIG_OF_LIST="am57xx-beagle-x15"
diff --git a/configs/bayleybay_defconfig b/configs/bayleybay_defconfig
index 9f1d7fb..0a71bb8 100644
--- a/configs/bayleybay_defconfig
+++ b/configs/bayleybay_defconfig
@@ -2,6 +2,7 @@ CONFIG_X86=y
CONFIG_VENDOR_INTEL=y
CONFIG_DEFAULT_DEVICE_TREE="bayleybay"
CONFIG_TARGET_BAYLEYBAY=y
+CONFIG_INTERNAL_UART=y
CONFIG_HAVE_INTEL_ME=y
CONFIG_ENABLE_MRC_CACHE=y
CONFIG_SMP=y
diff --git a/configs/conga-qeval20-qa3-e3845-internal-uart_defconfig b/configs/conga-qeval20-qa3-e3845-internal-uart_defconfig
new file mode 100644
index 0000000..26f83ba
--- /dev/null
+++ b/configs/conga-qeval20-qa3-e3845-internal-uart_defconfig
@@ -0,0 +1,63 @@
+CONFIG_X86=y
+CONFIG_VENDOR_CONGATEC=y
+CONFIG_TARGET_CONGA_QEVAL20_QA3_E3845=y
+CONFIG_DEFAULT_DEVICE_TREE="conga-qeval20-qa3-e3845"
+CONFIG_INTERNAL_UART=y
+CONFIG_HAVE_INTEL_ME=y
+CONFIG_ENABLE_MRC_CACHE=y
+CONFIG_SMP=y
+CONFIG_HAVE_VGA_BIOS=y
+CONFIG_GENERATE_PIRQ_TABLE=y
+CONFIG_GENERATE_MP_TABLE=y
+CONFIG_GENERATE_ACPI_TABLE=y
+CONFIG_SEABIOS=y
+CONFIG_FIT=y
+CONFIG_FIT_SIGNATURE=y
+CONFIG_BOOTSTAGE=y
+CONFIG_BOOTSTAGE_REPORT=y
+CONFIG_HUSH_PARSER=y
+CONFIG_CMD_CPU=y
+# CONFIG_CMD_IMLS is not set
+# CONFIG_CMD_FLASH is not set
+CONFIG_CMD_MMC=y
+CONFIG_CMD_SF=y
+CONFIG_CMD_SPI=y
+CONFIG_CMD_USB=y
+CONFIG_CMD_GPIO=y
+# CONFIG_CMD_SETEXPR is not set
+CONFIG_CMD_DHCP=y
+# CONFIG_CMD_NFS is not set
+CONFIG_CMD_PING=y
+CONFIG_CMD_TIME=y
+CONFIG_CMD_BOOTSTAGE=y
+CONFIG_CMD_EXT2=y
+CONFIG_CMD_EXT4=y
+CONFIG_CMD_EXT4_WRITE=y
+CONFIG_CMD_FAT=y
+CONFIG_CMD_FS_GENERIC=y
+CONFIG_OF_CONTROL=y
+CONFIG_REGMAP=y
+CONFIG_SYSCON=y
+CONFIG_CPU=y
+CONFIG_WINBOND_W83627=y
+CONFIG_SPI_FLASH=y
+CONFIG_SPI_FLASH_GIGADEVICE=y
+CONFIG_SPI_FLASH_MACRONIX=y
+CONFIG_SPI_FLASH_STMICRO=y
+CONFIG_SPI_FLASH_WINBOND=y
+CONFIG_DM_ETH=y
+CONFIG_E1000=y
+CONFIG_DM_PCI=y
+CONFIG_DM_RTC=y
+CONFIG_DEBUG_UART=y
+CONFIG_DEBUG_UART_BASE=0x3f8
+CONFIG_DEBUG_UART_CLOCK=1843200
+CONFIG_SYS_NS16550=y
+CONFIG_ICH_SPI=y
+CONFIG_TIMER=y
+CONFIG_USB=y
+CONFIG_DM_USB=y
+CONFIG_VIDEO_VESA=y
+CONFIG_FRAMEBUFFER_SET_VESA_MODE=y
+CONFIG_FRAMEBUFFER_VESA_MODE_114=y
+CONFIG_USE_PRIVATE_LIBGCC=y
diff --git a/configs/da850evm_defconfig b/configs/da850evm_defconfig
index 0e281a5..40ab975 100644
--- a/configs/da850evm_defconfig
+++ b/configs/da850evm_defconfig
@@ -5,6 +5,7 @@ CONFIG_SPL=y
CONFIG_SYS_EXTRA_OPTIONS="MAC_ADDR_IN_SPIFLASH"
CONFIG_BOOTDELAY=3
CONFIG_HUSH_PARSER=y
+CONFIG_CMD_BOOTZ=y
CONFIG_SYS_PROMPT="U-Boot > "
# CONFIG_CMD_IMLS is not set
CONFIG_CMD_ASKENV=y
diff --git a/configs/dra7xx_hs_evm_defconfig b/configs/dra7xx_hs_evm_defconfig
index 6933ab5..eb01f41 100644
--- a/configs/dra7xx_hs_evm_defconfig
+++ b/configs/dra7xx_hs_evm_defconfig
@@ -58,4 +58,5 @@ CONFIG_G_DNL_PRODUCT_NUM=0xd022
CONFIG_FIT=y
CONFIG_SPL_OF_LIBFDT=y
CONFIG_SPL_LOAD_FIT=y
+CONFIG_SPL_FIT_IMAGE_POST_PROCESS=y
CONFIG_OF_LIST="dra7-evm dra72-evm"
diff --git a/configs/dragonboard410c_defconfig b/configs/dragonboard410c_defconfig
index 37c5ea77..ad2e8b8 100644
--- a/configs/dragonboard410c_defconfig
+++ b/configs/dragonboard410c_defconfig
@@ -18,6 +18,7 @@ CONFIG_CMD_EXT2=y
CONFIG_CMD_EXT4=y
CONFIG_CMD_FAT=y
CONFIG_CMD_FS_GENERIC=y
+CONFIG_BLK=y
CONFIG_CLK=y
CONFIG_MSM_GPIO=y
CONFIG_PM8916_GPIO=y
@@ -25,6 +26,7 @@ CONFIG_LED=y
CONFIG_LED_GPIO=y
CONFIG_SYSRESET=y
CONFIG_DM_MMC=y
+CONFIG_DM_MMC_OPS=y
CONFIG_MSM_SDHCI=y
CONFIG_DM_PMIC=y
CONFIG_PMIC_PM8916=y
diff --git a/configs/firefly-rk3288_defconfig b/configs/firefly-rk3288_defconfig
index 4af9120..bdafc71 100644
--- a/configs/firefly-rk3288_defconfig
+++ b/configs/firefly-rk3288_defconfig
@@ -69,3 +69,6 @@ CONFIG_USE_PRIVATE_LIBGCC=y
CONFIG_USE_TINY_PRINTF=y
CONFIG_CMD_DHRYSTONE=y
CONFIG_ERRNO_STR=y
+CONFIG_SPL_OF_PLATDATA=y
+# CONFIG_SPL_OF_LIBFDT is not set
+CONFIG_ROCKCHIP_SERIAL=y
diff --git a/configs/k2e_evm_defconfig b/configs/k2e_evm_defconfig
index 9fcdfe9..65561b1 100644
--- a/configs/k2e_evm_defconfig
+++ b/configs/k2e_evm_defconfig
@@ -28,6 +28,8 @@ CONFIG_CMD_FS_GENERIC=y
CONFIG_OF_CONTROL=y
CONFIG_DM=y
CONFIG_TI_AEMIF=y
+CONFIG_DM_SPI=y
+CONFIG_DM_SPI_FLASH=y
CONFIG_SPI_FLASH=y
CONFIG_SPI_FLASH_STMICRO=y
CONFIG_DM_ETH=y
diff --git a/configs/k2g_evm_defconfig b/configs/k2g_evm_defconfig
index 8efa58c..5d44e8d 100644
--- a/configs/k2g_evm_defconfig
+++ b/configs/k2g_evm_defconfig
@@ -27,6 +27,8 @@ CONFIG_CMD_FAT=y
CONFIG_CMD_FS_GENERIC=y
CONFIG_OF_CONTROL=y
CONFIG_DM=y
+CONFIG_DM_SPI=y
+CONFIG_DM_SPI_FLASH=y
CONFIG_SPI_FLASH=y
CONFIG_SPI_FLASH_STMICRO=y
CONFIG_DM_ETH=y
@@ -35,3 +37,5 @@ CONFIG_SYS_NS16550=y
CONFIG_USB=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_DWC3=y
+CONFIG_SPI_FLASH_SPANSION=y
+CONFIG_SPI_FLASH_BAR=y
diff --git a/configs/k2hk_evm_defconfig b/configs/k2hk_evm_defconfig
index 278eaf3..8623e1c 100644
--- a/configs/k2hk_evm_defconfig
+++ b/configs/k2hk_evm_defconfig
@@ -28,6 +28,8 @@ CONFIG_CMD_FS_GENERIC=y
CONFIG_OF_CONTROL=y
CONFIG_DM=y
CONFIG_TI_AEMIF=y
+CONFIG_DM_SPI=y
+CONFIG_DM_SPI_FLASH=y
CONFIG_SPI_FLASH=y
CONFIG_SPI_FLASH_STMICRO=y
CONFIG_DM_ETH=y
diff --git a/configs/k2l_evm_defconfig b/configs/k2l_evm_defconfig
index 8417e0a..9aa429c 100644
--- a/configs/k2l_evm_defconfig
+++ b/configs/k2l_evm_defconfig
@@ -28,6 +28,8 @@ CONFIG_CMD_FS_GENERIC=y
CONFIG_OF_CONTROL=y
CONFIG_DM=y
CONFIG_TI_AEMIF=y
+CONFIG_DM_SPI=y
+CONFIG_DM_SPI_FLASH=y
CONFIG_SPI_FLASH=y
CONFIG_SPI_FLASH_STMICRO=y
CONFIG_DM_ETH=y
diff --git a/configs/minnowmax_defconfig b/configs/minnowmax_defconfig
index 28b837d..ba2b7dc 100644
--- a/configs/minnowmax_defconfig
+++ b/configs/minnowmax_defconfig
@@ -2,6 +2,7 @@ CONFIG_X86=y
CONFIG_VENDOR_INTEL=y
CONFIG_DEFAULT_DEVICE_TREE="minnowmax"
CONFIG_TARGET_MINNOWMAX=y
+CONFIG_INTERNAL_UART=y
CONFIG_HAVE_INTEL_ME=y
CONFIG_ENABLE_MRC_CACHE=y
CONFIG_SMP=y
diff --git a/configs/orangepi_lite_defconfig b/configs/orangepi_lite_defconfig
new file mode 100644
index 0000000..417e4f6
--- /dev/null
+++ b/configs/orangepi_lite_defconfig
@@ -0,0 +1,15 @@
+CONFIG_ARM=y
+CONFIG_ARCH_SUNXI=y
+CONFIG_MACH_SUN8I_H3=y
+CONFIG_DRAM_CLK=672
+CONFIG_DRAM_ZQ=3881979
+CONFIG_DRAM_ODT_EN=y
+CONFIG_MMC0_CD_PIN="PF6"
+# CONFIG_VIDEO is not set
+CONFIG_DEFAULT_DEVICE_TREE="sun8i-h3-orangepi-lite"
+# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+CONFIG_SPL=y
+# CONFIG_CMD_IMLS is not set
+# CONFIG_CMD_FLASH is not set
+# CONFIG_CMD_FPGA is not set
+CONFIG_USB_EHCI_HCD=y
diff --git a/configs/orangepi_pc_defconfig b/configs/orangepi_pc_defconfig
index 7eaa795..43ec927 100644
--- a/configs/orangepi_pc_defconfig
+++ b/configs/orangepi_pc_defconfig
@@ -4,6 +4,8 @@ CONFIG_MACH_SUN8I_H3=y
CONFIG_DRAM_CLK=624
CONFIG_DRAM_ZQ=3881979
CONFIG_DRAM_ODT_EN=y
+CONFIG_MMC0_CD_PIN="PF6"
+CONFIG_MMC_SUNXI_SLOT_EXTRA=2
# CONFIG_VIDEO is not set
CONFIG_DEFAULT_DEVICE_TREE="sun8i-h3-orangepi-pc"
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
@@ -13,3 +15,4 @@ CONFIG_SPL=y
# CONFIG_CMD_FPGA is not set
CONFIG_SY8106A_POWER=y
CONFIG_USB_EHCI_HCD=y
+CONFIG_SUN8I_EMAC=y
diff --git a/configs/pine64_plus_defconfig b/configs/pine64_plus_defconfig
index 0bf79bf..5c97de1 100644
--- a/configs/pine64_plus_defconfig
+++ b/configs/pine64_plus_defconfig
@@ -10,3 +10,4 @@ CONFIG_DEFAULT_DEVICE_TREE="sun50i-a64-pine64-plus"
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_FPGA is not set
CONFIG_ENABLE_ARM_SOC_BOOT0_HOOK=y
+CONFIG_SUN8I_EMAC=y
diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index 94253a6..6a1874a 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -1,5 +1,4 @@
CONFIG_SYS_MALLOC_F_LEN=0x2000
-CONFIG_BLK=y
CONFIG_MMC=y
CONFIG_PCI=y
CONFIG_DEFAULT_DEVICE_TREE="sandbox"
@@ -71,6 +70,7 @@ CONFIG_DEVRES=y
CONFIG_DEBUG_DEVRES=y
CONFIG_ADC=y
CONFIG_ADC_SANDBOX=y
+CONFIG_BLK=y
CONFIG_CLK=y
CONFIG_CPU=y
CONFIG_DM_DEMO=y
@@ -101,7 +101,7 @@ CONFIG_CROS_EC_SPI=y
CONFIG_PWRSEQ=y
CONFIG_SPL_PWRSEQ=y
CONFIG_SYSRESET=y
-CONFIG_DM_MMC=y
+CONFIG_DM_MMC_OPS=y
CONFIG_SANDBOX_MMC=y
CONFIG_SPI_FLASH_SANDBOX=y
CONFIG_SPI_FLASH=y
diff --git a/configs/sandbox_spl_defconfig b/configs/sandbox_spl_defconfig
new file mode 100644
index 0000000..0f6dda8
--- /dev/null
+++ b/configs/sandbox_spl_defconfig
@@ -0,0 +1,183 @@
+CONFIG_SYS_MALLOC_F_LEN=0x2000
+CONFIG_MMC=y
+CONFIG_SANDBOX_SPL=y
+CONFIG_PCI=y
+CONFIG_DEFAULT_DEVICE_TREE="sandbox"
+CONFIG_I8042_KEYB=y
+CONFIG_SPL=y
+CONFIG_FIT=y
+CONFIG_FIT_VERBOSE=y
+CONFIG_FIT_SIGNATURE=y
+CONFIG_SPL_LOAD_FIT=y
+CONFIG_BOOTSTAGE=y
+CONFIG_BOOTSTAGE_REPORT=y
+CONFIG_BOOTSTAGE_USER_COUNT=0x20
+CONFIG_BOOTSTAGE_FDT=y
+CONFIG_BOOTSTAGE_STASH=y
+CONFIG_BOOTSTAGE_STASH_ADDR=0x0
+CONFIG_BOOTSTAGE_STASH_SIZE=0x4096
+CONFIG_CONSOLE_RECORD=y
+CONFIG_CONSOLE_RECORD_OUT_SIZE=0x1000
+CONFIG_HUSH_PARSER=y
+CONFIG_CMD_CPU=y
+CONFIG_CMD_LICENSE=y
+CONFIG_CMD_BOOTZ=y
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_IMLS is not set
+CONFIG_CMD_ASKENV=y
+CONFIG_CMD_GREPENV=y
+CONFIG_LOOPW=y
+CONFIG_CMD_MEMTEST=y
+CONFIG_CMD_MX_CYCLIC=y
+CONFIG_CMD_MEMINFO=y
+CONFIG_CMD_DEMO=y
+CONFIG_CMD_SF=y
+CONFIG_CMD_SPI=y
+CONFIG_CMD_I2C=y
+CONFIG_CMD_USB=y
+CONFIG_CMD_REMOTEPROC=y
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_TFTPPUT=y
+CONFIG_CMD_TFTPSRV=y
+CONFIG_CMD_RARP=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
+CONFIG_CMD_CDP=y
+CONFIG_CMD_SNTP=y
+CONFIG_CMD_DNS=y
+CONFIG_CMD_LINK_LOCAL=y
+CONFIG_CMD_TIME=y
+CONFIG_CMD_TIMER=y
+CONFIG_CMD_SOUND=y
+CONFIG_CMD_QFW=y
+CONFIG_CMD_BOOTSTAGE=y
+CONFIG_CMD_PMIC=y
+CONFIG_CMD_REGULATOR=y
+CONFIG_CMD_TPM=y
+CONFIG_CMD_TPM_TEST=y
+CONFIG_CMD_EXT2=y
+CONFIG_CMD_EXT4=y
+CONFIG_CMD_EXT4_WRITE=y
+CONFIG_CMD_FAT=y
+CONFIG_CMD_FS_GENERIC=y
+CONFIG_OF_CONTROL=y
+CONFIG_SPL_OF_CONTROL=y
+CONFIG_OF_HOSTFILE=y
+CONFIG_SPL_OF_PLATDATA=y
+CONFIG_NETCONSOLE=y
+CONFIG_SPL_DM=y
+CONFIG_REGMAP=y
+CONFIG_SPL_REGMAP=y
+CONFIG_SYSCON=y
+CONFIG_SPL_SYSCON=y
+CONFIG_DEVRES=y
+CONFIG_DEBUG_DEVRES=y
+# CONFIG_SPL_SIMPLE_BUS is not set
+CONFIG_ADC=y
+CONFIG_ADC_SANDBOX=y
+CONFIG_BLK=y
+CONFIG_CLK=y
+CONFIG_CPU=y
+CONFIG_DM_DEMO=y
+CONFIG_DM_DEMO_SIMPLE=y
+CONFIG_DM_DEMO_SHAPE=y
+CONFIG_PM8916_GPIO=y
+CONFIG_SANDBOX_GPIO=y
+CONFIG_DM_I2C_COMPAT=y
+CONFIG_I2C_CROS_EC_TUNNEL=y
+CONFIG_I2C_CROS_EC_LDO=y
+CONFIG_DM_I2C_GPIO=y
+CONFIG_SYS_I2C_SANDBOX=y
+CONFIG_I2C_MUX=y
+CONFIG_SPL_I2C_MUX=y
+CONFIG_I2C_ARB_GPIO_CHALLENGE=y
+CONFIG_CROS_EC_KEYB=y
+CONFIG_LED=y
+CONFIG_LED_GPIO=y
+CONFIG_DM_MAILBOX=y
+CONFIG_SANDBOX_MBOX=y
+CONFIG_MISC=y
+CONFIG_CMD_CROS_EC=y
+CONFIG_CROS_EC=y
+CONFIG_CROS_EC_I2C=y
+CONFIG_CROS_EC_LPC=y
+CONFIG_CROS_EC_SANDBOX=y
+CONFIG_CROS_EC_SPI=y
+CONFIG_PWRSEQ=y
+CONFIG_SPL_PWRSEQ=y
+CONFIG_SYSRESET=y
+CONFIG_DM_MMC_OPS=y
+CONFIG_SANDBOX_MMC=y
+CONFIG_SPI_FLASH_SANDBOX=y
+CONFIG_SPI_FLASH=y
+CONFIG_SPI_FLASH_ATMEL=y
+CONFIG_SPI_FLASH_EON=y
+CONFIG_SPI_FLASH_GIGADEVICE=y
+CONFIG_SPI_FLASH_MACRONIX=y
+CONFIG_SPI_FLASH_SPANSION=y
+CONFIG_SPI_FLASH_STMICRO=y
+CONFIG_SPI_FLASH_SST=y
+CONFIG_SPI_FLASH_WINBOND=y
+CONFIG_DM_ETH=y
+CONFIG_DM_PCI=y
+CONFIG_DM_PCI_COMPAT=y
+CONFIG_PCI_SANDBOX=y
+CONFIG_PINCTRL=y
+CONFIG_PINCONF=y
+CONFIG_ROCKCHIP_PINCTRL=y
+CONFIG_ROCKCHIP_3036_PINCTRL=y
+CONFIG_PINCTRL_SANDBOX=y
+CONFIG_DM_PMIC=y
+CONFIG_PMIC_ACT8846=y
+CONFIG_DM_PMIC_PFUZE100=y
+CONFIG_DM_PMIC_MAX77686=y
+CONFIG_PMIC_PM8916=y
+CONFIG_PMIC_RK808=y
+CONFIG_PMIC_S2MPS11=y
+CONFIG_DM_PMIC_SANDBOX=y
+CONFIG_PMIC_S5M8767=y
+CONFIG_PMIC_TPS65090=y
+CONFIG_DM_REGULATOR=y
+CONFIG_REGULATOR_ACT8846=y
+CONFIG_DM_REGULATOR_PFUZE100=y
+CONFIG_DM_REGULATOR_MAX77686=y
+CONFIG_DM_REGULATOR_FIXED=y
+CONFIG_REGULATOR_RK808=y
+CONFIG_REGULATOR_S5M8767=y
+CONFIG_DM_REGULATOR_SANDBOX=y
+CONFIG_REGULATOR_TPS65090=y
+CONFIG_RAM=y
+CONFIG_REMOTEPROC_SANDBOX=y
+CONFIG_DM_RESET=y
+CONFIG_SANDBOX_RESET=y
+CONFIG_DM_RTC=y
+CONFIG_SANDBOX_SERIAL=y
+CONFIG_SOUND=y
+CONFIG_SOUND_SANDBOX=y
+CONFIG_SANDBOX_SPI=y
+CONFIG_SPMI=y
+CONFIG_SPMI_SANDBOX=y
+CONFIG_TIMER=y
+CONFIG_TIMER_EARLY=y
+CONFIG_SANDBOX_TIMER=y
+CONFIG_TPM_TIS_SANDBOX=y
+CONFIG_USB=y
+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
+CONFIG_CONSOLE_TRUETYPE_CANTORAONE=y
+CONFIG_VIDEO_SANDBOX_SDL=y
+CONFIG_CMD_DHRYSTONE=y
+CONFIG_TPM=y
+CONFIG_LZ4=y
+CONFIG_ERRNO_STR=y
+CONFIG_UNIT_TEST=y
+CONFIG_UT_TIME=y
+CONFIG_UT_DM=y
+CONFIG_UT_ENV=y
diff --git a/configs/som-db5800-som-6867_defconfig b/configs/som-db5800-som-6867_defconfig
new file mode 100644
index 0000000..30e093b
--- /dev/null
+++ b/configs/som-db5800-som-6867_defconfig
@@ -0,0 +1,61 @@
+CONFIG_X86=y
+CONFIG_VENDOR_ADVANTECH=y
+CONFIG_DEFAULT_DEVICE_TREE="baytrail_som-db5800-som-6867"
+CONFIG_TARGET_SOM_DB5800_SOM_6867=y
+CONFIG_HAVE_INTEL_ME=y
+CONFIG_ENABLE_MRC_CACHE=y
+CONFIG_SMP=y
+CONFIG_HAVE_VGA_BIOS=y
+CONFIG_GENERATE_PIRQ_TABLE=y
+CONFIG_GENERATE_MP_TABLE=y
+CONFIG_GENERATE_ACPI_TABLE=y
+CONFIG_SEABIOS=y
+CONFIG_FIT=y
+CONFIG_FIT_SIGNATURE=y
+CONFIG_BOOTSTAGE=y
+CONFIG_BOOTSTAGE_REPORT=y
+CONFIG_HUSH_PARSER=y
+CONFIG_CMD_CPU=y
+# CONFIG_CMD_IMLS is not set
+# CONFIG_CMD_FLASH is not set
+# CONFIG_CMD_MMC is not set
+CONFIG_CMD_SF=y
+CONFIG_CMD_SPI=y
+CONFIG_CMD_USB=y
+CONFIG_CMD_GPIO=y
+# CONFIG_CMD_SETEXPR is not set
+CONFIG_CMD_DHCP=y
+# CONFIG_CMD_NFS is not set
+CONFIG_CMD_PING=y
+CONFIG_CMD_TIME=y
+CONFIG_CMD_BOOTSTAGE=y
+CONFIG_CMD_EXT2=y
+CONFIG_CMD_EXT4=y
+CONFIG_CMD_EXT4_WRITE=y
+CONFIG_CMD_FAT=y
+CONFIG_CMD_FS_GENERIC=y
+CONFIG_OF_CONTROL=y
+CONFIG_REGMAP=y
+CONFIG_SYSCON=y
+CONFIG_CPU=y
+CONFIG_SPI_FLASH=y
+CONFIG_SPI_FLASH_GIGADEVICE=y
+CONFIG_SPI_FLASH_MACRONIX=y
+CONFIG_SPI_FLASH_STMICRO=y
+CONFIG_SPI_FLASH_WINBOND=y
+CONFIG_DM_ETH=y
+CONFIG_E1000=y
+CONFIG_DM_PCI=y
+CONFIG_DM_RTC=y
+CONFIG_DEBUG_UART=y
+CONFIG_DEBUG_UART_BASE=0x3f8
+CONFIG_DEBUG_UART_CLOCK=1843200
+CONFIG_SYS_NS16550=y
+CONFIG_ICH_SPI=y
+CONFIG_TIMER=y
+CONFIG_USB=y
+CONFIG_DM_USB=y
+CONFIG_VIDEO_VESA=y
+CONFIG_FRAMEBUFFER_SET_VESA_MODE=y
+CONFIG_FRAMEBUFFER_VESA_MODE_11A=y
+CONFIG_USE_PRIVATE_LIBGCC=y
diff --git a/doc/README.gpt b/doc/README.gpt
index a6f6de6..3fcd835 100644
--- a/doc/README.gpt
+++ b/doc/README.gpt
@@ -165,7 +165,7 @@ To restore GUID partition table one needs to:
The fields 'name' and 'size' are mandatory for every partition.
The field 'start' is optional.
- If field 'size' of the last partition is 0, the partiton is extended
+ If field 'size' of the last partition is 0, the partition is extended
up to the end of the device.
The fields 'uuid' and 'uuid_disk' are optional if CONFIG_RANDOM_UUID is
diff --git a/doc/README.scrapyard b/doc/README.scrapyard
index b7cf62d..200f670 100644
--- a/doc/README.scrapyard
+++ b/doc/README.scrapyard
@@ -3,7 +3,7 @@ while other board support code dies a silent death caused by
negligence in combination with ordinary bitrot. Sometimes this goes
by unnoticed, but often build errors will result. If nobody cares any
more to resolve such problems, then the code is really dead and will
-be removed from the U-Boot source tree. The remainders rest in piece
+be removed from the U-Boot source tree. The remainders rest in peace
in the imperishable depths of the git history. This document tries to
maintain a list of such former fellows, so archaeologists can check
easily if there is something they might want to dig for...
diff --git a/doc/README.ti-secure b/doc/README.ti-secure
index 7fc9b9b..54c996d 100644
--- a/doc/README.ti-secure
+++ b/doc/README.ti-secure
@@ -19,69 +19,80 @@ control restrictions. Access must be requested and granted by TI before the
package is viewable and downloadable. Contact TI, either online or by way
of a local TI representative, to request access.
-When CONFIG_TI_SECURE_DEVICE is set, the U-Boot SPL build process requires
-the presence and use of these tools in order to create a viable boot image.
-The build process will look for the environment variable TI_SECURE_DEV_PKG,
-which should be the path of the installed SECDEV package. If the
-TI_SECURE_DEV_PKG variable is not defined or if it is defined but doesn't
-point to a valid SECDEV package, a warning is issued during the build to
-indicate that a final secure bootable image was not created.
-
-Within the SECDEV package exists an image creation script:
-
-${TI_SECURE_DEV_PKG}/scripts/create-boot-image.sh
-
-This is called as part of the SPL/u-boot build process. As the secure boot
-image formats and requirements differ between secure SOC from TI, the
-purpose of this script is to abstract these details as much as possible.
-
-The script is basically the only required interface to the TI SECDEV package
-for secure TI devices.
-
-Invoking the script for AM43xx Secure Devices
-=============================================
-
-create-boot-image.sh <IMAGE_FLAG> <INPUT_FILE> <OUTPUT_FILE> <SPL_LOAD_ADDR>
-
-<IMAGE_FLAG> is a value that specifies the type of the image to generate OR
-the action the image generation tool will take. Valid values are:
- SPI_X-LOADER - Generates an image for SPI flash (byte swapped)
- XIP_X-LOADER - Generates a single stage u-boot for NOR/QSPI XiP
- ISSW - Generates an image for all other boot modes
-
-<INPUT_FILE> is the full path and filename of the public world boot loader
-binary file (depending on the boot media, this is usually either
-u-boot-spl.bin or u-boot.bin).
-
-<OUTPUT_FILE> is the full path and filename of the final secure image. The
-output binary images should be used in place of the standard non-secure
-binary images (see the platform-specific user's guides and releases notes
-for how the non-secure images are typically used)
+Booting of U-Boot SPL
+=====================
+
+ When CONFIG_TI_SECURE_DEVICE is set, the U-Boot SPL build process
+ requires the presence and use of these tools in order to create a
+ viable boot image. The build process will look for the environment
+ variable TI_SECURE_DEV_PKG, which should be the path of the installed
+ SECDEV package. If the TI_SECURE_DEV_PKG variable is not defined or
+ if it is defined but doesn't point to a valid SECDEV package, a
+ warning is issued during the build to indicate that a final secure
+ bootable image was not created.
+
+ Within the SECDEV package exists an image creation script:
+
+ ${TI_SECURE_DEV_PKG}/scripts/create-boot-image.sh
+
+ This is called as part of the SPL/u-boot build process. As the secure
+ boot image formats and requirements differ between secure SOC from TI,
+ the purpose of this script is to abstract these details as much as
+ possible.
+
+ The script is basically the only required interface to the TI SECDEV
+ package for creating a bootable SPL image for secure TI devices.
+
+ Invoking the script for AM43xx Secure Devices
+ =============================================
+
+ create-boot-image.sh \
+ <IMAGE_FLAG> <INPUT_FILE> <OUTPUT_FILE> <SPL_LOAD_ADDR>
+
+ <IMAGE_FLAG> is a value that specifies the type of the image to
+ generate OR the action the image generation tool will take. Valid
+ values are:
+ SPI_X-LOADER - Generates an image for SPI flash (byte
+ swapped)
+ XIP_X-LOADER - Generates a single stage u-boot for
+ NOR/QSPI XiP
+ ISSW - Generates an image for all other boot modes
+
+ <INPUT_FILE> is the full path and filename of the public world boot
+ loaderbinary file (depending on the boot media, this is usually
+ either u-boot-spl.bin or u-boot.bin).
+
+ <OUTPUT_FILE> is the full path and filename of the final secure
+ image. The output binary images should be used in place of the standard
+ non-secure binary images (see the platform-specific user's guides and
+ releases notes for how the non-secure images are typically used)
u-boot-spl_HS_SPI_X-LOADER - byte swapped boot image for SPI flash
u-boot_HS_XIP_X-LOADER - boot image for NOR or QSPI flash
u-boot-spl_HS_ISSW - boot image for all other boot media
-<SPL_LOAD_ADDR> is the address at which SOC ROM should load the <INPUT_FILE>
+ <SPL_LOAD_ADDR> is the address at which SOC ROM should load the
+ <INPUT_FILE>
-Invoking the script for DRA7xx/AM57xx Secure Devices
-====================================================
+ Invoking the script for DRA7xx/AM57xx Secure Devices
+ ====================================================
-create-boot-image.sh <IMAGE_TYPE> <INPUT_FILE> <OUTPUT_FILE>
+ create-boot-image.sh <IMAGE_TYPE> <INPUT_FILE> <OUTPUT_FILE>
-<IMAGE_TYPE> is a value that specifies the type of the image to generate OR
-the action the image generation tool will take. Valid values are:
- X-LOADER - Generates an image for NOR or QSPI boot modes
- MLO - Generates an image for SD/MMC/eMMC boot modes
- ULO - Generates an image for USB/UART peripheral boot modes
- Note: ULO is not yet used by the u-boot build process
+ <IMAGE_TYPE> is a value that specifies the type of the image to
+ generate OR the action the image generation tool will take. Valid
+ values are:
+ X-LOADER - Generates an image for NOR or QSPI boot modes
+ MLO - Generates an image for SD/MMC/eMMC boot modes
+ ULO - Generates an image for USB/UART peripheral boot modes
+ Note: ULO is not yet used by the u-boot build process
-<INPUT_FILE> is the full path and filename of the public world boot loader
-binary file (for this platform, this is always u-boot-spl.bin).
+ <INPUT_FILE> is the full path and filename of the public world boot
+ loader binary file (for this platform, this is always u-boot-spl.bin).
-<OUTPUT_FILE> is the full path and filename of the final secure image. The
-output binary images should be used in place of the standard non-secure
-binary images (see the platform-specific user's guides and releases notes
-for how the non-secure images are typically used)
+ <OUTPUT_FILE> is the full path and filename of the final secure image.
+ The output binary images should be used in place of the standard
+ non-secure binary images (see the platform-specific user's guides
+ and releases notes for how the non-secure images are typically used)
u-boot-spl_HS_MLO - boot image for SD/MMC/eMMC. This image is
copied to a file named MLO, which is the name that
the device ROM bootloader requires for loading from
@@ -89,3 +100,61 @@ for how the non-secure images are typically used)
non-secure devices)
u-boot-spl_HS_X-LOADER - boot image for all other flash memories
including QSPI and NOR flash
+
+Booting of Primary U-Boot (u-boot.img)
+======================================
+
+ The SPL image is responsible for loading the next stage boot loader,
+ which is the main u-boot image. For secure TI devices, the SPL will
+ be authenticated, as described above, as part of the particular
+ device's ROM boot process. In order to continue the secure boot
+ process, the authenticated SPL must authenticate the main u-boot
+ image that it loads.
+
+ The configurations for secure TI platforms are written to make the boot
+ process use the FIT image format for the u-boot.img (CONFIG_SPL_FRAMEWORK
+ and CONFIG_SPL_LOAD_FIT). With these configurations the binary
+ components that the SPL loads include a specific DTB image and u-boot
+ image. These DTB image may be one of many available to the boot
+ process. In order to secure these components so that they can be
+ authenticated by the SPL as they are loaded from the FIT image, the
+ build procedure for secure TI devices will secure these images before
+ they are integrated into the FIT image. When those images are extracted
+ from the FIT image at boot time, they are post-processed to verify that
+ they are still secure. The outlined security-related SPL post-processing
+ is enabled through the CONFIG_SPL_FIT_IMAGE_POST_PROCESS option which
+ must be enabled for the secure boot scheme to work. In order to allow
+ verifying proper operation of the secure boot chain in case of successful
+ authentication messages like "Authentication passed: CERT_U-BOOT-NOD" are
+ output by the SPL to the console for each blob that got extracted from the
+ FIT image. Note that the last part of this log message is the (truncated)
+ name of the signing certificate embedded into the blob that got processed.
+
+ The exact details of the how the images are secured is handled by the
+ SECDEV package. Within the SECDEV package exists a script to process
+ an input binary image:
+
+ ${TI_SECURE_DEV_PKG}/scripts/secure-binary-image.sh
+
+ This is called as part of the u-boot build process. As the secure
+ image formats and requirements can differ between the various secure
+ SOCs from TI, this script in the SECDEV package abstracts these
+ details. This script is essentially the only required interface to the
+ TI SECDEV package for creating a u-boot.img image for secure TI
+ devices.
+
+ The SPL/u-boot code contains calls to dedicated secure ROM functions
+ to perform the validation on the secured images. The details of the
+ interface to those functions is shown in the code. The summary
+ is that they are accessed by invoking an ARM secure monitor call to
+ the device's secure ROM (fixed read-only-memory that is secure and
+ only accessible when the ARM core is operating in the secure mode).
+
+ Invoking the secure-binary-image script for Secure Devices
+ ==========================================================
+
+ secure-binary-image.sh <INPUT_FILE> <OUTPUT_FILE>
+
+ <INPUT_FILE> is the full path and filename of the input binary image
+
+ <OUTPUT_FILE> is the full path and filename of the output secure image.
diff --git a/doc/README.x86 b/doc/README.x86
index a548b54..7d694b1 100644
--- a/doc/README.x86
+++ b/doc/README.x86
@@ -1020,8 +1020,6 @@ Features not supported so far (to make it a complete ACPI solution):
* S3 (Suspend to RAM), S4 (Suspend to Disk).
Features that are optional:
- * ACPI global NVS support. We may need it to simplify ASL code logic if
- utilizing NVS variables. Most likely we will need this sooner or later.
* Dynamic AML bytecodes insertion at run-time. We may need this to support
SSDT table generation and DSDT fix up.
* SMI support. Since U-Boot is a modern bootloader, we don't want to bring
diff --git a/doc/driver-model/of-plat.txt b/doc/driver-model/of-plat.txt
new file mode 100644
index 0000000..86e5e25
--- /dev/null
+++ b/doc/driver-model/of-plat.txt
@@ -0,0 +1,310 @@
+Driver Model Compiled-in Device Tree / Platform Data
+====================================================
+
+
+Introduction
+------------
+
+Device tree is the standard configuration method in U-Boot. It is used to
+define what devices are in the system and provide configuration information
+to these devices.
+
+The overhead of adding device tree access to U-Boot is fairly modest,
+approximately 3KB on Thumb 2 (plus the size of the DT itself). This means
+that in most cases it is best to use device tree for configuration.
+
+However there are some very constrained environments where U-Boot needs to
+work. These include SPL with severe memory limitations. For example, some
+SoCs require a 16KB SPL image which must include a full MMC stack. In this
+case the overhead of device tree access may be too great.
+
+It is possible to create platform data manually by defining C structures
+for it, and reference that data in a U_BOOT_DEVICE() declaration. This
+bypasses the use of device tree completely, effectively creating a parallel
+configuration mechanism. But it is an available option for SPL.
+
+As an alternative, a new 'of-platdata' feature is provided. This converts the
+device tree contents into C code which can be compiled into the SPL binary.
+This saves the 3KB of code overhead and perhaps a few hundred more bytes due
+to more efficient storage of the data.
+
+Note: Quite a bit of thought has gone into the design of this feature.
+However it still has many rough edges and comments and suggestions are
+strongly encouraged! Quite possibly there is a much better approach.
+
+
+Caveats
+-------
+
+There are many problems with this features. It should only be used when
+strictly necessary. Notable problems include:
+
+ - Device tree does not describe data types. But the C code must define a
+ type for each property. These are guessed using heuristics which
+ are wrong in several fairly common cases. For example an 8-byte value
+ is considered to be a 2-item integer array, and is byte-swapped. A
+ boolean value that is not present means 'false', but cannot be
+ included in the structures since there is generally no mention of it
+ in the device tree file.
+
+ - Naming of nodes and properties is automatic. This means that they follow
+ the naming in the device tree, which may result in C identifiers that
+ look a bit strange.
+
+ - It is not possible to find a value given a property name. Code must use
+ the associated C member variable directly in the code. This makes
+ the code less robust in the face of device-tree changes. It also
+ makes it very unlikely that your driver code will be useful for more
+ than one SoC. Even if the code is common, each SoC will end up with
+ a different C struct name, and a likely a different format for the
+ platform data.
+
+ - The platform data is provided to drivers as a C structure. The driver
+ must use the same structure to access the data. Since a driver
+ normally also supports device tree it must use #ifdef to separate
+ out this code, since the structures are only available in SPL.
+
+
+How it works
+------------
+
+The feature is enabled by CONFIG SPL_OF_PLATDATA. This is only available
+in SPL and should be tested with:
+
+ #if CONFIG_IS_ENABLED(SPL_OF_PLATDATA)
+
+A new tool called 'dtoc' converts a device tree file either into a set of
+struct declarations, one for each compatible node, or a set of
+U_BOOT_DEVICE() declarations along with the actual platform data for each
+device. As an example, consider this MMC node:
+
+ sdmmc: dwmmc@ff0c0000 {
+ compatible = "rockchip,rk3288-dw-mshc";
+ clock-freq-min-max = <400000 150000000>;
+ clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>,
+ <&cru SCLK_SDMMC_DRV>, <&cru SCLK_SDMMC_SAMPLE>;
+ clock-names = "biu", "ciu", "ciu_drv", "ciu_sample";
+ fifo-depth = <0x100>;
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+ reg = <0xff0c0000 0x4000>;
+ bus-width = <4>;
+ cap-mmc-highspeed;
+ cap-sd-highspeed;
+ card-detect-delay = <200>;
+ disable-wp;
+ num-slots = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc_clk>, <&sdmmc_cmd>, <&sdmmc_cd>, <&sdmmc_bus4>;
+ vmmc-supply = <&vcc_sd>;
+ status = "okay";
+ u-boot,dm-pre-reloc;
+ };
+
+
+Some of these properties are dropped by U-Boot under control of the
+CONFIG_OF_SPL_REMOVE_PROPS option. The rest are processed. This will produce
+the following C struct declaration:
+
+struct dtd_rockchip_rk3288_dw_mshc {
+ fdt32_t bus_width;
+ bool cap_mmc_highspeed;
+ bool cap_sd_highspeed;
+ fdt32_t card_detect_delay;
+ fdt32_t clock_freq_min_max[2];
+ struct phandle_2_cell clocks[4];
+ bool disable_wp;
+ fdt32_t fifo_depth;
+ fdt32_t interrupts[3];
+ fdt32_t num_slots;
+ fdt32_t reg[2];
+ fdt32_t vmmc_supply;
+};
+
+and the following device declaration:
+
+static struct dtd_rockchip_rk3288_dw_mshc dtv_dwmmc_at_ff0c0000 = {
+ .fifo_depth = 0x100,
+ .cap_sd_highspeed = true,
+ .interrupts = {0x0, 0x20, 0x4},
+ .clock_freq_min_max = {0x61a80, 0x8f0d180},
+ .vmmc_supply = 0xb,
+ .num_slots = 0x1,
+ .clocks = {{&dtv_clock_controller_at_ff760000, 456},
+ {&dtv_clock_controller_at_ff760000, 68},
+ {&dtv_clock_controller_at_ff760000, 114},
+ {&dtv_clock_controller_at_ff760000, 118}},
+ .cap_mmc_highspeed = true,
+ .disable_wp = true,
+ .bus_width = 0x4,
+ .u_boot_dm_pre_reloc = true,
+ .reg = {0xff0c0000, 0x4000},
+ .card_detect_delay = 0xc8,
+};
+U_BOOT_DEVICE(dwmmc_at_ff0c0000) = {
+ .name = "rockchip_rk3288_dw_mshc",
+ .platdata = &dtv_dwmmc_at_ff0c0000,
+ .platdata_size = sizeof(dtv_dwmmc_at_ff0c0000),
+};
+
+The device is then instantiated at run-time and the platform data can be
+accessed using:
+
+ struct udevice *dev;
+ struct dtd_rockchip_rk3288_dw_mshc *plat = dev_get_platdata(dev);
+
+This avoids the code overhead of converting the device tree data to
+platform data in the driver. The ofdata_to_platdata() method should
+therefore do nothing in such a driver.
+
+
+Converting of-platdata to a useful form
+---------------------------------------
+
+Of course it would be possible use the of-platdata directly in your driver
+whenever configuration information is required. However this meands that the
+driver will not be able to support device tree, since the of-platdata
+structure is not available when device tree is used. It would make no sense
+to use this structure if device tree were available, since the structure has
+all the limitations metioned in caveats above.
+
+Therefore it is recommended that the of-platdata structure should be used
+only in the probe() method of your driver. It cannot be used in the
+ofdata_to_platdata() method since this is not called when platform data is
+already present.
+
+
+How to structure your driver
+----------------------------
+
+Drivers should always support device tree as an option. The of-platdata
+feature is intended as a add-on to existing drivers.
+
+Your driver should convert the platdata struct in its probe() method. The
+existing device tree decoding logic should be kept in the
+ofdata_to_platdata() method and wrapped with #if.
+
+For example:
+
+ #include <dt-structs.h>
+
+ struct mmc_platdata {
+ #if CONFIG_IS_ENABLED(SPL_OF_PLATDATA)
+ /* Put this first since driver model will copy the data here */
+ struct dtd_mmc dtplat;
+ #endif
+ /*
+ * Other fields can go here, to be filled in by decoding from
+ * the device tree (or the C structures when of-platdata is used).
+ */
+ int fifo_depth;
+ };
+
+ static int mmc_ofdata_to_platdata(struct udevice *dev)
+ {
+ #if !CONFIG_IS_ENABLED(SPL_OF_PLATDATA)
+ /* Decode the device tree data */
+ struct mmc_platdata *plat = dev_get_platdata(dev);
+ const void *blob = gd->fdt_blob;
+ int node = dev->of_offset;
+
+ plat->fifo_depth = fdtdec_get_int(blob, node, "fifo-depth", 0);
+ #endif
+
+ return 0;
+ }
+
+ static int mmc_probe(struct udevice *dev)
+ {
+ struct mmc_platdata *plat = dev_get_platdata(dev);
+
+ #if CONFIG_IS_ENABLED(SPL_OF_PLATDATA)
+ /* Decode the of-platdata from the C structures */
+ struct dtd_mmc *dtplat = &plat->dtplat;
+
+ plat->fifo_depth = dtplat->fifo_depth;
+ #endif
+ /* Set up the device from the plat data */
+ writel(plat->fifo_depth, ...)
+ }
+
+ static const struct udevice_id mmc_ids[] = {
+ { .compatible = "vendor,mmc" },
+ { }
+ };
+
+ U_BOOT_DRIVER(mmc_drv) = {
+ .name = "mmc",
+ .id = UCLASS_MMC,
+ .of_match = mmc_ids,
+ .ofdata_to_platdata = mmc_ofdata_to_platdata,
+ .probe = mmc_probe,
+ .priv_auto_alloc_size = sizeof(struct mmc_priv),
+ .platdata_auto_alloc_size = sizeof(struct mmc_platdata),
+ };
+
+
+In the case where SPL_OF_PLATDATA is enabled, platdata_auto_alloc_size is
+still used to allocate space for the platform data. This is different from
+the normal behaviour and is triggered by the use of of-platdata (strictly
+speaking it is a non-zero platdata_size which triggers this).
+
+The of-platdata struct contents is copied from the C structure data to the
+start of the newly allocated area. In the case where device tree is used,
+the platform data is allocated, and starts zeroed. In this case the
+ofdata_to_platdata() method should still set up the platform data (and the
+of-platdata struct will not be present).
+
+SPL must use either of-platdata or device tree. Drivers cannot use both at
+the same time, but they must support device tree. Supporting of-platdata is
+optional.
+
+The device tree becomes in accessible when CONFIG_SPL_OF_PLATDATA is enabled,
+since the device-tree access code is not compiled in. A corollary is that
+a board can only move to using of-platdata if all the drivers it uses support
+it. There would be little point in having some drivers require the device
+tree data, since then libfdt would still be needed for those drivers and
+there would be no code-size benefit.
+
+Internals
+---------
+
+The dt-structs.h file includes the generated file
+(include/generated//dt-structs.h) if CONFIG_SPL_OF_PLATDATA is enabled.
+Otherwise (such as in U-Boot proper) these structs are not available. This
+prevents them being used inadvertently. All usage must be bracketed with
+#if CONFIG_IS_ENABLED(SPL_OF_PLATDATA).
+
+The dt-platdata.c file contains the device declarations and is is built in
+spl/dt-platdata.c.
+
+Some phandles (thsoe that are recognised as such) are converted into
+points to platform data. This pointer can potentially be used to access the
+referenced device (by searching for the pointer value). This feature is not
+yet implemented, however.
+
+The beginnings of a libfdt Python module are provided. So far this only
+implements a subset of the features.
+
+The 'swig' tool is needed to build the libfdt Python module. If this is not
+found then the Python model is not used and a fallback is used instead, which
+makes use of fdtget.
+
+
+Credits
+-------
+
+This is an implementation of an idea by Tom Rini <trini@konsulko.com>.
+
+
+Future work
+-----------
+- Consider programmatically reading binding files instead of device tree
+ contents
+- Complete the phandle feature
+- Move to using a full Python libfdt module
+
+--
+Simon Glass <sjg@chromium.org>
+Google, Inc
+6/6/16
+Updated Independence Day 2016
diff --git a/doc/feature-removal-schedule.txt b/doc/feature-removal-schedule.txt
index 4ed30df..b5a70da 100644
--- a/doc/feature-removal-schedule.txt
+++ b/doc/feature-removal-schedule.txt
@@ -12,7 +12,7 @@ When: Release v2013.10
Why: As the 'mtest' command is no longer default, a number of platforms
have not opted to turn the command back on and thus provide unused
- defines (which are likely to be propogated to new platforms from
+ defines (which are likely to be propagated to new platforms from
copy/paste). Remove these defines when unused.
Who: Tom Rini <trini@ti.com>
diff --git a/doc/git-mailrc b/doc/git-mailrc
index 1d6f4fc..8f0724f 100644
--- a/doc/git-mailrc
+++ b/doc/git-mailrc
@@ -76,7 +76,7 @@ alias tegra2 tegra
alias ti uboot, trini
alias uniphier uboot, masahiro
alias zynq uboot, monstr
-
+alias rockchip uboot, sjg, Lin huang <hl@rock-chips.com>
alias avr32 uboot, abiessmann
alias bfin uboot, vapier, sonic
diff --git a/drivers/bios_emulator/x86emu/sys.c b/drivers/bios_emulator/x86emu/sys.c
index 0ba9c0c..c2db121 100644
--- a/drivers/bios_emulator/x86emu/sys.c
+++ b/drivers/bios_emulator/x86emu/sys.c
@@ -35,7 +35,7 @@
* Description: This file includes subroutines which are related to
* programmed I/O and memory access. Included in this module
* are default functions that do nothing. For real uses these
-* functions will have to be overriden by the user library.
+* functions will have to be overridden by the user library.
*
****************************************************************************/
diff --git a/drivers/clk/clk-uclass.c b/drivers/clk/clk-uclass.c
index 6e4d672..e0f8567 100644
--- a/drivers/clk/clk-uclass.c
+++ b/drivers/clk/clk-uclass.c
@@ -10,6 +10,7 @@
#include <clk.h>
#include <clk-uclass.h>
#include <dm.h>
+#include <dt-structs.h>
#include <errno.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -21,6 +22,22 @@ static inline struct clk_ops *clk_dev_ops(struct udevice *dev)
#if CONFIG_IS_ENABLED(OF_CONTROL)
#ifdef CONFIG_SPL_BUILD
+# if CONFIG_IS_ENABLED(OF_PLATDATA)
+int clk_get_by_index_platdata(struct udevice *dev, int index,
+ struct phandle_2_cell *cells, struct clk *clk)
+{
+ int ret;
+
+ if (index != 0)
+ return -ENOSYS;
+ ret = uclass_get_device(UCLASS_CLK, 0, &clk->dev);
+ if (ret)
+ return ret;
+ clk->id = cells[0].id;
+
+ return 0;
+}
+# else
int clk_get_by_index(struct udevice *dev, int index, struct clk *clk)
{
int ret;
@@ -39,6 +56,7 @@ int clk_get_by_index(struct udevice *dev, int index, struct clk *clk)
clk->id = cell[1];
return 0;
}
+# endif /* OF_PLATDATA */
int clk_get_by_name(struct udevice *dev, const char *name, struct clk *clk)
{
@@ -117,8 +135,8 @@ int clk_get_by_name(struct udevice *dev, const char *name, struct clk *clk)
return clk_get_by_index(dev, index, clk);
}
-#endif
-#endif
+#endif /* CONFIG_SPL_BUILD */
+#endif /* OF_CONTROL */
int clk_request(struct udevice *dev, struct clk *clk)
{
diff --git a/drivers/clk/clk_fixed_rate.c b/drivers/clk/clk_fixed_rate.c
index 797e537..9c4d2b3 100644
--- a/drivers/clk/clk_fixed_rate.c
+++ b/drivers/clk/clk_fixed_rate.c
@@ -30,9 +30,11 @@ const struct clk_ops clk_fixed_rate_ops = {
static int clk_fixed_rate_ofdata_to_platdata(struct udevice *dev)
{
+#if !CONFIG_IS_ENABLED(OF_PLATDATA)
to_clk_fixed_rate(dev)->fixed_rate =
fdtdec_get_int(gd->fdt_blob, dev->of_offset,
"clock-frequency", 0);
+#endif
return 0;
}
diff --git a/drivers/clk/clk_rk3288.c b/drivers/clk/clk_rk3288.c
index 2285453..679f010 100644
--- a/drivers/clk/clk_rk3288.c
+++ b/drivers/clk/clk_rk3288.c
@@ -7,7 +7,9 @@
#include <common.h>
#include <clk-uclass.h>
#include <dm.h>
+#include <dt-structs.h>
#include <errno.h>
+#include <mapmem.h>
#include <syscon.h>
#include <asm/io.h>
#include <asm/arch/clock.h>
@@ -21,6 +23,12 @@
DECLARE_GLOBAL_DATA_PTR;
+struct rk3288_clk_plat {
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+ struct dtd_rockchip_rk3288_cru dtd;
+#endif
+};
+
struct rk3288_clk_priv {
struct rk3288_grf *grf;
struct rk3288_cru *cru;
@@ -783,13 +791,30 @@ static struct clk_ops rk3288_clk_ops = {
.set_rate = rk3288_clk_set_rate,
};
-static int rk3288_clk_probe(struct udevice *dev)
+static int rk3288_clk_ofdata_to_platdata(struct udevice *dev)
{
+#if !CONFIG_IS_ENABLED(OF_PLATDATA)
struct rk3288_clk_priv *priv = dev_get_priv(dev);
priv->cru = (struct rk3288_cru *)dev_get_addr(dev);
+#endif
+
+ return 0;
+}
+
+static int rk3288_clk_probe(struct udevice *dev)
+{
+ struct rk3288_clk_priv *priv = dev_get_priv(dev);
+
priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
+ if (IS_ERR(priv->grf))
+ return PTR_ERR(priv->grf);
#ifdef CONFIG_SPL_BUILD
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+ struct rk3288_clk_plat *plat = dev_get_platdata(dev);
+
+ priv->cru = map_sysmem(plat->dtd.reg[0], plat->dtd.reg[1]);
+#endif
rkclk_init(priv->cru, priv->grf);
#endif
@@ -813,12 +838,14 @@ static const struct udevice_id rk3288_clk_ids[] = {
{ }
};
-U_BOOT_DRIVER(clk_rk3288) = {
- .name = "clk_rk3288",
+U_BOOT_DRIVER(rockchip_rk3288_cru) = {
+ .name = "rockchip_rk3288_cru",
.id = UCLASS_CLK,
.of_match = rk3288_clk_ids,
.priv_auto_alloc_size = sizeof(struct rk3288_clk_priv),
+ .platdata_auto_alloc_size = sizeof(struct rk3288_clk_plat),
.ops = &rk3288_clk_ops,
.bind = rk3288_clk_bind,
+ .ofdata_to_platdata = rk3288_clk_ofdata_to_platdata,
.probe = rk3288_clk_probe,
};
diff --git a/drivers/core/device-remove.c b/drivers/core/device-remove.c
index 0e56b23..a7f77b4 100644
--- a/drivers/core/device-remove.c
+++ b/drivers/core/device-remove.c
@@ -112,7 +112,7 @@ int device_unbind(struct udevice *dev)
devres_release_all(dev);
- if (dev->flags & DM_NAME_ALLOCED)
+ if (dev->flags & DM_FLAG_NAME_ALLOCED)
free((char *)dev->name);
free(dev);
diff --git a/drivers/core/device.c b/drivers/core/device.c
index eb75b17..5bb1d77 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -10,6 +10,7 @@
*/
#include <common.h>
+#include <asm/io.h>
#include <fdtdec.h>
#include <fdt_support.h>
#include <malloc.h>
@@ -29,7 +30,7 @@ DECLARE_GLOBAL_DATA_PTR;
static int device_bind_common(struct udevice *parent, const struct driver *drv,
const char *name, void *platdata,
ulong driver_data, int of_offset,
- struct udevice **devp)
+ uint of_platdata_size, struct udevice **devp)
{
struct udevice *dev;
struct uclass *uc;
@@ -83,12 +84,29 @@ static int device_bind_common(struct udevice *parent, const struct driver *drv,
}
}
- if (!dev->platdata && drv->platdata_auto_alloc_size) {
- dev->flags |= DM_FLAG_ALLOC_PDATA;
- dev->platdata = calloc(1, drv->platdata_auto_alloc_size);
- if (!dev->platdata) {
- ret = -ENOMEM;
- goto fail_alloc1;
+ if (drv->platdata_auto_alloc_size) {
+ bool alloc = !platdata;
+
+ if (CONFIG_IS_ENABLED(OF_PLATDATA)) {
+ if (of_platdata_size) {
+ dev->flags |= DM_FLAG_OF_PLATDATA;
+ if (of_platdata_size <
+ drv->platdata_auto_alloc_size)
+ alloc = true;
+ }
+ }
+ if (alloc) {
+ dev->flags |= DM_FLAG_ALLOC_PDATA;
+ dev->platdata = calloc(1,
+ drv->platdata_auto_alloc_size);
+ if (!dev->platdata) {
+ ret = -ENOMEM;
+ goto fail_alloc1;
+ }
+ if (CONFIG_IS_ENABLED(OF_PLATDATA) && platdata) {
+ memcpy(dev->platdata, platdata,
+ of_platdata_size);
+ }
}
}
@@ -201,14 +219,14 @@ int device_bind_with_driver_data(struct udevice *parent,
struct udevice **devp)
{
return device_bind_common(parent, drv, name, NULL, driver_data,
- of_offset, devp);
+ of_offset, 0, devp);
}
int device_bind(struct udevice *parent, const struct driver *drv,
const char *name, void *platdata, int of_offset,
struct udevice **devp)
{
- return device_bind_common(parent, drv, name, platdata, 0, of_offset,
+ return device_bind_common(parent, drv, name, platdata, 0, of_offset, 0,
devp);
}
@@ -216,6 +234,7 @@ int device_bind_by_name(struct udevice *parent, bool pre_reloc_only,
const struct driver_info *info, struct udevice **devp)
{
struct driver *drv;
+ uint platdata_size = 0;
drv = lists_driver_lookup_name(info->name);
if (!drv)
@@ -223,8 +242,11 @@ int device_bind_by_name(struct udevice *parent, bool pre_reloc_only,
if (pre_reloc_only && !(drv->flags & DM_FLAG_PRE_RELOC))
return -EPERM;
- return device_bind(parent, drv, info->name, (void *)info->platdata,
- -1, devp);
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+ platdata_size = info->platdata_size;
+#endif
+ return device_bind_common(parent, drv, info->name,
+ (void *)info->platdata, 0, -1, platdata_size, devp);
}
static void *alloc_priv(int size, uint flags)
@@ -607,7 +629,7 @@ const char *dev_get_uclass_name(struct udevice *dev)
fdt_addr_t dev_get_addr_index(struct udevice *dev, int index)
{
-#if CONFIG_IS_ENABLED(OF_CONTROL)
+#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
fdt_addr_t addr;
if (CONFIG_IS_ENABLED(OF_TRANSLATE)) {
@@ -697,6 +719,16 @@ void *dev_get_addr_ptr(struct udevice *dev)
return (void *)(uintptr_t)dev_get_addr_index(dev, 0);
}
+void *dev_map_physmem(struct udevice *dev, unsigned long size)
+{
+ fdt_addr_t addr = dev_get_addr(dev);
+
+ if (addr == FDT_ADDR_T_NONE)
+ return NULL;
+
+ return map_physmem(addr, size, MAP_NOCACHE);
+}
+
bool device_has_children(struct udevice *dev)
{
return !list_empty(&dev->child_head);
@@ -727,7 +759,7 @@ bool device_is_last_sibling(struct udevice *dev)
void device_set_name_alloced(struct udevice *dev)
{
- dev->flags |= DM_NAME_ALLOCED;
+ dev->flags |= DM_FLAG_NAME_ALLOCED;
}
int device_set_name(struct udevice *dev, const char *name)
diff --git a/drivers/core/lists.c b/drivers/core/lists.c
index 0c27717..6a634e6 100644
--- a/drivers/core/lists.c
+++ b/drivers/core/lists.c
@@ -99,7 +99,7 @@ int device_bind_driver_to_node(struct udevice *parent, const char *drv_name,
return 0;
}
-#if CONFIG_IS_ENABLED(OF_CONTROL)
+#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
/**
* driver_check_compatible() - Check if a driver is compatible with this node
*
diff --git a/drivers/core/regmap.c b/drivers/core/regmap.c
index 519832f..0299ff0 100644
--- a/drivers/core/regmap.c
+++ b/drivers/core/regmap.c
@@ -15,6 +15,49 @@
DECLARE_GLOBAL_DATA_PTR;
+static struct regmap *regmap_alloc_count(int count)
+{
+ struct regmap *map;
+
+ map = malloc(sizeof(struct regmap));
+ if (!map)
+ return NULL;
+ if (count <= 1) {
+ map->range = &map->base_range;
+ } else {
+ map->range = malloc(count * sizeof(struct regmap_range));
+ if (!map->range) {
+ free(map);
+ return NULL;
+ }
+ }
+ map->range_count = count;
+
+ return map;
+}
+
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+int regmap_init_mem_platdata(struct udevice *dev, u32 *reg, int count,
+ struct regmap **mapp)
+{
+ struct regmap_range *range;
+ struct regmap *map;
+
+ map = regmap_alloc_count(count);
+ if (!map)
+ return -ENOMEM;
+
+ map->base = *reg;
+ for (range = map->range; count > 0; reg += 2, range++, count--) {
+ range->start = *reg;
+ range->size = reg[1];
+ }
+
+ *mapp = map;
+
+ return 0;
+}
+#else
int regmap_init_mem(struct udevice *dev, struct regmap **mapp)
{
const void *blob = gd->fdt_blob;
@@ -37,22 +80,11 @@ int regmap_init_mem(struct udevice *dev, struct regmap **mapp)
if (!cell || !count)
return -EINVAL;
- map = malloc(sizeof(struct regmap));
+ map = regmap_alloc_count(count);
if (!map)
return -ENOMEM;
- if (count <= 1) {
- map->range = &map->base_range;
- } else {
- map->range = malloc(count * sizeof(struct regmap_range));
- if (!map->range) {
- free(map);
- return -ENOMEM;
- }
- }
-
map->base = fdtdec_get_number(cell, addr_len);
- map->range_count = count;
for (range = map->range; count > 0;
count--, cell += both_len, range++) {
@@ -64,6 +96,7 @@ int regmap_init_mem(struct udevice *dev, struct regmap **mapp)
return 0;
}
+#endif
void *regmap_get_range(struct regmap *map, unsigned int range_num)
{
diff --git a/drivers/core/root.c b/drivers/core/root.c
index 95886ad..1587024 100644
--- a/drivers/core/root.c
+++ b/drivers/core/root.c
@@ -188,7 +188,7 @@ int dm_scan_platdata(bool pre_reloc_only)
return ret;
}
-#if CONFIG_IS_ENABLED(OF_CONTROL)
+#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
int dm_scan_fdt_node(struct udevice *parent, const void *blob, int offset,
bool pre_reloc_only)
{
@@ -244,7 +244,7 @@ int dm_init_and_scan(bool pre_reloc_only)
return ret;
}
- if (CONFIG_IS_ENABLED(OF_CONTROL)) {
+ if (CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)) {
ret = dm_scan_fdt(gd->fdt_blob, pre_reloc_only);
if (ret) {
debug("dm_scan_fdt() failed: %d\n", ret);
diff --git a/drivers/core/syscon-uclass.c b/drivers/core/syscon-uclass.c
index e03f46a..01bd968 100644
--- a/drivers/core/syscon-uclass.c
+++ b/drivers/core/syscon-uclass.c
@@ -29,7 +29,20 @@ static int syscon_pre_probe(struct udevice *dev)
{
struct syscon_uc_info *priv = dev_get_uclass_priv(dev);
+ /*
+ * With OF_PLATDATA we really have no way of knowing the format of
+ * the device-specific platform data. So we assume that it starts with
+ * a 'reg' member, and this holds a single address and size. Drivers
+ * using OF_PLATDATA will need to ensure that this is true.
+ */
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+ struct syscon_base_platdata *plat = dev_get_platdata(dev);
+
+ return regmap_init_mem_platdata(dev, plat->reg, ARRAY_SIZE(plat->reg),
+ &priv->regmap);
+#else
return regmap_init_mem(dev, &priv->regmap);
+#endif
}
int syscon_get_by_driver_data(ulong driver_data, struct udevice **devp)
diff --git a/drivers/crypto/fsl/desc.h b/drivers/crypto/fsl/desc.h
index 1ac3a09..081bce5 100644
--- a/drivers/crypto/fsl/desc.h
+++ b/drivers/crypto/fsl/desc.h
@@ -107,7 +107,7 @@
*/
#define HDR_REVERSE 0x00000800
-/* Propogate DNR property to SharedDesc */
+/* Propagate DNR property to SharedDesc */
#define HDR_PROP_DNR 0x00000800
/* JobDesc/SharedDesc share property */
diff --git a/drivers/ddr/fsl/ctrl_regs.c b/drivers/ddr/fsl/ctrl_regs.c
index 1d5cec6..abd576b 100644
--- a/drivers/ddr/fsl/ctrl_regs.c
+++ b/drivers/ddr/fsl/ctrl_regs.c
@@ -2212,7 +2212,7 @@ static void set_ddr_wrlvl_cntl(fsl_ddr_cfg_regs_t *ddr, unsigned int wrlvl_en,
* Write leveling start time
* The value use for the DQS_ADJUST for the first sample
* when write leveling is enabled. It probably needs to be
- * overriden per platform.
+ * overridden per platform.
*/
wrlvl_start = 0x8;
/*
diff --git a/drivers/dfu/dfu_mmc.c b/drivers/dfu/dfu_mmc.c
index 78724e4..926ccbd 100644
--- a/drivers/dfu/dfu_mmc.c
+++ b/drivers/dfu/dfu_mmc.c
@@ -49,7 +49,7 @@ static int mmc_block_op(enum dfu_op op, struct dfu_entity *dfu,
}
if (dfu->data.mmc.hw_partition >= 0) {
- part_num_bkp = mmc->block_dev.hwpart;
+ part_num_bkp = mmc_get_blk_desc(mmc)->hwpart;
ret = blk_select_hwpart_devnum(IF_TYPE_MMC,
dfu->data.mmc.dev_num,
dfu->data.mmc.hw_partition);
@@ -62,12 +62,11 @@ static int mmc_block_op(enum dfu_op op, struct dfu_entity *dfu,
dfu->data.mmc.dev_num, blk_start, blk_count, buf);
switch (op) {
case DFU_OP_READ:
- n = mmc->block_dev.block_read(&mmc->block_dev, blk_start,
- blk_count, buf);
+ n = blk_dread(mmc_get_blk_desc(mmc), blk_start, blk_count, buf);
break;
case DFU_OP_WRITE:
- n = mmc->block_dev.block_write(&mmc->block_dev, blk_start,
- blk_count, buf);
+ n = blk_dwrite(mmc_get_blk_desc(mmc), blk_start, blk_count,
+ buf);
break;
default:
error("Operation not supported\n");
@@ -356,7 +355,7 @@ int dfu_fill_entity_mmc(struct dfu_entity *dfu, char *devstr, char *s)
} else if (!strcmp(entity_type, "part")) {
disk_partition_t partinfo;
- struct blk_desc *blk_dev = &mmc->block_dev;
+ struct blk_desc *blk_dev = mmc_get_blk_desc(mmc);
int mmcdev = second_arg;
int mmcpart = third_arg;
diff --git a/drivers/fpga/fpga.c b/drivers/fpga/fpga.c
index 7e2f3e1..e0fb1b4 100644
--- a/drivers/fpga/fpga.c
+++ b/drivers/fpga/fpga.c
@@ -31,7 +31,7 @@ static void fpga_no_sup(char *fn, char *msg)
else if (msg)
printf("No support for %s.\n", msg);
else
- printf("No FPGA suport!\n");
+ printf("No FPGA support!\n");
}
diff --git a/drivers/gpio/mpc85xx_gpio.c b/drivers/gpio/mpc85xx_gpio.c
index 04773e2..3754a82 100644
--- a/drivers/gpio/mpc85xx_gpio.c
+++ b/drivers/gpio/mpc85xx_gpio.c
@@ -163,23 +163,41 @@ static int mpc85xx_gpio_get_function(struct udevice *dev, unsigned gpio)
return dir ? GPIOF_OUTPUT : GPIOF_INPUT;
}
+#if CONFIG_IS_ENABLED(OF_CONTROL)
static int mpc85xx_gpio_ofdata_to_platdata(struct udevice *dev) {
- struct mpc85xx_gpio_data *data = dev_get_priv(dev);
+ struct mpc85xx_gpio_plat *plat = dev_get_platdata(dev);
fdt_addr_t addr;
fdt_size_t size;
addr = fdtdec_get_addr_size_auto_noparent(gd->fdt_blob, dev->of_offset,
"reg", 0, &size);
- data->addr = addr;
- data->base = map_sysmem(CONFIG_SYS_IMMR + addr, size);
+ plat->addr = addr;
+ plat->size = size;
+ plat->ngpios = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
+ "ngpios", 32);
- if (!data->base)
+ return 0;
+}
+#endif
+
+static int mpc85xx_gpio_platdata_to_priv(struct udevice *dev)
+{
+ struct mpc85xx_gpio_data *priv = dev_get_priv(dev);
+ struct mpc85xx_gpio_plat *plat = dev_get_platdata(dev);
+ unsigned long size = plat->size;
+
+ if (size == 0)
+ size = 0x100;
+
+ priv->addr = plat->addr;
+ priv->base = map_sysmem(CONFIG_SYS_IMMR + plat->addr, size);
+
+ if (!priv->base)
return -ENOMEM;
- data->gpio_count = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
- "ngpios", 32);
- data->dat_shadow = 0;
+ priv->gpio_count = plat->ngpios;
+ priv->dat_shadow = 0;
return 0;
}
@@ -190,6 +208,8 @@ static int mpc85xx_gpio_probe(struct udevice *dev)
struct mpc85xx_gpio_data *data = dev_get_priv(dev);
char name[32], *str;
+ mpc85xx_gpio_platdata_to_priv(dev);
+
snprintf(name, sizeof(name), "MPC@%lx_", data->addr);
str = strdup(name);
@@ -221,8 +241,11 @@ U_BOOT_DRIVER(gpio_mpc85xx) = {
.name = "gpio_mpc85xx",
.id = UCLASS_GPIO,
.ops = &gpio_mpc85xx_ops,
+#if CONFIG_IS_ENABLED(OF_CONTROL)
.ofdata_to_platdata = mpc85xx_gpio_ofdata_to_platdata,
+ .platdata_auto_alloc_size = sizeof(struct mpc85xx_gpio_plat),
.of_match = mpc85xx_gpio_ids,
+#endif
.probe = mpc85xx_gpio_probe,
.priv_auto_alloc_size = sizeof(struct mpc85xx_gpio_data),
};
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 066639b..fff6f0c 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -29,12 +29,19 @@ obj-$(CONFIG_PDSP188x) += pdsp188x.o
obj-$(CONFIG_$(SPL_)PWRSEQ) += pwrseq-uclass.o
obj-$(CONFIG_SANDBOX) += sysreset_sandbox.o
ifdef CONFIG_DM_I2C
+ifndef CONFIG_SPL_BUILD
obj-$(CONFIG_SANDBOX) += i2c_eeprom_emul.o
endif
+endif
obj-$(CONFIG_SMSC_LPC47M) += smsc_lpc47m.o
obj-$(CONFIG_SMSC_SIO1007) += smsc_sio1007.o
obj-$(CONFIG_STATUS_LED) += status_led.o
obj-$(CONFIG_SANDBOX) += swap_case.o
+ifdef CONFIG_SPL_OF_PLATDATA
+ifdef CONFIG_SPL_BUILD
+obj-$(CONFIG_SANDBOX) += spltest_sandbox.o
+endif
+endif
obj-$(CONFIG_SANDBOX) += syscon_sandbox.o
obj-$(CONFIG_TWL4030_LED) += twl4030_led.o
obj-$(CONFIG_FSL_IFC) += fsl_ifc.o
diff --git a/drivers/misc/cros_ec_sandbox.c b/drivers/misc/cros_ec_sandbox.c
index 98f19a6..c4fbca0 100644
--- a/drivers/misc/cros_ec_sandbox.c
+++ b/drivers/misc/cros_ec_sandbox.c
@@ -517,6 +517,7 @@ int cros_ec_probe(struct udevice *dev)
struct ec_state *ec = dev->priv;
struct cros_ec_dev *cdev = dev->uclass_priv;
const void *blob = gd->fdt_blob;
+ struct udevice *keyb_dev;
int node;
int err;
@@ -525,7 +526,15 @@ int cros_ec_probe(struct udevice *dev)
if (err)
return err;
- node = fdtdec_next_compatible(blob, 0, COMPAT_GOOGLE_CROS_EC_KEYB);
+ node = -1;
+ for (device_find_first_child(dev, &keyb_dev);
+ keyb_dev;
+ device_find_next_child(&keyb_dev)) {
+ if (device_get_uclass_id(keyb_dev) == UCLASS_KEYBOARD) {
+ node = keyb_dev->of_offset;
+ break;
+ }
+ }
if (node < 0) {
debug("%s: No cros_ec keyboard found\n", __func__);
} else if (keyscan_read_fdt_matrix(ec, blob, node)) {
diff --git a/drivers/misc/spltest_sandbox.c b/drivers/misc/spltest_sandbox.c
new file mode 100644
index 0000000..1fef825
--- /dev/null
+++ b/drivers/misc/spltest_sandbox.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2016 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <dt-structs.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static int sandbox_spl_probe(struct udevice *dev)
+{
+ struct dtd_sandbox_spl_test *plat = dev_get_platdata(dev);
+ int i;
+
+ printf("of-platdata probe:\n");
+ printf("bool %d\n", plat->boolval);
+
+ printf("byte %02x\n", plat->byteval);
+ printf("bytearray");
+ for (i = 0; i < sizeof(plat->bytearray); i++)
+ printf(" %02x", plat->bytearray[i]);
+ printf("\n");
+
+ printf("int %d\n", plat->intval);
+ printf("intarray");
+ for (i = 0; i < ARRAY_SIZE(plat->intarray); i++)
+ printf(" %d", plat->intarray[i]);
+ printf("\n");
+
+ printf("longbytearray");
+ for (i = 0; i < sizeof(plat->longbytearray); i++)
+ printf(" %02x", plat->longbytearray[i]);
+ printf("\n");
+
+ printf("string %s\n", plat->stringval);
+ printf("stringarray");
+ for (i = 0; i < ARRAY_SIZE(plat->stringarray); i++)
+ printf(" \"%s\"", plat->stringarray[i]);
+ printf("\n");
+
+ return 0;
+}
+
+U_BOOT_DRIVER(sandbox_spl_test) = {
+ .name = "sandbox_spl_test",
+ .id = UCLASS_MISC,
+ .flags = DM_FLAG_PRE_RELOC,
+ .probe = sandbox_spl_probe,
+};
diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig
index c80efc3..e0adb9b 100644
--- a/drivers/mmc/Kconfig
+++ b/drivers/mmc/Kconfig
@@ -10,15 +10,24 @@ config DM_MMC
bool "Enable MMC controllers using Driver Model"
depends on DM
help
- This enables the MultiMediaCard (MMC) uclass which suports MMC and
+ This enables the MultiMediaCard (MMC) uclass which supports MMC and
Secure Digital I/O (SDIO) cards. Both removable (SD, micro-SD, etc.)
and non-removable (e.g. eMMC chip) devices are supported. These
appear as block devices in U-Boot and can support filesystems such
as EXT4 and FAT.
+config DM_MMC_OPS
+ bool "Support MMC controller operations using Driver Model"
+ depends on DM_MMC
+ help
+ Driver model provides a means of supporting device operations. This
+ option moves MMC operations under the control of driver model. The
+ option will be removed as soon as all DM_MMC drivers use it, as it
+ will the only supported behaviour.
+
config MSM_SDHCI
bool "Qualcomm SDHCI controller"
- depends on DM_MMC
+ depends on DM_MMC && BLK && DM_MMC_OPS
help
Enables support for SDHCI 2.0 controller present on some Qualcomm
Snapdragon devices. This device is compatible with eMMC v4.5 and
diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile
index 3da4817..b44a12e 100644
--- a/drivers/mmc/Makefile
+++ b/drivers/mmc/Makefile
@@ -25,6 +25,9 @@ obj-$(CONFIG_FSL_ESDHC) += fsl_esdhc.o
obj-$(CONFIG_FTSDC010) += ftsdc010_mci.o
obj-$(CONFIG_FTSDC021) += ftsdc021_sdhci.o
obj-$(CONFIG_GENERIC_MMC) += mmc.o
+ifdef CONFIG_SUPPORT_EMMC_BOOT
+obj-$(CONFIG_GENERIC_MMC) += mmc_boot.o
+endif
obj-$(CONFIG_GENERIC_ATMEL_MCI) += gen_atmel_mci.o
obj-$(CONFIG_KONA_SDHCI) += kona_sdhci.o
obj-$(CONFIG_MMC_SPI) += mmc_spi.o
diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c
index af6e04a..2cf7bae 100644
--- a/drivers/mmc/dw_mmc.c
+++ b/drivers/mmc/dw_mmc.c
@@ -181,9 +181,16 @@ static int dwmci_set_transfer_mode(struct dwmci_host *host,
return mode;
}
+#ifdef CONFIG_DM_MMC_OPS
+int dwmci_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
+ struct mmc_data *data)
+{
+ struct mmc *mmc = mmc_get_mmc_dev(dev);
+#else
static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
struct mmc_data *data)
{
+#endif
struct dwmci_host *host = mmc->priv;
ALLOC_CACHE_ALIGN_BUFFER(struct dwmci_idmac, cur_idmac,
data ? DIV_ROUND_UP(data->blocks, 8) : 0);
@@ -373,8 +380,14 @@ static int dwmci_setup_bus(struct dwmci_host *host, u32 freq)
return 0;
}
+#ifdef CONFIG_DM_MMC_OPS
+int dwmci_set_ios(struct udevice *dev)
+{
+ struct mmc *mmc = mmc_get_mmc_dev(dev);
+#else
static void dwmci_set_ios(struct mmc *mmc)
{
+#endif
struct dwmci_host *host = (struct dwmci_host *)mmc->priv;
u32 ctype, regs;
@@ -405,6 +418,9 @@ static void dwmci_set_ios(struct mmc *mmc)
if (host->clksel)
host->clksel(host);
+#ifdef CONFIG_DM_MMC_OPS
+ return 0;
+#endif
}
static int dwmci_init(struct mmc *mmc)
@@ -448,17 +464,34 @@ static int dwmci_init(struct mmc *mmc)
return 0;
}
+#ifdef CONFIG_DM_MMC_OPS
+int dwmci_probe(struct udevice *dev)
+{
+ struct mmc *mmc = mmc_get_mmc_dev(dev);
+
+ return dwmci_init(mmc);
+}
+
+const struct dm_mmc_ops dm_dwmci_ops = {
+ .send_cmd = dwmci_send_cmd,
+ .set_ios = dwmci_set_ios,
+};
+
+#else
static const struct mmc_ops dwmci_ops = {
.send_cmd = dwmci_send_cmd,
.set_ios = dwmci_set_ios,
.init = dwmci_init,
};
+#endif
void dwmci_setup_cfg(struct mmc_config *cfg, const char *name, int buswidth,
uint caps, u32 max_clk, u32 min_clk)
{
cfg->name = name;
+#ifndef CONFIG_DM_MMC_OPS
cfg->ops = &dwmci_ops;
+#endif
cfg->f_min = min_clk;
cfg->f_max = max_clk;
diff --git a/drivers/mmc/exynos_dw_mmc.c b/drivers/mmc/exynos_dw_mmc.c
index 863bbb3..283befc 100644
--- a/drivers/mmc/exynos_dw_mmc.c
+++ b/drivers/mmc/exynos_dw_mmc.c
@@ -23,8 +23,21 @@
#define DWMMC_MMC0_SDR_TIMING_VAL 0x03030001
#define DWMMC_MMC2_SDR_TIMING_VAL 0x03020001
+#ifdef CONFIG_DM_MMC
+#include <dm.h>
+DECLARE_GLOBAL_DATA_PTR;
+
+struct exynos_mmc_plat {
+ struct mmc_config cfg;
+ struct mmc mmc;
+};
+#endif
+
/* Exynos implmentation specific drver private data */
struct dwmci_exynos_priv_data {
+#ifdef CONFIG_DM_MMC
+ struct dwmci_host host;
+#endif
u32 sdr_timing;
};
@@ -80,11 +93,10 @@ static void exynos_dwmci_board_init(struct dwmci_host *host)
exynos_dwmci_clksel(host);
}
-static int exynos_dwmci_core_init(struct dwmci_host *host, int index)
+static int exynos_dwmci_core_init(struct dwmci_host *host)
{
unsigned int div;
unsigned long freq, sclk;
- struct dwmci_exynos_priv_data *priv = host->priv;
if (host->bus_hz)
freq = host->bus_hz;
@@ -92,10 +104,10 @@ static int exynos_dwmci_core_init(struct dwmci_host *host, int index)
freq = DWMMC_MAX_FREQ;
/* request mmc clock vlaue of 52MHz. */
- sclk = get_mmc_clk(index);
+ sclk = get_mmc_clk(host->dev_index);
div = DIV_ROUND_UP(sclk, freq);
/* set the clock divisor for mmc */
- set_mmc_clk(index, div);
+ set_mmc_clk(host->dev_index, div);
host->name = "EXYNOS DWMMC";
#ifdef CONFIG_EXYNOS5420
@@ -103,78 +115,35 @@ static int exynos_dwmci_core_init(struct dwmci_host *host, int index)
#endif
host->board_init = exynos_dwmci_board_init;
- if (!priv->sdr_timing) {
- if (index == 0)
- priv->sdr_timing = DWMMC_MMC0_SDR_TIMING_VAL;
- else if (index == 2)
- priv->sdr_timing = DWMMC_MMC2_SDR_TIMING_VAL;
- }
-
host->caps = MMC_MODE_DDR_52MHz;
host->clksel = exynos_dwmci_clksel;
- host->dev_index = index;
host->get_mmc_clk = exynos_dwmci_get_clk;
+
+#ifndef CONFIG_DM_MMC
/* Add the mmc channel to be registered with mmc core */
if (add_dwmci(host, DWMMC_MAX_FREQ, DWMMC_MIN_FREQ)) {
- printf("DWMMC%d registration failed\n", index);
+ printf("DWMMC%d registration failed\n", host->dev_index);
return -1;
}
- return 0;
-}
-
-/*
- * This function adds the mmc channel to be registered with mmc core.
- * index - mmc channel number.
- * regbase - register base address of mmc channel specified in 'index'.
- * bus_width - operating bus width of mmc channel specified in 'index'.
- * clksel - value to be written into CLKSEL register in case of FDT.
- * NULL in case od non-FDT.
- */
-int exynos_dwmci_add_port(int index, u32 regbase, int bus_width, u32 clksel)
-{
- struct dwmci_host *host = NULL;
- struct dwmci_exynos_priv_data *priv;
-
- host = malloc(sizeof(struct dwmci_host));
- if (!host) {
- error("dwmci_host malloc fail!\n");
- return -ENOMEM;
- }
-
- priv = malloc(sizeof(struct dwmci_exynos_priv_data));
- if (!priv) {
- error("dwmci_exynos_priv_data malloc fail!\n");
- return -ENOMEM;
- }
-
- host->ioaddr = (void *)regbase;
- host->buswidth = bus_width;
-
- if (clksel)
- priv->sdr_timing = clksel;
-
- host->priv = priv;
+#endif
- return exynos_dwmci_core_init(host, index);
+ return 0;
}
-#if CONFIG_IS_ENABLED(OF_CONTROL)
static struct dwmci_host dwmci_host[DWMMC_MAX_CH_NUM];
static int do_dwmci_init(struct dwmci_host *host)
{
- int index, flag, err;
-
- index = host->dev_index;
+ int flag, err;
flag = host->buswidth == 8 ? PINMUX_FLAG_8BIT_MODE : PINMUX_FLAG_NONE;
err = exynos_pinmux_config(host->dev_id, flag);
if (err) {
- printf("DWMMC%d not configure\n", index);
+ printf("DWMMC%d not configure\n", host->dev_index);
return err;
}
- return exynos_dwmci_core_init(host, index);
+ return exynos_dwmci_core_init(host);
}
static int exynos_dwmci_get_config(const void *blob, int node,
@@ -197,13 +166,14 @@ static int exynos_dwmci_get_config(const void *blob, int node,
if (host->dev_index == host->dev_id)
host->dev_index = host->dev_id - PERIPH_ID_SDMMC0;
- /* Get the bus width from the device node */
- host->buswidth = fdtdec_get_int(blob, node, "samsung,bus-width", 0);
- if (host->buswidth <= 0) {
- printf("DWMMC%d: Can't get bus-width\n", host->dev_index);
+ if (host->dev_index > 4) {
+ printf("DWMMC%d: Can't get the dev index\n", host->dev_index);
return -EINVAL;
}
+ /* Get the bus width from the device node (Default is 4bit buswidth) */
+ host->buswidth = fdtdec_get_int(blob, node, "samsung,bus-width", 4);
+
/* Set the base address from the device node */
base = fdtdec_get_addr(blob, node, "reg");
if (!base) {
@@ -265,15 +235,13 @@ static int exynos_dwmci_process_node(const void *blob,
int exynos_dwmmc_init(const void *blob)
{
- int compat_id;
int node_list[DWMMC_MAX_CH_NUM];
int boot_dev_node;
int err = 0, count;
- compat_id = COMPAT_SAMSUNG_EXYNOS_DWMMC;
-
count = fdtdec_find_aliases_for_id(blob, "mmc",
- compat_id, node_list, DWMMC_MAX_CH_NUM);
+ COMPAT_SAMSUNG_EXYNOS_DWMMC, node_list,
+ DWMMC_MAX_CH_NUM);
/* For DWMMC always set boot device as mmc 0 */
if (count >= 3 && get_boot_mode() == BOOT_MODE_SD) {
@@ -286,4 +254,58 @@ int exynos_dwmmc_init(const void *blob)
return err;
}
+
+#ifdef CONFIG_DM_MMC
+static int exynos_dwmmc_probe(struct udevice *dev)
+{
+ struct exynos_mmc_plat *plat = dev_get_platdata(dev);
+ struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
+ struct dwmci_exynos_priv_data *priv = dev_get_priv(dev);
+ struct dwmci_host *host = &priv->host;
+ int err;
+
+ err = exynos_dwmci_get_config(gd->fdt_blob, dev->of_offset, host);
+ if (err)
+ return err;
+ err = do_dwmci_init(host);
+ if (err)
+ return err;
+
+ dwmci_setup_cfg(&plat->cfg, host->name, host->buswidth, host->caps,
+ DWMMC_MAX_FREQ, DWMMC_MIN_FREQ);
+ host->mmc = &plat->mmc;
+ host->mmc->priv = &priv->host;
+ host->priv = dev;
+ upriv->mmc = host->mmc;
+
+ return dwmci_probe(dev);
+}
+
+static int exynos_dwmmc_bind(struct udevice *dev)
+{
+ struct exynos_mmc_plat *plat = dev_get_platdata(dev);
+ int ret;
+
+ ret = dwmci_bind(dev, &plat->mmc, &plat->cfg);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static const struct udevice_id exynos_dwmmc_ids[] = {
+ { .compatible = "samsung,exynos4412-dw-mshc" },
+ { }
+};
+
+U_BOOT_DRIVER(exynos_dwmmc_drv) = {
+ .name = "exynos_dwmmc",
+ .id = UCLASS_MMC,
+ .of_match = exynos_dwmmc_ids,
+ .bind = exynos_dwmmc_bind,
+ .ops = &dm_dwmci_ops,
+ .probe = exynos_dwmmc_probe,
+ .priv_auto_alloc_size = sizeof(struct dwmci_exynos_priv_data),
+ .platdata_auto_alloc_size = sizeof(struct exynos_mmc_plat),
+};
#endif
diff --git a/drivers/mmc/mmc-uclass.c b/drivers/mmc/mmc-uclass.c
index 1b967d9..38ced41 100644
--- a/drivers/mmc/mmc-uclass.c
+++ b/drivers/mmc/mmc-uclass.c
@@ -8,8 +8,76 @@
#include <common.h>
#include <mmc.h>
#include <dm.h>
+#include <dm/device-internal.h>
#include <dm/lists.h>
#include <dm/root.h>
+#include "mmc_private.h"
+
+#ifdef CONFIG_DM_MMC_OPS
+int dm_mmc_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
+ struct mmc_data *data)
+{
+ struct mmc *mmc = mmc_get_mmc_dev(dev);
+ struct dm_mmc_ops *ops = mmc_get_ops(dev);
+ int ret;
+
+ mmmc_trace_before_send(mmc, cmd);
+ if (ops->send_cmd)
+ ret = ops->send_cmd(dev, cmd, data);
+ else
+ ret = -ENOSYS;
+ mmmc_trace_after_send(mmc, cmd, ret);
+
+ return ret;
+}
+
+int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
+{
+ return dm_mmc_send_cmd(mmc->dev, cmd, data);
+}
+
+int dm_mmc_set_ios(struct udevice *dev)
+{
+ struct dm_mmc_ops *ops = mmc_get_ops(dev);
+
+ if (!ops->set_ios)
+ return -ENOSYS;
+ return ops->set_ios(dev);
+}
+
+int mmc_set_ios(struct mmc *mmc)
+{
+ return dm_mmc_set_ios(mmc->dev);
+}
+
+int dm_mmc_get_wp(struct udevice *dev)
+{
+ struct dm_mmc_ops *ops = mmc_get_ops(dev);
+
+ if (!ops->get_wp)
+ return -ENOSYS;
+ return ops->get_wp(dev);
+}
+
+int mmc_getwp(struct mmc *mmc)
+{
+ return dm_mmc_get_wp(mmc->dev);
+}
+
+int dm_mmc_get_cd(struct udevice *dev)
+{
+ struct dm_mmc_ops *ops = mmc_get_ops(dev);
+
+ if (!ops->get_cd)
+ return -ENOSYS;
+ return ops->get_cd(dev);
+}
+
+int mmc_getcd(struct mmc *mmc)
+{
+ return dm_mmc_get_cd(mmc->dev);
+}
+#endif
struct mmc *mmc_get_mmc_dev(struct udevice *dev)
{
@@ -125,6 +193,84 @@ void print_mmc_devices(char separator)
#else
void print_mmc_devices(char separator) { }
#endif
+
+int mmc_bind(struct udevice *dev, struct mmc *mmc, const struct mmc_config *cfg)
+{
+ struct blk_desc *bdesc;
+ struct udevice *bdev;
+ int ret;
+
+ ret = blk_create_devicef(dev, "mmc_blk", "blk", IF_TYPE_MMC, -1, 512,
+ 0, &bdev);
+ if (ret) {
+ debug("Cannot create block device\n");
+ return ret;
+ }
+ bdesc = dev_get_uclass_platdata(bdev);
+ mmc->cfg = cfg;
+ mmc->priv = dev;
+
+ /* the following chunk was from mmc_register() */
+
+ /* Setup dsr related values */
+ mmc->dsr_imp = 0;
+ mmc->dsr = 0xffffffff;
+ /* Setup the universal parts of the block interface just once */
+ bdesc->removable = 1;
+
+ /* setup initial part type */
+ bdesc->part_type = cfg->part_type;
+ mmc->dev = dev;
+
+ return 0;
+}
+
+int mmc_unbind(struct udevice *dev)
+{
+ struct udevice *bdev;
+
+ device_find_first_child(dev, &bdev);
+ if (bdev) {
+ device_remove(bdev);
+ device_unbind(bdev);
+ }
+
+ return 0;
+}
+
+static int mmc_select_hwpart(struct udevice *bdev, int hwpart)
+{
+ struct udevice *mmc_dev = dev_get_parent(bdev);
+ struct mmc *mmc = mmc_get_mmc_dev(mmc_dev);
+ struct blk_desc *desc = dev_get_uclass_platdata(bdev);
+ int ret;
+
+ if (desc->hwpart == hwpart)
+ return 0;
+
+ if (mmc->part_config == MMCPART_NOAVAILABLE)
+ return -EMEDIUMTYPE;
+
+ ret = mmc_switch_part(mmc, hwpart);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static const struct blk_ops mmc_blk_ops = {
+ .read = mmc_bread,
+#ifndef CONFIG_SPL_BUILD
+ .write = mmc_bwrite,
+#endif
+ .select_hwpart = mmc_select_hwpart,
+};
+
+U_BOOT_DRIVER(mmc_blk) = {
+ .name = "mmc_blk",
+ .id = UCLASS_BLK,
+ .ops = &mmc_blk_ops,
+};
#endif /* CONFIG_BLK */
U_BOOT_DRIVER(mmc) = {
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index aabfc71..f8e5f7a 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -21,6 +21,7 @@
#include <div64.h>
#include "mmc_private.h"
+#ifndef CONFIG_DM_MMC_OPS
__weak int board_mmc_getwp(struct mmc *mmc)
{
return -1;
@@ -46,18 +47,20 @@ __weak int board_mmc_getcd(struct mmc *mmc)
{
return -1;
}
+#endif
-int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
+#ifdef CONFIG_MMC_TRACE
+void mmmc_trace_before_send(struct mmc *mmc, struct mmc_cmd *cmd)
{
- int ret;
+ printf("CMD_SEND:%d\n", cmd->cmdidx);
+ printf("\t\tARG\t\t\t 0x%08X\n", cmd->cmdarg);
+}
-#ifdef CONFIG_MMC_TRACE
+void mmmc_trace_after_send(struct mmc *mmc, struct mmc_cmd *cmd, int ret)
+{
int i;
u8 *ptr;
- printf("CMD_SEND:%d\n", cmd->cmdidx);
- printf("\t\tARG\t\t\t 0x%08X\n", cmd->cmdarg);
- ret = mmc->cfg->ops->send_cmd(mmc, cmd, data);
if (ret) {
printf("\t\tRET\t\t\t %d\n", ret);
} else {
@@ -103,19 +106,34 @@ int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
break;
}
}
-#else
- ret = mmc->cfg->ops->send_cmd(mmc, cmd, data);
+}
+
+void mmc_trace_state(struct mmc *mmc, struct mmc_cmd *cmd)
+{
+ int status;
+
+ status = (cmd->response[0] & MMC_STATUS_CURR_STATE) >> 9;
+ printf("CURR STATE:%d\n", status);
+}
#endif
+
+#ifndef CONFIG_DM_MMC_OPS
+int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
+{
+ int ret;
+
+ mmmc_trace_before_send(mmc, cmd);
+ ret = mmc->cfg->ops->send_cmd(mmc, cmd, data);
+ mmmc_trace_after_send(mmc, cmd, ret);
+
return ret;
}
+#endif
int mmc_send_status(struct mmc *mmc, int timeout)
{
struct mmc_cmd cmd;
int err, retries = 5;
-#ifdef CONFIG_MMC_TRACE
- int status;
-#endif
cmd.cmdidx = MMC_CMD_SEND_STATUS;
cmd.resp_type = MMC_RSP_R1;
@@ -145,10 +163,7 @@ int mmc_send_status(struct mmc *mmc, int timeout)
udelay(1000);
}
-#ifdef CONFIG_MMC_TRACE
- status = (cmd.response[0] & MMC_STATUS_CURR_STATE) >> 9;
- printf("CURR STATE:%d\n", status);
-#endif
+ mmc_trace_state(mmc, &cmd);
if (timeout <= 0) {
#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
printf("Timeout waiting card ready\n");
@@ -215,11 +230,10 @@ static int mmc_read_blocks(struct mmc *mmc, void *dst, lbaint_t start,
}
#ifdef CONFIG_BLK
-static ulong mmc_bread(struct udevice *dev, lbaint_t start, lbaint_t blkcnt,
- void *dst)
+ulong mmc_bread(struct udevice *dev, lbaint_t start, lbaint_t blkcnt, void *dst)
#else
-static ulong mmc_bread(struct blk_desc *block_dev, lbaint_t start,
- lbaint_t blkcnt, void *dst)
+ulong mmc_bread(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt,
+ void *dst)
#endif
{
#ifdef CONFIG_BLK
@@ -464,8 +478,7 @@ static int mmc_send_ext_csd(struct mmc *mmc, u8 *ext_csd)
return err;
}
-
-static int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value)
+int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value)
{
struct mmc_cmd cmd;
int timeout = 1000;
@@ -566,7 +579,7 @@ static int mmc_set_capacity(struct mmc *mmc, int part_num)
return 0;
}
-static int mmc_switch_part(struct mmc *mmc, unsigned int part_num)
+int mmc_switch_part(struct mmc *mmc, unsigned int part_num)
{
int ret;
@@ -586,49 +599,6 @@ static int mmc_switch_part(struct mmc *mmc, unsigned int part_num)
return ret;
}
-#ifdef CONFIG_BLK
-static int mmc_select_hwpart(struct udevice *bdev, int hwpart)
-{
- struct udevice *mmc_dev = dev_get_parent(bdev);
- struct mmc *mmc = mmc_get_mmc_dev(mmc_dev);
- struct blk_desc *desc = dev_get_uclass_platdata(bdev);
- int ret;
-
- if (desc->hwpart == hwpart)
- return 0;
-
- if (mmc->part_config == MMCPART_NOAVAILABLE)
- return -EMEDIUMTYPE;
-
- ret = mmc_switch_part(mmc, hwpart);
- if (ret)
- return ret;
-
- return 0;
-}
-#else
-static int mmc_select_hwpartp(struct blk_desc *desc, int hwpart)
-{
- struct mmc *mmc = find_mmc_device(desc->devnum);
- int ret;
-
- if (!mmc)
- return -ENODEV;
-
- if (mmc->block_dev.hwpart == hwpart)
- return 0;
-
- if (mmc->part_config == MMCPART_NOAVAILABLE)
- return -EMEDIUMTYPE;
-
- ret = mmc_switch_part(mmc, hwpart);
- if (ret)
- return ret;
-
- return 0;
-}
-#endif
-
int mmc_hwpart_config(struct mmc *mmc,
const struct mmc_hwpart_conf *conf,
enum mmc_hwpart_conf_mode mode)
@@ -823,6 +793,7 @@ int mmc_hwpart_config(struct mmc *mmc,
return 0;
}
+#ifndef CONFIG_DM_MMC_OPS
int mmc_getcd(struct mmc *mmc)
{
int cd;
@@ -838,6 +809,7 @@ int mmc_getcd(struct mmc *mmc)
return cd;
}
+#endif
static int sd_switch(struct mmc *mmc, int mode, int group, u8 value, u8 *resp)
{
@@ -1001,11 +973,13 @@ static const u8 multipliers[] = {
80,
};
+#ifndef CONFIG_DM_MMC_OPS
static void mmc_set_ios(struct mmc *mmc)
{
if (mmc->cfg->ops->set_ios)
mmc->cfg->ops->set_ios(mmc);
}
+#endif
void mmc_set_clock(struct mmc *mmc, uint clock)
{
@@ -1532,115 +1506,6 @@ static int mmc_send_if_cond(struct mmc *mmc)
return 0;
}
-#ifdef CONFIG_BLK
-int mmc_bind(struct udevice *dev, struct mmc *mmc, const struct mmc_config *cfg)
-{
- struct blk_desc *bdesc;
- struct udevice *bdev;
- int ret;
-
- ret = blk_create_devicef(dev, "mmc_blk", "blk", IF_TYPE_MMC, -1, 512,
- 0, &bdev);
- if (ret) {
- debug("Cannot create block device\n");
- return ret;
- }
- bdesc = dev_get_uclass_platdata(bdev);
- mmc->cfg = cfg;
- mmc->priv = dev;
-
- /* the following chunk was from mmc_register() */
-
- /* Setup dsr related values */
- mmc->dsr_imp = 0;
- mmc->dsr = 0xffffffff;
- /* Setup the universal parts of the block interface just once */
- bdesc->removable = 1;
-
- /* setup initial part type */
- bdesc->part_type = cfg->part_type;
- mmc->dev = dev;
-
- return 0;
-}
-
-int mmc_unbind(struct udevice *dev)
-{
- struct udevice *bdev;
-
- device_find_first_child(dev, &bdev);
- if (bdev) {
- device_remove(bdev);
- device_unbind(bdev);
- }
-
- return 0;
-}
-
-#else
-struct mmc *mmc_create(const struct mmc_config *cfg, void *priv)
-{
- struct blk_desc *bdesc;
- struct mmc *mmc;
-
- /* quick validation */
- if (cfg == NULL || cfg->ops == NULL || cfg->ops->send_cmd == NULL ||
- cfg->f_min == 0 || cfg->f_max == 0 || cfg->b_max == 0)
- return NULL;
-
- mmc = calloc(1, sizeof(*mmc));
- if (mmc == NULL)
- return NULL;
-
- mmc->cfg = cfg;
- mmc->priv = priv;
-
- /* the following chunk was mmc_register() */
-
- /* Setup dsr related values */
- mmc->dsr_imp = 0;
- mmc->dsr = 0xffffffff;
- /* Setup the universal parts of the block interface just once */
- bdesc = mmc_get_blk_desc(mmc);
- bdesc->if_type = IF_TYPE_MMC;
- bdesc->removable = 1;
- bdesc->devnum = mmc_get_next_devnum();
- bdesc->block_read = mmc_bread;
- bdesc->block_write = mmc_bwrite;
- bdesc->block_erase = mmc_berase;
-
- /* setup initial part type */
- bdesc->part_type = mmc->cfg->part_type;
- mmc_list_add(mmc);
-
- return mmc;
-}
-
-void mmc_destroy(struct mmc *mmc)
-{
- /* only freeing memory for now */
- free(mmc);
-}
-#endif
-
-#ifndef CONFIG_BLK
-static int mmc_get_dev(int dev, struct blk_desc **descp)
-{
- struct mmc *mmc = find_mmc_device(dev);
- int ret;
-
- if (!mmc)
- return -ENODEV;
- ret = mmc_init(mmc);
- if (ret)
- return ret;
-
- *descp = &mmc->block_dev;
-
- return 0;
-}
-#endif
-
/* board-specific MMC power initializations. */
__weak void board_mmc_power_init(void)
{
@@ -1648,10 +1513,15 @@ __weak void board_mmc_power_init(void)
int mmc_start_init(struct mmc *mmc)
{
+ bool no_card;
int err;
/* we pretend there's no card when init is NULL */
- if (mmc_getcd(mmc) == 0 || mmc->cfg->ops->init == NULL) {
+ no_card = mmc_getcd(mmc) == 0;
+#ifndef CONFIG_DM_MMC_OPS
+ no_card = no_card || (mmc->cfg->ops->init == NULL);
+#endif
+ if (no_card) {
mmc->has_init = 0;
#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
printf("MMC: no card present\n");
@@ -1667,12 +1537,14 @@ int mmc_start_init(struct mmc *mmc)
#endif
board_mmc_power_init();
+#ifdef CONFIG_DM_MMC_OPS
+ /* The device has already been probed ready for use */
+#else
/* made sure it's not NULL earlier */
err = mmc->cfg->ops->init(mmc);
-
if (err)
return err;
-
+#endif
mmc->ddr_mode = 0;
mmc_set_bus_width(mmc, 1);
mmc_set_clock(mmc, 1);
@@ -1839,148 +1711,3 @@ int mmc_initialize(bd_t *bis)
mmc_do_preinit();
return 0;
}
-
-#ifdef CONFIG_SUPPORT_EMMC_BOOT
-/*
- * This function changes the size of boot partition and the size of rpmb
- * partition present on EMMC devices.
- *
- * Input Parameters:
- * struct *mmc: pointer for the mmc device strcuture
- * bootsize: size of boot partition
- * rpmbsize: size of rpmb partition
- *
- * Returns 0 on success.
- */
-
-int mmc_boot_partition_size_change(struct mmc *mmc, unsigned long bootsize,
- unsigned long rpmbsize)
-{
- int err;
- struct mmc_cmd cmd;
-
- /* Only use this command for raw EMMC moviNAND. Enter backdoor mode */
- cmd.cmdidx = MMC_CMD_RES_MAN;
- cmd.resp_type = MMC_RSP_R1b;
- cmd.cmdarg = MMC_CMD62_ARG1;
-
- err = mmc_send_cmd(mmc, &cmd, NULL);
- if (err) {
- debug("mmc_boot_partition_size_change: Error1 = %d\n", err);
- return err;
- }
-
- /* Boot partition changing mode */
- cmd.cmdidx = MMC_CMD_RES_MAN;
- cmd.resp_type = MMC_RSP_R1b;
- cmd.cmdarg = MMC_CMD62_ARG2;
-
- err = mmc_send_cmd(mmc, &cmd, NULL);
- if (err) {
- debug("mmc_boot_partition_size_change: Error2 = %d\n", err);
- return err;
- }
- /* boot partition size is multiple of 128KB */
- bootsize = (bootsize * 1024) / 128;
-
- /* Arg: boot partition size */
- cmd.cmdidx = MMC_CMD_RES_MAN;
- cmd.resp_type = MMC_RSP_R1b;
- cmd.cmdarg = bootsize;
-
- err = mmc_send_cmd(mmc, &cmd, NULL);
- if (err) {
- debug("mmc_boot_partition_size_change: Error3 = %d\n", err);
- return err;
- }
- /* RPMB partition size is multiple of 128KB */
- rpmbsize = (rpmbsize * 1024) / 128;
- /* Arg: RPMB partition size */
- cmd.cmdidx = MMC_CMD_RES_MAN;
- cmd.resp_type = MMC_RSP_R1b;
- cmd.cmdarg = rpmbsize;
-
- err = mmc_send_cmd(mmc, &cmd, NULL);
- if (err) {
- debug("mmc_boot_partition_size_change: Error4 = %d\n", err);
- return err;
- }
- return 0;
-}
-
-/*
- * Modify EXT_CSD[177] which is BOOT_BUS_WIDTH
- * based on the passed in values for BOOT_BUS_WIDTH, RESET_BOOT_BUS_WIDTH
- * and BOOT_MODE.
- *
- * Returns 0 on success.
- */
-int mmc_set_boot_bus_width(struct mmc *mmc, u8 width, u8 reset, u8 mode)
-{
- int err;
-
- err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BOOT_BUS_WIDTH,
- EXT_CSD_BOOT_BUS_WIDTH_MODE(mode) |
- EXT_CSD_BOOT_BUS_WIDTH_RESET(reset) |
- EXT_CSD_BOOT_BUS_WIDTH_WIDTH(width));
-
- if (err)
- return err;
- return 0;
-}
-
-/*
- * Modify EXT_CSD[179] which is PARTITION_CONFIG (formerly BOOT_CONFIG)
- * based on the passed in values for BOOT_ACK, BOOT_PARTITION_ENABLE and
- * PARTITION_ACCESS.
- *
- * Returns 0 on success.
- */
-int mmc_set_part_conf(struct mmc *mmc, u8 ack, u8 part_num, u8 access)
-{
- int err;
-
- err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONF,
- EXT_CSD_BOOT_ACK(ack) |
- EXT_CSD_BOOT_PART_NUM(part_num) |
- EXT_CSD_PARTITION_ACCESS(access));
-
- if (err)
- return err;
- return 0;
-}
-
-/*
- * Modify EXT_CSD[162] which is RST_n_FUNCTION based on the given value
- * for enable. Note that this is a write-once field for non-zero values.
- *
- * Returns 0 on success.
- */
-int mmc_set_rst_n_function(struct mmc *mmc, u8 enable)
-{
- return mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_RST_N_FUNCTION,
- enable);
-}
-#endif
-
-#ifdef CONFIG_BLK
-static const struct blk_ops mmc_blk_ops = {
- .read = mmc_bread,
- .write = mmc_bwrite,
- .select_hwpart = mmc_select_hwpart,
-};
-
-U_BOOT_DRIVER(mmc_blk) = {
- .name = "mmc_blk",
- .id = UCLASS_BLK,
- .ops = &mmc_blk_ops,
-};
-#else
-U_BOOT_LEGACY_BLK(mmc) = {
- .if_typename = "mmc",
- .if_type = IF_TYPE_MMC,
- .max_devs = -1,
- .get_dev = mmc_get_dev,
- .select_hwpart = mmc_select_hwpartp,
-};
-#endif
diff --git a/drivers/mmc/mmc_boot.c b/drivers/mmc/mmc_boot.c
new file mode 100644
index 0000000..756a982
--- /dev/null
+++ b/drivers/mmc/mmc_boot.c
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2016 Google, Inc
+ * Written by Amar <amarendra.xt@samsung.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <mmc.h>
+#include "mmc_private.h"
+
+/*
+ * This function changes the size of boot partition and the size of rpmb
+ * partition present on EMMC devices.
+ *
+ * Input Parameters:
+ * struct *mmc: pointer for the mmc device strcuture
+ * bootsize: size of boot partition
+ * rpmbsize: size of rpmb partition
+ *
+ * Returns 0 on success.
+ */
+
+int mmc_boot_partition_size_change(struct mmc *mmc, unsigned long bootsize,
+ unsigned long rpmbsize)
+{
+ int err;
+ struct mmc_cmd cmd;
+
+ /* Only use this command for raw EMMC moviNAND. Enter backdoor mode */
+ cmd.cmdidx = MMC_CMD_RES_MAN;
+ cmd.resp_type = MMC_RSP_R1b;
+ cmd.cmdarg = MMC_CMD62_ARG1;
+
+ err = mmc_send_cmd(mmc, &cmd, NULL);
+ if (err) {
+ debug("mmc_boot_partition_size_change: Error1 = %d\n", err);
+ return err;
+ }
+
+ /* Boot partition changing mode */
+ cmd.cmdidx = MMC_CMD_RES_MAN;
+ cmd.resp_type = MMC_RSP_R1b;
+ cmd.cmdarg = MMC_CMD62_ARG2;
+
+ err = mmc_send_cmd(mmc, &cmd, NULL);
+ if (err) {
+ debug("mmc_boot_partition_size_change: Error2 = %d\n", err);
+ return err;
+ }
+ /* boot partition size is multiple of 128KB */
+ bootsize = (bootsize * 1024) / 128;
+
+ /* Arg: boot partition size */
+ cmd.cmdidx = MMC_CMD_RES_MAN;
+ cmd.resp_type = MMC_RSP_R1b;
+ cmd.cmdarg = bootsize;
+
+ err = mmc_send_cmd(mmc, &cmd, NULL);
+ if (err) {
+ debug("mmc_boot_partition_size_change: Error3 = %d\n", err);
+ return err;
+ }
+ /* RPMB partition size is multiple of 128KB */
+ rpmbsize = (rpmbsize * 1024) / 128;
+ /* Arg: RPMB partition size */
+ cmd.cmdidx = MMC_CMD_RES_MAN;
+ cmd.resp_type = MMC_RSP_R1b;
+ cmd.cmdarg = rpmbsize;
+
+ err = mmc_send_cmd(mmc, &cmd, NULL);
+ if (err) {
+ debug("mmc_boot_partition_size_change: Error4 = %d\n", err);
+ return err;
+ }
+ return 0;
+}
+
+/*
+ * Modify EXT_CSD[177] which is BOOT_BUS_WIDTH
+ * based on the passed in values for BOOT_BUS_WIDTH, RESET_BOOT_BUS_WIDTH
+ * and BOOT_MODE.
+ *
+ * Returns 0 on success.
+ */
+int mmc_set_boot_bus_width(struct mmc *mmc, u8 width, u8 reset, u8 mode)
+{
+ int err;
+
+ err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BOOT_BUS_WIDTH,
+ EXT_CSD_BOOT_BUS_WIDTH_MODE(mode) |
+ EXT_CSD_BOOT_BUS_WIDTH_RESET(reset) |
+ EXT_CSD_BOOT_BUS_WIDTH_WIDTH(width));
+
+ if (err)
+ return err;
+ return 0;
+}
+
+/*
+ * Modify EXT_CSD[179] which is PARTITION_CONFIG (formerly BOOT_CONFIG)
+ * based on the passed in values for BOOT_ACK, BOOT_PARTITION_ENABLE and
+ * PARTITION_ACCESS.
+ *
+ * Returns 0 on success.
+ */
+int mmc_set_part_conf(struct mmc *mmc, u8 ack, u8 part_num, u8 access)
+{
+ int err;
+
+ err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONF,
+ EXT_CSD_BOOT_ACK(ack) |
+ EXT_CSD_BOOT_PART_NUM(part_num) |
+ EXT_CSD_PARTITION_ACCESS(access));
+
+ if (err)
+ return err;
+ return 0;
+}
+
+/*
+ * Modify EXT_CSD[162] which is RST_n_FUNCTION based on the given value
+ * for enable. Note that this is a write-once field for non-zero values.
+ *
+ * Returns 0 on success.
+ */
+int mmc_set_rst_n_function(struct mmc *mmc, u8 enable)
+{
+ return mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_RST_N_FUNCTION,
+ enable);
+}
diff --git a/drivers/mmc/mmc_legacy.c b/drivers/mmc/mmc_legacy.c
index 3ec649f..040728b 100644
--- a/drivers/mmc/mmc_legacy.c
+++ b/drivers/mmc/mmc_legacy.c
@@ -6,7 +6,9 @@
*/
#include <common.h>
+#include <malloc.h>
#include <mmc.h>
+#include "mmc_private.h"
static struct list_head mmc_devices;
static int cur_dev_num = -1;
@@ -106,3 +108,92 @@ void print_mmc_devices(char separator)
#else
void print_mmc_devices(char separator) { }
#endif
+
+struct mmc *mmc_create(const struct mmc_config *cfg, void *priv)
+{
+ struct blk_desc *bdesc;
+ struct mmc *mmc;
+
+ /* quick validation */
+ if (cfg == NULL || cfg->ops == NULL || cfg->ops->send_cmd == NULL ||
+ cfg->f_min == 0 || cfg->f_max == 0 || cfg->b_max == 0)
+ return NULL;
+
+ mmc = calloc(1, sizeof(*mmc));
+ if (mmc == NULL)
+ return NULL;
+
+ mmc->cfg = cfg;
+ mmc->priv = priv;
+
+ /* the following chunk was mmc_register() */
+
+ /* Setup dsr related values */
+ mmc->dsr_imp = 0;
+ mmc->dsr = 0xffffffff;
+ /* Setup the universal parts of the block interface just once */
+ bdesc = mmc_get_blk_desc(mmc);
+ bdesc->if_type = IF_TYPE_MMC;
+ bdesc->removable = 1;
+ bdesc->devnum = mmc_get_next_devnum();
+ bdesc->block_read = mmc_bread;
+ bdesc->block_write = mmc_bwrite;
+ bdesc->block_erase = mmc_berase;
+
+ /* setup initial part type */
+ bdesc->part_type = mmc->cfg->part_type;
+ mmc_list_add(mmc);
+
+ return mmc;
+}
+
+void mmc_destroy(struct mmc *mmc)
+{
+ /* only freeing memory for now */
+ free(mmc);
+}
+
+static int mmc_select_hwpartp(struct blk_desc *desc, int hwpart)
+{
+ struct mmc *mmc = find_mmc_device(desc->devnum);
+ int ret;
+
+ if (!mmc)
+ return -ENODEV;
+
+ if (mmc->block_dev.hwpart == hwpart)
+ return 0;
+
+ if (mmc->part_config == MMCPART_NOAVAILABLE)
+ return -EMEDIUMTYPE;
+
+ ret = mmc_switch_part(mmc, hwpart);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static int mmc_get_dev(int dev, struct blk_desc **descp)
+{
+ struct mmc *mmc = find_mmc_device(dev);
+ int ret;
+
+ if (!mmc)
+ return -ENODEV;
+ ret = mmc_init(mmc);
+ if (ret)
+ return ret;
+
+ *descp = &mmc->block_dev;
+
+ return 0;
+}
+
+U_BOOT_LEGACY_BLK(mmc) = {
+ .if_typename = "mmc",
+ .if_type = IF_TYPE_MMC,
+ .max_devs = -1,
+ .get_dev = mmc_get_dev,
+ .select_hwpart = mmc_select_hwpartp,
+};
diff --git a/drivers/mmc/mmc_private.h b/drivers/mmc/mmc_private.h
index 9f0d5c2..49ec022 100644
--- a/drivers/mmc/mmc_private.h
+++ b/drivers/mmc/mmc_private.h
@@ -20,6 +20,14 @@ extern int mmc_set_blocklen(struct mmc *mmc, int len);
void mmc_adapter_card_type_ident(void);
#endif
+#ifdef CONFIG_BLK
+ulong mmc_bread(struct udevice *dev, lbaint_t start, lbaint_t blkcnt,
+ void *dst);
+#else
+ulong mmc_bread(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt,
+ void *dst);
+#endif
+
#ifndef CONFIG_SPL_BUILD
unsigned long mmc_berase(struct blk_desc *block_dev, lbaint_t start,
@@ -65,6 +73,25 @@ static inline ulong mmc_bwrite(struct blk_desc *block_dev, lbaint_t start,
#endif /* CONFIG_SPL_BUILD */
+#ifdef CONFIG_MMC_TRACE
+void mmmc_trace_before_send(struct mmc *mmc, struct mmc_cmd *cmd);
+void mmmc_trace_after_send(struct mmc *mmc, struct mmc_cmd *cmd, int ret);
+void mmc_trace_state(struct mmc *mmc, struct mmc_cmd *cmd);
+#else
+static inline void mmmc_trace_before_send(struct mmc *mmc, struct mmc_cmd *cmd)
+{
+}
+
+static inline void mmmc_trace_after_send(struct mmc *mmc, struct mmc_cmd *cmd,
+ int ret)
+{
+}
+
+static inline void mmc_trace_state(struct mmc *mmc, struct mmc_cmd *cmd)
+{
+}
+#endif
+
/**
* mmc_get_next_devnum() - Get the next available MMC device number
*
@@ -89,4 +116,24 @@ void mmc_list_init(void);
*/
void mmc_list_add(struct mmc *mmc);
+/**
+ * mmc_switch_part() - Switch to a new MMC hardware partition
+ *
+ * @mmc: MMC device
+ * @part_num: Hardware partition number
+ * @return 0 if OK, -ve on error
+ */
+int mmc_switch_part(struct mmc *mmc, unsigned int part_num);
+
+/**
+ * mmc_switch() - Issue and MMC switch mode command
+ *
+ * @mmc: MMC device
+ * @set: Unused
+ * @index: Cmdarg index
+ * @value: Cmdarg value
+ * @return 0 if OK, -ve on error
+ */
+int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value);
+
#endif /* _MMC_PRIVATE_H_ */
diff --git a/drivers/mmc/msm_sdhci.c b/drivers/mmc/msm_sdhci.c
index 96dcdbe..70a8d96 100644
--- a/drivers/mmc/msm_sdhci.c
+++ b/drivers/mmc/msm_sdhci.c
@@ -36,6 +36,11 @@
/* Non standard (?) SDHCI register */
#define SDHCI_VENDOR_SPEC_CAPABILITIES0 0x11c
+struct msm_sdhc_plat {
+ struct mmc_config cfg;
+ struct mmc mmc;
+};
+
struct msm_sdhc {
struct sdhci_host host;
void *base;
@@ -81,9 +86,12 @@ static int msm_sdc_clk_init(struct udevice *dev)
static int msm_sdc_probe(struct udevice *dev)
{
+ struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
+ struct msm_sdhc_plat *plat = dev_get_platdata(dev);
struct msm_sdhc *prv = dev_get_priv(dev);
struct sdhci_host *host = &prv->host;
u32 core_version, core_minor, core_major;
+ u32 caps;
int ret;
host->quirks = SDHCI_QUIRK_WAIT_SEND_CMD | SDHCI_QUIRK_BROKEN_R1B;
@@ -127,7 +135,7 @@ static int msm_sdc_probe(struct udevice *dev)
* controller versions and must be explicitly enabled.
*/
if (core_major >= 1 && core_minor != 0x11 && core_minor != 0x12) {
- u32 caps = readl(host->ioaddr + SDHCI_CAPABILITIES);
+ caps = readl(host->ioaddr + SDHCI_CAPABILITIES);
caps |= SDHCI_CAN_VDD_300 | SDHCI_CAN_DO_8BIT;
writel(caps, host->ioaddr + SDHCI_VENDOR_SPEC_CAPABILITIES0);
}
@@ -135,13 +143,17 @@ static int msm_sdc_probe(struct udevice *dev)
/* Set host controller version */
host->version = sdhci_readw(host, SDHCI_HOST_VERSION);
- /* automatically detect max and min speed */
- ret = add_sdhci(host, 0, 0);
+ caps = sdhci_readl(host, SDHCI_CAPABILITIES);
+ ret = sdhci_setup_cfg(&plat->cfg, dev->name, host->bus_width,
+ caps, 0, 0, host->version, host->quirks, 0);
+ host->mmc = &plat->mmc;
if (ret)
return ret;
+ host->mmc->priv = &prv->host;
host->mmc->dev = dev;
+ upriv->mmc = host->mmc;
- return 0;
+ return sdhci_probe(dev);
}
static int msm_sdc_remove(struct udevice *dev)
@@ -176,6 +188,18 @@ static int msm_ofdata_to_platdata(struct udevice *dev)
return 0;
}
+static int msm_sdc_bind(struct udevice *dev)
+{
+ struct msm_sdhc_plat *plat = dev_get_platdata(dev);
+ int ret;
+
+ ret = sdhci_bind(dev, &plat->mmc, &plat->cfg);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
static const struct udevice_id msm_mmc_ids[] = {
{ .compatible = "qcom,sdhci-msm-v4" },
{ }
@@ -186,7 +210,10 @@ U_BOOT_DRIVER(msm_sdc_drv) = {
.id = UCLASS_MMC,
.of_match = msm_mmc_ids,
.ofdata_to_platdata = msm_ofdata_to_platdata,
+ .ops = &sdhci_ops,
+ .bind = msm_sdc_bind,
.probe = msm_sdc_probe,
.remove = msm_sdc_remove,
.priv_auto_alloc_size = sizeof(struct msm_sdhc),
+ .platdata_auto_alloc_size = sizeof(struct msm_sdhc_plat),
};
diff --git a/drivers/mmc/rockchip_dw_mmc.c b/drivers/mmc/rockchip_dw_mmc.c
index d41d60c..020a59b 100644
--- a/drivers/mmc/rockchip_dw_mmc.c
+++ b/drivers/mmc/rockchip_dw_mmc.c
@@ -7,8 +7,10 @@
#include <common.h>
#include <clk.h>
#include <dm.h>
+#include <dt-structs.h>
#include <dwmmc.h>
#include <errno.h>
+#include <mapmem.h>
#include <pwrseq.h>
#include <syscon.h>
#include <asm/gpio.h>
@@ -19,6 +21,9 @@
DECLARE_GLOBAL_DATA_PTR;
struct rockchip_mmc_plat {
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+ struct dtd_rockchip_rk3288_dw_mshc dtplat;
+#endif
struct mmc_config cfg;
struct mmc mmc;
};
@@ -26,6 +31,9 @@ struct rockchip_mmc_plat {
struct rockchip_dwmmc_priv {
struct clk clk;
struct dwmci_host host;
+ int fifo_depth;
+ bool fifo_mode;
+ u32 minmax[2];
};
static uint rockchip_dwmmc_get_mmc_clk(struct dwmci_host *host, uint freq)
@@ -45,6 +53,7 @@ static uint rockchip_dwmmc_get_mmc_clk(struct dwmci_host *host, uint freq)
static int rockchip_dwmmc_ofdata_to_platdata(struct udevice *dev)
{
+#if !CONFIG_IS_ENABLED(OF_PLATDATA)
struct rockchip_dwmmc_priv *priv = dev_get_priv(dev);
struct dwmci_host *host = &priv->host;
@@ -61,40 +70,54 @@ static int rockchip_dwmmc_ofdata_to_platdata(struct udevice *dev)
else
host->dev_index = 1;
+ priv->fifo_depth = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
+ "fifo-depth", 0);
+ if (priv->fifo_depth < 0)
+ return -EINVAL;
+ priv->fifo_mode = fdtdec_get_bool(gd->fdt_blob, dev->of_offset,
+ "fifo-mode");
+ if (fdtdec_get_int_array(gd->fdt_blob, dev->of_offset,
+ "clock-freq-min-max", priv->minmax, 2))
+ return -EINVAL;
+#endif
return 0;
}
static int rockchip_dwmmc_probe(struct udevice *dev)
{
-#ifdef CONFIG_BLK
struct rockchip_mmc_plat *plat = dev_get_platdata(dev);
-#endif
struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
struct rockchip_dwmmc_priv *priv = dev_get_priv(dev);
struct dwmci_host *host = &priv->host;
struct udevice *pwr_dev __maybe_unused;
- u32 minmax[2];
int ret;
- int fifo_depth;
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+ struct dtd_rockchip_rk3288_dw_mshc *dtplat = &plat->dtplat;
+
+ host->name = dev->name;
+ host->ioaddr = map_sysmem(dtplat->reg[0], dtplat->reg[1]);
+ host->buswidth = dtplat->bus_width;
+ host->get_mmc_clk = rockchip_dwmmc_get_mmc_clk;
+ host->priv = dev;
+ host->dev_index = 0;
+ priv->fifo_depth = dtplat->fifo_depth;
+ priv->fifo_mode = 0;
+ memcpy(priv->minmax, dtplat->clock_freq_min_max, sizeof(priv->minmax));
+
+ ret = clk_get_by_index_platdata(dev, 0, dtplat->clocks, &priv->clk);
+ if (ret < 0)
+ return ret;
+#else
ret = clk_get_by_index(dev, 0, &priv->clk);
if (ret < 0)
return ret;
-
- if (fdtdec_get_int_array(gd->fdt_blob, dev->of_offset,
- "clock-freq-min-max", minmax, 2))
- return -EINVAL;
-
- fifo_depth = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
- "fifo-depth", 0);
- if (fifo_depth < 0)
- return -EINVAL;
-
+#endif
host->fifoth_val = MSIZE(0x2) |
- RX_WMARK(fifo_depth / 2 - 1) | TX_WMARK(fifo_depth / 2);
+ RX_WMARK(priv->fifo_depth / 2 - 1) |
+ TX_WMARK(priv->fifo_depth / 2);
- if (fdtdec_get_bool(gd->fdt_blob, dev->of_offset, "fifo-mode"))
- host->fifo_mode = true;
+ host->fifo_mode = priv->fifo_mode;
#ifdef CONFIG_PWRSEQ
/* Enable power if needed */
@@ -106,33 +129,24 @@ static int rockchip_dwmmc_probe(struct udevice *dev)
return ret;
}
#endif
-#ifdef CONFIG_BLK
dwmci_setup_cfg(&plat->cfg, dev->name, host->buswidth, host->caps,
- minmax[1], minmax[0]);
+ priv->minmax[1], priv->minmax[0]);
host->mmc = &plat->mmc;
-#else
- ret = add_dwmci(host, minmax[1], minmax[0]);
- if (ret)
- return ret;
-
-#endif
host->mmc->priv = &priv->host;
host->mmc->dev = dev;
upriv->mmc = host->mmc;
- return 0;
+ return dwmci_probe(dev);
}
static int rockchip_dwmmc_bind(struct udevice *dev)
{
-#ifdef CONFIG_BLK
struct rockchip_mmc_plat *plat = dev_get_platdata(dev);
int ret;
ret = dwmci_bind(dev, &plat->mmc, &plat->cfg);
if (ret)
return ret;
-#endif
return 0;
}
@@ -143,10 +157,11 @@ static const struct udevice_id rockchip_dwmmc_ids[] = {
};
U_BOOT_DRIVER(rockchip_dwmmc_drv) = {
- .name = "rockchip_dwmmc",
+ .name = "rockchip_rk3288_dw_mshc",
.id = UCLASS_MMC,
.of_match = rockchip_dwmmc_ids,
.ofdata_to_platdata = rockchip_dwmmc_ofdata_to_platdata,
+ .ops = &dm_dwmci_ops,
.bind = rockchip_dwmmc_bind,
.probe = rockchip_dwmmc_probe,
.priv_auto_alloc_size = sizeof(struct rockchip_dwmmc_priv),
diff --git a/drivers/mmc/sandbox_mmc.c b/drivers/mmc/sandbox_mmc.c
index 7da059c..5f1333b 100644
--- a/drivers/mmc/sandbox_mmc.c
+++ b/drivers/mmc/sandbox_mmc.c
@@ -25,7 +25,7 @@ struct sandbox_mmc_plat {
* This emulate an SD card version 2. Single-block reads result in zero data.
* Multiple-block reads return a test string.
*/
-static int sandbox_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
+static int sandbox_mmc_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
struct mmc_data *data)
{
switch (cmd->cmdidx) {
@@ -85,25 +85,20 @@ static int sandbox_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
return 0;
}
-static void sandbox_mmc_set_ios(struct mmc *mmc)
-{
-}
-
-static int sandbox_mmc_init(struct mmc *mmc)
+static int sandbox_mmc_set_ios(struct udevice *dev)
{
return 0;
}
-static int sandbox_mmc_getcd(struct mmc *mmc)
+static int sandbox_mmc_get_cd(struct udevice *dev)
{
return 1;
}
-static const struct mmc_ops sandbox_mmc_ops = {
+static const struct dm_mmc_ops sandbox_mmc_ops = {
.send_cmd = sandbox_mmc_send_cmd,
.set_ios = sandbox_mmc_set_ios,
- .init = sandbox_mmc_init,
- .getcd = sandbox_mmc_getcd,
+ .get_cd = sandbox_mmc_get_cd,
};
int sandbox_mmc_probe(struct udevice *dev)
@@ -120,7 +115,6 @@ int sandbox_mmc_bind(struct udevice *dev)
int ret;
cfg->name = dev->name;
- cfg->ops = &sandbox_mmc_ops;
cfg->host_caps = MMC_MODE_HS_52MHz | MMC_MODE_HS | MMC_MODE_8BIT;
cfg->voltages = MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34;
cfg->f_min = 1000000;
@@ -150,6 +144,7 @@ U_BOOT_DRIVER(mmc_sandbox) = {
.name = "mmc_sandbox",
.id = UCLASS_MMC,
.of_match = sandbox_mmc_ids,
+ .ops = &sandbox_mmc_ops,
.bind = sandbox_mmc_bind,
.unbind = sandbox_mmc_unbind,
.probe = sandbox_mmc_probe,
diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c
index 604f18d..de8d8ea 100644
--- a/drivers/mmc/sdhci.c
+++ b/drivers/mmc/sdhci.c
@@ -9,6 +9,7 @@
*/
#include <common.h>
+#include <errno.h>
#include <malloc.h>
#include <mmc.h>
#include <sdhci.h>
@@ -129,9 +130,17 @@ static int sdhci_transfer_data(struct sdhci_host *host, struct mmc_data *data,
#define CONFIG_SDHCI_CMD_DEFAULT_TIMEOUT 100
#define SDHCI_READ_STATUS_TIMEOUT 1000
+#ifdef CONFIG_DM_MMC_OPS
+static int sdhci_send_command(struct udevice *dev, struct mmc_cmd *cmd,
+ struct mmc_data *data)
+{
+ struct mmc *mmc = mmc_get_mmc_dev(dev);
+
+#else
static int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd,
- struct mmc_data *data)
+ struct mmc_data *data)
{
+#endif
struct sdhci_host *host = mmc->priv;
unsigned int stat = 0;
int ret = 0;
@@ -389,8 +398,14 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned short power)
sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL);
}
+#ifdef CONFIG_DM_MMC_OPS
+static int sdhci_set_ios(struct udevice *dev)
+{
+ struct mmc *mmc = mmc_get_mmc_dev(dev);
+#else
static void sdhci_set_ios(struct mmc *mmc)
{
+#endif
u32 ctrl;
struct sdhci_host *host = mmc->priv;
@@ -426,6 +441,9 @@ static void sdhci_set_ios(struct mmc *mmc)
ctrl &= ~SDHCI_CTRL_HISPD;
sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
+#ifdef CONFIG_DM_MMC_OPS
+ return 0;
+#endif
}
static int sdhci_init(struct mmc *mmc)
@@ -472,80 +490,110 @@ static int sdhci_init(struct mmc *mmc)
return 0;
}
+#ifdef CONFIG_DM_MMC_OPS
+int sdhci_probe(struct udevice *dev)
+{
+ struct mmc *mmc = mmc_get_mmc_dev(dev);
+
+ return sdhci_init(mmc);
+}
+const struct dm_mmc_ops sdhci_ops = {
+ .send_cmd = sdhci_send_command,
+ .set_ios = sdhci_set_ios,
+};
+#else
static const struct mmc_ops sdhci_ops = {
.send_cmd = sdhci_send_command,
.set_ios = sdhci_set_ios,
.init = sdhci_init,
};
+#endif
-int add_sdhci(struct sdhci_host *host, u32 max_clk, u32 min_clk)
+int sdhci_setup_cfg(struct mmc_config *cfg, const char *name, int buswidth,
+ uint caps, u32 max_clk, u32 min_clk, uint version,
+ uint quirks, uint host_caps)
{
- unsigned int caps;
-
- host->cfg.name = host->name;
- host->cfg.ops = &sdhci_ops;
-
- caps = sdhci_readl(host, SDHCI_CAPABILITIES);
-#ifdef CONFIG_MMC_SDMA
- if (!(caps & SDHCI_CAN_DO_SDMA)) {
- printf("%s: Your controller doesn't support SDMA!!\n",
- __func__);
- return -1;
- }
+ cfg->name = name;
+#ifndef CONFIG_DM_MMC_OPS
+ cfg->ops = &sdhci_ops;
#endif
-
if (max_clk)
- host->cfg.f_max = max_clk;
+ cfg->f_max = max_clk;
else {
- if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300)
- host->cfg.f_max = (caps & SDHCI_CLOCK_V3_BASE_MASK)
- >> SDHCI_CLOCK_BASE_SHIFT;
+ if (version >= SDHCI_SPEC_300)
+ cfg->f_max = (caps & SDHCI_CLOCK_V3_BASE_MASK) >>
+ SDHCI_CLOCK_BASE_SHIFT;
else
- host->cfg.f_max = (caps & SDHCI_CLOCK_BASE_MASK)
- >> SDHCI_CLOCK_BASE_SHIFT;
- host->cfg.f_max *= 1000000;
- }
- if (host->cfg.f_max == 0) {
- printf("%s: Hardware doesn't specify base clock frequency\n",
- __func__);
- return -1;
+ cfg->f_max = (caps & SDHCI_CLOCK_BASE_MASK) >>
+ SDHCI_CLOCK_BASE_SHIFT;
+ cfg->f_max *= 1000000;
}
+ if (cfg->f_max == 0)
+ return -EINVAL;
if (min_clk)
- host->cfg.f_min = min_clk;
+ cfg->f_min = min_clk;
else {
- if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300)
- host->cfg.f_min = host->cfg.f_max /
- SDHCI_MAX_DIV_SPEC_300;
+ if (version >= SDHCI_SPEC_300)
+ cfg->f_min = cfg->f_max / SDHCI_MAX_DIV_SPEC_300;
else
- host->cfg.f_min = host->cfg.f_max /
- SDHCI_MAX_DIV_SPEC_200;
+ cfg->f_min = cfg->f_max / SDHCI_MAX_DIV_SPEC_200;
}
-
- host->cfg.voltages = 0;
+ cfg->voltages = 0;
if (caps & SDHCI_CAN_VDD_330)
- host->cfg.voltages |= MMC_VDD_32_33 | MMC_VDD_33_34;
+ cfg->voltages |= MMC_VDD_32_33 | MMC_VDD_33_34;
if (caps & SDHCI_CAN_VDD_300)
- host->cfg.voltages |= MMC_VDD_29_30 | MMC_VDD_30_31;
+ cfg->voltages |= MMC_VDD_29_30 | MMC_VDD_30_31;
if (caps & SDHCI_CAN_VDD_180)
- host->cfg.voltages |= MMC_VDD_165_195;
+ cfg->voltages |= MMC_VDD_165_195;
- if (host->quirks & SDHCI_QUIRK_BROKEN_VOLTAGE)
- host->cfg.voltages |= host->voltages;
-
- host->cfg.host_caps = MMC_MODE_HS | MMC_MODE_HS_52MHz | MMC_MODE_4BIT;
- if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300) {
+ cfg->host_caps = MMC_MODE_HS | MMC_MODE_HS_52MHz | MMC_MODE_4BIT;
+ if (version >= SDHCI_SPEC_300) {
if (caps & SDHCI_CAN_DO_8BIT)
- host->cfg.host_caps |= MMC_MODE_8BIT;
+ cfg->host_caps |= MMC_MODE_8BIT;
}
- if (host->quirks & SDHCI_QUIRK_NO_HISPD_BIT)
- host->cfg.host_caps &= ~(MMC_MODE_HS | MMC_MODE_HS_52MHz);
+ if (quirks & SDHCI_QUIRK_NO_HISPD_BIT)
+ cfg->host_caps &= ~(MMC_MODE_HS | MMC_MODE_HS_52MHz);
- if (host->host_caps)
- host->cfg.host_caps |= host->host_caps;
+ if (host_caps)
+ cfg->host_caps |= host_caps;
- host->cfg.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
+
+ cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
+
+ return 0;
+}
+
+#ifdef CONFIG_BLK
+int sdhci_bind(struct udevice *dev, struct mmc *mmc, struct mmc_config *cfg)
+{
+ return mmc_bind(dev, mmc, cfg);
+}
+#else
+int add_sdhci(struct sdhci_host *host, u32 max_clk, u32 min_clk)
+{
+ unsigned int caps;
+
+ caps = sdhci_readl(host, SDHCI_CAPABILITIES);
+#ifdef CONFIG_MMC_SDMA
+ if (!(caps & SDHCI_CAN_DO_SDMA)) {
+ printf("%s: Your controller doesn't support SDMA!!\n",
+ __func__);
+ return -1;
+ }
+#endif
+
+ if (sdhci_setup_cfg(&host->cfg, host->name, host->bus_width, caps,
+ max_clk, min_clk, SDHCI_GET_VERSION(host),
+ host->quirks, host->host_caps)) {
+ printf("%s: Hardware doesn't specify base clock frequency\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ if (host->quirks & SDHCI_QUIRK_BROKEN_VOLTAGE)
+ host->cfg.voltages |= host->voltages;
sdhci_reset(host, SDHCI_RESET_ALL);
@@ -557,3 +605,4 @@ int add_sdhci(struct sdhci_host *host, u32 max_clk, u32 min_clk)
return 0;
}
+#endif
diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c
index ce2dc4a..5d8abdc 100644
--- a/drivers/mmc/sunxi_mmc.c
+++ b/drivers/mmc/sunxi_mmc.c
@@ -269,18 +269,18 @@ static int mmc_trans_data_by_cpu(struct mmc *mmc, struct mmc_data *data)
unsigned i;
unsigned *buff = (unsigned int *)(reading ? data->dest : data->src);
unsigned byte_cnt = data->blocksize * data->blocks;
- unsigned timeout_msecs = byte_cnt >> 8;
- if (timeout_msecs < 2000)
- timeout_msecs = 2000;
+ unsigned timeout_usecs = (byte_cnt >> 8) * 1000;
+ if (timeout_usecs < 2000000)
+ timeout_usecs = 2000000;
/* Always read / write data through the CPU */
setbits_le32(&mmchost->reg->gctrl, SUNXI_MMC_GCTRL_ACCESS_BY_AHB);
for (i = 0; i < (byte_cnt >> 2); i++) {
while (readl(&mmchost->reg->status) & status_bit) {
- if (!timeout_msecs--)
+ if (!timeout_usecs--)
return -1;
- udelay(1000);
+ udelay(1);
}
if (reading)
@@ -445,23 +445,6 @@ static int sunxi_mmc_getcd(struct mmc *mmc)
return !gpio_get_value(cd_pin);
}
-int sunxi_mmc_has_egon_boot_signature(struct mmc *mmc)
-{
- char *buf = malloc(512);
- int valid_signature = 0;
-
- if (buf == NULL)
- panic("Failed to allocate memory\n");
-
- if (mmc_getcd(mmc) && mmc_init(mmc) == 0 &&
- mmc->block_dev.block_read(&mmc->block_dev, 16, 1, buf) == 1 &&
- strncmp(&buf[4], "eGON.BT0", 8) == 0)
- valid_signature = 1;
-
- free(buf);
- return valid_signature;
-}
-
static const struct mmc_ops sunxi_mmc_ops = {
.send_cmd = sunxi_mmc_send_cmd,
.set_ios = sunxi_mmc_set_ios,
diff --git a/drivers/mtd/cfi_flash.c b/drivers/mtd/cfi_flash.c
index 8ccaff0..33c4a93 100644
--- a/drivers/mtd/cfi_flash.c
+++ b/drivers/mtd/cfi_flash.c
@@ -608,7 +608,7 @@ static int flash_full_status_check (flash_info_t * info, flash_sect_t sector,
case CFI_CMDSET_INTEL_EXTENDED:
case CFI_CMDSET_INTEL_STANDARD:
if ((retcode == ERR_OK)
- && !flash_isequal (info, sector, 0, FLASH_STATUS_DONE)) {
+ && !flash_isset(info, sector, 0, FLASH_STATUS_DONE)) {
retcode = ERR_INVAL;
printf ("Flash %s error at address %lx\n", prompt,
info->start[sector]);
diff --git a/drivers/mtd/nand/mxs_nand.c b/drivers/mtd/nand/mxs_nand.c
index c90a3a7..94fc5c1 100644
--- a/drivers/mtd/nand/mxs_nand.c
+++ b/drivers/mtd/nand/mxs_nand.c
@@ -976,7 +976,7 @@ static int mxs_nand_block_bad(struct mtd_info *mtd, loff_t ofs)
* counted, so we know the physical geometry. This enables us to make some
* important configuration decisions.
*
- * The return value of this function propogates directly back to this driver's
+ * The return value of this function propagates directly back to this driver's
* call to nand_scan(). Anything other than zero will cause this driver to
* tear everything down and declare failure.
*/
diff --git a/drivers/mtd/nand/tegra_nand.c b/drivers/mtd/nand/tegra_nand.c
index 2032f65..38bd7a5 100644
--- a/drivers/mtd/nand/tegra_nand.c
+++ b/drivers/mtd/nand/tegra_nand.c
@@ -884,7 +884,7 @@ static void setup_timing(unsigned timing[FDT_NAND_TIMING_COUNT],
* Decode NAND parameters from the device tree
*
* @param blob Device tree blob
- * @param node Node containing "nand-flash" compatble node
+ * @param node Node containing "nand-flash" compatible node
* @return 0 if ok, -ve on error (FDT_ERR_...)
*/
static int fdt_decode_nand(const void *blob, int node, struct fdt_nand *config)
diff --git a/drivers/mtd/spi/Kconfig b/drivers/mtd/spi/Kconfig
index 3f7433c..1f23c8e 100644
--- a/drivers/mtd/spi/Kconfig
+++ b/drivers/mtd/spi/Kconfig
@@ -128,4 +128,16 @@ config SPI_FLASH_MTD
If unsure, say N
+if SPL
+
+config SPL_SPI_SUNXI
+ bool "Support for SPI Flash on Allwinner SoCs in SPL"
+ depends on MACH_SUN4I || MACH_SUN5I || MACH_SUN7I || MACH_SUN8I_H3 || MACH_SUN50I
+ ---help---
+ Enable support for SPI Flash. This option allows SPL to read from
+ sunxi SPI Flash. It uses the same method as the boot ROM, so does
+ not need any extra configuration.
+
+endif
+
endmenu # menu "SPI Flash Support"
diff --git a/drivers/mtd/spi/Makefile b/drivers/mtd/spi/Makefile
index c665836..6f47a66 100644
--- a/drivers/mtd/spi/Makefile
+++ b/drivers/mtd/spi/Makefile
@@ -10,6 +10,7 @@ obj-$(CONFIG_DM_SPI_FLASH) += sf-uclass.o
ifdef CONFIG_SPL_BUILD
obj-$(CONFIG_SPL_SPI_LOAD) += spi_spl_load.o
obj-$(CONFIG_SPL_SPI_BOOT) += fsl_espi_spl.o
+obj-$(CONFIG_SPL_SPI_SUNXI) += sunxi_spi_spl.o
endif
obj-$(CONFIG_SPI_FLASH) += sf_probe.o spi_flash.o sf_params.o sf.o
diff --git a/drivers/mtd/spi/sunxi_spi_spl.c b/drivers/mtd/spi/sunxi_spi_spl.c
new file mode 100644
index 0000000..e3ded5b
--- /dev/null
+++ b/drivers/mtd/spi/sunxi_spi_spl.c
@@ -0,0 +1,283 @@
+/*
+ * Copyright (C) 2016 Siarhei Siamashka <siarhei.siamashka@gmail.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <spl.h>
+#include <asm/gpio.h>
+#include <asm/io.h>
+
+#ifdef CONFIG_SPL_OS_BOOT
+#error CONFIG_SPL_OS_BOOT is not supported yet
+#endif
+
+/*
+ * This is a very simple U-Boot image loading implementation, trying to
+ * replicate what the boot ROM is doing when loading the SPL. Because we
+ * know the exact pins where the SPI Flash is connected and also know
+ * that the Read Data Bytes (03h) command is supported, the hardware
+ * configuration is very simple and we don't need the extra flexibility
+ * of the SPI framework. Moreover, we rely on the default settings of
+ * the SPI controler hardware registers and only adjust what needs to
+ * be changed. This is good for the code size and this implementation
+ * adds less than 400 bytes to the SPL.
+ *
+ * There are two variants of the SPI controller in Allwinner SoCs:
+ * A10/A13/A20 (sun4i variant) and everything else (sun6i variant).
+ * Both of them are supported.
+ *
+ * The pin mixing part is SoC specific and only A10/A13/A20/H3/A64 are
+ * supported at the moment.
+ */
+
+/*****************************************************************************/
+/* SUN4I variant of the SPI controller */
+/*****************************************************************************/
+
+#define SUN4I_SPI0_CCTL (0x01C05000 + 0x1C)
+#define SUN4I_SPI0_CTL (0x01C05000 + 0x08)
+#define SUN4I_SPI0_RX (0x01C05000 + 0x00)
+#define SUN4I_SPI0_TX (0x01C05000 + 0x04)
+#define SUN4I_SPI0_FIFO_STA (0x01C05000 + 0x28)
+#define SUN4I_SPI0_BC (0x01C05000 + 0x20)
+#define SUN4I_SPI0_TC (0x01C05000 + 0x24)
+
+#define SUN4I_CTL_ENABLE BIT(0)
+#define SUN4I_CTL_MASTER BIT(1)
+#define SUN4I_CTL_TF_RST BIT(8)
+#define SUN4I_CTL_RF_RST BIT(9)
+#define SUN4I_CTL_XCH BIT(10)
+
+/*****************************************************************************/
+/* SUN6I variant of the SPI controller */
+/*****************************************************************************/
+
+#define SUN6I_SPI0_CCTL (0x01C68000 + 0x24)
+#define SUN6I_SPI0_GCR (0x01C68000 + 0x04)
+#define SUN6I_SPI0_TCR (0x01C68000 + 0x08)
+#define SUN6I_SPI0_FIFO_STA (0x01C68000 + 0x1C)
+#define SUN6I_SPI0_MBC (0x01C68000 + 0x30)
+#define SUN6I_SPI0_MTC (0x01C68000 + 0x34)
+#define SUN6I_SPI0_BCC (0x01C68000 + 0x38)
+#define SUN6I_SPI0_TXD (0x01C68000 + 0x200)
+#define SUN6I_SPI0_RXD (0x01C68000 + 0x300)
+
+#define SUN6I_CTL_ENABLE BIT(0)
+#define SUN6I_CTL_MASTER BIT(1)
+#define SUN6I_CTL_SRST BIT(31)
+#define SUN6I_TCR_XCH BIT(31)
+
+/*****************************************************************************/
+
+#define CCM_AHB_GATING0 (0x01C20000 + 0x60)
+#define CCM_SPI0_CLK (0x01C20000 + 0xA0)
+#define SUN6I_BUS_SOFT_RST_REG0 (0x01C20000 + 0x2C0)
+
+#define AHB_RESET_SPI0_SHIFT 20
+#define AHB_GATE_OFFSET_SPI0 20
+
+#define SPI0_CLK_DIV_BY_2 0x1000
+#define SPI0_CLK_DIV_BY_4 0x1001
+
+/*****************************************************************************/
+
+/*
+ * Allwinner A10/A20 SoCs were using pins PC0,PC1,PC2,PC23 for booting
+ * from SPI Flash, everything else is using pins PC0,PC1,PC2,PC3.
+ */
+static void spi0_pinmux_setup(unsigned int pin_function)
+{
+ unsigned int pin;
+
+ for (pin = SUNXI_GPC(0); pin <= SUNXI_GPC(2); pin++)
+ sunxi_gpio_set_cfgpin(pin, pin_function);
+
+ if (IS_ENABLED(CONFIG_MACH_SUN4I) || IS_ENABLED(CONFIG_MACH_SUN7I))
+ sunxi_gpio_set_cfgpin(SUNXI_GPC(23), pin_function);
+ else
+ sunxi_gpio_set_cfgpin(SUNXI_GPC(3), pin_function);
+}
+
+/*
+ * Setup 6 MHz from OSC24M (because the BROM is doing the same).
+ */
+static void spi0_enable_clock(void)
+{
+ /* Deassert SPI0 reset on SUN6I */
+ if (IS_ENABLED(CONFIG_SUNXI_GEN_SUN6I))
+ setbits_le32(SUN6I_BUS_SOFT_RST_REG0,
+ (1 << AHB_RESET_SPI0_SHIFT));
+
+ /* Open the SPI0 gate */
+ setbits_le32(CCM_AHB_GATING0, (1 << AHB_GATE_OFFSET_SPI0));
+
+ /* Divide by 4 */
+ writel(SPI0_CLK_DIV_BY_4, IS_ENABLED(CONFIG_SUNXI_GEN_SUN6I) ?
+ SUN6I_SPI0_CCTL : SUN4I_SPI0_CCTL);
+ /* 24MHz from OSC24M */
+ writel((1 << 31), CCM_SPI0_CLK);
+
+ if (IS_ENABLED(CONFIG_SUNXI_GEN_SUN6I)) {
+ /* Enable SPI in the master mode and do a soft reset */
+ setbits_le32(SUN6I_SPI0_GCR, SUN6I_CTL_MASTER |
+ SUN6I_CTL_ENABLE |
+ SUN6I_CTL_SRST);
+ /* Wait for completion */
+ while (readl(SUN6I_SPI0_GCR) & SUN6I_CTL_SRST)
+ ;
+ } else {
+ /* Enable SPI in the master mode and reset FIFO */
+ setbits_le32(SUN4I_SPI0_CTL, SUN4I_CTL_MASTER |
+ SUN4I_CTL_ENABLE |
+ SUN4I_CTL_TF_RST |
+ SUN4I_CTL_RF_RST);
+ }
+}
+
+static void spi0_disable_clock(void)
+{
+ /* Disable the SPI0 controller */
+ if (IS_ENABLED(CONFIG_SUNXI_GEN_SUN6I))
+ clrbits_le32(SUN6I_SPI0_GCR, SUN6I_CTL_MASTER |
+ SUN6I_CTL_ENABLE);
+ else
+ clrbits_le32(SUN4I_SPI0_CTL, SUN4I_CTL_MASTER |
+ SUN4I_CTL_ENABLE);
+
+ /* Disable the SPI0 clock */
+ writel(0, CCM_SPI0_CLK);
+
+ /* Close the SPI0 gate */
+ clrbits_le32(CCM_AHB_GATING0, (1 << AHB_GATE_OFFSET_SPI0));
+
+ /* Assert SPI0 reset on SUN6I */
+ if (IS_ENABLED(CONFIG_SUNXI_GEN_SUN6I))
+ clrbits_le32(SUN6I_BUS_SOFT_RST_REG0,
+ (1 << AHB_RESET_SPI0_SHIFT));
+}
+
+static int spi0_init(void)
+{
+ unsigned int pin_function = SUNXI_GPC_SPI0;
+ if (IS_ENABLED(CONFIG_MACH_SUN50I))
+ pin_function = SUN50I_GPC_SPI0;
+
+ spi0_pinmux_setup(pin_function);
+ spi0_enable_clock();
+}
+
+static void spi0_deinit(void)
+{
+ /* New SoCs can disable pins, older could only set them as input */
+ unsigned int pin_function = SUNXI_GPIO_INPUT;
+ if (IS_ENABLED(CONFIG_SUNXI_GEN_SUN6I))
+ pin_function = SUNXI_GPIO_DISABLE;
+
+ spi0_disable_clock();
+ spi0_pinmux_setup(pin_function);
+}
+
+/*****************************************************************************/
+
+#define SPI_READ_MAX_SIZE 60 /* FIFO size, minus 4 bytes of the header */
+
+static void sunxi_spi0_read_data(u8 *buf, u32 addr, u32 bufsize,
+ u32 spi_ctl_reg,
+ u32 spi_ctl_xch_bitmask,
+ u32 spi_fifo_reg,
+ u32 spi_tx_reg,
+ u32 spi_rx_reg,
+ u32 spi_bc_reg,
+ u32 spi_tc_reg,
+ u32 spi_bcc_reg)
+{
+ writel(4 + bufsize, spi_bc_reg); /* Burst counter (total bytes) */
+ writel(4, spi_tc_reg); /* Transfer counter (bytes to send) */
+ if (spi_bcc_reg)
+ writel(4, spi_bcc_reg); /* SUN6I also needs this */
+
+ /* Send the Read Data Bytes (03h) command header */
+ writeb(0x03, spi_tx_reg);
+ writeb((u8)(addr >> 16), spi_tx_reg);
+ writeb((u8)(addr >> 8), spi_tx_reg);
+ writeb((u8)(addr), spi_tx_reg);
+
+ /* Start the data transfer */
+ setbits_le32(spi_ctl_reg, spi_ctl_xch_bitmask);
+
+ /* Wait until everything is received in the RX FIFO */
+ while ((readl(spi_fifo_reg) & 0x7F) < 4 + bufsize)
+ ;
+
+ /* Skip 4 bytes */
+ readl(spi_rx_reg);
+
+ /* Read the data */
+ while (bufsize-- > 0)
+ *buf++ = readb(spi_rx_reg);
+
+ /* tSHSL time is up to 100 ns in various SPI flash datasheets */
+ udelay(1);
+}
+
+static void spi0_read_data(void *buf, u32 addr, u32 len)
+{
+ u8 *buf8 = buf;
+ u32 chunk_len;
+
+ while (len > 0) {
+ chunk_len = len;
+ if (chunk_len > SPI_READ_MAX_SIZE)
+ chunk_len = SPI_READ_MAX_SIZE;
+
+ if (IS_ENABLED(CONFIG_SUNXI_GEN_SUN6I)) {
+ sunxi_spi0_read_data(buf8, addr, chunk_len,
+ SUN6I_SPI0_TCR,
+ SUN6I_TCR_XCH,
+ SUN6I_SPI0_FIFO_STA,
+ SUN6I_SPI0_TXD,
+ SUN6I_SPI0_RXD,
+ SUN6I_SPI0_MBC,
+ SUN6I_SPI0_MTC,
+ SUN6I_SPI0_BCC);
+ } else {
+ sunxi_spi0_read_data(buf8, addr, chunk_len,
+ SUN4I_SPI0_CTL,
+ SUN4I_CTL_XCH,
+ SUN4I_SPI0_FIFO_STA,
+ SUN4I_SPI0_TX,
+ SUN4I_SPI0_RX,
+ SUN4I_SPI0_BC,
+ SUN4I_SPI0_TC,
+ 0);
+ }
+
+ len -= chunk_len;
+ buf8 += chunk_len;
+ addr += chunk_len;
+ }
+}
+
+/*****************************************************************************/
+
+int spl_spi_load_image(void)
+{
+ int err;
+ struct image_header *header;
+ header = (struct image_header *)(CONFIG_SYS_TEXT_BASE);
+
+ spi0_init();
+
+ spi0_read_data((void *)header, CONFIG_SYS_SPI_U_BOOT_OFFS, 0x40);
+ err = spl_parse_image_header(header);
+ if (err)
+ return err;
+
+ spi0_read_data((void *)spl_image.load_addr, CONFIG_SYS_SPI_U_BOOT_OFFS,
+ spl_image.size);
+
+ spi0_deinit();
+ return 0;
+}
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index c1cb689..88d8e83 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -152,6 +152,15 @@ config RTL8169
This driver supports Realtek 8169 series gigabit ethernet family of
PCI/PCIe chipsets/adapters.
+config SUN8I_EMAC
+ bool "Allwinner Sun8i Ethernet MAC support"
+ depends on DM_ETH
+ select PHYLIB
+ help
+ This driver supports the Allwinner based SUN8I/SUN50I Ethernet MAC.
+ It can be found in H3/A64/A83T based SoCs and compatible with both
+ External and Internal PHY's.
+
config XILINX_AXIEMAC
depends on DM_ETH && (MICROBLAZE || ARCH_ZYNQ || ARCH_ZYNQMP)
select PHYLIB
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 5702592..a448526 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -24,6 +24,7 @@ obj-$(CONFIG_E1000) += e1000.o
obj-$(CONFIG_E1000_SPI) += e1000_spi.o
obj-$(CONFIG_EEPRO100) += eepro100.o
obj-$(CONFIG_SUNXI_EMAC) += sunxi_emac.o
+obj-$(CONFIG_SUN8I_EMAC) += sun8i_emac.o
obj-$(CONFIG_ENC28J60) += enc28j60.o
obj-$(CONFIG_EP93XX) += ep93xx_eth.o
obj-$(CONFIG_ETHOC) += ethoc.o
diff --git a/drivers/net/sun8i_emac.c b/drivers/net/sun8i_emac.c
new file mode 100644
index 0000000..4bed50d
--- /dev/null
+++ b/drivers/net/sun8i_emac.c
@@ -0,0 +1,789 @@
+/*
+ * (C) Copyright 2016
+ * Author: Amit Singh Tomar, amittomer25@gmail.com
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ *
+ * Ethernet driver for H3/A64/A83T based SoC's
+ *
+ * It is derived from the work done by
+ * LABBE Corentin & Chen-Yu Tsai for Linux, THANKS!
+ *
+*/
+
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/gpio.h>
+#include <common.h>
+#include <dm.h>
+#include <fdt_support.h>
+#include <linux/err.h>
+#include <malloc.h>
+#include <miiphy.h>
+#include <net.h>
+
+#define SCTL_EMAC_TX_CLK_SRC_MII BIT(0)
+#define SCTL_EMAC_EPIT_MII BIT(2)
+#define SCTL_EMAC_CLK_SEL BIT(18) /* 25 Mhz */
+
+#define MDIO_CMD_MII_BUSY BIT(0)
+#define MDIO_CMD_MII_WRITE BIT(1)
+
+#define MDIO_CMD_MII_PHY_REG_ADDR_MASK 0x000001f0
+#define MDIO_CMD_MII_PHY_REG_ADDR_SHIFT 4
+#define MDIO_CMD_MII_PHY_ADDR_MASK 0x0001f000
+#define MDIO_CMD_MII_PHY_ADDR_SHIFT 12
+
+#define CONFIG_TX_DESCR_NUM 32
+#define CONFIG_RX_DESCR_NUM 32
+#define CONFIG_ETH_BUFSIZE 2024
+
+#define TX_TOTAL_BUFSIZE (CONFIG_ETH_BUFSIZE * CONFIG_TX_DESCR_NUM)
+#define RX_TOTAL_BUFSIZE (CONFIG_ETH_BUFSIZE * CONFIG_RX_DESCR_NUM)
+
+#define H3_EPHY_DEFAULT_VALUE 0x58000
+#define H3_EPHY_DEFAULT_MASK GENMASK(31, 15)
+#define H3_EPHY_ADDR_SHIFT 20
+#define REG_PHY_ADDR_MASK GENMASK(4, 0)
+#define H3_EPHY_LED_POL BIT(17) /* 1: active low, 0: active high */
+#define H3_EPHY_SHUTDOWN BIT(16) /* 1: shutdown, 0: power up */
+#define H3_EPHY_SELECT BIT(15) /* 1: internal PHY, 0: external PHY */
+
+#define SC_RMII_EN BIT(13)
+#define SC_EPIT BIT(2) /* 1: RGMII, 0: MII */
+#define SC_ETCS_MASK GENMASK(1, 0)
+#define SC_ETCS_EXT_GMII 0x1
+#define SC_ETCS_INT_GMII 0x2
+
+#define CONFIG_MDIO_TIMEOUT (3 * CONFIG_SYS_HZ)
+
+#define AHB_GATE_OFFSET_EPHY 0
+
+#if defined(CONFIG_MACH_SUN8I_H3)
+#define SUN8I_GPD8_GMAC 2
+#else
+#define SUN8I_GPD8_GMAC 4
+#endif
+
+/* H3/A64 EMAC Register's offset */
+#define EMAC_CTL0 0x00
+#define EMAC_CTL1 0x04
+#define EMAC_INT_STA 0x08
+#define EMAC_INT_EN 0x0c
+#define EMAC_TX_CTL0 0x10
+#define EMAC_TX_CTL1 0x14
+#define EMAC_TX_FLOW_CTL 0x1c
+#define EMAC_TX_DMA_DESC 0x20
+#define EMAC_RX_CTL0 0x24
+#define EMAC_RX_CTL1 0x28
+#define EMAC_RX_DMA_DESC 0x34
+#define EMAC_MII_CMD 0x48
+#define EMAC_MII_DATA 0x4c
+#define EMAC_ADDR0_HIGH 0x50
+#define EMAC_ADDR0_LOW 0x54
+#define EMAC_TX_DMA_STA 0xb0
+#define EMAC_TX_CUR_DESC 0xb4
+#define EMAC_TX_CUR_BUF 0xb8
+#define EMAC_RX_DMA_STA 0xc0
+#define EMAC_RX_CUR_DESC 0xc4
+
+DECLARE_GLOBAL_DATA_PTR;
+
+enum emac_variant {
+ A83T_EMAC = 1,
+ H3_EMAC,
+ A64_EMAC,
+};
+
+struct emac_dma_desc {
+ u32 status;
+ u32 st;
+ u32 buf_addr;
+ u32 next;
+} __aligned(ARCH_DMA_MINALIGN);
+
+struct emac_eth_dev {
+ struct emac_dma_desc rx_chain[CONFIG_TX_DESCR_NUM];
+ struct emac_dma_desc tx_chain[CONFIG_RX_DESCR_NUM];
+ char rxbuffer[RX_TOTAL_BUFSIZE] __aligned(ARCH_DMA_MINALIGN);
+ char txbuffer[TX_TOTAL_BUFSIZE] __aligned(ARCH_DMA_MINALIGN);
+
+ u32 interface;
+ u32 phyaddr;
+ u32 link;
+ u32 speed;
+ u32 duplex;
+ u32 phy_configured;
+ u32 tx_currdescnum;
+ u32 rx_currdescnum;
+ u32 addr;
+ u32 tx_slot;
+ bool use_internal_phy;
+
+ enum emac_variant variant;
+ void *mac_reg;
+ phys_addr_t sysctl_reg;
+ struct phy_device *phydev;
+ struct mii_dev *bus;
+};
+
+static int sun8i_mdio_read(struct mii_dev *bus, int addr, int devad, int reg)
+{
+ struct emac_eth_dev *priv = bus->priv;
+ ulong start;
+ u32 miiaddr = 0;
+ int timeout = CONFIG_MDIO_TIMEOUT;
+
+ miiaddr &= ~MDIO_CMD_MII_WRITE;
+ miiaddr &= ~MDIO_CMD_MII_PHY_REG_ADDR_MASK;
+ miiaddr |= (reg << MDIO_CMD_MII_PHY_REG_ADDR_SHIFT) &
+ MDIO_CMD_MII_PHY_REG_ADDR_MASK;
+
+ miiaddr &= ~MDIO_CMD_MII_PHY_ADDR_MASK;
+
+ miiaddr |= (addr << MDIO_CMD_MII_PHY_ADDR_SHIFT) &
+ MDIO_CMD_MII_PHY_ADDR_MASK;
+
+ miiaddr |= MDIO_CMD_MII_BUSY;
+
+ writel(miiaddr, priv->mac_reg + EMAC_MII_CMD);
+
+ start = get_timer(0);
+ while (get_timer(start) < timeout) {
+ if (!(readl(priv->mac_reg + EMAC_MII_CMD) & MDIO_CMD_MII_BUSY))
+ return readl(priv->mac_reg + EMAC_MII_DATA);
+ udelay(10);
+ };
+
+ return -1;
+}
+
+static int sun8i_mdio_write(struct mii_dev *bus, int addr, int devad, int reg,
+ u16 val)
+{
+ struct emac_eth_dev *priv = bus->priv;
+ ulong start;
+ u32 miiaddr = 0;
+ int ret = -1, timeout = CONFIG_MDIO_TIMEOUT;
+
+ miiaddr &= ~MDIO_CMD_MII_PHY_REG_ADDR_MASK;
+ miiaddr |= (reg << MDIO_CMD_MII_PHY_REG_ADDR_SHIFT) &
+ MDIO_CMD_MII_PHY_REG_ADDR_MASK;
+
+ miiaddr &= ~MDIO_CMD_MII_PHY_ADDR_MASK;
+ miiaddr |= (addr << MDIO_CMD_MII_PHY_ADDR_SHIFT) &
+ MDIO_CMD_MII_PHY_ADDR_MASK;
+
+ miiaddr |= MDIO_CMD_MII_WRITE;
+ miiaddr |= MDIO_CMD_MII_BUSY;
+
+ writel(miiaddr, priv->mac_reg + EMAC_MII_CMD);
+ writel(val, priv->mac_reg + EMAC_MII_DATA);
+
+ start = get_timer(0);
+ while (get_timer(start) < timeout) {
+ if (!(readl(priv->mac_reg + EMAC_MII_CMD) &
+ MDIO_CMD_MII_BUSY)) {
+ ret = 0;
+ break;
+ }
+ udelay(10);
+ };
+
+ return ret;
+}
+
+static int _sun8i_write_hwaddr(struct emac_eth_dev *priv, u8 *mac_id)
+{
+ u32 macid_lo, macid_hi;
+
+ macid_lo = mac_id[0] + (mac_id[1] << 8) + (mac_id[2] << 16) +
+ (mac_id[3] << 24);
+ macid_hi = mac_id[4] + (mac_id[5] << 8);
+
+ writel(macid_hi, priv->mac_reg + EMAC_ADDR0_HIGH);
+ writel(macid_lo, priv->mac_reg + EMAC_ADDR0_LOW);
+
+ return 0;
+}
+
+static void sun8i_adjust_link(struct emac_eth_dev *priv,
+ struct phy_device *phydev)
+{
+ u32 v;
+
+ v = readl(priv->mac_reg + EMAC_CTL0);
+
+ if (phydev->duplex)
+ v |= BIT(0);
+ else
+ v &= ~BIT(0);
+
+ v &= ~0x0C;
+
+ switch (phydev->speed) {
+ case 1000:
+ break;
+ case 100:
+ v |= BIT(2);
+ v |= BIT(3);
+ break;
+ case 10:
+ v |= BIT(3);
+ break;
+ }
+ writel(v, priv->mac_reg + EMAC_CTL0);
+}
+
+static int sun8i_emac_set_syscon_ephy(struct emac_eth_dev *priv, u32 *reg)
+{
+ if (priv->use_internal_phy) {
+ /* H3 based SoC's that has an Internal 100MBit PHY
+ * needs to be configured and powered up before use
+ */
+ *reg &= ~H3_EPHY_DEFAULT_MASK;
+ *reg |= H3_EPHY_DEFAULT_VALUE;
+ *reg |= priv->phyaddr << H3_EPHY_ADDR_SHIFT;
+ *reg &= ~H3_EPHY_SHUTDOWN;
+ *reg |= H3_EPHY_SELECT;
+ } else
+ /* This is to select External Gigabit PHY on
+ * the boards with H3 SoC.
+ */
+ *reg &= ~H3_EPHY_SELECT;
+
+ return 0;
+}
+
+static int sun8i_emac_set_syscon(struct emac_eth_dev *priv)
+{
+ int ret;
+ u32 reg;
+
+ reg = readl(priv->sysctl_reg);
+
+ if (priv->variant == H3_EMAC) {
+ ret = sun8i_emac_set_syscon_ephy(priv, &reg);
+ if (ret)
+ return ret;
+ }
+
+ reg &= ~(SC_ETCS_MASK | SC_EPIT);
+ if (priv->variant == H3_EMAC || priv->variant == A64_EMAC)
+ reg &= ~SC_RMII_EN;
+
+ switch (priv->interface) {
+ case PHY_INTERFACE_MODE_MII:
+ /* default */
+ break;
+ case PHY_INTERFACE_MODE_RGMII:
+ reg |= SC_EPIT | SC_ETCS_INT_GMII;
+ break;
+ case PHY_INTERFACE_MODE_RMII:
+ if (priv->variant == H3_EMAC ||
+ priv->variant == A64_EMAC) {
+ reg |= SC_RMII_EN | SC_ETCS_EXT_GMII;
+ break;
+ }
+ /* RMII not supported on A83T */
+ default:
+ debug("%s: Invalid PHY interface\n", __func__);
+ return -EINVAL;
+ }
+
+ writel(reg, priv->sysctl_reg);
+
+ return 0;
+}
+
+static int sun8i_phy_init(struct emac_eth_dev *priv, void *dev)
+{
+ struct phy_device *phydev;
+
+ phydev = phy_connect(priv->bus, priv->phyaddr, dev, priv->interface);
+ if (!phydev)
+ return -ENODEV;
+
+ phy_connect_dev(phydev, dev);
+
+ priv->phydev = phydev;
+ phy_config(priv->phydev);
+
+ return 0;
+}
+
+static void rx_descs_init(struct emac_eth_dev *priv)
+{
+ struct emac_dma_desc *desc_table_p = &priv->rx_chain[0];
+ char *rxbuffs = &priv->rxbuffer[0];
+ struct emac_dma_desc *desc_p;
+ u32 idx;
+
+ /* flush Rx buffers */
+ flush_dcache_range((uintptr_t)rxbuffs, (ulong)rxbuffs +
+ RX_TOTAL_BUFSIZE);
+
+ for (idx = 0; idx < CONFIG_RX_DESCR_NUM; idx++) {
+ desc_p = &desc_table_p[idx];
+ desc_p->buf_addr = (uintptr_t)&rxbuffs[idx * CONFIG_ETH_BUFSIZE]
+ ;
+ desc_p->next = (uintptr_t)&desc_table_p[idx + 1];
+ desc_p->st |= CONFIG_ETH_BUFSIZE;
+ desc_p->status = BIT(31);
+ }
+
+ /* Correcting the last pointer of the chain */
+ desc_p->next = (uintptr_t)&desc_table_p[0];
+
+ flush_dcache_range((uintptr_t)priv->rx_chain,
+ (uintptr_t)priv->rx_chain +
+ sizeof(priv->rx_chain));
+
+ writel((uintptr_t)&desc_table_p[0], (priv->mac_reg + EMAC_RX_DMA_DESC));
+ priv->rx_currdescnum = 0;
+}
+
+static void tx_descs_init(struct emac_eth_dev *priv)
+{
+ struct emac_dma_desc *desc_table_p = &priv->tx_chain[0];
+ char *txbuffs = &priv->txbuffer[0];
+ struct emac_dma_desc *desc_p;
+ u32 idx;
+
+ for (idx = 0; idx < CONFIG_TX_DESCR_NUM; idx++) {
+ desc_p = &desc_table_p[idx];
+ desc_p->buf_addr = (uintptr_t)&txbuffs[idx * CONFIG_ETH_BUFSIZE]
+ ;
+ desc_p->next = (uintptr_t)&desc_table_p[idx + 1];
+ desc_p->status = (1 << 31);
+ desc_p->st = 0;
+ }
+
+ /* Correcting the last pointer of the chain */
+ desc_p->next = (uintptr_t)&desc_table_p[0];
+
+ /* Flush all Tx buffer descriptors */
+ flush_dcache_range((uintptr_t)priv->tx_chain,
+ (uintptr_t)priv->tx_chain +
+ sizeof(priv->tx_chain));
+
+ writel((uintptr_t)&desc_table_p[0], priv->mac_reg + EMAC_TX_DMA_DESC);
+ priv->tx_currdescnum = 0;
+}
+
+static int _sun8i_emac_eth_init(struct emac_eth_dev *priv, u8 *enetaddr)
+{
+ u32 reg, v;
+ int timeout = 100;
+
+ reg = readl((priv->mac_reg + EMAC_CTL1));
+
+ if (!(reg & 0x1)) {
+ /* Soft reset MAC */
+ setbits_le32((priv->mac_reg + EMAC_CTL1), 0x1);
+ do {
+ reg = readl(priv->mac_reg + EMAC_CTL1);
+ } while ((reg & 0x01) != 0 && (--timeout));
+ if (!timeout) {
+ printf("%s: Timeout\n", __func__);
+ return -1;
+ }
+ }
+
+ /* Rewrite mac address after reset */
+ _sun8i_write_hwaddr(priv, enetaddr);
+
+ v = readl(priv->mac_reg + EMAC_TX_CTL1);
+ /* TX_MD Transmission starts after a full frame located in TX DMA FIFO*/
+ v |= BIT(1);
+ writel(v, priv->mac_reg + EMAC_TX_CTL1);
+
+ v = readl(priv->mac_reg + EMAC_RX_CTL1);
+ /* RX_MD RX DMA reads data from RX DMA FIFO to host memory after a
+ * complete frame has been written to RX DMA FIFO
+ */
+ v |= BIT(1);
+ writel(v, priv->mac_reg + EMAC_RX_CTL1);
+
+ /* DMA */
+ writel(8 << 24, priv->mac_reg + EMAC_CTL1);
+
+ /* Initialize rx/tx descriptors */
+ rx_descs_init(priv);
+ tx_descs_init(priv);
+
+ /* PHY Start Up */
+ genphy_parse_link(priv->phydev);
+
+ sun8i_adjust_link(priv, priv->phydev);
+
+ /* Start RX DMA */
+ v = readl(priv->mac_reg + EMAC_RX_CTL1);
+ v |= BIT(30);
+ writel(v, priv->mac_reg + EMAC_RX_CTL1);
+ /* Start TX DMA */
+ v = readl(priv->mac_reg + EMAC_TX_CTL1);
+ v |= BIT(30);
+ writel(v, priv->mac_reg + EMAC_TX_CTL1);
+
+ /* Enable RX/TX */
+ setbits_le32(priv->mac_reg + EMAC_RX_CTL0, BIT(31));
+ setbits_le32(priv->mac_reg + EMAC_TX_CTL0, BIT(31));
+
+ return 0;
+}
+
+static int parse_phy_pins(struct udevice *dev)
+{
+ int offset;
+ const char *pin_name;
+ int drive, pull, i;
+
+ offset = fdtdec_lookup_phandle(gd->fdt_blob, dev->of_offset,
+ "pinctrl-0");
+ if (offset < 0) {
+ printf("WARNING: emac: cannot find pinctrl-0 node\n");
+ return offset;
+ }
+
+ drive = fdt_getprop_u32_default_node(gd->fdt_blob, offset, 0,
+ "allwinner,drive", 4);
+ pull = fdt_getprop_u32_default_node(gd->fdt_blob, offset, 0,
+ "allwinner,pull", 0);
+ for (i = 0; ; i++) {
+ int pin;
+
+ if (fdt_get_string_index(gd->fdt_blob, offset,
+ "allwinner,pins", i, &pin_name))
+ break;
+ if (pin_name[0] != 'P')
+ continue;
+ pin = (pin_name[1] - 'A') << 5;
+ if (pin >= 26 << 5)
+ continue;
+ pin += simple_strtol(&pin_name[2], NULL, 10);
+
+ sunxi_gpio_set_cfgpin(pin, SUN8I_GPD8_GMAC);
+ sunxi_gpio_set_drv(pin, drive);
+ sunxi_gpio_set_pull(pin, pull);
+ }
+
+ if (!i) {
+ printf("WARNING: emac: cannot find allwinner,pins property\n");
+ return -2;
+ }
+
+ return 0;
+}
+
+static int _sun8i_eth_recv(struct emac_eth_dev *priv, uchar **packetp)
+{
+ u32 status, desc_num = priv->rx_currdescnum;
+ struct emac_dma_desc *desc_p = &priv->rx_chain[desc_num];
+ int length = -EAGAIN;
+ int good_packet = 1;
+ uintptr_t desc_start = (uintptr_t)desc_p;
+ uintptr_t desc_end = desc_start +
+ roundup(sizeof(*desc_p), ARCH_DMA_MINALIGN);
+
+ ulong data_start = (uintptr_t)desc_p->buf_addr;
+ ulong data_end;
+
+ /* Invalidate entire buffer descriptor */
+ invalidate_dcache_range(desc_start, desc_end);
+
+ status = desc_p->status;
+
+ /* Check for DMA own bit */
+ if (!(status & BIT(31))) {
+ length = (desc_p->status >> 16) & 0x3FFF;
+
+ if (length < 0x40) {
+ good_packet = 0;
+ debug("RX: Bad Packet (runt)\n");
+ }
+
+ data_end = data_start + length;
+ /* Invalidate received data */
+ invalidate_dcache_range(rounddown(data_start,
+ ARCH_DMA_MINALIGN),
+ roundup(data_end,
+ ARCH_DMA_MINALIGN));
+ if (good_packet) {
+ if (length > CONFIG_ETH_BUFSIZE) {
+ printf("Received packet is too big (len=%d)\n",
+ length);
+ return -EMSGSIZE;
+ }
+ *packetp = (uchar *)(ulong)desc_p->buf_addr;
+ return length;
+ }
+ }
+
+ return length;
+}
+
+static int _sun8i_emac_eth_send(struct emac_eth_dev *priv, void *packet,
+ int len)
+{
+ u32 v, desc_num = priv->tx_currdescnum;
+ struct emac_dma_desc *desc_p = &priv->tx_chain[desc_num];
+ uintptr_t desc_start = (uintptr_t)desc_p;
+ uintptr_t desc_end = desc_start +
+ roundup(sizeof(*desc_p), ARCH_DMA_MINALIGN);
+
+ uintptr_t data_start = (uintptr_t)desc_p->buf_addr;
+ uintptr_t data_end = data_start +
+ roundup(len, ARCH_DMA_MINALIGN);
+
+ /* Invalidate entire buffer descriptor */
+ invalidate_dcache_range(desc_start, desc_end);
+
+ desc_p->st = len;
+ /* Mandatory undocumented bit */
+ desc_p->st |= BIT(24);
+
+ memcpy((void *)data_start, packet, len);
+
+ /* Flush data to be sent */
+ flush_dcache_range(data_start, data_end);
+
+ /* frame end */
+ desc_p->st |= BIT(30);
+ desc_p->st |= BIT(31);
+
+ /*frame begin */
+ desc_p->st |= BIT(29);
+ desc_p->status = BIT(31);
+
+ /*Descriptors st and status field has changed, so FLUSH it */
+ flush_dcache_range(desc_start, desc_end);
+
+ /* Move to next Descriptor and wrap around */
+ if (++desc_num >= CONFIG_TX_DESCR_NUM)
+ desc_num = 0;
+ priv->tx_currdescnum = desc_num;
+
+ /* Start the DMA */
+ v = readl(priv->mac_reg + EMAC_TX_CTL1);
+ v |= BIT(31);/* mandatory */
+ v |= BIT(30);/* mandatory */
+ writel(v, priv->mac_reg + EMAC_TX_CTL1);
+
+ return 0;
+}
+
+static int sun8i_eth_write_hwaddr(struct udevice *dev)
+{
+ struct eth_pdata *pdata = dev_get_platdata(dev);
+ struct emac_eth_dev *priv = dev_get_priv(dev);
+
+ return _sun8i_write_hwaddr(priv, pdata->enetaddr);
+}
+
+static void sun8i_emac_board_setup(struct emac_eth_dev *priv)
+{
+ struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
+
+ if (priv->use_internal_phy) {
+ /* Set clock gating for ephy */
+ setbits_le32(&ccm->bus_gate4, BIT(AHB_GATE_OFFSET_EPHY));
+
+ /* Set Tx clock source as MII with rate 25 MZ */
+ setbits_le32(priv->sysctl_reg, SCTL_EMAC_TX_CLK_SRC_MII |
+ SCTL_EMAC_EPIT_MII | SCTL_EMAC_CLK_SEL);
+ /* Deassert EPHY */
+ setbits_le32(&ccm->ahb_reset2_cfg, BIT(AHB_RESET_OFFSET_EPHY));
+ }
+
+ /* Set clock gating for emac */
+ setbits_le32(&ccm->ahb_gate0, BIT(AHB_GATE_OFFSET_GMAC));
+
+ /* Set EMAC clock */
+ setbits_le32(&ccm->axi_gate, (BIT(1) | BIT(0)));
+
+ /* De-assert EMAC */
+ setbits_le32(&ccm->ahb_reset0_cfg, BIT(AHB_RESET_OFFSET_GMAC));
+}
+
+static int sun8i_mdio_init(const char *name, struct emac_eth_dev *priv)
+{
+ struct mii_dev *bus = mdio_alloc();
+
+ if (!bus) {
+ debug("Failed to allocate MDIO bus\n");
+ return -ENOMEM;
+ }
+
+ bus->read = sun8i_mdio_read;
+ bus->write = sun8i_mdio_write;
+ snprintf(bus->name, sizeof(bus->name), name);
+ bus->priv = (void *)priv;
+
+ return mdio_register(bus);
+}
+
+static int sun8i_emac_eth_start(struct udevice *dev)
+{
+ struct eth_pdata *pdata = dev_get_platdata(dev);
+
+ return _sun8i_emac_eth_init(dev->priv, pdata->enetaddr);
+}
+
+static int sun8i_emac_eth_send(struct udevice *dev, void *packet, int length)
+{
+ struct emac_eth_dev *priv = dev_get_priv(dev);
+
+ return _sun8i_emac_eth_send(priv, packet, length);
+}
+
+static int sun8i_emac_eth_recv(struct udevice *dev, int flags, uchar **packetp)
+{
+ struct emac_eth_dev *priv = dev_get_priv(dev);
+
+ return _sun8i_eth_recv(priv, packetp);
+}
+
+static int _sun8i_free_pkt(struct emac_eth_dev *priv)
+{
+ u32 desc_num = priv->rx_currdescnum;
+ struct emac_dma_desc *desc_p = &priv->rx_chain[desc_num];
+ uintptr_t desc_start = (uintptr_t)desc_p;
+ uintptr_t desc_end = desc_start +
+ roundup(sizeof(u32), ARCH_DMA_MINALIGN);
+
+ /* Make the current descriptor valid again */
+ desc_p->status |= BIT(31);
+
+ /* Flush Status field of descriptor */
+ flush_dcache_range(desc_start, desc_end);
+
+ /* Move to next desc and wrap-around condition. */
+ if (++desc_num >= CONFIG_RX_DESCR_NUM)
+ desc_num = 0;
+ priv->rx_currdescnum = desc_num;
+
+ return 0;
+}
+
+static int sun8i_eth_free_pkt(struct udevice *dev, uchar *packet,
+ int length)
+{
+ struct emac_eth_dev *priv = dev_get_priv(dev);
+
+ return _sun8i_free_pkt(priv);
+}
+
+static void sun8i_emac_eth_stop(struct udevice *dev)
+{
+ struct emac_eth_dev *priv = dev_get_priv(dev);
+
+ /* Stop Rx/Tx transmitter */
+ clrbits_le32(priv->mac_reg + EMAC_RX_CTL0, BIT(31));
+ clrbits_le32(priv->mac_reg + EMAC_TX_CTL0, BIT(31));
+
+ /* Stop TX DMA */
+ clrbits_le32(priv->mac_reg + EMAC_TX_CTL1, BIT(30));
+
+ phy_shutdown(priv->phydev);
+}
+
+static int sun8i_emac_eth_probe(struct udevice *dev)
+{
+ struct eth_pdata *pdata = dev_get_platdata(dev);
+ struct emac_eth_dev *priv = dev_get_priv(dev);
+
+ priv->mac_reg = (void *)pdata->iobase;
+
+ sun8i_emac_board_setup(priv);
+
+ sun8i_mdio_init(dev->name, priv);
+ priv->bus = miiphy_get_dev_by_name(dev->name);
+
+ sun8i_emac_set_syscon(priv);
+
+ return sun8i_phy_init(priv, dev);
+}
+
+static const struct eth_ops sun8i_emac_eth_ops = {
+ .start = sun8i_emac_eth_start,
+ .write_hwaddr = sun8i_eth_write_hwaddr,
+ .send = sun8i_emac_eth_send,
+ .recv = sun8i_emac_eth_recv,
+ .free_pkt = sun8i_eth_free_pkt,
+ .stop = sun8i_emac_eth_stop,
+};
+
+static int sun8i_emac_eth_ofdata_to_platdata(struct udevice *dev)
+{
+ struct eth_pdata *pdata = dev_get_platdata(dev);
+ struct emac_eth_dev *priv = dev_get_priv(dev);
+ const char *phy_mode;
+ int offset = 0;
+
+ pdata->iobase = dev_get_addr_name(dev, "emac");
+ priv->sysctl_reg = dev_get_addr_name(dev, "syscon");
+
+ pdata->phy_interface = -1;
+ priv->phyaddr = -1;
+ priv->use_internal_phy = false;
+
+ offset = fdtdec_lookup_phandle(gd->fdt_blob, dev->of_offset,
+ "phy");
+ if (offset > 0)
+ priv->phyaddr = fdtdec_get_int(gd->fdt_blob, offset, "reg",
+ -1);
+
+ phy_mode = fdt_getprop(gd->fdt_blob, dev->of_offset, "phy-mode", NULL);
+
+ if (phy_mode)
+ pdata->phy_interface = phy_get_interface_by_name(phy_mode);
+ printf("phy interface%d\n", pdata->phy_interface);
+
+ if (pdata->phy_interface == -1) {
+ debug("%s: Invalid PHY interface '%s'\n", __func__, phy_mode);
+ return -EINVAL;
+ }
+
+ priv->variant = dev_get_driver_data(dev);
+
+ if (!priv->variant) {
+ printf("%s: Missing variant '%s'\n", __func__,
+ (char *)priv->variant);
+ return -EINVAL;
+ }
+
+ if (priv->variant == H3_EMAC) {
+ if (fdt_getprop(gd->fdt_blob, dev->of_offset,
+ "allwinner,use-internal-phy", NULL))
+ priv->use_internal_phy = true;
+ }
+
+ priv->interface = pdata->phy_interface;
+
+ if (!priv->use_internal_phy)
+ parse_phy_pins(dev);
+
+ return 0;
+}
+
+static const struct udevice_id sun8i_emac_eth_ids[] = {
+ {.compatible = "allwinner,sun8i-h3-emac", .data = (uintptr_t)H3_EMAC },
+ {.compatible = "allwinner,sun50i-a64-emac",
+ .data = (uintptr_t)A64_EMAC },
+ {.compatible = "allwinner,sun8i-a83t-emac",
+ .data = (uintptr_t)A83T_EMAC },
+ { }
+};
+
+U_BOOT_DRIVER(eth_sun8i_emac) = {
+ .name = "eth_sun8i_emac",
+ .id = UCLASS_ETH,
+ .of_match = sun8i_emac_eth_ids,
+ .ofdata_to_platdata = sun8i_emac_eth_ofdata_to_platdata,
+ .probe = sun8i_emac_eth_probe,
+ .ops = &sun8i_emac_eth_ops,
+ .priv_auto_alloc_size = sizeof(struct emac_eth_dev),
+ .platdata_auto_alloc_size = sizeof(struct eth_pdata),
+ .flags = DM_FLAG_ALLOC_PRIV_DMA,
+};
diff --git a/drivers/pci/pci_rom.c b/drivers/pci/pci_rom.c
index 9eb605b..399055b 100644
--- a/drivers/pci/pci_rom.c
+++ b/drivers/pci/pci_rom.c
@@ -39,14 +39,9 @@ __weak bool board_should_run_oprom(struct udevice *dev)
return true;
}
-static bool should_load_oprom(struct udevice *dev)
+__weak bool board_should_load_oprom(struct udevice *dev)
{
- if (IS_ENABLED(CONFIG_ALWAYS_LOAD_OPROM))
- return 1;
- if (board_should_run_oprom(dev))
- return 1;
-
- return 0;
+ return true;
}
__weak uint32_t board_map_oprom_vendev(uint32_t vendev)
@@ -278,7 +273,7 @@ int dm_pci_run_vga_bios(struct udevice *dev, int (*int15_handler)(void),
return -ENODEV;
}
- if (!should_load_oprom(dev))
+ if (!board_should_load_oprom(dev))
return -ENXIO;
ret = pci_rom_probe(dev, &rom);
diff --git a/drivers/pinctrl/rockchip/pinctrl_rk3288.c b/drivers/pinctrl/rockchip/pinctrl_rk3288.c
index 1fa1daa..8cb3b82 100644
--- a/drivers/pinctrl/rockchip/pinctrl_rk3288.c
+++ b/drivers/pinctrl/rockchip/pinctrl_rk3288.c
@@ -476,6 +476,7 @@ static int rk3288_pinctrl_request(struct udevice *dev, int func, int flags)
static int rk3288_pinctrl_get_periph_id(struct udevice *dev,
struct udevice *periph)
{
+#if !CONFIG_IS_ENABLED(OF_PLATDATA)
u32 cell[3];
int ret;
@@ -506,6 +507,7 @@ static int rk3288_pinctrl_get_periph_id(struct udevice *dev,
case 103:
return PERIPH_ID_HDMI;
}
+#endif
return -ENOENT;
}
@@ -664,8 +666,12 @@ static struct pinctrl_ops rk3288_pinctrl_ops = {
static int rk3288_pinctrl_bind(struct udevice *dev)
{
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+ return 0;
+#else
/* scan child GPIO banks */
return dm_scan_fdt_node(dev, gd->fdt_blob, dev->of_offset, false);
+#endif
}
#ifndef CONFIG_SPL_BUILD
@@ -719,7 +725,7 @@ static const struct udevice_id rk3288_pinctrl_ids[] = {
};
U_BOOT_DRIVER(pinctrl_rk3288) = {
- .name = "pinctrl_rk3288",
+ .name = "rockchip_rk3288_pinctrl",
.id = UCLASS_PINCTRL,
.of_match = rk3288_pinctrl_ids,
.priv_auto_alloc_size = sizeof(struct rk3288_pinctrl_priv),
diff --git a/drivers/rtc/date.c b/drivers/rtc/date.c
index 8c643a0..bfa2e13 100644
--- a/drivers/rtc/date.c
+++ b/drivers/rtc/date.c
@@ -5,10 +5,6 @@
* SPDX-License-Identifier: GPL-2.0+
*/
-/*
- * Date & Time support for Philips PCF8563 RTC
- */
-
#include <common.h>
#include <command.h>
#include <errno.h>
@@ -28,53 +24,52 @@ static int month_days[12] = {
31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
};
+static int month_offset[] = {
+ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
+};
+
/*
* This only works for the Gregorian calendar - i.e. after 1752 (in the UK)
*/
int rtc_calc_weekday(struct rtc_time *tm)
{
- int leapsToDate;
- int lastYear;
+ int leaps_to_date;
+ int last_year;
int day;
- int MonthOffset[] = { 0,31,59,90,120,151,181,212,243,273,304,334 };
if (tm->tm_year < 1753)
- return -EINVAL;
- lastYear=tm->tm_year-1;
+ return -1;
+ last_year = tm->tm_year - 1;
- /*
- * Number of leap corrections to apply up to end of last year
- */
- leapsToDate = lastYear/4 - lastYear/100 + lastYear/400;
+ /* Number of leap corrections to apply up to end of last year */
+ leaps_to_date = last_year / 4 - last_year / 100 + last_year / 400;
/*
* This year is a leap year if it is divisible by 4 except when it is
* divisible by 100 unless it is divisible by 400
*
- * e.g. 1904 was a leap year, 1900 was not, 1996 is, and 2000 will be
+ * e.g. 1904 was a leap year, 1900 was not, 1996 is, and 2000 is.
*/
- if((tm->tm_year%4==0) &&
- ((tm->tm_year%100!=0) || (tm->tm_year%400==0)) &&
- (tm->tm_mon>2)) {
- /*
- * We are past Feb. 29 in a leap year
- */
- day=1;
+ if (tm->tm_year % 4 == 0 &&
+ ((tm->tm_year % 100 != 0) || (tm->tm_year % 400 == 0)) &&
+ tm->tm_mon > 2) {
+ /* We are past Feb. 29 in a leap year */
+ day = 1;
} else {
- day=0;
+ day = 0;
}
- day += lastYear*365 + leapsToDate + MonthOffset[tm->tm_mon-1] + tm->tm_mday;
-
- tm->tm_wday=day%7;
+ day += last_year * 365 + leaps_to_date + month_offset[tm->tm_mon - 1] +
+ tm->tm_mday;
+ tm->tm_wday = day % 7;
return 0;
}
int rtc_to_tm(int tim, struct rtc_time *tm)
{
- register int i;
- register long hms, day;
+ register int i;
+ register long hms, day;
day = tim / SECDAY;
hms = tim % SECDAY;
@@ -85,22 +80,19 @@ int rtc_to_tm(int tim, struct rtc_time *tm)
tm->tm_sec = (hms % 3600) % 60;
/* Number of years in days */
- for (i = STARTOFTIME; day >= days_in_year(i); i++) {
+ for (i = STARTOFTIME; day >= days_in_year(i); i++)
day -= days_in_year(i);
- }
tm->tm_year = i;
/* Number of months in days left */
- if (leapyear(tm->tm_year)) {
+ if (leapyear(tm->tm_year))
days_in_month(FEBRUARY) = 29;
- }
- for (i = 1; day >= days_in_month(i); i++) {
+ for (i = 1; day >= days_in_month(i); i++)
day -= days_in_month(i);
- }
days_in_month(FEBRUARY) = 28;
tm->tm_mon = i;
- /* Days are what is left over (+1) from all that. */
+ /* Days are what is left over (+1) from all that */
tm->tm_mday = day + 1;
/* Zero unused fields */
@@ -113,19 +105,20 @@ int rtc_to_tm(int tim, struct rtc_time *tm)
return rtc_calc_weekday(tm);
}
-/* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
+/*
+ * Converts Gregorian date to seconds since 1970-01-01 00:00:00.
* Assumes input in normal date format, i.e. 1980-12-31 23:59:59
* => year=1980, mon=12, day=31, hour=23, min=59, sec=59.
*
* [For the Julian calendar (which was used in Russia before 1917,
* Britain & colonies before 1752, anywhere else before 1582,
* and is still in use by some communities) leave out the
- * -year/100+year/400 terms, and add 10.]
+ * -year / 100 + year / 400 terms, and add 10.]
*
* This algorithm was first published by Gauss (I think).
*
* WARNING: this function will overflow on 2106-02-07 06:28:16 on
- * machines were long is 32-bit! (However, as time_t is signed, we
+ * machines where long is 32-bit! (However, as time_t is signed, we
* will already get problems at other places on 2038-01-19 03:14:08)
*/
unsigned long rtc_mktime(const struct rtc_time *tm)
@@ -135,8 +128,8 @@ unsigned long rtc_mktime(const struct rtc_time *tm)
int days, hours;
mon -= 2;
- if (0 >= (int)mon) { /* 1..12 -> 11,12,1..10 */
- mon += 12; /* Puts Feb last since it has leap day */
+ if (0 >= (int)mon) { /* 1..12 -> 11, 12, 1..10 */
+ mon += 12; /* Puts Feb last since it has leap day */
year -= 1;
}
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 0e38903..9ff7234 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -312,6 +312,15 @@ config SYS_NS16550
be used. It can be a constant or a function to get clock, eg,
get_serial_clock().
+config ROCKCHIP_SERIAL
+ bool "Rockchip on-chip UART support"
+ depends on DM_SERIAL && SPL_OF_PLATDATA
+ help
+ Select this to enable a debug UART for Rockchip devices when using
+ CONFIG_OF_PLATDATA (i.e. a compiled-in device tree replacemenmt).
+ This uses the ns16550 driver, converting the platdata from of-platdata
+ to the ns16550 format.
+
config SANDBOX_SERIAL
bool "Sandbox UART support"
depends on SANDBOX
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index 92cbea5..6986d65 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -28,6 +28,9 @@ obj-$(CONFIG_S5P) += serial_s5p.o
obj-$(CONFIG_MXC_UART) += serial_mxc.o
obj-$(CONFIG_PXA_SERIAL) += serial_pxa.o
obj-$(CONFIG_MESON_SERIAL) += serial_meson.o
+ifdef CONFIG_SPL_BUILD
+obj-$(CONFIG_ROCKCHIP_SERIAL) += serial_rockchip.o
+endif
obj-$(CONFIG_S3C24X0_SERIAL) += serial_s3c24x0.o
obj-$(CONFIG_XILINX_UARTLITE) += serial_xuartlite.o
obj-$(CONFIG_SANDBOX_SERIAL) += sandbox.o
diff --git a/drivers/serial/ns16550.c b/drivers/serial/ns16550.c
index c6cb3eb..88fca15 100644
--- a/drivers/serial/ns16550.c
+++ b/drivers/serial/ns16550.c
@@ -347,7 +347,7 @@ int ns16550_serial_probe(struct udevice *dev)
return 0;
}
-#if CONFIG_IS_ENABLED(OF_CONTROL)
+#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
int ns16550_serial_ofdata_to_platdata(struct udevice *dev)
{
struct ns16550_platdata *plat = dev->platdata;
@@ -416,6 +416,7 @@ const struct dm_serial_ops ns16550_serial_ops = {
.setbrg = ns16550_serial_setbrg,
};
+#if !CONFIG_IS_ENABLED(OF_PLATDATA)
#if CONFIG_IS_ENABLED(OF_CONTROL)
/*
* Please consider existing compatible strings before adding a new
@@ -452,4 +453,5 @@ U_BOOT_DRIVER(ns16550_serial) = {
.flags = DM_FLAG_PRE_RELOC,
};
#endif
+#endif /* !OF_PLATDATA */
#endif /* CONFIG_DM_SERIAL */
diff --git a/drivers/serial/sandbox.c b/drivers/serial/sandbox.c
index 58f882b..bcc3465 100644
--- a/drivers/serial/sandbox.c
+++ b/drivers/serial/sandbox.c
@@ -115,7 +115,9 @@ static int sandbox_serial_pending(struct udevice *dev, bool input)
return 0;
os_usleep(100);
+#ifndef CONFIG_SPL_BUILD
video_sync_all();
+#endif
if (next_index == serial_buf_read)
return 1; /* buffer full */
diff --git a/drivers/serial/serial-uclass.c b/drivers/serial/serial-uclass.c
index 0ce5c44..19f38e1 100644
--- a/drivers/serial/serial-uclass.c
+++ b/drivers/serial/serial-uclass.c
@@ -33,7 +33,13 @@ static void serial_find_console_or_panic(void)
struct udevice *dev;
int node;
- if (CONFIG_IS_ENABLED(OF_CONTROL) && blob) {
+ if (CONFIG_IS_ENABLED(OF_PLATDATA)) {
+ uclass_first_device(UCLASS_SERIAL, &dev);
+ if (dev) {
+ gd->cur_serial_dev = dev;
+ return;
+ }
+ } else if (CONFIG_IS_ENABLED(OF_CONTROL) && blob) {
/* Check for a chosen console */
node = fdtdec_get_chosen_node(blob, "stdout-path");
if (node < 0) {
diff --git a/drivers/serial/serial_rockchip.c b/drivers/serial/serial_rockchip.c
new file mode 100644
index 0000000..6bac95a
--- /dev/null
+++ b/drivers/serial/serial_rockchip.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2015 Google, Inc
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <debug_uart.h>
+#include <dm.h>
+#include <dt-structs.h>
+#include <ns16550.h>
+#include <serial.h>
+#include <asm/arch/clock.h>
+
+struct rockchip_uart_platdata {
+ struct dtd_rockchip_rk3288_uart dtplat;
+ struct ns16550_platdata plat;
+};
+
+struct dtd_rockchip_rk3288_uart *dtplat, s_dtplat;
+
+static int rockchip_serial_probe(struct udevice *dev)
+{
+ struct rockchip_uart_platdata *plat = dev_get_platdata(dev);
+
+ /* Create some new platform data for the standard driver */
+ plat->plat.base = plat->dtplat.reg[0];
+ plat->plat.reg_shift = plat->dtplat.reg_shift;
+ plat->plat.clock = plat->dtplat.clock_frequency;
+ dev->platdata = &plat->plat;
+
+ return ns16550_serial_probe(dev);
+}
+
+U_BOOT_DRIVER(rockchip_rk3288_uart) = {
+ .name = "rockchip_rk3288_uart",
+ .id = UCLASS_SERIAL,
+ .priv_auto_alloc_size = sizeof(struct NS16550),
+ .platdata_auto_alloc_size = sizeof(struct rockchip_uart_platdata),
+ .probe = rockchip_serial_probe,
+ .ops = &ns16550_serial_ops,
+ .flags = DM_FLAG_PRE_RELOC,
+};
diff --git a/drivers/serial/serial_stm32x7.c b/drivers/serial/serial_stm32x7.c
index cfbfab7..592c0bd 100644
--- a/drivers/serial/serial_stm32x7.c
+++ b/drivers/serial/serial_stm32x7.c
@@ -9,6 +9,7 @@
#include <dm.h>
#include <asm/io.h>
#include <serial.h>
+#include <asm/arch/stm32.h>
#include <dm/platform_data/serial_stm32x7.h>
#include "serial_stm32x7.h"
@@ -18,7 +19,20 @@ static int stm32_serial_setbrg(struct udevice *dev, int baudrate)
{
struct stm32x7_serial_platdata *plat = dev->platdata;
struct stm32_usart *const usart = plat->base;
- writel(plat->clock/baudrate, &usart->brr);
+ u32 clock, int_div, frac_div, tmp;
+
+ if (((u32)usart & STM32_BUS_MASK) == APB1_PERIPH_BASE)
+ clock = clock_get(CLOCK_APB1);
+ else if (((u32)usart & STM32_BUS_MASK) == APB2_PERIPH_BASE)
+ clock = clock_get(CLOCK_APB2);
+ else
+ return -EINVAL;
+
+ int_div = (25 * clock) / (4 * baudrate);
+ tmp = ((int_div / 100) << USART_BRR_M_SHIFT) & USART_BRR_M_MASK;
+ frac_div = int_div - (100 * (tmp >> USART_BRR_M_SHIFT));
+ tmp |= (((frac_div * 16) + 50) / 100) & USART_BRR_F_MASK;
+ writel(tmp, &usart->brr);
return 0;
}
diff --git a/drivers/spi/cadence_qspi.c b/drivers/spi/cadence_qspi.c
index 4f7fd52..a5244ff 100644
--- a/drivers/spi/cadence_qspi.c
+++ b/drivers/spi/cadence_qspi.c
@@ -191,6 +191,7 @@ static int cadence_spi_xfer(struct udevice *dev, unsigned int bitlen,
struct udevice *bus = dev->parent;
struct cadence_spi_platdata *plat = bus->platdata;
struct cadence_spi_priv *priv = dev_get_priv(bus);
+ struct dm_spi_slave_platdata *dm_plat = dev_get_parent_platdata(dev);
void *base = priv->regbase;
u8 *cmd_buf = priv->cmd_buf;
size_t data_bytes;
@@ -250,7 +251,7 @@ static int cadence_spi_xfer(struct udevice *dev, unsigned int bitlen,
break;
case CQSPI_INDIRECT_READ:
err = cadence_qspi_apb_indirect_read_setup(plat,
- priv->cmd_len, cmd_buf);
+ priv->cmd_len, dm_plat->mode_rx, cmd_buf);
if (!err) {
err = cadence_qspi_apb_indirect_read_execute
(plat, data_bytes, din);
diff --git a/drivers/spi/cadence_qspi.h b/drivers/spi/cadence_qspi.h
index 2912e36..a849f7b 100644
--- a/drivers/spi/cadence_qspi.h
+++ b/drivers/spi/cadence_qspi.h
@@ -53,7 +53,7 @@ int cadence_qspi_apb_command_write(void *reg_base_addr,
unsigned int txlen, const u8 *txbuf);
int cadence_qspi_apb_indirect_read_setup(struct cadence_spi_platdata *plat,
- unsigned int cmdlen, const u8 *cmdbuf);
+ unsigned int cmdlen, unsigned int rx_width, const u8 *cmdbuf);
int cadence_qspi_apb_indirect_read_execute(struct cadence_spi_platdata *plat,
unsigned int rxlen, u8 *rxbuf);
int cadence_qspi_apb_indirect_write_setup(struct cadence_spi_platdata *plat,
diff --git a/drivers/spi/cadence_qspi_apb.c b/drivers/spi/cadence_qspi_apb.c
index a71531d..1a35d55 100644
--- a/drivers/spi/cadence_qspi_apb.c
+++ b/drivers/spi/cadence_qspi_apb.c
@@ -29,6 +29,7 @@
#include <asm/io.h>
#include <asm/errno.h>
#include <wait_bit.h>
+#include <spi.h>
#include "cadence_qspi.h"
#define CQSPI_REG_POLL_US (1) /* 1us */
@@ -45,7 +46,6 @@
#define CQSPI_INST_TYPE_QUAD (2)
#define CQSPI_STIG_DATA_LEN_MAX (8)
-#define CQSPI_INDIRECTTRIGGER_ADDR_MASK (0xFFFFF)
#define CQSPI_DUMMY_CLKS_PER_BYTE (8)
#define CQSPI_DUMMY_BYTES_MAX (4)
@@ -549,7 +549,7 @@ int cadence_qspi_apb_command_write(void *reg_base, unsigned int cmdlen,
/* Opcode + Address (3/4 bytes) + dummy bytes (0-4 bytes) */
int cadence_qspi_apb_indirect_read_setup(struct cadence_spi_platdata *plat,
- unsigned int cmdlen, const u8 *cmdbuf)
+ unsigned int cmdlen, unsigned int rx_width, const u8 *cmdbuf)
{
unsigned int reg;
unsigned int rd_reg;
@@ -573,16 +573,15 @@ int cadence_qspi_apb_indirect_read_setup(struct cadence_spi_platdata *plat,
addr_bytes = cmdlen - 1;
/* Setup the indirect trigger address */
- writel(((u32)plat->ahbbase & CQSPI_INDIRECTTRIGGER_ADDR_MASK),
+ writel((u32)plat->ahbbase,
plat->regbase + CQSPI_REG_INDIRECTTRIGGER);
/* Configure the opcode */
rd_reg = cmdbuf[0] << CQSPI_REG_RD_INSTR_OPCODE_LSB;
-#if (CONFIG_SPI_FLASH_QUAD == 1)
- /* Instruction and address at DQ0, data at DQ0-3. */
- rd_reg |= CQSPI_INST_TYPE_QUAD << CQSPI_REG_RD_INSTR_TYPE_DATA_LSB;
-#endif
+ if (rx_width & SPI_RX_QUAD)
+ /* Instruction and address at DQ0, data at DQ0-3. */
+ rd_reg |= CQSPI_INST_TYPE_QUAD << CQSPI_REG_RD_INSTR_TYPE_DATA_LSB;
/* Get address */
addr_value = cadence_qspi_apb_cmd2addr(&cmdbuf[1], addr_bytes);
@@ -714,7 +713,7 @@ int cadence_qspi_apb_indirect_write_setup(struct cadence_spi_platdata *plat,
return -EINVAL;
}
/* Setup the indirect trigger address */
- writel(((u32)plat->ahbbase & CQSPI_INDIRECTTRIGGER_ADDR_MASK),
+ writel((u32)plat->ahbbase,
plat->regbase + CQSPI_REG_INDIRECTTRIGGER);
/* Configure the opcode */
diff --git a/drivers/spi/davinci_spi.c b/drivers/spi/davinci_spi.c
index 0bd4f88..20aa99a 100644
--- a/drivers/spi/davinci_spi.c
+++ b/drivers/spi/davinci_spi.c
@@ -14,6 +14,7 @@
#include <malloc.h>
#include <asm/io.h>
#include <asm/arch/hardware.h>
+#include <dm.h>
/* SPIGCR0 */
#define SPIGCR0_SPIENA_MASK 0x1
@@ -51,6 +52,7 @@
/* SPIDEF */
#define SPIDEF_CSDEF0_MASK BIT(0)
+#ifndef CONFIG_DM_SPI
#define SPI0_BUS 0
#define SPI0_BASE CONFIG_SYS_SPI_BASE
/*
@@ -83,6 +85,9 @@
#define SPI2_NUM_CS CONFIG_SYS_SPI2_NUM_CS
#define SPI2_BASE CONFIG_SYS_SPI2_BASE
#endif
+#endif
+
+DECLARE_GLOBAL_DATA_PTR;
/* davinci spi register set */
struct davinci_spi_regs {
@@ -114,16 +119,17 @@ struct davinci_spi_regs {
/* davinci spi slave */
struct davinci_spi_slave {
+#ifndef CONFIG_DM_SPI
struct spi_slave slave;
+#endif
struct davinci_spi_regs *regs;
- unsigned int freq;
+ unsigned int freq; /* current SPI bus frequency */
+ unsigned int mode; /* current SPI mode used */
+ u8 num_cs; /* total no. of CS available */
+ u8 cur_cs; /* CS of current slave */
+ bool half_duplex; /* true, if master is half-duplex only */
};
-static inline struct davinci_spi_slave *to_davinci_spi(struct spi_slave *slave)
-{
- return container_of(slave, struct davinci_spi_slave, slave);
-}
-
/*
* This functions needs to act like a macro to avoid pipeline reloads in the
* loops below. Use always_inline. This gains us about 160KiB/s and the bloat
@@ -144,15 +150,14 @@ static inline u32 davinci_spi_xfer_data(struct davinci_spi_slave *ds, u32 data)
return buf_reg_val;
}
-static int davinci_spi_read(struct spi_slave *slave, unsigned int len,
+static int davinci_spi_read(struct davinci_spi_slave *ds, unsigned int len,
u8 *rxp, unsigned long flags)
{
- struct davinci_spi_slave *ds = to_davinci_spi(slave);
unsigned int data1_reg_val;
/* enable CS hold, CS[n] and clear the data bits */
data1_reg_val = ((1 << SPIDAT1_CSHOLD_SHIFT) |
- (slave->cs << SPIDAT1_CSNR_SHIFT));
+ (ds->cur_cs << SPIDAT1_CSNR_SHIFT));
/* wait till TXFULL is deasserted */
while (readl(&ds->regs->buf) & SPIBUF_TXFULL_MASK)
@@ -175,15 +180,14 @@ static int davinci_spi_read(struct spi_slave *slave, unsigned int len,
return 0;
}
-static int davinci_spi_write(struct spi_slave *slave, unsigned int len,
+static int davinci_spi_write(struct davinci_spi_slave *ds, unsigned int len,
const u8 *txp, unsigned long flags)
{
- struct davinci_spi_slave *ds = to_davinci_spi(slave);
unsigned int data1_reg_val;
/* enable CS hold and clear the data bits */
data1_reg_val = ((1 << SPIDAT1_CSHOLD_SHIFT) |
- (slave->cs << SPIDAT1_CSNR_SHIFT));
+ (ds->cur_cs << SPIDAT1_CSNR_SHIFT));
/* wait till TXFULL is deasserted */
while (readl(&ds->regs->buf) & SPIBUF_TXFULL_MASK)
@@ -209,16 +213,15 @@ static int davinci_spi_write(struct spi_slave *slave, unsigned int len,
return 0;
}
-#ifndef CONFIG_SPI_HALF_DUPLEX
-static int davinci_spi_read_write(struct spi_slave *slave, unsigned int len,
- u8 *rxp, const u8 *txp, unsigned long flags)
+static int davinci_spi_read_write(struct davinci_spi_slave *ds, unsigned
+ int len, u8 *rxp, const u8 *txp,
+ unsigned long flags)
{
- struct davinci_spi_slave *ds = to_davinci_spi(slave);
unsigned int data1_reg_val;
/* enable CS hold and clear the data bits */
data1_reg_val = ((1 << SPIDAT1_CSHOLD_SHIFT) |
- (slave->cs << SPIDAT1_CSNR_SHIFT));
+ (ds->cur_cs << SPIDAT1_CSNR_SHIFT));
/* wait till TXFULL is deasserted */
while (readl(&ds->regs->buf) & SPIBUF_TXFULL_MASK)
@@ -237,7 +240,115 @@ static int davinci_spi_read_write(struct spi_slave *slave, unsigned int len,
return 0;
}
-#endif
+
+
+static int __davinci_spi_claim_bus(struct davinci_spi_slave *ds, int cs)
+{
+ unsigned int mode = 0, scalar;
+
+ /* Enable the SPI hardware */
+ writel(SPIGCR0_SPIRST_MASK, &ds->regs->gcr0);
+ udelay(1000);
+ writel(SPIGCR0_SPIENA_MASK, &ds->regs->gcr0);
+
+ /* Set master mode, powered up and not activated */
+ writel(SPIGCR1_MASTER_MASK | SPIGCR1_CLKMOD_MASK, &ds->regs->gcr1);
+
+ /* CS, CLK, SIMO and SOMI are functional pins */
+ writel(((1 << cs) | SPIPC0_CLKFUN_MASK |
+ SPIPC0_DOFUN_MASK | SPIPC0_DIFUN_MASK), &ds->regs->pc0);
+
+ /* setup format */
+ scalar = ((CONFIG_SYS_SPI_CLK / ds->freq) - 1) & 0xFF;
+
+ /*
+ * Use following format:
+ * character length = 8,
+ * MSB shifted out first
+ */
+ if (ds->mode & SPI_CPOL)
+ mode |= SPI_CPOL;
+ if (!(ds->mode & SPI_CPHA))
+ mode |= SPI_CPHA;
+ writel(8 | (scalar << SPIFMT_PRESCALE_SHIFT) |
+ (mode << SPIFMT_PHASE_SHIFT), &ds->regs->fmt0);
+
+ /*
+ * Including a minor delay. No science here. Should be good even with
+ * no delay
+ */
+ writel((50 << SPI_C2TDELAY_SHIFT) |
+ (50 << SPI_T2CDELAY_SHIFT), &ds->regs->delay);
+
+ /* default chip select register */
+ writel(SPIDEF_CSDEF0_MASK, &ds->regs->def);
+
+ /* no interrupts */
+ writel(0, &ds->regs->int0);
+ writel(0, &ds->regs->lvl);
+
+ /* enable SPI */
+ writel((readl(&ds->regs->gcr1) | SPIGCR1_SPIENA_MASK), &ds->regs->gcr1);
+
+ return 0;
+}
+
+static int __davinci_spi_release_bus(struct davinci_spi_slave *ds)
+{
+ /* Disable the SPI hardware */
+ writel(SPIGCR0_SPIRST_MASK, &ds->regs->gcr0);
+
+ return 0;
+}
+
+static int __davinci_spi_xfer(struct davinci_spi_slave *ds,
+ unsigned int bitlen, const void *dout, void *din,
+ unsigned long flags)
+{
+ unsigned int len;
+
+ if (bitlen == 0)
+ /* Finish any previously submitted transfers */
+ goto out;
+
+ /*
+ * It's not clear how non-8-bit-aligned transfers are supposed to be
+ * represented as a stream of bytes...this is a limitation of
+ * the current SPI interface - here we terminate on receiving such a
+ * transfer request.
+ */
+ if (bitlen % 8) {
+ /* Errors always terminate an ongoing transfer */
+ flags |= SPI_XFER_END;
+ goto out;
+ }
+
+ len = bitlen / 8;
+
+ if (!dout)
+ return davinci_spi_read(ds, len, din, flags);
+ if (!din)
+ return davinci_spi_write(ds, len, dout, flags);
+ if (!ds->half_duplex)
+ return davinci_spi_read_write(ds, len, din, dout, flags);
+
+ printf("SPI full duplex not supported\n");
+ flags |= SPI_XFER_END;
+
+out:
+ if (flags & SPI_XFER_END) {
+ u8 dummy = 0;
+ davinci_spi_write(ds, 1, &dummy, flags);
+ }
+ return 0;
+}
+
+#ifndef CONFIG_DM_SPI
+
+static inline struct davinci_spi_slave *to_davinci_spi(struct spi_slave *slave)
+{
+ return container_of(slave, struct davinci_spi_slave, slave);
+}
int spi_cs_is_valid(unsigned int bus, unsigned int cs)
{
@@ -313,6 +424,7 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
}
ds->freq = max_hz;
+ ds->mode = mode;
return &ds->slave;
}
@@ -324,104 +436,143 @@ void spi_free_slave(struct spi_slave *slave)
free(ds);
}
+int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
+ const void *dout, void *din, unsigned long flags)
+{
+ struct davinci_spi_slave *ds = to_davinci_spi(slave);
+
+ ds->cur_cs = slave->cs;
+
+ return __davinci_spi_xfer(ds, bitlen, dout, din, flags);
+}
+
int spi_claim_bus(struct spi_slave *slave)
{
struct davinci_spi_slave *ds = to_davinci_spi(slave);
- unsigned int scalar;
- /* Enable the SPI hardware */
- writel(SPIGCR0_SPIRST_MASK, &ds->regs->gcr0);
- udelay(1000);
- writel(SPIGCR0_SPIENA_MASK, &ds->regs->gcr0);
+#ifdef CONFIG_SPI_HALF_DUPLEX
+ ds->half_duplex = true;
+#else
+ ds->half_duplex = false;
+#endif
+ return __davinci_spi_claim_bus(ds, ds->slave.cs);
+}
- /* Set master mode, powered up and not activated */
- writel(SPIGCR1_MASTER_MASK | SPIGCR1_CLKMOD_MASK, &ds->regs->gcr1);
+void spi_release_bus(struct spi_slave *slave)
+{
+ struct davinci_spi_slave *ds = to_davinci_spi(slave);
- /* CS, CLK, SIMO and SOMI are functional pins */
- writel(((1 << slave->cs) | SPIPC0_CLKFUN_MASK |
- SPIPC0_DOFUN_MASK | SPIPC0_DIFUN_MASK), &ds->regs->pc0);
+ __davinci_spi_release_bus(ds);
+}
- /* setup format */
- scalar = ((CONFIG_SYS_SPI_CLK / ds->freq) - 1) & 0xFF;
+#else
+static int davinci_spi_set_speed(struct udevice *bus, uint max_hz)
+{
+ struct davinci_spi_slave *ds = dev_get_priv(bus);
- /*
- * Use following format:
- * character length = 8,
- * clock signal delayed by half clk cycle,
- * clock low in idle state - Mode 0,
- * MSB shifted out first
- */
- writel(8 | (scalar << SPIFMT_PRESCALE_SHIFT) |
- (1 << SPIFMT_PHASE_SHIFT), &ds->regs->fmt0);
+ debug("%s speed %u\n", __func__, max_hz);
+ if (max_hz > CONFIG_SYS_SPI_CLK / 2)
+ return -EINVAL;
- /*
- * Including a minor delay. No science here. Should be good even with
- * no delay
- */
- writel((50 << SPI_C2TDELAY_SHIFT) |
- (50 << SPI_T2CDELAY_SHIFT), &ds->regs->delay);
+ ds->freq = max_hz;
- /* default chip select register */
- writel(SPIDEF_CSDEF0_MASK, &ds->regs->def);
+ return 0;
+}
- /* no interrupts */
- writel(0, &ds->regs->int0);
- writel(0, &ds->regs->lvl);
+static int davinci_spi_set_mode(struct udevice *bus, uint mode)
+{
+ struct davinci_spi_slave *ds = dev_get_priv(bus);
- /* enable SPI */
- writel((readl(&ds->regs->gcr1) | SPIGCR1_SPIENA_MASK), &ds->regs->gcr1);
+ debug("%s mode %u\n", __func__, mode);
+ ds->mode = mode;
return 0;
}
-void spi_release_bus(struct spi_slave *slave)
+static int davinci_spi_claim_bus(struct udevice *dev)
{
- struct davinci_spi_slave *ds = to_davinci_spi(slave);
+ struct dm_spi_slave_platdata *slave_plat =
+ dev_get_parent_platdata(dev);
+ struct udevice *bus = dev->parent;
+ struct davinci_spi_slave *ds = dev_get_priv(bus);
+
+ if (slave_plat->cs >= ds->num_cs) {
+ printf("Invalid SPI chipselect\n");
+ return -EINVAL;
+ }
+ ds->half_duplex = slave_plat->mode & SPI_PREAMBLE;
- /* Disable the SPI hardware */
- writel(SPIGCR0_SPIRST_MASK, &ds->regs->gcr0);
+ return __davinci_spi_claim_bus(ds, slave_plat->cs);
}
-int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
- const void *dout, void *din, unsigned long flags)
+static int davinci_spi_release_bus(struct udevice *dev)
{
- unsigned int len;
+ struct davinci_spi_slave *ds = dev_get_priv(dev->parent);
- if (bitlen == 0)
- /* Finish any previously submitted transfers */
- goto out;
+ return __davinci_spi_release_bus(ds);
+}
- /*
- * It's not clear how non-8-bit-aligned transfers are supposed to be
- * represented as a stream of bytes...this is a limitation of
- * the current SPI interface - here we terminate on receiving such a
- * transfer request.
- */
- if (bitlen % 8) {
- /* Errors always terminate an ongoing transfer */
- flags |= SPI_XFER_END;
- goto out;
+static int davinci_spi_xfer(struct udevice *dev, unsigned int bitlen,
+ const void *dout, void *din,
+ unsigned long flags)
+{
+ struct dm_spi_slave_platdata *slave =
+ dev_get_parent_platdata(dev);
+ struct udevice *bus = dev->parent;
+ struct davinci_spi_slave *ds = dev_get_priv(bus);
+
+ if (slave->cs >= ds->num_cs) {
+ printf("Invalid SPI chipselect\n");
+ return -EINVAL;
}
+ ds->cur_cs = slave->cs;
- len = bitlen / 8;
+ return __davinci_spi_xfer(ds, bitlen, dout, din, flags);
+}
- if (!dout)
- return davinci_spi_read(slave, len, din, flags);
- else if (!din)
- return davinci_spi_write(slave, len, dout, flags);
-#ifndef CONFIG_SPI_HALF_DUPLEX
- else
- return davinci_spi_read_write(slave, len, din, dout, flags);
-#else
- printf("SPI full duplex transaction requested with "
- "CONFIG_SPI_HALF_DUPLEX defined.\n");
- flags |= SPI_XFER_END;
-#endif
+static int davinci_spi_probe(struct udevice *bus)
+{
+ /* Nothing to do */
+ return 0;
+}
-out:
- if (flags & SPI_XFER_END) {
- u8 dummy = 0;
- davinci_spi_write(slave, 1, &dummy, flags);
+static int davinci_ofdata_to_platadata(struct udevice *bus)
+{
+ struct davinci_spi_slave *ds = dev_get_priv(bus);
+ const void *blob = gd->fdt_blob;
+ int node = bus->of_offset;
+
+ ds->regs = dev_map_physmem(bus, sizeof(struct davinci_spi_regs));
+ if (!ds->regs) {
+ printf("%s: could not map device address\n", __func__);
+ return -EINVAL;
}
+ ds->num_cs = fdtdec_get_int(blob, node, "num-cs", 4);
+
return 0;
}
+
+static const struct dm_spi_ops davinci_spi_ops = {
+ .claim_bus = davinci_spi_claim_bus,
+ .release_bus = davinci_spi_release_bus,
+ .xfer = davinci_spi_xfer,
+ .set_speed = davinci_spi_set_speed,
+ .set_mode = davinci_spi_set_mode,
+};
+
+static const struct udevice_id davinci_spi_ids[] = {
+ { .compatible = "ti,keystone-spi" },
+ { .compatible = "ti,dm6441-spi" },
+ { }
+};
+
+U_BOOT_DRIVER(davinci_spi) = {
+ .name = "davinci_spi",
+ .id = UCLASS_SPI,
+ .of_match = davinci_spi_ids,
+ .ops = &davinci_spi_ops,
+ .ofdata_to_platdata = davinci_ofdata_to_platadata,
+ .priv_auto_alloc_size = sizeof(struct davinci_spi_slave),
+ .probe = davinci_spi_probe,
+};
+#endif
diff --git a/drivers/spi/spi-uclass.c b/drivers/spi/spi-uclass.c
index 84b6786..8003f9b 100644
--- a/drivers/spi/spi-uclass.c
+++ b/drivers/spi/spi-uclass.c
@@ -278,6 +278,7 @@ int spi_get_bus_and_cs(int busnum, int cs, int speed, int mode,
struct udevice **busp, struct spi_slave **devp)
{
struct udevice *bus, *dev;
+ struct dm_spi_slave_platdata *plat;
bool created = false;
int ret;
@@ -294,8 +295,6 @@ int spi_get_bus_and_cs(int busnum, int cs, int speed, int mode,
* SPI flash chip - we will bind to the correct driver.
*/
if (ret == -ENODEV && drv_name) {
- struct dm_spi_slave_platdata *plat;
-
debug("%s: Binding new device '%s', busnum=%d, cs=%d, driver=%s\n",
__func__, dev_name, busnum, cs, drv_name);
ret = device_bind_driver(bus, drv_name, dev_name, &dev);
@@ -322,6 +321,11 @@ int spi_get_bus_and_cs(int busnum, int cs, int speed, int mode,
slave->dev = dev;
}
+ plat = dev_get_parent_platdata(dev);
+ if (!speed) {
+ speed = plat->max_hz;
+ mode = plat->mode;
+ }
ret = spi_set_speed_mode(bus, speed, mode);
if (ret)
goto err;
@@ -333,7 +337,7 @@ int spi_get_bus_and_cs(int busnum, int cs, int speed, int mode,
return 0;
err:
- debug("%s: Error path, credted=%d, device '%s'\n", __func__,
+ debug("%s: Error path, created=%d, device '%s'\n", __func__,
created, dev->name);
if (created) {
device_remove(dev);
diff --git a/drivers/usb/musb-new/musb_dsps.c b/drivers/usb/musb-new/musb_dsps.c
index bb7c952..a71db76 100644
--- a/drivers/usb/musb-new/musb_dsps.c
+++ b/drivers/usb/musb-new/musb_dsps.c
@@ -627,7 +627,7 @@ static int __devinit dsps_probe(struct platform_device *pdev)
/* get memory resource */
iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!iomem) {
- dev_err(&pdev->dev, "failed to get usbss mem resourse\n");
+ dev_err(&pdev->dev, "failed to get usbss mem resource\n");
ret = -ENODEV;
goto err1;
}
diff --git a/drivers/video/tegra.c b/drivers/video/tegra.c
index 217f05f..92214d6 100644
--- a/drivers/video/tegra.c
+++ b/drivers/video/tegra.c
@@ -251,7 +251,7 @@ static int setup_window(struct disp_ctl_win *win,
/**
* Register a new display based on device tree configuration.
*
- * The frame buffer can be positioned by U-Boot or overriden by the fdt.
+ * The frame buffer can be positioned by U-Boot or overridden by the fdt.
* You should pass in the U-Boot address here, and check the contents of
* struct tegra_lcd_priv to see what was actually chosen.
*
diff --git a/dts/Kconfig b/dts/Kconfig
index c56c129..4b7d8b1 100644
--- a/dts/Kconfig
+++ b/dts/Kconfig
@@ -85,4 +85,25 @@ config OF_SPL_REMOVE_PROPS
can be discarded. This option defines the list of properties to
discard.
+config SPL_OF_PLATDATA
+ bool "Generate platform data for use in SPL"
+ depends on SPL_OF_CONTROL
+ help
+ For very constrained SPL environments the overhead of decoding
+ device tree nodes and converting their contents into platform data
+ is too large. This overhead includes libfdt code as well as the
+ device tree contents itself. The latter is fairly compact, but the
+ former can add 3KB or more to a Thumb 2 Image.
+
+ This option enables generation of platform data from the device
+ tree as C code. This code creates devices using U_BOOT_DEVICE()
+ declarations. The benefit is that it allows driver code to access
+ the platform data directly in C structures, avoidin the libfdt
+ overhead.
+
+ This option works by generating C structure declarations for each
+ compatible string, then adding platform data and U_BOOT_DEVICE
+ declarations for each node. See README.platdata for more
+ information.
+
endmenu
diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h
index 0abcbe4..a6d1d2a 100644
--- a/include/asm-generic/global_data.h
+++ b/include/asm-generic/global_data.h
@@ -55,20 +55,6 @@ typedef struct global_data {
unsigned long relocaddr; /* Start address of U-Boot in RAM */
phys_size_t ram_size; /* RAM size */
-#ifdef CONFIG_SYS_MEM_RESERVE_SECURE
-#define MEM_RESERVE_SECURE_SECURED 0x1
-#define MEM_RESERVE_SECURE_MAINTAINED 0x2
-#define MEM_RESERVE_SECURE_ADDR_MASK (~0x3)
- /*
- * Secure memory addr
- * This variable needs maintenance if the RAM base is not zero,
- * or if RAM splits into non-consecutive banks. It also has a
- * flag indicating the secure memory is marked as secure by MMU.
- * Flags used: 0x1 secured
- * 0x2 maintained
- */
- phys_addr_t secure_ram;
-#endif
unsigned long mon_len; /* monitor len */
unsigned long irq_sp; /* irq stack pointer */
unsigned long start_addr_sp; /* start_addr_stackpointer */
diff --git a/include/clk.h b/include/clk.h
index 2f31cf7..161bc28 100644
--- a/include/clk.h
+++ b/include/clk.h
@@ -60,6 +60,10 @@ struct clk {
};
#if CONFIG_IS_ENABLED(OF_CONTROL)
+struct phandle_2_cell;
+int clk_get_by_index_platdata(struct udevice *dev, int index,
+ struct phandle_2_cell *cells, struct clk *clk);
+
/**
* clock_get_by_index - Get/request a clock by integer index.
*
diff --git a/include/common.h b/include/common.h
index 3feaae6..e9f0dea 100644
--- a/include/common.h
+++ b/include/common.h
@@ -101,6 +101,13 @@ typedef volatile unsigned char vu_char;
#define _DEBUG 0
#endif
+#ifdef CONFIG_SPL_BUILD
+#define _SPL_BUILD 1
+#else
+#define _SPL_BUILD 0
+#endif
+
+/* Define this at the top of a file to add a prefix to debug messages */
#ifndef pr_fmt
#define pr_fmt(fmt) fmt
#endif
@@ -116,9 +123,14 @@ typedef volatile unsigned char vu_char;
printf(pr_fmt(fmt), ##args); \
} while (0)
+/* Show a message if DEBUG is defined in a file */
#define debug(fmt, args...) \
debug_cond(_DEBUG, fmt, ##args)
+/* Show a message if not in SPL */
+#define warn_non_spl(fmt, args...) \
+ debug_cond(!_SPL_BUILD, fmt, ##args)
+
/*
* An assertion is run-time check done in debug mode only. If DEBUG is not
* defined then it is skipped. If DEBUG is defined and the assertion fails,
diff --git a/include/configs/arndale.h b/include/configs/arndale.h
index b08f341..18e59fc 100644
--- a/include/configs/arndale.h
+++ b/include/configs/arndale.h
@@ -45,6 +45,7 @@
#define CONFIG_S5P_PA_SYSRAM 0x02020000
#define CONFIG_SMP_PEN_ADDR CONFIG_S5P_PA_SYSRAM
+#define CONFIG_ARMV7_PSCI_NR_CPUS 4
/* The PERIPHBASE in the CBAR register is wrong on the Arndale, so override it */
#define CONFIG_ARM_GIC_BASE_ADDRESS 0x10480000
diff --git a/include/configs/bcm_ep_board.h b/include/configs/bcm_ep_board.h
index d5888e8..50cd743 100644
--- a/include/configs/bcm_ep_board.h
+++ b/include/configs/bcm_ep_board.h
@@ -93,5 +93,6 @@
/* Misc utility code */
#define CONFIG_BOUNCE_BUFFER
#define CONFIG_CRC32_VERIFY
+#define CONFIG_ARMV7_PSCI_NR_CPUS 4
#endif /* __BCM_EP_BOARD_H */
diff --git a/include/configs/dragonboard410c.h b/include/configs/dragonboard410c.h
index 4b00922..1dbe219 100644
--- a/include/configs/dragonboard410c.h
+++ b/include/configs/dragonboard410c.h
@@ -84,8 +84,8 @@
#define BOOT_TARGET_DEVICES(func) \
func(USB, usb, 0) \
- func(MMC, mmc, 0) \
func(MMC, mmc, 1) \
+ func(MMC, mmc, 0) \
func(DHCP, dhcp, na)
#include <config_distro_bootcmd.h>
@@ -126,6 +126,8 @@ REFLASH(dragonboard/u-boot.img, 8)\
"fdtfile=apq8016-sbc.dtb\0" \
"fdt_addr_r=0x83000000\0"\
"ramdisk_addr_r=0x84000000\0"\
+ "scriptaddr=0x90000000\0"\
+ "pxefile_addr_r=0x90100000\0"\
BOOTENV
#define CONFIG_ENV_IS_NOWHERE
diff --git a/include/configs/jetson-tk1.h b/include/configs/jetson-tk1.h
index 953c088..2b172a5 100644
--- a/include/configs/jetson-tk1.h
+++ b/include/configs/jetson-tk1.h
@@ -61,6 +61,7 @@
#include "tegra-common-post.h"
#define CONFIG_ARMV7_PSCI 1
+#define CONFIG_ARMV7_PSCI_NR_CPUS 4
/* Reserve top 1M for secure RAM */
#define CONFIG_ARMV7_SECURE_BASE 0xfff00000
#define CONFIG_ARMV7_SECURE_RESERVE_SIZE 0x00100000
diff --git a/include/configs/k2g_evm.h b/include/configs/k2g_evm.h
index f8bba67..71b0037 100644
--- a/include/configs/k2g_evm.h
+++ b/include/configs/k2g_evm.h
@@ -73,4 +73,10 @@
#define CONFIG_SF_DEFAULT_BUS 1
#define CONFIG_SF_DEFAULT_CS 0
+#ifndef CONFIG_SPL_BUILD
+#define CONFIG_CADENCE_QSPI
+#define CONFIG_CQSPI_REF_CLK 384000000
+#define CONFIG_CQSPI_DECODER 0x0
+#endif
+
#endif /* __CONFIG_K2G_EVM_H */
diff --git a/include/configs/ls1021aqds.h b/include/configs/ls1021aqds.h
index db684d2..eb444eb 100644
--- a/include/configs/ls1021aqds.h
+++ b/include/configs/ls1021aqds.h
@@ -10,6 +10,7 @@
#define CONFIG_LS102XA
#define CONFIG_ARMV7_PSCI
+#define CONFIG_ARMV7_PSCI_NR_CPUS CONFIG_MAX_CPUS
#define CONFIG_SYS_FSL_CLK
diff --git a/include/configs/ls1021atwr.h b/include/configs/ls1021atwr.h
index 0fb28ef..616aebb 100644
--- a/include/configs/ls1021atwr.h
+++ b/include/configs/ls1021atwr.h
@@ -10,6 +10,7 @@
#define CONFIG_LS102XA
#define CONFIG_ARMV7_PSCI
+#define CONFIG_ARMV7_PSCI_NR_CPUS CONFIG_MAX_CPUS
#define CONFIG_SYS_FSL_CLK
diff --git a/include/configs/ls1043ardb.h b/include/configs/ls1043ardb.h
index 94ddfb1..44f86fa 100644
--- a/include/configs/ls1043ardb.h
+++ b/include/configs/ls1043ardb.h
@@ -9,6 +9,17 @@
#include "ls1043a_common.h"
+#if defined(CONFIG_FSL_LS_PPA)
+#define CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT
+#define SEC_FIRMWARE_ERET_ADDR_REVERT
+#define CONFIG_ARMV8_PSCI
+
+#define CONFIG_SYS_LS_PPA_FW_IN_NOR
+#ifdef CONFIG_SYS_LS_PPA_FW_IN_NOR
+#define CONFIG_SYS_LS_PPA_FW_ADDR 0x60500000
+#endif
+#endif
+
#define CONFIG_DISPLAY_CPUINFO
#define CONFIG_DISPLAY_BOARDINFO
diff --git a/include/configs/mxs.h b/include/configs/mxs.h
index 0882d5d..238b16d 100644
--- a/include/configs/mxs.h
+++ b/include/configs/mxs.h
@@ -120,7 +120,7 @@
#define CONFIG_PL011_CLOCK 24000000
#define CONFIG_PL01x_PORTS { (void *)MXS_UARTDBG_BASE }
#define CONFIG_CONS_INDEX 0
-/* Default baudrate can be overriden by board! */
+/* Default baudrate can be overridden by board! */
#ifndef CONFIG_BAUDRATE
#define CONFIG_BAUDRATE 115200
#endif
diff --git a/include/configs/rk3036_common.h b/include/configs/rk3036_common.h
index 1bdcf9d..ae4b101 100644
--- a/include/configs/rk3036_common.h
+++ b/include/configs/rk3036_common.h
@@ -45,7 +45,6 @@
/* MMC/SD IP block */
#define CONFIG_MMC
#define CONFIG_GENERIC_MMC
-#define CONFIG_SDHCI
#define CONFIG_DWMMC
#define CONFIG_BOUNCE_BUFFER
diff --git a/include/configs/rk3288_common.h b/include/configs/rk3288_common.h
index 9d50d83..8adc26f 100644
--- a/include/configs/rk3288_common.h
+++ b/include/configs/rk3288_common.h
@@ -51,7 +51,6 @@
/* MMC/SD IP block */
#define CONFIG_MMC
#define CONFIG_GENERIC_MMC
-#define CONFIG_SDHCI
#define CONFIG_DWMMC
#define CONFIG_BOUNCE_BUFFER
diff --git a/include/configs/sandbox.h b/include/configs/sandbox.h
index 23a0c40..4de89f8 100644
--- a/include/configs/sandbox.h
+++ b/include/configs/sandbox.h
@@ -16,8 +16,10 @@
#endif
+#ifndef CONFIG_SPL_BUILD
#define CONFIG_IO_TRACE
#define CONFIG_CMD_IOTRACE
+#endif
#ifndef CONFIG_TIMER
#define CONFIG_SYS_TIMER_RATE 1000000
@@ -192,6 +194,7 @@
#define CONFIG_CMD_LZMADEC
#define CONFIG_CMD_DATE
+#ifndef CONFIG_SPL_BUILD
#define CONFIG_CMD_IDE
#define CONFIG_SYS_IDE_MAXBUS 1
#define CONFIG_SYS_ATA_IDE0_OFFSET 0
@@ -201,6 +204,7 @@
#define CONFIG_SYS_ATA_REG_OFFSET 1
#define CONFIG_SYS_ATA_ALT_OFFSET 2
#define CONFIG_SYS_ATA_STRIDE 4
+#endif
#define CONFIG_SCSI
#define CONFIG_SCSI_AHCI_PLAT
diff --git a/include/configs/sandbox_spl.h b/include/configs/sandbox_spl.h
new file mode 100644
index 0000000..ffc3098
--- /dev/null
+++ b/include/configs/sandbox_spl.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2016 Google, Inc
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __SANDBOX_SPL_CONFIG_H
+#define __SANDBOX_SPL_CONFIG_H
+
+#include <configs/sandbox.h>
+
+#define CONFIG_SPL_BOARD_INIT
+
+#define CONFIG_SPL_DRIVERS_MISC_SUPPORT
+#define CONFIG_SPL_ENV_SUPPORT
+#define CONFIG_SPL_FRAMEWORK
+#define CONFIG_SPL_LIBCOMMON_SUPPORT
+#define CONFIG_SPL_LIBGENERIC_SUPPORT
+#define CONFIG_SPL_SERIAL_SUPPORT
+
+#endif
diff --git a/include/configs/som-db5800-som-6867.h b/include/configs/som-db5800-som-6867.h
new file mode 100644
index 0000000..a4b343e
--- /dev/null
+++ b/include/configs/som-db5800-som-6867.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2015 Google, Inc
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+/*
+ * board/config.h - configuration options, board specific
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#include <configs/x86-common.h>
+
+#define CONFIG_SYS_MONITOR_LEN (1 << 20)
+#define CONFIG_BOARD_EARLY_INIT_F
+#define CONFIG_ARCH_EARLY_INIT_R
+#define CONFIG_ARCH_MISC_INIT
+
+#define CONFIG_PCI_PNP
+#define CONFIG_STD_DEVICES_SETTINGS "stdin=serial,usbkbd,vga\0" \
+ "stdout=serial,vga\0" \
+ "stderr=serial,vga\0"
+
+#define CONFIG_SCSI_DEV_LIST \
+ {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_VALLEYVIEW_SATA}, \
+ {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_VALLEYVIEW_SATA_ALT}
+
+#define VIDEO_IO_OFFSET 0
+#define CONFIG_X86EMU_RAW_IO
+
+#define CONFIG_ENV_SECT_SIZE 0x1000
+#define CONFIG_ENV_OFFSET 0x006ef000
+
+#endif /* __CONFIG_H */
diff --git a/include/configs/stm32f746-disco.h b/include/configs/stm32f746-disco.h
index e544a21..4391bff 100644
--- a/include/configs/stm32f746-disco.h
+++ b/include/configs/stm32f746-disco.h
@@ -24,13 +24,13 @@
* Configuration of the external SDRAM memory
*/
#define CONFIG_NR_DRAM_BANKS 1
-#define CONFIG_SYS_RAM_SIZE ((64 + 192) << 10)
+#define CONFIG_SYS_RAM_SIZE (8 * 1024 * 1024)
#define CONFIG_SYS_RAM_CS 1
#define CONFIG_SYS_RAM_FREQ_DIV 2
-#define CONFIG_SYS_RAM_BASE 0x20000000
+#define CONFIG_SYS_RAM_BASE 0xC0000000
#define CONFIG_SYS_SDRAM_BASE CONFIG_SYS_RAM_BASE
-#define CONFIG_SYS_LOAD_ADDR 0x20000000
-#define CONFIG_LOADADDR 0x20000000
+#define CONFIG_SYS_LOAD_ADDR 0xC0400000
+#define CONFIG_LOADADDR 0xC0400000
#define CONFIG_SYS_MAX_FLASH_SECT 8
#define CONFIG_SYS_MAX_FLASH_BANKS 1
@@ -42,7 +42,8 @@
#define CONFIG_STM32_FLASH
#define CONFIG_STM32X7_SERIAL
-#define CONFIG_SYS_CLK_FREQ 16*1000*1000 /* 180 MHz */
+#define CONFIG_STM32_HSE_HZ 25000000
+#define CONFIG_SYS_CLK_FREQ 200000000 /* 200 MHz */
#define CONFIG_SYS_HZ_CLOCK 1000000 /* Timer is clocked at 1MHz */
#define CONFIG_CMDLINE_TAG
diff --git a/include/configs/sun6i.h b/include/configs/sun6i.h
index 95ccc35..0625502 100644
--- a/include/configs/sun6i.h
+++ b/include/configs/sun6i.h
@@ -25,6 +25,7 @@
#define CONFIG_ARMV7_PSCI 1
#define CONFIG_ARMV7_PSCI_NR_CPUS 4
#define CONFIG_ARMV7_SECURE_BASE SUNXI_SRAM_B_BASE
+#define CONFIG_ARMV7_SECURE_MAX_SIZE (64 * 1024) /* 64 KB */
/*
* Include common sunxi configuration where most the settings are
diff --git a/include/configs/sun7i.h b/include/configs/sun7i.h
index 0dd2902..e9074d5 100644
--- a/include/configs/sun7i.h
+++ b/include/configs/sun7i.h
@@ -21,7 +21,9 @@
#define CONFIG_SUNXI_USB_PHYS 3
#define CONFIG_ARMV7_PSCI 1
+#define CONFIG_ARMV7_PSCI_NR_CPUS 2
#define CONFIG_ARMV7_SECURE_BASE SUNXI_SRAM_B_BASE
+#define CONFIG_ARMV7_SECURE_MAX_SIZE (64 * 1024) /* 64 KB */
/*
* Include common sunxi configuration where most the settings are
diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h
index 94275a7..6358901 100644
--- a/include/configs/sunxi-common.h
+++ b/include/configs/sunxi-common.h
@@ -137,6 +137,11 @@
#define CONFIG_SPL_NAND_SUPPORT 1
#endif
+#ifdef CONFIG_SPL_SPI_SUNXI
+#define CONFIG_SPL_SPI_FLASH_SUPPORT 1
+#define CONFIG_SYS_SPI_U_BOOT_OFFS 0x8000
+#endif
+
/* mmc config */
#ifdef CONFIG_MMC
#define CONFIG_GENERIC_MMC
diff --git a/include/configs/ti_armv7_keystone2.h b/include/configs/ti_armv7_keystone2.h
index 2ee26c4..4aa262e 100644
--- a/include/configs/ti_armv7_keystone2.h
+++ b/include/configs/ti_armv7_keystone2.h
@@ -89,6 +89,10 @@
#define CONFIG_SYS_SPI2
#define CONFIG_SYS_SPI2_BASE KS2_SPI2_BASE
#define CONFIG_SYS_SPI2_NUM_CS 4
+#ifdef CONFIG_SPL_BUILD
+#undef CONFIG_DM_SPI
+#undef CONFIG_DM_SPI_FLASH
+#endif
/* Network Configuration */
#define CONFIG_PHYLIB
diff --git a/include/configs/v38b.h b/include/configs/v38b.h
index 28c748d..5ebdf5b 100644
--- a/include/configs/v38b.h
+++ b/include/configs/v38b.h
@@ -55,7 +55,7 @@
#define SDRAM_TAPDELAY 0x10000000
/*
- * PCI - no suport
+ * PCI - no support
*/
#undef CONFIG_PCI
diff --git a/include/configs/vexpress_ca15_tc2.h b/include/configs/vexpress_ca15_tc2.h
index b509a9c..9583e8c 100644
--- a/include/configs/vexpress_ca15_tc2.h
+++ b/include/configs/vexpress_ca15_tc2.h
@@ -16,5 +16,6 @@
#define CONFIG_SYSFLAGS_ADDR 0x1c010030
#define CONFIG_SMP_PEN_ADDR CONFIG_SYSFLAGS_ADDR
+#define CONFIG_ARMV7_PSCI_NR_CPUS 4
#endif
diff --git a/include/dm/device.h b/include/dm/device.h
index f03bcd3..c825d47 100644
--- a/include/dm/device.h
+++ b/include/dm/device.h
@@ -42,7 +42,9 @@ struct driver_info;
#define DM_FLAG_BOUND (1 << 6)
/* Device name is allocated and should be freed on unbind() */
-#define DM_NAME_ALLOCED (1 << 7)
+#define DM_FLAG_NAME_ALLOCED (1 << 7)
+
+#define DM_FLAG_OF_PLATDATA (1 << 8)
/**
* struct udevice - An instance of a driver
@@ -467,6 +469,19 @@ fdt_addr_t dev_get_addr(struct udevice *dev);
void *dev_get_addr_ptr(struct udevice *dev);
/**
+ * dev_map_physmem() - Read device address from reg property of the
+ * device node and map the address into CPU address
+ * space.
+ *
+ * @dev: Pointer to device
+ * @size: size of the memory to map
+ *
+ * @return mapped address, or NULL if the device does not have reg
+ * property.
+ */
+void *dev_map_physmem(struct udevice *dev, unsigned long size);
+
+/**
* dev_get_addr_index() - Get the indexed reg property of a device
*
* @dev: Pointer to a device
@@ -540,7 +555,7 @@ int device_set_name(struct udevice *dev, const char *name);
/**
* device_set_name_alloced() - note that a device name is allocated
*
- * This sets the DM_NAME_ALLOCED flag for the device, so that when it is
+ * This sets the DM_FLAG_NAME_ALLOCED flag for the device, so that when it is
* unbound the name will be freed. This avoids memory leaks.
*
* @dev: Device to update
diff --git a/include/dm/platdata.h b/include/dm/platdata.h
index 6f4f001..488b2ab 100644
--- a/include/dm/platdata.h
+++ b/include/dm/platdata.h
@@ -22,10 +22,15 @@
*
* @name: Driver name
* @platdata: Driver-specific platform data
+ * @platdata_size: Size of platform data structure
+ * @flags: Platform data flags (DM_FLAG_...)
*/
struct driver_info {
const char *name;
const void *platdata;
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+ uint platdata_size;
+#endif
};
/**
diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h
index b768660..c5cdfc7 100644
--- a/include/dm/uclass-id.h
+++ b/include/dm/uclass-id.h
@@ -33,7 +33,6 @@ enum uclass_id {
UCLASS_CROS_EC, /* Chrome OS EC */
UCLASS_DISPLAY, /* Display (e.g. DisplayPort, HDMI) */
UCLASS_DMA, /* Direct Memory Access */
- UCLASS_RAM, /* RAM controller */
UCLASS_ETH, /* Ethernet device */
UCLASS_GPIO, /* Bank of general-purpose I/O pins */
UCLASS_I2C, /* I2C bus */
@@ -56,11 +55,12 @@ enum uclass_id {
UCLASS_PCH, /* x86 platform controller hub */
UCLASS_PCI, /* PCI bus */
UCLASS_PCI_GENERIC, /* Generic PCI bus device */
- UCLASS_PINCTRL, /* Pinctrl (pin muxing/configuration) device */
UCLASS_PINCONFIG, /* Pin configuration node device */
+ UCLASS_PINCTRL, /* Pinctrl (pin muxing/configuration) device */
UCLASS_PMIC, /* PMIC I/O device */
UCLASS_PWM, /* Pulse-width modulator */
UCLASS_PWRSEQ, /* Power sequence device */
+ UCLASS_RAM, /* RAM controller */
UCLASS_REGULATOR, /* Regulator device */
UCLASS_REMOTEPROC, /* Remote Processor device */
UCLASS_RESET, /* Reset controller device */
diff --git a/include/dt-structs.h b/include/dt-structs.h
new file mode 100644
index 0000000..e13afa6
--- /dev/null
+++ b/include/dt-structs.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2016 Google, Inc
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __DT_STTUCTS
+#define __DT_STTUCTS
+
+/* These structures may only be used in SPL */
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+struct phandle_2_cell {
+ const void *node;
+ int id;
+};
+#include <generated/dt-structs.h>
+#endif
+
+#endif
diff --git a/include/dwmmc.h b/include/dwmmc.h
index 335af51..6aebe96 100644
--- a/include/dwmmc.h
+++ b/include/dwmmc.h
@@ -224,9 +224,82 @@ static inline u8 dwmci_readb(struct dwmci_host *host, int reg)
return readb(host->ioaddr + reg);
}
+#ifdef CONFIG_BLK
+/**
+ * dwmci_setup_cfg() - Set up the configuration for DWMMC
+ *
+ * This is used to set up a DWMMC device when you are using CONFIG_BLK.
+ *
+ * This should be called from your MMC driver's probe() method once you have
+ * the information required.
+ *
+ * Generally your driver will have a platform data structure which holds both
+ * the configuration (struct mmc_config) and the MMC device info (struct mmc).
+ * For example:
+ *
+ * struct rockchip_mmc_plat {
+ * struct mmc_config cfg;
+ * struct mmc mmc;
+ * };
+ *
+ * ...
+ *
+ * Inside U_BOOT_DRIVER():
+ * .platdata_auto_alloc_size = sizeof(struct rockchip_mmc_plat),
+ *
+ * To access platform data:
+ * struct rockchip_mmc_plat *plat = dev_get_platdata(dev);
+ *
+ * See rockchip_dw_mmc.c for an example.
+ *
+ * @cfg: Configuration structure to fill in (generally &plat->mmc)
+ * @name: Device name (normally dev->name)
+ * @buswidth: Bus width (in bits, such as 4 or 8)
+ * @caps: Host capabilities (MMC_MODE_...)
+ * @max_clk: Maximum supported clock speed in HZ (e.g. 400000)
+ * @min_clk: Minimum supported clock speed in HZ (e.g. 150000000)
+ */
void dwmci_setup_cfg(struct mmc_config *cfg, const char *name, int buswidth,
uint caps, u32 max_clk, u32 min_clk);
+
+/**
+ * dwmci_bind() - Set up a new MMC block device
+ *
+ * This is used to set up a DWMMC block device when you are using CONFIG_BLK.
+ * It should be called from your driver's bind() method.
+ *
+ * See rockchip_dw_mmc.c for an example.
+ *
+ * @dev: Device to set up
+ * @mmc: Pointer to mmc structure (normally &plat->mmc)
+ * @cfg: Empty configuration structure (generally &plat->cfg). This is
+ * normally all zeroes at this point. The only purpose of passing
+ * this in is to set mmc->cfg to it.
+ * @return 0 if OK, -ve if the block device could not be created
+ */
int dwmci_bind(struct udevice *dev, struct mmc *mmc, struct mmc_config *cfg);
+#else
+/**
+ * add_dwmci() - Add a new DWMMC interface
+ *
+ * This is used when you are not using CONFIG_BLK. Convert your driver over!
+ *
+ * @host: DWMMC host structure
+ * @max_clk: Maximum supported clock speed in HZ (e.g. 400000)
+ * @min_clk: Minimum supported clock speed in HZ (e.g. 150000000)
+ * @return 0 if OK, -ve on error
+ */
int add_dwmci(struct dwmci_host *host, u32 max_clk, u32 min_clk);
+#endif /* !CONFIG_BLK */
+
+#ifdef CONFIG_DM_MMC_OPS
+/* Export the operations to drivers */
+int dwmci_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
+ struct mmc_data *data);
+int dwmci_set_ios(struct udevice *dev);
+int dwmci_probe(struct udevice *dev);
+extern const struct dm_mmc_ops dm_dwmci_ops;
+#endif
+
#endif /* __DWMMC_HW_H */
diff --git a/include/fdtdec.h b/include/fdtdec.h
index 05d70c4..151c590 100644
--- a/include/fdtdec.h
+++ b/include/fdtdec.h
@@ -134,13 +134,10 @@ enum fdt_compat_id {
COMPAT_SAMSUNG_S3C2440_I2C, /* Exynos I2C Controller */
COMPAT_SAMSUNG_EXYNOS5_SOUND, /* Exynos Sound */
COMPAT_WOLFSON_WM8994_CODEC, /* Wolfson WM8994 Sound Codec */
- COMPAT_GOOGLE_CROS_EC_KEYB, /* Google CROS_EC Keyboard */
COMPAT_SAMSUNG_EXYNOS_USB_PHY, /* Exynos phy controller for usb2.0 */
COMPAT_SAMSUNG_EXYNOS5_USB3_PHY,/* Exynos phy controller for usb3.0 */
COMPAT_SAMSUNG_EXYNOS_TMU, /* Exynos TMU */
- COMPAT_SAMSUNG_EXYNOS_FIMD, /* Exynos Display controller */
COMPAT_SAMSUNG_EXYNOS_MIPI_DSI, /* Exynos mipi dsi */
- COMPAT_SAMSUNG_EXYNOS5_DP, /* Exynos Display port controller */
COMPAT_SAMSUNG_EXYNOS_DWMMC, /* Exynos DWMMC controller */
COMPAT_SAMSUNG_EXYNOS_MMC, /* Exynos MMC controller */
COMPAT_MAXIM_MAX77686_PMIC, /* MAX77686 PMIC */
@@ -149,14 +146,9 @@ enum fdt_compat_id {
COMPAT_SAMSUNG_EXYNOS5_I2C, /* Exynos5 High Speed I2C Controller */
COMPAT_SAMSUNG_EXYNOS_SYSMMU, /* Exynos sysmmu */
COMPAT_INTEL_MICROCODE, /* Intel microcode update */
- COMPAT_INTEL_PANTHERPOINT_AHCI, /* Intel Pantherpoint AHCI */
- COMPAT_INTEL_MODEL_206AX, /* Intel Model 206AX CPU */
- COMPAT_INTEL_GMA, /* Intel Graphics Media Accelerator */
COMPAT_AMS_AS3722, /* AMS AS3722 PMIC */
- COMPAT_INTEL_ICH_SPI, /* Intel ICH7/9 SPI controller */
COMPAT_INTEL_QRK_MRC, /* Intel Quark MRC */
COMPAT_SOCIONEXT_XHCI, /* Socionext UniPhier xHCI */
- COMPAT_INTEL_PCH, /* Intel PCH */
COMPAT_ALTERA_SOCFPGA_DWMAC, /* SoCFPGA Ethernet controller */
COMPAT_ALTERA_SOCFPGA_DWMMC, /* SoCFPGA DWMMC controller */
COMPAT_ALTERA_SOCFPGA_DWC2USB, /* SoCFPGA DWC2 USB controller */
diff --git a/include/image.h b/include/image.h
index d788c26..2a5b560 100644
--- a/include/image.h
+++ b/include/image.h
@@ -123,62 +123,79 @@ struct lmb;
# define IMAGE_OF_SYSTEM_SETUP 0
#endif
+enum ih_category {
+ IH_ARCH,
+ IH_COMP,
+ IH_OS,
+ IH_TYPE,
+
+ IH_COUNT,
+};
+
/*
* Operating System Codes
*/
-#define IH_OS_INVALID 0 /* Invalid OS */
-#define IH_OS_OPENBSD 1 /* OpenBSD */
-#define IH_OS_NETBSD 2 /* NetBSD */
-#define IH_OS_FREEBSD 3 /* FreeBSD */
-#define IH_OS_4_4BSD 4 /* 4.4BSD */
-#define IH_OS_LINUX 5 /* Linux */
-#define IH_OS_SVR4 6 /* SVR4 */
-#define IH_OS_ESIX 7 /* Esix */
-#define IH_OS_SOLARIS 8 /* Solaris */
-#define IH_OS_IRIX 9 /* Irix */
-#define IH_OS_SCO 10 /* SCO */
-#define IH_OS_DELL 11 /* Dell */
-#define IH_OS_NCR 12 /* NCR */
-#define IH_OS_LYNXOS 13 /* LynxOS */
-#define IH_OS_VXWORKS 14 /* VxWorks */
-#define IH_OS_PSOS 15 /* pSOS */
-#define IH_OS_QNX 16 /* QNX */
-#define IH_OS_U_BOOT 17 /* Firmware */
-#define IH_OS_RTEMS 18 /* RTEMS */
-#define IH_OS_ARTOS 19 /* ARTOS */
-#define IH_OS_UNITY 20 /* Unity OS */
-#define IH_OS_INTEGRITY 21 /* INTEGRITY */
-#define IH_OS_OSE 22 /* OSE */
-#define IH_OS_PLAN9 23 /* Plan 9 */
-#define IH_OS_OPENRTOS 24 /* OpenRTOS */
+enum {
+ IH_OS_INVALID = 0, /* Invalid OS */
+ IH_OS_OPENBSD, /* OpenBSD */
+ IH_OS_NETBSD, /* NetBSD */
+ IH_OS_FREEBSD, /* FreeBSD */
+ IH_OS_4_4BSD, /* 4.4BSD */
+ IH_OS_LINUX, /* Linux */
+ IH_OS_SVR4, /* SVR4 */
+ IH_OS_ESIX, /* Esix */
+ IH_OS_SOLARIS, /* Solaris */
+ IH_OS_IRIX, /* Irix */
+ IH_OS_SCO, /* SCO */
+ IH_OS_DELL, /* Dell */
+ IH_OS_NCR, /* NCR */
+ IH_OS_LYNXOS, /* LynxOS */
+ IH_OS_VXWORKS, /* VxWorks */
+ IH_OS_PSOS, /* pSOS */
+ IH_OS_QNX, /* QNX */
+ IH_OS_U_BOOT, /* Firmware */
+ IH_OS_RTEMS, /* RTEMS */
+ IH_OS_ARTOS, /* ARTOS */
+ IH_OS_UNITY, /* Unity OS */
+ IH_OS_INTEGRITY, /* INTEGRITY */
+ IH_OS_OSE, /* OSE */
+ IH_OS_PLAN9, /* Plan 9 */
+ IH_OS_OPENRTOS, /* OpenRTOS */
+
+ IH_OS_COUNT,
+};
/*
* CPU Architecture Codes (supported by Linux)
*/
-#define IH_ARCH_INVALID 0 /* Invalid CPU */
-#define IH_ARCH_ALPHA 1 /* Alpha */
-#define IH_ARCH_ARM 2 /* ARM */
-#define IH_ARCH_I386 3 /* Intel x86 */
-#define IH_ARCH_IA64 4 /* IA64 */
-#define IH_ARCH_MIPS 5 /* MIPS */
-#define IH_ARCH_MIPS64 6 /* MIPS 64 Bit */
-#define IH_ARCH_PPC 7 /* PowerPC */
-#define IH_ARCH_S390 8 /* IBM S390 */
-#define IH_ARCH_SH 9 /* SuperH */
-#define IH_ARCH_SPARC 10 /* Sparc */
-#define IH_ARCH_SPARC64 11 /* Sparc 64 Bit */
-#define IH_ARCH_M68K 12 /* M68K */
-#define IH_ARCH_MICROBLAZE 14 /* MicroBlaze */
-#define IH_ARCH_NIOS2 15 /* Nios-II */
-#define IH_ARCH_BLACKFIN 16 /* Blackfin */
-#define IH_ARCH_AVR32 17 /* AVR32 */
-#define IH_ARCH_ST200 18 /* STMicroelectronics ST200 */
-#define IH_ARCH_SANDBOX 19 /* Sandbox architecture (test only) */
-#define IH_ARCH_NDS32 20 /* ANDES Technology - NDS32 */
-#define IH_ARCH_OPENRISC 21 /* OpenRISC 1000 */
-#define IH_ARCH_ARM64 22 /* ARM64 */
-#define IH_ARCH_ARC 23 /* Synopsys DesignWare ARC */
-#define IH_ARCH_X86_64 24 /* AMD x86_64, Intel and Via */
+enum {
+ IH_ARCH_INVALID = 0, /* Invalid CPU */
+ IH_ARCH_ALPHA, /* Alpha */
+ IH_ARCH_ARM, /* ARM */
+ IH_ARCH_I386, /* Intel x86 */
+ IH_ARCH_IA64, /* IA64 */
+ IH_ARCH_MIPS, /* MIPS */
+ IH_ARCH_MIPS64, /* MIPS 64 Bit */
+ IH_ARCH_PPC, /* PowerPC */
+ IH_ARCH_S390, /* IBM S390 */
+ IH_ARCH_SH, /* SuperH */
+ IH_ARCH_SPARC, /* Sparc */
+ IH_ARCH_SPARC64, /* Sparc 64 Bit */
+ IH_ARCH_M68K, /* M68K */
+ IH_ARCH_MICROBLAZE, /* MicroBlaze */
+ IH_ARCH_NIOS2, /* Nios-II */
+ IH_ARCH_BLACKFIN, /* Blackfin */
+ IH_ARCH_AVR32, /* AVR32 */
+ IH_ARCH_ST200, /* STMicroelectronics ST200 */
+ IH_ARCH_SANDBOX, /* Sandbox architecture (test only) */
+ IH_ARCH_NDS32, /* ANDES Technology - NDS32 */
+ IH_ARCH_OPENRISC, /* OpenRISC 1000 */
+ IH_ARCH_ARM64, /* ARM64 */
+ IH_ARCH_ARC, /* Synopsys DesignWare ARC */
+ IH_ARCH_X86_64, /* AMD x86_64, Intel and Via */
+
+ IH_ARCH_COUNT,
+};
/*
* Image Types
@@ -219,47 +236,54 @@ struct lmb;
* as command interpreter (=> Shell Scripts).
*/
-#define IH_TYPE_INVALID 0 /* Invalid Image */
-#define IH_TYPE_STANDALONE 1 /* Standalone Program */
-#define IH_TYPE_KERNEL 2 /* OS Kernel Image */
-#define IH_TYPE_RAMDISK 3 /* RAMDisk Image */
-#define IH_TYPE_MULTI 4 /* Multi-File Image */
-#define IH_TYPE_FIRMWARE 5 /* Firmware Image */
-#define IH_TYPE_SCRIPT 6 /* Script file */
-#define IH_TYPE_FILESYSTEM 7 /* Filesystem Image (any type) */
-#define IH_TYPE_FLATDT 8 /* Binary Flat Device Tree Blob */
-#define IH_TYPE_KWBIMAGE 9 /* Kirkwood Boot Image */
-#define IH_TYPE_IMXIMAGE 10 /* Freescale IMXBoot Image */
-#define IH_TYPE_UBLIMAGE 11 /* Davinci UBL Image */
-#define IH_TYPE_OMAPIMAGE 12 /* TI OMAP Config Header Image */
-#define IH_TYPE_AISIMAGE 13 /* TI Davinci AIS Image */
-#define IH_TYPE_KERNEL_NOLOAD 14 /* OS Kernel Image, can run from any load address */
-#define IH_TYPE_PBLIMAGE 15 /* Freescale PBL Boot Image */
-#define IH_TYPE_MXSIMAGE 16 /* Freescale MXSBoot Image */
-#define IH_TYPE_GPIMAGE 17 /* TI Keystone GPHeader Image */
-#define IH_TYPE_ATMELIMAGE 18 /* ATMEL ROM bootable Image */
-#define IH_TYPE_SOCFPGAIMAGE 19 /* Altera SOCFPGA Preloader */
-#define IH_TYPE_X86_SETUP 20 /* x86 setup.bin Image */
-#define IH_TYPE_LPC32XXIMAGE 21 /* x86 setup.bin Image */
-#define IH_TYPE_LOADABLE 22 /* A list of typeless images */
-#define IH_TYPE_RKIMAGE 23 /* Rockchip Boot Image */
-#define IH_TYPE_RKSD 24 /* Rockchip SD card */
-#define IH_TYPE_RKSPI 25 /* Rockchip SPI image */
-#define IH_TYPE_ZYNQIMAGE 26 /* Xilinx Zynq Boot Image */
-#define IH_TYPE_ZYNQMPIMAGE 27 /* Xilinx ZynqMP Boot Image */
-#define IH_TYPE_FPGA 28 /* FPGA Image */
-
-#define IH_TYPE_COUNT 29 /* Number of image types */
+enum {
+ IH_TYPE_INVALID = 0, /* Invalid Image */
+ IH_TYPE_STANDALONE, /* Standalone Program */
+ IH_TYPE_KERNEL, /* OS Kernel Image */
+ IH_TYPE_RAMDISK, /* RAMDisk Image */
+ IH_TYPE_MULTI, /* Multi-File Image */
+ IH_TYPE_FIRMWARE, /* Firmware Image */
+ IH_TYPE_SCRIPT, /* Script file */
+ IH_TYPE_FILESYSTEM, /* Filesystem Image (any type) */
+ IH_TYPE_FLATDT, /* Binary Flat Device Tree Blob */
+ IH_TYPE_KWBIMAGE, /* Kirkwood Boot Image */
+ IH_TYPE_IMXIMAGE, /* Freescale IMXBoot Image */
+ IH_TYPE_UBLIMAGE, /* Davinci UBL Image */
+ IH_TYPE_OMAPIMAGE, /* TI OMAP Config Header Image */
+ IH_TYPE_AISIMAGE, /* TI Davinci AIS Image */
+ /* OS Kernel Image, can run from any load address */
+ IH_TYPE_KERNEL_NOLOAD,
+ IH_TYPE_PBLIMAGE, /* Freescale PBL Boot Image */
+ IH_TYPE_MXSIMAGE, /* Freescale MXSBoot Image */
+ IH_TYPE_GPIMAGE, /* TI Keystone GPHeader Image */
+ IH_TYPE_ATMELIMAGE, /* ATMEL ROM bootable Image */
+ IH_TYPE_SOCFPGAIMAGE, /* Altera SOCFPGA Preloader */
+ IH_TYPE_X86_SETUP, /* x86 setup.bin Image */
+ IH_TYPE_LPC32XXIMAGE, /* x86 setup.bin Image */
+ IH_TYPE_LOADABLE, /* A list of typeless images */
+ IH_TYPE_RKIMAGE, /* Rockchip Boot Image */
+ IH_TYPE_RKSD, /* Rockchip SD card */
+ IH_TYPE_RKSPI, /* Rockchip SPI image */
+ IH_TYPE_ZYNQIMAGE, /* Xilinx Zynq Boot Image */
+ IH_TYPE_ZYNQMPIMAGE, /* Xilinx ZynqMP Boot Image */
+ IH_TYPE_FPGA, /* FPGA Image */
+
+ IH_TYPE_COUNT, /* Number of image types */
+};
/*
* Compression Types
*/
-#define IH_COMP_NONE 0 /* No Compression Used */
-#define IH_COMP_GZIP 1 /* gzip Compression Used */
-#define IH_COMP_BZIP2 2 /* bzip2 Compression Used */
-#define IH_COMP_LZMA 3 /* lzma Compression Used */
-#define IH_COMP_LZO 4 /* lzo Compression Used */
-#define IH_COMP_LZ4 5 /* lz4 Compression Used */
+enum {
+ IH_COMP_NONE = 0, /* No Compression Used */
+ IH_COMP_GZIP, /* gzip Compression Used */
+ IH_COMP_BZIP2, /* bzip2 Compression Used */
+ IH_COMP_LZMA, /* lzma Compression Used */
+ IH_COMP_LZO, /* lzo Compression Used */
+ IH_COMP_LZ4, /* lz4 Compression Used */
+
+ IH_COMP_COUNT,
+};
#define IH_MAGIC 0x27051956 /* Image Magic Number */
#define IH_NMLEN 32 /* Image Name Length */
@@ -454,6 +478,40 @@ const char *genimg_get_comp_name(uint8_t comp);
*/
const char *genimg_get_comp_short_name(uint8_t comp);
+/**
+ * genimg_get_cat_name() - Get the name of an item in a category
+ *
+ * @category: Category of item
+ * @id: Item ID
+ * @return name of item, or "Unknown ..." if unknown
+ */
+const char *genimg_get_cat_name(enum ih_category category, uint id);
+
+/**
+ * genimg_get_cat_short_name() - Get the short name of an item in a category
+ *
+ * @category: Category of item
+ * @id: Item ID
+ * @return short name of item, or "Unknown ..." if unknown
+ */
+const char *genimg_get_cat_short_name(enum ih_category category, uint id);
+
+/**
+ * genimg_get_cat_count() - Get the number of items in a category
+ *
+ * @category: Category to check
+ * @return the number of items in the category (IH_xxx_COUNT)
+ */
+int genimg_get_cat_count(enum ih_category category);
+
+/**
+ * genimg_get_cat_desc() - Get the description of a category
+ *
+ * @return the description of a category, e.g. "architecture". This
+ * effectively converts the enum to a string.
+ */
+const char *genimg_get_cat_desc(enum ih_category category);
+
int genimg_get_os_id(const char *name);
int genimg_get_arch_id(const char *name);
int genimg_get_type_id(const char *name);
@@ -1173,4 +1231,21 @@ void android_print_contents(const struct andr_img_hdr *hdr);
*/
int board_fit_config_name_match(const char *name);
+#ifdef CONFIG_SPL_FIT_IMAGE_POST_PROCESS
+/**
+ * board_fit_image_post_process() - Do any post-process on FIT binary data
+ *
+ * This is used to do any sort of image manipulation, verification, decryption
+ * etc. in a platform or board specific way. Obviously, anything done here would
+ * need to be comprehended in how the images were prepared before being injected
+ * into the FIT creation (i.e. the binary blobs would have been pre-processed
+ * before being added to the FIT image).
+ *
+ * @image: pointer to the image start pointer
+ * @size: pointer to the image size
+ * @return no return value (failure should be handled internally)
+ */
+void board_fit_image_post_process(void **p_image, size_t *p_size);
+#endif /* CONFIG_SPL_FIT_IMAGE_POST_PROCESS */
+
#endif /* __IMAGE_H__ */
diff --git a/include/linux/io.h b/include/linux/io.h
index 1b36a22..a104b7e 100644
--- a/include/linux/io.h
+++ b/include/linux/io.h
@@ -5,6 +5,22 @@
#ifndef _LINUX_IO_H
#define _LINUX_IO_H
+#include <linux/compiler.h>
+#include <linux/types.h>
#include <asm/io.h>
+#ifndef CONFIG_HAVE_ARCH_IOREMAP
+static inline void __iomem *ioremap(resource_size_t offset,
+ resource_size_t size)
+{
+ return (void __iomem *)(unsigned long)offset;
+}
+
+static inline void iounmap(void __iomem *addr)
+{
+}
+
+#define devm_ioremap(dev, offset, size) ioremap(offset, size)
+#endif
+
#endif /* _LINUX_IO_H */
diff --git a/include/linux/types.h b/include/linux/types.h
index 6f75be4..416fa66 100644
--- a/include/linux/types.h
+++ b/include/linux/types.h
@@ -124,6 +124,10 @@ typedef __UINT64_TYPE__ u_int64_t;
typedef __INT64_TYPE__ int64_t;
#endif
+#ifdef __KERNEL__
+typedef phys_addr_t resource_size_t;
+#endif
+
/*
* Below are truly Linux-specific types that should never collide with
* any application/library that wants linux/types.h.
diff --git a/include/mmc.h b/include/mmc.h
index f383925..8f309f1 100644
--- a/include/mmc.h
+++ b/include/mmc.h
@@ -323,6 +323,58 @@ struct mmc_data {
/* forward decl. */
struct mmc;
+#ifdef CONFIG_DM_MMC_OPS
+struct dm_mmc_ops {
+ /**
+ * send_cmd() - Send a command to the MMC device
+ *
+ * @dev: Device to receive the command
+ * @cmd: Command to send
+ * @data: Additional data to send/receive
+ * @return 0 if OK, -ve on error
+ */
+ int (*send_cmd)(struct udevice *dev, struct mmc_cmd *cmd,
+ struct mmc_data *data);
+
+ /**
+ * set_ios() - Set the I/O speed/width for an MMC device
+ *
+ * @dev: Device to update
+ * @return 0 if OK, -ve on error
+ */
+ int (*set_ios)(struct udevice *dev);
+
+ /**
+ * get_cd() - See whether a card is present
+ *
+ * @dev: Device to check
+ * @return 0 if not present, 1 if present, -ve on error
+ */
+ int (*get_cd)(struct udevice *dev);
+
+ /**
+ * get_wp() - See whether a card has write-protect enabled
+ *
+ * @dev: Device to check
+ * @return 0 if write-enabled, 1 if write-protected, -ve on error
+ */
+ int (*get_wp)(struct udevice *dev);
+};
+
+#define mmc_get_ops(dev) ((struct dm_mmc_ops *)(dev)->driver->ops)
+
+int dm_mmc_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
+ struct mmc_data *data);
+int dm_mmc_set_ios(struct udevice *dev);
+int dm_mmc_get_cd(struct udevice *dev);
+int dm_mmc_get_wp(struct udevice *dev);
+
+/* Transition functions for compatibility */
+int mmc_set_ios(struct mmc *mmc);
+int mmc_getcd(struct mmc *mmc);
+int mmc_getwp(struct mmc *mmc);
+
+#else
struct mmc_ops {
int (*send_cmd)(struct mmc *mmc,
struct mmc_cmd *cmd, struct mmc_data *data);
@@ -331,10 +383,13 @@ struct mmc_ops {
int (*getcd)(struct mmc *mmc);
int (*getwp)(struct mmc *mmc);
};
+#endif
struct mmc_config {
const char *name;
+#ifndef CONFIG_DM_MMC_OPS
const struct mmc_ops *ops;
+#endif
uint host_caps;
uint voltages;
uint f_min;
@@ -343,7 +398,12 @@ struct mmc_config {
unsigned char part_type;
};
-/* TODO struct mmc should be in mmc_private but it's hard to fix right now */
+/*
+ * With CONFIG_DM_MMC enabled, struct mmc can be accessed from the MMC device
+ * with mmc_get_mmc_dev().
+ *
+ * TODO struct mmc should be in mmc_private but it's hard to fix right now
+ */
struct mmc {
#ifndef CONFIG_BLK
struct list_head link;
@@ -446,10 +506,14 @@ void print_mmc_devices(char separator);
int get_mmc_num(void);
int mmc_hwpart_config(struct mmc *mmc, const struct mmc_hwpart_conf *conf,
enum mmc_hwpart_conf_mode mode);
+
+#ifndef CONFIG_DM_MMC_OPS
int mmc_getcd(struct mmc *mmc);
int board_mmc_getcd(struct mmc *mmc);
int mmc_getwp(struct mmc *mmc);
int board_mmc_getwp(struct mmc *mmc);
+#endif
+
int mmc_set_dsr(struct mmc *mmc, u16 val);
/* Function to change the size of boot partition and rpmb partitions */
int mmc_boot_partition_size_change(struct mmc *mmc, unsigned long bootsize,
diff --git a/include/net.h b/include/net.h
index 5ee5929..06320c6 100644
--- a/include/net.h
+++ b/include/net.h
@@ -238,7 +238,7 @@ int eth_getenv_enetaddr(const char *name, uchar *enetaddr);
int eth_setenv_enetaddr(const char *name, const uchar *enetaddr);
/**
- * eth_setenv_enetaddr_by_index() - set the MAC address envrionment variable
+ * eth_setenv_enetaddr_by_index() - set the MAC address environment variable
*
* This sets up an environment variable with the given MAC address (@enetaddr).
* The environment variable to be set is defined by <@base_name><@index>addr.
diff --git a/include/os.h b/include/os.h
index 954a48c..1782e50 100644
--- a/include/os.h
+++ b/include/os.h
@@ -287,6 +287,31 @@ int os_read_ram_buf(const char *fname);
int os_jump_to_image(const void *dest, int size);
/**
+ * os_find_u_boot() - Determine the path to U-Boot proper
+ *
+ * This function is intended to be called from within sandbox SPL. It uses
+ * a few heuristics to find U-Boot proper. Normally it is either in the same
+ * directory, or the directory above (since u-boot-spl is normally in an
+ * spl/ subdirectory when built).
+ *
+ * @fname: Place to put full path to U-Boot
+ * @maxlen: Maximum size of @fname
+ * @return 0 if OK, -NOSPC if the filename is too large, -ENOENT if not found
+ */
+int os_find_u_boot(char *fname, int maxlen);
+
+/**
+ * os_spl_to_uboot() - Run U-Boot proper
+ *
+ * When called from SPL, this runs U-Boot proper. The filename is obtained by
+ * calling os_find_u_boot().
+ *
+ * @fname: Full pathname to U-Boot executable
+ * @return 0 if OK, -ve on error
+ */
+int os_spl_to_uboot(const char *fname);
+
+/**
* Read the current system time
*
* This reads the current Local Time and places it into the provided
diff --git a/include/regmap.h b/include/regmap.h
index eccf770..1eed94e 100644
--- a/include/regmap.h
+++ b/include/regmap.h
@@ -57,6 +57,22 @@ int regmap_read(struct regmap *map, uint offset, uint *valp);
int regmap_init_mem(struct udevice *dev, struct regmap **mapp);
/**
+ * regmap_init_mem_platdata() - Set up a new memory register map for of-platdata
+ *
+ * This creates a new regmap with a list of regions passed in, rather than
+ * using the device tree. It only supports 32-bit machines.
+ *
+ * Use regmap_uninit() to free it.
+ *
+ * @dev: Device that uses this map
+ * @reg: List of address, size pairs
+ * @count: Number of pairs (e.g. 1 if the regmap has a single entry)
+ * @mapp: Returns allocated map
+ */
+int regmap_init_mem_platdata(struct udevice *dev, u32 *reg, int count,
+ struct regmap **mapp);
+
+/**
* regmap_get_range() - Obtain the base memory address of a regmap range
*
* @map: Regmap to query
diff --git a/include/sdhci.h b/include/sdhci.h
index e0f6667..c4d3b55 100644
--- a/include/sdhci.h
+++ b/include/sdhci.h
@@ -338,5 +338,85 @@ static inline u8 sdhci_readb(struct sdhci_host *host, int reg)
}
#endif
+#ifdef CONFIG_BLK
+/**
+ * sdhci_setup_cfg() - Set up the configuration for DWMMC
+ *
+ * This is used to set up an SDHCI device when you are using CONFIG_BLK.
+ *
+ * This should be called from your MMC driver's probe() method once you have
+ * the information required.
+ *
+ * Generally your driver will have a platform data structure which holds both
+ * the configuration (struct mmc_config) and the MMC device info (struct mmc).
+ * For example:
+ *
+ * struct msm_sdhc_plat {
+ * struct mmc_config cfg;
+ * struct mmc mmc;
+ * };
+ *
+ * ...
+ *
+ * Inside U_BOOT_DRIVER():
+ * .platdata_auto_alloc_size = sizeof(struct msm_sdhc_plat),
+ *
+ * To access platform data:
+ * struct msm_sdhc_plat *plat = dev_get_platdata(dev);
+ *
+ * See msm_sdhci.c for an example.
+ *
+ * @cfg: Configuration structure to fill in (generally &plat->mmc)
+ * @name: Device name (normally dev->name)
+ * @buswidth: Bus width (in bits, such as 4 or 8)
+ * @caps: Host capabilities (MMC_MODE_...)
+ * @max_clk: Maximum supported clock speed in HZ (0 for default)
+ * @min_clk: Minimum supported clock speed in HZ (0 for default)
+ * @version: Host controller version (generally read from the
+ * SDHCI_HOST_VERSION register)
+ * @quirks: Quick flags (SDHCI_QUIRK_...)
+ * @host_caps: Additional host capabilities (0 if none)
+ */
+int sdhci_setup_cfg(struct mmc_config *cfg, const char *name, int buswidth,
+ uint caps, u32 max_clk, u32 min_clk, uint version,
+ uint quirks, uint host_caps);
+
+/**
+ * sdhci_bind() - Set up a new MMC block device
+ *
+ * This is used to set up an SDHCI block device when you are using CONFIG_BLK.
+ * It should be called from your driver's bind() method.
+ *
+ * See msm_sdhci.c for an example.
+ *
+ * @dev: Device to set up
+ * @mmc: Pointer to mmc structure (normally &plat->mmc)
+ * @cfg: Empty configuration structure (generally &plat->cfg). This is
+ * normally all zeroes at this point. The only purpose of passing
+ * this in is to set mmc->cfg to it.
+ * @return 0 if OK, -ve if the block device could not be created
+ */
+int sdhci_bind(struct udevice *dev, struct mmc *mmc, struct mmc_config *cfg);
+#else
+
+/**
+ * add_sdhci() - Add a new SDHCI interface
+ *
+ * This is used when you are not using CONFIG_BLK. Convert your driver over!
+ *
+ * @host: SDHCI host structure
+ * @max_clk: Maximum supported clock speed in HZ (0 for default)
+ * @min_clk: Minimum supported clock speed in HZ (0 for default)
+ * @return 0 if OK, -ve on error
+ */
int add_sdhci(struct sdhci_host *host, u32 max_clk, u32 min_clk);
+#endif /* !CONFIG_BLK */
+
+#ifdef CONFIG_DM_MMC_OPS
+/* Export the operations to drivers */
+int sdhci_probe(struct udevice *dev);
+extern const struct dm_mmc_ops sdhci_ops;
+#else
+#endif
+
#endif /* __SDHCI_HW_H */
diff --git a/include/syscon.h b/include/syscon.h
index 4593b6e..34842aa 100644
--- a/include/syscon.h
+++ b/include/syscon.h
@@ -23,6 +23,17 @@ struct syscon_ops {
#define syscon_get_ops(dev) ((struct syscon_ops *)(dev)->driver->ops)
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+/*
+ * We don't support 64-bit machines. If they are so resource-contrained that
+ * they need to use OF_PLATDATA, something is horribly wrong with the
+ * education of our hardware engineers.
+ */
+struct syscon_base_platdata {
+ u32 reg[2];
+};
+#endif
+
/**
* syscon_get_regmap() - Get access to a register map
*
diff --git a/lib/Makefile b/lib/Makefile
index f48d901..f6a8ba1 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -48,11 +48,10 @@ obj-$(CONFIG_$(SPL_)SHA1) += sha1.o
obj-$(CONFIG_$(SPL_)SHA256) += sha256.o
obj-$(CONFIG_$(SPL_)OF_LIBFDT) += libfdt/
-ifdef CONFIG_SPL_OF_CONTROL
-obj-$(CONFIG_OF_LIBFDT) += libfdt/
-endif
+ifneq ($(CONFIG_SPL_BUILD)$(CONFIG_SPL_OF_PLATDATA),yy)
obj-$(CONFIG_$(SPL_)OF_CONTROL) += fdtdec_common.o
obj-$(CONFIG_$(SPL_)OF_CONTROL) += fdtdec.o
+endif
ifdef CONFIG_SPL_BUILD
obj-$(CONFIG_SPL_YMODEM_SUPPORT) += crc16.o
diff --git a/lib/fdtdec.c b/lib/fdtdec.c
index 0534c0b..c2bcbde 100644
--- a/lib/fdtdec.c
+++ b/lib/fdtdec.c
@@ -19,6 +19,11 @@ DECLARE_GLOBAL_DATA_PTR;
* Here are the type we know about. One day we might allow drivers to
* register. For now we just put them here. The COMPAT macro allows us to
* turn this into a sparse list later, and keeps the ID with the name.
+ *
+ * NOTE: This list is basically a TODO list for things that need to be
+ * converted to driver model. So don't add new things here unless there is a
+ * good reason why driver-model conversion is infeasible. Examples include
+ * things which are used before driver model is available.
*/
#define COMPAT(id, name) name
static const char * const compat_names[COMPAT_COUNT] = {
@@ -39,13 +44,10 @@ static const char * const compat_names[COMPAT_COUNT] = {
COMPAT(SAMSUNG_S3C2440_I2C, "samsung,s3c2440-i2c"),
COMPAT(SAMSUNG_EXYNOS5_SOUND, "samsung,exynos-sound"),
COMPAT(WOLFSON_WM8994_CODEC, "wolfson,wm8994-codec"),
- COMPAT(GOOGLE_CROS_EC_KEYB, "google,cros-ec-keyb"),
COMPAT(SAMSUNG_EXYNOS_USB_PHY, "samsung,exynos-usb-phy"),
COMPAT(SAMSUNG_EXYNOS5_USB3_PHY, "samsung,exynos5250-usb3-phy"),
COMPAT(SAMSUNG_EXYNOS_TMU, "samsung,exynos-tmu"),
- COMPAT(SAMSUNG_EXYNOS_FIMD, "samsung,exynos-fimd"),
COMPAT(SAMSUNG_EXYNOS_MIPI_DSI, "samsung,exynos-mipi-dsi"),
- COMPAT(SAMSUNG_EXYNOS5_DP, "samsung,exynos5-dp"),
COMPAT(SAMSUNG_EXYNOS_DWMMC, "samsung,exynos-dwmmc"),
COMPAT(SAMSUNG_EXYNOS_MMC, "samsung,exynos-mmc"),
COMPAT(MAXIM_MAX77686_PMIC, "maxim,max77686"),
@@ -54,20 +56,15 @@ static const char * const compat_names[COMPAT_COUNT] = {
COMPAT(SAMSUNG_EXYNOS5_I2C, "samsung,exynos5-hsi2c"),
COMPAT(SAMSUNG_EXYNOS_SYSMMU, "samsung,sysmmu-v3.3"),
COMPAT(INTEL_MICROCODE, "intel,microcode"),
- COMPAT(INTEL_PANTHERPOINT_AHCI, "intel,pantherpoint-ahci"),
- COMPAT(INTEL_MODEL_206AX, "intel,model-206ax"),
- COMPAT(INTEL_GMA, "intel,gma"),
COMPAT(AMS_AS3722, "ams,as3722"),
- COMPAT(INTEL_ICH_SPI, "intel,ich-spi"),
COMPAT(INTEL_QRK_MRC, "intel,quark-mrc"),
COMPAT(SOCIONEXT_XHCI, "socionext,uniphier-xhci"),
- COMPAT(COMPAT_INTEL_PCH, "intel,bd82x6x"),
COMPAT(ALTERA_SOCFPGA_DWMAC, "altr,socfpga-stmmac"),
COMPAT(ALTERA_SOCFPGA_DWMMC, "altr,socfpga-dw-mshc"),
COMPAT(ALTERA_SOCFPGA_DWC2USB, "snps,dwc2"),
- COMPAT(COMPAT_INTEL_BAYTRAIL_FSP, "intel,baytrail-fsp"),
- COMPAT(COMPAT_INTEL_BAYTRAIL_FSP_MDP, "intel,baytrail-fsp-mdp"),
- COMPAT(COMPAT_INTEL_IVYBRIDGE_FSP, "intel,ivybridge-fsp"),
+ COMPAT(INTEL_BAYTRAIL_FSP, "intel,baytrail-fsp"),
+ COMPAT(INTEL_BAYTRAIL_FSP_MDP, "intel,baytrail-fsp-mdp"),
+ COMPAT(INTEL_IVYBRIDGE_FSP, "intel,ivybridge-fsp"),
};
const char *fdtdec_get_compatible(enum fdt_compat_id id)
diff --git a/lib/hashtable.c b/lib/hashtable.c
index 02b4105..435e2a6 100644
--- a/lib/hashtable.c
+++ b/lib/hashtable.c
@@ -822,7 +822,7 @@ int himport_r(struct hsearch_data *htab,
* (CONFIG_ENV_SIZE). This heuristics will result in
* unreasonably large numbers (and thus memory footprint) for
* big flash environments (>8,000 entries for 64 KB
- * envrionment size), so we clip it to a reasonable value.
+ * environment size), so we clip it to a reasonable value.
* On the other hand we need to add some more entries for free
* space when importing very small buffers. Both boundaries can
* be overwritten in the board config file if needed.
diff --git a/lib/libfdt/libfdt.swig b/lib/libfdt/libfdt.swig
new file mode 100644
index 0000000..14f583d
--- /dev/null
+++ b/lib/libfdt/libfdt.swig
@@ -0,0 +1,89 @@
+/* File: libfdt.i */
+%module libfdt
+
+%{
+#define SWIG_FILE_WITH_INIT
+#include "libfdt.h"
+%}
+
+%pythoncode %{
+def Raise(errnum):
+ raise ValueError('Error %s' % fdt_strerror(errnum))
+
+def Name(fdt, offset):
+ name, len = fdt_get_name(fdt, offset)
+ return name
+
+def String(fdt, offset):
+ offset = fdt32_to_cpu(offset)
+ name = fdt_string(fdt, offset)
+ return name
+
+def swap32(x):
+ return (((x << 24) & 0xFF000000) |
+ ((x << 8) & 0x00FF0000) |
+ ((x >> 8) & 0x0000FF00) |
+ ((x >> 24) & 0x000000FF))
+
+def fdt32_to_cpu(x):
+ return swap32(x)
+
+def Data(prop):
+ set_prop(prop)
+ return get_prop_data()
+%}
+
+%include "typemaps.i"
+%include "cstring.i"
+
+%typemap(in) void* = char*;
+
+typedef int fdt32_t;
+
+struct fdt_property {
+ fdt32_t tag;
+ fdt32_t len;
+ fdt32_t nameoff;
+ char data[0];
+};
+
+/*
+ * This is a work-around since I'm not sure of a better way to copy out the
+ * contents of a string. This is used in dtoc/GetProps(). The intent is to
+ * pass in a pointer to a property and access the data field at the end of
+ * it. Ideally the Data() function above would be able to do this directly,
+ * but I'm not sure how to do that.
+ */
+#pragma SWIG nowarn=454
+%inline %{
+ static struct fdt_property *cur_prop;
+
+ void set_prop(struct fdt_property *prop) {
+ cur_prop = prop;
+ }
+%}
+
+%cstring_output_allocate_size(char **s, int *sz, free(*$1));
+%inline %{
+ void get_prop_data(char **s, int *sz) {
+ *sz = fdt32_to_cpu(cur_prop->len);
+ *s = (char *)malloc(*sz);
+ if (!*s)
+ *sz = 0;
+ else
+ memcpy(*s, cur_prop + 1, *sz);
+ }
+%}
+
+const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int checklen);
+int fdt_path_offset(const void *fdt, const char *path);
+int fdt_first_property_offset(const void *fdt, int nodeoffset);
+int fdt_next_property_offset(const void *fdt, int offset);
+const char *fdt_strerror(int errval);
+const struct fdt_property *fdt_get_property_by_offset(const void *fdt,
+ int offset,
+ int *OUTPUT);
+const char *fdt_get_name(const void *fdt, int nodeoffset, int *OUTPUT);
+const char *fdt_string(const void *fdt, int stroffset);
+int fdt_first_subnode(const void *fdt, int offset);
+int fdt_next_subnode(const void *fdt, int offset);
diff --git a/lib/libfdt/setup.py b/lib/libfdt/setup.py
new file mode 100644
index 0000000..62e7bcc
--- /dev/null
+++ b/lib/libfdt/setup.py
@@ -0,0 +1,38 @@
+#!/usr/bin/env python
+
+"""
+setup.py file for SWIG libfdt
+"""
+
+from distutils.core import setup, Extension
+import os
+import sys
+
+# Don't cross-compile - always use the host compiler.
+del os.environ['CROSS_COMPILE']
+del os.environ['CC']
+
+progname = sys.argv[0]
+cflags = sys.argv[1]
+files = sys.argv[2:]
+
+if cflags:
+ cflags = [flag for flag in cflags.split(' ') if flag]
+else:
+ cflags = None
+
+libfdt_module = Extension(
+ '_libfdt',
+ sources = files,
+ extra_compile_args = cflags
+)
+
+sys.argv = [progname, '--quiet', 'build_ext', '--inplace']
+
+setup (name = 'libfdt',
+ version = '0.1',
+ author = "SWIG Docs",
+ description = """Simple swig libfdt from docs""",
+ ext_modules = [libfdt_module],
+ py_modules = ["libfdt"],
+ )
diff --git a/lib/libfdt/test_libfdt.py b/lib/libfdt/test_libfdt.py
new file mode 100644
index 0000000..14d0da4
--- /dev/null
+++ b/lib/libfdt/test_libfdt.py
@@ -0,0 +1,14 @@
+#!/usr/bin/python
+
+import os
+import sys
+
+our_path = os.path.dirname(os.path.realpath(__file__))
+sys.path.append(os.path.join(our_path, '../../b/sandbox_spl/tools'))
+
+import libfdt
+
+with open('b/sandbox_spl/u-boot.dtb') as fd:
+ fdt = fd.read()
+
+print libfdt.fdt_path_offset(fdt, "/aliases")
diff --git a/lib/tiny-printf.c b/lib/tiny-printf.c
index b334f05..1aa43ab 100644
--- a/lib/tiny-printf.c
+++ b/lib/tiny-printf.c
@@ -185,3 +185,12 @@ int snprintf(char *buf, size_t size, const char *fmt, ...)
return ret;
}
+
+void __assert_fail(const char *assertion, const char *file, unsigned line,
+ const char *function)
+{
+ /* This will not return */
+ printf("%s:%u: %s: Assertion `%s' failed.", file, line, function,
+ assertion);
+ hang();
+}
diff --git a/net/eth_internal.h b/net/eth_internal.h
index 6e4753c..a14b208 100644
--- a/net/eth_internal.h
+++ b/net/eth_internal.h
@@ -13,7 +13,7 @@
void eth_common_init(void);
/**
- * eth_setenv_enetaddr_by_index() - set the MAC address envrionment variable
+ * eth_setenv_enetaddr_by_index() - set the MAC address environment variable
*
* This sets up an environment variable with the given MAC address (@enetaddr).
* The environment variable to be set is defined by <@base_name><@index>addr.
diff --git a/post/cpu/ppc4xx/ether.c b/post/cpu/ppc4xx/ether.c
index 4c9a39b..8a4c56b 100644
--- a/post/cpu/ppc4xx/ether.c
+++ b/post/cpu/ppc4xx/ether.c
@@ -21,7 +21,7 @@
* CONFIG_SYS_POST_ETH_LOOPS - Number of test loops. Each loop
* is tested with a different frame length. Starting with
* MAX_PACKET_LENGTH and going down to MIN_PACKET_LENGTH.
- * Defaults to 10 and can be overriden in the board config header.
+ * Defaults to 10 and can be overridden in the board config header.
*/
#include <post.h>
diff --git a/scripts/Makefile.host b/scripts/Makefile.host
index bff8b5b..763a699 100644
--- a/scripts/Makefile.host
+++ b/scripts/Makefile.host
@@ -28,12 +28,16 @@ __hostprogs := $(sort $(hostprogs-y) $(hostprogs-m))
# C code
# Executables compiled from a single .c file
host-csingle := $(foreach m,$(__hostprogs), \
- $(if $($(m)-objs)$($(m)-cxxobjs),,$(m)))
+ $(if $($(m)-objs)$($(m)-cxxobjs)$($(m)-sharedobjs),,$(m)))
# C executables linked based on several .o files
host-cmulti := $(foreach m,$(__hostprogs),\
$(if $($(m)-cxxobjs),,$(if $($(m)-objs),$(m))))
+# Shared object libraries
+host-shared := $(foreach m,$(__hostprogs),\
+ $(if $($(m)-sharedobjs),$(m))))
+
# Object (.o) files compiled from .c files
host-cobjs := $(sort $(foreach m,$(__hostprogs),$($(m)-objs)))
@@ -59,6 +63,7 @@ host-cmulti := $(addprefix $(obj)/,$(host-cmulti))
host-cobjs := $(addprefix $(obj)/,$(host-cobjs))
host-cxxmulti := $(addprefix $(obj)/,$(host-cxxmulti))
host-cxxobjs := $(addprefix $(obj)/,$(host-cxxobjs))
+host-shared := $(addprefix $(obj)/,$(host-shared))
host-objdirs := $(addprefix $(obj)/,$(host-objdirs))
obj-dirs += $(host-objdirs)
@@ -128,4 +133,4 @@ $(host-cxxobjs): $(obj)/%.o: $(src)/%.cc FORCE
$(call if_changed_dep,host-cxxobjs)
targets += $(host-csingle) $(host-cmulti) $(host-cobjs)\
- $(host-cxxmulti) $(host-cxxobjs)
+ $(host-cxxmulti) $(host-cxxobjs) $(host-shared)
diff --git a/scripts/Makefile.spl b/scripts/Makefile.spl
index 0997fd9..3ba9742 100644
--- a/scripts/Makefile.spl
+++ b/scripts/Makefile.spl
@@ -45,6 +45,7 @@ LDFLAGS_FINAL += --gc-sections
# FIX ME
cpp_flags := $(KBUILD_CPPFLAGS) $(PLATFORM_CPPFLAGS) $(UBOOTINCLUDE) \
$(NOSTDINC_FLAGS)
+c_flags := $(KBUILD_CFLAGS) $(cpp_flags)
HAVE_VENDOR_COMMON_LIB = $(if $(wildcard $(srctree)/board/$(VENDOR)/common/Makefile),y,n)
@@ -76,6 +77,9 @@ endif
u-boot-spl-init := $(head-y)
u-boot-spl-main := $(libs-y)
+ifdef CONFIG_SPL_OF_PLATDATA
+u-boot-spl-platdata := $(obj)/dts/dt-platdata.o
+endif
# Linker Script
ifdef CONFIG_SPL_LDSCRIPT
@@ -169,7 +173,7 @@ cmd_cat = cat $(filter-out $(PHONY), $^) > $@
quiet_cmd_copy = COPY $@
cmd_copy = cp $< $@
-ifeq ($(CONFIG_SPL_OF_CONTROL)$(CONFIG_OF_SEPARATE),yy)
+ifeq ($(CONFIG_SPL_OF_CONTROL)$(CONFIG_OF_SEPARATE)$(CONFIG_SPL_OF_PLATDATA),yy)
$(obj)/$(SPL_BIN)-dtb.bin: $(obj)/$(SPL_BIN)-nodtb.bin $(obj)/$(SPL_BIN)-pad.bin \
$(obj)/$(SPL_BIN).dtb FORCE
$(call if_changed,cat)
@@ -207,6 +211,32 @@ cmd_cpp_cfg = $(CPP) -Wp,-MD,$(depfile) $(cpp_flags) $(LDPPFLAGS) -ansi \
$(obj)/$(SPL_BIN).cfg: include/config.h FORCE
$(call if_changed,cpp_cfg)
+pythonpath = PYTHONPATH=tools
+
+quiet_cmd_dtocc = DTOC C $@
+cmd_dtocc = $(pythonpath) $(srctree)/tools/dtoc/dtoc -d $(obj)/$(SPL_BIN).dtb -o $@ platdata
+
+quiet_cmd_dtoch = DTOC H $@
+cmd_dtoch = $(pythonpath) $(srctree)/tools/dtoc/dtoc -d $(obj)/$(SPL_BIN).dtb -o $@ struct
+
+quiet_cmd_plat = PLAT $@
+cmd_plat = $(CC) $(c_flags) -c $< -o $@
+
+$(obj)/dts/dt-platdata.o: $(obj)/dts/dt-platdata.c include/generated/dt-structs.h
+ $(call if_changed,plat)
+
+PHONY += dts_dir
+dts_dir:
+ $(shell [ -d $(obj)/dts ] || mkdir -p $(obj)/dts)
+
+include/generated/dt-structs.h: $(obj)/$(SPL_BIN).dtb dts_dir dtoc
+ $(call if_changed,dtoch)
+
+$(obj)/dts/dt-platdata.c: $(obj)/$(SPL_BIN).dtb dts_dir dtoc
+ $(call if_changed,dtocc)
+
+dtoc: #$(objtree)/tools/_libfdt.so
+
ifdef CONFIG_SAMSUNG
ifdef CONFIG_VAR_SIZE_SPL
VAR_SIZE_PARAM = --vs
@@ -241,19 +271,24 @@ cmd_mksunxiboot = $(objtree)/tools/mksunxiboot $< $@
$(obj)/sunxi-spl.bin: $(obj)/$(SPL_BIN).bin FORCE
$(call if_changed,mksunxiboot)
-quiet_cmd_u-boot-spl = LD $@
- cmd_u-boot-spl = (cd $(obj) && $(LD) $(LDFLAGS) $(LDFLAGS_$(@F)) \
+# Rule to link u-boot-spl
+# May be overridden by arch/$(ARCH)/config.mk
+quiet_cmd_u-boot-spl ?= LD $@
+ cmd_u-boot-spl ?= (cd $(obj) && $(LD) $(LDFLAGS) $(LDFLAGS_$(@F)) \
$(patsubst $(obj)/%,%,$(u-boot-spl-init)) --start-group \
- $(patsubst $(obj)/%,%,$(u-boot-spl-main)) --end-group \
+ $(patsubst $(obj)/%,%,$(u-boot-spl-main)) \
+ $(patsubst $(obj)/%,%,$(u-boot-spl-platdata)) \
+ --end-group \
$(PLATFORM_LIBS) -Map $(SPL_BIN).map -o $(SPL_BIN))
-$(obj)/$(SPL_BIN): $(u-boot-spl-init) $(u-boot-spl-main) $(obj)/u-boot-spl.lds FORCE
+$(obj)/$(SPL_BIN): $(u-boot-spl-platdata) $(u-boot-spl-init) \
+ $(u-boot-spl-main) $(obj)/u-boot-spl.lds FORCE
$(call if_changed,u-boot-spl)
$(sort $(u-boot-spl-init) $(u-boot-spl-main)): $(u-boot-spl-dirs) ;
PHONY += $(u-boot-spl-dirs)
-$(u-boot-spl-dirs):
+$(u-boot-spl-dirs): $(u-boot-spl-platdata)
$(Q)$(MAKE) $(build)=$@
quiet_cmd_cpp_lds = LDS $@
diff --git a/test/README b/test/README
new file mode 100644
index 0000000..ee55972
--- /dev/null
+++ b/test/README
@@ -0,0 +1,92 @@
+Testing in U-Boot
+=================
+
+U-Boot has a large amount of code. This file describes how this code is
+tested and what tests you should write when adding a new feature.
+
+
+Running tests
+-------------
+
+To run most tests on sandbox, type this:
+
+ test/run
+
+in the U-Boot directory. Note that only the pytest suite is run using this
+comment.
+
+
+Sandbox
+-------
+U-Boot can be built as a user-space application (e.g. for Linux). This
+allows test to be executed without needing target hardware. The 'sandbox'
+target provides this feature and it is widely used in tests.
+
+
+Pytest Suite
+------------
+
+Many tests are available using the pytest suite, in test/py. This can run
+either on sandbox or on real hardware. It relies on the U-Boot console to
+inject test commands and check the result. It is slower to run than C code,
+but provides the ability to unify lots of test and summarise their results.
+
+You can run the tests on sandbox with:
+
+ ./test/py/test.py --bd sandbox --build
+
+This will produce HTML output in build-sandbox/test-log.html
+
+See test/py/README.md for more information about the pytest suite.
+
+
+tbot
+----
+
+Tbot provides a way to execute tests on target hardware. It is intended for
+trying out both U-Boot and Linux (and potentially other software) on a
+number of boards automatically. It can be used to create a continuous test
+environment. See tools/tbot/README for more information.
+
+
+Ad-hoc tests
+------------
+
+There are several ad-hoc tests which run outside the pytest environment:
+
+ test/fs - File system test (shell script)
+ test/image - FIT and lagacy image tests (shell script and Python)
+ test/stdint - A test that stdint.h can be used in U-Boot (shell script)
+ trace - Test for the tracing feature (shell script)
+
+The above should be converted to run as part of the pytest suite.
+
+
+When to write tests
+-------------------
+
+If you add code to U-Boot without a test you are taking a risk. Even if you
+perform thorough manual testing at the time of submission, it may break when
+future changes are made to U-Boot. It may even break when applied to mainline,
+if other changes interact with it. A good mindset is that untested code
+probably doesn't work and should be deleted.
+
+You can assume that the Pytest suite will be run before patches are accepted
+to mainline, so this provides protection against future breakage.
+
+On the other hand there is quite a bit of code that is not covered with tests,
+or is covered sparingly. So here are some suggestions:
+
+- If you are adding a new uclass, add a sandbox driver and a test that uses it
+- If you are modifying code covered by an existing test, add a new test case
+ to cover your changes
+- If the code you are modifying has not tests, consider writing one. Even a
+ very basic test is useful, and may be picked up and enhanced by others. It
+ is much easier to add onto a test - writing a new large test can seem
+ daunting to most contributors.
+
+
+Future work
+-----------
+
+Converting existing shell scripts into pytest tests.
diff --git a/test/py/conftest.py b/test/py/conftest.py
index 449f98b..5b3a923 100644
--- a/test/py/conftest.py
+++ b/test/py/conftest.py
@@ -179,6 +179,7 @@ def pytest_configure(config):
ubconfig.board_type = board_type
ubconfig.board_identity = board_identity
ubconfig.gdbserver = gdbserver
+ ubconfig.dtb = build_dir + '/arch/sandbox/dts/test.dtb'
env_vars = (
'board_type',
@@ -192,7 +193,7 @@ def pytest_configure(config):
for v in env_vars:
os.environ['U_BOOT_' + v.upper()] = getattr(ubconfig, v)
- if board_type == 'sandbox':
+ if board_type.startswith('sandbox'):
import u_boot_console_sandbox
console = u_boot_console_sandbox.ConsoleSandbox(log, ubconfig)
else:
diff --git a/test/py/multiplexed_log.py b/test/py/multiplexed_log.py
index 68917eb..35a32fb 100644
--- a/test/py/multiplexed_log.py
+++ b/test/py/multiplexed_log.py
@@ -101,6 +101,7 @@ class RunAndLog(object):
self.logfile = logfile
self.name = name
self.chained_file = chained_file
+ self.output = None
def close(self):
"""Clean up any resources managed by this object."""
@@ -109,6 +110,9 @@ class RunAndLog(object):
def run(self, cmd, cwd=None, ignore_errors=False):
"""Run a command as a sub-process, and log the results.
+ The output is available at self.output which can be useful if there is
+ an exception.
+
Args:
cmd: The command to execute.
cwd: The directory to run the command in. Can be None to use the
@@ -119,7 +123,7 @@ class RunAndLog(object):
raised if such problems occur.
Returns:
- Nothing.
+ The output as a string.
"""
msg = '+' + ' '.join(cmd) + '\n'
@@ -159,8 +163,12 @@ class RunAndLog(object):
self.logfile.write(self, output)
if self.chained_file:
self.chained_file.write(output)
+
+ # Store the output so it can be accessed if we raise an exception.
+ self.output = output
if exception:
raise exception
+ return output
class SectionCtxMgr(object):
"""A context manager for Python's "with" statement, which allows a certain
diff --git a/test/py/tests/test_ofplatdata.py b/test/py/tests/test_ofplatdata.py
new file mode 100644
index 0000000..457c405
--- /dev/null
+++ b/test/py/tests/test_ofplatdata.py
@@ -0,0 +1,42 @@
+# Copyright (c) 2016 Google, Inc
+#
+# SPDX-License-Identifier: GPL-2.0+
+
+import pytest
+
+OF_PLATDATA_OUTPUT = '''
+of-platdata probe:
+bool 1
+byte 05
+bytearray 06 00 00
+int 1
+intarray 2 3 4 0
+longbytearray 09 0a 0b 0c 0d 0e 0f 10 11
+string message
+stringarray "multi-word" "message" ""
+of-platdata probe:
+bool 0
+byte 08
+bytearray 01 23 34
+int 3
+intarray 5 0 0 0
+longbytearray 09 00 00 00 00 00 00 00 00
+string message2
+stringarray "another" "multi-word" "message"
+of-platdata probe:
+bool 0
+byte 00
+bytearray 00 00 00
+int 0
+intarray 0 0 0 0
+longbytearray 00 00 00 00 00 00 00 00 00
+string <NULL>
+stringarray "one" "" ""
+'''
+
+@pytest.mark.buildconfigspec('spl_of_platdata')
+def test_ofplatdata(u_boot_console):
+ """Test that of-platdata can be generated and used in sandbox"""
+ cons = u_boot_console
+ output = cons.get_spawn_output().replace('\r', '')
+ assert OF_PLATDATA_OUTPUT in output
diff --git a/test/py/tests/test_vboot.py b/test/py/tests/test_vboot.py
new file mode 100644
index 0000000..c779895
--- /dev/null
+++ b/test/py/tests/test_vboot.py
@@ -0,0 +1,185 @@
+# Copyright (c) 2013, Google Inc.
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+# U-Boot Verified Boot Test
+
+"""
+This tests verified boot in the following ways:
+
+For image verification:
+- Create FIT (unsigned) with mkimage
+- Check that verification shows that no keys are verified
+- Sign image
+- Check that verification shows that a key is now verified
+
+For configuration verification:
+- Corrupt signature and check for failure
+- Create FIT (with unsigned configuration) with mkimage
+- Check that image veriication works
+- Sign the FIT and mark the key as 'required' for verification
+- Check that image verification works
+- Corrupt the signature
+- Check that image verification no-longer works
+
+Tests run with both SHA1 and SHA256 hashing.
+"""
+
+import pytest
+import sys
+import u_boot_utils as util
+
+@pytest.mark.buildconfigspec('fit_signature')
+def test_vboot(u_boot_console):
+ """Test verified boot signing with mkimage and verification with 'bootm'.
+
+ This works using sandbox only as it needs to update the device tree used
+ by U-Boot to hold public keys from the signing process.
+
+ The SHA1 and SHA256 tests are combined into a single test since the
+ key-generation process is quite slow and we want to avoid doing it twice.
+ """
+ def dtc(dts):
+ """Run the device-tree compiler to compile a .dts file
+
+ The output file will be the same as the input file but with a .dtb
+ extension.
+
+ Args:
+ dts: Device tree file to compile.
+ """
+ dtb = dts.replace('.dts', '.dtb')
+ util.cmd(cons, 'dtc %s %s%s -O dtb '
+ '-o %s%s' % (dtc_args, datadir, dts, tmpdir, dtb))
+
+ def run_bootm(test_type, expect_string):
+ """Run a 'bootm' command U-Boot.
+
+ This always starts a fresh U-Boot instance since the device tree may
+ contain a new public key.
+
+ Args:
+ test_type: A string identifying the test type
+ expect_string: A string which is expected in the output
+ """
+ cons.cleanup_spawn()
+ cons.ensure_spawned()
+ cons.log.action('%s: Test Verified Boot Run: %s' % (algo, test_type))
+ output = cons.run_command_list(
+ ['sb load hostfs - 100 %stest.fit' % tmpdir,
+ 'fdt addr 100',
+ 'bootm 100'])
+ assert(expect_string in output)
+
+ def make_fit(its):
+ """Make a new FIT from the .its source file
+
+ This runs 'mkimage -f' to create a new FIT.
+
+ Args:
+ its: Filename containing .its source
+ """
+ util.run_and_log(cons, [mkimage, '-D', dtc_args, '-f',
+ '%s%s' % (datadir, its), fit])
+
+ def sign_fit():
+ """Sign the FIT
+
+ Signs the FIT and writes the signature into it. It also writes the
+ public key into the dtb.
+ """
+ cons.log.action('%s: Sign images' % algo)
+ util.run_and_log(cons, [mkimage, '-F', '-k', tmpdir, '-K', dtb,
+ '-r', fit])
+
+ def test_with_algo(sha):
+ """Test verified boot with the given hash algorithm
+
+ This is the main part of the test code. The same procedure is followed
+ for both hashing algorithms.
+
+ Args:
+ sha: Either 'sha1' or 'sha256', to select the algorithm to use
+ """
+ global algo
+
+ algo = sha
+
+ # Compile our device tree files for kernel and U-Boot
+ dtc('sandbox-kernel.dts')
+ dtc('sandbox-u-boot.dts')
+
+ # Build the FIT, but don't sign anything yet
+ cons.log.action('%s: Test FIT with signed images' % algo)
+ make_fit('sign-images-%s.its' % algo)
+ run_bootm('unsigned images', 'dev-')
+
+ # Sign images with our dev keys
+ sign_fit()
+ run_bootm('signed images', 'dev+')
+
+ # Create a fresh .dtb without the public keys
+ dtc('sandbox-u-boot.dts')
+
+ cons.log.action('%s: Test FIT with signed configuration' % algo)
+ make_fit('sign-configs-%s.its' % algo)
+ run_bootm('unsigned config', '%s+ OK' % algo)
+
+ # Sign images with our dev keys
+ sign_fit()
+ run_bootm('signed config', 'dev+')
+
+ cons.log.action('%s: Check signed config on the host' % algo)
+
+ util.run_and_log(cons, [fit_check_sign, '-f', fit, '-k', tmpdir,
+ '-k', dtb])
+
+ # Increment the first byte of the signature, which should cause failure
+ sig = util.cmd(cons, 'fdtget -t bx %s %s value' % (fit, sig_node))
+ byte_list = sig.split()
+ byte = int(byte_list[0], 16)
+ byte_list = ['%x' % (byte + 1)] + byte_list[1:]
+ sig = ' '.join(byte_list)
+ util.cmd(cons, 'fdtput -t bx %s %s value %s' % (fit, sig_node, sig))
+
+ run_bootm('Signed config with bad hash', 'Bad Data Hash')
+
+ cons.log.action('%s: Check bad config on the host' % algo)
+ util.run_and_log_expect_exception(cons, [fit_check_sign, '-f', fit,
+ '-k', dtb], 1, 'Failed to verify required signature')
+
+ cons = u_boot_console
+ tmpdir = cons.config.result_dir + '/'
+ tmp = tmpdir + 'vboot.tmp'
+ datadir = 'test/py/tests/vboot/'
+ fit = '%stest.fit' % tmpdir
+ mkimage = cons.config.build_dir + '/tools/mkimage'
+ fit_check_sign = cons.config.build_dir + '/tools/fit_check_sign'
+ dtc_args = '-I dts -O dtb -i %s' % tmpdir
+ dtb = '%ssandbox-u-boot.dtb' % tmpdir
+ sig_node = '/configurations/conf@1/signature@1'
+
+ # Create an RSA key pair
+ public_exponent = 65537
+ util.cmd(cons, 'openssl genpkey -algorithm RSA -out %sdev.key '
+ '-pkeyopt rsa_keygen_bits:2048 '
+ '-pkeyopt rsa_keygen_pubexp:%d '
+ '2>/dev/null' % (tmpdir, public_exponent))
+
+ # Create a certificate containing the public key
+ util.cmd(cons, 'openssl req -batch -new -x509 -key %sdev.key -out '
+ '%sdev.crt' % (tmpdir, tmpdir))
+
+ # Create a number kernel image with zeroes
+ with open('%stest-kernel.bin' % tmpdir, 'w') as fd:
+ fd.write(5000 * chr(0))
+
+ try:
+ # We need to use our own device tree file. Remember to restore it
+ # afterwards.
+ old_dtb = cons.config.dtb
+ cons.config.dtb = dtb
+ test_with_algo('sha1')
+ test_with_algo('sha256')
+ finally:
+ cons.config.dtb = old_dtb
diff --git a/test/vboot/sandbox-kernel.dts b/test/py/tests/vboot/sandbox-kernel.dts
index a1e853c..a1e853c 100644
--- a/test/vboot/sandbox-kernel.dts
+++ b/test/py/tests/vboot/sandbox-kernel.dts
diff --git a/test/vboot/sandbox-u-boot.dts b/test/py/tests/vboot/sandbox-u-boot.dts
index 63f8f40..63f8f40 100644
--- a/test/vboot/sandbox-u-boot.dts
+++ b/test/py/tests/vboot/sandbox-u-boot.dts
diff --git a/test/vboot/sign-configs-sha1.its b/test/py/tests/vboot/sign-configs-sha1.its
index db2ed79..db2ed79 100644
--- a/test/vboot/sign-configs-sha1.its
+++ b/test/py/tests/vboot/sign-configs-sha1.its
diff --git a/test/vboot/sign-configs-sha256.its b/test/py/tests/vboot/sign-configs-sha256.its
index 1b3432e..1b3432e 100644
--- a/test/vboot/sign-configs-sha256.its
+++ b/test/py/tests/vboot/sign-configs-sha256.its
diff --git a/test/vboot/sign-images-sha1.its b/test/py/tests/vboot/sign-images-sha1.its
index f69326a..f69326a 100644
--- a/test/vboot/sign-images-sha1.its
+++ b/test/py/tests/vboot/sign-images-sha1.its
diff --git a/test/vboot/sign-images-sha256.its b/test/py/tests/vboot/sign-images-sha256.its
index e6aa9fc..e6aa9fc 100644
--- a/test/vboot/sign-images-sha256.its
+++ b/test/py/tests/vboot/sign-images-sha256.its
diff --git a/test/py/u_boot_console_base.py b/test/py/u_boot_console_base.py
index 815fa64..4606ad4 100644
--- a/test/py/u_boot_console_base.py
+++ b/test/py/u_boot_console_base.py
@@ -216,6 +216,22 @@ class ConsoleBase(object):
self.cleanup_spawn()
raise
+ def run_command_list(self, cmds):
+ """Run a list of commands.
+
+ This is a helper function to call run_command() with default arguments
+ for each command in a list.
+
+ Args:
+ cmd: List of commands (each a string)
+ Returns:
+ Combined output of all commands, as a string
+ """
+ output = ''
+ for cmd in cmds:
+ output += self.run_command(cmd)
+ return output
+
def ctrlc(self):
"""Send a CTRL-C character to U-Boot.
@@ -329,7 +345,7 @@ class ConsoleBase(object):
m = self.p.expect([pattern_u_boot_spl_signon] +
self.bad_patterns)
if m != 0:
- raise Exception('Bad pattern found on console: ' +
+ raise Exception('Bad pattern found on SPL console: ' +
self.bad_pattern_ids[m - 1])
m = self.p.expect([pattern_u_boot_main_signon] + self.bad_patterns)
if m != 0:
@@ -377,6 +393,16 @@ class ConsoleBase(object):
pass
self.p = None
+ def get_spawn_output(self):
+ """Return the start-up output from U-Boot
+
+ Returns:
+ The output produced by ensure_spawed(), as a string.
+ """
+ if self.p:
+ return self.p.get_expect_output()
+ return None
+
def validate_version_string_in_text(self, text):
"""Assert that a command's output includes the U-Boot signon message.
diff --git a/test/py/u_boot_console_sandbox.py b/test/py/u_boot_console_sandbox.py
index 04654ae..647e1f8 100644
--- a/test/py/u_boot_console_sandbox.py
+++ b/test/py/u_boot_console_sandbox.py
@@ -39,14 +39,18 @@ class ConsoleSandbox(ConsoleBase):
A u_boot_spawn.Spawn object that is attached to U-Boot.
"""
+ bcfg = self.config.buildconfig
+ config_spl = bcfg.get('config_spl', 'n') == 'y'
+ fname = '/spl/u-boot-spl' if config_spl else '/u-boot'
+ print fname
cmd = []
if self.config.gdbserver:
cmd += ['gdbserver', self.config.gdbserver]
cmd += [
- self.config.build_dir + '/u-boot',
+ self.config.build_dir + fname,
'-v',
'-d',
- self.config.build_dir + '/arch/sandbox/dts/test.dtb'
+ self.config.dtb
]
return Spawn(cmd, cwd=self.config.source_dir)
diff --git a/test/py/u_boot_spawn.py b/test/py/u_boot_spawn.py
index a5f4a8e..3a0fbfa 100644
--- a/test/py/u_boot_spawn.py
+++ b/test/py/u_boot_spawn.py
@@ -18,6 +18,9 @@ class Timeout(Exception):
class Spawn(object):
"""Represents the stdio of a freshly created sub-process. Commands may be
sent to the process, and responses waited for.
+
+ Members:
+ output: accumulated output from expect()
"""
def __init__(self, args, cwd=None):
@@ -34,10 +37,16 @@ class Spawn(object):
self.waited = False
self.buf = ''
+ self.output = ''
self.logfile_read = None
self.before = ''
self.after = ''
self.timeout = None
+ # http://stackoverflow.com/questions/7857352/python-regex-to-match-vt100-escape-sequences
+ # Note that re.I doesn't seem to work with this regex (or perhaps the
+ # version of Python in Ubuntu 14.04), hence the inclusion of a-z inside
+ # [] instead.
+ self.re_vt100 = re.compile('(\x1b\[|\x9b)[^@-_a-z]*[@-_a-z]|\x1b[@-_a-z]')
(self.pid, self.fd) = pty.fork()
if self.pid == 0:
@@ -149,6 +158,7 @@ class Spawn(object):
posafter = earliest_m.end()
self.before = self.buf[:pos]
self.after = self.buf[pos:posafter]
+ self.output += self.buf[:posafter]
self.buf = self.buf[posafter:]
return earliest_pi
tnow_s = time.time()
@@ -168,6 +178,10 @@ class Spawn(object):
if self.logfile_read:
self.logfile_read.write(c)
self.buf += c
+ # count=0 is supposed to be the default, which indicates
+ # unlimited substitutions, but in practice the version of
+ # Python in Ubuntu 14.04 appears to default to count=2!
+ self.buf = self.re_vt100.sub('', self.buf, count=1000000)
finally:
if self.logfile_read:
self.logfile_read.flush()
@@ -189,3 +203,11 @@ class Spawn(object):
if not self.isalive():
break
time.sleep(0.1)
+
+ def get_expect_output(self):
+ """Return the output read by expect()
+
+ Returns:
+ The output processed by expect(), as a string.
+ """
+ return self.output
diff --git a/test/py/u_boot_utils.py b/test/py/u_boot_utils.py
index 6a6b2ec..e358c58 100644
--- a/test/py/u_boot_utils.py
+++ b/test/py/u_boot_utils.py
@@ -165,12 +165,47 @@ def run_and_log(u_boot_console, cmd, ignore_errors=False):
problems occur.
Returns:
- Nothing.
+ The output as a string.
"""
runner = u_boot_console.log.get_runner(cmd[0], sys.stdout)
- runner.run(cmd, ignore_errors=ignore_errors)
+ output = runner.run(cmd, ignore_errors=ignore_errors)
runner.close()
+ return output
+
+def cmd(u_boot_console, cmd_str):
+ """Run a single command string and log its output.
+
+ Args:
+ u_boot_console: A console connection to U-Boot.
+ cmd: The command to run, as a string.
+
+ Returns:
+ The output as a string.
+ """
+ return run_and_log(u_boot_console, cmd_str.split())
+
+def run_and_log_expect_exception(u_boot_console, cmd, retcode, msg):
+ """Run a command which is expected to fail.
+
+ This runs a command and checks that it fails with the expected return code
+ and exception method. If not, an exception is raised.
+
+ Args:
+ u_boot_console: A console connection to U-Boot.
+ cmd: The command to run, as an array of argv[].
+ retcode: Expected non-zero return code from the command.
+ msg: String which should be contained within the command's output.
+ """
+ try:
+ runner = u_boot_console.log.get_runner(cmd[0], sys.stdout)
+ runner.run(cmd)
+ except Exception as e:
+ assert(msg in runner.output)
+ else:
+ raise Exception('Expected exception, but not raised')
+ finally:
+ runner.close()
ram_base = None
def find_ram_base(u_boot_console):
@@ -201,7 +236,7 @@ def find_ram_base(u_boot_console):
with u_boot_console.log.section('find_ram_base'):
response = u_boot_console.run_command('bdinfo')
for l in response.split('\n'):
- if '-> start' in l:
+ if '-> start' in l or 'memstart =' in l:
ram_base = int(l.split('=')[1].strip(), 16)
break
if ram_base is None:
diff --git a/test/run b/test/run
new file mode 100755
index 0000000..a6dcf8f
--- /dev/null
+++ b/test/run
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+# Run all tests
+./test/py/test.py --bd sandbox --build
diff --git a/test/vboot/.gitignore b/test/vboot/.gitignore
deleted file mode 100644
index 4631242..0000000
--- a/test/vboot/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-/*.dtb
-/test.fit
-/dev-keys
diff --git a/test/vboot/vboot_test.sh b/test/vboot/vboot_test.sh
deleted file mode 100755
index 6d7abb8..0000000
--- a/test/vboot/vboot_test.sh
+++ /dev/null
@@ -1,151 +0,0 @@
-#!/bin/bash
-#
-# Copyright (c) 2013, Google Inc.
-#
-# Simple Verified Boot Test Script
-#
-# SPDX-License-Identifier: GPL-2.0+
-
-set -e
-
-# Run U-Boot and report the result
-# Args:
-# $1: Test message
-run_uboot() {
- echo -n "Test Verified Boot Run: $1: "
- ${uboot} -d sandbox-u-boot.dtb >${tmp} -c '
-sb load hostfs - 100 test.fit;
-fdt addr 100;
-bootm 100;
-reset'
- if ! grep -q "$2" ${tmp}; then
- echo
- echo "Verified boot key check failed, output follows:"
- cat ${tmp}
- false
- else
- echo "OK"
- fi
-}
-
-echo "Simple Verified Boot Test"
-echo "========================="
-echo
-echo "Please see doc/uImage.FIT/verified-boot.txt for more information"
-echo
-
-err=0
-tmp=/tmp/vboot_test.$$
-
-dir=$(dirname $0)
-
-if [ -z ${O} ]; then
- O=.
-fi
-O=$(readlink -f ${O})
-
-dtc="-I dts -O dtb -p 2000"
-uboot="${O}/u-boot"
-mkimage="${O}/tools/mkimage"
-fit_check_sign="${O}/tools/fit_check_sign"
-keys="${dir}/dev-keys"
-echo ${mkimage} -D "${dtc}"
-
-echo "Build keys"
-mkdir -p ${keys}
-
-PUBLIC_EXPONENT=${1}
-
-if [ -z "${PUBLIC_EXPONENT}" ]; then
- PUBLIC_EXPONENT=65537
-fi
-
-# Create an RSA key pair
-openssl genpkey -algorithm RSA -out ${keys}/dev.key \
- -pkeyopt rsa_keygen_bits:2048 \
- -pkeyopt rsa_keygen_pubexp:${PUBLIC_EXPONENT} 2>/dev/null
-
-# Create a certificate containing the public key
-openssl req -batch -new -x509 -key ${keys}/dev.key -out ${keys}/dev.crt
-
-pushd ${dir} >/dev/null
-
-function do_test {
- echo do $sha test
- # Compile our device tree files for kernel and U-Boot
- dtc -p 0x1000 sandbox-kernel.dts -O dtb -o sandbox-kernel.dtb
- dtc -p 0x1000 sandbox-u-boot.dts -O dtb -o sandbox-u-boot.dtb
-
- # Create a number kernel image with zeroes
- head -c 5000 /dev/zero >test-kernel.bin
-
- # Build the FIT, but don't sign anything yet
- echo Build FIT with signed images
- ${mkimage} -D "${dtc}" -f sign-images-$sha.its test.fit >${tmp}
-
- run_uboot "unsigned signatures:" "dev-"
-
- # Sign images with our dev keys
- echo Sign images
- ${mkimage} -D "${dtc}" -F -k dev-keys -K sandbox-u-boot.dtb \
- -r test.fit >${tmp}
-
- run_uboot "signed images" "dev+"
-
-
- # Create a fresh .dtb without the public keys
- dtc -p 0x1000 sandbox-u-boot.dts -O dtb -o sandbox-u-boot.dtb
-
- echo Build FIT with signed configuration
- ${mkimage} -D "${dtc}" -f sign-configs-$sha.its test.fit >${tmp}
-
- run_uboot "unsigned config" $sha"+ OK"
-
- # Sign images with our dev keys
- echo Sign images
- ${mkimage} -D "${dtc}" -F -k dev-keys -K sandbox-u-boot.dtb \
- -r test.fit >${tmp}
-
- run_uboot "signed config" "dev+"
-
- echo check signed config on the host
- if ! ${fit_check_sign} -f test.fit -k sandbox-u-boot.dtb >${tmp}; then
- echo
- echo "Verified boot key check on host failed, output follows:"
- cat ${tmp}
- false
- else
- if ! grep -q "dev+" ${tmp}; then
- echo
- echo "Verified boot key check failed, output follows:"
- cat ${tmp}
- false
- else
- echo "OK"
- fi
- fi
-
- run_uboot "signed config" "dev+"
-
- # Increment the first byte of the signature, which should cause failure
- sig=$(fdtget -t bx test.fit /configurations/conf@1/signature@1 value)
- newbyte=$(printf %x $((0x${sig:0:2} + 1)))
- sig="${newbyte} ${sig:2}"
- fdtput -t bx test.fit /configurations/conf@1/signature@1 value ${sig}
-
- run_uboot "signed config with bad hash" "Bad Data Hash"
-}
-
-sha=sha1
-do_test
-sha=sha256
-do_test
-
-popd >/dev/null
-
-echo
-if ${ok}; then
- echo "Test passed"
-else
- echo "Test failed"
-fi
diff --git a/tools/Makefile b/tools/Makefile
index 63355aa..421414b 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -76,8 +76,6 @@ dumpimage-mkimage-objs := aisimage.o \
lib/fdtdec.o \
fit_common.o \
fit_image.o \
- gpimage.o \
- gpimage-common.o \
common/image-fit.o \
image-host.o \
common/image.o \
@@ -100,6 +98,8 @@ dumpimage-mkimage-objs := aisimage.o \
zynqimage.o \
zynqmpimage.o \
$(LIBFDT_OBJS) \
+ gpimage.o \
+ gpimage-common.o \
$(RSA_OBJS-y)
dumpimage-objs := $(dumpimage-mkimage-objs) dumpimage.o
@@ -107,6 +107,20 @@ mkimage-objs := $(dumpimage-mkimage-objs) mkimage.o
fit_info-objs := $(dumpimage-mkimage-objs) fit_info.o
fit_check_sign-objs := $(dumpimage-mkimage-objs) fit_check_sign.o
+# Build a libfdt Python module if swig is available
+# Use 'sudo apt-get install swig libpython-dev' to enable this
+hostprogs-$(CONFIG_SPL_OF_PLATDATA) += \
+ $(if $(shell which swig),_libfdt.so)
+_libfdt.so-sharedobjs += $(LIBFDT_OBJS)
+libfdt:
+
+tools/_libfdt.so: $(patsubst %.o,%.c,$(LIBFDT_OBJS)) tools/libfdt_wrap.c
+ python $(srctree)/lib/libfdt/setup.py "$(_hostc_flags)" $^
+ mv _libfdt.so $@
+
+tools/libfdt_wrap.c: $(srctree)/lib/libfdt/libfdt.swig
+ swig -python -o $@ $<
+
# TODO(sjg@chromium.org): Is this correct on Mac OS?
ifneq ($(CONFIG_MX23)$(CONFIG_MX28),)
diff --git a/tools/dtoc/.gitignore b/tools/dtoc/.gitignore
new file mode 100644
index 0000000..0d20b64
--- /dev/null
+++ b/tools/dtoc/.gitignore
@@ -0,0 +1 @@
+*.pyc
diff --git a/tools/dtoc/dtoc b/tools/dtoc/dtoc
new file mode 120000
index 0000000..896ca44
--- /dev/null
+++ b/tools/dtoc/dtoc
@@ -0,0 +1 @@
+dtoc.py \ No newline at end of file
diff --git a/tools/dtoc/dtoc.py b/tools/dtoc/dtoc.py
new file mode 100755
index 0000000..ec80abe
--- /dev/null
+++ b/tools/dtoc/dtoc.py
@@ -0,0 +1,394 @@
+#!/usr/bin/python
+#
+# Copyright (C) 2016 Google, Inc
+# Written by Simon Glass <sjg@chromium.org>
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+import copy
+from optparse import OptionError, OptionParser
+import os
+import sys
+
+import fdt_util
+
+# Bring in the patman libraries
+our_path = os.path.dirname(os.path.realpath(__file__))
+sys.path.append(os.path.join(our_path, '../patman'))
+
+# Bring in either the normal fdt library (which relies on libfdt) or the
+# fallback one (which uses fdtget and is slower). Both provide the same
+# interfface for this file to use.
+try:
+ from fdt import Fdt
+ import fdt
+ have_libfdt = True
+except ImportError:
+ have_libfdt = False
+ from fdt_fallback import Fdt
+ import fdt_fallback as fdt
+
+import struct
+
+# When we see these properties we ignore them - i.e. do not create a structure member
+PROP_IGNORE_LIST = [
+ '#address-cells',
+ '#gpio-cells',
+ '#size-cells',
+ 'compatible',
+ 'linux,phandle',
+ "status",
+ 'phandle',
+ 'u-boot,dm-pre-reloc',
+]
+
+# C type declarations for the tyues we support
+TYPE_NAMES = {
+ fdt_util.TYPE_INT: 'fdt32_t',
+ fdt_util.TYPE_BYTE: 'unsigned char',
+ fdt_util.TYPE_STRING: 'const char *',
+ fdt_util.TYPE_BOOL: 'bool',
+};
+
+STRUCT_PREFIX = 'dtd_'
+VAL_PREFIX = 'dtv_'
+
+def Conv_name_to_c(name):
+ """Convert a device-tree name to a C identifier
+
+ Args:
+ name: Name to convert
+ Return:
+ String containing the C version of this name
+ """
+ str = name.replace('@', '_at_')
+ str = str.replace('-', '_')
+ str = str.replace(',', '_')
+ str = str.replace('/', '__')
+ return str
+
+def TabTo(num_tabs, str):
+ if len(str) >= num_tabs * 8:
+ return str + ' '
+ return str + '\t' * (num_tabs - len(str) / 8)
+
+class DtbPlatdata:
+ """Provide a means to convert device tree binary data to platform data
+
+ The output of this process is C structures which can be used in space-
+ constrained encvironments where the ~3KB code overhead of device tree
+ code is not affordable.
+
+ Properties:
+ fdt: Fdt object, referencing the device tree
+ _dtb_fname: Filename of the input device tree binary file
+ _valid_nodes: A list of Node object with compatible strings
+ _options: Command-line options
+ _phandle_node: A dict of nodes indexed by phandle number (1, 2...)
+ _outfile: The current output file (sys.stdout or a real file)
+ _lines: Stashed list of output lines for outputting in the future
+ _phandle_node: A dict of Nodes indexed by phandle (an integer)
+ """
+ def __init__(self, dtb_fname, options):
+ self._dtb_fname = dtb_fname
+ self._valid_nodes = None
+ self._options = options
+ self._phandle_node = {}
+ self._outfile = None
+ self._lines = []
+
+ def SetupOutput(self, fname):
+ """Set up the output destination
+
+ Once this is done, future calls to self.Out() will output to this
+ file.
+
+ Args:
+ fname: Filename to send output to, or '-' for stdout
+ """
+ if fname == '-':
+ self._outfile = sys.stdout
+ else:
+ self._outfile = open(fname, 'w')
+
+ def Out(self, str):
+ """Output a string to the output file
+
+ Args:
+ str: String to output
+ """
+ self._outfile.write(str)
+
+ def Buf(self, str):
+ """Buffer up a string to send later
+
+ Args:
+ str: String to add to our 'buffer' list
+ """
+ self._lines.append(str)
+
+ def GetBuf(self):
+ """Get the contents of the output buffer, and clear it
+
+ Returns:
+ The output buffer, which is then cleared for future use
+ """
+ lines = self._lines
+ self._lines = []
+ return lines
+
+ def GetValue(self, type, value):
+ """Get a value as a C expression
+
+ For integers this returns a byte-swapped (little-endian) hex string
+ For bytes this returns a hex string, e.g. 0x12
+ For strings this returns a literal string enclosed in quotes
+ For booleans this return 'true'
+
+ Args:
+ type: Data type (fdt_util)
+ value: Data value, as a string of bytes
+ """
+ if type == fdt_util.TYPE_INT:
+ return '%#x' % fdt_util.fdt32_to_cpu(value)
+ elif type == fdt_util.TYPE_BYTE:
+ return '%#x' % ord(value[0])
+ elif type == fdt_util.TYPE_STRING:
+ return '"%s"' % value
+ elif type == fdt_util.TYPE_BOOL:
+ return 'true'
+
+ def GetCompatName(self, node):
+ """Get a node's first compatible string as a C identifier
+
+ Args:
+ node: Node object to check
+ Return:
+ C identifier for the first compatible string
+ """
+ compat = node.props['compatible'].value
+ if type(compat) == list:
+ compat = compat[0]
+ return Conv_name_to_c(compat)
+
+ def ScanDtb(self):
+ """Scan the device tree to obtain a tree of notes and properties
+
+ Once this is done, self.fdt.GetRoot() can be called to obtain the
+ device tree root node, and progress from there.
+ """
+ self.fdt = Fdt(self._dtb_fname)
+ self.fdt.Scan()
+
+ def ScanTree(self):
+ """Scan the device tree for useful information
+
+ This fills in the following properties:
+ _phandle_node: A dict of Nodes indexed by phandle (an integer)
+ _valid_nodes: A list of nodes we wish to consider include in the
+ platform data
+ """
+ node_list = []
+ self._phandle_node = {}
+ for node in self.fdt.GetRoot().subnodes:
+ if 'compatible' in node.props:
+ status = node.props.get('status')
+ if (not options.include_disabled and not status or
+ status.value != 'disabled'):
+ node_list.append(node)
+ phandle_prop = node.props.get('phandle')
+ if phandle_prop:
+ phandle = phandle_prop.GetPhandle()
+ self._phandle_node[phandle] = node
+
+ self._valid_nodes = node_list
+
+ def IsPhandle(self, prop):
+ """Check if a node contains phandles
+
+ We have no reliable way of detecting whether a node uses a phandle
+ or not. As an interim measure, use a list of known property names.
+
+ Args:
+ prop: Prop object to check
+ Return:
+ True if the object value contains phandles, else False
+ """
+ if prop.name in ['clocks']:
+ return True
+ return False
+
+ def ScanStructs(self):
+ """Scan the device tree building up the C structures we will use.
+
+ Build a dict keyed by C struct name containing a dict of Prop
+ object for each struct field (keyed by property name). Where the
+ same struct appears multiple times, try to use the 'widest'
+ property, i.e. the one with a type which can express all others.
+
+ Once the widest property is determined, all other properties are
+ updated to match that width.
+ """
+ structs = {}
+ for node in self._valid_nodes:
+ node_name = self.GetCompatName(node)
+ fields = {}
+
+ # Get a list of all the valid properties in this node.
+ for name, prop in node.props.iteritems():
+ if name not in PROP_IGNORE_LIST and name[0] != '#':
+ fields[name] = copy.deepcopy(prop)
+
+ # If we've seen this node_name before, update the existing struct.
+ if node_name in structs:
+ struct = structs[node_name]
+ for name, prop in fields.iteritems():
+ oldprop = struct.get(name)
+ if oldprop:
+ oldprop.Widen(prop)
+ else:
+ struct[name] = prop
+
+ # Otherwise store this as a new struct.
+ else:
+ structs[node_name] = fields
+
+ upto = 0
+ for node in self._valid_nodes:
+ node_name = self.GetCompatName(node)
+ struct = structs[node_name]
+ for name, prop in node.props.iteritems():
+ if name not in PROP_IGNORE_LIST and name[0] != '#':
+ prop.Widen(struct[name])
+ upto += 1
+ return structs
+
+ def GenerateStructs(self, structs):
+ """Generate struct defintions for the platform data
+
+ This writes out the body of a header file consisting of structure
+ definitions for node in self._valid_nodes. See the documentation in
+ README.of-plat for more information.
+ """
+ self.Out('#include <stdbool.h>\n')
+ self.Out('#include <libfdt.h>\n')
+
+ # Output the struct definition
+ for name in sorted(structs):
+ self.Out('struct %s%s {\n' % (STRUCT_PREFIX, name));
+ for pname in sorted(structs[name]):
+ prop = structs[name][pname]
+ if self.IsPhandle(prop):
+ # For phandles, include a reference to the target
+ self.Out('\t%s%s[%d]' % (TabTo(2, 'struct phandle_2_cell'),
+ Conv_name_to_c(prop.name),
+ len(prop.value) / 2))
+ else:
+ ptype = TYPE_NAMES[prop.type]
+ self.Out('\t%s%s' % (TabTo(2, ptype),
+ Conv_name_to_c(prop.name)))
+ if type(prop.value) == list:
+ self.Out('[%d]' % len(prop.value))
+ self.Out(';\n')
+ self.Out('};\n')
+
+ def GenerateTables(self):
+ """Generate device defintions for the platform data
+
+ This writes out C platform data initialisation data and
+ U_BOOT_DEVICE() declarations for each valid node. See the
+ documentation in README.of-plat for more information.
+ """
+ self.Out('#include <common.h>\n')
+ self.Out('#include <dm.h>\n')
+ self.Out('#include <dt-structs.h>\n')
+ self.Out('\n')
+ node_txt_list = []
+ for node in self._valid_nodes:
+ struct_name = self.GetCompatName(node)
+ var_name = Conv_name_to_c(node.name)
+ self.Buf('static struct %s%s %s%s = {\n' %
+ (STRUCT_PREFIX, struct_name, VAL_PREFIX, var_name))
+ for pname, prop in node.props.iteritems():
+ if pname in PROP_IGNORE_LIST or pname[0] == '#':
+ continue
+ ptype = TYPE_NAMES[prop.type]
+ member_name = Conv_name_to_c(prop.name)
+ self.Buf('\t%s= ' % TabTo(3, '.' + member_name))
+
+ # Special handling for lists
+ if type(prop.value) == list:
+ self.Buf('{')
+ vals = []
+ # For phandles, output a reference to the platform data
+ # of the target node.
+ if self.IsPhandle(prop):
+ # Process the list as pairs of (phandle, id)
+ it = iter(prop.value)
+ for phandle_cell, id_cell in zip(it, it):
+ phandle = fdt_util.fdt32_to_cpu(phandle_cell)
+ id = fdt_util.fdt32_to_cpu(id_cell)
+ target_node = self._phandle_node[phandle]
+ name = Conv_name_to_c(target_node.name)
+ vals.append('{&%s%s, %d}' % (VAL_PREFIX, name, id))
+ else:
+ for val in prop.value:
+ vals.append(self.GetValue(prop.type, val))
+ self.Buf(', '.join(vals))
+ self.Buf('}')
+ else:
+ self.Buf(self.GetValue(prop.type, prop.value))
+ self.Buf(',\n')
+ self.Buf('};\n')
+
+ # Add a device declaration
+ self.Buf('U_BOOT_DEVICE(%s) = {\n' % var_name)
+ self.Buf('\t.name\t\t= "%s",\n' % struct_name)
+ self.Buf('\t.platdata\t= &%s%s,\n' % (VAL_PREFIX, var_name))
+ self.Buf('\t.platdata_size\t= sizeof(%s%s),\n' %
+ (VAL_PREFIX, var_name))
+ self.Buf('};\n')
+ self.Buf('\n')
+
+ # Output phandle target nodes first, since they may be referenced
+ # by others
+ if 'phandle' in node.props:
+ self.Out(''.join(self.GetBuf()))
+ else:
+ node_txt_list.append(self.GetBuf())
+
+ # Output all the nodes which are not phandle targets themselves, but
+ # may reference them. This avoids the need for forward declarations.
+ for node_txt in node_txt_list:
+ self.Out(''.join(node_txt))
+
+
+if __name__ != "__main__":
+ pass
+
+parser = OptionParser()
+parser.add_option('-d', '--dtb-file', action='store',
+ help='Specify the .dtb input file')
+parser.add_option('--include-disabled', action='store_true',
+ help='Include disabled nodes')
+parser.add_option('-o', '--output', action='store', default='-',
+ help='Select output filename')
+(options, args) = parser.parse_args()
+
+if not args:
+ raise ValueError('Please specify a command: struct, platdata')
+
+plat = DtbPlatdata(options.dtb_file, options)
+plat.ScanDtb()
+plat.ScanTree()
+plat.SetupOutput(options.output)
+structs = plat.ScanStructs()
+
+for cmd in args[0].split(','):
+ if cmd == 'struct':
+ plat.GenerateStructs(structs)
+ elif cmd == 'platdata':
+ plat.GenerateTables()
+ else:
+ raise ValueError("Unknown command '%s': (use: struct, platdata)" % cmd)
diff --git a/tools/dtoc/fdt.py b/tools/dtoc/fdt.py
new file mode 100644
index 0000000..1d913a9
--- /dev/null
+++ b/tools/dtoc/fdt.py
@@ -0,0 +1,180 @@
+#!/usr/bin/python
+#
+# Copyright (C) 2016 Google, Inc
+# Written by Simon Glass <sjg@chromium.org>
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+import fdt_util
+import libfdt
+import sys
+
+# This deals with a device tree, presenting it as a list of Node and Prop
+# objects, representing nodes and properties, respectively.
+#
+# This implementation uses a libfdt Python library to access the device tree,
+# so it is fairly efficient.
+
+class Prop:
+ """A device tree property
+
+ Properties:
+ name: Property name (as per the device tree)
+ value: Property value as a string of bytes, or a list of strings of
+ bytes
+ type: Value type
+ """
+ def __init__(self, name, bytes):
+ self.name = name
+ self.value = None
+ if not bytes:
+ self.type = fdt_util.TYPE_BOOL
+ self.value = True
+ return
+ self.type, self.value = fdt_util.BytesToValue(bytes)
+
+ def GetPhandle(self):
+ """Get a (single) phandle value from a property
+
+ Gets the phandle valuie from a property and returns it as an integer
+ """
+ return fdt_util.fdt32_to_cpu(self.value[:4])
+
+ def Widen(self, newprop):
+ """Figure out which property type is more general
+
+ Given a current property and a new property, this function returns the
+ one that is less specific as to type. The less specific property will
+ be ble to represent the data in the more specific property. This is
+ used for things like:
+
+ node1 {
+ compatible = "fred";
+ value = <1>;
+ };
+ node1 {
+ compatible = "fred";
+ value = <1 2>;
+ };
+
+ He we want to use an int array for 'value'. The first property
+ suggests that a single int is enough, but the second one shows that
+ it is not. Calling this function with these two propertes would
+ update the current property to be like the second, since it is less
+ specific.
+ """
+ if newprop.type < self.type:
+ self.type = newprop.type
+
+ if type(newprop.value) == list and type(self.value) != list:
+ self.value = [self.value]
+
+ if type(self.value) == list and len(newprop.value) > len(self.value):
+ val = fdt_util.GetEmpty(self.type)
+ while len(self.value) < len(newprop.value):
+ self.value.append(val)
+
+
+class Node:
+ """A device tree node
+
+ Properties:
+ offset: Integer offset in the device tree
+ name: Device tree node tname
+ path: Full path to node, along with the node name itself
+ _fdt: Device tree object
+ subnodes: A list of subnodes for this node, each a Node object
+ props: A dict of properties for this node, each a Prop object.
+ Keyed by property name
+ """
+ def __init__(self, fdt, offset, name, path):
+ self.offset = offset
+ self.name = name
+ self.path = path
+ self._fdt = fdt
+ self.subnodes = []
+ self.props = {}
+
+ def Scan(self):
+ """Scan a node's properties and subnodes
+
+ This fills in the props and subnodes properties, recursively
+ searching into subnodes so that the entire tree is built.
+ """
+ self.props = self._fdt.GetProps(self.path)
+
+ offset = libfdt.fdt_first_subnode(self._fdt.GetFdt(), self.offset)
+ while offset >= 0:
+ sep = '' if self.path[-1] == '/' else '/'
+ name = libfdt.Name(self._fdt.GetFdt(), offset)
+ path = self.path + sep + name
+ node = Node(self._fdt, offset, name, path)
+ self.subnodes.append(node)
+
+ node.Scan()
+ offset = libfdt.fdt_next_subnode(self._fdt.GetFdt(), offset)
+
+
+class Fdt:
+ """Provides simple access to a flat device tree blob.
+
+ Properties:
+ fname: Filename of fdt
+ _root: Root of device tree (a Node object)
+ """
+
+ def __init__(self, fname):
+ self.fname = fname
+ with open(fname) as fd:
+ self._fdt = fd.read()
+
+ def GetFdt(self):
+ """Get the contents of the FDT
+
+ Returns:
+ The FDT contents as a string of bytes
+ """
+ return self._fdt
+
+ def Scan(self):
+ """Scan a device tree, building up a tree of Node objects
+
+ This fills in the self._root property
+ """
+ self._root = Node(self, 0, '/', '/')
+ self._root.Scan()
+
+ def GetRoot(self):
+ """Get the root Node of the device tree
+
+ Returns:
+ The root Node object
+ """
+ return self._root
+
+ def GetProps(self, node):
+ """Get all properties from a node.
+
+ Args:
+ node: Full path to node name to look in.
+
+ Returns:
+ A dictionary containing all the properties, indexed by node name.
+ The entries are Prop objects.
+
+ Raises:
+ ValueError: if the node does not exist.
+ """
+ offset = libfdt.fdt_path_offset(self._fdt, node)
+ if offset < 0:
+ libfdt.Raise(offset)
+ props_dict = {}
+ poffset = libfdt.fdt_first_property_offset(self._fdt, offset)
+ while poffset >= 0:
+ dprop, plen = libfdt.fdt_get_property_by_offset(self._fdt, poffset)
+ prop = Prop(libfdt.String(self._fdt, dprop.nameoff), libfdt.Data(dprop))
+ props_dict[prop.name] = prop
+
+ poffset = libfdt.fdt_next_property_offset(self._fdt, poffset)
+ return props_dict
diff --git a/tools/dtoc/fdt_fallback.py b/tools/dtoc/fdt_fallback.py
new file mode 100644
index 0000000..14decf3
--- /dev/null
+++ b/tools/dtoc/fdt_fallback.py
@@ -0,0 +1,207 @@
+#!/usr/bin/python
+#
+# Copyright (C) 2016 Google, Inc
+# Written by Simon Glass <sjg@chromium.org>
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+import command
+import fdt_util
+import sys
+
+# This deals with a device tree, presenting it as a list of Node and Prop
+# objects, representing nodes and properties, respectively.
+#
+# This implementation uses the fdtget tool to access the device tree, so it
+# is not very efficient for larger trees. The tool is called once for each
+# node and property in the tree.
+
+class Prop:
+ """A device tree property
+
+ Properties:
+ name: Property name (as per the device tree)
+ value: Property value as a string of bytes, or a list of strings of
+ bytes
+ type: Value type
+ """
+ def __init__(self, name, byte_list_str):
+ self.name = name
+ self.value = None
+ if not byte_list_str.strip():
+ self.type = fdt_util.TYPE_BOOL
+ return
+ bytes = [chr(int(byte, 16)) for byte in byte_list_str.strip().split(' ')]
+ self.type, self.value = fdt_util.BytesToValue(''.join(bytes))
+
+ def GetPhandle(self):
+ """Get a (single) phandle value from a property
+
+ Gets the phandle valuie from a property and returns it as an integer
+ """
+ return fdt_util.fdt32_to_cpu(self.value[:4])
+
+ def Widen(self, newprop):
+ """Figure out which property type is more general
+
+ Given a current property and a new property, this function returns the
+ one that is less specific as to type. The less specific property will
+ be ble to represent the data in the more specific property. This is
+ used for things like:
+
+ node1 {
+ compatible = "fred";
+ value = <1>;
+ };
+ node1 {
+ compatible = "fred";
+ value = <1 2>;
+ };
+
+ He we want to use an int array for 'value'. The first property
+ suggests that a single int is enough, but the second one shows that
+ it is not. Calling this function with these two propertes would
+ update the current property to be like the second, since it is less
+ specific.
+ """
+ if newprop.type < self.type:
+ self.type = newprop.type
+
+ if type(newprop.value) == list and type(self.value) != list:
+ self.value = newprop.value
+
+class Node:
+ """A device tree node
+
+ Properties:
+ name: Device tree node tname
+ path: Full path to node, along with the node name itself
+ _fdt: Device tree object
+ subnodes: A list of subnodes for this node, each a Node object
+ props: A dict of properties for this node, each a Prop object.
+ Keyed by property name
+ """
+ def __init__(self, fdt, name, path):
+ self.name = name
+ self.path = path
+ self._fdt = fdt
+ self.subnodes = []
+ self.props = {}
+
+ def Scan(self):
+ """Scan a node's properties and subnodes
+
+ This fills in the props and subnodes properties, recursively
+ searching into subnodes so that the entire tree is built.
+ """
+ for name, byte_list_str in self._fdt.GetProps(self.path).iteritems():
+ prop = Prop(name, byte_list_str)
+ self.props[name] = prop
+
+ for name in self._fdt.GetSubNodes(self.path):
+ sep = '' if self.path[-1] == '/' else '/'
+ path = self.path + sep + name
+ node = Node(self._fdt, name, path)
+ self.subnodes.append(node)
+
+ node.Scan()
+
+
+class Fdt:
+ """Provides simple access to a flat device tree blob.
+
+ Properties:
+ fname: Filename of fdt
+ _root: Root of device tree (a Node object)
+ """
+
+ def __init__(self, fname):
+ self.fname = fname
+
+ def Scan(self):
+ """Scan a device tree, building up a tree of Node objects
+
+ This fills in the self._root property
+ """
+ self._root = Node(self, '/', '/')
+ self._root.Scan()
+
+ def GetRoot(self):
+ """Get the root Node of the device tree
+
+ Returns:
+ The root Node object
+ """
+ return self._root
+
+ def GetSubNodes(self, node):
+ """Returns a list of sub-nodes of a given node
+
+ Args:
+ node: Node name to return children from
+
+ Returns:
+ List of children in the node (each a string node name)
+
+ Raises:
+ CmdError: if the node does not exist.
+ """
+ out = command.Output('fdtget', self.fname, '-l', node)
+ return out.strip().splitlines()
+
+ def GetProps(self, node, convert_dashes=False):
+ """Get all properties from a node
+
+ Args:
+ node: full path to node name to look in
+ convert_dashes: True to convert - to _ in node names
+
+ Returns:
+ A dictionary containing all the properties, indexed by node name.
+ The entries are simply strings - no decoding of lists or numbers
+ is done.
+
+ Raises:
+ CmdError: if the node does not exist.
+ """
+ out = command.Output('fdtget', self.fname, node, '-p')
+ props = out.strip().splitlines()
+ props_dict = {}
+ for prop in props:
+ name = prop
+ if convert_dashes:
+ prop = re.sub('-', '_', prop)
+ props_dict[prop] = self.GetProp(node, name)
+ return props_dict
+
+ def GetProp(self, node, prop, default=None, typespec=None):
+ """Get a property from a device tree.
+
+ This looks up the given node and property, and returns the value as a
+ string,
+
+ If the node or property does not exist, this will return the default
+ value.
+
+ Args:
+ node: Full path to node to look up.
+ prop: Property name to look up.
+ default: Default value to return if nothing is present in the fdt,
+ or None to raise in this case. This will be converted to a
+ string.
+ typespec: Type character to use (None for default, 's' for string)
+
+ Returns:
+ string containing the property value.
+
+ Raises:
+ CmdError: if the property does not exist and no default is provided.
+ """
+ args = [self.fname, node, prop, '-t', 'bx']
+ if default is not None:
+ args += ['-d', str(default)]
+ if typespec is not None:
+ args += ['-t%s' % typespec]
+ out = command.Output('fdtget', *args)
+ return out.strip()
diff --git a/tools/dtoc/fdt_util.py b/tools/dtoc/fdt_util.py
new file mode 100644
index 0000000..929b524
--- /dev/null
+++ b/tools/dtoc/fdt_util.py
@@ -0,0 +1,86 @@
+#!/usr/bin/python
+#
+# Copyright (C) 2016 Google, Inc
+# Written by Simon Glass <sjg@chromium.org>
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+import struct
+
+# A list of types we support
+(TYPE_BYTE, TYPE_INT, TYPE_STRING, TYPE_BOOL) = range(4)
+
+def BytesToValue(bytes):
+ """Converts a string of bytes into a type and value
+
+ Args:
+ A string containing bytes
+
+ Return:
+ A tuple:
+ Type of data
+ Data, either a single element or a list of elements. Each element
+ is one of:
+ TYPE_STRING: string value from the property
+ TYPE_INT: a byte-swapped integer stored as a 4-byte string
+ TYPE_BYTE: a byte stored as a single-byte string
+ """
+ size = len(bytes)
+ strings = bytes.split('\0')
+ is_string = True
+ count = len(strings) - 1
+ if count > 0 and not strings[-1]:
+ for string in strings[:-1]:
+ if not string:
+ is_string = False
+ break
+ for ch in string:
+ if ch < ' ' or ch > '~':
+ is_string = False
+ break
+ else:
+ is_string = False
+ if is_string:
+ if count == 1:
+ return TYPE_STRING, strings[0]
+ else:
+ return TYPE_STRING, strings[:-1]
+ if size % 4:
+ if size == 1:
+ return TYPE_BYTE, bytes[0]
+ else:
+ return TYPE_BYTE, list(bytes)
+ val = []
+ for i in range(0, size, 4):
+ val.append(bytes[i:i + 4])
+ if size == 4:
+ return TYPE_INT, val[0]
+ else:
+ return TYPE_INT, val
+
+def GetEmpty(type):
+ """Get an empty / zero value of the given type
+
+ Returns:
+ A single value of the given type
+ """
+ if type == TYPE_BYTE:
+ return chr(0)
+ elif type == TYPE_INT:
+ return struct.pack('<I', 0);
+ elif type == TYPE_STRING:
+ return ''
+ else:
+ return True
+
+def fdt32_to_cpu(val):
+ """Convert a device tree cell to an integer
+
+ Args:
+ Value to convert (4-character string representing the cell value)
+
+ Return:
+ A native-endian integer value
+ """
+ return struct.unpack(">I", val)[0]
diff --git a/tools/env/fw_env.config b/tools/env/fw_env.config
index 6f216f9..776e16f 100644
--- a/tools/env/fw_env.config
+++ b/tools/env/fw_env.config
@@ -2,7 +2,7 @@
# Up to two entries are valid, in this case the redundant
# environment sector is assumed present.
# Notice, that the "Number of sectors" is not required on NOR and SPI-dataflash.
-# Futhermore, if the Flash sector size is ommitted, this value is assumed to
+# Futhermore, if the Flash sector size is omitted, this value is assumed to
# be the same as the Environment size, which is valid for NOR and SPI-dataflash
# NOR example
diff --git a/tools/fit_image.c b/tools/fit_image.c
index 58aa8e2..10fd6d4 100644
--- a/tools/fit_image.c
+++ b/tools/fit_image.c
@@ -195,7 +195,8 @@ static int fit_write_images(struct image_tool_params *params, char *fdt)
fdt_begin_node(fdt, str);
fdt_property_string(fdt, "description", params->imagename);
fdt_property_string(fdt, "type", typename);
- fdt_property_string(fdt, "arch", genimg_get_arch_name(params->arch));
+ fdt_property_string(fdt, "arch",
+ genimg_get_arch_short_name(params->arch));
fdt_property_string(fdt, "os", genimg_get_os_short_name(params->os));
fdt_property_string(fdt, "compression",
genimg_get_comp_short_name(params->comp));
@@ -650,8 +651,8 @@ static int fit_handle_file(struct image_tool_params *params)
}
if (ret) {
- fprintf(stderr, "%s Can't add hashes to FIT blob\n",
- params->cmdname);
+ fprintf(stderr, "%s Can't add hashes to FIT blob: %d\n",
+ params->cmdname, ret);
goto err_system;
}
diff --git a/tools/image-host.c b/tools/image-host.c
index 7effb6c..3e14fdc 100644
--- a/tools/image-host.c
+++ b/tools/image-host.c
@@ -38,7 +38,7 @@ static int fit_set_hash_value(void *fit, int noffset, uint8_t *value,
printf("Can't set hash '%s' property for '%s' node(%s)\n",
FIT_VALUE_PROP, fit_get_name(fit, noffset, NULL),
fdt_strerror(ret));
- return -1;
+ return ret == -FDT_ERR_NOSPACE ? -ENOSPC : -EIO;
}
return 0;
@@ -64,25 +64,27 @@ static int fit_image_process_hash(void *fit, const char *image_name,
const char *node_name;
int value_len;
char *algo;
+ int ret;
node_name = fit_get_name(fit, noffset, NULL);
if (fit_image_hash_get_algo(fit, noffset, &algo)) {
printf("Can't get hash algo property for '%s' hash node in '%s' image node\n",
node_name, image_name);
- return -1;
+ return -ENOENT;
}
if (calculate_hash(data, size, algo, value, &value_len)) {
printf("Unsupported hash algorithm (%s) for '%s' hash node in '%s' image node\n",
algo, node_name, image_name);
- return -1;
+ return -EPROTONOSUPPORT;
}
- if (fit_set_hash_value(fit, noffset, value, value_len)) {
+ ret = fit_set_hash_value(fit, noffset, value, value_len);
+ if (ret) {
printf("Can't set hash value for '%s' hash node in '%s' image node\n",
node_name, image_name);
- return -1;
+ return ret;
}
return 0;
@@ -322,7 +324,7 @@ int fit_image_add_verification_data(const char *keydir, void *keydest,
comment, require_keys);
}
if (ret)
- return -1;
+ return ret;
}
return 0;
diff --git a/tools/mkimage.c b/tools/mkimage.c
index ff3024a..d993958 100644
--- a/tools/mkimage.c
+++ b/tools/mkimage.c
@@ -25,45 +25,47 @@ static struct image_tool_params params = {
.imagename2 = "",
};
-static int h_compare_image_name(const void *vtype1, const void *vtype2)
+static enum ih_category cur_category;
+
+static int h_compare_category_name(const void *vtype1, const void *vtype2)
{
const int *type1 = vtype1;
const int *type2 = vtype2;
- const char *name1 = genimg_get_type_short_name(*type1);
- const char *name2 = genimg_get_type_short_name(*type2);
+ const char *name1 = genimg_get_cat_short_name(cur_category, *type1);
+ const char *name2 = genimg_get_cat_short_name(cur_category, *type2);
return strcmp(name1, name2);
}
-/* Show all image types supported by mkimage */
-static void show_image_types(void)
+static int show_valid_options(enum ih_category category)
{
- struct image_type_params *tparams;
- int order[IH_TYPE_COUNT];
+ int *order;
int count;
- int type;
+ int item;
int i;
+ count = genimg_get_cat_count(category);
+ order = calloc(count, sizeof(*order));
+ if (!order)
+ return -ENOMEM;
+
/* Sort the names in order of short name for easier reading */
- memset(order, '\0', sizeof(order));
- for (count = 0, type = 0; type < IH_TYPE_COUNT; type++) {
- tparams = imagetool_get_type(type);
- if (tparams)
- order[count++] = type;
- }
- qsort(order, count, sizeof(int), h_compare_image_name);
+ for (item = 0; item < count; item++)
+ order[item] = item;
+ cur_category = category;
+ qsort(order, count, sizeof(int), h_compare_category_name);
- fprintf(stderr, "\nInvalid image type. Supported image types:\n");
+ fprintf(stderr, "\nInvalid %s, supported are:\n",
+ genimg_get_cat_desc(category));
for (i = 0; i < count; i++) {
- type = order[i];
- tparams = imagetool_get_type(type);
- if (tparams) {
- fprintf(stderr, "\t%-15s %s\n",
- genimg_get_type_short_name(type),
- genimg_get_type_name(type));
- }
+ item = order[i];
+ fprintf(stderr, "\t%-15s %s\n",
+ genimg_get_cat_short_name(category, item),
+ genimg_get_cat_name(category, item));
}
fprintf(stderr, "\n");
+
+ return 0;
}
static void usage(const char *msg)
@@ -150,8 +152,10 @@ static void process_args(int argc, char **argv)
break;
case 'A':
params.arch = genimg_get_arch_id(optarg);
- if (params.arch < 0)
+ if (params.arch < 0) {
+ show_valid_options(IH_ARCH);
usage("Invalid architecture");
+ }
break;
case 'b':
if (add_content(IH_TYPE_FLATDT, optarg)) {
@@ -166,8 +170,10 @@ static void process_args(int argc, char **argv)
break;
case 'C':
params.comp = genimg_get_comp_id(optarg);
- if (params.comp < 0)
+ if (params.comp < 0) {
+ show_valid_options(IH_COMP);
usage("Invalid compression type");
+ }
break;
case 'd':
params.datafile = optarg;
@@ -197,7 +203,6 @@ static void process_args(int argc, char **argv)
* The flattened image tree (FIT) format
* requires a flattened device tree image type
*/
- params.fit_image_type = params.type;
params.type = IH_TYPE_FLATDT;
params.fflag = 1;
break;
@@ -215,8 +220,10 @@ static void process_args(int argc, char **argv)
break;
case 'O':
params.os = genimg_get_os_id(optarg);
- if (params.os < 0)
+ if (params.os < 0) {
+ show_valid_options(IH_OS);
usage("Invalid operating system");
+ }
break;
case 'p':
params.external_offset = strtoull(optarg, &ptr, 16);
@@ -225,6 +232,7 @@ static void process_args(int argc, char **argv)
params.cmdname, optarg);
exit(EXIT_FAILURE);
}
+ break;
case 'q':
params.quiet = 1;
break;
@@ -244,7 +252,7 @@ static void process_args(int argc, char **argv)
case 'T':
type = genimg_get_type_id(optarg);
if (type < 0) {
- show_image_types();
+ show_valid_options(IH_TYPE);
usage("Invalid image type");
}
break;
@@ -272,9 +280,12 @@ static void process_args(int argc, char **argv)
* will always be IH_TYPE_FLATDT in this case).
*/
if (params.type == IH_TYPE_FLATDT) {
- params.fit_image_type = type;
+ params.fit_image_type = type ? type : IH_TYPE_KERNEL;
+ /* For auto_its, datafile is always 'auto' */
if (!params.auto_its)
params.datafile = datafile;
+ else if (!params.datafile)
+ usage("Missing data file for auto-FIT (use -d)");
} else if (type != IH_TYPE_INVALID) {
params.type = type;
}
@@ -283,7 +294,6 @@ static void process_args(int argc, char **argv)
usage("Missing output filename");
}
-
int main(int argc, char **argv)
{
int ifd = -1;
diff --git a/tools/patman/patchstream.py b/tools/patman/patchstream.py
index 27d031e..69d5cfb 100644
--- a/tools/patman/patchstream.py
+++ b/tools/patman/patchstream.py
@@ -112,6 +112,14 @@ class PatchStream:
if self.commit and self.is_log:
self.series.AddCommit(self.commit)
self.commit = None
+ # If 'END' is missing in a 'Cover-letter' section, and that section
+ # happens to show up at the very end of the commit message, this is
+ # the chance for us to fix it up.
+ if self.in_section == 'cover' and self.is_log:
+ self.series.cover = self.section
+ self.in_section = None
+ self.skip_blank = True
+ self.section = []
def ProcessLine(self, line):
"""Process a single line of a patch file or commit log
@@ -150,6 +158,7 @@ class PatchStream:
# Handle state transition and skipping blank lines
series_tag_match = re_series_tag.match(line)
commit_tag_match = re_commit_tag.match(line)
+ cover_match = re_cover.match(line)
cover_cc_match = re_cover_cc.match(line)
signoff_match = re_signoff.match(line)
tag_match = None
@@ -168,6 +177,33 @@ class PatchStream:
elif commit_match:
self.state = STATE_MSG_HEADER
+ # If a tag is detected, or a new commit starts
+ if series_tag_match or commit_tag_match or \
+ cover_match or cover_cc_match or signoff_match or \
+ self.state == STATE_MSG_HEADER:
+ # but we are already in a section, this means 'END' is missing
+ # for that section, fix it up.
+ if self.in_section:
+ self.warn.append("Missing 'END' in section '%s'" % self.in_section)
+ if self.in_section == 'cover':
+ self.series.cover = self.section
+ elif self.in_section == 'notes':
+ if self.is_log:
+ self.series.notes += self.section
+ elif self.in_section == 'commit-notes':
+ if self.is_log:
+ self.commit.notes += self.section
+ else:
+ self.warn.append("Unknown section '%s'" % self.in_section)
+ self.in_section = None
+ self.skip_blank = True
+ self.section = []
+ # but we are already in a change list, that means a blank line
+ # is missing, fix it up.
+ if self.in_change:
+ self.warn.append("Missing 'blank line' in section 'Series-changes'")
+ self.in_change = 0
+
# If we are in a section, keep collecting lines until we see END
if self.in_section:
if line == 'END':
@@ -203,7 +239,7 @@ class PatchStream:
self.skip_blank = False
# Detect the start of a cover letter section
- elif re_cover.match(line):
+ elif cover_match:
self.in_section = 'cover'
self.skip_blank = False