Merge branch 'master' of git://git.denx.de/u-boot-video
authorTom Rini <trini@konsulko.com>
Wed, 27 Jul 2016 19:22:21 +0000 (15:22 -0400)
committerTom Rini <trini@konsulko.com>
Wed, 27 Jul 2016 19:22:21 +0000 (15:22 -0400)
700 files changed:
Kconfig
Makefile
README
api/api_net.c
arch/Kconfig
arch/arm/Kconfig
arch/arm/config.mk
arch/arm/cpu/arm11/cpu.c
arch/arm/cpu/arm926ejs/cache.c
arch/arm/cpu/armv7/Kconfig
arch/arm/cpu/armv7/Makefile
arch/arm/cpu/armv7/am33xx/config.mk
arch/arm/cpu/armv7/am33xx/ddr.c
arch/arm/cpu/armv7/cache_v7.c
arch/arm/cpu/armv7/ls102xa/psci.S
arch/arm/cpu/armv7/mx7/psci-mx7.c
arch/arm/cpu/armv7/mx7/psci.S
arch/arm/cpu/armv7/nonsec_virt.S
arch/arm/cpu/armv7/omap-common/Makefile
arch/arm/cpu/armv7/omap-common/config_secure.mk
arch/arm/cpu/armv7/omap-common/emif-common.c
arch/arm/cpu/armv7/omap-common/hwinit-common.c
arch/arm/cpu/armv7/omap-common/lowlevel_init.S
arch/arm/cpu/armv7/omap-common/mem-common.c
arch/arm/cpu/armv7/omap-common/sec-common.c [new file with mode: 0644]
arch/arm/cpu/armv7/omap3/spl_id_nand.c
arch/arm/cpu/armv7/omap5/config.mk
arch/arm/cpu/armv7/psci-common.c [new file with mode: 0644]
arch/arm/cpu/armv7/psci.S
arch/arm/cpu/armv7/sunxi/Makefile
arch/arm/cpu/armv7/sunxi/psci.c
arch/arm/cpu/armv7/sunxi/psci_head.S [deleted file]
arch/arm/cpu/armv7/virt-dt.c
arch/arm/cpu/armv7m/config.mk
arch/arm/cpu/armv8/Kconfig
arch/arm/cpu/armv8/Makefile
arch/arm/cpu/armv8/cache_v8.c
arch/arm/cpu/armv8/cpu-dt.c [new file with mode: 0644]
arch/arm/cpu/armv8/fsl-layerscape/Makefile
arch/arm/cpu/armv8/fsl-layerscape/cpu.c
arch/arm/cpu/armv8/fsl-layerscape/doc/README.lsch3
arch/arm/cpu/armv8/fsl-layerscape/doc/README.soc
arch/arm/cpu/armv8/fsl-layerscape/fdt.c
arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch2_serdes.c
arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch2_speed.c
arch/arm/cpu/armv8/fsl-layerscape/ls1046a_serdes.c [new file with mode: 0644]
arch/arm/cpu/armv8/fsl-layerscape/ppa.c [new file with mode: 0644]
arch/arm/cpu/armv8/s32v234/cpu.c
arch/arm/cpu/armv8/sec_firmware.c [new file with mode: 0644]
arch/arm/cpu/armv8/sec_firmware_asm.S [new file with mode: 0644]
arch/arm/cpu/armv8/spin_table.c [new file with mode: 0644]
arch/arm/cpu/armv8/spin_table_v8.S [new file with mode: 0644]
arch/arm/cpu/armv8/start.S
arch/arm/cpu/armv8/zynqmp/clk.c
arch/arm/cpu/armv8/zynqmp/cpu.c
arch/arm/cpu/armv8/zynqmp/mp.c
arch/arm/cpu/u-boot.lds
arch/arm/dts/Makefile
arch/arm/dts/dra7-evm.dts
arch/arm/dts/dra72-evm.dts
arch/arm/dts/exynos4210-origen.dts
arch/arm/dts/exynos4210-trats.dts
arch/arm/dts/exynos4210-universal_c210.dts
arch/arm/dts/exynos4412-odroid.dts
arch/arm/dts/exynos4412-trats2.dts
arch/arm/dts/k2e-evm.dts
arch/arm/dts/k2g-evm.dts
arch/arm/dts/k2g.dtsi
arch/arm/dts/k2hk-evm.dts
arch/arm/dts/k2l-evm.dts
arch/arm/dts/keystone.dtsi
arch/arm/dts/rk3288-evb.dts [new file with mode: 0644]
arch/arm/dts/rk3288-evb.dtsi [new file with mode: 0644]
arch/arm/dts/rk3288-firefly.dts
arch/arm/dts/rk3288.dtsi
arch/arm/dts/rk3399-evb.dts [new file with mode: 0644]
arch/arm/dts/rk3399.dtsi [new file with mode: 0644]
arch/arm/dts/sun50i-a64-pine64-plus.dts
arch/arm/dts/sun50i-a64.dtsi
arch/arm/dts/sun5i-a10s.dtsi
arch/arm/dts/sun5i-a13-olinuxino.dts
arch/arm/dts/sun5i-r8-chip.dts
arch/arm/dts/sun5i.dtsi
arch/arm/dts/sun8i-h3-orangepi-2.dts
arch/arm/dts/sun8i-h3-orangepi-lite.dts [new file with mode: 0644]
arch/arm/dts/sun8i-h3-orangepi-pc-plus.dts [new file with mode: 0644]
arch/arm/dts/sun8i-h3-orangepi-pc.dts
arch/arm/dts/sun8i-h3-orangepi-plus.dts
arch/arm/dts/sun8i-h3.dtsi
arch/arm/dts/tegra186-p2771-0000-a02.dts [new file with mode: 0644]
arch/arm/dts/tegra186-p2771-0000-b00.dts [new file with mode: 0644]
arch/arm/dts/tegra186-p2771-0000.dts [deleted file]
arch/arm/dts/tegra186-p2771-0000.dtsi [new file with mode: 0644]
arch/arm/dts/tegra186.dtsi
arch/arm/dts/uniphier-proxstream2-gentil.dts
arch/arm/dts/uniphier-proxstream2-vodka.dts
arch/arm/imx-common/ddrmc-vf610.c
arch/arm/include/asm/arch-am33xx/sys_proto.h
arch/arm/include/asm/arch-fsl-layerscape/config.h
arch/arm/include/asm/arch-fsl-layerscape/cpu.h
arch/arm/include/asm/arch-fsl-layerscape/fsl_serdes.h
arch/arm/include/asm/arch-fsl-layerscape/immap_lsch2.h
arch/arm/include/asm/arch-fsl-layerscape/immap_lsch3.h
arch/arm/include/asm/arch-fsl-layerscape/ppa.h [new file with mode: 0644]
arch/arm/include/asm/arch-fsl-layerscape/soc.h
arch/arm/include/asm/arch-ls102xa/config.h
arch/arm/include/asm/arch-omap3/sys_proto.h
arch/arm/include/asm/arch-omap4/i2c.h
arch/arm/include/asm/arch-omap5/i2c.h
arch/arm/include/asm/arch-rockchip/clock.h
arch/arm/include/asm/arch-rockchip/sdram.h
arch/arm/include/asm/arch-stm32f7/fmc.h [new file with mode: 0644]
arch/arm/include/asm/arch-stm32f7/stm32.h
arch/arm/include/asm/arch-sunxi/clock_sun4i.h
arch/arm/include/asm/arch-sunxi/clock_sun6i.h
arch/arm/include/asm/arch-sunxi/cpu_sun4i.h
arch/arm/include/asm/arch-sunxi/gpio.h
arch/arm/include/asm/arch-sunxi/mmc.h
arch/arm/include/asm/arch-sunxi/spl.h
arch/arm/include/asm/arch-tegra/board.h
arch/arm/include/asm/arch-tegra/clock.h
arch/arm/include/asm/arch-tegra/ivc.h [new file with mode: 0644]
arch/arm/include/asm/arch-tegra124/display.h
arch/arm/include/asm/arch-zynqmp/clk.h
arch/arm/include/asm/armv7.h
arch/arm/include/asm/armv7m.h
arch/arm/include/asm/armv8/mmu.h
arch/arm/include/asm/armv8/sec_firmware.h [new file with mode: 0644]
arch/arm/include/asm/cache.h
arch/arm/include/asm/fsl_secure_boot.h
arch/arm/include/asm/global_data.h
arch/arm/include/asm/io.h
arch/arm/include/asm/omap_common.h
arch/arm/include/asm/omap_sec_common.h [new file with mode: 0644]
arch/arm/include/asm/psci.h
arch/arm/include/asm/secure.h
arch/arm/include/asm/spin_table.h [new file with mode: 0644]
arch/arm/include/asm/types.h
arch/arm/lib/Makefile
arch/arm/lib/bootm-fdt.c
arch/arm/lib/bootm.c
arch/arm/lib/cache.c
arch/arm/lib/crt0_64.S
arch/arm/lib/psci-dt.c [new file with mode: 0644]
arch/arm/lib/sections.c
arch/arm/lib/spl.c
arch/arm/lib/zimage.c [new file with mode: 0644]
arch/arm/mach-exynos/include/mach/dwmmc.h
arch/arm/mach-exynos/mmu-arm64.c
arch/arm/mach-keystone/init.c
arch/arm/mach-meson/board.c
arch/arm/mach-rockchip/Kconfig
arch/arm/mach-rockchip/Makefile
arch/arm/mach-rockchip/board.c
arch/arm/mach-rockchip/rk3036/Kconfig
arch/arm/mach-rockchip/rk3036/Makefile
arch/arm/mach-rockchip/rk3036/save_boot_param.S [deleted file]
arch/arm/mach-rockchip/rk3288-board-spl.c
arch/arm/mach-rockchip/rk3288/Kconfig
arch/arm/mach-rockchip/rk3288/Makefile
arch/arm/mach-rockchip/rk3288/clk_rk3288.c [new file with mode: 0644]
arch/arm/mach-rockchip/rk3288/sdram_rk3288.c
arch/arm/mach-rockchip/rk3288/syscon_rk3288.c
arch/arm/mach-rockchip/rk3399/Kconfig [new file with mode: 0644]
arch/arm/mach-rockchip/rk3399/Makefile [new file with mode: 0644]
arch/arm/mach-rockchip/rk3399/rk3399.c [new file with mode: 0644]
arch/arm/mach-rockchip/save_boot_param.S [new file with mode: 0644]
arch/arm/mach-snapdragon/sysmap-apq8016.c
arch/arm/mach-stm32/stm32f7/Makefile
arch/arm/mach-stm32/stm32f7/clock.c
arch/arm/mach-stm32/stm32f7/soc.c [new file with mode: 0644]
arch/arm/mach-sunxi/board.c
arch/arm/mach-tegra/Kconfig
arch/arm/mach-tegra/Makefile
arch/arm/mach-tegra/arm64-mmu.c
arch/arm/mach-tegra/board186.c
arch/arm/mach-tegra/clock.c
arch/arm/mach-tegra/ivc.c [new file with mode: 0644]
arch/arm/mach-tegra/psci.S
arch/arm/mach-tegra/tegra186/Makefile
arch/arm/mach-tegra/tegra186/nvtboot_ll.S [new file with mode: 0644]
arch/arm/mach-tegra/tegra186/nvtboot_mem.c [new file with mode: 0644]
arch/arm/mach-uniphier/Kconfig
arch/arm/mach-uniphier/arm32/Makefile
arch/arm/mach-uniphier/arm32/cache-uniphier.c [new file with mode: 0644]
arch/arm/mach-uniphier/arm32/cache_uniphier.c [deleted file]
arch/arm/mach-uniphier/arm32/late_lowlevel_init.S
arch/arm/mach-uniphier/arm32/lowlevel_init.S
arch/arm/mach-uniphier/arm32/ssc-regs.h
arch/arm/mach-uniphier/arm64/arm-cci500.c
arch/arm/mach-uniphier/arm64/mem_map.c
arch/arm/mach-uniphier/arm64/smp_kick_cpus.c
arch/arm/mach-uniphier/arm64/timer.c
arch/arm/mach-uniphier/boards.c
arch/arm/mach-uniphier/clk/clk-pxs2.c
arch/arm/mach-uniphier/dram/cmd_ddrphy.c
arch/arm/mach-uniphier/dram/umc-ld4.c
arch/arm/mach-uniphier/dram/umc-pro4.c
arch/arm/mach-uniphier/dram/umc-sld8.c
arch/arm/mach-uniphier/init.h
arch/arm/mach-uniphier/sc-regs.h
arch/nds32/include/asm/io.h
arch/powerpc/cpu/mpc85xx/cpu_init.c
arch/powerpc/cpu/mpc85xx/mp.c
arch/powerpc/cpu/mpc85xx/start.S
arch/powerpc/cpu/mpc86xx/config.mk
arch/powerpc/cpu/mpc8xxx/fsl_pamu.c
arch/powerpc/cpu/mpc8xxx/pamu_table.c
arch/powerpc/cpu/ppc4xx/start.S
arch/powerpc/include/asm/arch-mpc85xx/gpio.h
arch/powerpc/include/asm/fsl_secure_boot.h
arch/powerpc/include/asm/status_led.h
arch/sandbox/Kconfig
arch/sandbox/config.mk
arch/sandbox/cpu/Makefile
arch/sandbox/cpu/cpu.c
arch/sandbox/cpu/os.c
arch/sandbox/cpu/spl.c [new file with mode: 0644]
arch/sandbox/cpu/start.c
arch/sandbox/cpu/u-boot-spl.lds [new file with mode: 0644]
arch/sandbox/dts/sandbox.dts
arch/sandbox/include/asm/spl.h [new file with mode: 0644]
arch/sandbox/lib/Makefile
arch/sandbox/lib/bootm.c
arch/sh/include/asm/io.h
arch/x86/Kconfig
arch/x86/cpu/baytrail/Kconfig
arch/x86/cpu/baytrail/acpi.c
arch/x86/cpu/ivybridge/lpc.c
arch/x86/cpu/ivybridge/sdram.c
arch/x86/cpu/quark/acpi.c
arch/x86/dts/Makefile
arch/x86/dts/baytrail_som-db5800-som-6867.dts [new file with mode: 0644]
arch/x86/include/asm/acpi/global_nvs.h [new file with mode: 0644]
arch/x86/include/asm/acpi_table.h
arch/x86/include/asm/arch-baytrail/acpi/global_nvs.asl [new file with mode: 0644]
arch/x86/include/asm/arch-baytrail/acpi/lpc.asl
arch/x86/include/asm/arch-baytrail/acpi/platform.asl
arch/x86/include/asm/arch-baytrail/global_nvs.h [new file with mode: 0644]
arch/x86/include/asm/arch-quark/acpi/global_nvs.asl [new file with mode: 0644]
arch/x86/include/asm/arch-quark/acpi/platform.asl
arch/x86/include/asm/arch-quark/global_nvs.h [new file with mode: 0644]
arch/x86/lib/acpi_table.c
arch/x86/lib/fsp/fsp_support.c
board/advantech/Kconfig [new file with mode: 0644]
board/advantech/som-db5800-som-6867/.gitignore [new file with mode: 0644]
board/advantech/som-db5800-som-6867/Kconfig [new file with mode: 0644]
board/advantech/som-db5800-som-6867/MAINTAINERS [new file with mode: 0644]
board/advantech/som-db5800-som-6867/Makefile [new file with mode: 0644]
board/advantech/som-db5800-som-6867/acpi/mainboard.asl [new file with mode: 0644]
board/advantech/som-db5800-som-6867/dsdt.asl [new file with mode: 0644]
board/advantech/som-db5800-som-6867/som-db5800-som-6867.c [new file with mode: 0644]
board/advantech/som-db5800-som-6867/start.S [new file with mode: 0644]
board/armltd/vexpress64/vexpress64.c
board/cavium/thunderx/thunderx.c
board/congatec/conga-qeval20-qa3-e3845/conga-qeval20-qa3.c
board/evb-rk3288/evb-rk3288/Kconfig [new file with mode: 0644]
board/evb-rk3288/evb-rk3288/MAINTAINERS [new file with mode: 0644]
board/evb-rk3288/evb-rk3288/Makefile [new file with mode: 0644]
board/evb-rk3288/evb-rk3288/evb-rk3288.c [new file with mode: 0644]
board/evb_rk3036/evb_rk3036/Kconfig [deleted file]
board/evb_rk3036/evb_rk3036/MAINTAINERS [deleted file]
board/evb_rk3036/evb_rk3036/Makefile [deleted file]
board/evb_rk3036/evb_rk3036/evb_rk3036.c [deleted file]
board/freescale/common/fsl_chain_of_trust.c
board/freescale/ls1021aqds/Makefile
board/freescale/ls1021aqds/psci.S [new file with mode: 0644]
board/freescale/ls1021atwr/Makefile
board/freescale/ls1021atwr/ls1021atwr.c
board/freescale/ls1021atwr/psci.S [new file with mode: 0644]
board/freescale/ls1043aqds/MAINTAINERS
board/freescale/ls1043aqds/ddr.c
board/freescale/ls1043aqds/ls1043aqds.c
board/freescale/ls1043ardb/ddr.c
board/freescale/ls1043ardb/ls1043ardb.c
board/freescale/ls2080a/ddr.c
board/freescale/ls2080aqds/MAINTAINERS
board/freescale/ls2080aqds/ddr.c
board/freescale/ls2080ardb/ddr.c
board/freescale/t104xrdb/t104x_pbi_sb.cfg [new file with mode: 0644]
board/freescale/t104xrdb/tlb.c
board/gdsys/405ep/405ep.c
board/gdsys/405ep/dlvision-10g.c
board/gdsys/405ex/405ex.c
board/gdsys/mpc8308/mpc8308.c
board/gumstix/duovero/duovero.c
board/hisilicon/hikey/hikey.c
board/isee/igep00x0/igep00x0.c
board/isee/igep00x0/igep00x0.h
board/keymile/common/common.c
board/keymile/kmp204x/ddr.c
board/kylin/kylin_rk3036/Kconfig [deleted file]
board/kylin/kylin_rk3036/MAINTAINERS [deleted file]
board/kylin/kylin_rk3036/Makefile [deleted file]
board/kylin/kylin_rk3036/kylin_rk3036.c [deleted file]
board/logicpd/zoom1/zoom1.c
board/micronas/vct/ebi_onenand.c
board/nvidia/p2371-2180/p2371-2180.c
board/nvidia/p2571/max77620_init.h
board/raspberrypi/rpi/rpi.c
board/rockchip/evb_rk3036/Kconfig [new file with mode: 0644]
board/rockchip/evb_rk3036/MAINTAINERS [new file with mode: 0644]
board/rockchip/evb_rk3036/Makefile [new file with mode: 0644]
board/rockchip/evb_rk3036/evb_rk3036.c [new file with mode: 0644]
board/rockchip/evb_rk3399/Kconfig [new file with mode: 0644]
board/rockchip/evb_rk3399/MAINTAINERS [new file with mode: 0644]
board/rockchip/evb_rk3399/Makefile [new file with mode: 0644]
board/rockchip/evb_rk3399/README [new file with mode: 0644]
board/rockchip/evb_rk3399/evb-rk3399.c [new file with mode: 0644]
board/rockchip/kylin_rk3036/Kconfig [new file with mode: 0644]
board/rockchip/kylin_rk3036/MAINTAINERS [new file with mode: 0644]
board/rockchip/kylin_rk3036/Makefile [new file with mode: 0644]
board/rockchip/kylin_rk3036/kylin_rk3036.c [new file with mode: 0644]
board/samsung/goni/onenand.c
board/samsung/smdkc100/onenand.c
board/samsung/universal_c210/onenand.c
board/sandbox/MAINTAINERS
board/sandbox/README.sandbox
board/st/stm32f746-disco/stm32f746-disco.c
board/sunxi/MAINTAINERS
board/sunxi/board.c
board/ti/am43xx/board.c
board/ti/am57xx/board.c
board/ti/dra7xx/evm.c
cmd/bdinfo.c
cmd/bootefi.c
cmd/i2c.c
cmd/lzmadec.c
cmd/misc.c
cmd/mtdparts.c
cmd/nand.c
cmd/sf.c
common/Kconfig
common/board_f.c
common/bootm.c
common/bootm_os.c
common/env_common.c
common/env_sf.c
common/fb_mmc.c
common/image-fit.c
common/image.c
common/spl/Makefile
common/spl/spl.c
common/spl/spl_fat.c
common/spl/spl_fit.c
common/spl/spl_mmc.c
common/spl/spl_ubi.c [new file with mode: 0644]
configs/T1042RDB_PI_NAND_SECURE_BOOT_defconfig [new file with mode: 0644]
configs/am335x_boneblack_vboot_defconfig
configs/am335x_evm_defconfig
configs/am43xx_evm_defconfig
configs/am43xx_hs_evm_defconfig
configs/am57xx_evm_defconfig
configs/am57xx_hs_evm_defconfig
configs/bayleybay_defconfig
configs/chromebook_jerry_defconfig
configs/conga-qeval20-qa3-e3845-internal-uart_defconfig [new file with mode: 0644]
configs/da850evm_defconfig
configs/dra7xx_evm_defconfig
configs/dra7xx_hs_evm_defconfig
configs/dragonboard410c_defconfig
configs/evb-rk3036_defconfig
configs/evb-rk3288_defconfig [new file with mode: 0644]
configs/evb-rk3399_defconfig [new file with mode: 0644]
configs/firefly-rk3288_defconfig
configs/igep0020_defconfig
configs/igep0020_nand_defconfig [deleted file]
configs/k2e_evm_defconfig
configs/k2g_evm_defconfig
configs/k2hk_evm_defconfig
configs/k2l_evm_defconfig
configs/kylin-rk3036_defconfig
configs/ls1021atwr_sdcard_ifc_SECURE_BOOT_defconfig [new file with mode: 0644]
configs/minnowmax_defconfig
configs/orangepi_lite_defconfig [new file with mode: 0644]
configs/orangepi_pc_defconfig
configs/orangepi_pc_plus_defconfig [new file with mode: 0644]
configs/p2771-0000-a02_defconfig [new file with mode: 0644]
configs/p2771-0000-b00_defconfig [new file with mode: 0644]
configs/p2771-0000_defconfig [deleted file]
configs/rock2_defconfig
configs/sandbox_defconfig
configs/sandbox_noblk_defconfig
configs/sandbox_spl_defconfig [new file with mode: 0644]
configs/som-db5800-som-6867_defconfig [new file with mode: 0644]
configs/thunderx_88xx_defconfig
configs/uniphier_ld11_defconfig
configs/uniphier_ld20_defconfig
configs/uniphier_ld4_sld8_defconfig
configs/uniphier_pro4_defconfig
configs/uniphier_pxs2_ld6b_defconfig
configs/uniphier_sld3_defconfig
configs/xilinx_zynqmp_ep_defconfig
configs/xilinx_zynqmp_zc1751_xm015_dc1_defconfig
configs/xilinx_zynqmp_zc1751_xm016_dc2_defconfig
configs/xilinx_zynqmp_zc1751_xm018_dc4_defconfig
configs/xilinx_zynqmp_zc1751_xm019_dc5_defconfig
configs/xilinx_zynqmp_zcu102_defconfig
configs/xilinx_zynqmp_zcu102_revB_defconfig
configs/zynq_microzed_defconfig
configs/zynq_picozed_defconfig
configs/zynq_zc702_defconfig
configs/zynq_zc706_defconfig
configs/zynq_zc770_xm010_defconfig
configs/zynq_zc770_xm011_defconfig
configs/zynq_zc770_xm012_defconfig
configs/zynq_zc770_xm013_defconfig
configs/zynq_zed_defconfig
configs/zynq_zybo_defconfig
disk/part_efi.c
disk/part_iso.c
doc/README.gpt
doc/README.rockchip
doc/README.scrapyard
doc/README.ti-secure
doc/README.ubispl [new file with mode: 0644]
doc/README.x86
doc/SPL/README.spl-secure-boot [new file with mode: 0644]
doc/device-tree-bindings/serial/sh.txt [new file with mode: 0644]
doc/driver-model/of-plat.txt [new file with mode: 0644]
doc/feature-removal-schedule.txt
drivers/Makefile
drivers/bios_emulator/x86emu/sys.c
drivers/clk/clk-uclass.c
drivers/clk/clk_fixed_rate.c
drivers/clk/clk_rk3288.c
drivers/clk/uniphier/clk-uniphier-core.c
drivers/clk/uniphier/clk-uniphier-mio.c
drivers/clk/uniphier/clk-uniphier.h
drivers/core/device-remove.c
drivers/core/device.c
drivers/core/lists.c
drivers/core/regmap.c
drivers/core/root.c
drivers/core/syscon-uclass.c
drivers/core/uclass.c
drivers/crypto/fsl/desc.h
drivers/crypto/fsl/fsl_rsa.c
drivers/crypto/fsl/jr.c
drivers/ddr/fsl/ctrl_regs.c
drivers/dfu/dfu_mmc.c
drivers/fpga/fpga.c
drivers/gpio/gpio-uniphier.c
drivers/gpio/mpc85xx_gpio.c
drivers/i2c/Kconfig
drivers/i2c/fsl_i2c.c
drivers/i2c/i2c-uclass.c
drivers/i2c/i2c-uniphier-f.c
drivers/i2c/i2c-uniphier.c
drivers/i2c/mvtwsi.c
drivers/i2c/omap24xx_i2c.c
drivers/misc/Kconfig
drivers/misc/Makefile
drivers/misc/cros_ec_sandbox.c
drivers/misc/i2c_eeprom.c
drivers/misc/spltest_sandbox.c [new file with mode: 0644]
drivers/mmc/Kconfig
drivers/mmc/Makefile
drivers/mmc/dw_mmc.c
drivers/mmc/exynos_dw_mmc.c
drivers/mmc/mmc-uclass.c
drivers/mmc/mmc.c
drivers/mmc/mmc_boot.c [new file with mode: 0644]
drivers/mmc/mmc_legacy.c
drivers/mmc/mmc_private.h
drivers/mmc/msm_sdhci.c
drivers/mmc/rockchip_dw_mmc.c
drivers/mmc/rockchip_sdhci.c [new file with mode: 0644]
drivers/mmc/sandbox_mmc.c
drivers/mmc/sdhci.c
drivers/mmc/sunxi_mmc.c
drivers/mmc/uniphier-sd.c
drivers/mtd/cfi_flash.c
drivers/mtd/nand/Kconfig
drivers/mtd/nand/Makefile
drivers/mtd/nand/fsl_ifc_spl.c
drivers/mtd/nand/mxs_nand.c
drivers/mtd/nand/nand_base.c
drivers/mtd/nand/nand_ids.c
drivers/mtd/nand/nand_spl_simple.c
drivers/mtd/nand/omap_gpmc.c
drivers/mtd/nand/sunxi_nand.c [new file with mode: 0644]
drivers/mtd/nand/tegra_nand.c
drivers/mtd/onenand/onenand_base.c
drivers/mtd/onenand/onenand_spl.c
drivers/mtd/onenand/onenand_uboot.c
drivers/mtd/spi/Kconfig
drivers/mtd/spi/Makefile
drivers/mtd/spi/sunxi_spi_spl.c [new file with mode: 0644]
drivers/mtd/ubispl/Makefile [new file with mode: 0644]
drivers/mtd/ubispl/ubi-wrapper.h [new file with mode: 0644]
drivers/mtd/ubispl/ubispl.c [new file with mode: 0644]
drivers/mtd/ubispl/ubispl.h [new file with mode: 0644]
drivers/net/Kconfig
drivers/net/Makefile
drivers/net/fm/Makefile
drivers/net/fm/ls1046.c [new file with mode: 0644]
drivers/net/sun8i_emac.c [new file with mode: 0644]
drivers/pci/pci_rom.c
drivers/pinctrl/Kconfig
drivers/pinctrl/rockchip/Makefile
drivers/pinctrl/rockchip/pinctrl_rk3288.c
drivers/pinctrl/uniphier/pinctrl-uniphier-core.c
drivers/pinctrl/uniphier/pinctrl-uniphier-ld11.c
drivers/pinctrl/uniphier/pinctrl-uniphier-ld20.c
drivers/pinctrl/uniphier/pinctrl-uniphier-ld4.c
drivers/pinctrl/uniphier/pinctrl-uniphier-ld6b.c
drivers/pinctrl/uniphier/pinctrl-uniphier-pro4.c
drivers/pinctrl/uniphier/pinctrl-uniphier-pro5.c
drivers/pinctrl/uniphier/pinctrl-uniphier-pxs2.c
drivers/pinctrl/uniphier/pinctrl-uniphier-sld8.c
drivers/pinctrl/uniphier/pinctrl-uniphier.h
drivers/rtc/date.c
drivers/serial/Kconfig
drivers/serial/Makefile
drivers/serial/ns16550.c
drivers/serial/sandbox.c
drivers/serial/serial-uclass.c
drivers/serial/serial_rockchip.c [new file with mode: 0644]
drivers/serial/serial_sh.c
drivers/serial/serial_stm32x7.c
drivers/serial/serial_uniphier.c
drivers/serial/serial_zynq.c
drivers/spi/cadence_qspi.c
drivers/spi/cadence_qspi.h
drivers/spi/cadence_qspi_apb.c
drivers/spi/davinci_spi.c
drivers/spi/spi-uclass.c
drivers/usb/gadget/dwc2_udc_otg.c
drivers/usb/gadget/dwc2_udc_otg_regs.h
drivers/usb/gadget/dwc2_udc_otg_xfer_dma.c
drivers/usb/host/Kconfig
drivers/usb/musb-new/musb_dsps.c
drivers/usb/phy/Makefile
drivers/usb/phy/rockchip_usb2_phy.c [new file with mode: 0644]
drivers/video/rockchip/rk_vop.c
drivers/video/tegra.c
dts/Kconfig
include/asm-generic/global_data.h
include/clk.h
include/common.h
include/config_fsl_chain_trust.h
include/configs/B4860QDS.h
include/configs/BSC9131RDB.h
include/configs/BSC9132QDS.h
include/configs/C29XPCIE.h
include/configs/MPC8308RDB.h
include/configs/MPC8313ERDB.h
include/configs/MPC8315ERDB.h
include/configs/MPC8323ERDB.h
include/configs/MPC832XEMDS.h
include/configs/MPC8349EMDS.h
include/configs/MPC8349ITX.h
include/configs/MPC837XEMDS.h
include/configs/MPC837XERDB.h
include/configs/MPC8536DS.h
include/configs/MPC8544DS.h
include/configs/MPC8548CDS.h
include/configs/MPC8572DS.h
include/configs/P1010RDB.h
include/configs/P1022DS.h
include/configs/P1023RDB.h
include/configs/P2041RDB.h
include/configs/T102xRDB.h
include/configs/T1040QDS.h
include/configs/T104xRDB.h
include/configs/T208xQDS.h
include/configs/T208xRDB.h
include/configs/T4240QDS.h
include/configs/T4240RDB.h
include/configs/arndale.h
include/configs/bcm_ep_board.h
include/configs/controlcenterd.h
include/configs/corenet_ds.h
include/configs/cyrus.h
include/configs/dragonboard410c.h
include/configs/evb-rk3288.h [new file with mode: 0644]
include/configs/evb_rk3399.h [new file with mode: 0644]
include/configs/jetson-tk1.h
include/configs/k2g_evm.h
include/configs/ls1021aqds.h
include/configs/ls1021atwr.h
include/configs/ls1043a_common.h
include/configs/ls1043ardb.h
include/configs/microblaze-generic.h
include/configs/mxs.h
include/configs/omap3_igep00x0.h
include/configs/p1_p2_rdb_pc.h
include/configs/p1_twr.h
include/configs/rk3036_common.h
include/configs/rk3288_common.h
include/configs/rk3399_common.h [new file with mode: 0644]
include/configs/sandbox.h
include/configs/sandbox_spl.h [new file with mode: 0644]
include/configs/sbc8548.h
include/configs/som-db5800-som-6867.h [new file with mode: 0644]
include/configs/stm32f746-disco.h
include/configs/sun6i.h
include/configs/sun7i.h
include/configs/sunxi-common.h
include/configs/ti_armv7_common.h
include/configs/ti_armv7_keystone2.h
include/configs/uniphier.h
include/configs/v38b.h
include/configs/vexpress_ca15_tc2.h
include/configs/xilinx_zynqmp_ep.h
include/configs/xpedite1000.h
include/configs/xpedite517x.h
include/configs/xpedite520x.h
include/configs/xpedite537x.h
include/configs/xpedite550x.h
include/configs/zynq-common.h
include/configs/zynq_microzed.h [deleted file]
include/configs/zynq_picozed.h [deleted file]
include/configs/zynq_zc70x.h
include/configs/zynq_zc770.h [deleted file]
include/configs/zynq_zed.h [deleted file]
include/configs/zynq_zybo.h
include/dm/device.h
include/dm/platdata.h
include/dm/uclass-id.h
include/dm/uclass.h
include/dt-bindings/clock/rk3399-cru.h [new file with mode: 0644]
include/dt-structs.h [new file with mode: 0644]
include/dwmmc.h
include/fdtdec.h
include/fsl_validate.h
include/gdsys_fpga.h
include/i2c_eeprom.h
include/image.h
include/linux/io.h
include/linux/mtd/mtd.h
include/linux/mtd/nand.h
include/linux/mtd/omap_gpmc.h
include/linux/types.h
include/linux/usb/xhci-fsl.h
include/mmc.h
include/nand.h
include/net.h
include/onenand_uboot.h
include/os.h
include/regmap.h
include/sdhci.h
include/spl.h
include/syscon.h
include/ubispl.h [new file with mode: 0644]
include/usb/dwc2_udc.h
include/usb/ehci-ci.h
lib/Makefile
lib/efi_loader/efi_memory.c
lib/fdtdec.c
lib/hashtable.c
lib/libfdt/libfdt.swig [new file with mode: 0644]
lib/libfdt/setup.py [new file with mode: 0644]
lib/libfdt/test_libfdt.py [new file with mode: 0644]
lib/rsa/rsa-sign.c
lib/tiny-printf.c
net/eth_internal.h
post/cpu/ppc4xx/ether.c
scripts/Makefile.host
scripts/Makefile.spl
test/README [new file with mode: 0644]
test/py/conftest.py
test/py/multiplexed_log.py
test/py/tests/test_ofplatdata.py [new file with mode: 0644]
test/py/tests/test_vboot.py [new file with mode: 0644]
test/py/tests/vboot/sandbox-kernel.dts [new file with mode: 0644]
test/py/tests/vboot/sandbox-u-boot.dts [new file with mode: 0644]
test/py/tests/vboot/sign-configs-sha1.its [new file with mode: 0644]
test/py/tests/vboot/sign-configs-sha256.its [new file with mode: 0644]
test/py/tests/vboot/sign-images-sha1.its [new file with mode: 0644]
test/py/tests/vboot/sign-images-sha256.its [new file with mode: 0644]
test/py/u_boot_console_base.py
test/py/u_boot_console_sandbox.py
test/py/u_boot_spawn.py
test/py/u_boot_utils.py
test/run [new file with mode: 0755]
test/vboot/.gitignore [deleted file]
test/vboot/sandbox-kernel.dts [deleted file]
test/vboot/sandbox-u-boot.dts [deleted file]
test/vboot/sign-configs-sha1.its [deleted file]
test/vboot/sign-configs-sha256.its [deleted file]
test/vboot/sign-images-sha1.its [deleted file]
test/vboot/sign-images-sha256.its [deleted file]
test/vboot/vboot_test.sh [deleted file]
tools/Makefile
tools/dtoc/.gitignore [new file with mode: 0644]
tools/dtoc/dtoc [new symlink]
tools/dtoc/dtoc.py [new file with mode: 0755]
tools/dtoc/fdt.py [new file with mode: 0644]
tools/dtoc/fdt_fallback.py [new file with mode: 0644]
tools/dtoc/fdt_util.py [new file with mode: 0644]
tools/env/fw_env.c
tools/env/fw_env.config
tools/env/fw_env.h
tools/fit_image.c
tools/image-host.c
tools/mkimage.c
tools/patman/patchstream.py
tools/rkcommon.c

diff --git a/Kconfig b/Kconfig
index 3ceff250321e2d3c50575939f100317369247d49..ef12f9fbee403c2e9786764f64ff2070f6e336cb 100644 (file)
--- 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"
index 88128ec72a26878740dc3ac0719252819654bea4..bccfbaa11db76c4d85d70b34db1ed8a1ab69774c 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -3,9 +3,9 @@
 #
 
 VERSION = 2016
-PATCHLEVEL = 07
+PATCHLEVEL = 09
 SUBLEVEL =
-EXTRAVERSION =
+EXTRAVERSION = -rc1
 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 e86934af696474a7def7b8c959973dcc5d9865d9..cadb571166bf4117730f81fd044d0beb21b8f1b3 100644 (file)
--- 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.
 
@@ -3586,6 +3586,10 @@ FIT uImage format:
                Support for NAND boot using simple NAND drivers that
                expose the cmd_ctrl() interface.
 
+               CONFIG_SPL_UBI
+               Support for a lightweight UBI (fastmap) scanner and
+               loader
+
                CONFIG_SPL_MTD_SUPPORT
                Support for the MTD subsystem within SPL.  Useful for
                environment on NAND support within SPL.
@@ -3769,10 +3773,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.
 
@@ -3838,9 +3843,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
@@ -4812,7 +4814,7 @@ Low Level (hardware related) configuration options:
 
 - CONFIG_SKIP_LOWLEVEL_INIT_ONLY
                [ARM926EJ-S only] This allows just the call to lowlevel_init()
-               to be skipped. The normal CPU15 init (such as enabling the
+               to be skipped. The normal CP15 init (such as enabling the
                instruction cache) is still performed.
 
 - CONFIG_SPL_BUILD
index 04e4f4a44eff9ce9d6e4688a978e1179b7599c66..67c291682a655a4bc545a4cd86cf2b52eb29808d 100644 (file)
@@ -25,7 +25,7 @@ DECLARE_GLOBAL_DATA_PTR;
 
 #define errf(fmt, args...) do { printf("ERROR @ %s(): ", __func__); printf(fmt, ##args); } while (0)
 
-#ifdef CONFIG_CMD_NET
+#if defined(CONFIG_CMD_NET) && !defined(CONFIG_DM_ETH)
 
 static int dev_valid_net(void *cookie)
 {
index 566f04430890e212fcd16331d7fd51dbe0103d0c..92d4b97701bf6b160e99f2214328fac1046c47e8 100644 (file)
@@ -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"
index 3237a74f722358bdb76207fa0244eeb1fb3a403f..4a62d4b1083dd21c7bf120a00548c5923f1a670f 100644 (file)
@@ -669,6 +669,8 @@ config ARCH_ZYNQMP
        select OF_CONTROL
        select DM_SERIAL
        select SUPPORT_SPL
+       select CLK
+       select SPL_CLK
 
 config TEGRA
        bool "NVIDIA Tegra"
@@ -838,11 +840,19 @@ config STM32
 
 config ARCH_ROCKCHIP
        bool "Support Rockchip SoCs"
-       select SUPPORT_SPL
-       select SPL
        select OF_CONTROL
-       select CPU_V7
+       select BLK
        select DM
+       select SPL_DM if SPL
+       select SYS_MALLOC_F
+       select SPL_SYS_MALLOC_SIMPLE if SPL
+       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"
index 9a5a9747c48a4b82380c34f568fb1239be0cb6cd..8f8586295efd76e57f00c07c0214c103e8d99d4b 100644 (file)
@@ -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
index 1e4c2142b1317cea432c950af40486b35876fe53..7244c2e7d79e6e6dd34b3009d10b4dc10db4b07b 100644 (file)
@@ -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))
index 2839c863e82c790f2345332f8b7eb23033d96bab..2119382ab2451583a0399672e0bf914389d8743c 100644 (file)
@@ -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))
index afeaac84dec1016b090bb6f41bca613daee8547c..bd6108eec06caf2118f6f792c7baa02f387228f3 100644 (file)
@@ -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
index ddd8d12d51700f4f2fac80a8e1cc72ffb361203b..0d4bfbc55b313f2506c8c83af71972ca9cb96823 100644 (file)
@@ -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/
index 6d95d327b45b525b5bbc43bb8e232a9a2acf0be4..d4eb21ca14e19f68cebf9a6a863076af13e8890e 100644 (file)
@@ -26,6 +26,7 @@ endif
 else
 ifeq ($(CONFIG_TI_SECURE_DEVICE),y)
 ALL-$(CONFIG_QSPI_BOOT) += u-boot_HS_XIP_X-LOADER
+ALL-$(CONFIG_SPL_LOAD_FIT) += u-boot_HS.img
 endif
 ALL-y  += u-boot.img
 endif
index 888cf1f73269cb39d245f148756a8b8a0f12d659..6acf30c5db00fe4e363a0fe449e1193cc8306643 100644 (file)
@@ -120,12 +120,15 @@ void config_sdram_emif4d5(const struct emif_regs *regs, int nr)
 
        writel(regs->sdram_config, &emif_reg[nr]->emif_sdram_config);
        writel(regs->sdram_config, &cstat->secure_emif_sdram_config);
+
+       /* Wait 1ms because of L3 timeout error */
+       udelay(1000);
+
        writel(regs->ref_ctrl, &emif_reg[nr]->emif_sdram_ref_ctrl);
        writel(regs->ref_ctrl, &emif_reg[nr]->emif_sdram_ref_ctrl_shdw);
 
        /* Perform hardware leveling for DDR3 */
        if (emif_sdram_type(regs->sdram_config) == EMIF_SDRAM_TYPE_DDR3) {
-               udelay(1000);
                writel(readl(&emif_reg[nr]->emif_ddr_ext_phy_ctrl_36) |
                       0x100, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_36);
                writel(readl(&emif_reg[nr]->emif_ddr_ext_phy_ctrl_36_shdw) |
@@ -289,19 +292,14 @@ static void ext_phy_settings_hwlvl(const struct emif_regs *regs, int nr)
 void config_ddr_phy(const struct emif_regs *regs, int nr)
 {
        /*
-        * Disable initialization and refreshes for now until we
-        * finish programming EMIF regs.
-        * Also set time between rising edge of DDR_RESET to rising
-        * edge of DDR_CKE to > 500us per memory spec.
+        * Disable initialization and refreshes for now until we finish
+        * programming EMIF regs and set time between rising edge of
+        * DDR_RESET to rising edge of DDR_CKE to > 500us per memory spec.
+        * We currently hardcode a value based on a max expected frequency
+        * of 400MHz.
         */
-#ifndef CONFIG_AM43XX
-       setbits_le32(&emif_reg[nr]->emif_sdram_ref_ctrl,
-                    EMIF_REG_INITREF_DIS_MASK);
-#endif
-       if (regs->zq_config)
-               /* Set time between rising edge of DDR_RESET to rising
-                * edge of DDR_CKE to > 500us per memory spec. */
-               writel(0x00003100, &emif_reg[nr]->emif_sdram_ref_ctrl);
+       writel(EMIF_REG_INITREF_DIS_MASK | 0x3100,
+               &emif_reg[nr]->emif_sdram_ref_ctrl);
 
        writel(regs->emif_ddr_phy_ctlr_1,
                &emif_reg[nr]->emif_ddr_phy_ctrl_1);
index dc309dac909a1aefeb8490da03db23cab0dff8d9..52f18565db2726844a075b82e15b60a8978c16f7 100644 (file)
 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)
 {
 }
index cf5cd48bcbec037015e422273f6b8a6df292a535..8f386800f6c2e74e26f83ef85ed96dfd0acea02a 100644 (file)
 #include <asm/arch-armv7/generictimer.h>
 #include <asm/psci.h>
 
+#define RCPM_TWAITSR           0x04C
+
 #define SCFG_CORE0_SFT_RST      0x130
 #define SCFG_CORESRENCR         0x204
 
-#define DCFG_CCSR_BRR           0x0E4
-#define DCFG_CCSR_SCRATCHRW1    0x200
+#define DCFG_CCSR_RSTCR                        0x0B0
+#define DCFG_CCSR_RSTCR_RESET_REQ      0x2
+#define DCFG_CCSR_BRR                  0x0E4
+#define DCFG_CCSR_SCRATCHRW1           0x200
+
+#define PSCI_FN_PSCI_VERSION_FEATURE_MASK      0x0
+#define PSCI_FN_CPU_SUSPEND_FEATURE_MASK       0x0
+#define PSCI_FN_CPU_OFF_FEATURE_MASK           0x0
+#define PSCI_FN_CPU_ON_FEATURE_MASK            0x0
+#define PSCI_FN_AFFINITY_INFO_FEATURE_MASK     0x0
+#define PSCI_FN_SYSTEM_OFF_FEATURE_MASK                0x0
+#define PSCI_FN_SYSTEM_RESET_FEATURE_MASK      0x0
 
        .pushsection ._secure.text, "ax"
 
        .arch_extension sec
 
+       .align  5
+
 #define        ONE_MS          (GENERIC_TIMER_CLK / 1000)
 #define        RESET_WAIT      (30 * ONE_MS)
 
+.globl psci_version
+psci_version:
+       movw    r0, #0
+       movt    r0, #1
+
+       bx      lr
+
+_ls102x_psci_supported_table:
+       .word   ARM_PSCI_0_2_FN_PSCI_VERSION
+       .word   PSCI_FN_PSCI_VERSION_FEATURE_MASK
+       .word   ARM_PSCI_0_2_FN_CPU_SUSPEND
+       .word   PSCI_FN_CPU_SUSPEND_FEATURE_MASK
+       .word   ARM_PSCI_0_2_FN_CPU_OFF
+       .word   PSCI_FN_CPU_OFF_FEATURE_MASK
+       .word   ARM_PSCI_0_2_FN_CPU_ON
+       .word   PSCI_FN_CPU_ON_FEATURE_MASK
+       .word   ARM_PSCI_0_2_FN_AFFINITY_INFO
+       .word   PSCI_FN_AFFINITY_INFO_FEATURE_MASK
+       .word   ARM_PSCI_0_2_FN_SYSTEM_OFF
+       .word   PSCI_FN_SYSTEM_OFF_FEATURE_MASK
+       .word   ARM_PSCI_0_2_FN_SYSTEM_RESET
+       .word   PSCI_FN_SYSTEM_RESET_FEATURE_MASK
+       .word   0
+       .word   ARM_PSCI_RET_NI
+
+.globl psci_features
+psci_features:
+       adr     r2, _ls102x_psci_supported_table
+1:     ldr     r3, [r2]
+       cmp     r3, #0
+       beq     out_psci_features
+       cmp     r1, r3
+       addne   r2, r2, #8
+       bne     1b
+
+out_psci_features:
+       ldr     r0, [r2, #4]
+       bx      lr
+
+@ r0: return value ARM_PSCI_RET_SUCCESS or ARM_PSCI_RET_INVAL
+@ r1: input target CPU ID in MPIDR format, original value in r1 may be dropped
+@ r4: output validated CPU ID if ARM_PSCI_RET_SUCCESS returns, meaningless for
+@ ARM_PSCI_RET_INVAL,suppose caller saves r4 before calling
+LENTRY(psci_check_target_cpu_id)
+       @ Get the real CPU number
+       and     r4, r1, #0xff
+       mov     r0, #ARM_PSCI_RET_INVAL
+
+       @ Bit[31:24], bits must be zero.
+       tst     r1, #0xff000000
+       bxne    lr
+
+       @ Affinity level 2 - Cluster: only one cluster in LS1021xa.
+       tst     r1, #0xff0000
+       bxne    lr
+
+       @ Affinity level 1 - Processors: should be in 0xf00 format.
+       lsr     r1, r1, #8
+       teq     r1, #0xf
+       bxne    lr
+
+       @ Affinity level 0 - CPU: only 0, 1 are valid in LS1021xa.
+       cmp     r4, #2
+       bxge    lr
+
+       mov     r0, #ARM_PSCI_RET_SUCCESS
+       bx      lr
+ENDPROC(psci_check_target_cpu_id)
+
        @ r1 = target CPU
        @ 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
+       bl      psci_check_target_cpu_id
+       cmp     r0, #ARM_PSCI_RET_INVAL
+       beq     out_psci_cpu_on
 
-       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 +186,8 @@ holdoff_release:
        @ Return
        mov     r0, #ARM_PSCI_RET_SUCCESS
 
-       pop     {lr}
+out_psci_cpu_on:
+       pop     {r4, r5, r6, lr}
        bx      lr
 
 .globl psci_cpu_off
@@ -111,16 +197,50 @@ psci_cpu_off:
 1:     wfi
        b       1b
 
-.globl psci_arch_init
-psci_arch_init:
-       mov     r6, lr
+.globl psci_affinity_info
+psci_affinity_info:
+       push    {lr}
+
+       mov     r0, #ARM_PSCI_RET_INVAL
+
+       @ Verify Affinity level
+       cmp     r2, #0
+       bne     out_affinity_info
+
+       bl      psci_check_target_cpu_id
+       cmp     r0, #ARM_PSCI_RET_INVAL
+       beq     out_affinity_info
+       mov     r1, r4
+
+       @ Get RCPM base address
+       movw    r4, #(CONFIG_SYS_FSL_RCPM_ADDR & 0xffff)
+       movt    r4, #(CONFIG_SYS_FSL_RCPM_ADDR >> 16)
+
+       mov     r0, #PSCI_AFFINITY_LEVEL_ON
+
+       @ Detect target CPU state
+       ldr     r2, [r4, #RCPM_TWAITSR]
+       rev     r2, r2
+       lsr     r2, r2, r1
+       ands    r2, r2, #1
+       beq     out_affinity_info
+
+       mov     r0, #PSCI_AFFINITY_LEVEL_OFF
 
-       bl      psci_get_cpu_id
-       bl      psci_get_cpu_stack_top
-       mov     sp, r0
+out_affinity_info:
+       pop     {pc}
+
+.globl psci_system_reset
+psci_system_reset:
+       @ Get DCFG base address
+       movw    r1, #(CONFIG_SYS_FSL_GUTS_ADDR & 0xffff)
+       movt    r1, #(CONFIG_SYS_FSL_GUTS_ADDR >> 16)
 
-       bx      r6
+       mov     r2, #DCFG_CCSR_RSTCR_RESET_REQ
+       rev     r2, r2
+       str     r2, [r1, #DCFG_CCSR_RSTCR]
+
+1:     wfi
+       b       1b
 
-       .globl psci_text_end
-psci_text_end:
        .popsection
index 9a330476cf5f32c9c83444238df3e805b0adbc1d..502552d1718fe32a4ddd45d52984805c9039b14a 100644 (file)
@@ -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
index 34c6ab33f058745993221ec2c1c097a86241fc98..96e88d6184e40b06a67ade00ac67e309b8f094a7 100644 (file)
@@ -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
index b7563edbe6bc0d81891abdd47f62f85b5a1be663..95ce9387b83e972414b6de2d5711a9f40fe097df 100644 (file)
@@ -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
index 87a7ac03f92021f50bd9252e6d087820c1cbc6b4..3172bae105bb120b79d33b900b3a9e09ea89e2b5 100644 (file)
@@ -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
index c7bb101be8e96fd966101cfa7bf3a03884ca74b8..1122439e38b34a4b3ec70293cf357907b9652cdd 100644 (file)
@@ -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
index 9a9c764b4d11319d1743256b1ac1eee3bee838b1..2b790105b0bb51036a6e38d849121342b0e65e63 100644 (file)
@@ -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)
index 2f9693f28e9ded3d6c26dfde701ea20f9f33512d..f3172939889296dec5c5ec797058505c60372ed1 100644 (file)
@@ -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();
index 528313584f3dd07e28dda860a2dc6d7404c7f074..66a3b3d26c950a48f29e19cab4681eff98f9e766 100644 (file)
 #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)
index fc4290c3c4e0227443f8a8a5a079d8187aa74681..d72e82e028338b01d149c6f2fda86d6e839bd2e6 100644 (file)
 #include <asm/arch/sys_proto.h>
 #include <command.h>
 #include <linux/mtd/omap_gpmc.h>
+#include <jffs2/load_kernel.h>
 
-struct gpmc *gpmc_cfg;
+const struct gpmc *gpmc_cfg = (struct gpmc *)GPMC_BASE;
+
+#if defined(CONFIG_NOR)
+char gpmc_cs0_flash = MTD_DEV_TYPE_NOR;
+#elif defined(CONFIG_NAND) || defined(CONFIG_CMD_NAND)
+char gpmc_cs0_flash = MTD_DEV_TYPE_NAND;
+#elif defined(CONFIG_CMD_ONENAND)
+char gpmc_cs0_flash = MTD_DEV_TYPE_ONENAND;
+#else
+char gpmc_cs0_flash = -1;
+#endif
 
 #if defined(CONFIG_OMAP34XX)
 /********************************************************
@@ -50,8 +61,8 @@ u32 mem_ok(u32 cs)
 }
 #endif
 
-void enable_gpmc_cs_config(const u32 *gpmc_config, struct gpmc_cs *cs, u32 base,
-                       u32 size)
+void enable_gpmc_cs_config(const u32 *gpmc_config, const struct gpmc_cs *cs,
+                               u32 base, u32 size)
 {
        writel(0, &cs->config7);
        sdelay(1000);
@@ -68,6 +79,81 @@ void enable_gpmc_cs_config(const u32 *gpmc_config, struct gpmc_cs *cs, u32 base,
        sdelay(2000);
 }
 
+void set_gpmc_cs0(int flash_type)
+{
+       const u32 *gpmc_regs;
+       u32 base, size;
+#if defined(CONFIG_NOR)
+       const u32 gpmc_regs_nor[GPMC_MAX_REG] = {
+               STNOR_GPMC_CONFIG1,
+               STNOR_GPMC_CONFIG2,
+               STNOR_GPMC_CONFIG3,
+               STNOR_GPMC_CONFIG4,
+               STNOR_GPMC_CONFIG5,
+               STNOR_GPMC_CONFIG6,
+               STNOR_GPMC_CONFIG7
+       };
+#endif
+#if defined(CONFIG_NAND) || defined(CONFIG_CMD_NAND)
+       const u32 gpmc_regs_nand[GPMC_MAX_REG] = {
+               M_NAND_GPMC_CONFIG1,
+               M_NAND_GPMC_CONFIG2,
+               M_NAND_GPMC_CONFIG3,
+               M_NAND_GPMC_CONFIG4,
+               M_NAND_GPMC_CONFIG5,
+               M_NAND_GPMC_CONFIG6,
+               0
+       };
+#endif
+#if defined(CONFIG_CMD_ONENAND)
+       const u32 gpmc_regs_onenand[GPMC_MAX_REG] = {
+               ONENAND_GPMC_CONFIG1,
+               ONENAND_GPMC_CONFIG2,
+               ONENAND_GPMC_CONFIG3,
+               ONENAND_GPMC_CONFIG4,
+               ONENAND_GPMC_CONFIG5,
+               ONENAND_GPMC_CONFIG6,
+               0
+       };
+#endif
+
+       switch (flash_type) {
+#if defined(CONFIG_NOR)
+       case MTD_DEV_TYPE_NOR:
+               gpmc_regs = gpmc_regs_nor;
+               base = CONFIG_SYS_FLASH_BASE;
+               size = (CONFIG_SYS_FLASH_SIZE > 0x08000000) ? GPMC_SIZE_256M :
+                     ((CONFIG_SYS_FLASH_SIZE > 0x04000000) ? GPMC_SIZE_128M :
+                     ((CONFIG_SYS_FLASH_SIZE > 0x02000000) ? GPMC_SIZE_64M  :
+                     ((CONFIG_SYS_FLASH_SIZE > 0x01000000) ? GPMC_SIZE_32M  :
+                                                             GPMC_SIZE_16M)));
+               break;
+#endif
+#if defined(CONFIG_NAND) || defined(CONFIG_CMD_NAND)
+       case MTD_DEV_TYPE_NAND:
+               gpmc_regs = gpmc_regs_nand;
+               base = CONFIG_SYS_NAND_BASE;
+               size = GPMC_SIZE_16M;
+               break;
+#endif
+#if defined(CONFIG_CMD_ONENAND)
+       case MTD_DEV_TYPE_ONENAND:
+               gpmc_regs = gpmc_regs_onenand;
+               base = CONFIG_SYS_ONENAND_BASE;
+               size = GPMC_SIZE_128M;
+               break;
+#endif
+       default:
+               /* disable the GPMC0 config set by ROM code */
+               writel(0, &gpmc_cfg->cs[0].config7);
+               sdelay(1000);
+               return;
+       }
+
+       /* enable chip-select specific configurations */
+       enable_gpmc_cs_config(gpmc_regs, &gpmc_cfg->cs[0], base, size);
+}
+
 /*****************************************************
  * gpmc_init(): init gpmc bus
  * Init GPMC for x16, MuxMode (SDRAM in x32).
@@ -75,70 +161,14 @@ void enable_gpmc_cs_config(const u32 *gpmc_config, struct gpmc_cs *cs, u32 base,
  *****************************************************/
 void gpmc_init(void)
 {
-       /* putting a blanket check on GPMC based on ZeBu for now */
-       gpmc_cfg = (struct gpmc *)GPMC_BASE;
-#if defined(CONFIG_NOR)
-/* configure GPMC for NOR */
-       const u32 gpmc_regs[GPMC_MAX_REG] = {   STNOR_GPMC_CONFIG1,
-                                               STNOR_GPMC_CONFIG2,
-                                               STNOR_GPMC_CONFIG3,
-                                               STNOR_GPMC_CONFIG4,
-                                               STNOR_GPMC_CONFIG5,
-                                               STNOR_GPMC_CONFIG6,
-                                               STNOR_GPMC_CONFIG7
-                                               };
-       u32 base = CONFIG_SYS_FLASH_BASE;
-       u32 size =      (CONFIG_SYS_FLASH_SIZE  > 0x08000000) ? GPMC_SIZE_256M :
-       /* > 64MB */    ((CONFIG_SYS_FLASH_SIZE > 0x04000000) ? GPMC_SIZE_128M :
-       /* > 32MB */    ((CONFIG_SYS_FLASH_SIZE > 0x02000000) ? GPMC_SIZE_64M  :
-       /* > 16MB */    ((CONFIG_SYS_FLASH_SIZE > 0x01000000) ? GPMC_SIZE_32M  :
-       /* min 16MB */  GPMC_SIZE_16M)));
-#elif defined(CONFIG_NAND) || defined(CONFIG_CMD_NAND)
-/* configure GPMC for NAND */
-       const u32  gpmc_regs[GPMC_MAX_REG] = {  M_NAND_GPMC_CONFIG1,
-                                               M_NAND_GPMC_CONFIG2,
-                                               M_NAND_GPMC_CONFIG3,
-                                               M_NAND_GPMC_CONFIG4,
-                                               M_NAND_GPMC_CONFIG5,
-                                               M_NAND_GPMC_CONFIG6,
-                                               0
-                                               };
-       u32 base = CONFIG_SYS_NAND_BASE;
-       u32 size = GPMC_SIZE_16M;
-
-#elif defined(CONFIG_CMD_ONENAND)
-       const u32 gpmc_regs[GPMC_MAX_REG] = {   ONENAND_GPMC_CONFIG1,
-                                               ONENAND_GPMC_CONFIG2,
-                                               ONENAND_GPMC_CONFIG3,
-                                               ONENAND_GPMC_CONFIG4,
-                                               ONENAND_GPMC_CONFIG5,
-                                               ONENAND_GPMC_CONFIG6,
-                                               0
-                                               };
-       u32 size = GPMC_SIZE_128M;
-       u32 base = CONFIG_SYS_ONENAND_BASE;
-#else
-       const u32 gpmc_regs[GPMC_MAX_REG] = { 0, 0, 0, 0, 0, 0, 0 };
-       u32 size = 0;
-       u32 base = 0;
-#endif
        /* global settings */
        writel(0x00000008, &gpmc_cfg->sysconfig);
        writel(0x00000000, &gpmc_cfg->irqstatus);
        writel(0x00000000, &gpmc_cfg->irqenable);
        /* disable timeout, set a safe reset value */
        writel(0x00001ff0, &gpmc_cfg->timeout_control);
-#ifdef CONFIG_NOR
-       writel(0x00000200, &gpmc_cfg->config);
-#else
-       writel(0x00000012, &gpmc_cfg->config);
-#endif
-       /*
-        * Disable the GPMC0 config set by ROM code
-        */
-       writel(0, &gpmc_cfg->cs[0].config7);
-       sdelay(1000);
-       /* enable chip-select specific configurations */
-       if (base != 0)
-               enable_gpmc_cs_config(gpmc_regs, &gpmc_cfg->cs[0], base, size);
+       writel(gpmc_cs0_flash == MTD_DEV_TYPE_NOR ?
+               0x00000200 : 0x00000012, &gpmc_cfg->config);
+
+       set_gpmc_cs0(gpmc_cs0_flash);
 }
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 (file)
index 0000000..246a239
--- /dev/null
@@ -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;
+}
index db6de0911bfe1fc120472335628bf11fa74ab217..0e2f0a2f6d67127537a9b5256b744d3ce3cc507e 100644 (file)
  */
 
 #include <common.h>
+#include <jffs2/load_kernel.h>
 #include <linux/mtd/nand.h>
+#include <linux/mtd/omap_gpmc.h>
 #include <asm/io.h>
 #include <asm/arch/sys_proto.h>
 #include <asm/arch/mem.h>
 
-static struct gpmc *gpmc_config = (struct gpmc *)GPMC_BASE;
-
-/* nand_command: Send a flash command to the flash chip */
-static void nand_command(u8 command)
-{
-       writeb(command, &gpmc_config->cs[0].nand_cmd);
-
-       if (command == NAND_CMD_RESET) {
-               unsigned char ret_val;
-               writeb(NAND_CMD_STATUS, &gpmc_config->cs[0].nand_cmd);
-               do {
-                       /* Wait until ready */
-                       ret_val = readl(&gpmc_config->cs[0].nand_dat);
-               } while ((ret_val & NAND_STATUS_READY) != NAND_STATUS_READY);
-       }
-}
-
 /*
  * Many boards will want to know the results of the NAND_CMD_READID command
  * in order to decide what to do about DDR initialization.  This function
  * allows us to do that very early and to pass those results back to the
  * board so it can make whatever decisions need to be made.
  */
-void identify_nand_chip(int *mfr, int *id)
+int identify_nand_chip(int *mfr, int *id)
 {
-       /* Make sure that we have setup GPMC for NAND correctly. */
-       writel(M_NAND_GPMC_CONFIG1, &gpmc_config->cs[0].config1);
-       writel(M_NAND_GPMC_CONFIG2, &gpmc_config->cs[0].config2);
-       writel(M_NAND_GPMC_CONFIG3, &gpmc_config->cs[0].config3);
-       writel(M_NAND_GPMC_CONFIG4, &gpmc_config->cs[0].config4);
-       writel(M_NAND_GPMC_CONFIG5, &gpmc_config->cs[0].config5);
-       writel(M_NAND_GPMC_CONFIG6, &gpmc_config->cs[0].config6);
+       int loops = 1000;
 
-       /*
-        * Enable the config.  The CS size goes in bits 11:8.  We set
-        * bit 6 to enable the CS and the base address goes into bits 5:0.
-        */
-       writel((GPMC_SIZE_128M << 8) | (GPMC_CS_ENABLE << 6) |
-                               ((NAND_BASE >> 24) & GPMC_BASEADDR_MASK),
-                       &gpmc_config->cs[0].config7);
+       /* Make sure that we have setup GPMC for NAND correctly. */
+       set_gpmc_cs0(MTD_DEV_TYPE_NAND);
 
        sdelay(2000);
 
        /* Issue a RESET and then READID */
-       nand_command(NAND_CMD_RESET);
-       nand_command(NAND_CMD_READID);
+       writeb(NAND_CMD_RESET, &gpmc_cfg->cs[0].nand_cmd);
+       writeb(NAND_CMD_STATUS, &gpmc_cfg->cs[0].nand_cmd);
+       while ((readl(&gpmc_cfg->cs[0].nand_dat) & NAND_STATUS_READY)
+                                               != NAND_STATUS_READY) {
+               sdelay(100);
+               if (--loops == 0)
+                       return 1;
+       }
+       writeb(NAND_CMD_READID, &gpmc_cfg->cs[0].nand_cmd);
 
        /* Set the address to read to 0x0 */
-       writeb(0x0, &gpmc_config->cs[0].nand_adr);
+       writeb(0x0, &gpmc_cfg->cs[0].nand_adr);
 
        /* Read off the manufacturer and device id. */
-       *mfr = readb(&gpmc_config->cs[0].nand_dat);
-       *id = readb(&gpmc_config->cs[0].nand_dat);
+       *mfr = readb(&gpmc_cfg->cs[0].nand_dat);
+       *id = readb(&gpmc_cfg->cs[0].nand_dat);
+
+       return 0;
 }
index a7e55a5e2449e0c9d6e4cbb158cf0dc186c1a57b..286ca8688d761b31d08303387f70d3c68d0c7a45 100644 (file)
@@ -15,5 +15,8 @@ else
 ALL-y  += MLO
 endif
 else
+ifeq ($(CONFIG_TI_SECURE_DEVICE),y)
+ALL-$(CONFIG_SPL_LOAD_FIT) += 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 (file)
index 0000000..d14b693
--- /dev/null
@@ -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];
+}
+
index ab408378fcae329592d03b590dc0205cb2272b2b..f80f6e20d1ecee25edf17a7a12f59081f997d198 100644 (file)
@@ -46,20 +46,62 @@ ENTRY(default_psci_vector)
 ENDPROC(default_psci_vector)
 .weak default_psci_vector
 
+ENTRY(psci_version)
 ENTRY(psci_cpu_suspend)
 ENTRY(psci_cpu_off)
 ENTRY(psci_cpu_on)
+ENTRY(psci_affinity_info)
 ENTRY(psci_migrate)
+ENTRY(psci_migrate_info_type)
+ENTRY(psci_migrate_info_up_cpu)
+ENTRY(psci_system_off)
+ENTRY(psci_system_reset)
+ENTRY(psci_features)
+ENTRY(psci_cpu_freeze)
+ENTRY(psci_cpu_default_suspend)
+ENTRY(psci_node_hw_state)
+ENTRY(psci_system_suspend)
+ENTRY(psci_set_suspend_mode)
+ENTRY(psi_stat_residency)
+ENTRY(psci_stat_count)
        mov     r0, #ARM_PSCI_RET_NI    @ Return -1 (Not Implemented)
        mov     pc, lr
+ENDPROC(psci_stat_count)
+ENDPROC(psi_stat_residency)
+ENDPROC(psci_set_suspend_mode)
+ENDPROC(psci_system_suspend)
+ENDPROC(psci_node_hw_state)
+ENDPROC(psci_cpu_default_suspend)
+ENDPROC(psci_cpu_freeze)
+ENDPROC(psci_features)
+ENDPROC(psci_system_reset)
+ENDPROC(psci_system_off)
+ENDPROC(psci_migrate_info_up_cpu)
+ENDPROC(psci_migrate_info_type)
 ENDPROC(psci_migrate)
+ENDPROC(psci_affinity_info)
 ENDPROC(psci_cpu_on)
 ENDPROC(psci_cpu_off)
 ENDPROC(psci_cpu_suspend)
+ENDPROC(psci_version)
+.weak psci_version
 .weak psci_cpu_suspend
 .weak psci_cpu_off
 .weak psci_cpu_on
+.weak psci_affinity_info
 .weak psci_migrate
+.weak psci_migrate_info_type
+.weak psci_migrate_info_up_cpu
+.weak psci_system_off
+.weak psci_system_reset
+.weak psci_features
+.weak psci_cpu_freeze
+.weak psci_cpu_default_suspend
+.weak psci_node_hw_state
+.weak psci_system_suspend
+.weak psci_set_suspend_mode
+.weak psi_stat_residency
+.weak psci_stat_count
 
 _psci_table:
        .word   ARM_PSCI_FN_CPU_SUSPEND
@@ -70,6 +112,42 @@ _psci_table:
        .word   psci_cpu_on
        .word   ARM_PSCI_FN_MIGRATE
        .word   psci_migrate
+       .word   ARM_PSCI_0_2_FN_PSCI_VERSION
+       .word   psci_version
+       .word   ARM_PSCI_0_2_FN_CPU_SUSPEND
+       .word   psci_cpu_suspend
+       .word   ARM_PSCI_0_2_FN_CPU_OFF
+       .word   psci_cpu_off
+       .word   ARM_PSCI_0_2_FN_CPU_ON
+       .word   psci_cpu_on
+       .word   ARM_PSCI_0_2_FN_AFFINITY_INFO
+       .word   psci_affinity_info
+       .word   ARM_PSCI_0_2_FN_MIGRATE
+       .word   psci_migrate
+       .word   ARM_PSCI_0_2_FN_MIGRATE_INFO_TYPE
+       .word   psci_migrate_info_type
+       .word   ARM_PSCI_0_2_FN_MIGRATE_INFO_UP_CPU
+       .word   psci_migrate_info_up_cpu
+       .word   ARM_PSCI_0_2_FN_SYSTEM_OFF
+       .word   psci_system_off
+       .word   ARM_PSCI_0_2_FN_SYSTEM_RESET
+       .word   psci_system_reset
+       .word   ARM_PSCI_1_0_FN_PSCI_FEATURES
+       .word   psci_features
+       .word   ARM_PSCI_1_0_FN_CPU_FREEZE
+       .word   psci_cpu_freeze
+       .word   ARM_PSCI_1_0_FN_CPU_DEFAULT_SUSPEND
+       .word   psci_cpu_default_suspend
+       .word   ARM_PSCI_1_0_FN_NODE_HW_STATE
+       .word   psci_node_hw_state
+       .word   ARM_PSCI_1_0_FN_SYSTEM_SUSPEND
+       .word   psci_system_suspend
+       .word   ARM_PSCI_1_0_FN_SET_SUSPEND_MODE
+       .word   psci_set_suspend_mode
+       .word   ARM_PSCI_1_0_FN_STAT_RESIDENCY
+       .word   psi_stat_residency
+       .word   ARM_PSCI_1_0_FN_STAT_COUNT
+       .word   psci_stat_count
        .word   0
        .word   0
 
@@ -196,29 +274,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)
 
index c2085101685bb28199e38c6e91ea8668027795da..b35b9df4a9d6f7d75a82265a19914946131e1aca 100644 (file)
@@ -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
index a118e9d0c4ada1c73001109d013cd84eaf227c73..7ac84065f4ab99fbf822f47984117525396b2e6d 100644 (file)
 #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 (file)
index 8fa823d..0000000
+++ /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
index 32c368f1455343ac26c2ec8ac24709ff8b2d4899..707dad4829a983d4023acc3aee71abe0d1ced948 100644 (file)
 #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
index 4a53006b6a77f711829b1c12bdcde5b02fee2ea3..db4660e15dae0b0dabc97bc5d0d17b69aec99f57 100644 (file)
@@ -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
index 3d19bbfbe24124df6f3a7680f9b0a5d5adc6050b..acf2460ede2509f17bbd246072a09e6e8826aa14 100644 (file)
@@ -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
index bf8644ccd2e70b6b066af38df530ed3342098c7d..dea14657d9aef4ff3ef974cbceb75dd061536107 100644 (file)
@@ -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/
index 1615542a99f3f62c4228100d70e700c5eb5506ed..ac909a15ffaa6974c2c633a2e73bd00a62c6d41d 100644 (file)
@@ -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 (file)
index 0000000..9ffb49c
--- /dev/null
@@ -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;
+}
index eb2cbc3f7e2b87587a24d4002ce280807ad8d052..8c1317faea26931c64370cf0ff710ec88f0dd23a 100644 (file)
@@ -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
@@ -32,3 +33,7 @@ endif
 ifneq ($(CONFIG_LS1012A),)
 obj-$(CONFIG_SYS_HAS_SERDES) += ls1012a_serdes.o
 endif
+
+ifneq ($(CONFIG_LS1046A),)
+obj-$(CONFIG_SYS_HAS_SERDES) += ls1046a_serdes.o
+endif
index 8062106e3e90fad3df513ab7e4a4e26fbdab2115..e12b77355068a195ab461b5ef2ea19aade1b4317 100644 (file)
 #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,355 +53,106 @@ 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};
+       unsigned int el = current_el();
 
-       /* Invalidate all table entries */
-       memset(level0_table, 0, 0x5000);
+       /* 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;
 
-       /* 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);
+       /* Create early page tables */
+       setup_pgtables();
 
-#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.
-                        */
-               }
-       }
-
-       el = current_el();
-
-       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;
-#endif
-       table.ptr = level0_table;
-
-       /* Invalidate all table entries */
-       memset(level0_table, 0, PGTABLE_SIZE);
-
-       /* 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);
+       int index;
 #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]);
-                       }
+       mem_map = final_map;
 
-               } 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
+        * EL3 MMU is already enabled, just need to invalidate TLB to load the
         * new table. The new table is compatible with the current table, if
         * MMU somehow walks through the new table before invalidation TLB,
         * it still works. So we don't need to turn off MMU here.
+        * When EL2 MMU table is created by calling this function, MMU needs
+        * to be enabled.
         */
+       set_sctlr(get_sctlr() | CR_M);
 }
 
 u64 get_page_table_size(void)
@@ -422,15 +170,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
 
@@ -558,7 +312,8 @@ int print_cpuinfo(void)
                printf("CPU%d(%s):%-4s MHz  ", core,
                       type == TY_ITYP_VER_A7 ? "A7 " :
                       (type == TY_ITYP_VER_A53 ? "A53" :
-                       (type == TY_ITYP_VER_A57 ? "A57" : "   ")),
+                      (type == TY_ITYP_VER_A57 ? "A57" :
+                      (type == TY_ITYP_VER_A72 ? "A72" : "   "))),
                       strmhz(buf, sysinfo.freq_processor[core]));
        }
        printf("\n       Bus:      %-4s MHz  ",
@@ -616,6 +371,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 +379,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
index da5e052569c49bcd5bab96b0fee1cc2c981ebba7..7867c379d4b3ea8765a44ee0f362d759ac663e68 100644 (file)
@@ -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:
 
index 8eee016f11c2681ca0591b67b9ac0247df929656..f7b949aca22ef5953f40f3bd3296045a85c92060 100644 (file)
@@ -3,6 +3,7 @@ SoC overview
        1. LS1043A
        2. LS2080A
        3. LS1012A
+       4. LS1046A
 
 LS1043A
 ---------
@@ -127,3 +128,44 @@ The LS1012A SoC includes the following function and features:
     - Two WatchDog timers
     - ARM generic timer
  - QorIQ platform's trust architecture 2.1
+
+LS1046A
+--------
+The LS1046A integrated multicore processor combines four ARM Cortex-A72
+processor cores with datapath acceleration optimized for L2/3 packet
+processing, single pass security offload and robust traffic management
+and quality of service.
+
+The LS1046A SoC includes the following function and features:
+ - Four 64-bit ARM Cortex-A72 CPUs
+ - 2 MB unified L2 Cache
+ - One 64-bit DDR4 SDRAM memory controllers with ECC and interleaving
+   support
+ - Data Path Acceleration Architecture (DPAA) incorporating acceleration the
+   the following functions:
+   - Packet parsing, classification, and distribution (FMan)
+   - Queue management for scheduling, packet sequencing, and congestion
+     management (QMan)
+   - Hardware buffer management for buffer allocation and de-allocation (BMan)
+   - Cryptography acceleration (SEC)
+ - Two Configurable x4 SerDes
+   - Two PLLs per four-lane SerDes
+   - Support for 10G operation
+ - Ethernet interfaces by FMan
+   - Up to 2 x XFI supporting 10G interface (MAC 9, 10)
+   - Up to 1 x QSGMII (MAC 5, 6, 10, 1)
+   - Up to 4 x SGMII supporting 1000Mbps (MAC 5, 6, 9, 10)
+   - Up to 3 x SGMII supporting 2500Mbps (MAC 5, 9, 10)
+   - Up to 2 x RGMII supporting 1000Mbps (MAC 3, 4)
+ - High-speed peripheral interfaces
+   - Three PCIe 3.0 controllers, one supporting x4 operation
+   - One serial ATA (SATA 3.0) controllers
+ - Additional peripheral interfaces
+   - Three high-speed USB 3.0 controllers with integrated PHY
+   - Enhanced secure digital host controller (eSDXC/eMMC)
+   - Quad Serial Peripheral Interface (QSPI) Controller
+   - Serial peripheral interface (SPI) controller
+   - Four I2C controllers
+   - Two DUARTs
+   - Integrated flash controller (IFC) supporting NAND and NOR flash
+ - QorIQ platform's trust architecture 2.1
index d17227ab2b2526ada76bb7e47ff51631c81e5d7e..40d6a761e8703a31312627f7ba003351c3db4e95 100644 (file)
@@ -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");
index fe3444a91e36c9e3321bbda0ec523c829b05ebdd..f73092ae3e44aaec50234084625e6add4e138ef8 100644 (file)
@@ -13,6 +13,9 @@
 #ifdef CONFIG_SYS_FSL_SRDS_1
 static u8 serdes1_prtcl_map[SERDES_PRCTL_COUNT];
 #endif
+#ifdef CONFIG_SYS_FSL_SRDS_2
+static u8 serdes2_prtcl_map[SERDES_PRCTL_COUNT];
+#endif
 
 int is_serdes_configured(enum srds_prtcl device)
 {
@@ -21,6 +24,9 @@ int is_serdes_configured(enum srds_prtcl device)
 #ifdef CONFIG_SYS_FSL_SRDS_1
        ret |= serdes1_prtcl_map[device];
 #endif
+#ifdef CONFIG_SYS_FSL_SRDS_2
+       ret |= serdes2_prtcl_map[device];
+#endif
 
        return !!ret;
 }
@@ -37,6 +43,12 @@ int serdes_get_first_lane(u32 sd, enum srds_prtcl device)
                cfg &= FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_MASK;
                cfg >>= FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_SHIFT;
                break;
+#endif
+#ifdef CONFIG_SYS_FSL_SRDS_2
+       case FSL_SRDS_2:
+               cfg &= FSL_CHASSIS2_RCWSR4_SRDS2_PRTCL_MASK;
+               cfg >>= FSL_CHASSIS2_RCWSR4_SRDS2_PRTCL_SHIFT;
+               break;
 #endif
        default:
                printf("invalid SerDes%d\n", sd);
@@ -114,4 +126,11 @@ void fsl_serdes_init(void)
                    FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_SHIFT,
                    serdes1_prtcl_map);
 #endif
+#ifdef CONFIG_SYS_FSL_SRDS_2
+       serdes_init(FSL_SRDS_2,
+                   CONFIG_SYS_FSL_SERDES_ADDR,
+                   FSL_CHASSIS2_RCWSR4_SRDS2_PRTCL_MASK,
+                   FSL_CHASSIS2_RCWSR4_SRDS2_PRTCL_SHIFT,
+                   serdes2_prtcl_map);
+#endif
 }
index d0dc58d1814d7fc1d2fcbaa8cd72c349ffe8ec03..8922197d439666676371f4591bca5076527baf56 100644 (file)
@@ -107,6 +107,12 @@ void get_sys_info(struct sys_info *sys_info)
        case 3:
                sys_info->freq_fman[0] = freq_c_pll[0] / 3;
                break;
+       case 4:
+               sys_info->freq_fman[0] = freq_c_pll[0] / 4;
+               break;
+       case 5:
+               sys_info->freq_fman[0] = sys_info->freq_systembus;
+               break;
        case 6:
                sys_info->freq_fman[0] = freq_c_pll[1] / 2;
                break;
@@ -124,8 +130,23 @@ void get_sys_info(struct sys_info *sys_info)
 #ifdef CONFIG_FSL_ESDHC
 #ifdef CONFIG_FSL_ESDHC_USE_PERIPHERAL_CLK
        rcw_tmp = in_be32(&gur->rcwsr[15]);
-       rcw_tmp = (rcw_tmp & HWA_CGA_M2_CLK_SEL) >> HWA_CGA_M2_CLK_SHIFT;
-       sys_info->freq_sdhc = freq_c_pll[1] / rcw_tmp;
+       switch ((rcw_tmp & HWA_CGA_M2_CLK_SEL) >> HWA_CGA_M2_CLK_SHIFT) {
+       case 1:
+               sys_info->freq_sdhc = freq_c_pll[1];
+               break;
+       case 2:
+               sys_info->freq_sdhc = freq_c_pll[1] / 2;
+               break;
+       case 3:
+               sys_info->freq_sdhc = freq_c_pll[1] / 3;
+               break;
+       case 6:
+               sys_info->freq_sdhc = freq_c_pll[0] / 2;
+               break;
+       default:
+               printf("Error: Unknown ESDHC clock select!\n");
+               break;
+       }
 #else
        sys_info->freq_sdhc = sys_info->freq_systembus;
 #endif
diff --git a/arch/arm/cpu/armv8/fsl-layerscape/ls1046a_serdes.c b/arch/arm/cpu/armv8/fsl-layerscape/ls1046a_serdes.c
new file mode 100644 (file)
index 0000000..1da6b71
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2016 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/arch/fsl_serdes.h>
+#include <asm/arch/immap_lsch2.h>
+
+struct serdes_config {
+       u32 protocol;
+       u8 lanes[SRDS_MAX_LANES];
+};
+
+static struct serdes_config serdes1_cfg_tbl[] = {
+       /* SerDes 1 */
+       {0x3333, {SGMII_FM1_DTSEC9, SGMII_FM1_DTSEC10, SGMII_FM1_DTSEC5,
+                 SGMII_FM1_DTSEC6} },
+       {0x1133, {XFI_FM1_MAC9, XFI_FM1_MAC10, SGMII_FM1_DTSEC5,
+                 SGMII_FM1_DTSEC6} },
+       {0x1333, {XFI_FM1_MAC9, SGMII_FM1_DTSEC10, SGMII_FM1_DTSEC5,
+                 SGMII_FM1_DTSEC6} },
+       {0x2333, {SGMII_2500_FM1_DTSEC9, SGMII_FM1_DTSEC10, SGMII_FM1_DTSEC5,
+                 SGMII_FM1_DTSEC6} },
+       {0x2233, {SGMII_2500_FM1_DTSEC9, SGMII_2500_FM1_DTSEC10,
+                 SGMII_FM1_DTSEC5, SGMII_FM1_DTSEC6} },
+       {0x1040, {XFI_FM1_MAC9, NONE, QSGMII_FM1_A, NONE} },
+       {0x2040, {SGMII_2500_FM1_DTSEC9, NONE, QSGMII_FM1_A, NONE} },
+       {0x1163, {XFI_FM1_MAC9, XFI_FM1_MAC10, PCIE1, SGMII_FM1_DTSEC6} },
+       {0x2263, {SGMII_2500_FM1_DTSEC9, SGMII_2500_FM1_DTSEC10, PCIE1,
+                 SGMII_FM1_DTSEC6} },
+       {0x3363, {SGMII_FM1_DTSEC5, SGMII_FM1_DTSEC6, PCIE1,
+                 SGMII_FM1_DTSEC6} },
+       {0x2223, {SGMII_2500_FM1_DTSEC9, SGMII_2500_FM1_DTSEC10,
+                 SGMII_2500_FM1_DTSEC5, SGMII_FM1_DTSEC6} },
+       {}
+};
+
+static struct serdes_config serdes2_cfg_tbl[] = {
+       /* SerDes 2 */
+       {0x8888, {PCIE1, PCIE1, PCIE1, PCIE1} },
+       {0x5559, {PCIE1, PCIE2, PCIE3, SATA1} },
+       {0x5577, {PCIE1, PCIE2, PCIE3, PCIE3} },
+       {0x5506, {PCIE1, PCIE2, NONE, PCIE3} },
+       {0x0506, {NONE, PCIE2, NONE, PCIE3} },
+       {0x0559, {NONE, PCIE2, PCIE3, SATA1} },
+       {0x5A59, {PCIE1, SGMII_FM1_DTSEC2, PCIE3, SATA1} },
+       {0x5A06, {PCIE1, SGMII_FM1_DTSEC2, NONE, PCIE3} },
+       {}
+};
+
+static struct serdes_config *serdes_cfg_tbl[] = {
+       serdes1_cfg_tbl,
+       serdes2_cfg_tbl,
+};
+
+enum srds_prtcl serdes_get_prtcl(int serdes, int cfg, int lane)
+{
+       struct serdes_config *ptr;
+
+       if (serdes >= ARRAY_SIZE(serdes_cfg_tbl))
+               return 0;
+
+       ptr = serdes_cfg_tbl[serdes];
+       while (ptr->protocol) {
+               if (ptr->protocol == cfg)
+                       return ptr->lanes[lane];
+               ptr++;
+       }
+
+       return 0;
+}
+
+int is_serdes_prtcl_valid(int serdes, u32 prtcl)
+{
+       int i;
+       struct serdes_config *ptr;
+
+       if (serdes >= ARRAY_SIZE(serdes_cfg_tbl))
+               return 0;
+
+       ptr = serdes_cfg_tbl[serdes];
+       while (ptr->protocol) {
+               if (ptr->protocol == prtcl)
+                       break;
+               ptr++;
+       }
+
+       if (!ptr->protocol)
+               return 0;
+
+       for (i = 0; i < SRDS_MAX_LANES; i++) {
+               if (ptr->lanes[i] != NONE)
+                       return 1;
+       }
+
+       return 0;
+}
diff --git a/arch/arm/cpu/armv8/fsl-layerscape/ppa.c b/arch/arm/cpu/armv8/fsl-layerscape/ppa.c
new file mode 100644 (file)
index 0000000..541b251
--- /dev/null
@@ -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;
+}
index dac12a2552fbe132fef39d9a5724c9131d8e1eb1..5c97e0eee43469748daea37d16d49a30e2af08ed 100644 (file)
@@ -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 (file)
index 0000000..e21e199
--- /dev/null
@@ -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 (file)
index 0000000..0c6a462
--- /dev/null
@@ -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 (file)
index 0000000..ec1c9b8
--- /dev/null
@@ -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 (file)
index 0000000..d7f78a6
--- /dev/null
@@ -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)
index dfce469206681acf558760c4faa9d6ef22c00010..19c771dba3abc2dad0971474d2f9d7773119f771 100644 (file)
@@ -53,6 +53,11 @@ _bss_end_ofs:
        .quad   __bss_end - _start
 
 reset:
+       /* Allow the board to save important registers */
+       b       save_boot_params
+.globl save_boot_params_ret
+save_boot_params_ret:
+
 #ifdef CONFIG_SYS_RESET_SCTRL
        bl reset_sctrl
 #endif
@@ -81,14 +86,6 @@ reset:
        msr     cpacr_el1, x0                   /* Enable FP/SIMD */
 0:
 
-       /* Enalbe SMPEN bit for coherency.
-        * This register is not architectural but at the moment
-        * this bit should be set for A53/A57/A72.
-        */
-       mrs     x0, S3_1_c15_c2_1               /* cpuactlr_el1 */
-       orr     x0, x0, #0x40
-       msr     S3_1_c15_c2_1, x0
-
        /* Apply ARM core specific erratas */
        bl      apply_core_errata
 
@@ -102,7 +99,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
 
        /*
@@ -114,10 +115,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
@@ -288,3 +287,7 @@ ENTRY(c_runtime_cpu_setup)
 
        ret
 ENDPROC(c_runtime_cpu_setup)
+
+WEAK(save_boot_params)
+       b       save_boot_params_ret    /* back to my caller */
+ENDPROC(save_boot_params)
index 690c72dd66836190a5c709900d1d694d8d5fd02d..f7e5ebfa6343dc79b542700a80816c0e6365de1d 100644 (file)
 
 DECLARE_GLOBAL_DATA_PTR;
 
-unsigned long get_uart_clk(int dev_id)
-{
-       u32 ver = zynqmp_get_silicon_version();
-
-       switch (ver) {
-       case ZYNQMP_CSU_VERSION_VELOCE:
-               return 48000;
-       case ZYNQMP_CSU_VERSION_EP108:
-               return 25000000;
-       case ZYNQMP_CSU_VERSION_QEMU:
-               return 133000000;
-       }
-
-       return 100000000;
-}
-
 unsigned long zynqmp_get_system_timer_freq(void)
 {
        u32 ver = zynqmp_get_silicon_version();
index 509f0aa387a645a42d68e70cebaf931548a52f5d..b0f12955a1ffac03ec37f3ccf87ac52d687fee51 100644 (file)
@@ -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 |
index 58312a79bc59b9b6edf06e59bce1f6d6a5e8a0c3..e10fc3136c85b3958ecfbccbce9a6ed0a20407ec 100644 (file)
@@ -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);
 }
 
index 1769b6ea881b2f909a0799237869754fd1c777f3..36c9fd0bd01f36737ed60b3b33d239b7cb860610 100644 (file)
@@ -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 */
        }
index ef573ec68515c42214b72a79ee919958c6f08c5d..7e2108312be641dd818596772642a3c71498c4b2 100644 (file)
@@ -31,7 +31,9 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += \
        rk3288-firefly.dtb \
        rk3288-jerry.dtb \
        rk3288-rock2-square.dtb \
-       rk3036-sdk.dtb
+       rk3288-evb.dtb \
+       rk3036-sdk.dtb \
+       rk3399-evb.dtb
 dtb-$(CONFIG_ARCH_MESON) += \
        meson-gxbb-odroidc2.dtb
 dtb-$(CONFIG_TEGRA) += tegra20-harmony.dtb \
@@ -53,7 +55,8 @@ dtb-$(CONFIG_TEGRA) += tegra20-harmony.dtb \
        tegra124-jetson-tk1.dtb \
        tegra124-nyan-big.dtb \
        tegra124-venice2.dtb \
-       tegra186-p2771-0000.dtb \
+       tegra186-p2771-0000-a02.dtb \
+       tegra186-p2771-0000-b00.dtb \
        tegra210-e2220-1170.dtb \
        tegra210-p2371-0000.dtb \
        tegra210-p2371-2180.dtb \
@@ -242,8 +245,10 @@ 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-pc-plus.dtb \
        sun8i-h3-orangepi-plus.dtb
 dtb-$(CONFIG_MACH_SUN50I) += \
        sun50i-a64-pine64-plus.dtb \
index 08ef04e177b038bb500b4b134d783788fba0ab4b..429b9edc1b2b4f547fa844a92a97e0fa4123003f 100644 (file)
        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>;
 
index 205103e2b0e1ab0a62096bb055ae1f2d4a13d106..ced2f1166d8c2ddb5d57e33fcf853a91daf9cf5e 100644 (file)
        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>;
 
index 3f877615844e107262316dead327905335f862d0..26c4d7f4c646f7c65196640b72e5701ecbb64931 100644 (file)
@@ -22,7 +22,7 @@
        aliases {
                serial0 = "/serial@13800000";
                console = "/serial@13820000";
-               mmc2 = "sdhci@12530000";
+               mmc2 = "/sdhci@12530000";
        };
 
        sdhci@12510000 {
index f3fac801905696f9eba76814fb3a8e0c4833152b..2ed38f369e4ee8ec602c5e4e530a92356b0832e9 100644 (file)
@@ -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 {
index ad3527ec6f118324e82e0168681c6d2e7774dec2..8cac7dd752e082589eb85e7c3c01868c39ad894b 100644 (file)
@@ -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 {
index a63e8abab4ae9cdcc708960930f551bde7bbcb8d..188cb939bb8a1795037c937b9b7101c0900a90ef 100644 (file)
@@ -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 {
index 2d4e522ea2770ef0e428eea352b4ffd4e43271d9..1fbcf8914fa50050fbdffbd64ed41b3262ad1fa7 100644 (file)
@@ -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 {
index 50c83c21d9118baa9b4f0ec2a2e30c20f8d64981..e2c3fb49102adfcbcabe71fc357975379b24b150 100644 (file)
 };
 
 &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>;
index 0ca36ef39ad307c149ea79c31736a61105ee91b2..e95efd4767076caf3373e68879092642678cbcc6 100644 (file)
 &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>;
+                };
+        };
+};
index a3ed444d3c31892e72fbe8e26121aaa59f584273..00cd492973366e0c0f6108486148cc645c7209fc 100644 (file)
 
        aliases {
                serial0 = &uart0;
+               spi0 = &spi0;
+               spi1 = &spi1;
+               spi2 = &spi2;
+               spi3 = &spi3;
+               spi4 = &qspi;
        };
 
        memory {
                        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 {
                        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";
+               };
        };
 };
index 660ebf58d547cf4f3f18396159fb7cd5ed7da550..c5cad2c9da80a6a826f2d55fadf2e2f382dc9596 100644 (file)
 };
 
 &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>;
index 9a69a6b553748bb5752bd12c7dbe9c251e8b7705..da0661ba3e8a058840b2e5e71438c008dea02a52 100644 (file)
 };
 
 &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>;
index f39b969f8d437054255b3c4debbba8072a7559f6..be97f3f21f926e95b799dd24d2943ca1a7223652 100644 (file)
@@ -19,6 +19,9 @@
 
        aliases {
                serial0 = &uart0;
+               spi0 = &spi0;
+               spi1 = &spi1;
+               spi2 = &spi2;
        };
 
        chosen {
diff --git a/arch/arm/dts/rk3288-evb.dts b/arch/arm/dts/rk3288-evb.dts
new file mode 100644 (file)
index 0000000..caf24ee
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * (C) Copyright 2016 Rockchip Electronics Co., Ltd
+ *
+ * SPDX-License-Identifier:     GPL-2.0+ X11
+ */
+
+/dts-v1/;
+#include "rk3288-evb.dtsi"
+
+/ {
+       model = "Evb-RK3288";
+       compatible = "evb-rk3288,evb-rk3288", "rockchip,rk3288";
+
+       chosen {
+               stdout-path = &uart2;
+       };
+};
+
+&dmc {
+       rockchip,num-channels = <2>;
+       rockchip,pctl-timing = <0x215 0xc8 0x0 0x35 0x26 0x2 0x70 0x2000d
+               0x6 0x0 0x8 0x4 0x17 0x24 0xd 0x6
+               0x4 0x8 0x4 0x76 0x4 0x0 0x30 0x0
+               0x1 0x2 0x2 0x4 0x0 0x0 0xc0 0x4
+               0x8 0x1f4>;
+       rockchip,phy-timing = <0x48d7dd93 0x187008d8 0x121076
+               0x0 0xc3 0x6 0x2>;
+       rockchip,sdram-channel = /bits/ 8 <0x2 0xa 0x3 0x2 0x2 0x0 0xe 0xe>;
+       rockchip,sdram-params = <0x20d266a4 0x5b6 2 533000000 6 9 0>;
+};
+
+&pinctrl {
+       u-boot,dm-pre-reloc;
+};
+
+&pwm1 {
+       status = "okay";
+};
+
+&uart2 {
+       u-boot,dm-pre-reloc;
+       reg-shift = <2>;
+};
+
+&sdmmc {
+       u-boot,dm-pre-reloc;
+};
+
+&emmc {
+       u-boot,dm-pre-reloc;
+};
+
+&gpio3 {
+       u-boot,dm-pre-reloc;
+};
+
+&gpio8 {
+       u-boot,dm-pre-reloc;
+};
diff --git a/arch/arm/dts/rk3288-evb.dtsi b/arch/arm/dts/rk3288-evb.dtsi
new file mode 100644 (file)
index 0000000..cb7d03e
--- /dev/null
@@ -0,0 +1,379 @@
+/*
+ * (C) Copyright 2016 Rockchip Electronics Co., Ltd
+ *
+ * SPDX-License-Identifier:     GPL-2.0+ X11
+ */
+
+#include "rk3288.dtsi"
+
+/ {
+       memory {
+               reg = <0 0x80000000>;
+       };
+
+       keys: gpio-keys {
+               compatible = "gpio-keys";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               button@0 {
+                       gpio-key,wakeup = <1>;
+                       gpios = <&gpio0 5 GPIO_ACTIVE_LOW>;
+                       label = "GPIO Power";
+                       linux,code = <116>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&pwr_key>;
+               };
+       };
+
+       vcc_sys: vsys-regulator {
+               compatible = "regulator-fixed";
+               regulator-name = "vcc_sys";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               regulator-always-on;
+               regulator-boot-on;
+       };
+
+       vcc_flash: flash-regulator {
+               compatible = "regulator-fixed";
+               regulator-name = "vcc_flash";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
+               vin-supply = <&vcc_io>;
+       };
+
+       vcc_5v: usb-regulator {
+               compatible = "regulator-fixed";
+               regulator-name = "vcc_5v";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               regulator-always-on;
+               regulator-boot-on;
+               vin-supply = <&vcc_sys>;
+       };
+
+       vcc_host_5v: usb-host-regulator {
+               compatible = "regulator-fixed";
+               enable-active-high;
+               gpio = <&gpio0 14 GPIO_ACTIVE_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&host_vbus_drv>;
+               regulator-name = "vcc_host_5v";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               regulator-always-on;
+               vin-supply = <&vcc_5v>;
+       };
+
+       vcc_otg_5v: usb-otg-regulator {
+               compatible = "regulator-fixed";
+               enable-active-high;
+               gpio = <&gpio0 12 GPIO_ACTIVE_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&otg_vbus_drv>;
+               regulator-name = "vcc_otg_5v";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               regulator-always-on;
+               vin-supply = <&vcc_5v>;
+       };
+};
+
+&cpu0 {
+       cpu0-supply = <&vdd_cpu>;
+};
+
+&emmc {
+       broken-cd;
+       bus-width = <8>;
+       cap-mmc-highspeed;
+       disable-wp;
+       non-removable;
+       num-slots = <1>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&emmc_clk>, <&emmc_cmd>, <&emmc_pwr>, <&emmc_bus8>;
+       vmmc-supply = <&vcc_io>;
+       vqmmc-supply = <&vcc_flash>;
+       status = "okay";
+};
+
+&hdmi {
+       ddc-i2c-bus = <&i2c5>;
+       status = "okay";
+};
+
+&i2c0 {
+       clock-frequency = <400000>;
+       status = "okay";
+
+       vdd_cpu: syr827@40 {
+               compatible = "silergy,syr827";
+               fcs,suspend-voltage-selector = <1>;
+               reg = <0x40>;
+               regulator-name = "vdd_cpu";
+               regulator-min-microvolt = <850000>;
+               regulator-max-microvolt = <1350000>;
+               regulator-always-on;
+               regulator-boot-on;
+               vin-supply = <&vcc_sys>;
+       };
+
+       vdd_gpu: syr828@41 {
+               compatible = "silergy,syr828";
+               fcs,suspend-voltage-selector = <1>;
+               reg = <0x41>;
+               regulator-name = "vdd_gpu";
+               regulator-min-microvolt = <850000>;
+               regulator-max-microvolt = <1350000>;
+               regulator-always-on;
+               vin-supply = <&vcc_sys>;
+       };
+
+       hym8563: hym8563@51 {
+               compatible = "haoyu,hym8563";
+               reg = <0x51>;
+               #clock-cells = <0>;
+               clock-frequency = <32768>;
+               clock-output-names = "xin32k";
+               interrupt-parent = <&gpio7>;
+               interrupts = <4 IRQ_TYPE_EDGE_FALLING>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&rtc_int>;
+       };
+
+       act8846: act8846@5a {
+               compatible = "active-semi,act8846";
+               reg = <0x5a>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pwr_hold>;
+               system-power-controller;
+
+               regulators {
+                       vcc_ddr: REG1 {
+                               regulator-name = "vcc_ddr";
+                               regulator-min-microvolt = <1200000>;
+                               regulator-max-microvolt = <1200000>;
+                               regulator-always-on;
+                       };
+
+                       vcc_io: REG2 {
+                               regulator-name = "vcc_io";
+                               regulator-min-microvolt = <3300000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-always-on;
+                       };
+
+                       vdd_log: REG3 {
+                               regulator-name = "vdd_log";
+                               regulator-min-microvolt = <1100000>;
+                               regulator-max-microvolt = <1100000>;
+                               regulator-always-on;
+                       };
+
+                       vcc_20: REG4 {
+                               regulator-name = "vcc_20";
+                               regulator-min-microvolt = <2000000>;
+                               regulator-max-microvolt = <2000000>;
+                               regulator-always-on;
+                       };
+
+                       vccio_sd: REG5 {
+                               regulator-name = "vccio_sd";
+                               regulator-min-microvolt = <3300000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-always-on;
+                       };
+
+                       vdd10_lcd: REG6 {
+                               regulator-name = "vdd10_lcd";
+                               regulator-min-microvolt = <1000000>;
+                               regulator-max-microvolt = <1000000>;
+                               regulator-always-on;
+                       };
+
+                       vcca_codec: REG7 {
+                               regulator-name = "vcca_codec";
+                               regulator-min-microvolt = <3300000>;
+                               regulator-max-microvolt = <3300000>;
+                       };
+
+                       vcc_tp: REG8 {
+                               regulator-name = "vcca_33";
+                               regulator-min-microvolt = <3300000>;
+                               regulator-max-microvolt = <3300000>;
+                       };
+
+                       vccio_pmu: REG9 {
+                               regulator-name = "vccio_pmu";
+                               regulator-min-microvolt = <3300000>;
+                               regulator-max-microvolt = <3300000>;
+                       };
+
+                       vdd_10: REG10 {
+                               regulator-name = "vdd_10";
+                               regulator-min-microvolt = <1000000>;
+                               regulator-max-microvolt = <1000000>;
+                               regulator-always-on;
+                       };
+
+                       vcc_18: REG11 {
+                               regulator-name = "vcc_18";
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-always-on;
+                       };
+
+                       vcc18_lcd: REG12 {
+                               regulator-name = "vcc18_lcd";
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-always-on;
+                       };
+               };
+       };
+};
+
+&i2c1 {
+       status = "okay";
+};
+
+&i2c2 {
+       status = "okay";
+};
+
+&i2c4 {
+       status = "okay";
+};
+
+&i2c5 {
+       status = "okay";
+};
+
+&pinctrl {
+       pcfg_output_high: pcfg-output-high {
+               output-high;
+       };
+
+       pcfg_output_low: pcfg-output-low {
+               output-low;
+       };
+
+       act8846 {
+               pwr_hold: pwr-hold {
+                       rockchip,pins = <0 9 RK_FUNC_GPIO &pcfg_output_high>;
+               };
+       };
+
+       hym8563 {
+               rtc_int: rtc-int {
+                       rockchip,pins = <0 4 RK_FUNC_GPIO &pcfg_pull_up>;
+               };
+       };
+
+       keys {
+               pwr_key: pwr-key {
+                       rockchip,pins = <0 5 RK_FUNC_GPIO &pcfg_pull_up>;
+               };
+       };
+
+       sdmmc {
+               sdmmc_pwr: sdmmc-pwr {
+                       rockchip,pins = <7 11 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
+
+       usb_host {
+               host_vbus_drv: host-vbus-drv {
+                       rockchip,pins = <0 14 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
+
+       usb_otg {
+               otg_vbus_drv: otg-vbus-drv {
+                       rockchip,pins = <0 12 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
+};
+
+&saradc {
+       vref-supply = <&vcc_18>;
+       status = "okay";
+};
+
+&sdio0 {
+       broken-cd;
+       bus-width = <4>;
+       disable-wp;
+       non-removable;
+       num-slots = <1>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&sdio0_bus4>, <&sdio0_cmd>, <&sdio0_clk>;
+       vmmc-supply = <&vcc_18>;
+       status = "disabled";
+};
+
+&sdmmc {
+       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 = <&vccio_sd>;
+       status = "okay";
+};
+
+&spi0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&spi0_clk>, <&spi0_cs0>, <&spi0_tx>, <&spi0_rx>, <&spi0_cs1>;
+       status = "okay";
+};
+
+&uart0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart0_xfer>, <&uart0_cts>, <&uart0_rts>;
+       status = "okay";
+};
+
+&uart1 {
+       status = "okay";
+};
+
+&uart2 {
+       status = "okay";
+};
+
+&uart3 {
+       status = "okay";
+};
+
+&usb_host1 {
+       status = "okay";
+};
+
+&usb_otg {
+       status = "okay";
+};
+
+&vopb {
+       status = "okay";
+};
+
+&vopb_mmu {
+       status = "okay";
+};
+
+&vopl {
+       status = "okay";
+};
+
+&vopl_mmu {
+       status = "okay";
+};
+
+&wdt {
+       status = "okay";
+};
index aed8d3a712b037b363464759c9c17a6adc1d1e67..3176d5046b2a4a622bb700b2ab189575204ec2c0 100644 (file)
@@ -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>;
 };
 
index 3dab0fc83ead0f70f0b2e99e4e3157eccbb46a27..bcf051a9d9b374b31aed4ec7894c6d466851c551 100644 (file)
                interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&cru HCLK_OTG0>;
                clock-names = "otg";
+               dr_mode = "otg";
                phys = <&usbphy0>;
                phy-names = "usb2-phy";
                status = "disabled";
diff --git a/arch/arm/dts/rk3399-evb.dts b/arch/arm/dts/rk3399-evb.dts
new file mode 100644 (file)
index 0000000..bbcfcd0
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ * (C) Copyright 2016 Rockchip Electronics Co., Ltd
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+/dts-v1/;
+#include <dt-bindings/pwm/pwm.h>
+#include "rk3399.dtsi"
+
+/ {
+       model = "Rockchip RK3399 Evaluation Board";
+       compatible = "rockchip,rk3399-evb", "rockchip,rk3399",
+                    "google,rk3399evb-rev2";
+
+       chosen {
+               stdout-path = &uart2;
+       };
+
+       vdd_center: vdd-center {
+               compatible = "pwm-regulator";
+               pwms = <&pwm3 0 25000 0>;
+               regulator-name = "vdd_center";
+               regulator-min-microvolt = <800000>;
+               regulator-max-microvolt = <1400000>;
+               regulator-always-on;
+               regulator-boot-on;
+               status = "okay";
+       };
+
+       vcc3v3_sys: vcc3v3-sys {
+               compatible = "regulator-fixed";
+               regulator-name = "vcc3v3_sys";
+               regulator-always-on;
+               regulator-boot-on;
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+       };
+
+       vcc_phy: vcc-phy-regulator {
+               compatible = "regulator-fixed";
+               regulator-name = "vcc_phy";
+               regulator-always-on;
+               regulator-boot-on;
+       };
+};
+
+&emmc_phy {
+       status = "okay";
+};
+
+&pwm0 {
+       status = "okay";
+};
+
+&pwm2 {
+       status = "okay";
+};
+
+&pwm3 {
+       status = "okay";
+};
+
+&sdhci {
+       bus-width = <8>;
+       mmc-hs400-1_8v;
+       mmc-hs400-enhanced-strobe;
+       non-removable;
+       status = "okay";
+};
+
+&uart2 {
+       status = "okay";
+};
+
+&usb_host0_ehci {
+       status = "okay";
+};
+
+&usb_host0_ohci {
+       status = "okay";
+};
+
+&usb_host1_ehci {
+       status = "okay";
+};
+
+&usb_host1_ohci {
+       status = "okay";
+};
+
+&pinctrl {
+       pmic {
+               pmic_int_l: pmic-int-l {
+                       rockchip,pins =
+                               <1 21 RK_FUNC_GPIO &pcfg_pull_up>;
+               };
+
+               pmic_dvs2: pmic-dvs2 {
+                       rockchip,pins =
+                               <1 18 RK_FUNC_GPIO &pcfg_pull_down>;
+               };
+       };
+};
diff --git a/arch/arm/dts/rk3399.dtsi b/arch/arm/dts/rk3399.dtsi
new file mode 100644 (file)
index 0000000..fb5af54
--- /dev/null
@@ -0,0 +1,1028 @@
+/*
+ * (C) Copyright 2016 Rockchip Electronics Co., Ltd
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <dt-bindings/clock/rk3399-cru.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+
+/ {
+       compatible = "rockchip,rk3399";
+
+       interrupt-parent = <&gic>;
+       #address-cells = <2>;
+       #size-cells = <2>;
+
+       aliases {
+               serial0 = &uart0;
+               serial1 = &uart1;
+               serial2 = &uart2;
+               serial3 = &uart3;
+               serial4 = &uart4;
+       };
+
+       cpus {
+               #address-cells = <2>;
+               #size-cells = <0>;
+
+               cpu-map {
+                       cluster0 {
+                               core0 {
+                                       cpu = <&cpu_l0>;
+                               };
+                               core1 {
+                                       cpu = <&cpu_l1>;
+                               };
+                               core2 {
+                                       cpu = <&cpu_l2>;
+                               };
+                               core3 {
+                                       cpu = <&cpu_l3>;
+                               };
+                       };
+
+                       cluster1 {
+                               core0 {
+                                       cpu = <&cpu_b0>;
+                               };
+                               core1 {
+                                       cpu = <&cpu_b1>;
+                               };
+                       };
+               };
+
+               cpu_l0: cpu@0 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a53", "arm,armv8";
+                       reg = <0x0 0x0>;
+                       enable-method = "psci";
+                       #cooling-cells = <2>; /* min followed by max */
+                       clocks = <&cru ARMCLKL>;
+               };
+
+               cpu_l1: cpu@1 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a53", "arm,armv8";
+                       reg = <0x0 0x1>;
+                       enable-method = "psci";
+                       clocks = <&cru ARMCLKL>;
+               };
+
+               cpu_l2: cpu@2 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a53", "arm,armv8";
+                       reg = <0x0 0x2>;
+                       enable-method = "psci";
+                       clocks = <&cru ARMCLKL>;
+               };
+
+               cpu_l3: cpu@3 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a53", "arm,armv8";
+                       reg = <0x0 0x3>;
+                       enable-method = "psci";
+                       clocks = <&cru ARMCLKL>;
+               };
+
+               cpu_b0: cpu@100 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a72", "arm,armv8";
+                       reg = <0x0 0x100>;
+                       enable-method = "psci";
+                       #cooling-cells = <2>; /* min followed by max */
+                       clocks = <&cru ARMCLKB>;
+               };
+
+               cpu_b1: cpu@101 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a72", "arm,armv8";
+                       reg = <0x0 0x101>;
+                       enable-method = "psci";
+                       clocks = <&cru ARMCLKB>;
+               };
+       };
+
+       psci {
+               compatible = "arm,psci-1.0";
+               method = "smc";
+       };
+
+       timer {
+               compatible = "arm,armv8-timer";
+               interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
+                            <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
+                            <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
+                            <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
+       };
+
+       xin24m: xin24m {
+               compatible = "fixed-clock";
+               clock-frequency = <24000000>;
+               clock-output-names = "xin24m";
+               #clock-cells = <0>;
+       };
+
+       amba {
+               compatible = "simple-bus";
+               #address-cells = <2>;
+               #size-cells = <2>;
+               ranges;
+
+               dmac_bus: dma-controller@ff6d0000 {
+                       compatible = "arm,pl330", "arm,primecell";
+                       reg = <0x0 0xff6d0000 0x0 0x4000>;
+                       interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
+                       #dma-cells = <1>;
+                       clocks = <&cru ACLK_DMAC0_PERILP>;
+                       clock-names = "apb_pclk";
+               };
+
+               dmac_peri: dma-controller@ff6e0000 {
+                       compatible = "arm,pl330", "arm,primecell";
+                       reg = <0x0 0xff6e0000 0x0 0x4000>;
+                       interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
+                       #dma-cells = <1>;
+                       clocks = <&cru ACLK_DMAC1_PERILP>;
+                       clock-names = "apb_pclk";
+               };
+       };
+
+       sdio0: dwmmc@fe310000 {
+               compatible = "rockchip,rk3399-dw-mshc",
+                            "rockchip,rk3288-dw-mshc";
+               reg = <0x0 0xfe310000 0x0 0x4000>;
+               interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>;
+               clock-freq-min-max = <400000 150000000>;
+               clocks = <&cru HCLK_SDIO>, <&cru SCLK_SDIO>,
+                        <&cru SCLK_SDIO_DRV>, <&cru SCLK_SDIO_SAMPLE>;
+               clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
+               fifo-depth = <0x100>;
+               status = "disabled";
+       };
+
+       sdmmc: dwmmc@fe320000 {
+               compatible = "rockchip,rk3399-dw-mshc",
+                            "rockchip,rk3288-dw-mshc";
+               reg = <0x0 0xfe320000 0x0 0x4000>;
+               interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
+               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-drive", "ciu-sample";
+               fifo-depth = <0x100>;
+               status = "disabled";
+       };
+
+       sdhci: sdhci@fe330000 {
+               compatible = "rockchip,rk3399-sdhci-5.1", "arasan,sdhci-5.1";
+               reg = <0x0 0xfe330000 0x0 0x10000>;
+               interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
+               assigned-clocks = <&cru SCLK_EMMC>;
+               assigned-clock-rates = <200000000>;
+               clocks = <&cru SCLK_EMMC>, <&cru ACLK_EMMC>;
+               clock-names = "clk_xin", "clk_ahb";
+               phys = <&emmc_phy>;
+               phy-names = "phy_arasan";
+               status = "disabled";
+       };
+
+       usb_host0_ehci: usb@fe380000 {
+               compatible = "generic-ehci";
+               reg = <0x0 0xfe380000 0x0 0x20000>;
+               interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&cru HCLK_HOST0>, <&cru HCLK_HOST0_ARB>;
+               clock-names = "hclk_host0", "hclk_host0_arb";
+               status = "disabled";
+       };
+
+       usb_host0_ohci: usb@fe3a0000 {
+               compatible = "generic-ohci";
+               reg = <0x0 0xfe3a0000 0x0 0x20000>;
+               interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&cru HCLK_HOST0>, <&cru HCLK_HOST0_ARB>;
+               clock-names = "hclk_host0", "hclk_host0_arb";
+               status = "disabled";
+       };
+
+       usb_host1_ehci: usb@fe3c0000 {
+               compatible = "generic-ehci";
+               reg = <0x0 0xfe3c0000 0x0 0x20000>;
+               interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&cru HCLK_HOST1>, <&cru HCLK_HOST1_ARB>;
+               clock-names = "hclk_host1", "hclk_host1_arb";
+               status = "disabled";
+       };
+
+       usb_host1_ohci: usb@fe3e0000 {
+               compatible = "generic-ohci";
+               reg = <0x0 0xfe3e0000 0x0 0x20000>;
+               interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&cru HCLK_HOST1>, <&cru HCLK_HOST1_ARB>;
+               clock-names = "hclk_host1", "hclk_host1_arb";
+               status = "disabled";
+       };
+
+       gic: interrupt-controller@fee00000 {
+               compatible = "arm,gic-v3";
+               #interrupt-cells = <3>;
+               #address-cells = <2>;
+               #size-cells = <2>;
+               ranges;
+               interrupt-controller;
+
+               reg = <0x0 0xfee00000 0 0x10000>, /* GICD */
+                     <0x0 0xfef00000 0 0xc0000>, /* GICR */
+                     <0x0 0xfff00000 0 0x10000>, /* GICC */
+                     <0x0 0xfff10000 0 0x10000>, /* GICH */
+                     <0x0 0xfff20000 0 0x10000>; /* GICV */
+               interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
+               its: interrupt-controller@fee20000 {
+                       compatible = "arm,gic-v3-its";
+                       msi-controller;
+                       reg = <0x0 0xfee20000 0x0 0x20000>;
+               };
+       };
+
+       uart0: serial@ff180000 {
+               compatible = "rockchip,rk3399-uart", "snps,dw-apb-uart";
+               reg = <0x0 0xff180000 0x0 0x100>;
+               clocks = <&cru SCLK_UART0>, <&cru PCLK_UART0>;
+               clock-names = "baudclk", "apb_pclk";
+               interrupts = <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>;
+               reg-shift = <2>;
+               reg-io-width = <4>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&uart0_xfer>;
+               status = "disabled";
+       };
+
+       uart1: serial@ff190000 {
+               compatible = "rockchip,rk3399-uart", "snps,dw-apb-uart";
+               reg = <0x0 0xff190000 0x0 0x100>;
+               clocks = <&cru SCLK_UART1>, <&cru PCLK_UART1>;
+               clock-names = "baudclk", "apb_pclk";
+               interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
+               reg-shift = <2>;
+               reg-io-width = <4>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&uart1_xfer>;
+               status = "disabled";
+       };
+
+       uart2: serial@ff1a0000 {
+               compatible = "rockchip,rk3399-uart", "snps,dw-apb-uart";
+               reg = <0x0 0xff1a0000 0x0 0x100>;
+               clocks = <&cru SCLK_UART2>, <&cru PCLK_UART2>;
+               clock-names = "baudclk", "apb_pclk";
+               interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>;
+               clock-frequency = <24000000>;
+               reg-shift = <2>;
+               reg-io-width = <4>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&uart2c_xfer>;
+               status = "disabled";
+       };
+
+       uart3: serial@ff1b0000 {
+               compatible = "rockchip,rk3399-uart", "snps,dw-apb-uart";
+               reg = <0x0 0xff1b0000 0x0 0x100>;
+               clocks = <&cru SCLK_UART3>, <&cru PCLK_UART3>;
+               clock-names = "baudclk", "apb_pclk";
+               interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
+               reg-shift = <2>;
+               reg-io-width = <4>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&uart3_xfer>;
+               status = "disabled";
+       };
+
+       spi0: spi@ff1c0000 {
+               compatible = "rockchip,rk3399-spi", "rockchip,rk3066-spi";
+               reg = <0x0 0xff1c0000 0x0 0x1000>;
+               clocks = <&cru SCLK_SPI0>, <&cru PCLK_SPI0>;
+               clock-names = "spiclk", "apb_pclk";
+               interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&spi0_clk &spi0_tx &spi0_rx &spi0_cs0>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               status = "disabled";
+       };
+
+       spi1: spi@ff1d0000 {
+               compatible = "rockchip,rk3399-spi", "rockchip,rk3066-spi";
+               reg = <0x0 0xff1d0000 0x0 0x1000>;
+               clocks = <&cru SCLK_SPI1>, <&cru PCLK_SPI1>;
+               clock-names = "spiclk", "apb_pclk";
+               interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&spi1_clk &spi1_tx &spi1_rx &spi1_cs0>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               status = "disabled";
+       };
+
+       spi2: spi@ff1e0000 {
+               compatible = "rockchip,rk3399-spi", "rockchip,rk3066-spi";
+               reg = <0x0 0xff1e0000 0x0 0x1000>;
+               clocks = <&cru SCLK_SPI2>, <&cru PCLK_SPI2>;
+               clock-names = "spiclk", "apb_pclk";
+               interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&spi2_clk &spi2_tx &spi2_rx &spi2_cs0>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               status = "disabled";
+       };
+
+       spi4: spi@ff1f0000 {
+               compatible = "rockchip,rk3399-spi", "rockchip,rk3066-spi";
+               reg = <0x0 0xff1f0000 0x0 0x1000>;
+               clocks = <&cru SCLK_SPI4>, <&cru PCLK_SPI4>;
+               clock-names = "spiclk", "apb_pclk";
+               interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&spi4_clk &spi4_tx &spi4_rx &spi4_cs0>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               status = "disabled";
+       };
+
+       spi5: spi@ff200000 {
+               compatible = "rockchip,rk3399-spi", "rockchip,rk3066-spi";
+               reg = <0x0 0xff200000 0x0 0x1000>;
+               clocks = <&cru SCLK_SPI5>, <&cru PCLK_SPI5>;
+               clock-names = "spiclk", "apb_pclk";
+               interrupts = <GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&spi5_clk &spi5_tx &spi5_rx &spi5_cs0>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               status = "disabled";
+       };
+
+       pmugrf: syscon@ff320000 {
+               compatible = "rockchip,rk3399-pmugrf", "syscon", "simple-mfd";
+               reg = <0x0 0xff320000 0x0 0x1000>;
+               #address-cells = <1>;
+               #size-cells = <1>;
+
+               pmu_io_domains: io-domains {
+                       compatible = "rockchip,rk3399-pmu-io-voltage-domain";
+                       status = "disabled";
+               };
+       };
+
+       spi3: spi@ff350000 {
+               compatible = "rockchip,rk3399-spi", "rockchip,rk3066-spi";
+               reg = <0x0 0xff350000 0x0 0x1000>;
+               clocks = <&pmucru SCLK_SPI3_PMU>, <&pmucru PCLK_SPI3_PMU>;
+               clock-names = "spiclk", "apb_pclk";
+               interrupts = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&spi3_clk &spi3_tx &spi3_rx &spi3_cs0>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               status = "disabled";
+       };
+
+       uart4: serial@ff370000 {
+               compatible = "rockchip,rk3399-uart", "snps,dw-apb-uart";
+               reg = <0x0 0xff370000 0x0 0x100>;
+               clocks = <&pmucru SCLK_UART4_PMU>, <&pmucru PCLK_UART4_PMU>;
+               clock-names = "baudclk", "apb_pclk";
+               interrupts = <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>;
+               reg-shift = <2>;
+               reg-io-width = <4>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&uart4_xfer>;
+               status = "disabled";
+       };
+
+       pwm0: pwm@ff420000 {
+               compatible = "rockchip,rk3399-pwm", "rockchip,rk3288-pwm";
+               reg = <0x0 0xff420000 0x0 0x10>;
+               #pwm-cells = <3>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pwm0_pin>;
+               clocks = <&pmucru PCLK_RKPWM_PMU>;
+               clock-names = "pwm";
+               status = "disabled";
+       };
+
+       pwm1: pwm@ff420010 {
+               compatible = "rockchip,rk3399-pwm", "rockchip,rk3288-pwm";
+               reg = <0x0 0xff420010 0x0 0x10>;
+               #pwm-cells = <3>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pwm1_pin>;
+               clocks = <&pmucru PCLK_RKPWM_PMU>;
+               clock-names = "pwm";
+               status = "disabled";
+       };
+
+       pwm2: pwm@ff420020 {
+               compatible = "rockchip,rk3399-pwm", "rockchip,rk3288-pwm";
+               reg = <0x0 0xff420020 0x0 0x10>;
+               #pwm-cells = <3>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pwm2_pin>;
+               clocks = <&pmucru PCLK_RKPWM_PMU>;
+               clock-names = "pwm";
+               status = "disabled";
+       };
+
+       pwm3: pwm@ff420030 {
+               compatible = "rockchip,rk3399-pwm", "rockchip,rk3288-pwm";
+               reg = <0x0 0xff420030 0x0 0x10>;
+               #pwm-cells = <3>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pwm3a_pin>;
+               clocks = <&pmucru PCLK_RKPWM_PMU>;
+               clock-names = "pwm";
+               status = "disabled";
+       };
+
+       pmucru: pmu-clock-controller@ff750000 {
+               compatible = "rockchip,rk3399-pmucru";
+               reg = <0x0 0xff750000 0x0 0x1000>;
+               #clock-cells = <1>;
+               #reset-cells = <1>;
+               assigned-clocks = <&pmucru PLL_PPLL>;
+               assigned-clock-rates = <676000000>;
+       };
+
+       cru: clock-controller@ff760000 {
+               compatible = "rockchip,rk3399-cru";
+               reg = <0x0 0xff760000 0x0 0x1000>;
+               #clock-cells = <1>;
+               #reset-cells = <1>;
+               assigned-clocks =
+                       <&cru PLL_GPLL>, <&cru PLL_CPLL>,
+                       <&cru PLL_NPLL>,
+                       <&cru ACLK_PERIHP>, <&cru HCLK_PERIHP>,
+                       <&cru PCLK_PERIHP>,
+                       <&cru ACLK_PERILP0>, <&cru HCLK_PERILP0>,
+                       <&cru PCLK_PERILP0>,
+                       <&cru HCLK_PERILP1>, <&cru PCLK_PERILP1>;
+               assigned-clock-rates =
+                        <594000000>,  <800000000>,
+                       <1000000000>,
+                        <150000000>,   <75000000>,
+                         <37500000>,
+                        <100000000>,  <100000000>,
+                         <50000000>,
+                        <100000000>,   <50000000>;
+       };
+
+       grf: syscon@ff770000 {
+               compatible = "rockchip,rk3399-grf", "syscon", "simple-mfd";
+               reg = <0x0 0xff770000 0x0 0x10000>;
+               #address-cells = <1>;
+               #size-cells = <1>;
+
+               io_domains: io-domains {
+                       compatible = "rockchip,rk3399-io-voltage-domain";
+                       status = "disabled";
+               };
+
+               emmc_phy: phy@f780 {
+                       compatible = "rockchip,rk3399-emmc-phy";
+                       reg = <0xf780 0x24>;
+                       #phy-cells = <0>;
+                       status = "disabled";
+               };
+       };
+
+       watchdog@ff840000 {
+               compatible = "snps,dw-wdt";
+               reg = <0x0 0xff840000 0x0 0x100>;
+               clocks = <&cru PCLK_WDT>;
+               interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
+       };
+
+       spdif: spdif@ff870000 {
+               compatible = "rockchip,rk3399-spdif";
+               reg = <0x0 0xff870000 0x0 0x1000>;
+               interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>;
+               dmas = <&dmac_bus 7>;
+               dma-names = "tx";
+               clock-names = "mclk", "hclk";
+               clocks = <&cru SCLK_SPDIF_8CH>, <&cru HCLK_SPDIF>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&spdif_bus>;
+               status = "disabled";
+       };
+
+       i2s0: i2s@ff880000 {
+               compatible = "rockchip,rk3399-i2s", "rockchip,rk3066-i2s";
+               reg = <0x0 0xff880000 0x0 0x1000>;
+               rockchip,grf = <&grf>;
+               interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
+               dmas = <&dmac_bus 0>, <&dmac_bus 1>;
+               dma-names = "tx", "rx";
+               clock-names = "i2s_clk", "i2s_hclk";
+               clocks = <&cru SCLK_I2S0_8CH>, <&cru HCLK_I2S0_8CH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&i2s0_8ch_bus>;
+               status = "disabled";
+       };
+
+       i2s1: i2s@ff890000 {
+               compatible = "rockchip,rk3399-i2s", "rockchip,rk3066-i2s";
+               reg = <0x0 0xff890000 0x0 0x1000>;
+               interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
+               dmas = <&dmac_bus 2>, <&dmac_bus 3>;
+               dma-names = "tx", "rx";
+               clock-names = "i2s_clk", "i2s_hclk";
+               clocks = <&cru SCLK_I2S1_8CH>, <&cru HCLK_I2S1_8CH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&i2s1_2ch_bus>;
+               status = "disabled";
+       };
+
+       i2s2: i2s@ff8a0000 {
+               compatible = "rockchip,rk3399-i2s", "rockchip,rk3066-i2s";
+               reg = <0x0 0xff8a0000 0x0 0x1000>;
+               interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
+               dmas = <&dmac_bus 4>, <&dmac_bus 5>;
+               dma-names = "tx", "rx";
+               clock-names = "i2s_clk", "i2s_hclk";
+               clocks = <&cru SCLK_I2S2_8CH>, <&cru HCLK_I2S2_8CH>;
+               status = "disabled";
+       };
+
+       pinctrl: pinctrl {
+               compatible = "rockchip,rk3399-pinctrl";
+               rockchip,grf = <&grf>;
+               rockchip,pmu = <&pmugrf>;
+               #address-cells = <2>;
+               #size-cells = <2>;
+               ranges;
+
+               gpio0: gpio0@ff720000 {
+                       compatible = "rockchip,gpio-bank";
+                       reg = <0x0 0xff720000 0x0 0x100>;
+                       clocks = <&pmucru PCLK_GPIO0_PMU>;
+                       interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+
+                       gpio-controller;
+                       #gpio-cells = <0x2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <0x2>;
+               };
+
+               gpio1: gpio1@ff730000 {
+                       compatible = "rockchip,gpio-bank";
+                       reg = <0x0 0xff730000 0x0 0x100>;
+                       clocks = <&pmucru PCLK_GPIO1_PMU>;
+                       interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
+
+                       gpio-controller;
+                       #gpio-cells = <0x2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <0x2>;
+               };
+
+               gpio2: gpio2@ff780000 {
+                       compatible = "rockchip,gpio-bank";
+                       reg = <0x0 0xff780000 0x0 0x100>;
+                       clocks = <&cru PCLK_GPIO2>;
+                       interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
+
+                       gpio-controller;
+                       #gpio-cells = <0x2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <0x2>;
+               };
+
+               gpio3: gpio3@ff788000 {
+                       compatible = "rockchip,gpio-bank";
+                       reg = <0x0 0xff788000 0x0 0x100>;
+                       clocks = <&cru PCLK_GPIO3>;
+                       interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
+
+                       gpio-controller;
+                       #gpio-cells = <0x2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <0x2>;
+               };
+
+               gpio4: gpio4@ff790000 {
+                       compatible = "rockchip,gpio-bank";
+                       reg = <0x0 0xff790000 0x0 0x100>;
+                       clocks = <&cru PCLK_GPIO4>;
+                       interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>;
+
+                       gpio-controller;
+                       #gpio-cells = <0x2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <0x2>;
+               };
+
+               pcfg_pull_up: pcfg-pull-up {
+                       bias-pull-up;
+               };
+
+               pcfg_pull_down: pcfg-pull-down {
+                       bias-pull-down;
+               };
+
+               pcfg_pull_none: pcfg-pull-none {
+                       bias-disable;
+               };
+
+               pcfg_pull_none_12ma: pcfg-pull-none-12ma {
+                       bias-disable;
+                       drive-strength = <12>;
+               };
+
+               pcfg_pull_up_8ma: pcfg-pull-up-8ma {
+                       bias-pull-up;
+                       drive-strength = <8>;
+               };
+
+               pcfg_pull_down_4ma: pcfg-pull-down-4ma {
+                       bias-pull-down;
+                       drive-strength = <4>;
+               };
+
+               pcfg_pull_up_2ma: pcfg-pull-up-2ma {
+                       bias-pull-up;
+                       drive-strength = <2>;
+               };
+
+               pcfg_pull_down_12ma: pcfg-pull-down-12ma {
+                       bias-pull-down;
+                       drive-strength = <12>;
+               };
+
+               pcfg_pull_none_13ma: pcfg-pull-none-13ma {
+                       bias-disable;
+                       drive-strength = <13>;
+               };
+
+               i2c0 {
+                       i2c0_xfer: i2c0-xfer {
+                               rockchip,pins =
+                                       <1 15 RK_FUNC_2 &pcfg_pull_none>,
+                                       <1 16 RK_FUNC_2 &pcfg_pull_none>;
+                       };
+               };
+
+               i2c1 {
+                       i2c1_xfer: i2c1-xfer {
+                               rockchip,pins =
+                                       <4 2 RK_FUNC_1 &pcfg_pull_none>,
+                                       <4 1 RK_FUNC_1 &pcfg_pull_none>;
+                       };
+               };
+
+               i2c2 {
+                       i2c2_xfer: i2c2-xfer {
+                               rockchip,pins =
+                                       <2 1 RK_FUNC_2 &pcfg_pull_none_12ma>,
+                                       <2 0 RK_FUNC_2 &pcfg_pull_none_12ma>;
+                       };
+               };
+
+               i2c3 {
+                       i2c3_xfer: i2c3-xfer {
+                               rockchip,pins =
+                                       <4 17 RK_FUNC_1 &pcfg_pull_none>,
+                                       <4 16 RK_FUNC_1 &pcfg_pull_none>;
+                       };
+               };
+
+               i2c4 {
+                       i2c4_xfer: i2c4-xfer {
+                               rockchip,pins =
+                                       <1 12 RK_FUNC_1 &pcfg_pull_none>,
+                                       <1 11 RK_FUNC_1 &pcfg_pull_none>;
+                       };
+               };
+
+               i2c5 {
+                       i2c5_xfer: i2c5-xfer {
+                               rockchip,pins =
+                                       <3 11 RK_FUNC_2 &pcfg_pull_none>,
+                                       <3 10 RK_FUNC_2 &pcfg_pull_none>;
+                       };
+               };
+
+               i2c6 {
+                       i2c6_xfer: i2c6-xfer {
+                               rockchip,pins =
+                                       <2 10 RK_FUNC_2 &pcfg_pull_none>,
+                                       <2 9 RK_FUNC_2 &pcfg_pull_none>;
+                       };
+               };
+
+               i2c7 {
+                       i2c7_xfer: i2c7-xfer {
+                               rockchip,pins =
+                                       <2 8 RK_FUNC_2 &pcfg_pull_none>,
+                                       <2 7 RK_FUNC_2 &pcfg_pull_none>;
+                       };
+               };
+
+               i2c8 {
+                       i2c8_xfer: i2c8-xfer {
+                               rockchip,pins =
+                                       <1 21 RK_FUNC_1 &pcfg_pull_none>,
+                                       <1 20 RK_FUNC_1 &pcfg_pull_none>;
+                       };
+               };
+
+               i2s0 {
+                       i2s0_8ch_bus: i2s0-8ch-bus {
+                               rockchip,pins =
+                                       <3 24 RK_FUNC_1 &pcfg_pull_none>,
+                                       <3 25 RK_FUNC_1 &pcfg_pull_none>,
+                                       <3 26 RK_FUNC_1 &pcfg_pull_none>,
+                                       <3 27 RK_FUNC_1 &pcfg_pull_none>,
+                                       <3 28 RK_FUNC_1 &pcfg_pull_none>,
+                                       <3 29 RK_FUNC_1 &pcfg_pull_none>,
+                                       <3 30 RK_FUNC_1 &pcfg_pull_none>,
+                                       <3 31 RK_FUNC_1 &pcfg_pull_none>,
+                                       <4 0 RK_FUNC_1 &pcfg_pull_none>;
+                       };
+               };
+
+               i2s1 {
+                       i2s1_2ch_bus: i2s1-2ch-bus {
+                               rockchip,pins =
+                                       <4 3 RK_FUNC_1 &pcfg_pull_none>,
+                                       <4 4 RK_FUNC_1 &pcfg_pull_none>,
+                                       <4 5 RK_FUNC_1 &pcfg_pull_none>,
+                                       <4 6 RK_FUNC_1 &pcfg_pull_none>,
+                                       <4 7 RK_FUNC_1 &pcfg_pull_none>;
+                       };
+               };
+
+               spdif {
+                       spdif_bus: spdif-bus {
+                               rockchip,pins =
+                                       <4 21 RK_FUNC_1 &pcfg_pull_none>;
+                       };
+               };
+
+               spi0 {
+                       spi0_clk: spi0-clk {
+                               rockchip,pins =
+                                       <3 6 RK_FUNC_2 &pcfg_pull_up>;
+                       };
+                       spi0_cs0: spi0-cs0 {
+                               rockchip,pins =
+                                       <3 7 RK_FUNC_2 &pcfg_pull_up>;
+                       };
+                       spi0_cs1: spi0-cs1 {
+                               rockchip,pins =
+                                       <3 8 RK_FUNC_2 &pcfg_pull_up>;
+                       };
+                       spi0_tx: spi0-tx {
+                               rockchip,pins =
+                                       <3 5 RK_FUNC_2 &pcfg_pull_up>;
+                       };
+                       spi0_rx: spi0-rx {
+                               rockchip,pins =
+                                       <3 4 RK_FUNC_2 &pcfg_pull_up>;
+                       };
+               };
+
+               spi1 {
+                       spi1_clk: spi1-clk {
+                               rockchip,pins =
+                                       <1 9 RK_FUNC_2 &pcfg_pull_up>;
+                       };
+                       spi1_cs0: spi1-cs0 {
+                               rockchip,pins =
+                                       <1 10 RK_FUNC_2 &pcfg_pull_up>;
+                       };
+                       spi1_rx: spi1-rx {
+                               rockchip,pins =
+                                       <1 7 RK_FUNC_2 &pcfg_pull_up>;
+                       };
+                       spi1_tx: spi1-tx {
+                               rockchip,pins =
+                                       <1 8 RK_FUNC_2 &pcfg_pull_up>;
+                       };
+               };
+
+               spi2 {
+                       spi2_clk: spi2-clk {
+                               rockchip,pins =
+                                       <2 11 RK_FUNC_1 &pcfg_pull_up>;
+                       };
+                       spi2_cs0: spi2-cs0 {
+                               rockchip,pins =
+                                       <2 12 RK_FUNC_1 &pcfg_pull_up>;
+                       };
+                       spi2_rx: spi2-rx {
+                               rockchip,pins =
+                                       <2 9 RK_FUNC_1 &pcfg_pull_up>;
+                       };
+                       spi2_tx: spi2-tx {
+                               rockchip,pins =
+                                       <2 10 RK_FUNC_1 &pcfg_pull_up>;
+                       };
+               };
+
+               spi3 {
+                       spi3_clk: spi3-clk {
+                               rockchip,pins =
+                                       <1 17 RK_FUNC_1 &pcfg_pull_up>;
+                       };
+                       spi3_cs0: spi3-cs0 {
+                               rockchip,pins =
+                                       <1 18 RK_FUNC_1 &pcfg_pull_up>;
+                       };
+                       spi3_rx: spi3-rx {
+                               rockchip,pins =
+                                       <1 15 RK_FUNC_1 &pcfg_pull_up>;
+                       };
+                       spi3_tx: spi3-tx {
+                               rockchip,pins =
+                                       <1 16 RK_FUNC_1 &pcfg_pull_up>;
+                       };
+               };
+
+               spi4 {
+                       spi4_clk: spi4-clk {
+                               rockchip,pins =
+                                       <3 2 RK_FUNC_2 &pcfg_pull_up>;
+                       };
+                       spi4_cs0: spi4-cs0 {
+                               rockchip,pins =
+                                       <3 3 RK_FUNC_2 &pcfg_pull_up>;
+                       };
+                       spi4_rx: spi4-rx {
+                               rockchip,pins =
+                                       <3 0 RK_FUNC_2 &pcfg_pull_up>;
+                       };
+                       spi4_tx: spi4-tx {
+                               rockchip,pins =
+                                       <3 1 RK_FUNC_2 &pcfg_pull_up>;
+                       };
+               };
+
+               spi5 {
+                       spi5_clk: spi5-clk {
+                               rockchip,pins =
+                                       <2 22 RK_FUNC_2 &pcfg_pull_up>;
+                       };
+                       spi5_cs0: spi5-cs0 {
+                               rockchip,pins =
+                                       <2 23 RK_FUNC_2 &pcfg_pull_up>;
+                       };
+                       spi5_rx: spi5-rx {
+                               rockchip,pins =
+                                       <2 20 RK_FUNC_2 &pcfg_pull_up>;
+                       };
+                       spi5_tx: spi5-tx {
+                               rockchip,pins =
+                                       <2 21 RK_FUNC_2 &pcfg_pull_up>;
+                       };
+               };
+
+               uart0 {
+                       uart0_xfer: uart0-xfer {
+                               rockchip,pins =
+                                       <2 16 RK_FUNC_1 &pcfg_pull_up>,
+                                       <2 17 RK_FUNC_1 &pcfg_pull_none>;
+                       };
+
+                       uart0_cts: uart0-cts {
+                               rockchip,pins =
+                                       <2 18 RK_FUNC_1 &pcfg_pull_none>;
+                       };
+
+                       uart0_rts: uart0-rts {
+                               rockchip,pins =
+                                       <2 19 RK_FUNC_1 &pcfg_pull_none>;
+                       };
+               };
+
+               uart1 {
+                       uart1_xfer: uart1-xfer {
+                               rockchip,pins =
+                                       <3 12 RK_FUNC_2 &pcfg_pull_up>,
+                                       <3 13 RK_FUNC_2 &pcfg_pull_none>;
+                       };
+               };
+
+               uart2a {
+                       uart2a_xfer: uart2a-xfer {
+                               rockchip,pins =
+                                       <4 8 RK_FUNC_2 &pcfg_pull_up>,
+                                       <4 9 RK_FUNC_2 &pcfg_pull_none>;
+                       };
+               };
+
+               uart2b {
+                       uart2b_xfer: uart2b-xfer {
+                               rockchip,pins =
+                                       <4 16 RK_FUNC_2 &pcfg_pull_up>,
+                                       <4 17 RK_FUNC_2 &pcfg_pull_none>;
+                       };
+               };
+
+               uart2c {
+                       uart2c_xfer: uart2c-xfer {
+                               rockchip,pins =
+                                       <4 19 RK_FUNC_1 &pcfg_pull_up>,
+                                       <4 20 RK_FUNC_1 &pcfg_pull_none>;
+                       };
+               };
+
+               uart3 {
+                       uart3_xfer: uart3-xfer {
+                               rockchip,pins =
+                                       <3 14 RK_FUNC_2 &pcfg_pull_up>,
+                                       <3 15 RK_FUNC_2 &pcfg_pull_none>;
+                       };
+
+                       uart3_cts: uart3-cts {
+                               rockchip,pins =
+                                       <3 18 RK_FUNC_2 &pcfg_pull_none>;
+                       };
+
+                       uart3_rts: uart3-rts {
+                               rockchip,pins =
+                                       <3 19 RK_FUNC_2 &pcfg_pull_none>;
+                       };
+               };
+
+               uart4 {
+                       uart4_xfer: uart4-xfer {
+                               rockchip,pins =
+                                       <1 7 RK_FUNC_1 &pcfg_pull_up>,
+                                       <1 8 RK_FUNC_1 &pcfg_pull_none>;
+                       };
+               };
+
+               uarthdcp {
+                       uarthdcp_xfer: uarthdcp-xfer {
+                               rockchip,pins =
+                                       <4 21 RK_FUNC_2 &pcfg_pull_up>,
+                                       <4 22 RK_FUNC_2 &pcfg_pull_none>;
+                       };
+               };
+
+               pwm0 {
+                       pwm0_pin: pwm0-pin {
+                               rockchip,pins =
+                                       <4 18 RK_FUNC_1 &pcfg_pull_none>;
+                       };
+
+                       vop0_pwm_pin: vop0-pwm-pin {
+                               rockchip,pins =
+                                       <4 18 RK_FUNC_2 &pcfg_pull_none>;
+                       };
+               };
+
+               pwm1 {
+                       pwm1_pin: pwm1-pin {
+                               rockchip,pins =
+                                       <4 22 RK_FUNC_1 &pcfg_pull_none>;
+                       };
+
+                       vop1_pwm_pin: vop1-pwm-pin {
+                               rockchip,pins =
+                                       <4 18 RK_FUNC_3 &pcfg_pull_none>;
+                       };
+               };
+
+               pwm2 {
+                       pwm2_pin: pwm2-pin {
+                               rockchip,pins =
+                                       <1 19 RK_FUNC_1 &pcfg_pull_none>;
+                       };
+               };
+
+               pwm3a {
+                       pwm3a_pin: pwm3a-pin {
+                               rockchip,pins =
+                                       <0 6 RK_FUNC_1 &pcfg_pull_none>;
+                       };
+               };
+
+               pwm3b {
+                       pwm3b_pin: pwm3b-pin {
+                               rockchip,pins =
+                                       <1 14 RK_FUNC_1 &pcfg_pull_none>;
+                       };
+               };
+       };
+};
index 549dc15bd5d0000e2260136498dab6ca9045b3fd..389c6096ca149734af69b9d9549b72073841d475 100644 (file)
                reg = <0x40000000 0x40000000>;
        };
 };
+
+&emac {
+       pinctrl-names = "default";
+       pinctrl-0 = <&rgmii_pins>;
+       phy-mode = "rgmii";
+       phy = <&phy1>;
+       status = "okay";
+
+       phy1: ethernet-phy@1 {
+       reg = <1>;
+       };
+};
+
index 1bd436f8470b08b19401e75f23a507055f1eecf8..7d0dc76a11f7170f45248bfa8b543ea63b9a24bf 100644 (file)
                                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 {
                        #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>;
+               };
        };
 };
index bddd0de88af6be1d3e68b027b644a56e5e0ee61b..a5f8855389a17cdc85dfa21990ca9635d3989eaa 100644 (file)
                allwinner,drive = <SUN4I_PINCTRL_30_MA>;
                allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
        };
+
+       nand_cs2_pins_a: nand_cs@2 {
+               allwinner,pins = "PC17";
+               allwinner,function = "nand0";
+               allwinner,drive = <0>;
+               allwinner,pull = <0>;
+       };
+
+       nand_cs3_pins_a: nand_cs@3 {
+               allwinner,pins = "PC18";
+               allwinner,function = "nand0";
+               allwinner,drive = <0>;
+               allwinner,pull = <0>;
+       };
 };
 
 &sram_a {
index b3c234c65ea19bb1f69984f350db0dad7ceea440..30e069a6cf4a8a50c15c0d4b5c55666985c0b548 100644 (file)
        status = "okay";
 };
 
+&nfc {
+       pinctrl-names = "default";
+       pinctrl-0 = <&nand_pins_a &nand_cs0_pins_a &nand_rb0_pins_a>;
+       status = "okay";
+
+       nand@0 {
+               #address-cells = <2>;
+               #size-cells = <2>;
+               reg = <0>;
+               allwinner,rb = <0>;
+               nand-ecc-mode = "hw";
+               allwinner,randomize;
+       };
+};
+
 &ohci0 {
        status = "okay";
 };
index 6ad19e272f4bc94904d6ed4fefab8cca835f6e13..b1b62d511645e095e62737614651723cd7947701 100644 (file)
        status = "okay";
 };
 
+&nfc {
+       pinctrl-names = "default";
+       pinctrl-0 = <&nand_pins_a &nand_cs0_pins_a &nand_rb0_pins_a>;
+       status = "okay";
+
+       nand@0 {
+               #address-cells = <2>;
+               #size-cells = <2>;
+               reg = <0>;
+               allwinner,rb = <0>;
+               nand-ecc-mode = "hw";
+               nand-on-flash-bbt;
+       };
+};
+
 &ohci0 {
        status = "okay";
 };
index 59a9426e3bd4ed68aefa8b3aca7469dd3e27f5dc..87e535301a641d8b54cf37511eb6df6d85b93b00 100644 (file)
                        #dma-cells = <2>;
                };
 
+               nfc: nand@01c03000 {
+                       compatible = "allwinner,sun4i-a10-nand";
+                       reg = <0x01c03000 0x1000>;
+                       interrupts = <37>;
+                       clocks = <&ahb_gates 13>, <&nand_clk>;
+                       clock-names = "ahb", "mod";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
                spi0: spi@01c05000 {
                        compatible = "allwinner,sun4i-a10-spi";
                        reg = <0x01c05000 0x1000>;
                                allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
                        };
 
+                       nand_pins_a: nand_base0@0 {
+                               allwinner,pins = "PC0", "PC1", "PC2",
+                                               "PC5", "PC8", "PC9", "PC10",
+                                               "PC11", "PC12", "PC13", "PC14",
+                                               "PC15";
+                               allwinner,function = "nand0";
+                               allwinner,drive = <0>;
+                               allwinner,pull = <0>;
+                       };
+
+                       nand_cs0_pins_a: nand_cs@0 {
+                               allwinner,pins = "PC4";
+                               allwinner,function = "nand0";
+                               allwinner,drive = <0>;
+                               allwinner,pull = <0>;
+                       };
+
+                       nand_cs1_pins_a: nand_cs@1 {
+                               allwinner,pins = "PC3";
+                               allwinner,function = "nand0";
+                               allwinner,drive = <0>;
+                               allwinner,pull = <0>;
+                       };
+
+                       nand_rb0_pins_a: nand_rb@0 {
+                               allwinner,pins = "PC6";
+                               allwinner,function = "nand0";
+                               allwinner,drive = <0>;
+                               allwinner,pull = <0>;
+                       };
+
+                       nand_rb1_pins_a: nand_rb@1 {
+                               allwinner,pins = "PC7";
+                               allwinner,function = "nand0";
+                               allwinner,drive = <0>;
+                               allwinner,pull = <0>;
+                       };
+
                        uart3_pins_a: uart3@0 {
                                allwinner,pins = "PG9", "PG10";
                                allwinner,function = "uart3";
index f93f5d1695c4b38a05fbc8fdb818e2301e7366e4..d3f8f550a227a6b74982d517cc68b5b9c3a3cf50 100644 (file)
        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 (file)
index 0000000..ac71749
--- /dev/null
@@ -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-plus.dts b/arch/arm/dts/sun8i-h3-orangepi-pc-plus.dts
new file mode 100644 (file)
index 0000000..9a8cdd4
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * 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.
+ */
+
+/* The Orange Pi PC Plus is an extended version of the regular PC */
+#include "sun8i-h3-orangepi-pc.dts"
+
+/ {
+       model = "Xunlong Orange Pi PC / PC Plus";
+
+       aliases {
+               /* ethernet0 is the H3 emac, defined in sun8i-h3.dtsi */
+               ethernet1 = &rtl8189ftv;
+       };
+};
+
+&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>;
+       };
+};
+
+&mmc2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&mmc2_8bit_pins>;
+       vmmc-supply = <&reg_vcc3v3>;
+       bus-width = <8>;
+       non-removable;
+       cap-mmc-hw-reset;
+       status = "okay";
+};
+
+&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>;
+};
index 30ccca019dd23747256b2c90b305b7d667a27287..0a74a9193bbfc06d54efb7a301340c14d5390378 100644 (file)
        /* 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>;
+       };
+};
index 900ec4fc8c818a660435a048e699007eb9529068..28f74f6ffd1ea119dfcfe99462673f5739f4ac08 100644 (file)
  *     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";
                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";
 };
 
        };
 };
 
-&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";
 };
index c2f63c50501cd0196b8ef14ae8a4e133f8ca877d..84e52b9cdb2976fea32b1c39df3c2524ab9ee939 100644 (file)
 / {
        interrupt-parent = <&gic>;
 
+       aliases {
+               ethernet0 = <&emac>;
+       };
+
        cpus {
                #address-cells = <1>;
                #size-cells = <0>;
                        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";
                                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 {
                        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/dts/tegra186-p2771-0000-a02.dts b/arch/arm/dts/tegra186-p2771-0000-a02.dts
new file mode 100644 (file)
index 0000000..70f4326
--- /dev/null
@@ -0,0 +1,8 @@
+/dts-v1/;
+
+#include "tegra186-p2771-0000.dtsi"
+
+/ {
+       model = "NVIDIA P2771-0000 A02";
+       compatible = "nvidia,p2771-0000-a02", "nvidia,p2771-0000", "nvidia,tegra186";
+};
diff --git a/arch/arm/dts/tegra186-p2771-0000-b00.dts b/arch/arm/dts/tegra186-p2771-0000-b00.dts
new file mode 100644 (file)
index 0000000..2384a65
--- /dev/null
@@ -0,0 +1,8 @@
+/dts-v1/;
+
+#include "tegra186-p2771-0000.dtsi"
+
+/ {
+       model = "NVIDIA P2771-0000 B00";
+       compatible = "nvidia,p2771-0000-b00", "nvidia,p2771-0000", "nvidia,tegra186";
+};
diff --git a/arch/arm/dts/tegra186-p2771-0000.dts b/arch/arm/dts/tegra186-p2771-0000.dts
deleted file mode 100644 (file)
index 5f29ee4..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-/dts-v1/;
-
-#include "tegra186.dtsi"
-
-/ {
-       model = "NVIDIA P2771-0000";
-       compatible = "nvidia,p2771-0000", "nvidia,tegra186";
-
-       chosen {
-               stdout-path = &uarta;
-       };
-
-       aliases {
-               sdhci0 = "/sdhci@3460000";
-       };
-
-       memory {
-               reg = <0x0 0x80000000 0x0 0x60000000>;
-       };
-
-       sdhci@3460000 {
-               status = "okay";
-               bus-width = <8>;
-       };
-};
diff --git a/arch/arm/dts/tegra186-p2771-0000.dtsi b/arch/arm/dts/tegra186-p2771-0000.dtsi
new file mode 100644 (file)
index 0000000..87f0427
--- /dev/null
@@ -0,0 +1,23 @@
+#include "tegra186.dtsi"
+
+/ {
+       model = "NVIDIA P2771-0000";
+       compatible = "nvidia,p2771-0000", "nvidia,tegra186";
+
+       chosen {
+               stdout-path = &uarta;
+       };
+
+       aliases {
+               sdhci0 = "/sdhci@3460000";
+       };
+
+       memory {
+               reg = <0x0 0x80000000 0x0 0x60000000>;
+       };
+
+       sdhci@3460000 {
+               status = "okay";
+               bus-width = <8>;
+       };
+};
index fce34fa6500e0ed84ac04a6767921f9ad30dee60..99d49254b36b0e91553e85accb5e86fc542ff6dd 100644 (file)
@@ -1,5 +1,5 @@
 #include "skeleton.dtsi"
-#include <dt-bindings/gpio/tegra-gpio.h>
+#include <dt-bindings/gpio/tegra186-gpio.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/mailbox/tegra-hsp.h>
 
index 61f61641afc1078e8d015836f95a19b45257d263..117570352f8fea850f529ba2a8dc97a230a59b54 100644 (file)
        };
 
        chosen {
-               stdout-path = "serial2:115200n8";
+               stdout-path = "serial0:115200n8";
        };
 
        aliases {
-               serial0 = &serial0;
-               serial1 = &serial1;
-               serial2 = &serial2;
+               serial0 = &serial2;
+               serial1 = &serial0;
+               serial2 = &serial1;
                i2c0 = &i2c0;
                i2c2 = &i2c2;
                i2c4 = &i2c4;
index 3d5b300716021d405261f97fbe46ce36b5505515..928a0928fd1b71d444ff307002aa7fa92f28575d 100644 (file)
        };
 
        chosen {
-               stdout-path = "serial2:115200n8";
+               stdout-path = "serial0:115200n8";
        };
 
        aliases {
-               serial0 = &serial0;
-               serial1 = &serial1;
-               serial2 = &serial2;
+               serial0 = &serial2;
+               serial1 = &serial0;
+               serial2 = &serial1;
                i2c0 = &i2c0;
                i2c4 = &i2c4;
                i2c5 = &i2c5;
index daf3c7ebfaf29e9c0611f7e005f000cb25f327be..9bc56f6ac13bada1411d2dae218ff392641f6db0 100644 (file)
@@ -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,
index 8f573d2d02a4f5a7ac4ca361a1f5362d932f7253..ed1a46c2e71d7477e04b30ee5ca7e440fce095aa 100644 (file)
@@ -25,9 +25,8 @@ void ddr_pll_config(unsigned int ddrpll_M);
 
 void sdelay(unsigned long);
 
-struct gpmc_cs;
 void gpmc_init(void);
-void enable_gpmc_cs_config(const u32 *gpmc_config, struct gpmc_cs *cs, u32 base,
+void enable_gpmc_cs_config(const u32 *gpmc_config, const struct gpmc_cs *cs, u32 base,
                        u32 size);
 void omap_nand_switch_ecc(uint32_t, uint32_t);
 
index 44fe0c00953964b8f59ebac78fb8495cc5a85666..b0ad4b462689f6e48ab89d6f2ad3cb2069244002 100644 (file)
 #define CONFIG_ARM_ERRATA_833471
 
 #define CONFIG_SYS_FSL_MAX_NUM_OF_SEC          1
-#elif defined(CONFIG_LS1043A)
-#define CONFIG_MAX_CPUS                                4
+#elif defined(CONFIG_FSL_LSCH2)
 #define CONFIG_SYS_CACHELINE_SIZE              64
-#define CONFIG_SYS_FMAN_V3
-#define CONFIG_SYS_NUM_FMAN                    1
-#define CONFIG_SYS_NUM_FM1_DTSEC               7
-#define CONFIG_SYS_NUM_FM1_10GEC               1
-#define CONFIG_SYS_FSL_IFC_BANK_COUNT          4
 #define CONFIG_NUM_DDR_CONTROLLERS             1
-#define CONFIG_SYS_CCSRBAR_DEFAULT             0x01000000
 #define CONFIG_SYS_FSL_SEC_COMPAT              5
 #define CONFIG_SYS_FSL_OCRAM_BASE              0x10000000 /* initial RAM */
-#define CONFIG_SYS_FSL_OCRAM_SIZE              0x200000 /* 2 MiB */
-#define CONFIG_SYS_FSL_DDR_BE
-#define CONFIG_SYS_DDR_BLOCK1_SIZE             ((phys_size_t)2 << 30)
-#define CONFIG_MAX_MEM_MAPPED                  CONFIG_SYS_DDR_BLOCK1_SIZE
+#define CONFIG_SYS_FSL_OCRAM_SIZE              0x00200000 /* 2M */
+#define CONFIG_SYS_CCSRBAR_DEFAULT             0x01000000
 
-#define CONFIG_SYS_FSL_CCSR_GUR_BE
 #define CONFIG_SYS_FSL_CCSR_SCFG_BE
-#define CONFIG_SYS_FSL_IFC_BE
 #define CONFIG_SYS_FSL_ESDHC_BE
 #define CONFIG_SYS_FSL_WDOG_BE
 #define CONFIG_SYS_FSL_DSPI_BE
 #define CONFIG_SYS_FSL_QSPI_BE
+#define CONFIG_SYS_FSL_CCSR_GUR_BE
 #define CONFIG_SYS_FSL_PEX_LUT_BE
+#define CONFIG_SYS_FSL_SEC_BE
+
+#define CONFIG_SYS_FSL_SRDS_1
+/* SoC related */
+#ifdef CONFIG_LS1043A
+#define CONFIG_MAX_CPUS                                4
+#define CONFIG_SYS_FMAN_V3
+#define CONFIG_SYS_NUM_FMAN                    1
+#define CONFIG_SYS_NUM_FM1_DTSEC               7
+#define CONFIG_SYS_NUM_FM1_10GEC               1
+#define CONFIG_SYS_FSL_IFC_BANK_COUNT          4
+#define CONFIG_SYS_FSL_DDR_BE
+#define CONFIG_SYS_DDR_BLOCK1_SIZE             ((phys_size_t)2 << 30)
+#define CONFIG_MAX_MEM_MAPPED                  CONFIG_SYS_DDR_BLOCK1_SIZE
 
 #define QE_MURAM_SIZE          0x6000UL
 #define MAX_QE_RISC            1
 #define QE_NUM_OF_SNUM         28
 
-#define SRDS_MAX_LANES         4
-#define CONFIG_SYS_FSL_SRDS_1
-#define CONFIG_SYS_FSL_PCIE_COMPAT             "fsl,qoriq-pcie-v2.4"
-
+#define CONFIG_SYS_FSL_IFC_BE
 #define CONFIG_SYS_FSL_SFP_VER_3_2
 #define CONFIG_SYS_FSL_SEC_MON_BE
-#define CONFIG_SYS_FSL_SEC_BE
 #define CONFIG_SYS_FSL_SFP_BE
 #define CONFIG_SYS_FSL_SRK_LE
 #define CONFIG_KEY_REVOCATION
 #define CONFIG_SYS_FSL_MAX_NUM_OF_SEC          1
 #elif defined(CONFIG_LS1012A)
 #define CONFIG_MAX_CPUS                         1
-#define CONFIG_SYS_CACHELINE_SIZE              64
-#define CONFIG_NUM_DDR_CONTROLLERS             1
-#define CONFIG_SYS_CCSRBAR_DEFAULT             0x01000000
-#define CONFIG_SYS_FSL_SEC_COMPAT              5
 #undef CONFIG_SYS_FSL_DDRC_ARM_GEN3
 
-#define CONFIG_SYS_FSL_OCRAM_BASE              0x10000000 /* initial RAM */
-#define CONFIG_SYS_FSL_OCRAM_SIZE              0x200000 /* 2 MiB */
-
 #define GICD_BASE              0x01401000
 #define GICC_BASE              0x01402000
+#elif defined(CONFIG_LS1046A)
+#define CONFIG_MAX_CPUS                                4
+#define CONFIG_SYS_FMAN_V3
+#define CONFIG_SYS_NUM_FMAN                    1
+#define CONFIG_SYS_NUM_FM1_DTSEC               8
+#define CONFIG_SYS_NUM_FM1_10GEC               2
+#define CONFIG_SYS_FSL_IFC_BANK_COUNT          4
+#define CONFIG_SYS_FSL_DDR_BE
+#define CONFIG_SYS_DDR_BLOCK1_SIZE  ((phys_size_t)2 << 30)
+#define CONFIG_MAX_MEM_MAPPED           CONFIG_SYS_DDR_BLOCK1_SIZE
 
-#define CONFIG_SYS_FSL_CCSR_GUR_BE
-#define CONFIG_SYS_FSL_CCSR_SCFG_BE
-#define CONFIG_SYS_FSL_ESDHC_BE
-#define CONFIG_SYS_FSL_WDOG_BE
-#define CONFIG_SYS_FSL_DSPI_BE
-#define CONFIG_SYS_FSL_QSPI_BE
-#define CONFIG_SYS_FSL_PEX_LUT_BE
+#define CONFIG_SYS_FSL_SRDS_2
+#define CONFIG_SYS_FSL_IFC_BE
+#define CONFIG_SYS_FSL_SFP_VER_3_2
+#define CONFIG_SYS_FSL_SNVS_LE
+#define CONFIG_SYS_FSL_SFP_BE
+#define CONFIG_SYS_FSL_SRK_LE
+#define CONFIG_KEY_REVOCATION
 
-#define SRDS_MAX_LANES         4
-#define CONFIG_SYS_FSL_SRDS_1
-#define CONFIG_SYS_FSL_PCIE_COMPAT             "fsl,qoriq-pcie-v2.4"
-#define CONFIG_SYS_FSL_SEC_BE
+/* SMMU Defintions */
+#define SMMU_BASE              0x09000000
+
+/* Generic Interrupt Controller Definitions */
+#define GICD_BASE              0x01410000
+#define GICC_BASE              0x01420000
+
+#define CONFIG_SYS_FSL_MAX_NUM_OF_SEC          1
 #else
 #error SoC not defined
 #endif
+#endif
 
 #endif /* _ASM_ARMV8_FSL_LAYERSCAPE_CONFIG_H_ */
index 197b0eb5a53a4a3ed8724b61ab2f41ec05305e62..e2d96a1b7816b2666636278bb3bf606121e6d21d 100644 (file)
@@ -13,35 +13,14 @@ static struct cpu_type cpu_type_list[] = {
        CPU_TYPE_ENTRY(LS2045A, LS2045A, 4),
        CPU_TYPE_ENTRY(LS1043A, LS1043A, 4),
        CPU_TYPE_ENTRY(LS1023A, LS1023A, 2),
+       CPU_TYPE_ENTRY(LS1046A, LS1046A, 4),
+       CPU_TYPE_ENTRY(LS1026A, LS1026A, 2),
        CPU_TYPE_ENTRY(LS2040A, LS2040A, 4),
        CPU_TYPE_ENTRY(LS1012A, LS1012A, 1),
 };
 
 #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 +80,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);
index 487cba80803f64c9f520e7c15e08d65542c06abe..e1b3f44d853956d684709b1b9e88c93127109620 100644 (file)
@@ -140,6 +140,7 @@ enum srds_prtcl {
 
 enum srds {
        FSL_SRDS_1  = 0,
+       FSL_SRDS_2  = 1,
 };
 
 #endif
@@ -150,7 +151,7 @@ int serdes_get_first_lane(u32 sd, enum srds_prtcl device);
 enum srds_prtcl serdes_get_prtcl(int serdes, int cfg, int lane);
 int is_serdes_prtcl_valid(int serdes, u32 prtcl);
 
-#ifdef CONFIG_LS1043A
+#ifdef CONFIG_FSL_LSCH2
 const char *serdes_clock_to_string(u32 clock);
 int get_serdes_protocol(void);
 #endif
index 8b8a7c15bddb1bf05df2515f3113bd430e46db72..95a42935cac9c20b29f9c2e21802b1d264562b2c 100644 (file)
@@ -31,9 +31,9 @@
 #define CONFIG_SYS_NS16550_COM2                        (CONFIG_SYS_IMMR + 0x011c0600)
 #define CONFIG_SYS_NS16550_COM3                        (CONFIG_SYS_IMMR + 0x011d0500)
 #define CONFIG_SYS_NS16550_COM4                        (CONFIG_SYS_IMMR + 0x011d0600)
-#define CONFIG_SYS_LS1043A_XHCI_USB1_ADDR      (CONFIG_SYS_IMMR + 0x01f00000)
-#define CONFIG_SYS_LS1043A_XHCI_USB2_ADDR      (CONFIG_SYS_IMMR + 0x02000000)
-#define CONFIG_SYS_LS1043A_XHCI_USB3_ADDR      (CONFIG_SYS_IMMR + 0x02100000)
+#define CONFIG_SYS_XHCI_USB1_ADDR              (CONFIG_SYS_IMMR + 0x01f00000)
+#define CONFIG_SYS_XHCI_USB2_ADDR              (CONFIG_SYS_IMMR + 0x02000000)
+#define CONFIG_SYS_XHCI_USB3_ADDR              (CONFIG_SYS_IMMR + 0x02100000)
 #define CONFIG_SYS_PCIE1_ADDR                  (CONFIG_SYS_IMMR + 0x2400000)
 #define CONFIG_SYS_PCIE2_ADDR                  (CONFIG_SYS_IMMR + 0x2500000)
 #define CONFIG_SYS_PCIE3_ADDR                  (CONFIG_SYS_IMMR + 0x2600000)
@@ -94,6 +94,7 @@
 #define TY_ITYP_VER_A7          0x1
 #define TY_ITYP_VER_A53         0x2
 #define TY_ITYP_VER_A57         0x3
+#define TY_ITYP_VER_A72                0x4
 
 #define TP_CLUSTER_EOC         0xc0000000      /* end of clusters */
 #define TP_CLUSTER_INIT_MASK    0x0000003f      /* initiator mask */
@@ -227,6 +228,8 @@ struct ccsr_gur {
 #define FSL_CHASSIS2_RCWSR0_MEM_PLL_RAT_MASK   0x3f
 #define FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_MASK   0xffff0000
 #define FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_SHIFT  16
+#define FSL_CHASSIS2_RCWSR4_SRDS2_PRTCL_MASK   0x0000ffff
+#define FSL_CHASSIS2_RCWSR4_SRDS2_PRTCL_SHIFT  0
 #define RCW_SB_EN_REG_INDEX    7
 #define RCW_SB_EN_MASK         0x00200000
 
index 3ad46eb37143983895330dbb16c7fc840e293369..93e26c1d7f489c684a2f2978204bdb642945c016 100644 (file)
@@ -52,8 +52,8 @@
 #define I2C3_BASE_ADDR                         (CONFIG_SYS_IMMR + 0x01020000)
 #define I2C4_BASE_ADDR                         (CONFIG_SYS_IMMR + 0x01030000)
 
-#define CONFIG_SYS_LS2080A_XHCI_USB1_ADDR      (CONFIG_SYS_IMMR + 0x02100000)
-#define CONFIG_SYS_LS2080A_XHCI_USB2_ADDR      (CONFIG_SYS_IMMR + 0x02110000)
+#define CONFIG_SYS_XHCI_USB1_ADDR              (CONFIG_SYS_IMMR + 0x02100000)
+#define CONFIG_SYS_XHCI_USB2_ADDR              (CONFIG_SYS_IMMR + 0x02110000)
 
 /* TZ Address Space Controller Definitions */
 #define TZASC1_BASE                    0x01100000      /* as per CCSR map. */
 #define TY_ITYP_VER_A7         0x1
 #define TY_ITYP_VER_A53                0x2
 #define TY_ITYP_VER_A57                0x3
+#define TY_ITYP_VER_A72                0x4
 
 #define TP_CLUSTER_EOC         0x80000000      /* end of clusters */
 #define TP_CLUSTER_INIT_MASK   0x0000003f      /* initiator mask */
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 (file)
index 0000000..1f1442b
--- /dev/null
@@ -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
index 39e8c7a17c34ec644c36735ca5fd8a1c22ed8594..8d4a7adb1d574aca4a9e3e13a8918dc0a9fc9c69 100644 (file)
@@ -44,6 +44,8 @@ struct cpu_type {
 #define SVR_LS1012A            0x870400
 #define SVR_LS1043A            0x879200
 #define SVR_LS1023A            0x879208
+#define SVR_LS1046A            0x870700
+#define SVR_LS1026A            0x870708
 #define SVR_LS2045A            0x870120
 #define SVR_LS2080A            0x870110
 #define SVR_LS2085A            0x870100
index 04abec467c2112daad7280a3408fc8d89da5e1af..d408fe40561a51523b85eda7986c061475685d38 100644 (file)
@@ -10,7 +10,7 @@
 #define CONFIG_SYS_CACHELINE_SIZE              64
 
 #define OCRAM_BASE_ADDR                                0x10000000
-#define OCRAM_SIZE                             0x00020000
+#define OCRAM_SIZE                             0x00010000
 #define OCRAM_BASE_S_ADDR                      0x10010000
 #define OCRAM_S_SIZE                           0x00010000
 
 #define CONFIG_SYS_FSL_SERDES_ADDR             (CONFIG_SYS_IMMR + 0x00ea0000)
 #define CONFIG_SYS_FSL_GUTS_ADDR               (CONFIG_SYS_IMMR + 0x00ee0000)
 #define CONFIG_SYS_FSL_LS1_CLK_ADDR            (CONFIG_SYS_IMMR + 0x00ee1000)
+#define CONFIG_SYS_FSL_RCPM_ADDR               (CONFIG_SYS_IMMR + 0x00ee2000)
 #define CONFIG_SYS_NS16550_COM1                        (CONFIG_SYS_IMMR + 0x011c0500)
 #define CONFIG_SYS_NS16550_COM2                        (CONFIG_SYS_IMMR + 0x011d0500)
 #define CONFIG_SYS_DCU_ADDR                    (CONFIG_SYS_IMMR + 0x01ce0000)
-#define CONFIG_SYS_LS102XA_XHCI_USB1_ADDR      (CONFIG_SYS_IMMR + 0x02100000)
-#define CONFIG_SYS_LS102XA_USB1_ADDR \
-       (CONFIG_SYS_IMMR + CONFIG_SYS_LS102XA_USB1_OFFSET)
+#define CONFIG_SYS_XHCI_USB1_ADDR              (CONFIG_SYS_IMMR + 0x02100000)
+#define CONFIG_SYS_EHCI_USB1_ADDR              (CONFIG_SYS_IMMR + 0x07600000)
 
 #define CONFIG_SYS_FSL_SEC_OFFSET              0x00700000
 #define CONFIG_SYS_FSL_JR0_OFFSET              0x00710000
-#define CONFIG_SYS_LS102XA_USB1_OFFSET         0x07600000
 #define CONFIG_SYS_TSEC1_OFFSET                        0x01d10000
 #define CONFIG_SYS_TSEC2_OFFSET                        0x01d50000
 #define CONFIG_SYS_TSEC3_OFFSET                        0x01d90000
index 24563c08e4d2097405d0576c473f475d6857afe8..5979340ac8a72082bf5b1fbbb956f5d4009dfaa0 100644 (file)
@@ -40,11 +40,12 @@ void sdrc_init(void);
 void do_sdrc_init(u32, u32);
 
 void get_board_mem_timings(struct board_sdrc_timings *timings);
-void identify_nand_chip(int *mfr, int *id);
+int identify_nand_chip(int *mfr, int *id);
 void emif4_init(void);
 void gpmc_init(void);
-void enable_gpmc_cs_config(const u32 *gpmc_config, struct gpmc_cs *cs, u32 base,
-                       u32 size);
+void enable_gpmc_cs_config(const u32 *gpmc_config, const struct gpmc_cs *cs,
+                               u32 base, u32 size);
+void set_gpmc_cs0(int flash_type);
 
 void watchdog_init(void);
 void set_muxconf_regs(void);
index adc8eb23fffb6739217511cefcfec1359dcd054e..463e979758ec3030c91ed4725af9a88c70f135c3 100644 (file)
@@ -14,9 +14,9 @@ struct i2c {
        unsigned short revnb_lo;        /* 0x00 */
        unsigned short res1;
        unsigned short revnb_hi;        /* 0x04 */
-       unsigned short res2[13];
-       unsigned short sysc;            /* 0x20 */
-       unsigned short res3;
+       unsigned short res2[5];
+       unsigned short sysc;            /* 0x10 */
+       unsigned short res3[9];
        unsigned short irqstatus_raw;   /* 0x24 */
        unsigned short res4;
        unsigned short stat;            /* 0x28 */
index d875cfe0b4fdd5418bcd81ee6c28e54619bbed09..2b55edf7f0c89628048aa9e56c84057603f94e8c 100644 (file)
@@ -14,9 +14,9 @@ struct i2c {
        unsigned short revnb_lo;        /* 0x00 */
        unsigned short res1;
        unsigned short revnb_hi;        /* 0x04 */
-       unsigned short res2[13];
-       unsigned short sysc;            /* 0x20 */
-       unsigned short res3;
+       unsigned short res2[5];
+       unsigned short sysc;            /* 0x10 */
+       unsigned short res3[9];
        unsigned short irqstatus_raw;   /* 0x24 */
        unsigned short res4;
        unsigned short stat;            /* 0x28 */
index 317e5128ed2bc48342e163b120f81f05c87de9f7..21edbc2f8989705b1b84c9b1b3d03706a72907bc 100644 (file)
@@ -65,6 +65,8 @@ void *rockchip_get_cru(void);
 struct rk3288_cru;
 struct rk3288_grf;
 
-void rkclk_configure_cpu(struct rk3288_cru *cru, struct rk3288_grf *grf);
+void rk3288_clk_configure_cpu(struct rk3288_cru *cru, struct rk3288_grf *grf);
+
+int rockchip_get_clk(struct udevice **devp);
 
 #endif
index d3de42d297745152efa3076e0e3aa1427005c7f6..e08e28f4f0c5c9e9e81c3f77db85972162512e46 100644 (file)
@@ -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 (file)
index 0000000..7dd5077
--- /dev/null
@@ -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_ */
index 68bdab069d480752a7c99e6bbde255a0442dd319..de55ae5df1530c595c21e9c1f3be0ea7e198262e 100644 (file)
@@ -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 */
index 0088bb9d0b48638481a0843d305010de87a99d37..d1c5ad0a739b55318f15ee7094f559b52319b718 100644 (file)
@@ -269,6 +269,11 @@ struct sunxi_ccm_reg {
 #define CCM_MBUS_CTRL_CLK_SRC_PLL5 0x2
 #define CCM_MBUS_CTRL_GATE (0x1 << 31)
 
+#define CCM_NAND_CTRL_M(x)             ((x) - 1)
+#define CCM_NAND_CTRL_N(x)             ((x) << 16)
+#define CCM_NAND_CTRL_OSCM24           (0x0 << 24)
+#define CCM_NAND_CTRL_PLL6             (0x1 << 24)
+#define CCM_NAND_CTRL_PLL5             (0x2 << 24)
 #define CCM_NAND_CTRL_ENABLE           (0x1 << 31)
 
 #define CCM_MMC_CTRL_M(x)              ((x) - 1)
index c2e72f5a86b2595609d856d75a2ce18a1a87021a..d4dff1e3463e5a532aa79645ecd08dc8d2651209 100644 (file)
@@ -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 */
index c5e9d88bab5c974ce040a5555fd676dbd0860f48..cd009d7ccc2332075943956bf1387c42be5bb704 100644 (file)
@@ -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
index 1ace54802273643df8fbb91aeb00ec651e9c2d35..bff7d1453f12d71624ffdd08f25ee66b36fda398 100644 (file)
@@ -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
index 3da360b177d9b2a0369745f253a759652aac32ca..cb52e648731ce9687b7c9cb472463fd54d8da38d 100644 (file)
@@ -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 */
index ec73379735c93257b209ad0ec7dba7da71eebdbe..5d7ab559ef90b9211aafa59ada93435a2beebce2 100644 (file)
@@ -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 */
 };
index 783bb3c0fa12265901fdd3b99c9f2cc008486a83..a3db7ed6044127c4343136f54ee70c525d6013fa 100644 (file)
@@ -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.
  */
 
index e56031d1afa7e8bd5508447be3e2c16aa0d9417b..7daf8bc1632a6076fff33bf04c508b36ba627ce1 100644 (file)
@@ -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-tegra/ivc.h b/arch/arm/include/asm/arch-tegra/ivc.h
new file mode 100644 (file)
index 0000000..7f2287a
--- /dev/null
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 2016, NVIDIA CORPORATION.
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#ifndef _ASM_ARCH_TEGRA_IVC_H
+#define _ASM_ARCH_TEGRA_IVC_H
+
+#include <common.h>
+
+/*
+ * Tegra IVC is a communication protocol that transfers fixed-size frames
+ * bi-directionally and in-order between the local CPU and some remote entity.
+ * Communication is via a statically sized and allocated buffer in shared
+ * memory and a notification mechanism.
+ *
+ * This API handles all aspects of the shared memory buffer's metadata, and
+ * leaves all aspects of the frame content to the calling code; frames
+ * typically contain some higher-level protocol. The notification mechanism is
+ * also handled externally to this API, since it can vary from instance to
+ * instance.
+ *
+ * The client model is to first find some free (for TX) or filled (for RX)
+ * frame, process that frame's memory buffer (fill or read it), and then
+ * inform the protocol that the frame has been filled/read, i.e. advance the
+ * write/read pointer. If the channel is full, there may be no available frames
+ * to fill/read. In this case, client code may either poll for an available
+ * frame, or wait for the remote entity to send a notification to the local
+ * CPU.
+ */
+
+/**
+ * struct tegra_ivc - In-memory shared memory layout.
+ *
+ * This is described in detail in ivc.c.
+ */
+struct tegra_ivc_channel_header;
+
+/**
+ * struct tegra_ivc - Software state of an IVC channel.
+ *
+ * This state is internal to the IVC code and should not be accessed directly
+ * by clients. It is public solely so clients can allocate storage for the
+ * structure.
+ */
+struct tegra_ivc {
+       /**
+        * rx_channel - Pointer to the shared memory region used to receive
+        * messages from the remote entity.
+        */
+       struct tegra_ivc_channel_header *rx_channel;
+       /**
+        * tx_channel - Pointer to the shared memory region used to send
+        * messages to the remote entity.
+        */
+       struct tegra_ivc_channel_header *tx_channel;
+       /**
+        * r_pos - The position in list of frames in rx_channel that we are
+        * reading from.
+        */
+       uint32_t r_pos;
+       /**
+        * w_pos - The position in list of frames in tx_channel that we are
+        * writing to.
+        */
+       uint32_t w_pos;
+       /**
+        * nframes - The number of frames allocated (in each direction) in
+        * shared memory.
+        */
+       uint32_t nframes;
+       /**
+        * frame_size - The size of each frame in shared memory.
+        */
+       uint32_t frame_size;
+       /**
+        * notify - Function to call to notify the remote processor of a
+        * change in channel state.
+        */
+       void (*notify)(struct tegra_ivc *);
+};
+
+/**
+ * tegra_ivc_read_get_next_frame - Locate the next frame to receive.
+ *
+ * Locate the next frame to be received/processed, return the address of the
+ * frame, and do not remove it from the queue. Repeated calls to this function
+ * will return the same address until tegra_ivc_read_advance() is called.
+ *
+ * @ivc                The IVC channel.
+ * @frame      Pointer to be filled with the address of the frame to receive.
+ *
+ * @return 0 if a frame is available, else a negative error code.
+ */
+int tegra_ivc_read_get_next_frame(struct tegra_ivc *ivc, void **frame);
+
+/**
+ * tegra_ivc_read_advance - Advance the read queue.
+ *
+ * Inform the protocol and remote entity that the frame returned by
+ * tegra_ivc_read_get_next_frame() has been processed. The remote end may then
+ * re-use it to transmit further data. Subsequent to this function returning,
+ * tegra_ivc_read_get_next_frame() will return a different frame.
+ *
+ * @ivc                The IVC channel.
+ *
+ * @return 0 if OK, else a negative error code.
+ */
+int tegra_ivc_read_advance(struct tegra_ivc *ivc);
+
+/**
+ * tegra_ivc_write_get_next_frame - Locate the next frame to fill for transmit.
+ *
+ * Locate the next frame to be filled for transmit, return the address of the
+ * frame, and do not add it to the queue. Repeated calls to this function
+ * will return the same address until tegra_ivc_read_advance() is called.
+ *
+ * @ivc                The IVC channel.
+ * @frame      Pointer to be filled with the address of the frame to fill.
+ *
+ * @return 0 if a frame is available, else a negative error code.
+ */
+int tegra_ivc_write_get_next_frame(struct tegra_ivc *ivc, void **frame);
+
+/**
+ * tegra_ivc_write_advance - Advance the write queue.
+ *
+ * Inform the protocol and remote entity that the frame returned by
+ * tegra_ivc_write_get_next_frame() has been filled and should be transmitted.
+ * The remote end may then read data from it. Subsequent to this function
+ * returning, tegra_ivc_write_get_next_frame() will return a different frame.
+ *
+ * @ivc                The IVC channel.
+ *
+ * @return 0 if OK, else a negative error code.
+ */
+int tegra_ivc_write_advance(struct tegra_ivc *ivc);
+
+/**
+ * tegra_ivc_channel_notified - handle internal messages
+ *
+ * This function must be called following every notification.
+ *
+ * @ivc                The IVC channel.
+ *
+ * @return 0 if the channel is ready for communication, or -EAGAIN if a
+ * channel reset is in progress.
+ */
+int tegra_ivc_channel_notified(struct tegra_ivc *ivc);
+
+/**
+ * tegra_ivc_channel_reset - initiates a reset of the shared memory state
+ *
+ * This function must be called after a channel is initialized but before it
+ * is used for communication. The channel will be ready for use when a
+ * subsequent call to notify the remote of the channel reset indicates the
+ * reset operation is complete.
+ *
+ * @ivc                The IVC channel.
+ */
+void tegra_ivc_channel_reset(struct tegra_ivc *ivc);
+
+/**
+ * tegra_ivc_init - Initialize a channel's software state.
+ *
+ * @ivc                The IVC channel.
+ * @rx_base    Address of the the RX shared memory buffer.
+ * @tx_base    Address of the the TX shared memory buffer.
+ * @nframes    Number of frames in each shared memory buffer.
+ * @frame_size Size of each frame.
+ *
+ * @return 0 if OK, else a negative error code.
+ */
+int tegra_ivc_init(struct tegra_ivc *ivc, ulong rx_base, ulong tx_base,
+                  uint32_t nframes, uint32_t frame_size,
+                  void (*notify)(struct tegra_ivc *));
+
+#endif
index ca6644af345b6d6cb52dedd99636766a853fcf30..c522faa93678cf73bcc574b68dad8836632ac470 100644 (file)
@@ -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.
  *
index b18333d1ca25fd29bb13100d58646fe01adb8316..bfd53b530584285c51e35a3af58c8353df54474c 100644 (file)
@@ -8,7 +8,6 @@
 #ifndef _ASM_ARCH_CLK_H_
 #define _ASM_ARCH_CLK_H_
 
-unsigned long get_uart_clk(int dev_id);
 unsigned long zynqmp_get_system_timer_freq(void);
 
 #endif /* _ASM_ARCH_CLK_H_ */
index 423fc701116614ea94c56fae77c299ca2124d5d3..a20702e612b1b0a9fd31cc5a5eb141e1fa0894b1 100644 (file)
@@ -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 */
 
index 200444dda14d7a937dafef574894648a410eb31f..54d8a2bdff6852f44996f17905fedc2edcf7c21c 100644 (file)
@@ -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 */
index 0d08ed3ba81060235d2f32e8efaec93ef69e1907..aa0f3c42f63211a4ff906fc51111fe6529a0f577 100644 (file)
@@ -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 (file)
index 0000000..eb68185
--- /dev/null
@@ -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_ */
index 1f63127bdc8af38269e0ab2ab9487dc1292641b9..16e65c36a9a5dacefadd4281b30a8a4d4bc77c41 100644 (file)
@@ -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);
index 53cd7550a0629e467e4f5153213a38c2cc4ec3eb..b35c271bba17a3c352397c5b518a72406c0f47d9 100644 (file)
@@ -17,8 +17,6 @@
 
 #ifdef CONFIG_CHAIN_OF_TRUST
 #define CONFIG_CMD_ESBC_VALIDATE
-#define CONFIG_CMD_BLOB
-#define CONFIG_CMD_HASH
 #define CONFIG_FSL_SEC_MON
 #define CONFIG_SHA_HW_ACCEL
 #define CONFIG_SHA_PROG_HW_ACCEL
 #define CONFIG_FSL_CAAM
 #endif
 
+#ifdef CONFIG_SPL_BUILD
+#define CONFIG_SPL_BOARD_INIT
+#define CONFIG_SPL_DM                  1
+#define CONFIG_SPL_CRYPTO_SUPPORT
+#define CONFIG_SPL_HASH_SUPPORT
+#define CONFIG_SPL_RSA
+#define CONFIG_SPL_DRIVERS_MISC_SUPPORT
+/*
+ * Define the key hash for U-Boot here if public/private key pair used to
+ * sign U-boot are different from the SRK hash put in the fuse
+ * Example of defining KEY_HASH is
+ * #define CONFIG_SPL_UBOOT_KEY_HASH \
+ *      "41066b564c6ffcef40ccbc1e0a5d0d519604000c785d97bbefd25e4d288d1c8b"
+ * else leave it defined as NULL
+ */
+
+#define CONFIG_SPL_UBOOT_KEY_HASH      NULL
+#endif /* ifdef CONFIG_SPL_BUILD */
+
+#ifndef CONFIG_SPL_BUILD
+#define CONFIG_CMD_BLOB
+#define CONFIG_CMD_HASH
 #define CONFIG_KEY_REVOCATION
 #ifndef CONFIG_SYS_RAMBOOT
 /* The key used for verification of next level images
        "setenv hwconfig \'fsl_ddr:ctlr_intlv=null,bank_intlv=null\';"
 #else
 #define CONFIG_EXTRA_ENV \
-       "setenv fdt_high 0xcfffffff;"   \
-       "setenv initrd_high 0xcfffffff;"        \
+       "setenv fdt_high 0xffffffff;"   \
+       "setenv initrd_high 0xffffffff;"        \
        "setenv hwconfig \'fsl_ddr:ctlr_intlv=null,bank_intlv=null\';"
 #endif
 
 /* Copying Bootscript and Header to DDR from NOR for LS2 and for rest, from
  * Non-XIP Memory (Nand/SD)*/
-#if defined(CONFIG_SYS_RAMBOOT) || defined(CONFIG_LS2080A)
+#if defined(CONFIG_SYS_RAMBOOT) || defined(CONFIG_LS2080A) || \
+       defined(CONFIG_SD_BOOT)
 #define CONFIG_BOOTSCRIPT_COPY_RAM
 #endif
-/* The address needs to be modified according to NOR and DDR memory map */
+/* The address needs to be modified according to NOR, NAND, SD and
+ * DDR memory map
+ */
 #ifdef CONFIG_LS2080A
-#define CONFIG_BS_HDR_ADDR_FLASH       0x583920000
-#define CONFIG_BS_ADDR_FLASH           0x583900000
+#define CONFIG_BS_HDR_ADDR_DEVICE      0x583920000
+#define CONFIG_BS_ADDR_DEVICE          0x583900000
 #define CONFIG_BS_HDR_ADDR_RAM         0xa3920000
 #define CONFIG_BS_ADDR_RAM             0xa3900000
+#define CONFIG_BS_HDR_SIZE             0x00002000
+#define CONFIG_BS_SIZE                 0x00001000
+#else
+#ifdef CONFIG_SD_BOOT
+/* For SD boot address and size are assigned in terms of sector
+ * offset and no. of sectors respectively.
+ */
+#define CONFIG_BS_HDR_ADDR_DEVICE      0x00000800
+#define CONFIG_BS_ADDR_DEVICE          0x00000840
+#define CONFIG_BS_HDR_SIZE             0x00000010
+#define CONFIG_BS_SIZE                 0x00000008
 #else
-#define CONFIG_BS_HDR_ADDR_FLASH       0x600a0000
-#define CONFIG_BS_ADDR_FLASH           0x60060000
-#define CONFIG_BS_HDR_ADDR_RAM         0xa0060000
-#define CONFIG_BS_ADDR_RAM             0xa0060000
+#define CONFIG_BS_HDR_ADDR_DEVICE      0x600a0000
+#define CONFIG_BS_ADDR_DEVICE          0x60060000
+#define CONFIG_BS_HDR_SIZE             0x00002000
+#define CONFIG_BS_SIZE                 0x00001000
+#endif /* #ifdef CONFIG_SD_BOOT */
+#define CONFIG_BS_HDR_ADDR_RAM         0x81000000
+#define CONFIG_BS_ADDR_RAM             0x81020000
 #endif
 
 #ifdef CONFIG_BOOTSCRIPT_COPY_RAM
 #define CONFIG_BOOTSCRIPT_HDR_ADDR     CONFIG_BS_HDR_ADDR_RAM
-#define CONFIG_BS_HDR_SIZE             0x00002000
 #define CONFIG_BOOTSCRIPT_ADDR         CONFIG_BS_ADDR_RAM
-#define CONFIG_BS_SIZE                 0x00001000
 #else
-#define CONFIG_BOOTSCRIPT_HDR_ADDR     CONFIG_BS_HDR_ADDR_FLASH
-/* BS_HDR_SIZE, BOOTSCRIPT_ADDR and BS_SIZE are not required */
+#define CONFIG_BOOTSCRIPT_HDR_ADDR     CONFIG_BS_HDR_ADDR_DEVICE
+/* BOOTSCRIPT_ADDR is not required */
 #endif
 
 #include <config_fsl_chain_trust.h>
+#endif /* #ifndef CONFIG_SPL_BUILD */
 #endif /* #ifdef CONFIG_CHAIN_OF_TRUST */
 #endif
index 77d2653e27a1002a7afcccaf4513d987570294b4..10550174df4bddc9f73e32ea89e8fd66e49f9d78 100644 (file)
@@ -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;
index 9d185a61223afbdb392f39d536c380976f169a0e..6121f1ddcac49febcd6ccf2a8d834aec00c6a148 100644 (file)
@@ -291,40 +291,6 @@ static inline void __raw_readsl(unsigned long addr, void *data, int longlen)
 #define writesb(a, d, s)       __raw_writesb((unsigned long)a, d, s)
 #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
index 07f384867eb03d43e75eefe8b001a7202033ad1c..605c549f0a5a647b84874d7cd4ed108762c63cc5 100644 (file)
@@ -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 (file)
index 0000000..842f2af
--- /dev/null
@@ -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_ */
index bc5edda73f0076a670214b348bdbc41f976ba720..8aefaa7708559c358215a3948081f65ab4aa08c5 100644 (file)
 #define ARM_PSCI_RET_NI                        (-1)
 #define ARM_PSCI_RET_INVAL             (-2)
 #define ARM_PSCI_RET_DENIED            (-3)
+#define ARM_PSCI_RET_ALREADY_ON                (-4)
+#define ARM_PSCI_RET_ON_PENDING                (-5)
+#define ARM_PSCI_RET_INTERNAL_FAILURE  (-6)
+#define ARM_PSCI_RET_NOT_PRESENT       (-7)
+#define ARM_PSCI_RET_DISABLED          (-8)
+#define ARM_PSCI_RET_INVALID_ADDRESS   (-9)
 
 /* PSCI 0.2 interface */
 #define ARM_PSCI_0_2_FN_BASE                   0x84000000
 #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)
 
+/* PSCI 1.0 interface */
+#define ARM_PSCI_1_0_FN_PSCI_FEATURES          ARM_PSCI_0_2_FN(10)
+#define ARM_PSCI_1_0_FN_CPU_FREEZE             ARM_PSCI_0_2_FN(11)
+#define ARM_PSCI_1_0_FN_CPU_DEFAULT_SUSPEND    ARM_PSCI_0_2_FN(12)
+#define ARM_PSCI_1_0_FN_NODE_HW_STATE          ARM_PSCI_0_2_FN(13)
+#define ARM_PSCI_1_0_FN_SYSTEM_SUSPEND         ARM_PSCI_0_2_FN(14)
+#define ARM_PSCI_1_0_FN_SET_SUSPEND_MODE       ARM_PSCI_0_2_FN(15)
+#define ARM_PSCI_1_0_FN_STAT_RESIDENCY         ARM_PSCI_0_2_FN(16)
+#define ARM_PSCI_1_0_FN_STAT_COUNT             ARM_PSCI_0_2_FN(17)
+
+/* 1KB stack per core */
+#define ARM_PSCI_STACK_SHIFT   10
+#define ARM_PSCI_STACK_SIZE    (1 << ARM_PSCI_STACK_SHIFT)
+
+/* PSCI affinity level state returned by AFFINITY_INFO */
+#define PSCI_AFFINITY_LEVEL_ON         0
+#define PSCI_AFFINITY_LEVEL_OFF                1
+#define PSCI_AFFINITY_LEVEL_ON_PENDING 2
+
 #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__ */
index effdb1858d88759b945c8e6f45eadad6666c6266..5a403bc0f153593163f3883692233ac1386ff81d 100644 (file)
@@ -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/spin_table.h b/arch/arm/include/asm/spin_table.h
new file mode 100644 (file)
index 0000000..8b57539
--- /dev/null
@@ -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__ */
index d108915ff5c1e1accc0f4d80be10921707dea667..9af7353f0866f05dbe298a603d52d90e9c8e6d28 100644 (file)
@@ -71,5 +71,4 @@ typedef u32 dma_addr_t;
 
 #endif /* __KERNEL__ */
 
-typedef unsigned long resource_size_t;
 #endif
index 0e05e87deafcb7581a6cc1c8def80fd2ec98fa6b..9f71376d30af4a54692e0c4be252af4215d00d4e 100644 (file)
@@ -27,11 +27,13 @@ endif
 obj-$(CONFIG_CPU_V7M) += cmd_boot.o
 obj-$(CONFIG_OF_LIBFDT) += bootm-fdt.o
 obj-$(CONFIG_CMD_BOOTM) += bootm.o
+obj-$(CONFIG_CMD_BOOTM) += zimage.o
 obj-$(CONFIG_SYS_L2_PL310) += cache-pl310.o
 obj-$(CONFIG_USE_ARCH_MEMSET) += memset.o
 obj-$(CONFIG_USE_ARCH_MEMCPY) += memcpy.o
 else
 obj-$(CONFIG_SPL_FRAMEWORK) += spl.o
+obj-$(CONFIG_SPL_FRAMEWORK) += zimage.o
 endif
 obj-$(CONFIG_SEMIHOSTING) += semihosting.o
 
@@ -55,6 +57,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()
index 76b75d8e4643ee9a018c216c15301de2ae15f3d4..4481f9e2fa9ceb26f2f54f21e67f6b825c016601 100644 (file)
@@ -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;
index 0838d89907b9a2eb81f4ebb31d8c045e031c5e11..c20ef227fb4e7afd48e051cf50b36380db1fa5da 100644 (file)
@@ -358,38 +358,6 @@ int do_bootm_linux(int flag, int argc, char * const argv[],
        return 0;
 }
 
-#ifdef CONFIG_CMD_BOOTZ
-
-struct zimage_header {
-       uint32_t        code[9];
-       uint32_t        zi_magic;
-       uint32_t        zi_start;
-       uint32_t        zi_end;
-};
-
-#define        LINUX_ARM_ZIMAGE_MAGIC  0x016f2818
-
-int bootz_setup(ulong image, ulong *start, ulong *end)
-{
-       struct zimage_header *zi;
-
-       zi = (struct zimage_header *)map_sysmem(image, 0);
-       if (zi->zi_magic != LINUX_ARM_ZIMAGE_MAGIC) {
-               puts("Bad Linux ARM zImage magic!\n");
-               return 1;
-       }
-
-       *start = zi->zi_start;
-       *end = zi->zi_end;
-
-       printf("Kernel image @ %#08lx [ %#08lx - %#08lx ]\n", image, *start,
-             *end);
-
-       return 0;
-}
-
-#endif /* CONFIG_CMD_BOOTZ */
-
 #if defined(CONFIG_BOOTM_VXWORKS)
 void boot_prep_vxworks(bootm_headers_t *images)
 {
index 3bd87105c58bb760048f127c5e292ae9fec0362e..d330b09434a46df1ab6505bf8b46c54e90ccfa21 100644 (file)
 #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
index cad22c7b41fe4c7237acba611057255931d02fea..91b19e00da22cd12a68991cc40680de0736651ca 100644 (file)
@@ -108,6 +108,7 @@ relocation_return:
  * Set up final (full) environment
  */
        bl      c_runtime_cpu_setup             /* still call old routine */
+#endif /* !CONFIG_SPL_BUILD */
 
 /* TODO: For SPL, call spl_relocate_stack_gd() to alloc stack relocation */
 
@@ -130,6 +131,4 @@ clear_loop:
 
        /* NOTREACHED - board_init_r() does not return */
 
-#endif /* !CONFIG_SPL_BUILD */
-
 ENDPROC(_main)
diff --git a/arch/arm/lib/psci-dt.c b/arch/arm/lib/psci-dt.c
new file mode 100644 (file)
index 0000000..8dc31d4
--- /dev/null
@@ -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;
+}
index 6a9452241834c68d329834ccd10ae5e73c31c023..952e8ae49bf4ae9b19c755b5240791f31e1127ec 100644 (file)
@@ -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")));
index e42886840ed64865aaeabaed93678801e098a5dd..3587ad681297e980ed65fca650314c09474c5b20 100644 (file)
@@ -25,22 +25,20 @@ gd_t gdata __attribute__ ((section(".data")));
 #endif
 
 /*
- * In the context of SPL, board_init_f must ensure that any clocks/etc for
- * DDR are enabled, ensure that the stack pointer is valid, clear the BSS
- * and call board_init_r.  We provide this version by default but mark it
- * as __weak to allow for platforms to do this in their own way if needed.
+ * In the context of SPL, board_init_f() prepares the hardware for execution
+ * from system RAM (DRAM, DDR...). As system RAM may not be available yet,
+ * board_init_f() must use the current GD to store any data which must be
+ * passed on to later stages. These data include the relocation destination,
+ * the future stack, and the future GD location. BSS is cleared after this
+ * function (and therefore must be accessible).
+ *
+ * We provide this version by default but mark it as __weak to allow for
+ * platforms to do this in their own way if needed. Please see the top
+ * level U-Boot README "Board Initialization Flow" section for info on what
+ * to put in this function.
  */
 void __weak board_init_f(ulong dummy)
 {
-       /* Clear the BSS. */
-       memset(__bss_start, 0, __bss_end - __bss_start);
-
-#ifndef CONFIG_SPL_DM
-       /* TODO: Remove settings of the global data pointer here */
-       gd = &gdata;
-#endif
-
-       board_init_r(NULL, 0);
 }
 
 /*
@@ -60,7 +58,7 @@ void __noreturn jump_to_image_linux(void *arg)
        typedef void (*image_entry_arg_t)(int, int, void *)
                __attribute__ ((noreturn));
        image_entry_arg_t image_entry =
-               (image_entry_arg_t) spl_image.entry_point;
+               (image_entry_arg_t)(uintptr_t) spl_image.entry_point;
        cleanup_before_linux();
        image_entry(0, machid, arg);
 }
diff --git a/arch/arm/lib/zimage.c b/arch/arm/lib/zimage.c
new file mode 100644 (file)
index 0000000..1e811a8
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2016
+ * Ladislav Michl <ladis@linux-mips.org>
+ *
+ * bootz code:
+ * Copyright (C) 2012 Marek Vasut <marek.vasut@gmail.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+#include <common.h>
+
+#define        LINUX_ARM_ZIMAGE_MAGIC  0x016f2818
+
+struct arm_z_header {
+       uint32_t        code[9];
+       uint32_t        zi_magic;
+       uint32_t        zi_start;
+       uint32_t        zi_end;
+} __attribute__ ((__packed__));
+
+int bootz_setup(ulong image, ulong *start, ulong *end)
+{
+       struct arm_z_header *zi = (struct arm_z_header *)image;
+
+       if (zi->zi_magic != LINUX_ARM_ZIMAGE_MAGIC) {
+#ifndef CONFIG_SPL_FRAMEWORK
+               puts("Bad Linux ARM zImage magic!\n");
+#endif
+               return 1;
+       }
+
+       *start = zi->zi_start;
+       *end = zi->zi_end;
+#ifndef CONFIG_SPL_FRAMEWORK
+       printf("Kernel image @ %#08lx [ %#08lx - %#08lx ]\n",
+              image, *start, *end);
+#endif
+
+       return 0;
+}
index bd997ad47e31f82cf96df1d15dceb327bd8b2849..ab8361f4a8bf119b11273161d9c21cce2a95f943 100644 (file)
@@ -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);
index ba6d99d329d515e855d0c7084350e41add1e42a5..23814222d82d3e2ec4c9e317c555c87998eb98d3 100644 (file)
@@ -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,
        },
 };
 
index 3b6d5efce1a1386f2203d5e75b0e46892612e47f..6e5a1e1af1705c1d6b160f95d1740aefc6b25414 100644 (file)
@@ -101,9 +101,7 @@ static void msmc_k2hkle_common_setup(void)
        msmc_share_all_segments(KS2_MSMC_SEGMENT_C6X_0);
        msmc_share_all_segments(K2HKLE_MSMC_SEGMENT_ARM);
        msmc_share_all_segments(K2HKLE_MSMC_SEGMENT_NETCP);
-#ifdef KS2_MSMC_SEGMENT_QM_PDSP
        msmc_share_all_segments(K2HKLE_MSMC_SEGMENT_QM_PDSP);
-#endif
        msmc_share_all_segments(K2HKLE_MSMC_SEGMENT_PCIE0);
        msmc_share_all_segments(KS2_MSMC_SEGMENT_DEBUG);
 }
index 64fa3c191ee79b8f95325fd23a20a07d740e267c..1dd53e2313f31b278e52f814f492914758b3def1 100644 (file)
@@ -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 |
index 2a8afac5e125b30c5f041bcfa229c46830206321..1aac3c85ba5f5121a6d667a16fb0a74bd674e61f 100644 (file)
@@ -1,7 +1,21 @@
 if ARCH_ROCKCHIP
 
+config ROCKCHIP_RK3036
+       bool "Support Rockchip RK3036"
+       select CPU_V7
+       select SUPPORT_SPL
+       select SPL
+       help
+         The Rockchip RK3036 is a ARM-based SoC with a dual-core Cortex-A7
+         including NEON and GPU, Mali-400 graphics, several DDR3 options
+         and video codec support. Peripherals include Gigabit Ethernet,
+         USB2 host and OTG, SDIO, I2S, UART, SPI, I2C and PWMs.
+
 config ROCKCHIP_RK3288
        bool "Support Rockchip RK3288"
+       select CPU_V7
+       select SUPPORT_SPL
+       select SPL
        help
          The Rockchip RK3288 is a ARM-based SoC with a quad-core Cortex-A17
          including NEON and GPU, 1MB L2 cache, Mali-T7 graphics, two
@@ -9,41 +23,26 @@ config ROCKCHIP_RK3288
          and video codec support. Peripherals include Gigabit Ethernet,
          USB2 host and OTG, SDIO, I2S, UART,s, SPI, I2C and PWMs.
 
-config ROCKCHIP_RK3036
-       bool "Support Rockchip RK3036"
+config ROCKCHIP_RK3399
+       bool "Support Rockchip RK3399"
+       select ARM64
        help
-         The Rockchip RK3036 is a ARM-based SoC with a dual-core Cortex-A7
-         including NEON and GPU, Mali-400 graphics, several DDR3 options
+         The Rockchip RK3399 is a ARM-based SoC with a dual-core Cortex-A72
+         and quad-core Cortex-A53.
+         including NEON and GPU, 1MB L2 cache, Mali-T7 graphics, two
+         video interfaces supporting HDMI and eDP, several DDR3 options
          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
+         USB2 host and OTG, SDIO, I2S, UARTs, SPI, I2C and PWMs.
 
-config DM_SPI_FLASH
-       default y
-
-config DM_I2C
-       default y
-
-config DM_GPIO
-       default y
-
-config BLK
-       default y
+config ROCKCHIP_SPL_BACK_TO_BROM
+       bool "SPL returns to bootrom"
+       default y if ROCKCHIP_RK3036
+       help
+         Rockchip SoCs have ability to load SPL & U-Boot binary. If enabled,
+          SPL will return to the boot rom, which will then load the U-Boot
+          binary to keep going on.
 
-source "arch/arm/mach-rockchip/rk3288/Kconfig"
 source "arch/arm/mach-rockchip/rk3036/Kconfig"
+source "arch/arm/mach-rockchip/rk3288/Kconfig"
+source "arch/arm/mach-rockchip/rk3399/Kconfig"
 endif
index 55567cb131b16293abfdead422a0abba68c73601..157d42fe960dff02cc74057947db405c9afccad6 100644 (file)
@@ -5,11 +5,15 @@
 #
 
 ifdef CONFIG_SPL_BUILD
-obj-$(CONFIG_ROCKCHIP_RK3288) += rk3288-board-spl.o
 obj-$(CONFIG_ROCKCHIP_RK3036) += rk3036-board-spl.o
+obj-$(CONFIG_ROCKCHIP_RK3288) += rk3288-board-spl.o
+obj-$(CONFIG_ROCKCHIP_SPL_BACK_TO_BROM) += save_boot_param.o
 else
 obj-$(CONFIG_ROCKCHIP_RK3288) += board.o
 endif
+ifndef CONFIG_ARM64
 obj-y += rk_timer.o
-obj-$(CONFIG_ROCKCHIP_RK3288) += rk3288/
+endif
 obj-$(CONFIG_ROCKCHIP_RK3036) += rk3036/
+obj-$(CONFIG_ROCKCHIP_RK3288) += rk3288/
+obj-$(CONFIG_ROCKCHIP_RK3399) += rk3399/
index 816540e5821459fbfff4b5d953f3ee2e70cf2cf7..bec756d7ac0bad6aed9324254909b2d675a85fc9 100644 (file)
 #include <ram.h>
 #include <asm/io.h>
 #include <asm/arch/clock.h>
+#include <asm/arch/periph.h>
+#include <asm/gpio.h>
+#include <dm/pinctrl.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
 int board_init(void)
 {
+#ifdef CONFIG_ROCKCHIP_SPL_BACK_TO_BROM
+       struct udevice *pinctrl;
+       int ret;
+
+    /*
+     * We need to implement sdcard iomux here for the further
+     * initlization, otherwise, it'll hit sdcard command sending
+     * timeout exception.
+     */
+       ret = uclass_get_device(UCLASS_PINCTRL, 0, &pinctrl);
+       if (ret) {
+               debug("%s: Cannot find pinctrl device\n", __func__);
+               goto err;
+       }
+       ret = pinctrl_request_noflags(pinctrl, PERIPH_ID_SDCARD);
+       if (ret) {
+               debug("%s: Failed to set up SD card\n", __func__);
+               goto err;
+       }
+
+       return 0;
+err:
+       printf("board_init: Error %d\n", ret);
+
+       /* No way to report error here */
+       hang();
+
+       return -1;
+#else
        return 0;
+#endif
 }
 
 int dram_init(void)
@@ -52,6 +85,78 @@ void lowlevel_init(void)
 {
 }
 
+#if defined(CONFIG_USB_GADGET) && defined(CONFIG_USB_GADGET_DWC2_OTG)
+#include <usb.h>
+#include <usb/dwc2_udc.h>
+
+static struct dwc2_plat_otg_data rk3288_otg_data = {
+       .rx_fifo_sz     = 512,
+       .np_tx_fifo_sz  = 16,
+       .tx_fifo_sz     = 128,
+};
+
+int board_usb_init(int index, enum usb_init_type init)
+{
+       int node, phy_node;
+       const char *mode;
+       bool matched = false;
+       const void *blob = gd->fdt_blob;
+       u32 grf_phy_offset;
+
+       /* find the usb_otg node */
+       node = fdt_node_offset_by_compatible(blob, -1,
+                                       "rockchip,rk3288-usb");
+
+       while (node > 0) {
+               mode = fdt_getprop(blob, node, "dr_mode", NULL);
+               if (mode && strcmp(mode, "otg") == 0) {
+                       matched = true;
+                       break;
+               }
+
+               node = fdt_node_offset_by_compatible(blob, node,
+                                       "rockchip,rk3288-usb");
+       }
+       if (!matched) {
+               debug("Not found usb_otg device\n");
+               return -ENODEV;
+       }
+       rk3288_otg_data.regs_otg = fdtdec_get_addr(blob, node, "reg");
+
+       node = fdtdec_lookup_phandle(blob, node, "phys");
+       if (node <= 0) {
+               debug("Not found usb phy device\n");
+               return -ENODEV;
+       }
+
+       phy_node = fdt_parent_offset(blob, node);
+       if (phy_node <= 0) {
+               debug("Not found usb phy device\n");
+               return -ENODEV;
+       }
+
+       rk3288_otg_data.phy_of_node = phy_node;
+       grf_phy_offset = fdtdec_get_addr(blob, node, "reg");
+
+       /* find the grf node */
+       node = fdt_node_offset_by_compatible(blob, -1,
+                                       "rockchip,rk3288-grf");
+       if (node <= 0) {
+               debug("Not found grf device\n");
+               return -ENODEV;
+       }
+       rk3288_otg_data.regs_phy = grf_phy_offset +
+                               fdtdec_get_addr(blob, node, "reg");
+
+       return dwc2_udc_probe(&rk3288_otg_data);
+}
+
+int board_usb_cleanup(int index, enum usb_init_type init)
+{
+       return 0;
+}
+#endif
+
 static int do_clock(cmd_tbl_t *cmdtp, int flag, int argc,
                       char * const argv[])
 {
@@ -73,7 +178,7 @@ static int do_clock(cmd_tbl_t *cmdtp, int flag, int argc,
        int ret, i;
        struct udevice *dev;
 
-       ret = uclass_get_device(UCLASS_CLK, 0, &dev);
+       ret = rockchip_get_clk(&dev);
        if (ret) {
                printf("clk-uclass not found\n");
                return 0;
index cc0380884729bd69be6ad0fb53180da49d6a10ff..f7562bd610faa7845ac4fb9b8576d27aa0eb5b6a 100644 (file)
@@ -15,7 +15,7 @@ config SYS_MALLOC_F_LEN
 config ROCKCHIP_COMMON
        bool "Support rk common fuction"
 
-source "board/evb_rk3036/evb_rk3036/Kconfig"
-source "board/kylin/kylin_rk3036/Kconfig"
+source "board/rockchip/evb_rk3036/Kconfig"
+source "board/rockchip/kylin_rk3036/Kconfig"
 
 endif
index 97d299d6cc6963efde70d88678d74c8773de528c..6095777b8fcf2b1b1d1ec3dfc4c78566fabe2648 100644 (file)
@@ -10,4 +10,3 @@ obj-y += syscon_rk3036.o
 endif
 
 obj-y += sdram_rk3036.o
-obj-y += save_boot_param.o
diff --git a/arch/arm/mach-rockchip/rk3036/save_boot_param.S b/arch/arm/mach-rockchip/rk3036/save_boot_param.S
deleted file mode 100644 (file)
index 778ec83..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * (C) Copyright 2015 Google, Inc
- *
- * SPDX-License-Identifier:     GPL-2.0+
- */
-
-#include <linux/linkage.h>
-
-.globl SAVE_SP_ADDR
-SAVE_SP_ADDR:
-       .word 0
-
-/*
- * void save_boot_params
- *
- * Save sp, lr, r1~r12
- */
-ENTRY(save_boot_params)
-       push    {r1-r12, lr}
-       ldr     r0, =SAVE_SP_ADDR
-       str     sp, [r0]
-       b       save_boot_params_ret            @ back to my caller
-ENDPROC(save_boot_params)
-
-
-.globl back_to_bootrom
-ENTRY(back_to_bootrom)
-       ldr     r0, =SAVE_SP_ADDR
-       ldr     sp, [r0]
-       mov     r0, #0
-       pop     {r1-r12, pc}
-ENDPROC(back_to_bootrom)
index 15f1266a7bf4380cdb195fa3810b0ded970c735e..ed14023021d5694a9c8a4ef512d1da0c9a96c5ac 100644 (file)
@@ -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,12 +145,11 @@ static int configure_emmc(struct udevice *pinctrl)
                debug("gpio value ret=%d\n", ret);
                return ret;
        }
-#endif
 
        return 0;
 }
 #endif
-
+extern void back_to_bootrom(void);
 void board_init_f(ulong dummy)
 {
        struct udevice *pinctrl;
@@ -187,7 +187,7 @@ void board_init_f(ulong dummy)
        rockchip_timer_init();
        configure_l2ctlr();
 
-       ret = uclass_get_device(UCLASS_CLK, 0, &dev);
+       ret = rockchip_get_clk(&dev);
        if (ret) {
                debug("CLK init failed: %d\n", ret);
                return;
@@ -204,6 +204,9 @@ void board_init_f(ulong dummy)
                debug("DRAM init failed: %d\n", ret);
                return;
        }
+#ifdef CONFIG_ROCKCHIP_SPL_BACK_TO_BROM
+       back_to_bootrom();
+#endif
 }
 
 static int setup_led(void)
@@ -247,15 +250,19 @@ 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) &&
+           !IS_ENABLED(CONFIG_TARGET_EVB_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
 
index 72156245bd37552845bda63b18315c01a90e2273..031dbfc06146236cd38cfc8d0a949f12e724c6d3 100644 (file)
@@ -8,6 +8,14 @@ config TARGET_FIREFLY_RK3288
          also includes on-board eMMC and 1GB of SDRAM. Expansion connectors
          provide access to display pins, I2C, SPI, UART and GPIOs.
 
+config TARGET_EVB_RK3288
+       bool "Evb-RK3288"
+       help
+         EVB-RK3288 is a RK3288-based development board with 2 USB ports,
+         HDMI, VGA, micro-SD card, audio, WiFi  and Gigabit Ethernet, It
+         also includes on-board eMMC and 2GB of SDRAM. Expansion connectors
+         provide access to display pins, I2C, SPI, UART and GPIOs.
+
 config TARGET_CHROMEBOOK_JERRY
        bool "Google/Rockchip Veyron-Jerry Chromebook"
        help
@@ -45,4 +53,6 @@ source "board/firefly/firefly-rk3288/Kconfig"
 
 source "board/radxa/rock2/Kconfig"
 
+source "board/evb-rk3288/evb-rk3288/Kconfig"
+
 endif
index 6f62375f46452c910a8b0cd37bc15f73ac1ae4a2..82b00a1b01254593e6d4e0387367082c9ac84766 100644 (file)
@@ -4,6 +4,7 @@
 # SPDX-License-Identifier:      GPL-2.0+
 #
 
+obj-y += clk_rk3288.o
 obj-y += reset_rk3288.o
 obj-y += sdram_rk3288.o
 obj-y += syscon_rk3288.o
diff --git a/arch/arm/mach-rockchip/rk3288/clk_rk3288.c b/arch/arm/mach-rockchip/rk3288/clk_rk3288.c
new file mode 100644 (file)
index 0000000..2099e34
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <syscon.h>
+#include <asm/arch/clock.h>
+
+int rockchip_get_clk(struct udevice **devp)
+{
+       return uclass_get_device_by_driver(UCLASS_CLK,
+                       DM_GET_DRIVER(rockchip_rk3288_cru), devp);
+}
index 55ac73e9d25111eb96345e07d66cd7af9f80e9ed..cf9ef2e8451aa9f2f6dca33953bf1f2be3a7f5b4 100644 (file)
@@ -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
@@ -561,14 +575,14 @@ static void dram_all_config(const struct dram_info *dram,
                        &sdram_params->ch[chan];
 
                sys_reg |= info->row_3_4 << SYS_REG_ROW_3_4_SHIFT(chan);
-               sys_reg |= chan << SYS_REG_CHINFO_SHIFT(chan);
+               sys_reg |= 1 << SYS_REG_CHINFO_SHIFT(chan);
                sys_reg |= (info->rank - 1) << SYS_REG_RANK_SHIFT(chan);
                sys_reg |= (info->col - 9) << SYS_REG_COL_SHIFT(chan);
-               sys_reg |= info->bk == 3 ? 1 << SYS_REG_BK_SHIFT(chan) : 0;
+               sys_reg |= info->bk == 3 ? 0 : 1 << SYS_REG_BK_SHIFT(chan);
                sys_reg |= (info->cs0_row - 13) << SYS_REG_CS0_ROW_SHIFT(chan);
                sys_reg |= (info->cs1_row - 13) << SYS_REG_CS1_ROW_SHIFT(chan);
-               sys_reg |= info->bw << SYS_REG_BW_SHIFT(chan);
-               sys_reg |= info->dbw << SYS_REG_DBW_SHIFT(chan);
+               sys_reg |= (2 >> info->bw) << SYS_REG_BW_SHIFT(chan);
+               sys_reg |= (2 >> info->dbw) << SYS_REG_DBW_SHIFT(chan);
 
                dram_cfg_rbc(&dram->chan[chan], chan, sdram_params);
        }
@@ -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)
 {
@@ -720,13 +734,13 @@ size_t sdram_size_mb(struct rk3288_pmu *pmu)
                rank = 1 + (sys_reg >> SYS_REG_RANK_SHIFT(ch) &
                        SYS_REG_RANK_MASK);
                col = 9 + (sys_reg >> SYS_REG_COL_SHIFT(ch) & SYS_REG_COL_MASK);
-               bk = sys_reg & (1 << SYS_REG_BK_SHIFT(ch)) ? 3 : 0;
+               bk = 3 - ((sys_reg >> SYS_REG_BK_SHIFT(ch)) & SYS_REG_BK_MASK);
                cs0_row = 13 + (sys_reg >> SYS_REG_CS0_ROW_SHIFT(ch) &
                                SYS_REG_CS0_ROW_MASK);
                cs1_row = 13 + (sys_reg >> SYS_REG_CS1_ROW_SHIFT(ch) &
                                SYS_REG_CS1_ROW_MASK);
-               bw = (sys_reg >> SYS_REG_BW_SHIFT(ch)) &
-                       SYS_REG_BW_MASK;
+               bw = (2 >> ((sys_reg >> SYS_REG_BW_SHIFT(ch)) &
+                       SYS_REG_BW_MASK));
                row_3_4 = sys_reg >> SYS_REG_ROW_3_4_SHIFT(ch) &
                        SYS_REG_ROW_3_4_MASK;
 
@@ -770,7 +784,7 @@ static int veyron_init(struct dram_info *priv)
                return ret;
        udelay(100);/* Must wait for voltage to stabilize, 2mV/us */
 
-       rkclk_configure_cpu(priv->cru, priv->grf);
+       rk3288_clk_configure_cpu(priv->cru, priv->grf);
 
        return 0;
 }
@@ -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,15 +917,13 @@ 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);
-
-       ret = uclass_get_device(UCLASS_CLK, 0, &dev_clk);
+#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 = rockchip_get_clk(&dev_clk);
        if (ret)
                return ret;
        priv->ddr_clk.id = CLK_DDR;
@@ -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
 };
index c9f7c4e32f44b883cb22052e23f48b0f858e107b..be4b2b00c30b78a98a5919e19280ccb93bb3127a 100644 (file)
@@ -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-rockchip/rk3399/Kconfig b/arch/arm/mach-rockchip/rk3399/Kconfig
new file mode 100644 (file)
index 0000000..83bd04a
--- /dev/null
@@ -0,0 +1,23 @@
+if ROCKCHIP_RK3399
+
+choice
+       prompt "RK3399 board select"
+
+config TARGET_EVB_RK3399
+       bool "RK3399 evaluation board"
+       help
+         RK3399evb is a evaluation board for Rockchp rk3399,
+         with full function and phisical connectors support like type-C ports,
+         usb2.0 host ports, LVDS, JTAG, MAC, SDcard, HDMI, USB-2-serial...
+
+endchoice
+
+config SYS_SOC
+       default "rockchip"
+
+config SYS_MALLOC_F_LEN
+       default 0x0800
+
+source "board/rockchip/evb_rk3399/Kconfig"
+
+endif
diff --git a/arch/arm/mach-rockchip/rk3399/Makefile b/arch/arm/mach-rockchip/rk3399/Makefile
new file mode 100644 (file)
index 0000000..3f219ac
--- /dev/null
@@ -0,0 +1,7 @@
+#
+# (C) Copyright 2016 Rockchip Electronics Co., Ltd
+#
+# SPDX-License-Identifier:     GPL-2.0+
+#
+
+obj-y += rk3399.o
diff --git a/arch/arm/mach-rockchip/rk3399/rk3399.c b/arch/arm/mach-rockchip/rk3399/rk3399.c
new file mode 100644 (file)
index 0000000..b9d7629
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2016 Rockchip Electronics Co., Ltd
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/armv8/mmu.h>
+
+static struct mm_region rk3399_mem_map[] = {
+       {
+               .virt = 0x0UL,
+               .phys = 0x0UL,
+               .size = 0x80000000UL,
+               .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+                        PTE_BLOCK_INNER_SHARE
+       }, {
+               .virt = 0xf0000000UL,
+               .phys = 0xf0000000UL,
+               .size = 0x10000000UL,
+               .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+                        PTE_BLOCK_NON_SHARE |
+                        PTE_BLOCK_PXN | PTE_BLOCK_UXN
+       }, {
+               /* List terminator */
+               0,
+       }
+};
+
+struct mm_region *mem_map = rk3399_mem_map;
diff --git a/arch/arm/mach-rockchip/save_boot_param.S b/arch/arm/mach-rockchip/save_boot_param.S
new file mode 100644 (file)
index 0000000..85b407b
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * (C) Copyright 2016 Rockchip Electronics Co., Ltd
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <linux/linkage.h>
+
+.globl SAVE_SP_ADDR
+SAVE_SP_ADDR:
+       .word 0
+
+/*
+ * void save_boot_params
+ *
+ * Save sp, lr, r1~r12
+ */
+ENTRY(save_boot_params)
+       push    {r1-r12, lr}
+       ldr     r0, =SAVE_SP_ADDR
+       str     sp, [r0]
+       b       save_boot_params_ret            @ back to my caller
+ENDPROC(save_boot_params)
+
+
+.globl back_to_bootrom
+ENTRY(back_to_bootrom)
+       ldr     r0, =SAVE_SP_ADDR
+       ldr     sp, [r0]
+       mov     r0, #0
+       pop     {r1-r12, pc}
+ENDPROC(back_to_bootrom)
index ef0db2ab5f42dad002a87728158fc4666a214b9e..580b9c7e6159a7e4f7aa07d893454c22b54835ec 100644 (file)
 
 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
index 40f1ad35b7eb1fe4d3b4991ed4cc05d8387f6162..643d4d919c2cdf5c0f156f362a09540de2202cc3 100644 (file)
@@ -5,4 +5,4 @@
 # SPDX-License-Identifier:     GPL-2.0+
 #
 
-obj-y += timer.o clock.o
+obj-y += timer.o clock.o soc.o
index 17a715bac92e9fb840b08b2ae40f28dd81a0711d..78d22d40fd83edbd7ed3b2204aa77a9dbfc5ca05 100644 (file)
 #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) {
diff --git a/arch/arm/mach-stm32/stm32f7/soc.c b/arch/arm/mach-stm32/stm32f7/soc.c
new file mode 100644 (file)
index 0000000..8baee99
--- /dev/null
@@ -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)
+{
+}
index 66e028ec1467d657a1c408f6bd80b9b8dd50cc45..6d9518d4c6036a09a7462674df5ef0a940404ef6 100644 (file)
@@ -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 */
 }
 
index f4affa5512bcf8c5f78a75a8e0c7b020d1674821..85ae3b7f420992c2a125fc7c981c87fb6f4cf6a0 100644 (file)
@@ -1,5 +1,13 @@
 if TEGRA
 
+config TEGRA_IVC
+       bool "Tegra IVC protocol"
+       help
+         IVC (Inter-VM Communication) protocol is a Tegra-specific IPC
+         (Inter Processor Communication) framework. Within the context of
+         U-Boot, it is typically used for communication between the main CPU
+         and various auxiliary processors.
+
 config TEGRA_COMMON
        bool "Tegra common options"
        select DM
@@ -60,6 +68,7 @@ config TEGRA186
        select TEGRA186_GPIO
        select TEGRA_ARMV8_COMMON
        select TEGRA_HSP
+       select TEGRA_IVC
 
 endchoice
 
index 12ee1cd7495b48a9055e6bb6ff154df3ed1080cf..d0bf5a6e75ef2dc178bf612d85565a66b05eef0e 100644 (file)
@@ -15,23 +15,24 @@ else
 obj-$(CONFIG_CMD_ENTERRCM) += cmd_enterrcm.o
 endif
 
-obj-$(CONFIG_ARM64) += arm64-mmu.o
 obj-y += ap.o
 obj-y += board.o board2.o
 obj-y += cache.o
 obj-y += clock.o
-obj-y += lowlevel_init.o
 obj-y += pinmux-common.o
 obj-y += powergate.o
 obj-y += xusb-padctl-dummy.o
-obj-$(CONFIG_DISPLAY_CPUINFO) += sys_info.o
-obj-$(CONFIG_TEGRA_GPU) += gpu.o
-obj-$(CONFIG_TEGRA_CLOCK_SCALING) += emc.o
+endif
 
+obj-$(CONFIG_ARM64) += arm64-mmu.o
+obj-$(CONFIG_TEGRA_CLOCK_SCALING) += emc.o
+obj-$(CONFIG_TEGRA_GPU) += gpu.o
+obj-$(CONFIG_TEGRA_IVC) += ivc.o
+obj-y += lowlevel_init.o
 ifndef CONFIG_SPL_BUILD
 obj-$(CONFIG_ARMV7_PSCI) += psci.o
 endif
-endif
+obj-$(CONFIG_DISPLAY_CPUINFO) += sys_info.o
 
 obj-$(CONFIG_TEGRA20) += tegra20/
 obj-$(CONFIG_TEGRA30) += tegra30/
index 501c4f00c4e03ef9d536eff2e1c1ac0646e2dff6..7b1d258ed84f5f6cedb051107a9811d5111d8a42 100644 (file)
 
 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
index f4b6152a79374b3f9d87090e9ff33b854f9b634c..876ccba5e599cb45fea9351eb92448d47cbd2e2b 100644 (file)
 
 DECLARE_GLOBAL_DATA_PTR;
 
-int dram_init(void)
-{
-       gd->ram_size = (1.5 * 1024 * 1024 * 1024);
-       return 0;
-}
-
 int board_early_init_f(void)
 {
        return 0;
@@ -32,12 +26,6 @@ int board_late_init(void)
        return 0;
 }
 
-void dram_init_banksize(void)
-{
-       gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE;
-       gd->bd->bi_dram[0].size = gd->ram_size;
-}
-
 void pad_init_mmc(struct mmc_host *host)
 {
 }
index c50d56dc888b5f612604832b22045b317cfdc93c..36eabc8f5721125a6708573ab2b0755822df23a6 100644 (file)
@@ -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/ivc.c b/arch/arm/mach-tegra/ivc.c
new file mode 100644 (file)
index 0000000..cf6626f
--- /dev/null
@@ -0,0 +1,553 @@
+/*
+ * Copyright (c) 2016, NVIDIA CORPORATION.
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch-tegra/ivc.h>
+
+#define TEGRA_IVC_ALIGN 64
+
+/*
+ * IVC channel reset protocol.
+ *
+ * Each end uses its tx_channel.state to indicate its synchronization state.
+ */
+enum ivc_state {
+       /*
+        * This value is zero for backwards compatibility with services that
+        * assume channels to be initially zeroed. Such channels are in an
+        * initially valid state, but cannot be asynchronously reset, and must
+        * maintain a valid state at all times.
+        *
+        * The transmitting end can enter the established state from the sync or
+        * ack state when it observes the receiving endpoint in the ack or
+        * established state, indicating that has cleared the counters in our
+        * rx_channel.
+        */
+       ivc_state_established = 0,
+
+       /*
+        * If an endpoint is observed in the sync state, the remote endpoint is
+        * allowed to clear the counters it owns asynchronously with respect to
+        * the current endpoint. Therefore, the current endpoint is no longer
+        * allowed to communicate.
+        */
+       ivc_state_sync,
+
+       /*
+        * When the transmitting end observes the receiving end in the sync
+        * state, it can clear the w_count and r_count and transition to the ack
+        * state. If the remote endpoint observes us in the ack state, it can
+        * return to the established state once it has cleared its counters.
+        */
+       ivc_state_ack
+};
+
+/*
+ * This structure is divided into two-cache aligned parts, the first is only
+ * written through the tx_channel pointer, while the second is only written
+ * through the rx_channel pointer. This delineates ownership of the cache lines,
+ * which is critical to performance and necessary in non-cache coherent
+ * implementations.
+ */
+struct tegra_ivc_channel_header {
+       union {
+               /* fields owned by the transmitting end */
+               struct {
+                       uint32_t w_count;
+                       uint32_t state;
+               };
+               uint8_t w_align[TEGRA_IVC_ALIGN];
+       };
+       union {
+               /* fields owned by the receiving end */
+               uint32_t r_count;
+               uint8_t r_align[TEGRA_IVC_ALIGN];
+       };
+};
+
+static inline void tegra_ivc_invalidate_counter(struct tegra_ivc *ivc,
+                                       struct tegra_ivc_channel_header *h,
+                                       ulong offset)
+{
+       ulong base = ((ulong)h) + offset;
+       invalidate_dcache_range(base, base + TEGRA_IVC_ALIGN);
+}
+
+static inline void tegra_ivc_flush_counter(struct tegra_ivc *ivc,
+                                          struct tegra_ivc_channel_header *h,
+                                          ulong offset)
+{
+       ulong base = ((ulong)h) + offset;
+       flush_dcache_range(base, base + TEGRA_IVC_ALIGN);
+}
+
+static inline ulong tegra_ivc_frame_addr(struct tegra_ivc *ivc,
+                                        struct tegra_ivc_channel_header *h,
+                                        uint32_t frame)
+{
+       BUG_ON(frame >= ivc->nframes);
+
+       return ((ulong)h) + sizeof(struct tegra_ivc_channel_header) +
+              (ivc->frame_size * frame);
+}
+
+static inline void *tegra_ivc_frame_pointer(struct tegra_ivc *ivc,
+                                           struct tegra_ivc_channel_header *ch,
+                                           uint32_t frame)
+{
+       return (void *)tegra_ivc_frame_addr(ivc, ch, frame);
+}
+
+static inline void tegra_ivc_invalidate_frame(struct tegra_ivc *ivc,
+                                       struct tegra_ivc_channel_header *h,
+                                       unsigned frame)
+{
+       ulong base = tegra_ivc_frame_addr(ivc, h, frame);
+       invalidate_dcache_range(base, base + ivc->frame_size);
+}
+
+static inline void tegra_ivc_flush_frame(struct tegra_ivc *ivc,
+                                        struct tegra_ivc_channel_header *h,
+                                        unsigned frame)
+{
+       ulong base = tegra_ivc_frame_addr(ivc, h, frame);
+       flush_dcache_range(base, base + ivc->frame_size);
+}
+
+static inline int tegra_ivc_channel_empty(struct tegra_ivc *ivc,
+                                         struct tegra_ivc_channel_header *ch)
+{
+       /*
+        * This function performs multiple checks on the same values with
+        * security implications, so create snapshots with ACCESS_ONCE() to
+        * ensure that these checks use the same values.
+        */
+       uint32_t w_count = ACCESS_ONCE(ch->w_count);
+       uint32_t r_count = ACCESS_ONCE(ch->r_count);
+
+       /*
+        * Perform an over-full check to prevent denial of service attacks where
+        * a server could be easily fooled into believing that there's an
+        * extremely large number of frames ready, since receivers are not
+        * expected to check for full or over-full conditions.
+        *
+        * Although the channel isn't empty, this is an invalid case caused by
+        * a potentially malicious peer, so returning empty is safer, because it
+        * gives the impression that the channel has gone silent.
+        */
+       if (w_count - r_count > ivc->nframes)
+               return 1;
+
+       return w_count == r_count;
+}
+
+static inline int tegra_ivc_channel_full(struct tegra_ivc *ivc,
+                                        struct tegra_ivc_channel_header *ch)
+{
+       /*
+        * Invalid cases where the counters indicate that the queue is over
+        * capacity also appear full.
+        */
+       return (ACCESS_ONCE(ch->w_count) - ACCESS_ONCE(ch->r_count)) >=
+              ivc->nframes;
+}
+
+static inline void tegra_ivc_advance_rx(struct tegra_ivc *ivc)
+{
+       ACCESS_ONCE(ivc->rx_channel->r_count) =
+                       ACCESS_ONCE(ivc->rx_channel->r_count) + 1;
+
+       if (ivc->r_pos == ivc->nframes - 1)
+               ivc->r_pos = 0;
+       else
+               ivc->r_pos++;
+}
+
+static inline void tegra_ivc_advance_tx(struct tegra_ivc *ivc)
+{
+       ACCESS_ONCE(ivc->tx_channel->w_count) =
+                       ACCESS_ONCE(ivc->tx_channel->w_count) + 1;
+
+       if (ivc->w_pos == ivc->nframes - 1)
+               ivc->w_pos = 0;
+       else
+               ivc->w_pos++;
+}
+
+static inline int tegra_ivc_check_read(struct tegra_ivc *ivc)
+{
+       ulong offset;
+
+       /*
+        * tx_channel->state is set locally, so it is not synchronized with
+        * state from the remote peer. The remote peer cannot reset its
+        * transmit counters until we've acknowledged its synchronization
+        * request, so no additional synchronization is required because an
+        * asynchronous transition of rx_channel->state to ivc_state_ack is not
+        * allowed.
+        */
+       if (ivc->tx_channel->state != ivc_state_established)
+               return -ECONNRESET;
+
+       /*
+        * Avoid unnecessary invalidations when performing repeated accesses to
+        * an IVC channel by checking the old queue pointers first.
+        * Synchronization is only necessary when these pointers indicate empty
+        * or full.
+        */
+       if (!tegra_ivc_channel_empty(ivc, ivc->rx_channel))
+               return 0;
+
+       offset = offsetof(struct tegra_ivc_channel_header, w_count);
+       tegra_ivc_invalidate_counter(ivc, ivc->rx_channel, offset);
+       return tegra_ivc_channel_empty(ivc, ivc->rx_channel) ? -ENOMEM : 0;
+}
+
+static inline int tegra_ivc_check_write(struct tegra_ivc *ivc)
+{
+       ulong offset;
+
+       if (ivc->tx_channel->state != ivc_state_established)
+               return -ECONNRESET;
+
+       if (!tegra_ivc_channel_full(ivc, ivc->tx_channel))
+               return 0;
+
+       offset = offsetof(struct tegra_ivc_channel_header, r_count);
+       tegra_ivc_invalidate_counter(ivc, ivc->tx_channel, offset);
+       return tegra_ivc_channel_full(ivc, ivc->tx_channel) ? -ENOMEM : 0;
+}
+
+static inline uint32_t tegra_ivc_channel_avail_count(struct tegra_ivc *ivc,
+       struct tegra_ivc_channel_header *ch)
+{
+       /*
+        * This function isn't expected to be used in scenarios where an
+        * over-full situation can lead to denial of service attacks. See the
+        * comment in tegra_ivc_channel_empty() for an explanation about
+        * special over-full considerations.
+        */
+       return ACCESS_ONCE(ch->w_count) - ACCESS_ONCE(ch->r_count);
+}
+
+int tegra_ivc_read_get_next_frame(struct tegra_ivc *ivc, void **frame)
+{
+       int result = tegra_ivc_check_read(ivc);
+       if (result < 0)
+               return result;
+
+       /*
+        * Order observation of w_pos potentially indicating new data before
+        * data read.
+        */
+       mb();
+
+       tegra_ivc_invalidate_frame(ivc, ivc->rx_channel, ivc->r_pos);
+       *frame = tegra_ivc_frame_pointer(ivc, ivc->rx_channel, ivc->r_pos);
+
+       return 0;
+}
+
+int tegra_ivc_read_advance(struct tegra_ivc *ivc)
+{
+       ulong offset;
+       int result;
+
+       /*
+        * No read barriers or synchronization here: the caller is expected to
+        * have already observed the channel non-empty. This check is just to
+        * catch programming errors.
+        */
+       result = tegra_ivc_check_read(ivc);
+       if (result)
+               return result;
+
+       tegra_ivc_advance_rx(ivc);
+       offset = offsetof(struct tegra_ivc_channel_header, r_count);
+       tegra_ivc_flush_counter(ivc, ivc->rx_channel, offset);
+
+       /*
+        * Ensure our write to r_pos occurs before our read from w_pos.
+        */
+       mb();
+
+       offset = offsetof(struct tegra_ivc_channel_header, w_count);
+       tegra_ivc_invalidate_counter(ivc, ivc->rx_channel, offset);
+
+       if (tegra_ivc_channel_avail_count(ivc, ivc->rx_channel) ==
+           ivc->nframes - 1)
+               ivc->notify(ivc);
+
+       return 0;
+}
+
+int tegra_ivc_write_get_next_frame(struct tegra_ivc *ivc, void **frame)
+{
+       int result = tegra_ivc_check_write(ivc);
+       if (result)
+               return result;
+
+       *frame = tegra_ivc_frame_pointer(ivc, ivc->tx_channel, ivc->w_pos);
+
+       return 0;
+}
+
+int tegra_ivc_write_advance(struct tegra_ivc *ivc)
+{
+       ulong offset;
+       int result;
+
+       result = tegra_ivc_check_write(ivc);
+       if (result)
+               return result;
+
+       tegra_ivc_flush_frame(ivc, ivc->tx_channel, ivc->w_pos);
+
+       /*
+        * Order any possible stores to the frame before update of w_pos.
+        */
+       mb();
+
+       tegra_ivc_advance_tx(ivc);
+       offset = offsetof(struct tegra_ivc_channel_header, w_count);
+       tegra_ivc_flush_counter(ivc, ivc->tx_channel, offset);
+
+       /*
+        * Ensure our write to w_pos occurs before our read from r_pos.
+        */
+       mb();
+
+       offset = offsetof(struct tegra_ivc_channel_header, r_count);
+       tegra_ivc_invalidate_counter(ivc, ivc->tx_channel, offset);
+
+       if (tegra_ivc_channel_avail_count(ivc, ivc->tx_channel) == 1)
+               ivc->notify(ivc);
+
+       return 0;
+}
+
+/*
+ * ===============================================================
+ *  IVC State Transition Table - see tegra_ivc_channel_notified()
+ * ===============================================================
+ *
+ *     local   remote  action
+ *     -----   ------  -----------------------------------
+ *     SYNC    EST     <none>
+ *     SYNC    ACK     reset counters; move to EST; notify
+ *     SYNC    SYNC    reset counters; move to ACK; notify
+ *     ACK     EST     move to EST; notify
+ *     ACK     ACK     move to EST; notify
+ *     ACK     SYNC    reset counters; move to ACK; notify
+ *     EST     EST     <none>
+ *     EST     ACK     <none>
+ *     EST     SYNC    reset counters; move to ACK; notify
+ *
+ * ===============================================================
+ */
+int tegra_ivc_channel_notified(struct tegra_ivc *ivc)
+{
+       ulong offset;
+       enum ivc_state peer_state;
+
+       /* Copy the receiver's state out of shared memory. */
+       offset = offsetof(struct tegra_ivc_channel_header, w_count);
+       tegra_ivc_invalidate_counter(ivc, ivc->rx_channel, offset);
+       peer_state = ACCESS_ONCE(ivc->rx_channel->state);
+
+       if (peer_state == ivc_state_sync) {
+               /*
+                * Order observation of ivc_state_sync before stores clearing
+                * tx_channel.
+                */
+               mb();
+
+               /*
+                * Reset tx_channel counters. The remote end is in the SYNC
+                * state and won't make progress until we change our state,
+                * so the counters are not in use at this time.
+                */
+               ivc->tx_channel->w_count = 0;
+               ivc->rx_channel->r_count = 0;
+
+               ivc->w_pos = 0;
+               ivc->r_pos = 0;
+
+               /*
+                * Ensure that counters appear cleared before new state can be
+                * observed.
+                */
+               mb();
+
+               /*
+                * Move to ACK state. We have just cleared our counters, so it
+                * is now safe for the remote end to start using these values.
+                */
+               ivc->tx_channel->state = ivc_state_ack;
+               offset = offsetof(struct tegra_ivc_channel_header, w_count);
+               tegra_ivc_flush_counter(ivc, ivc->tx_channel, offset);
+
+               /*
+                * Notify remote end to observe state transition.
+                */
+               ivc->notify(ivc);
+       } else if (ivc->tx_channel->state == ivc_state_sync &&
+                       peer_state == ivc_state_ack) {
+               /*
+                * Order observation of ivc_state_sync before stores clearing
+                * tx_channel.
+                */
+               mb();
+
+               /*
+                * Reset tx_channel counters. The remote end is in the ACK
+                * state and won't make progress until we change our state,
+                * so the counters are not in use at this time.
+                */
+               ivc->tx_channel->w_count = 0;
+               ivc->rx_channel->r_count = 0;
+
+               ivc->w_pos = 0;
+               ivc->r_pos = 0;
+
+               /*
+                * Ensure that counters appear cleared before new state can be
+                * observed.
+                */
+               mb();
+
+               /*
+                * Move to ESTABLISHED state. We know that the remote end has
+                * already cleared its counters, so it is safe to start
+                * writing/reading on this channel.
+                */
+               ivc->tx_channel->state = ivc_state_established;
+               offset = offsetof(struct tegra_ivc_channel_header, w_count);
+               tegra_ivc_flush_counter(ivc, ivc->tx_channel, offset);
+
+               /*
+                * Notify remote end to observe state transition.
+                */
+               ivc->notify(ivc);
+       } else if (ivc->tx_channel->state == ivc_state_ack) {
+               /*
+                * At this point, we have observed the peer to be in either
+                * the ACK or ESTABLISHED state. Next, order observation of
+                * peer state before storing to tx_channel.
+                */
+               mb();
+
+               /*
+                * Move to ESTABLISHED state. We know that we have previously
+                * cleared our counters, and we know that the remote end has
+                * cleared its counters, so it is safe to start writing/reading
+                * on this channel.
+                */
+               ivc->tx_channel->state = ivc_state_established;
+               offset = offsetof(struct tegra_ivc_channel_header, w_count);
+               tegra_ivc_flush_counter(ivc, ivc->tx_channel, offset);
+
+               /*
+                * Notify remote end to observe state transition.
+                */
+               ivc->notify(ivc);
+       } else {
+               /*
+                * There is no need to handle any further action. Either the
+                * channel is already fully established, or we are waiting for
+                * the remote end to catch up with our current state. Refer
+                * to the diagram in "IVC State Transition Table" above.
+                */
+       }
+
+       if (ivc->tx_channel->state != ivc_state_established)
+               return -EAGAIN;
+
+       return 0;
+}
+
+void tegra_ivc_channel_reset(struct tegra_ivc *ivc)
+{
+       ulong offset;
+
+       ivc->tx_channel->state = ivc_state_sync;
+       offset = offsetof(struct tegra_ivc_channel_header, w_count);
+       tegra_ivc_flush_counter(ivc, ivc->tx_channel, offset);
+       ivc->notify(ivc);
+}
+
+static int check_ivc_params(ulong qbase1, ulong qbase2, uint32_t nframes,
+                           uint32_t frame_size)
+{
+       int ret = 0;
+
+       BUG_ON(offsetof(struct tegra_ivc_channel_header, w_count) &
+              (TEGRA_IVC_ALIGN - 1));
+       BUG_ON(offsetof(struct tegra_ivc_channel_header, r_count) &
+              (TEGRA_IVC_ALIGN - 1));
+       BUG_ON(sizeof(struct tegra_ivc_channel_header) &
+              (TEGRA_IVC_ALIGN - 1));
+
+       if ((uint64_t)nframes * (uint64_t)frame_size >= 0x100000000) {
+               error("tegra_ivc: nframes * frame_size overflows\n");
+               return -EINVAL;
+       }
+
+       /*
+        * The headers must at least be aligned enough for counters
+        * to be accessed atomically.
+        */
+       if ((qbase1 & (TEGRA_IVC_ALIGN - 1)) ||
+           (qbase2 & (TEGRA_IVC_ALIGN - 1))) {
+               error("tegra_ivc: channel start not aligned\n");
+               return -EINVAL;
+       }
+
+       if (frame_size & (TEGRA_IVC_ALIGN - 1)) {
+               error("tegra_ivc: frame size not adequately aligned\n");
+               return -EINVAL;
+       }
+
+       if (qbase1 < qbase2) {
+               if (qbase1 + frame_size * nframes > qbase2)
+                       ret = -EINVAL;
+       } else {
+               if (qbase2 + frame_size * nframes > qbase1)
+                       ret = -EINVAL;
+       }
+
+       if (ret) {
+               error("tegra_ivc: queue regions overlap\n");
+               return ret;
+       }
+
+       return 0;
+}
+
+int tegra_ivc_init(struct tegra_ivc *ivc, ulong rx_base, ulong tx_base,
+                  uint32_t nframes, uint32_t frame_size,
+                  void (*notify)(struct tegra_ivc *))
+{
+       int ret;
+
+       if (!ivc)
+               return -EINVAL;
+
+       ret = check_ivc_params(rx_base, tx_base, nframes, frame_size);
+       if (ret)
+               return ret;
+
+       ivc->rx_channel = (struct tegra_ivc_channel_header *)rx_base;
+       ivc->tx_channel = (struct tegra_ivc_channel_header *)tx_base;
+       ivc->w_pos = 0;
+       ivc->r_pos = 0;
+       ivc->nframes = nframes;
+       ivc->frame_size = frame_size;
+       ivc->notify = notify;
+
+       return 0;
+}
index b836da1c0ed79b958c5544cfeff36a55b90314fe..645d08fa0bd84b7287e4137f8d2dd47a6bd99987 100644 (file)
@@ -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
index ce4610d8f809a999f5ade4d75a298b6b718de959..033d6005fb44f25252133e20c7ad32b9dc26bcf7 100644 (file)
@@ -2,7 +2,6 @@
 #
 # SPDX-License-Identifier: GPL-2.0
 
-obj-y += ../arm64-mmu.o
 obj-y += ../board186.o
-obj-y += ../lowlevel_init.o
-obj-$(CONFIG_DISPLAY_CPUINFO) += ../sys_info.o
+obj-y += nvtboot_ll.o
+obj-y += nvtboot_mem.o
diff --git a/arch/arm/mach-tegra/tegra186/nvtboot_ll.S b/arch/arm/mach-tegra/tegra186/nvtboot_ll.S
new file mode 100644 (file)
index 0000000..1eab890
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ * Save nvtboot-related boot-time CPU state
+ *
+ * (C) Copyright 2015-2016 NVIDIA Corporation <www.nvidia.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <config.h>
+#include <linux/linkage.h>
+
+.globl nvtboot_boot_x0
+nvtboot_boot_x0:
+       .dword 0
+
+ENTRY(save_boot_params)
+       adr     x8, nvtboot_boot_x0
+       str     x0, [x8]
+       b       save_boot_params_ret
+ENDPROC(save_boot_params)
diff --git a/arch/arm/mach-tegra/tegra186/nvtboot_mem.c b/arch/arm/mach-tegra/tegra186/nvtboot_mem.c
new file mode 100644 (file)
index 0000000..37dd8d4
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2016, NVIDIA CORPORATION.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <fdt_support.h>
+#include <fdtdec.h>
+#include <asm/arch/tegra.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+extern unsigned long nvtboot_boot_x0;
+
+/*
+ * A parsed version of /memory/reg from the DTB that is passed to U-Boot in x0.
+ *
+ * We only support up to two banks since that's all the binary  bootloader
+ * ever sets. We assume bank 0 is RAM below 4G and bank 1 is RAM  above 4G.
+ * This is all a fairly safe assumption, since the L4T kernel makes  the same
+ * assumptions, so the bootloader is unlikely to change.
+ *
+ * This is written to before relocation, and hence cannot be in .bss, since
+ * .bss overlaps the DTB that's appended to the U-Boot binary. The initializer
+ * forces this into .data and avoids this issue. This also has the nice side-
+ * effect of the content being valid after relocation.
+ */
+static struct {
+       u64 start;
+       u64 size;
+} ram_banks[2] = {{1}};
+
+int dram_init(void)
+{
+       unsigned int na, ns;
+       const void *nvtboot_blob = (void *)nvtboot_boot_x0;
+       int node, len, i;
+       const u32 *prop;
+
+       memset(ram_banks, 0, sizeof(ram_banks));
+
+       na = fdtdec_get_uint(nvtboot_blob, 0, "#address-cells", 2);
+       ns = fdtdec_get_uint(nvtboot_blob, 0, "#size-cells", 2);
+
+       node = fdt_path_offset(nvtboot_blob, "/memory");
+       if (node < 0) {
+               error("Can't find /memory node in nvtboot DTB");
+               hang();
+       }
+       prop = fdt_getprop(nvtboot_blob, node, "reg", &len);
+       if (!prop) {
+               error("Can't find /memory/reg property in nvtboot DTB");
+               hang();
+       }
+
+       len /= (na + ns);
+       if (len > ARRAY_SIZE(ram_banks))
+               len = ARRAY_SIZE(ram_banks);
+
+       gd->ram_size = 0;
+       for (i = 0; i < len; i++) {
+               ram_banks[i].start = of_read_number(prop, na);
+               prop += na;
+               ram_banks[i].size = of_read_number(prop, ns);
+               prop += ns;
+               gd->ram_size += ram_banks[i].size;
+       }
+
+       return 0;
+}
+
+extern unsigned long nvtboot_boot_x0;
+
+void dram_init_banksize(void)
+{
+       int i;
+
+       for (i = 0; i < 2; i++) {
+               gd->bd->bi_dram[i].start = ram_banks[i].start;
+               gd->bd->bi_dram[i].size = ram_banks[i].size;
+       }
+}
+
+ulong board_get_usable_ram_top(ulong total_size)
+{
+       return ram_banks[0].start + ram_banks[0].size;
+}
index e256eeb6686805131a1a5cb5aaf992df1cf6de1e..e39ced674f1de0ce25d32fa339b0997724ecde7a 100644 (file)
@@ -12,6 +12,7 @@ config ARCH_UNIPHIER_64BIT
        select ARM64
        select SPL_SEPARATE_BSS
        select ARMV8_MULTIENTRY
+       select ARMV8_SPIN_TABLE
 
 choice
         prompt "UniPhier SoC select"
index 376c06b59758f554aac38f21e41e2749c5f0c8cf..5074ebda97aaf6b6a983d8b0716a69874e5b4848 100644 (file)
@@ -7,7 +7,7 @@ obj-y += lowlevel_init.o
 obj-$(CONFIG_DEBUG_LL) += debug_ll.o
 else
 obj-y += late_lowlevel_init.o
-obj-y += cache_uniphier.o
+obj-y += cache-uniphier.o
 endif
 
 obj-y += timer.o
diff --git a/arch/arm/mach-uniphier/arm32/cache-uniphier.c b/arch/arm/mach-uniphier/arm32/cache-uniphier.c
new file mode 100644 (file)
index 0000000..76fe5eb
--- /dev/null
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2012-2014 Panasonic Corporation
+ * Copyright (C) 2015-2016 Socionext Inc.
+ *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <linux/io.h>
+#include <asm/armv7.h>
+
+#include "ssc-regs.h"
+
+#ifdef CONFIG_UNIPHIER_L2CACHE_ON
+static void uniphier_cache_sync(void)
+{
+       /* drain internal buffers */
+       writel(UNIPHIER_SSCOPE_CM_SYNC, UNIPHIER_SSCOPE);
+       /* need a read back to confirm */
+       readl(UNIPHIER_SSCOPE);
+}
+
+static void uniphier_cache_maint_all(u32 operation)
+{
+       /* clear the complete notification flag */
+       writel(UNIPHIER_SSCOLPQS_EF, UNIPHIER_SSCOLPQS);
+
+       /* try until the command is successfully set */
+       do {
+               writel(UNIPHIER_SSCOQM_S_ALL | UNIPHIER_SSCOQM_CE | operation,
+                      UNIPHIER_SSCOQM);
+       } while (readl(UNIPHIER_SSCOPPQSEF) &
+                (UNIPHIER_SSCOPPQSEF_FE | UNIPHIER_SSCOPPQSEF_OE));
+
+       /* wait until the operation is completed */
+       while (readl(UNIPHIER_SSCOLPQS) != UNIPHIER_SSCOLPQS_EF)
+               ;
+
+       uniphier_cache_sync();
+}
+
+void v7_outer_cache_flush_all(void)
+{
+       uniphier_cache_maint_all(UNIPHIER_SSCOQM_CM_FLUSH);
+}
+
+void v7_outer_cache_inval_all(void)
+{
+       uniphier_cache_maint_all(UNIPHIER_SSCOQM_CM_INV);
+}
+
+static void __uniphier_cache_maint_range(u32 start, u32 size, u32 operation)
+{
+       /* clear the complete notification flag */
+       writel(UNIPHIER_SSCOLPQS_EF, UNIPHIER_SSCOLPQS);
+
+       /* try until the command is successfully set */
+       do {
+               writel(UNIPHIER_SSCOQM_S_RANGE | UNIPHIER_SSCOQM_CE | operation,
+                      UNIPHIER_SSCOQM);
+               writel(start, UNIPHIER_SSCOQAD);
+               writel(size, UNIPHIER_SSCOQSZ);
+
+       } while (readl(UNIPHIER_SSCOPPQSEF) &
+                (UNIPHIER_SSCOPPQSEF_FE | UNIPHIER_SSCOPPQSEF_OE));
+
+       /* wait until the operation is completed */
+       while (readl(UNIPHIER_SSCOLPQS) != UNIPHIER_SSCOLPQS_EF)
+               ;
+}
+
+static void uniphier_cache_maint_range(u32 start, u32 end, u32 operation)
+{
+       u32 size;
+
+       /*
+        * If start address is not aligned to cache-line,
+        * do cache operation for the first cache-line
+        */
+       start = start & ~(UNIPHIER_SSC_LINE_SIZE - 1);
+
+       size = end - start;
+
+       if (unlikely(size >= (u32)(-UNIPHIER_SSC_LINE_SIZE))) {
+               /* this means cache operation for all range */
+               uniphier_cache_maint_all(operation);
+               return;
+       }
+
+       /*
+        * If end address is not aligned to cache-line,
+        * do cache operation for the last cache-line
+        */
+       size = ALIGN(size, UNIPHIER_SSC_LINE_SIZE);
+
+       while (size) {
+               u32 chunk_size = size > UNIPHIER_SSC_RANGE_OP_MAX_SIZE ?
+                                       UNIPHIER_SSC_RANGE_OP_MAX_SIZE : size;
+               __uniphier_cache_maint_range(start, chunk_size, operation);
+
+               start += chunk_size;
+               size -= chunk_size;
+       }
+
+       uniphier_cache_sync();
+}
+
+void v7_outer_cache_flush_range(u32 start, u32 end)
+{
+       uniphier_cache_maint_range(start, end, UNIPHIER_SSCOQM_CM_FLUSH);
+}
+
+void v7_outer_cache_inval_range(u32 start, u32 end)
+{
+       if (start & (UNIPHIER_SSC_LINE_SIZE - 1)) {
+               start &= ~(UNIPHIER_SSC_LINE_SIZE - 1);
+               __uniphier_cache_maint_range(start, UNIPHIER_SSC_LINE_SIZE,
+                                            UNIPHIER_SSCOQM_CM_FLUSH);
+               start += UNIPHIER_SSC_LINE_SIZE;
+       }
+
+       if (start >= end) {
+               uniphier_cache_sync();
+               return;
+       }
+
+       if (end & (UNIPHIER_SSC_LINE_SIZE - 1)) {
+               end &= ~(UNIPHIER_SSC_LINE_SIZE - 1);
+               __uniphier_cache_maint_range(end, UNIPHIER_SSC_LINE_SIZE,
+                                            UNIPHIER_SSCOQM_CM_FLUSH);
+       }
+
+       if (start >= end) {
+               uniphier_cache_sync();
+               return;
+       }
+
+       uniphier_cache_maint_range(start, end, UNIPHIER_SSCOQM_CM_INV);
+}
+
+void v7_outer_cache_enable(void)
+{
+       u32 tmp;
+
+       writel(U32_MAX, UNIPHIER_SSCLPDAWCR);   /* activate all ways */
+       tmp = readl(UNIPHIER_SSCC);
+       tmp |= UNIPHIER_SSCC_ON;
+       writel(tmp, UNIPHIER_SSCC);
+}
+#endif
+
+void v7_outer_cache_disable(void)
+{
+       u32 tmp;
+
+       tmp = readl(UNIPHIER_SSCC);
+       tmp &= ~UNIPHIER_SSCC_ON;
+       writel(tmp, UNIPHIER_SSCC);
+}
+
+void enable_caches(void)
+{
+       dcache_enable();
+}
diff --git a/arch/arm/mach-uniphier/arm32/cache_uniphier.c b/arch/arm/mach-uniphier/arm32/cache_uniphier.c
deleted file mode 100644 (file)
index 4398114..0000000
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * Copyright (C) 2012-2015 Masahiro Yamada <yamada.masahiro@socionext.com>
- *
- * SPDX-License-Identifier:    GPL-2.0+
- */
-
-#include <common.h>
-#include <linux/io.h>
-#include <asm/armv7.h>
-
-#include "ssc-regs.h"
-
-#ifdef CONFIG_UNIPHIER_L2CACHE_ON
-static void uniphier_cache_sync(void)
-{
-       writel(SSCOPE_CM_SYNC, SSCOPE); /* drain internal buffers */
-       readl(SSCOPE); /* need a read back to confirm */
-}
-
-static void uniphier_cache_maint_all(u32 operation)
-{
-       /* try until the command is successfully set */
-       do {
-               writel(SSCOQM_S_ALL | SSCOQM_CE | operation, SSCOQM);
-       } while (readl(SSCOPPQSEF) & (SSCOPPQSEF_FE | SSCOPPQSEF_OE));
-
-       /* wait until the operation is completed */
-       while (readl(SSCOLPQS) != SSCOLPQS_EF)
-               ;
-
-       /* clear the complete notification flag */
-       writel(SSCOLPQS_EF, SSCOLPQS);
-
-       uniphier_cache_sync();
-}
-
-void v7_outer_cache_flush_all(void)
-{
-       uniphier_cache_maint_all(SSCOQM_CM_WB_INV);
-}
-
-void v7_outer_cache_inval_all(void)
-{
-       uniphier_cache_maint_all(SSCOQM_CM_INV);
-}
-
-static void __uniphier_cache_maint_range(u32 start, u32 size, u32 operation)
-{
-       /* try until the command is successfully set */
-       do {
-               writel(SSCOQM_S_ADDRESS | SSCOQM_CE | operation, SSCOQM);
-               writel(start, SSCOQAD);
-               writel(size, SSCOQSZ);
-
-       } while (readl(SSCOPPQSEF) & (SSCOPPQSEF_FE | SSCOPPQSEF_OE));
-
-       /* wait until the operation is completed */
-       while (readl(SSCOLPQS) != SSCOLPQS_EF)
-               ;
-
-       /* clear the complete notification flag */
-       writel(SSCOLPQS_EF, SSCOLPQS);
-}
-
-static void uniphier_cache_maint_range(u32 start, u32 end, u32 operation)
-{
-       u32 size;
-
-       /*
-        * If start address is not aligned to cache-line,
-        * do cache operation for the first cache-line
-        */
-       start = start & ~(SSC_LINE_SIZE - 1);
-
-       size = end - start;
-
-       if (unlikely(size >= (u32)(-SSC_LINE_SIZE))) {
-               /* this means cache operation for all range */
-               uniphier_cache_maint_all(operation);
-               return;
-       }
-
-       /*
-        * If end address is not aligned to cache-line,
-        * do cache operation for the last cache-line
-        */
-       size = ALIGN(size, SSC_LINE_SIZE);
-
-       while (size) {
-               u32 chunk_size = size > SSC_RANGE_OP_MAX_SIZE ?
-                                               SSC_RANGE_OP_MAX_SIZE : size;
-               __uniphier_cache_maint_range(start, chunk_size, operation);
-
-               start += chunk_size;
-               size -= chunk_size;
-       }
-
-       uniphier_cache_sync();
-}
-
-void v7_outer_cache_flush_range(u32 start, u32 end)
-{
-       uniphier_cache_maint_range(start, end, SSCOQM_CM_WB_INV);
-}
-
-void v7_outer_cache_inval_range(u32 start, u32 end)
-{
-       if (start & (SSC_LINE_SIZE - 1)) {
-               start &= ~(SSC_LINE_SIZE - 1);
-               __uniphier_cache_maint_range(start, SSC_LINE_SIZE,
-                                            SSCOQM_CM_WB_INV);
-               start += SSC_LINE_SIZE;
-       }
-
-       if (start >= end) {
-               uniphier_cache_sync();
-               return;
-       }
-
-       if (end & (SSC_LINE_SIZE - 1)) {
-               end &= ~(SSC_LINE_SIZE - 1);
-               __uniphier_cache_maint_range(end, SSC_LINE_SIZE,
-                                            SSCOQM_CM_WB_INV);
-       }
-
-       if (start >= end) {
-               uniphier_cache_sync();
-               return;
-       }
-
-       uniphier_cache_maint_range(start, end, SSCOQM_CM_INV);
-}
-
-void v7_outer_cache_enable(void)
-{
-       u32 tmp;
-
-       writel(U32_MAX, SSCLPDAWCR);    /* activate all ways */
-       tmp = readl(SSCC);
-       tmp |= SSCC_ON;
-       writel(tmp, SSCC);
-}
-#endif
-
-void v7_outer_cache_disable(void)
-{
-       u32 tmp;
-       tmp = readl(SSCC);
-       tmp &= ~SSCC_ON;
-       writel(tmp, SSCC);
-}
-
-void enable_caches(void)
-{
-       dcache_enable();
-}
index cce91dfac7bd16b8fb87c86dc2946356d245cbf3..001d732e39726b8fad81730b05a4f60f32c04895 100644 (file)
@@ -10,9 +10,9 @@
 #include "ssc-regs.h"
 
 ENTRY(lowlevel_init)
-       ldr     r1, = SSCC
+       ldr     r1, = UNIPHIER_SSCC
        ldr     r0, [r1]
-       bic     r0, r0, #SSCC_ON        @ L2 disable
+       bic     r0, r0, #UNIPHIER_SSCC_ON       @ L2 disable
        str     r0, [r1]
        mov     pc, lr
 ENDPROC(lowlevel_init)
index cc34116baaeb2a5c984c309b2cff634bdca1d463..8e32b357235ce2ec215aec7e0ea623b5d02f6c88 100644 (file)
@@ -1,5 +1,7 @@
 /*
- * Copyright (C) 2012-2015 Masahiro Yamada <yamada.masahiro@socionext.com>
+ * Copyright (C) 2012-2015 Panasonic Corporation
+ * Copyright (C) 2015-2016 Socionext Inc.
+ *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
  *
  * SPDX-License-Identifier:    GPL-2.0+
  */
@@ -94,26 +96,26 @@ ENTRY(setup_init_ram)
         */
 0:
        /*
-        * set SSCOQM, SSCOQAD, SSCOQSZ, SSCOQWN in this order
+        * set UNIPHIER_SSCOQM, UNIPHIER_SSCOQAD, UNIPHIER_SSCOQSZ, UNIPHIER_SSCOQWN in this order
         */
        ldr     r0, = 0x00408006        @ touch to zero with address range
-       ldr     r1, = SSCOQM
+       ldr     r1, = UNIPHIER_SSCOQM
        str     r0, [r1]
        ldr     r0, = BOOT_RAM_BASE
-       ldr     r1, = SSCOQAD
+       ldr     r1, = UNIPHIER_SSCOQAD
        str     r0, [r1]
        ldr     r0, = BOOT_RAM_SIZE
-       ldr     r1, = SSCOQSZ
+       ldr     r1, = UNIPHIER_SSCOQSZ
        str     r0, [r1]
        ldr     r0, = BOOT_WAY_BITS
-       ldr     r1, = SSCOQWN
+       ldr     r1, = UNIPHIER_SSCOQWN
        str     r0, [r1]
-       ldr     r1, = SSCOPPQSEF
+       ldr     r1, = UNIPHIER_SSCOPPQSEF
        ldr     r0, [r1]
        cmp     r0, #0                  @ check if the command is successfully set
        bne     0b                      @ try again if an error occurs
 
-       ldr     r1, = SSCOLPQS
+       ldr     r1, = UNIPHIER_SSCOLPQS
 1:
        ldr     r0, [r1]
        cmp     r0, #0x4
index 02fca3b6f61e79c5ab9324778c9240d0ed282911..8f423e92da6f2ef8f0dce8ece44356702ae2210d 100644 (file)
@@ -2,6 +2,7 @@
  * UniPhier System Cache (L2 Cache) registers
  *
  * Copyright (C) 2011-2014 Panasonic Corporation
+ * Copyright (C) 2016      Socionext Inc.
  *
  * SPDX-License-Identifier:    GPL-2.0+
  */
 #ifndef ARCH_SSC_REGS_H
 #define ARCH_SSC_REGS_H
 
-#define SSCC                   0x500c0000
-#define SSCC_BST               (0x1 << 20)
-#define SSCC_ACT               (0x1 << 19)
-#define SSCC_WTG               (0x1 << 18)
-#define SSCC_PRD               (0x1 << 17)
-#define SSCC_WBWA              (0x1 << 16)
-#define SSCC_EX                        (0x1 << 13)
-#define SSCC_ON                        (0x1 <<  0)
+/* control registers */
+#define UNIPHIER_SSCC          0x500c0000      /* Control Register */
+#define    UNIPHIER_SSCC_BST                   (0x1 << 20)     /* UCWG burst read */
+#define    UNIPHIER_SSCC_ACT                   (0x1 << 19)     /* Inst-Data separate */
+#define    UNIPHIER_SSCC_WTG                   (0x1 << 18)     /* WT gathering on */
+#define    UNIPHIER_SSCC_PRD                   (0x1 << 17)     /* enable pre-fetch */
+#define    UNIPHIER_SSCC_ON                    (0x1 <<  0)     /* enable cache */
+#define UNIPHIER_SSCLPDAWCR    0x500c0030      /* Unified/Data Active Way Control */
+#define UNIPHIER_SSCLPIAWCR    0x500c0034      /* Instruction Active Way Control */
 
-#define SSCLPDAWCR             0x500c0030
+/* revision registers */
+#define UNIPHIER_SSCID         0x503c0100      /* ID Register */
 
-#define SSCOPE                 0x506c0244
-#define SSCOPE_CM_SYNC         0x00000008
+/* operation registers */
+#define UNIPHIER_SSCOPE                0x506c0244      /* Cache Operation Primitive Entry */
+#define    UNIPHIER_SSCOPE_CM_INV              0x0     /* invalidate */
+#define    UNIPHIER_SSCOPE_CM_CLEAN            0x1     /* clean */
+#define    UNIPHIER_SSCOPE_CM_FLUSH            0x2     /* flush */
+#define    UNIPHIER_SSCOPE_CM_SYNC             0x8     /* sync (drain bufs) */
+#define    UNIPHIER_SSCOPE_CM_FLUSH_PREFETCH   0x9     /* flush p-fetch buf */
+#define UNIPHIER_SSCOQM                0x506c0248
+#define    UNIPHIER_SSCOQM_TID_MASK            (0x3 << 21)
+#define    UNIPHIER_SSCOQM_TID_LRU_DATA                (0x0 << 21)
+#define    UNIPHIER_SSCOQM_TID_LRU_INST                (0x1 << 21)
+#define    UNIPHIER_SSCOQM_TID_WAY             (0x2 << 21)
+#define    UNIPHIER_SSCOQM_S_MASK              (0x3 << 17)
+#define    UNIPHIER_SSCOQM_S_RANGE             (0x0 << 17)
+#define    UNIPHIER_SSCOQM_S_ALL               (0x1 << 17)
+#define    UNIPHIER_SSCOQM_S_WAY               (0x2 << 17)
+#define    UNIPHIER_SSCOQM_CE                  (0x1 << 15)     /* notify completion */
+#define    UNIPHIER_SSCOQM_CW                  (0x1 << 14)
+#define    UNIPHIER_SSCOQM_CM_MASK             (0x7)
+#define    UNIPHIER_SSCOQM_CM_INV              0x0     /* invalidate */
+#define    UNIPHIER_SSCOQM_CM_CLEAN            0x1     /* clean */
+#define    UNIPHIER_SSCOQM_CM_FLUSH            0x2     /* flush */
+#define    UNIPHIER_SSCOQM_CM_PREFETCH         0x3     /* prefetch to cache */
+#define    UNIPHIER_SSCOQM_CM_PREFETCH_BUF     0x4     /* prefetch to pf-buf */
+#define    UNIPHIER_SSCOQM_CM_TOUCH            0x5     /* touch */
+#define    UNIPHIER_SSCOQM_CM_TOUCH_ZERO       0x6     /* touch to zero */
+#define    UNIPHIER_SSCOQM_CM_TOUCH_DIRTY      0x7     /* touch with dirty */
+#define UNIPHIER_SSCOQAD       0x506c024c      /* Cache Operation Queue Address */
+#define UNIPHIER_SSCOQSZ       0x506c0250      /* Cache Operation Queue Size */
+#define UNIPHIER_SSCOQMASK     0x506c0254      /* Cache Operation Queue Address Mask */
+#define UNIPHIER_SSCOQWN       0x506c0258      /* Cache Operation Queue Way Number */
+#define UNIPHIER_SSCOPPQSEF    0x506c025c      /* Cache Operation Queue Set Complete */
+#define    UNIPHIER_SSCOPPQSEF_FE              (0x1 << 1)
+#define    UNIPHIER_SSCOPPQSEF_OE              (0x1 << 0)
+#define UNIPHIER_SSCOLPQS      0x506c0260      /* Cache Operation Queue Status */
+#define    UNIPHIER_SSCOLPQS_EF                        (0x1 << 2)
+#define    UNIPHIER_SSCOLPQS_EST               (0x1 << 1)
+#define    UNIPHIER_SSCOLPQS_QST               (0x1 << 0)
 
-#define SSCOQM                 0x506c0248
-#define SSCOQM_TID_MASK                (0x3 << 21)
-#define SSCOQM_TID_BY_WAY      (0x2 << 21)
-#define SSCOQM_TID_BY_INST_WAY (0x1 << 21)
-#define SSCOQM_TID_BY_DATA_WAY (0x0 << 21)
-#define SSCOQM_S_MASK          (0x3 << 17)
-#define SSCOQM_S_WAY           (0x2 << 17)
-#define SSCOQM_S_ALL           (0x1 << 17)
-#define SSCOQM_S_ADDRESS       (0x0 << 17)
-#define SSCOQM_CE              (0x1 << 15)
-#define SSCOQM_CW              (0x1 << 14)
-#define SSCOQM_CM_MASK         (0x7)
-#define SSCOQM_CM_DIRT_TOUCH   (0x7)
-#define SSCOQM_CM_ZERO_TOUCH   (0x6)
-#define SSCOQM_CM_NORM_TOUCH   (0x5)
-#define SSCOQM_CM_PREF_FETCH   (0x4)
-#define SSCOQM_CM_SSC_FETCH    (0x3)
-#define SSCOQM_CM_WB_INV       (0x2)
-#define SSCOQM_CM_WB           (0x1)
-#define SSCOQM_CM_INV          (0x0)
-
-#define SSCOQAD                        0x506c024c
-#define SSCOQSZ                        0x506c0250
-#define SSCOQWN                        0x506c0258
-
-#define SSCOPPQSEF             0x506c025c
-#define SSCOPPQSEF_FE          (0x1 << 1)
-#define SSCOPPQSEF_OE          (0x1 << 0)
-
-#define SSCOLPQS               0x506c0260
-#define SSCOLPQS_EF            (0x1 << 2)
-#define SSCOLPQS_EST           (0x1 << 1)
-#define SSCOLPQS_QST           (0x1 << 0)
-
-#define SSCOQCE0               0x506c0270
-
-#define SSC_LINE_SIZE          128
-#define SSC_RANGE_OP_MAX_SIZE  (0x00400000 - (SSC_LINE_SIZE))
+#define UNIPHIER_SSC_LINE_SIZE         128
+#define UNIPHIER_SSC_RANGE_OP_MAX_SIZE (0x00400000 - (UNIPHIER_SSC_LINE_SIZE))
 
 #endif  /* ARCH_SSC_REGS_H */
index 607f96a58de04cdc06b1f95c7046cf78186cff2a..f18595dc1311cb80118a6fa0587f536c4db331ab 100644 (file)
@@ -1,13 +1,12 @@
 /*
  * Initialization of ARM Corelink CCI-500 Cache Coherency Interconnect
  *
- * Copyright (C) 2016 Masahiro Yamada <yamada.masahiro@socionext.com>
+ * Copyright (C) 2016 Socionext Inc.
+ *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
  *
  * SPDX-License-Identifier:    GPL-2.0+
  */
 
-#include <common.h>
-#include <mapmem.h>
 #include <linux/bitops.h>
 #include <linux/io.h>
 #include <linux/sizes.h>
@@ -28,13 +27,13 @@ void cci500_init(unsigned int nr_slaves)
                void __iomem *base;
                u32 tmp;
 
-               base = map_sysmem(slave_base, SZ_4K);
+               base = ioremap(slave_base, SZ_4K);
 
                tmp = readl(base);
                tmp |= CCI500_SNOOP_CTRL_EN_DVM | CCI500_SNOOP_CTRL_EN_SNOOP;
                writel(tmp, base);
 
-               unmap_sysmem(base);
+               iounmap(base);
 
                slave_base += CCI500_SLAVE_OFFSET;
        }
index 74ef91984ca86eb3b4885ce142853382c89b794e..67bc4f1209b6670b20f34a3f85e2e264aae92d42 100644 (file)
 
 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
index 5971ad256b8b055db4bead72cb088c97dce8dcba..4f08963118a346449e7addef5f438adebc12db8a 100644 (file)
@@ -1,11 +1,10 @@
 /*
- * Copyright (C) 2016 Masahiro Yamada <yamada.masahiro@socionext.com>
+ * Copyright (C) 2016 Socionext Inc.
+ *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
  *
  * SPDX-License-Identifier:    GPL-2.0+
  */
 
-#include <common.h>
-#include <mapmem.h>
 #include <linux/io.h>
 #include <linux/sizes.h>
 
@@ -18,11 +17,11 @@ void uniphier_smp_kick_all_cpus(void)
 {
        void __iomem *rom_boot_rsv0;
 
-       rom_boot_rsv0 = map_sysmem(UNIPHIER_SMPCTRL_ROM_RSV0, SZ_8);
+       rom_boot_rsv0 = ioremap(UNIPHIER_SMPCTRL_ROM_RSV0, SZ_8);
 
        writeq((u64)uniphier_secondary_startup, rom_boot_rsv0);
 
-       unmap_sysmem(rom_boot_rsv0);
+       iounmap(rom_boot_rsv0);
 
        uniphier_smp_setup();
 
index 4beab9dca87ca423439dd0466602f9af317e6419..c10903ae58fdee2849c406e11e156e69a27ae914 100644 (file)
@@ -1,11 +1,10 @@
 /*
- * Copyright (C) 2016 Masahiro Yamada <yamada.masahiro@socionext.com>
+ * Copyright (C) 2016 Socionext Inc.
+ *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
  *
  * SPDX-License-Identifier:    GPL-2.0+
  */
 
-#include <common.h>
-#include <mapmem.h>
 #include <linux/bitops.h>
 #include <linux/io.h>
 #include <linux/sizes.h>
@@ -21,7 +20,7 @@ int timer_init(void)
        void __iomem *base;
        u32 tmp;
 
-       base = map_sysmem(CNT_CONTROL_BASE, SZ_4K);
+       base = ioremap(CNT_CONTROL_BASE, SZ_4K);
 
        /*
         * Note:
@@ -32,7 +31,7 @@ int timer_init(void)
        tmp |= CNTCR_EN;
        writel(tmp, base + CNTCR);
 
-       unmap_sysmem(base);
+       iounmap(base);
 
        return 0;
 }
index ed308f3ecba0d4c2efc839ea02f46de7a29ac859..20093d8178a6cab432ee5a05ca45db1e0b0ec207 100644 (file)
@@ -1,5 +1,6 @@
 /*
- * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com>
+ * Copyright (C) 2015-2016 Socionext Inc.
+ *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
  *
  * SPDX-License-Identifier:    GPL-2.0+
  */
@@ -38,7 +39,6 @@ static const struct uniphier_board_data uniphier_sld3_data = {
 static const struct uniphier_board_data uniphier_ld4_data = {
        .dram_freq = 1600,
        .dram_nr_ch = 2,
-       .dram_ddr3plus = true,
        .dram_ch[0] = {
                .base = 0x80000000,
                .size = 0x10000000,
@@ -49,6 +49,7 @@ static const struct uniphier_board_data uniphier_ld4_data = {
                .size = 0x10000000,
                .width = 16,
        },
+       .flags = UNIPHIER_BD_DDR3PLUS,
 };
 #endif
 
@@ -90,7 +91,6 @@ static const struct uniphier_board_data uniphier_pro4_2g_data = {
 static const struct uniphier_board_data uniphier_sld8_data = {
        .dram_freq = 1333,
        .dram_nr_ch = 2,
-       .dram_ddr3plus = true,
        .dram_ch[0] = {
                .base = 0x80000000,
                .size = 0x10000000,
@@ -101,6 +101,7 @@ static const struct uniphier_board_data uniphier_sld8_data = {
                .size = 0x10000000,
                .width = 16,
        },
+       .flags = UNIPHIER_BD_DDR3PLUS,
 };
 #endif
 
@@ -202,6 +203,22 @@ static const struct uniphier_board_data uniphier_ld20_data = {
                .width = 32,
        },
 };
+
+static const struct uniphier_board_data uniphier_ld21_data = {
+       .dram_freq = 1866,
+       .dram_nr_ch = 2,
+       .dram_ch[0] = {
+               .base = 0x80000000,
+               .size = 0x40000000,
+               .width = 32,
+       },
+       .dram_ch[1] = {
+               .base = 0xc0000000,
+               .size = 0x40000000,
+               .width = 32,
+       },
+       .flags = UNIPHIER_BD_PACKAGE_LD21,
+};
 #endif
 
 struct uniphier_board_id {
@@ -237,6 +254,7 @@ static const struct uniphier_board_id uniphier_boards[] = {
        { "socionext,ph1-ld11", &uniphier_ld11_data, },
 #endif
 #if defined(CONFIG_ARCH_UNIPHIER_LD20)
+       { "socionext,ph1-ld21", &uniphier_ld21_data, },
        { "socionext,ph1-ld20", &uniphier_ld20_data, },
 #endif
 };
index 76bf856c9e998f0a8aa076ac14cae1dc45553651..0d9240519c2525ac5293b29d94293b1ecd3e0d77 100644 (file)
@@ -4,6 +4,7 @@
  * SPDX-License-Identifier:    GPL-2.0+
  */
 
+#include <linux/bitops.h>
 #include <linux/io.h>
 
 #include "../init.h"
@@ -32,12 +33,16 @@ void uniphier_pxs2_clk_init(void)
        tmp |= SC_RSTCTRL2_NRST_USB3B1;
        writel(tmp, SC_RSTCTRL2);
        readl(SC_RSTCTRL2); /* dummy read */
+
+       tmp = readl(SC_RSTCTRL6);
+       tmp |= 0x37;
+       writel(tmp, SC_RSTCTRL6);
 #endif
 
        /* provide clocks */
        tmp = readl(SC_CLKCTRL);
 #ifdef CONFIG_USB_XHCI_UNIPHIER
-       tmp |= SC_CLKCTRL_CEN_USB31 | SC_CLKCTRL_CEN_USB30 |
+       tmp |= BIT(20) | BIT(19) | SC_CLKCTRL_CEN_USB31 | SC_CLKCTRL_CEN_USB30 |
                SC_CLKCTRL_CEN_GIO;
 #endif
 #ifdef CONFIG_UNIPHIER_ETH
index 7a9f76caeb7e7e3e78ef2896d0024d363729437d..0a5a73d8eea2ec6268adcbde76b6f50637300615 100644 (file)
@@ -1,11 +1,12 @@
 /*
- * Copyright (C) 2014-2015 Masahiro Yamada <yamada.masahiro@socionext.com>
+ * Copyright (C) 2014      Panasonic Corporation
+ * Copyright (C) 2015-2016 Socionext Inc.
+ *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
  *
  * SPDX-License-Identifier:    GPL-2.0+
  */
 
 #include <common.h>
-#include <mapmem.h>
 #include <linux/io.h>
 #include <linux/sizes.h>
 
@@ -51,7 +52,7 @@ static void dump_loop(unsigned long *base,
        int p, dx;
 
        for (p = 0; *base; base++, p++) {
-               phy = map_sysmem(*base, SZ_4K);
+               phy = ioremap(*base, SZ_4K);
 
                for (dx = 0; dx < NR_DATX8_PER_DDRPHY; dx++) {
                        printf("PHY%dDX%d:", p, dx);
@@ -59,7 +60,7 @@ static void dump_loop(unsigned long *base,
                        printf("\n");
                }
 
-               unmap_sysmem(phy);
+               iounmap(phy);
        }
 }
 
@@ -172,7 +173,7 @@ static void reg_dump(unsigned long *base)
        printf("\n--- DDR PHY registers ---\n");
 
        for (p = 0; *base; base++, p++) {
-               phy = map_sysmem(*base, SZ_4K);
+               phy = ioremap(*base, SZ_4K);
 
                printf("== PHY%d (base: %p) ==\n", p, phy);
                printf(" No: Name      : Address  : Data\n");
@@ -206,7 +207,7 @@ static void reg_dump(unsigned long *base)
                REG_DUMP(dx[1].gcr);
                REG_DUMP(dx[1].gtr);
 
-               unmap_sysmem(phy);
+               iounmap(phy);
        }
 }
 
index fc75864a105caa1cc0af128435656c15cb35df88..1ea6193f88ffabedc51b501583c936b81f097b43 100644 (file)
@@ -1,5 +1,7 @@
 /*
- * Copyright (C) 2011-2015 Masahiro Yamada <yamada.masahiro@socionext.com>
+ * Copyright (C) 2011-2014 Panasonic Corporation
+ * Copyright (C) 2015-2016 Socionext Inc.
+ *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
  *
  * SPDX-License-Identifier:    GPL-2.0+
  */
@@ -175,7 +177,7 @@ int uniphier_ld4_umc_init(const struct uniphier_board_data *bd)
        for (ch = 0; ch < DRAM_CH_NR; ch++) {
                ret = umc_ch_init(dc_base, ca_base, bd->dram_freq,
                                  bd->dram_ch[ch].size,
-                                 bd->dram_ddr3plus, ch);
+                                 !!(bd->flags & UNIPHIER_BD_DDR3PLUS), ch);
                if (ret) {
                        pr_err("failed to initialize UMC ch%d\n", ch);
                        return ret;
index 853f561cb23da3f929d07f258f2aab97be286037..f6c2d7f145f31095f8781919fce2922a729954a4 100644 (file)
@@ -1,5 +1,7 @@
 /*
- * Copyright (C) 2011-2015 Masahiro Yamada <yamada.masahiro@socionext.com>
+ * Copyright (C) 2011-2014 Panasonic Corporation
+ * Copyright (C) 2015-2016 Socionext Inc.
+ *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
  *
  * SPDX-License-Identifier:    GPL-2.0+
  */
@@ -170,7 +172,7 @@ int uniphier_pro4_umc_init(const struct uniphier_board_data *bd)
                ret = umc_ch_init(dc_base, ca_base, bd->dram_freq,
                                  bd->dram_ch[ch].size,
                                  bd->dram_ch[ch].width,
-                                 bd->dram_ddr3plus);
+                                 !!(bd->flags & UNIPHIER_BD_DDR3PLUS));
                if (ret) {
                        pr_err("failed to initialize UMC ch%d\n", ch);
                        return ret;
index e83176658364f5c470b10c73d16d4989ac036ee8..61b1dc1a3a24aac65f8414b58524ca81d24e8f52 100644 (file)
@@ -1,5 +1,7 @@
 /*
- * Copyright (C) 2011-2015 Masahiro Yamada <yamada.masahiro@socionext.com>
+ * Copyright (C) 2011-2014 Panasonic Corporation
+ * Copyright (C) 2015-2016 Socionext Inc.
+ *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
  *
  * SPDX-License-Identifier:    GPL-2.0+
  */
@@ -178,7 +180,7 @@ int uniphier_sld8_umc_init(const struct uniphier_board_data *bd)
        for (ch = 0; ch < DRAM_CH_NR; ch++) {
                ret = umc_ch_init(dc_base, ca_base, bd->dram_freq,
                                  bd->dram_ch[ch].size,
-                                 bd->dram_ddr3plus, ch);
+                                 !!(bd->flags & UNIPHIER_BD_DDR3PLUS), ch);
                if (ret) {
                        pr_err("failed to initialize UMC ch%d\n", ch);
                        return ret;
index cba0bc9d37453538848d0d7b6c40b49481ca6160..db80074fc9e708485af2f9ec71ca2e61001d82ca 100644 (file)
@@ -1,5 +1,6 @@
 /*
- * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com>
+ * Copyright (C) 2015-2016 Socionext Inc.
+ *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
  *
  * SPDX-License-Identifier:    GPL-2.0+
  */
@@ -20,8 +21,11 @@ struct uniphier_dram_ch {
 struct uniphier_board_data {
        unsigned int dram_freq;
        unsigned int dram_nr_ch;
-       bool dram_ddr3plus;
        struct uniphier_dram_ch dram_ch[UNIPHIER_MAX_NR_DRAM_CH];
+       unsigned int flags;
+#define UNIPHIER_BD_DDR3PLUS           BIT(2)
+#define UNIPHIER_BD_PACKAGE_LD21       1
+#define UNIPHIER_BD_PACKAGE_TYPE(f)    ((f) & 0x3)
 };
 
 const struct uniphier_board_data *uniphier_get_board_param(void);
index a0955893ef774cc215eff2c92b45862776091f7f..ad58e10e23d0b6ac7406163418ccb50185be8c61 100644 (file)
@@ -1,7 +1,9 @@
 /*
  * UniPhier SC (System Control) block registers
  *
- * Copyright (C) 2011-2015 Masahiro Yamada <yamada.masahiro@socionext.com>
+ * Copyright (C) 2011-2015 Panasonic Corporation
+ * Copyright (C) 2015-2016 Socionext Inc.
+ *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
  *
  * SPDX-License-Identifier:    GPL-2.0+
  */
 #define SC_RSTCTRL4_NRST_UMC31         (0x1 <<  5)     /* UMC ch1 */
 #define SC_RSTCTRL4_NRST_UMC30         (0x1 <<  4)     /* UMC ch0 */
 
+#define SC_RSTCTRL5                    (SC_BASE_ADDR | 0x2010)
+
+#define SC_RSTCTRL6                    (SC_BASE_ADDR | 0x2014)
+
 #define SC_CLKCTRL                     (SC_BASE_ADDR | 0x2104)
 #define SC_CLKCTRL_CEN_USB31           (0x1 << 17)     /* USB3 #1 */
 #define SC_CLKCTRL_CEN_USB30           (0x1 << 16)     /* USB3 #0 */
index 04708e9359461b641d01e9c8b1fd2d4920b91ef3..b2c4d0ef8cf342e18f523920987e5f11917fb08e 100644 (file)
@@ -343,40 +343,6 @@ static inline void writesl(unsigned int *addr, const void * data, int longlen)
 #define insw_p(port, to, len)          insw(port, to, len)
 #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
index 61f5639e0ded8b7bc95c0cd10b72c31abf51e181..ace42799f7ae8ad34cc0e0bc438947b10112868d 100644 (file)
@@ -439,7 +439,7 @@ ulong cpu_init_f(void)
 #ifdef CONFIG_SYS_DCSRBAR_PHYS
        ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
 #endif
-#if defined(CONFIG_SECURE_BOOT)
+#if defined(CONFIG_SECURE_BOOT) && !defined(CONFIG_SYS_RAMBOOT)
        struct law_entry law;
 #endif
 #ifdef CONFIG_MPC8548
@@ -459,7 +459,7 @@ ulong cpu_init_f(void)
        disable_tlb(14);
        disable_tlb(15);
 
-#if defined(CONFIG_SECURE_BOOT)
+#if defined(CONFIG_SECURE_BOOT) && !defined(CONFIG_SYS_RAMBOOT)
        /* Disable the LAW created for NOR flash by the PBI commands */
        law = find_law(CONFIG_SYS_PBI_FLASH_BASE);
        if (law.index != -1)
index 88c8e65930e6918002fd8495fb4dc9644f704e53..0addf8493c2577bbd6d07e66c383f2eb3e3f422c 100644 (file)
@@ -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");
index 4c5122586854dedd236e296aa0915447f2d9f940..c3e12349f7fc53ec79368e9fb8d2d9c4accf18dc 100644 (file)
@@ -1069,17 +1069,23 @@ create_init_ram_area:
 #elif !defined(CONFIG_SYS_RAMBOOT) && defined(CONFIG_SECURE_BOOT)
        /* create a temp mapping in AS = 1 for Flash mapping
         * created by PBL for ISBC code
-       */
+        */
        create_tlb1_entry 15, \
                1, BOOKE_PAGESZ_1M, \
                CONFIG_SYS_MONITOR_BASE & 0xfff00000, MAS2_I|MAS2_G, \
                CONFIG_SYS_PBI_FLASH_WINDOW & 0xfff00000, MAS3_SX|MAS3_SW|MAS3_SR, \
                0, r6
 
-#elif defined(CONFIG_RAMBOOT_PBL) && defined(CONFIG_SECURE_BOOT)
+/*
+ * For Targets without CONFIG_SPL like P3, P5
+ * and for targets with CONFIG_SPL like T1, T2, T4, only for
+ * u-boot-spl i.e. CONFIG_SPL_BUILD
+ */
+#elif defined(CONFIG_RAMBOOT_PBL) && defined(CONFIG_SECURE_BOOT) && \
+       (!defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD))
        /* create a temp mapping in AS = 1 for mapping CONFIG_SYS_MONITOR_BASE
         * to L3 Address configured by PBL for ISBC code
-       */
+        */
        create_tlb1_entry 15, \
                1, BOOKE_PAGESZ_1M, \
                CONFIG_SYS_MONITOR_BASE & 0xfff00000, MAS2_I|MAS2_G, \
index 69a0b96eadb742918daa651a0c210eca612f474a..aefb0f1fb4ffeae8af4b19e4786323ff511e7fa6 100644 (file)
@@ -5,4 +5,4 @@
 # SPDX-License-Identifier:     GPL-2.0+
 #
 
-PLATFORM_CPPFLAGS += -mstring -maltivec -mabi=altivec -msoft-float
+PLATFORM_CPPFLAGS += -mcpu=7400 -mstring -maltivec -mabi=altivec -msoft-float
index 9421f1ebf6f312c081cb9f295e33fc5c4b1707ca..ede8e662104e890ec03bfa14724ed3dca38a096d 100644 (file)
@@ -239,15 +239,23 @@ int pamu_init(void)
        spaact_size = sizeof(struct paace) * NUM_SPAACT_ENTRIES;
 
        /* Allocate space for Primary PAACT Table */
+#if (defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_PPAACT_ADDR))
+       ppaact = (void *)CONFIG_SPL_PPAACT_ADDR;
+#else
        ppaact = memalign(PAMU_TABLE_ALIGNMENT, ppaact_size);
        if (!ppaact)
                return -1;
+#endif
        memset(ppaact, 0, ppaact_size);
 
        /* Allocate space for Secondary PAACT Table */
+#if (defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_SPAACT_ADDR))
+       sec = (void *)CONFIG_SPL_SPAACT_ADDR;
+#else
        sec = memalign(PAMU_TABLE_ALIGNMENT, spaact_size);
        if (!sec)
                return -1;
+#endif
        memset(sec, 0, spaact_size);
 
        ppaact_phys = virt_to_phys((void *)ppaact);
index 26c5ea4fd7a9fd13a73e54aa0f7dbd1d630092b0..a8e6f5177713ea31489703e026f70f0e879272fd 100644 (file)
@@ -28,6 +28,14 @@ void construct_pamu_addr_table(struct pamu_addr_tbl *tbl, int *num_entries)
 
        i++;
 #endif
+#if (defined(CONFIG_SPL_BUILD) && (CONFIG_SYS_INIT_L3_VADDR))
+       tbl->start_addr[i] =
+               (uint64_t)virt_to_phys((void *)CONFIG_SYS_INIT_L3_VADDR);
+       tbl->size[i] = 256 * 1024; /* 256K CPC flash */
+       tbl->end_addr[i] = tbl->start_addr[i] +  tbl->size[i] - 1;
+
+       i++;
+#endif
        debug("PAMU address\t\t\tsize\n");
        for (j = 0; j < i ; j++)
                debug("%llx \t\t\t%llx\n",  tbl->start_addr[j],  tbl->size[j]);
index b432b18c74d6939d735829d11696f50938a17c0f..5647d712d6d4e43025ca13e831a736548628e0ac 100644 (file)
 #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.
  */
index 41b6677bba38836bc4a29381f0f193380f66266a..76faa22c8b437012ce9bbd72fde83e3c686e5736 100644 (file)
 #include <asm/mpc85xx_gpio.h>
 #endif
 
+struct mpc85xx_gpio_plat {
+       ulong addr;
+       unsigned long size;
+       uint ngpios;
+};
+
 #endif
index 826f9c960e956aec2a630b73bee8aa160450dae4..2e937f0364b9503dc758e52a7e7950a789a10306 100644 (file)
@@ -35,7 +35,9 @@
        defined(CONFIG_T104xD4RDB) || \
        defined(CONFIG_PPC_T1023) || \
        defined(CONFIG_PPC_T1024)
+#ifndef CONFIG_SYS_RAMBOOT
 #define CONFIG_SYS_CPC_REINIT_F
+#endif
 #define CONFIG_KEY_REVOCATION
 #undef CONFIG_SYS_INIT_L3_ADDR
 #define CONFIG_SYS_INIT_L3_ADDR                        0xbff00000
 
 #if defined(CONFIG_RAMBOOT_PBL)
 #undef CONFIG_SYS_INIT_L3_ADDR
-#define CONFIG_SYS_INIT_L3_ADDR                        0xbff00000
+#ifdef CONFIG_SYS_INIT_L3_VADDR
+#define CONFIG_SYS_INIT_L3_ADDR        \
+                       (CONFIG_SYS_INIT_L3_VADDR & ~0xFFF00000) | \
+                                       0xbff00000
+#else
+#define CONFIG_SYS_INIT_L3_ADDR                0xbff00000
+#endif
 #endif
 
 #if defined(CONFIG_C29XPCIE)
 
 #ifdef CONFIG_CHAIN_OF_TRUST
 
+#ifdef CONFIG_SPL_BUILD
+#define CONFIG_SPL_DM                  1
+#define CONFIG_SPL_CRYPTO_SUPPORT
+#define CONFIG_SPL_HASH_SUPPORT
+#define CONFIG_SPL_RSA
+#define CONFIG_SPL_DRIVERS_MISC_SUPPORT
+/*
+ * PPAACT and SPAACT table for PAMU must be placed on DDR after DDR init
+ * due to space crunch on CPC and thus malloc will not work.
+ */
+#define CONFIG_SPL_PPAACT_ADDR         0x2e000000
+#define CONFIG_SPL_SPAACT_ADDR         0x2f000000
+#define CONFIG_SPL_JR0_LIODN_S         454
+#define CONFIG_SPL_JR0_LIODN_NS                458
+/*
+ * Define the key hash for U-Boot here if public/private key pair used to
+ * sign U-boot are different from the SRK hash put in the fuse
+ * Example of defining KEY_HASH is
+ * #define CONFIG_SPL_UBOOT_KEY_HASH \
+ *      "41066b564c6ffcef40ccbc1e0a5d0d519604000c785d97bbefd25e4d288d1c8b"
+ * else leave it defined as NULL
+ */
+
+#define CONFIG_SPL_UBOOT_KEY_HASH      NULL
+#endif /* ifdef CONFIG_SPL_BUILD */
+
 #define CONFIG_CMD_ESBC_VALIDATE
 #define CONFIG_CMD_BLOB
 #define CONFIG_FSL_SEC_MON
 #define CONFIG_FSL_CAAM
 #endif
 
-/* fsl_setenv_chain_of_trust() must be called from
+#ifndef CONFIG_SPL_BUILD
+/*
+ * fsl_setenv_chain_of_trust() must be called from
  * board_late_init()
  */
 #ifndef CONFIG_BOARD_LATE_INIT
 /* If Boot Script is not on NOR and is required to be copied on RAM */
 #ifdef CONFIG_BOOTSCRIPT_COPY_RAM
 #define CONFIG_BS_HDR_ADDR_RAM         0x00010000
-#define CONFIG_BS_HDR_ADDR_FLASH       0x00800000
+#define CONFIG_BS_HDR_ADDR_DEVICE      0x00800000
 #define CONFIG_BS_HDR_SIZE             0x00002000
 #define CONFIG_BS_ADDR_RAM             0x00012000
-#define CONFIG_BS_ADDR_FLASH           0x00802000
+#define CONFIG_BS_ADDR_DEVICE          0x00802000
 #define CONFIG_BS_SIZE                 0x00001000
 
 #define CONFIG_BOOTSCRIPT_HDR_ADDR     CONFIG_BS_HDR_ADDR_RAM
 #endif /* #ifdef CONFIG_BOOTSCRIPT_COPY_RAM */
 
 #include <config_fsl_chain_trust.h>
+#endif /* #ifndef CONFIG_SPL_BUILD */
 #endif /* #ifdef CONFIG_CHAIN_OF_TRUST */
 #endif
index 441619042d21bb86f0cbd8df1163d201c48fdc46..260a8319ce34ccf228ecac69742d6febe4015b86 100644 (file)
@@ -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>
index a8a90cb7a4dd9d14c35cc60b16e6eca4698eb6af..d4c1ee0662c57f74e3b7acb35418a2789d2b90ac 100644 (file)
@@ -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"
index 16fd6d508a9322ed5bf68db1b5769cea3b4c9e35..6d62abb0352492b7b2f19fcab60a43d001ad5d62 100644 (file)
@@ -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
index 1b42fee141277b0ca917ae14c265f72d9c73d2b5..db4363358a85dee0949dd1a683873afd8470cd58 100644 (file)
@@ -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
 
index 196f3e1191e166c821378bc05dcecfb20cb25953..2def72212d1feae279506403663cfd4b0fdb0f56 100644 (file)
@@ -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;
 
index 8a4d719835ccb88c00b5aa6fd1e37cfdc049e8e8..2d63dd88f121e0cbcb4effa498c56530aa6223fb 100644 (file)
@@ -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 (file)
index 0000000..e8349c0
--- /dev/null
@@ -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))
+               ;
+}
index 969618ef87502dfb1f34c0f677c18e66c4f6072f..6e4ec017ccd98239faf8af7a9730c8bb3567cb4c 100644 (file)
@@ -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 (file)
index 0000000..7e92b4a
--- /dev/null
@@ -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;
index 2ae40148b09a3976f488b39a0df503ace67ab21f..e6d336f16ab3357f25fdef2e7cf06b3245e353b5 100644 (file)
                };
        };
 
+       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 (file)
index 0000000..59f2401
--- /dev/null
@@ -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
index 96761e27f7a38a80a20176d85ca3c2f2242cc65a..7820c55c8554fce2f94c6af214d8a2cb921cbf20 100644 (file)
@@ -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
index d49c927b3465b5c73956f6d312b7a8226ac2c558..0c9a7979d23142fbc3d96d1722c7d8cd4d6b3c09 100644 (file)
@@ -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;
index 0a00db361798d17dfdf666b73b9834a1afbeda60..5dc27bebd5033b28213043ea2d0755697a34021d 100644 (file)
@@ -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
index 29d2307fa5653cb88b80416b2b04f41974079e3f..29d112097a7bc0d4730476c220a67cae7266271b 100644 (file)
@@ -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"
index 407feb214bf864dd3ed51e451e746ce90fdc0579..1c8ac370b30b7920ebb38bc13abd3f97411ca300 100644 (file)
@@ -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
index 5ee4868cf82ae219470795d154c6ebeb218a742b..fa92d8852eadba38a7a584c6d824153399c451e8 100644 (file)
@@ -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;
+}
index ff1faa501472ec75de6d9ae17acee6af58f3094d..4e0be2a88b907b41beacfe5d0d8e199eb23c8538 100644 (file)
@@ -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);
 
index 9d9f63d70c6974bd523c43190c47c77bc926825a..e0b06b5ada56a7aab20466c6ffdad3d60549fa37 100644 (file)
@@ -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;
index 8f69829608398fe8ae3045850498d5f3c23a8ddd..3968f7a8bfe0111d7902cfbb32e47412d44ad674 100644 (file)
@@ -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;
+}
index 23156bb2314fc17effbc3c2c8a50764dd94beef0..4f07f4104259efa9b7dd2afa094a48a7ae4f4dbd 100644 (file)
@@ -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 (file)
index 0000000..64e2e52
--- /dev/null
@@ -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 (file)
index 0000000..7f2ffd4
--- /dev/null
@@ -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_ */
index 56aa28212772919ee1b5f3c391e3dd6ea9a6d191..caff4d8a1e0df982049380eedc1582cf1a44d3f1 100644 (file)
@@ -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 (file)
index 0000000..a28d4df
--- /dev/null
@@ -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 */
+}
index 22f0d68f4dd5df100a38332595c31d9718075793..fe34d3271c870b3c9f925884c573a32777ec0c5b 100644 (file)
@@ -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)
+                       }
 
                }
 
index 6bc82ecfe1932c78ca42bfa4b0dc623c3b8fb86e..a80d2c0e51599f60ae9219023389813c55f1a44e 100644 (file)
@@ -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 (file)
index 0000000..56e3626
--- /dev/null
@@ -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 (file)
index 0000000..6f0435e
--- /dev/null
@@ -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 */
+}
index bd72842dd6b3eb7d10809f67bca6e6aaee21d7c5..1ecf153c0f9af622da71f187817dfdcad2ea2fa1 100644 (file)
@@ -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 (file)
index 0000000..0231da0
--- /dev/null
@@ -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_ */
index bb71286dba88a80325e3d5a06fff540a36a3d7c9..7001e8ba348932541ecd0ca1f647f7dda6f62759 100644 (file)
 #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);
index b05dcede0c40d38ae473c18dec34cf27e313cd19..a48036121119a27699f6dc2415c017044f4cf4be 100644 (file)
@@ -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 (file)
index 0000000..a8d4969
--- /dev/null
@@ -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 (file)
index 0000000..6eb8a54
--- /dev/null
@@ -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 (file)
index 0000000..f6f3748
--- /dev/null
@@ -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 (file)
index 0000000..92989bf
--- /dev/null
@@ -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 (file)
index 0000000..9837aa0
--- /dev/null
@@ -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 (file)
index 0000000..21785ea
--- /dev/null
@@ -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 (file)
index 0000000..6042011
--- /dev/null
@@ -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 (file)
index 0000000..5bed2c1
--- /dev/null
@@ -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 (file)
index 0000000..2c941a4
--- /dev/null
@@ -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
index 973b57969f8f418f6d02a5e41fad08527d1a515f..e34af6c4d932edb93a4db7cc440e74b0edce9abc 100644 (file)
@@ -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
index 9131a385fd07965d0619740a3f5cf225229482c2..960ca53b021eaf4e7c5490a5f518aca6f843c33f 100644 (file)
@@ -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,
index 6a946d575856989b99bdc444dd8204b4c7e6b258..737e6103f373c45ff3bdbbdad8061be364af0638 100644 (file)
@@ -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-rk3288/evb-rk3288/Kconfig b/board/evb-rk3288/evb-rk3288/Kconfig
new file mode 100644 (file)
index 0000000..b201acb
--- /dev/null
@@ -0,0 +1,15 @@
+if TARGET_EVB_RK3288
+
+config SYS_BOARD
+       default "evb-rk3288"
+
+config SYS_VENDOR
+       default "evb-rk3288"
+
+config SYS_CONFIG_NAME
+       default "evb-rk3288"
+
+config BOARD_SPECIFIC_OPTIONS # dummy
+       def_bool y
+
+endif
diff --git a/board/evb-rk3288/evb-rk3288/MAINTAINERS b/board/evb-rk3288/evb-rk3288/MAINTAINERS
new file mode 100644 (file)
index 0000000..222c254
--- /dev/null
@@ -0,0 +1,6 @@
+EVB-RK3288
+M:     Lin Huang <hl@rock-chips.com>
+S:     Maintained
+F:     board/evb-rk3288/evb-rk3288
+F:     include/configs/evb-rk3288.h
+F:     configs/evb-rk3288_defconfig
diff --git a/board/evb-rk3288/evb-rk3288/Makefile b/board/evb-rk3288/evb-rk3288/Makefile
new file mode 100644 (file)
index 0000000..c11b657
--- /dev/null
@@ -0,0 +1,7 @@
+#
+# (C) Copyright 2016 Rockchip Electronics Co., Ltd
+#
+# SPDX-License-Identifier:     GPL-2.0+
+#
+
+obj-y  += evb-rk3288.o
diff --git a/board/evb-rk3288/evb-rk3288/evb-rk3288.c b/board/evb-rk3288/evb-rk3288/evb-rk3288.c
new file mode 100644 (file)
index 0000000..a82f0ae
--- /dev/null
@@ -0,0 +1,15 @@
+/*
+ * (C) Copyright 2016 Rockchip Electronics Co., Ltd
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include <spl.h>
+
+void board_boot_order(u32 *spl_boot_list)
+{
+       /* eMMC prior to sdcard. */
+       spl_boot_list[0] = BOOT_DEVICE_MMC2;
+       spl_boot_list[1] = BOOT_DEVICE_MMC1;
+}
diff --git a/board/evb_rk3036/evb_rk3036/Kconfig b/board/evb_rk3036/evb_rk3036/Kconfig
deleted file mode 100644 (file)
index ae2a9eb..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-if TARGET_EVB_RK3036
-
-config SYS_BOARD
-       default "evb_rk3036"
-
-config SYS_VENDOR
-       default "evb_rk3036"
-
-config SYS_CONFIG_NAME
-       default "evb_rk3036"
-
-config BOARD_SPECIFIC_OPTIONS # dummy
-       def_bool y
-
-endif
diff --git a/board/evb_rk3036/evb_rk3036/MAINTAINERS b/board/evb_rk3036/evb_rk3036/MAINTAINERS
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/board/evb_rk3036/evb_rk3036/Makefile b/board/evb_rk3036/evb_rk3036/Makefile
deleted file mode 100644 (file)
index 0403836..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-#
-# (C) Copyright 2015 Google, Inc
-#
-# SPDX-License-Identifier:     GPL-2.0+
-#
-
-obj-y  += evb_rk3036.o
diff --git a/board/evb_rk3036/evb_rk3036/evb_rk3036.c b/board/evb_rk3036/evb_rk3036/evb_rk3036.c
deleted file mode 100644 (file)
index f5758b1..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * (C) Copyright 2015 Rockchip Electronics Co., Ltd
- *
- * SPDX-License-Identifier:     GPL-2.0+
- */
-
-#include <common.h>
-#include <dm.h>
-#include <asm/io.h>
-#include <asm/arch/uart.h>
-#include <asm/arch/sdram_rk3036.h>
-
-DECLARE_GLOBAL_DATA_PTR;
-
-void get_ddr_config(struct rk3036_ddr_config *config)
-{
-       /* K4B4G1646Q config */
-       config->ddr_type = 3;
-       config->rank = 2;
-       config->cs0_row = 15;
-       config->cs1_row = 15;
-
-       /* 8bank */
-       config->bank = 3;
-       config->col = 10;
-
-       /* 16bit bw */
-       config->bw = 1;
-}
-
-int board_init(void)
-{
-       return 0;
-}
-
-int dram_init(void)
-{
-       gd->ram_size = sdram_size();
-
-       return 0;
-}
-
-#ifndef CONFIG_SYS_DCACHE_OFF
-void enable_caches(void)
-{
-       /* Enable D-cache. I-cache is already enabled in start.S */
-       dcache_enable();
-}
-#endif
index ecfcc8253a88b5a5700678cbbedeb83c26bbdc4b..dea231b866fe73b1d74b7d5f0bd2bb4c7201e6a6 100644 (file)
@@ -6,7 +6,21 @@
 
 #include <common.h>
 #include <fsl_validate.h>
+#include <fsl_secboot_err.h>
 #include <fsl_sfp.h>
+#include <dm/root.h>
+
+#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_FRAMEWORK)
+#include <spl.h>
+#endif
+
+#ifdef CONFIG_ADDR_MAP
+#include <asm/mmu.h>
+#endif
+
+#ifdef CONFIG_FSL_CORENET
+#include <asm/fsl_pamu.h>
+#endif
 
 #ifdef CONFIG_LS102XA
 #include <asm/arch/immap_ls102xa.h>
@@ -52,6 +66,7 @@ int fsl_check_boot_mode_secure(void)
        return 0;
 }
 
+#ifndef CONFIG_SPL_BUILD
 int fsl_setenv_chain_of_trust(void)
 {
        /* Check Boot Mode
@@ -68,3 +83,76 @@ int fsl_setenv_chain_of_trust(void)
        setenv("bootcmd", CONFIG_CHAIN_BOOT_CMD);
        return 0;
 }
+#endif
+
+#ifdef CONFIG_SPL_BUILD
+void spl_validate_uboot(uint32_t hdr_addr, uintptr_t img_addr)
+{
+       int res;
+
+       /*
+        * Check Boot Mode
+        * If Boot Mode is Non-Secure, skip validation
+        */
+       if (fsl_check_boot_mode_secure() == 0)
+               return;
+
+       printf("SPL: Validating U-Boot image\n");
+
+#ifdef CONFIG_ADDR_MAP
+       init_addr_map();
+#endif
+
+#ifdef CONFIG_FSL_CORENET
+       if (pamu_init() < 0)
+               fsl_secboot_handle_error(ERROR_ESBC_PAMU_INIT);
+#endif
+
+#ifdef CONFIG_FSL_CAAM
+       if (sec_init() < 0)
+               fsl_secboot_handle_error(ERROR_ESBC_SEC_INIT);
+#endif
+
+/*
+ * dm_init_and_scan() is called as part of common SPL framework, so no
+ * need to call it again but in case of powerpc platforms which currently
+ * do not use common SPL framework, so need to call this function here.
+ */
+#if defined(CONFIG_SPL_DM) && (!defined(CONFIG_SPL_FRAMEWORK))
+       dm_init_and_scan(true);
+#endif
+       res = fsl_secboot_validate(hdr_addr, CONFIG_SPL_UBOOT_KEY_HASH,
+                                  &img_addr);
+
+       if (res == 0)
+               printf("SPL: Validation of U-boot successful\n");
+}
+
+#ifdef CONFIG_SPL_FRAMEWORK
+/* Override weak funtion defined in SPL framework to enable validation
+ * of main u-boot image before jumping to u-boot image.
+ */
+void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image)
+{
+       typedef void __noreturn (*image_entry_noargs_t)(void);
+       uint32_t hdr_addr;
+
+       image_entry_noargs_t image_entry =
+               (image_entry_noargs_t)(unsigned long)spl_image->entry_point;
+
+       hdr_addr = (spl_image->entry_point + spl_image->size -
+                       CONFIG_U_BOOT_HDR_SIZE);
+       spl_validate_uboot(hdr_addr, (uintptr_t)spl_image->entry_point);
+       /*
+        * In case of failure in validation, spl_validate_uboot would
+        * not return back in case of Production environment with ITS=1.
+        * Thus U-Boot will not start.
+        * In Development environment (ITS=0 and SB_EN=1), the function
+        * may return back in case of non-fatal failures.
+        */
+
+       debug("image entry point: 0x%X\n", spl_image->entry_point);
+       image_entry();
+}
+#endif /* ifdef CONFIG_SPL_FRAMEWORK */
+#endif /* ifdef CONFIG_SPL_BUILD */
index ab0234412cb88b7d3c9537eea771c327190383ea..f0390c129f8627390354731b0beff1a97adff876 100644 (file)
@@ -8,3 +8,4 @@ obj-y += ls1021aqds.o
 obj-y += ddr.o
 obj-y += eth.o
 obj-$(CONFIG_FSL_DCU_FB) += dcu.o
+obj-$(CONFIG_ARMV7_PSCI) += psci.o
diff --git a/board/freescale/ls1021aqds/psci.S b/board/freescale/ls1021aqds/psci.S
new file mode 100644 (file)
index 0000000..598168c
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2016 NXP Semiconductor.
+ * Author: Wang Dongsheng <dongsheng.wang@freescale.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <config.h>
+#include <linux/linkage.h>
+
+#include <asm/armv7.h>
+#include <asm/psci.h>
+
+       .pushsection ._secure.text, "ax"
+
+       .arch_extension sec
+
+       .align  5
+
+.globl psci_system_off
+psci_system_off:
+       @ Get QIXIS base address
+       movw    r1, #(QIXIS_BASE & 0xffff)
+       movt    r1, #(QIXIS_BASE >> 16)
+
+       ldrb    r2, [r1, #QIXIS_PWR_CTL]
+       orr     r2, r2, #QIXIS_PWR_CTL_POWEROFF
+       strb    r2, [r1, #QIXIS_PWR_CTL]
+
+1:     wfi
+       b       1b
+
+       .popsection
index 01296c04b2931e60d044daf8631fe4df4399820c..5238b158d7c52580d303bf7acd866ad85743651c 100644 (file)
@@ -6,3 +6,4 @@
 
 obj-y += ls1021atwr.o
 obj-$(CONFIG_FSL_DCU_FB) += dcu.o
+obj-$(CONFIG_ARMV7_PSCI) += psci.o
index c69c9cba42e506d32ad5b8b6bbe512fe06aaa750..77482a947bf445b52ae19764b067c9e7bc274b50 100644 (file)
@@ -503,6 +503,13 @@ int board_init(void)
        return 0;
 }
 
+#if defined(CONFIG_SPL_BUILD)
+void spl_board_init(void)
+{
+       ls102xa_smmu_stream_id_init();
+}
+#endif
+
 #ifdef CONFIG_BOARD_LATE_INIT
 int board_late_init(void)
 {
diff --git a/board/freescale/ls1021atwr/psci.S b/board/freescale/ls1021atwr/psci.S
new file mode 100644 (file)
index 0000000..bec7356
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2016 NXP Semiconductor.
+ * Author: Wang Dongsheng <dongsheng.wang@freescale.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <config.h>
+#include <linux/linkage.h>
+
+#include <asm/armv7.h>
+#include <asm/psci.h>
+
+       .pushsection ._secure.text, "ax"
+
+       .arch_extension sec
+
+       .align  5
+
+.globl psci_system_off
+psci_system_off:
+1:     wfi
+       b       1b
+
+       .popsection
index 65a0af193097cd99c96a72b875558cf641ea68f5..992c54c95fa16d451392bd1b3e95c5847fdd2521 100644 (file)
@@ -9,3 +9,4 @@ F:      configs/ls1043aqds_nand_defconfig
 F:     configs/ls1043aqds_sdcard_ifc_defconfig
 F:     configs/ls1043aqds_sdcard_qspi_defconfig
 F:     configs/ls1043aqds_qspi_defconfig
+F:     configs/ls1043aqds_lpuart_defconfig
index 0fd835d74fb3712467719cb79b718740d06bf1ef..d4540d0a9a0e4b2be5bed3e97e70a170f4f22fc3 100644 (file)
@@ -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
        }
 }
index b7e9c2172773fff279ee18b9f60bb50247584003..941dfbc447ebe9f1b3ed29c1d8e7bc1710dee264 100644 (file)
@@ -327,6 +327,7 @@ int ft_board_setup(void *blob, bd_t *bd)
 {
        u64 base[CONFIG_NR_DRAM_BANKS];
        u64 size[CONFIG_NR_DRAM_BANKS];
+       u8 reg;
 
        /* fixup DT for the two DDR banks */
        base[0] = gd->bd->bi_dram[0].start;
@@ -341,6 +342,15 @@ int ft_board_setup(void *blob, bd_t *bd)
        fdt_fixup_fman_ethernet(blob);
        fdt_fixup_board_enet(blob);
 #endif
+
+       reg = QIXIS_READ(brdcfg[0]);
+       reg = (reg & QIXIS_LBMAP_MASK) >> QIXIS_LBMAP_SHIFT;
+
+       /* Disable IFC if QSPI is enabled */
+       if (reg == 0xF)
+               do_fixup_by_compat(blob, "fsl,ifc",
+                                  "status", "disabled", 8 + 1, 1);
+
        return 0;
 }
 #endif
index 1e2fd2ed0c136d25b8325fdd56dfb098e82de7ba..61b1cc4f30e178561b5d8859d6e5bc36544c08d0 100644 (file)
@@ -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
        }
 }
index 14365207da1b383cb755fcc15657dd526629165e..d3e37b4996a0a87adc389b6451df0ee4cbfb34cf 100644 (file)
@@ -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
index 1827ddca6952097fe726db7e9844f3884b1c143a..e6130ec709309b0ecf716c4c5f0cbbc3cb6a9117 100644 (file)
@@ -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
        }
 
index 076532622f45068055475420806fd63e95dae179..8f78b67baae96c01f02748cb52197d9402dd3450 100644 (file)
@@ -6,6 +6,7 @@ F:      board/freescale/ls2080a/ls2080aqds.c
 F:     include/configs/ls2080aqds.h
 F:     configs/ls2080aqds_defconfig
 F:     configs/ls2080aqds_nand_defconfig
+F:     configs/ls2080aqds_qspi_defconfig
 
 LS2080A_SECURE_BOOT BOARD
 M:     Saksham Jain <saksham.jain@nxp.freescale.com>
index fcb03665bf97d83fe6e67de38acb5ba7afb67784..9c6f477c7f4cabd719011cf37c582d04fa2fd78c 100644 (file)
@@ -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
        }
 
index a04d21be130df2b234577f18dca099bab8328346..ecd1e71ad8fb81034a225e82f036aebac18dcb88 100644 (file)
@@ -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/t104xrdb/t104x_pbi_sb.cfg b/board/freescale/t104xrdb/t104x_pbi_sb.cfg
new file mode 100644 (file)
index 0000000..98dc8e4
--- /dev/null
@@ -0,0 +1,38 @@
+#PBI commands
+#Software Workaround for errata A-007662 to train PCIe2 controller in Gen2 speed
+09250100 00000400
+09250108 00002000
+#Software Workaround for errata A-008007 to reset PVR register
+09000010 0000000b
+09000014 c0000000
+09000018 81d00017
+89020400 a1000000
+091380c0 000f0000
+89020400 00000000
+#Initialize CPC1
+09010000 00200400
+09138000 00000000
+091380c0 00000100
+#Configure CPC1 as 256KB SRAM
+09010100 00000000
+09010104 bffc0007
+09010f00 081e000d
+09010000 80000000
+#Configure LAW for CPC1
+09000cd0 00000000
+09000cd4 bffc0000
+09000cd8 81000011
+#Configure alternate space
+09000010 00000000
+09000014 bf000000
+09000018 81000000
+#Configure SPI controller
+09110000 80000403
+09110020 2d170008
+09110024 00100008
+09110028 00100008
+0911002c 00100008
+#Flush PBL data
+091380c0 000FFFFF
+090e0200 bffd0000
+091380c0 000FFFFF
index 95c15aa5965a5c260f6d690fd2aa40be3ace1a1d..7c0511e268bad96546b13aae3882a0e1f7dd3275 100644 (file)
@@ -28,7 +28,8 @@ struct fsl_e_tlb_entry tlb_table[] = {
 
        /* TLB 1 */
        /* *I*** - Covers boot page */
-#if defined(CONFIG_SYS_RAMBOOT) && defined(CONFIG_SYS_INIT_L3_ADDR)
+#if defined(CONFIG_SYS_RAMBOOT) && defined(CONFIG_SYS_INIT_L3_ADDR) && \
+       !defined(CONFIG_SECURE_BOOT)
        /*
         * *I*G - L3SRAM. When L3 is used as 256K SRAM, the address of the
         * SRAM is at 0xfffc0000, it covered the 0xfffff000.
@@ -36,6 +37,18 @@ struct fsl_e_tlb_entry tlb_table[] = {
        SET_TLB_ENTRY(1, CONFIG_SYS_INIT_L3_ADDR, CONFIG_SYS_INIT_L3_ADDR,
                      MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
                      0, 0, BOOKE_PAGESZ_256K, 1),
+
+#elif defined(CONFIG_SECURE_BOOT) && defined(CONFIG_SPL_BUILD)
+       /*
+        * *I*G - L3SRAM. When L3 is used as 256K SRAM, in case of Secure Boot
+        * the physical address of the SRAM is at 0xbffc0000,
+        * and virtual address is 0xfffc0000
+        */
+
+       SET_TLB_ENTRY(1, CONFIG_SYS_INIT_L3_VADDR,
+                     CONFIG_SYS_INIT_L3_ADDR,
+                     MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
+                     0, 0, BOOKE_PAGESZ_256K, 1),
 #else
        SET_TLB_ENTRY(1, 0xfffff000, 0xfffff000,
                      MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
index 426dc05c7d3cea53fda73193e25a3a2e40007aa2..35fa06a2ee97825f0aea09b1b724477357376858 100644 (file)
@@ -31,14 +31,6 @@ int get_fpga_state(unsigned dev)
        return gd->arch.fpga_state[dev];
 }
 
-void print_fpga_state(unsigned dev)
-{
-       if (gd->arch.fpga_state[dev] & FPGA_STATE_DONE_FAILED)
-               puts("       Waiting for FPGA-DONE timed out.\n");
-       if (gd->arch.fpga_state[dev] & FPGA_STATE_REFLECTION_FAILED)
-               puts("       FPGA reflection test failed.\n");
-}
-
 int board_early_init_f(void)
 {
        unsigned k;
index 54c7eb3a12aba1abbf3f33e7dc0b6fb420ad3451..e400d1945a7caf448c6fd0275781f2a3188223ba 100644 (file)
@@ -109,7 +109,10 @@ static void print_fpga_info(unsigned dev)
            && !((hardware_version == HWVER_101)
                 && (fpga_state == FPGA_STATE_DONE_FAILED))) {
                puts("not available\n");
-               print_fpga_state(dev);
+               if (fpga_state & FPGA_STATE_DONE_FAILED)
+                       puts("       Waiting for FPGA-DONE timed out.\n");
+               if (fpga_state & FPGA_STATE_REFLECTION_FAILED)
+                       puts("       FPGA reflection test failed.\n");
                return;
        }
 
index c1a583ffbe09fcbb80e0af44401b4e9931814e80..9e1c57f80857167c455dfafc90e926dbc16a1dc2 100644 (file)
@@ -24,14 +24,6 @@ int get_fpga_state(unsigned dev)
        return gd->arch.fpga_state[dev];
 }
 
-void print_fpga_state(unsigned dev)
-{
-       if (gd->arch.fpga_state[dev] & FPGA_STATE_DONE_FAILED)
-               puts("       Waiting for FPGA-DONE timed out.\n");
-       if (gd->arch.fpga_state[dev] & FPGA_STATE_REFLECTION_FAILED)
-               puts("       FPGA reflection test failed.\n");
-}
-
 int board_early_init_f(void)
 {
        u32 val;
index 4338a3312685972d435fc7dd7e210fccfd946da8..1b8e035b4b2cee60fb77bd3546b6a1c9f5da0df8 100644 (file)
@@ -31,14 +31,6 @@ int get_fpga_state(unsigned dev)
        return gd->arch.fpga_state[dev];
 }
 
-void print_fpga_state(unsigned dev)
-{
-       if (gd->arch.fpga_state[dev] & FPGA_STATE_DONE_FAILED)
-               puts("       Waiting for FPGA-DONE timed out.\n");
-       if (gd->arch.fpga_state[dev] & FPGA_STATE_REFLECTION_FAILED)
-               puts("       FPGA reflection test failed.\n");
-}
-
 int board_early_init_f(void)
 {
        unsigned k;
index 9671c5aa54bc2c38f673fc8c348c3446f90a013a..3786842d365d70b2bbeb311ecf9295a3e71f468d 100644 (file)
@@ -128,7 +128,7 @@ void board_mmc_power_init(void)
 #define GPMC_BASEADDR_MASK     0x3F
 #define GPMC_CS_ENABLE         0x1
 
-static void enable_gpmc_net_config(const u32 *gpmc_config, struct gpmc_cs *cs,
+static void enable_gpmc_net_config(const u32 *gpmc_config, const struct gpmc_cs *cs,
                u32 base, u32 size)
 {
        writel(0, &cs->config7);
index 7abc67874ab0c8e7773ed2eca41ba149c7c4d538..72d6334b5f69c0f17166b4a2ad0a12c811bfd039 100644 (file)
@@ -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 |
index d1a6a6f56f0211da5f8424ca95d64783150f661e..808955e69e76e91ffd250f8f1997f8f6ff06147f 100644 (file)
@@ -10,6 +10,7 @@
 #include <ns16550.h>
 #include <twl4030.h>
 #include <netdev.h>
+#include <spl.h>
 #include <asm/gpio.h>
 #include <asm/io.h>
 #include <asm/arch/mem.h>
 #include <asm/arch/mux.h>
 #include <asm/arch/sys_proto.h>
 #include <asm/mach-types.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/onenand.h>
+#include <jffs2/load_kernel.h>
 #include "igep00x0.h"
 
 DECLARE_GLOBAL_DATA_PTR;
 
-#if defined(CONFIG_CMD_NET)
-/* GPMC definitions for LAN9221 chips */
-static const u32 gpmc_lan_config[] = {
-       NET_LAN9221_GPMC_CONFIG1,
-       NET_LAN9221_GPMC_CONFIG2,
-       NET_LAN9221_GPMC_CONFIG3,
-       NET_LAN9221_GPMC_CONFIG4,
-       NET_LAN9221_GPMC_CONFIG5,
-       NET_LAN9221_GPMC_CONFIG6,
-};
+const omap3_sysinfo sysinfo = {
+       DDR_STACKED,
+#if (CONFIG_MACH_TYPE == MACH_TYPE_IGEP0020)
+       "IGEPv2",
+#endif
+#if (CONFIG_MACH_TYPE == MACH_TYPE_IGEP0030)
+       "IGEP COM MODULE/ELECTRON",
+#endif
+#if (CONFIG_MACH_TYPE == MACH_TYPE_IGEP0032)
+       "IGEP COM PROTON",
+#endif
+#if defined(CONFIG_ENV_IS_IN_ONENAND)
+       "ONENAND",
+#else
+       "NAND",
 #endif
+};
 
 static const struct ns16550_platdata igep_serial = {
        .base = OMAP34XX_UART3,
@@ -50,7 +62,25 @@ U_BOOT_DEVICE(igep_uart) = {
  */
 int board_init(void)
 {
-       gpmc_init(); /* in SRAM or SDRAM, finish GPMC */
+       int loops = 100;
+
+       /* find out flash memory type, assume NAND first */
+       gpmc_cs0_flash = MTD_DEV_TYPE_NAND;
+       gpmc_init();
+
+       /* Issue a RESET and then READID */
+       writeb(NAND_CMD_RESET, &gpmc_cfg->cs[0].nand_cmd);
+       writeb(NAND_CMD_STATUS, &gpmc_cfg->cs[0].nand_cmd);
+       while ((readl(&gpmc_cfg->cs[0].nand_dat) & NAND_STATUS_READY)
+                                               != NAND_STATUS_READY) {
+               udelay(1);
+               if (--loops == 0) {
+                       gpmc_cs0_flash = MTD_DEV_TYPE_ONENAND;
+                       gpmc_init();    /* reinitialize for OneNAND */
+                       break;
+               }
+       }
+
        /* boot param addr */
        gd->bd->bi_boot_params = (OMAP34XX_SDRC_CS0 + 0x100);
 
@@ -62,14 +92,6 @@ int board_init(void)
 }
 
 #ifdef CONFIG_SPL_BUILD
-/*
- * Routine: omap_rev_string
- * Description: For SPL builds output board rev
- */
-void omap_rev_string(void)
-{
-}
-
 /*
  * Routine: get_board_mem_timings
  * Description: If we use SPL then there is no x-loader nor config header
@@ -77,31 +99,54 @@ void omap_rev_string(void)
  */
 void get_board_mem_timings(struct board_sdrc_timings *timings)
 {
-       timings->mr = MICRON_V_MR_165;
-#ifdef CONFIG_BOOT_NAND
-       timings->mcfg = MICRON_V_MCFG_200(256 << 20);
-       timings->ctrla = MICRON_V_ACTIMA_200;
-       timings->ctrlb = MICRON_V_ACTIMB_200;
-       timings->rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_200MHz;
-#else
-       if (get_cpu_family() == CPU_OMAP34XX) {
-               timings->mcfg = NUMONYX_V_MCFG_165(256 << 20);
-               timings->ctrla = NUMONYX_V_ACTIMA_165;
-               timings->ctrlb = NUMONYX_V_ACTIMB_165;
-               timings->rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_165MHz;
+       int mfr, id, err = identify_nand_chip(&mfr, &id);
 
-       } else {
-               timings->mcfg = NUMONYX_V_MCFG_200(256 << 20);
-               timings->ctrla = NUMONYX_V_ACTIMA_200;
-               timings->ctrlb = NUMONYX_V_ACTIMB_200;
+       timings->mr = MICRON_V_MR_165;
+       if (!err && mfr == NAND_MFR_MICRON) {
+               timings->mcfg = MICRON_V_MCFG_200(256 << 20);
+               timings->ctrla = MICRON_V_ACTIMA_200;
+               timings->ctrlb = MICRON_V_ACTIMB_200;
                timings->rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_200MHz;
+               gpmc_cs0_flash = MTD_DEV_TYPE_NAND;
+       } else {
+               if (get_cpu_family() == CPU_OMAP34XX) {
+                       timings->mcfg = NUMONYX_V_MCFG_165(256 << 20);
+                       timings->ctrla = NUMONYX_V_ACTIMA_165;
+                       timings->ctrlb = NUMONYX_V_ACTIMB_165;
+                       timings->rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_165MHz;
+               } else {
+                       timings->mcfg = NUMONYX_V_MCFG_200(256 << 20);
+                       timings->ctrla = NUMONYX_V_ACTIMA_200;
+                       timings->ctrlb = NUMONYX_V_ACTIMB_200;
+                       timings->rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_200MHz;
+               }
+               gpmc_cs0_flash = MTD_DEV_TYPE_ONENAND;
        }
-#endif
+}
+
+#ifdef CONFIG_SPL_OS_BOOT
+int spl_start_uboot(void)
+{
+       /* break into full u-boot on 'c' */
+       if (serial_tstc() && serial_getc() == 'c')
+               return 1;
+
+       return 0;
 }
 #endif
+#endif
 
-#if defined(CONFIG_CMD_NET)
+int onenand_board_init(struct mtd_info *mtd)
+{
+       if (gpmc_cs0_flash == MTD_DEV_TYPE_ONENAND) {
+               struct onenand_chip *this = mtd->priv;
+               this->base = (void *)CONFIG_SYS_ONENAND_BASE;
+               return 0;
+       }
+       return 1;
+}
 
+#if defined(CONFIG_CMD_NET)
 static void reset_net_chip(int gpio)
 {
        if (!gpio_request(gpio, "eth nrst")) {
@@ -122,6 +167,14 @@ static void reset_net_chip(int gpio)
 static void setup_net_chip(void)
 {
        struct ctrl *ctrl_base = (struct ctrl *)OMAP34XX_CTRL_BASE;
+       static const u32 gpmc_lan_config[] = {
+               NET_LAN9221_GPMC_CONFIG1,
+               NET_LAN9221_GPMC_CONFIG2,
+               NET_LAN9221_GPMC_CONFIG3,
+               NET_LAN9221_GPMC_CONFIG4,
+               NET_LAN9221_GPMC_CONFIG5,
+               NET_LAN9221_GPMC_CONFIG6,
+       };
 
        enable_gpmc_cs_config(gpmc_lan_config, &gpmc_cfg->cs[5],
                        CONFIG_SMC911X_BASE, GPMC_SIZE_16M);
@@ -136,6 +189,15 @@ static void setup_net_chip(void)
 
        reset_net_chip(64);
 }
+
+int board_eth_init(bd_t *bis)
+{
+#ifdef CONFIG_SMC911X
+       return smc911x_initialize(0, CONFIG_SMC911X_BASE);
+#else
+       return 0;
+#endif
+}
 #else
 static inline void setup_net_chip(void) {}
 #endif
@@ -183,6 +245,23 @@ int misc_init_r(void)
        return 0;
 }
 
+void board_mtdparts_default(const char **mtdids, const char **mtdparts)
+{
+       struct mtd_info *mtd = get_mtd_device(NULL, 0);
+       if (mtd) {
+               static char ids[24];
+               static char parts[48];
+               const char *linux_name = "omap2-nand";
+               if (strncmp(mtd->name, "onenand0", 8) == 0)
+                       linux_name = "omap2-onenand";
+               snprintf(ids, sizeof(ids), "%s=%s", mtd->name, linux_name);
+               snprintf(parts, sizeof(parts), "mtdparts=%s:%dk(SPL),-(UBI)",
+                        linux_name, 4 * mtd->erasesize >> 10);
+               *mtdids = ids;
+               *mtdparts = parts;
+       }
+}
+
 /*
  * Routine: set_muxconf_regs
  * Description: Setting up the configuration Mux registers specific to the
@@ -201,14 +280,3 @@ void set_muxconf_regs(void)
        MUX_IGEP0030();
 #endif
 }
-
-#if defined(CONFIG_CMD_NET)
-int board_eth_init(bd_t *bis)
-{
-#ifdef CONFIG_SMC911X
-       return smc911x_initialize(0, CONFIG_SMC911X_BASE);
-#else
-       return 0;
-#endif
-}
-#endif
index 3c7ff9b1488a25ed2bec2fea417a1fdf57e45687..5698efab5d7f9cba7bbbbd5237c9495b0f7fa4c1 100644 (file)
@@ -7,26 +7,6 @@
 #ifndef _IGEP00X0_H_
 #define _IGEP00X0_H_
 
-const omap3_sysinfo sysinfo = {
-       DDR_STACKED,
-#if (CONFIG_MACH_TYPE == MACH_TYPE_IGEP0020)
-       "IGEPv2",
-#endif
-#if (CONFIG_MACH_TYPE == MACH_TYPE_IGEP0030)
-       "IGEP COM MODULE/ELECTRON",
-#endif
-#if (CONFIG_MACH_TYPE == MACH_TYPE_IGEP0032)
-       "IGEP COM PROTON",
-#endif
-#if defined(CONFIG_ENV_IS_IN_ONENAND)
-       "ONENAND",
-#else
-       "NAND",
-#endif
-};
-
-static void setup_net_chip(void);
-
 /*
  * IEN  - Input Enable
  * IDIS - Input Disable
index a42f3eca33b3f22b1721879da42116d03b9f7d99..0829b7fa0666574ed2f82bdd0a8c5e48001cf404 100644 (file)
@@ -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);
index 34ac6979bd7d13c602f47f8ef218e9123d39ba02..77af184c82b5effc4863f8d10618db849501ab38 100644 (file)
@@ -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/Kconfig b/board/kylin/kylin_rk3036/Kconfig
deleted file mode 100644 (file)
index 5d75c1f..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-if TARGET_KYLIN_RK3036
-
-config SYS_BOARD
-       default "kylin_rk3036"
-
-config SYS_VENDOR
-       default "kylin"
-
-config SYS_CONFIG_NAME
-       default "kylin_rk3036"
-
-config BOARD_SPECIFIC_OPTIONS # dummy
-       def_bool y
-
-endif
diff --git a/board/kylin/kylin_rk3036/MAINTAINERS b/board/kylin/kylin_rk3036/MAINTAINERS
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/board/kylin/kylin_rk3036/Makefile b/board/kylin/kylin_rk3036/Makefile
deleted file mode 100644 (file)
index 0663270..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-#
-# (C) Copyright 2015 Google, Inc
-#
-# SPDX-License-Identifier:     GPL-2.0+
-#
-
-obj-y  += kylin_rk3036.o
diff --git a/board/kylin/kylin_rk3036/kylin_rk3036.c b/board/kylin/kylin_rk3036/kylin_rk3036.c
deleted file mode 100644 (file)
index 2a25871..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * (C) Copyright 2015 Rockchip Electronics Co., Ltd
- *
- * SPDX-License-Identifier:     GPL-2.0+
- */
-
-#include <common.h>
-#include <dm.h>
-#include <asm/io.h>
-#include <asm/arch/uart.h>
-#include <asm/arch-rockchip/grf_rk3036.h>
-#include <asm/arch/sdram_rk3036.h>
-#include <asm/gpio.h>
-
-DECLARE_GLOBAL_DATA_PTR;
-
-#define GRF_BASE       0x20008000
-
-void get_ddr_config(struct rk3036_ddr_config *config)
-{
-       /* K4B4G1646Q config */
-       config->ddr_type = 3;
-       config->rank = 1;
-       config->cs0_row = 15;
-       config->cs1_row = 15;
-
-       /* 8bank */
-       config->bank = 3;
-       config->col = 10;
-
-       /* 16bit bw */
-       config->bw = 1;
-}
-
-#define FASTBOOT_KEY_GPIO 93
-
-int fastboot_key_pressed(void)
-{
-       gpio_request(FASTBOOT_KEY_GPIO, "fastboot_key");
-       gpio_direction_input(FASTBOOT_KEY_GPIO);
-       return !gpio_get_value(FASTBOOT_KEY_GPIO);
-}
-
-#define ROCKCHIP_BOOT_MODE_FASTBOOT    0x5242C309
-
-int board_late_init(void)
-{
-       struct rk3036_grf * const grf = (void *)GRF_BASE;
-       int boot_mode = readl(&grf->os_reg[4]);
-
-       /* Clear boot mode */
-       writel(0, &grf->os_reg[4]);
-
-       if (boot_mode == ROCKCHIP_BOOT_MODE_FASTBOOT ||
-           fastboot_key_pressed()) {
-               printf("enter fastboot!\n");
-               setenv("preboot", "setenv preboot; fastboot usb0");
-       }
-
-       return 0;
-}
-
-int board_init(void)
-{
-       return 0;
-}
-
-int dram_init(void)
-{
-       gd->ram_size = sdram_size();
-
-       return 0;
-}
-
-#ifndef CONFIG_SYS_DCACHE_OFF
-void enable_caches(void)
-{
-       /* Enable D-cache. I-cache is already enabled in start.S */
-       dcache_enable();
-}
-#endif
index 982619cd7bc7af4443d8305af462dc8bd9b2e7fc..2821ee22674f78a8afa2971c1cf982aa1255c468 100644 (file)
@@ -19,6 +19,7 @@
 #include <ns16550.h>
 #include <netdev.h>
 #include <twl4030.h>
+#include <linux/mtd/omap_gpmc.h>
 #include <asm/io.h>
 #include <asm/arch/mem.h>
 #include <asm/arch/mmc_host_def.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
-/* gpmc_cfg is initialized by gpmc_init and we use it here */
-extern struct gpmc *gpmc_cfg;
-
-/* GPMC definitions for Ethenet Controller LAN9211 */
+/*
+ * gpmc_cfg is initialized by gpmc_init and we use it here.
+ * GPMC definitions for Ethenet Controller LAN9211
+ */
 static const u32 gpmc_lab_enet[] = {
        ZOOM1_ENET_GPMC_CONF1,
        ZOOM1_ENET_GPMC_CONF2,
index 62eb6489be273252a9688e67f3b5d6b96e39a547..ef892cae15b730651643d9ae7e9ec484f42f18ee 100644 (file)
@@ -169,7 +169,7 @@ static int ebi_write_bufferram(struct mtd_info *mtd, loff_t addr, int area,
        return 0;
 }
 
-void onenand_board_init(struct mtd_info *mtd)
+int onenand_board_init(struct mtd_info *mtd)
 {
        struct onenand_chip *chip = mtd->priv;
 
@@ -181,4 +181,6 @@ void onenand_board_init(struct mtd_info *mtd)
 
        chip->read_bufferram = ebi_read_bufferram;
        chip->write_bufferram = ebi_write_bufferram;
+
+       return 0;
 }
index 0f587eaaa79695aafe5f9918546cce4e643521e8..dbdc1b65e6807ee380d502dc7671b257701f553d 100644 (file)
@@ -30,6 +30,28 @@ void pin_mux_mmc(void)
        ret = dm_i2c_write(dev, MAX77620_CNFG1_L2_REG, &val, 1);
        if (ret)
                printf("i2c_write 0 0x3c 0x27 failed: %d\n", ret);
+
+       /* Disable LDO4 discharge */
+       ret = dm_i2c_read(dev, MAX77620_CNFG2_L4_REG, &val, 1);
+       if (ret) {
+               printf("i2c_read 0 0x3c 0x2c failed: %d\n", ret);
+       } else {
+               val &= ~BIT(1); /* ADE */
+               ret = dm_i2c_write(dev, MAX77620_CNFG2_L4_REG, &val, 1);
+               if (ret)
+                       printf("i2c_write 0 0x3c 0x2c failed: %d\n", ret);
+       }
+
+       /* Set MBLPD */
+       ret = dm_i2c_read(dev, MAX77620_CNFGGLBL1_REG, &val, 1);
+       if (ret) {
+               printf("i2c_write 0 0x3c 0x00 failed: %d\n", ret);
+       } else {
+               val |= BIT(6); /* MBLPD */
+               ret = dm_i2c_write(dev, MAX77620_CNFGGLBL1_REG, &val, 1);
+               if (ret)
+                       printf("i2c_write 0 0x3c 0x00 failed: %d\n", ret);
+       }
 }
 
 /*
index 92c3719112a4cedb6660a1d483b6466a7853280f..39e550149aae669bf073bcc54be7bbc90ef90f8d 100644 (file)
@@ -13,6 +13,8 @@
 #define MAX77620_I2C_ADDR              0x78
 #define MAX77620_I2C_ADDR_7BIT         0x3C
 
+#define MAX77620_CNFGGLBL1_REG         0x00
+
 #define MAX77620_SD0_REG               0x16
 #define MAX77620_SD1_REG               0x17
 #define MAX77620_SD2_REG               0x18
index c45ddb14aa336c0771ae7f9f70e05f8b8ae422a8..fbfbf6cbbc64282c222a7047ed3c5e609f70b4c3 100644 (file)
@@ -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/rockchip/evb_rk3036/Kconfig b/board/rockchip/evb_rk3036/Kconfig
new file mode 100644 (file)
index 0000000..ef45f62
--- /dev/null
@@ -0,0 +1,15 @@
+if TARGET_EVB_RK3036
+
+config SYS_BOARD
+       default "evb_rk3036"
+
+config SYS_VENDOR
+       default "rockchip"
+
+config SYS_CONFIG_NAME
+       default "evb_rk3036"
+
+config BOARD_SPECIFIC_OPTIONS # dummy
+       def_bool y
+
+endif
diff --git a/board/rockchip/evb_rk3036/MAINTAINERS b/board/rockchip/evb_rk3036/MAINTAINERS
new file mode 100644 (file)
index 0000000..152d31c
--- /dev/null
@@ -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/rockchip/evb_rk3036/Makefile b/board/rockchip/evb_rk3036/Makefile
new file mode 100644 (file)
index 0000000..0403836
--- /dev/null
@@ -0,0 +1,7 @@
+#
+# (C) Copyright 2015 Google, Inc
+#
+# SPDX-License-Identifier:     GPL-2.0+
+#
+
+obj-y  += evb_rk3036.o
diff --git a/board/rockchip/evb_rk3036/evb_rk3036.c b/board/rockchip/evb_rk3036/evb_rk3036.c
new file mode 100644 (file)
index 0000000..f5758b1
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * (C) Copyright 2015 Rockchip Electronics Co., Ltd
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <asm/io.h>
+#include <asm/arch/uart.h>
+#include <asm/arch/sdram_rk3036.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+void get_ddr_config(struct rk3036_ddr_config *config)
+{
+       /* K4B4G1646Q config */
+       config->ddr_type = 3;
+       config->rank = 2;
+       config->cs0_row = 15;
+       config->cs1_row = 15;
+
+       /* 8bank */
+       config->bank = 3;
+       config->col = 10;
+
+       /* 16bit bw */
+       config->bw = 1;
+}
+
+int board_init(void)
+{
+       return 0;
+}
+
+int dram_init(void)
+{
+       gd->ram_size = sdram_size();
+
+       return 0;
+}
+
+#ifndef CONFIG_SYS_DCACHE_OFF
+void enable_caches(void)
+{
+       /* Enable D-cache. I-cache is already enabled in start.S */
+       dcache_enable();
+}
+#endif
diff --git a/board/rockchip/evb_rk3399/Kconfig b/board/rockchip/evb_rk3399/Kconfig
new file mode 100644 (file)
index 0000000..412b81c
--- /dev/null
@@ -0,0 +1,15 @@
+if TARGET_EVB_RK3399
+
+config SYS_BOARD
+       default "evb_rk3399"
+
+config SYS_VENDOR
+       default "rockchip"
+
+config SYS_CONFIG_NAME
+       default "evb_rk3399"
+
+config BOARD_SPECIFIC_OPTIONS # dummy
+       def_bool y
+
+endif
diff --git a/board/rockchip/evb_rk3399/MAINTAINERS b/board/rockchip/evb_rk3399/MAINTAINERS
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/board/rockchip/evb_rk3399/Makefile b/board/rockchip/evb_rk3399/Makefile
new file mode 100644 (file)
index 0000000..aaa51c2
--- /dev/null
@@ -0,0 +1,7 @@
+#
+# (C) Copyright 2016 Rockchip Electronics Co., Ltd
+#
+# SPDX-License-Identifier:     GPL-2.0+
+#
+
+obj-y  += evb-rk3399.o
diff --git a/board/rockchip/evb_rk3399/README b/board/rockchip/evb_rk3399/README
new file mode 100644 (file)
index 0000000..fb8bb19
--- /dev/null
@@ -0,0 +1,73 @@
+Introduction
+============
+
+RK3399 key features we might use in U-Boot:
+* CPU: ARMv8 64bit Big-Little architecture,
+*      Big: dual-core Cortex-A72
+*      Little: quad-core Cortex-A53
+* IRAM: 200KB
+* DRAM: 4GB-128MB dual-channel
+* eMMC: support eMMC 5.0/5.1, suport HS400, HS200, DDR50
+* SD/MMC: support SD 3.0, MMC 4.51
+* USB: USB3.0 typc-C port *2 with dwc3 controller
+*      USB2.0 EHCI host port *2
+* Display: RGB/HDMI/DP/MIPI/EDP
+
+evb key features:
+* regulator: pwm regulator for CPU B/L
+* PMIC: rk808
+* debug console: UART2
+
+In order to support Arm Trust Firmware(ATF), we need to use the
+miniloader from rockchip which:
+* do DRAM init
+* load and verify ATF image
+* load and verify U-Boot image
+
+Here is the step-by-step to boot to U-Boot on rk3399.
+
+Get the Source and prebuild binary
+==================================
+
+  > mkdir ~/evb_rk3399
+  > cd ~/evb_rk3399
+  > git clone https://github.com/ARM-software/arm-trusted-firmware.git
+  > git clone https://github.com/rockchip-linux/rkbin
+  > git clone https://github.com/rockchip-linux/rkflashtool
+
+Compile the ATF
+===============
+
+  > cd arm-trusted-firmware
+  > make realclean
+  > make CROSS_COMPILE=aarch64-linux-gnu- PLAT=rk3399 bl31
+
+Compile the U-Boot
+==================
+
+  > cd ../u-boot
+  > make CROSS_COMPILE=aarch64-linux-gnu- evb-rk3399_defconfig all
+
+Compile the rkflashtool
+=======================
+
+  > cd ../rkflashtool
+  > make
+
+Package the image for miniloader
+================================
+  > cd ..
+  > cp arm-trusted-firmware/build/rk3399/release/bl31.bin rkbin/rk33
+  > ./rkbin/tools/trust_merger rkbin/tools/RK3399TRUST.ini
+  > ./rkbin/tools/loaderimage --pack --uboot u-boot/u-boot-dtb.bin uboot.img
+  > mkdir image
+  > mv trust.img ./image/
+  > mv uboot.img ./image/rk3399evb-uboot.bin
+
+Flash the image
+===============
+Power on(or reset with RESET KEY) with MASKROM KEY preesed, and then:
+
+  > ./rkflashtool/rkflashloader rk3399evb
+
+You should be able to get U-Boot log message in console/UART2 now.
diff --git a/board/rockchip/evb_rk3399/evb-rk3399.c b/board/rockchip/evb_rk3399/evb-rk3399.c
new file mode 100644 (file)
index 0000000..dffacd0
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * (C) Copyright 2016 Rockchip Electronics Co., Ltd
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+#include <common.h>
+#include <asm/armv8/mmu.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int board_init(void)
+{
+       return 0;
+}
+
+int dram_init(void)
+{
+       gd->ram_size = 0x80000000;
+       return 0;
+}
+
+void dram_init_banksize(void)
+{
+       gd->bd->bi_dram[0].start = 0;
+       gd->bd->bi_dram[0].size = 0x80000000;
+}
diff --git a/board/rockchip/kylin_rk3036/Kconfig b/board/rockchip/kylin_rk3036/Kconfig
new file mode 100644 (file)
index 0000000..8d35b4e
--- /dev/null
@@ -0,0 +1,15 @@
+if TARGET_KYLIN_RK3036
+
+config SYS_BOARD
+       default "kylin_rk3036"
+
+config SYS_VENDOR
+       default "rockchip"
+
+config SYS_CONFIG_NAME
+       default "kylin_rk3036"
+
+config BOARD_SPECIFIC_OPTIONS # dummy
+       def_bool y
+
+endif
diff --git a/board/rockchip/kylin_rk3036/MAINTAINERS b/board/rockchip/kylin_rk3036/MAINTAINERS
new file mode 100644 (file)
index 0000000..f8ee834
--- /dev/null
@@ -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/rockchip/kylin_rk3036/Makefile b/board/rockchip/kylin_rk3036/Makefile
new file mode 100644 (file)
index 0000000..0663270
--- /dev/null
@@ -0,0 +1,7 @@
+#
+# (C) Copyright 2015 Google, Inc
+#
+# SPDX-License-Identifier:     GPL-2.0+
+#
+
+obj-y  += kylin_rk3036.o
diff --git a/board/rockchip/kylin_rk3036/kylin_rk3036.c b/board/rockchip/kylin_rk3036/kylin_rk3036.c
new file mode 100644 (file)
index 0000000..2a25871
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * (C) Copyright 2015 Rockchip Electronics Co., Ltd
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <asm/io.h>
+#include <asm/arch/uart.h>
+#include <asm/arch-rockchip/grf_rk3036.h>
+#include <asm/arch/sdram_rk3036.h>
+#include <asm/gpio.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define GRF_BASE       0x20008000
+
+void get_ddr_config(struct rk3036_ddr_config *config)
+{
+       /* K4B4G1646Q config */
+       config->ddr_type = 3;
+       config->rank = 1;
+       config->cs0_row = 15;
+       config->cs1_row = 15;
+
+       /* 8bank */
+       config->bank = 3;
+       config->col = 10;
+
+       /* 16bit bw */
+       config->bw = 1;
+}
+
+#define FASTBOOT_KEY_GPIO 93
+
+int fastboot_key_pressed(void)
+{
+       gpio_request(FASTBOOT_KEY_GPIO, "fastboot_key");
+       gpio_direction_input(FASTBOOT_KEY_GPIO);
+       return !gpio_get_value(FASTBOOT_KEY_GPIO);
+}
+
+#define ROCKCHIP_BOOT_MODE_FASTBOOT    0x5242C309
+
+int board_late_init(void)
+{
+       struct rk3036_grf * const grf = (void *)GRF_BASE;
+       int boot_mode = readl(&grf->os_reg[4]);
+
+       /* Clear boot mode */
+       writel(0, &grf->os_reg[4]);
+
+       if (boot_mode == ROCKCHIP_BOOT_MODE_FASTBOOT ||
+           fastboot_key_pressed()) {
+               printf("enter fastboot!\n");
+               setenv("preboot", "setenv preboot; fastboot usb0");
+       }
+
+       return 0;
+}
+
+int board_init(void)
+{
+       return 0;
+}
+
+int dram_init(void)
+{
+       gd->ram_size = sdram_size();
+
+       return 0;
+}
+
+#ifndef CONFIG_SYS_DCACHE_OFF
+void enable_caches(void)
+{
+       /* Enable D-cache. I-cache is already enabled in start.S */
+       dcache_enable();
+}
+#endif
index b74d8e8ac9eb3c8d26226529fc5b721fc5d3f866..cbe1d12fdaae659ee4b5ad10e390ea573a1da3bb 100644 (file)
 #include <linux/mtd/samsung_onenand.h>
 #include <onenand_uboot.h>
 
-void onenand_board_init(struct mtd_info *mtd)
+int onenand_board_init(struct mtd_info *mtd)
 {
        struct onenand_chip *this = mtd->priv;
 
        this->base = (void *)CONFIG_SYS_ONENAND_BASE;
        this->options |= ONENAND_RUNTIME_BADBLOCK_CHECK;
        this->chip_probe = s5pc110_chip_probe;
+
+       return 0;
 }
index 577c1a546f081a9749eaa07c99785b5e212a4ead..994d91d999f914330ee1e4d42929b9e3bb5c93ec 100644 (file)
@@ -16,7 +16,7 @@
 #include <asm/io.h>
 #include <asm/arch/clock.h>
 
-void onenand_board_init(struct mtd_info *mtd)
+int onenand_board_init(struct mtd_info *mtd)
 {
        struct onenand_chip *this = mtd->priv;
        struct s5pc100_clock *clk =
@@ -65,4 +65,6 @@ void onenand_board_init(struct mtd_info *mtd)
        writel(value, &onenand->int_err_mask);
 
        s3c_onenand_init(mtd);
+
+       return 0;
 }
index 28bc8114f4a4c6b5892d5ee06a98c505a731c4cc..147a95e2907a037ef427e1d52b3999fc2692ae88 100644 (file)
 #include <linux/mtd/onenand.h>
 #include <linux/mtd/samsung_onenand.h>
 
-void onenand_board_init(struct mtd_info *mtd)
+int onenand_board_init(struct mtd_info *mtd)
 {
        struct onenand_chip *this = mtd->priv;
 
        this->base = (void *)CONFIG_SYS_ONENAND_BASE;
        this->options |= ONENAND_RUNTIME_BADBLOCK_CHECK;
        this->chip_probe = s5pc210_chip_probe;
+
+       return 0;
 }
index f5db773a478ec827b525487207013fe1410c0da4..4dcbf4ba03c518ad36ec40dcb006e9b4094f2ec5 100644 (file)
@@ -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
index 9fe3bf171a22d64d18f64892b4f4fdb156214957..ed820d338e586bb9dba9d491152d2325f9757b2a 100644 (file)
@@ -44,6 +44,9 @@ Note:
       make sandbox_defconfig all NO_SDL=1
       ./u-boot
 
+   If you are building on a 32-bit machine you may get errors from __ffs.h
+   about shifting more than the machine word size. Edit the config file
+   include/configs/sandbox.h and change CONFIG_SANDBOX_BITS_PER_LONG to 32.
 
 U-Boot will start on your computer, showing a sandbox emulation of the serial
 console:
index 0e04d141480f8ade641957e6a6e1bf0b72af5f01..404fdfa2a714695404be2c6b65692cd36128819e 100644 (file)
@@ -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>
@@ -33,6 +35,221 @@ const struct stm32_gpio_ctl gpio_ctl_usart = {
        .af = STM32_GPIO_AF7
 };
 
+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 */
@@ -88,12 +305,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;
-}
index d2dfebef46bd8f4cfef96dd907c627aa6c10115f..de719cd1f90d2f60c714ed1587c9920db74e08f0 100644 (file)
@@ -56,8 +56,10 @@ 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_pc_plus_defconfig
 F:     configs/orangepi_plus_defconfig
 F:     configs/polaroid_mid2407pxe03_defconfig
 F:     configs/polaroid_mid2809pxe04_defconfig
index c8bf3169d12b94cb300f1505bdd2ddb0b3e835a4..36cf96381ce99cbf88d6cb3e33d7477547229d47 100644 (file)
 #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>
@@ -133,7 +136,7 @@ int dram_init(void)
        return 0;
 }
 
-#if defined(CONFIG_NAND_SUNXI) && defined(CONFIG_SPL_BUILD)
+#if defined(CONFIG_NAND_SUNXI)
 static void nand_pinmux_setup(void)
 {
        unsigned int pin;
@@ -170,6 +173,9 @@ void board_nand_init(void)
 {
        nand_pinmux_setup();
        nand_clock_setup();
+#ifndef CONFIG_SPL_BUILD
+       sunxi_nand_init();
+#endif
 }
 #endif
 
@@ -366,8 +372,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 +576,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 +584,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 +654,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 +679,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)
index f005762edadea944ce1840bc7430086912131c76..27c311ee9d2d930482c5f423a56b8c7df3eaabcb 100644 (file)
@@ -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
index 08cf14d5e73f629bf4a47d880aca7888d432d928..927d1364fe46736d0e52ab37d29e988d6125cbe0 100644 (file)
@@ -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
index 6a4d02769e584eed96fef0675e3bef5816d738db..99e82542f72a375d5f26cdf0b387ea4aba313432 100644 (file)
@@ -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
index 1c4bed96b5b75fc753cfb89485202cb4fb19f22d..f2435ab7e52e51e8969787257dfdd1b1386906fc 100644 (file)
@@ -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)
index 011f62c5b1ca76a409a96cb61581273c9c3c2b07..d66892e69ee963f893321878e961705996a0308f 100644 (file)
@@ -290,6 +290,11 @@ void efi_set_bootdev(const char *dev, const char *devnr, const char *path)
 
        /* Patch bootefi_image_path to the target file path */
        memset(bootefi_image_path[0].str, 0, sizeof(bootefi_image_path[0].str));
-       snprintf(devname, sizeof(devname), "%s", path);
+       if (strcmp(dev, "Net")) {
+               /* Add leading / to fs paths, because they're absolute */
+               snprintf(devname, sizeof(devname), "/%s", path);
+       } else {
+               snprintf(devname, sizeof(devname), "%s", path);
+       }
        ascii2unicode(bootefi_image_path[0].str, devname);
 }
index 18ce789d7edd916bd704e776b70afedaa3b446d7..473153fbd4737a7949a3f22b0c5a29b7009b941b 100644 (file)
--- 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
index 1ad9ed6ce96a5c37f32b2eb2f702cfc1787232bb..c78df825e84b6c6ea2a0300142d88de75f5fda81 100644 (file)
@@ -20,7 +20,7 @@
 static int do_lzmadec(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
 {
        unsigned long src, dst;
-       unsigned long src_len = ~0UL, dst_len = ~0UL;
+       SizeT src_len = ~0UL, dst_len = ~0UL;
        int ret;
 
        switch (argc) {
@@ -40,7 +40,8 @@ static int do_lzmadec(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
 
        if (ret != SZ_OK)
                return 1;
-       printf("Uncompressed size: %ld = 0x%lX\n", src_len, src_len);
+       printf("Uncompressed size: %ld = %#lX\n", (ulong)src_len,
+              (ulong)src_len);
        setenv_hex("filesize", src_len);
 
        return 0;
index 39d86835cff76122cc5940f521e5e4e6f2c2b11d..efcbb90d18da2769d7f7c73c6c12e08e8ab8d803 100644 (file)
 static int do_sleep(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
        ulong start = get_timer(0);
+       ulong mdelay = 0;
        ulong delay;
+       char *frpart;
 
        if (argc != 2)
                return CMD_RET_USAGE;
 
        delay = simple_strtoul(argv[1], NULL, 10) * CONFIG_SYS_HZ;
 
+       frpart = strchr(argv[1], '.');
+
+       if (frpart) {
+               uint mult = CONFIG_SYS_HZ / 10;
+               for (frpart++; *frpart != '\0' && mult > 0; frpart++) {
+                       if (*frpart < '0' || *frpart > '9') {
+                               mdelay = 0;
+                               break;
+                       }
+                       mdelay += (*frpart - '0') * mult;
+                       mult /= 10;
+               }
+       }
+
+       delay += mdelay;
+
        while (get_timer(start) < delay) {
                if (ctrlc())
                        return (-1);
@@ -36,7 +54,8 @@ U_BOOT_CMD(
        sleep ,    2,    1,     do_sleep,
        "delay execution for some time",
        "N\n"
-       "    - delay execution for N seconds (N is _decimal_ !!!)"
+       "    - delay execution for N seconds (N is _decimal_ and can be\n"
+       "      fractional)"
 );
 
 #ifdef CONFIG_CMD_TIMER
index 44b2c3a5a9fbfa55dd70505c126cc142f85de49c..b9b160dc1e2f7f8e1de776d11b2423626cb1330d 100644 (file)
@@ -109,17 +109,17 @@ DECLARE_GLOBAL_DATA_PTR;
 #define MTD_WRITEABLE_CMD              1
 
 /* default values for mtdids and mtdparts variables */
-#if defined(MTDIDS_DEFAULT)
-static const char *const mtdids_default = MTDIDS_DEFAULT;
-#else
-static const char *const mtdids_default = NULL;
+#if !defined(MTDIDS_DEFAULT)
+#define MTDIDS_DEFAULT NULL
 #endif
-
-#if defined(MTDPARTS_DEFAULT)
-static const char *const mtdparts_default = MTDPARTS_DEFAULT;
-#else
-static const char *const mtdparts_default = NULL;
+#if !defined(MTDPARTS_DEFAULT)
+#define MTDPARTS_DEFAULT NULL
+#endif
+#if defined(CONFIG_SYS_MTDPARTS_RUNTIME)
+extern void board_mtdparts_default(const char **mtdids, const char **mtdparts);
 #endif
+static const char *mtdids_default = MTDIDS_DEFAULT;
+static const char *mtdparts_default = MTDPARTS_DEFAULT;
 
 /* copies of last seen 'mtdids', 'mtdparts' and 'partition' env variables */
 #define MTDIDS_MAXLEN          128
@@ -142,6 +142,8 @@ static struct list_head devices;
 struct mtd_device *current_mtd_dev = NULL;
 u8 current_mtd_partnum = 0;
 
+u8 use_defaults;
+
 static struct part_info* mtd_part_info(struct mtd_device *dev, unsigned int part_num);
 
 /* command line only routines */
@@ -1491,7 +1493,7 @@ static int spread_partitions(void)
                        part = list_entry(pentry, struct part_info, link);
 
                        debug("spread_partitions: device = %s%d, partition %d ="
-                               " (%s) 0x%08x@0x%08x\n",
+                               " (%s) 0x%08llx@0x%08llx\n",
                                MTD_DEV_TYPE(dev->id->type), dev->id->num,
                                part_num, part->name, part->size,
                                part->offset);
@@ -1515,6 +1517,23 @@ static int spread_partitions(void)
 }
 #endif /* CONFIG_CMD_MTDPARTS_SPREAD */
 
+/**
+ * The mtdparts variable tends to be long. If we need to access it
+ * before the env is relocated, then we need to use our own stack
+ * buffer.  gd->env_buf will be too small.
+ *
+ * @param buf temporary buffer pointer MTDPARTS_MAXLEN long
+ * @return mtdparts variable string, NULL if not found
+ */
+static const char *getenv_mtdparts(char *buf)
+{
+       if (gd->flags & GD_FLG_ENV_READY)
+               return getenv("mtdparts");
+       if (getenv_f("mtdparts", buf, MTDPARTS_MAXLEN) != -1)
+               return buf;
+       return NULL;
+}
+
 /**
  * Accept character string describing mtd partitions and call device_parse()
  * for each entry. Add created devices to the global devices list.
@@ -1524,7 +1543,7 @@ static int spread_partitions(void)
  */
 static int parse_mtdparts(const char *const mtdparts)
 {
-       const char *p = mtdparts;
+       const char *p;
        struct mtd_device *dev;
        int err = 1;
        char tmp_parts[MTDPARTS_MAXLEN];
@@ -1538,12 +1557,9 @@ static int parse_mtdparts(const char *const mtdparts)
        }
 
        /* re-read 'mtdparts' variable, mtd_devices_init may be updating env */
-       if (gd->flags & GD_FLG_ENV_READY) {
-               p = getenv("mtdparts");
-       } else {
-               p = tmp_parts;
-               getenv_f("mtdparts", tmp_parts, MTDPARTS_MAXLEN);
-       }
+       p = getenv_mtdparts(tmp_parts);
+       if (!p)
+               p = mtdparts;
 
        if (strncmp(p, "mtdparts=", 9) != 0) {
                printf("mtdparts variable doesn't start with 'mtdparts='\n");
@@ -1551,7 +1567,7 @@ static int parse_mtdparts(const char *const mtdparts)
        }
        p += 9;
 
-       while (p && (*p != '\0')) {
+       while (*p != '\0') {
                err = 1;
                if ((device_parse(p, &p, &dev) != 0) || (!dev))
                        break;
@@ -1569,12 +1585,10 @@ static int parse_mtdparts(const char *const mtdparts)
                list_add_tail(&dev->link, &devices);
                err = 0;
        }
-       if (err == 1) {
+       if (err == 1)
                device_delall(&devices);
-               return 1;
-       }
 
-       return 0;
+       return err;
 }
 
 /**
@@ -1688,6 +1702,7 @@ static int parse_mtdids(const char *const ids)
        return 0;
 }
 
+
 /**
  * Parse and initialize global mtdids mapping and create global
  * device/partition list.
@@ -1710,22 +1725,16 @@ int mtdparts_init(void)
                memset(last_ids, 0, MTDIDS_MAXLEN);
                memset(last_parts, 0, MTDPARTS_MAXLEN);
                memset(last_partition, 0, PARTITION_MAXLEN);
+#if defined(CONFIG_SYS_MTDPARTS_RUNTIME)
+               board_mtdparts_default(&mtdids_default, &mtdparts_default);
+#endif
+               use_defaults = 1;
                initialized = 1;
        }
 
        /* get variables */
        ids = getenv("mtdids");
-       /*
-        * The mtdparts variable tends to be long. If we need to access it
-        * before the env is relocated, then we need to use our own stack
-        * buffer.  gd->env_buf will be too small.
-        */
-       if (gd->flags & GD_FLG_ENV_READY) {
-               parts = getenv("mtdparts");
-       } else {
-               parts = tmp_parts;
-               getenv_f("mtdparts", tmp_parts, MTDPARTS_MAXLEN);
-       }
+       parts = getenv_mtdparts(tmp_parts);
        current_partition = getenv("partition");
 
        /* save it for later parsing, cannot rely on current partition pointer
@@ -1758,10 +1767,16 @@ int mtdparts_init(void)
                return 1;
        }
 
-       /* do no try to use defaults when mtdparts variable is not defined,
-        * just check the length */
-       if (!parts)
-               printf("mtdparts variable not set, see 'help mtdparts'\n");
+       /* use defaults when mtdparts variable is not defined
+        * once mtdparts is saved environment, drop use_defaults flag */
+       if (!parts) {
+               if (mtdparts_default && use_defaults) {
+                       parts = mtdparts_default;
+                       if (setenv("mtdparts", (char *)parts) == 0)
+                               use_defaults = 0;
+               } else
+                       printf("mtdparts variable not set, see 'help mtdparts'\n");
+       }
 
        if (parts && (strlen(parts) > MTDPARTS_MAXLEN - 1)) {
                printf("mtdparts too long (> %d)\n", MTDPARTS_MAXLEN);
@@ -1933,9 +1948,10 @@ static int do_mtdparts(cmd_tbl_t *cmdtp, int flag, int argc,
 {
        if (argc == 2) {
                if (strcmp(argv[1], "default") == 0) {
-                       setenv("mtdids", (char *)mtdids_default);
-                       setenv("mtdparts", (char *)mtdparts_default);
+                       setenv("mtdids", NULL);
+                       setenv("mtdparts", NULL);
                        setenv("partition", NULL);
+                       use_defaults = 1;
 
                        mtdparts_init();
                        return 0;
@@ -2009,7 +2025,7 @@ static int do_mtdparts(cmd_tbl_t *cmdtp, int flag, int argc,
 
                if (!strcmp(&argv[1][3], ".spread")) {
                        spread_partition(mtd, p, &next_offset);
-                       debug("increased %s to %d bytes\n", p->name, p->size);
+                       debug("increased %s to %llu bytes\n", p->name, p->size);
                }
 #endif
 
index ffdeea41a5a7a7d4b61449e4bbd448a796508370..e10349ac2bed7bb4537635715b1dd684dbde44e1 100644 (file)
@@ -306,7 +306,7 @@ static void nand_print_and_set_info(int idx)
 }
 
 static int raw_access(struct mtd_info *mtd, ulong addr, loff_t off,
-                     ulong count, int read)
+                     ulong count, int read, int no_verify)
 {
        int ret = 0;
 
@@ -324,7 +324,7 @@ static int raw_access(struct mtd_info *mtd, ulong addr, loff_t off,
                        ret = mtd_read_oob(mtd, off, &ops);
                } else {
                        ret = mtd_write_oob(mtd, off, &ops);
-                       if (!ret)
+                       if (!ret && !no_verify)
                                ret = nand_verify_page_oob(mtd, &ops, off);
                }
 
@@ -546,6 +546,7 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
                ulong pagecount = 1;
                int read;
                int raw = 0;
+               int no_verify = 0;
 
                if (argc < 4)
                        goto usage;
@@ -557,9 +558,12 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 
                s = strchr(cmd, '.');
 
-               if (s && !strcmp(s, ".raw")) {
+               if (s && !strncmp(s, ".raw", 4)) {
                        raw = 1;
 
+                       if (!strcmp(s, ".raw.noverify"))
+                               no_verify = 1;
+
                        if (mtd_arg_off(argv[3], &dev, &off, &size, &maxsize,
                                        MTD_DEV_TYPE_NAND,
                                        nand_info[dev]->size))
@@ -633,7 +637,8 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
                        else
                                ret = mtd_write_oob(mtd, off, &ops);
                } else if (raw) {
-                       ret = raw_access(mtd, addr, off, pagecount, read);
+                       ret = raw_access(mtd, addr, off, pagecount, read,
+                                        no_verify);
                } else {
                        printf("Unknown nand command suffix '%s'.\n", s);
                        return 1;
@@ -786,7 +791,7 @@ static char nand_help_text[] =
        "    read/write 'size' bytes starting at offset 'off'\n"
        "    to/from memory address 'addr', skipping bad blocks.\n"
        "nand read.raw - addr off|partition [count]\n"
-       "nand write.raw - addr off|partition [count]\n"
+       "nand write.raw[.noverify] - addr off|partition [count]\n"
        "    Use read.raw/write.raw to avoid ECC and access the flash as-is.\n"
 #ifdef CONFIG_CMD_NAND_TRIMFFS
        "nand write.trimffs - addr off|partition size\n"
index 42862d9d921a9e0121169bb9c552a388cbf56fb8..286906c3a151c916d549df6938ad73a0273aec94 100644 (file)
--- 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
index 8adc821ae0b3572dac211cb3266c20a14337b05e..46e7173c7c90a00bebacfac7d6cc9edc9581efa4 100644 (file)
@@ -197,3 +197,9 @@ config CONSOLE_RECORD_IN_SIZE
          tstc() and getc() will use this in preference to real device input.
          The buffer is allocated immediately after the malloc() region is
          ready.
+
+config SYS_NO_FLASH
+       bool "Disable support for parallel NOR flash"
+       default n
+       help
+         This option is used to disable support for parallel NOR flash.
index d405b5b407e817677afcea7f626c44c2c9c16d23..c4501affd9da3b8a8e978ada308ceef4d335a5c5 100644 (file)
@@ -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
index 2431019b3f407d8eff683fa1cd8c5ce46a468cc4..9ed6428281b35c4c9e60d107e5188db1d982d706 100644 (file)
@@ -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 */
index 9ec84bd0dbe0349741b09b44010f3e4f75709be8..e3f5a4641207e41a387cbf941fb1d23afde0fdc0 100644 (file)
@@ -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);
index 13db7dc3f7553fc909618462a376b829e1a194c6..560cad02476404fdde6e4f0b4dff5f07a7ec22d1 100644 (file)
@@ -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.
  */
index 273098ceb605a6b2059dadc44d45f37c392b2c68..c53200f5c6fef36d0f7e8c248161b4dbffda0f8e 100644 (file)
@@ -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;
index c739651009b0f806b68bcc998f96d7fa3bd6a757..8d0524da78f39c5b829bc71813c7549007482ccb 100644 (file)
@@ -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");
index 6f920da2204348ce321f5d7def54a355b516727f..73ad34e491ba2fdeccaa3de11b6e4f8440bea122 100644 (file)
@@ -1684,12 +1684,13 @@ int fit_image_load(bootm_headers_t *images, ulong addr,
 
        bootstage_mark(bootstage_id + BOOTSTAGE_SUB_CHECK_ALL);
        type_ok = fit_image_check_type(fit, noffset, image_type) ||
-               (image_type == IH_TYPE_KERNEL &&
-                       fit_image_check_type(fit, noffset,
-                                            IH_TYPE_KERNEL_NOLOAD));
+                 fit_image_check_type(fit, noffset, IH_TYPE_FIRMWARE) ||
+                 (image_type == IH_TYPE_KERNEL &&
+                  fit_image_check_type(fit, noffset, IH_TYPE_KERNEL_NOLOAD));
 
        os_ok = image_type == IH_TYPE_FLATDT || IH_TYPE_FPGA ||
                fit_image_check_os(fit, noffset, IH_OS_LINUX) ||
+               fit_image_check_os(fit, noffset, IH_OS_U_BOOT) ||
                fit_image_check_os(fit, noffset, IH_OS_OPENRTOS);
 
        /*
index 0be09e5c6306df7973b3a45e00c6c891cef7ee26..af155b229b9dc2b5c5268732060860055d033a84 100644 (file)
@@ -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
index 2e0f695e46e2ea8cae1356b8247eaecf581d6588..b15f0f6dcdea51cc4ea456ec3a3fa983a9e6fd6d 100644 (file)
@@ -13,8 +13,11 @@ obj-$(CONFIG_SPL_FRAMEWORK) += spl.o
 obj-$(CONFIG_SPL_LOAD_FIT) += spl_fit.o
 obj-$(CONFIG_SPL_NOR_SUPPORT) += spl_nor.o
 obj-$(CONFIG_SPL_YMODEM_SUPPORT) += spl_ymodem.o
+ifndef CONFIG_SPL_UBI
 obj-$(CONFIG_SPL_NAND_SUPPORT) += spl_nand.o
 obj-$(CONFIG_SPL_ONENAND_SUPPORT) += spl_onenand.o
+endif
+obj-$(CONFIG_SPL_UBI) += spl_ubi.o
 obj-$(CONFIG_SPL_NET_SUPPORT) += spl_net.o
 obj-$(CONFIG_SPL_MMC_SUPPORT) += spl_mmc.o
 obj-$(CONFIG_SPL_USB_SUPPORT) += spl_usb.o
index 840910a6844425f04bcda3b4b280374369ae17d0..b7ec333c8a5fcf8081446803b01f0af6d2b2abf0 100644 (file)
@@ -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>
@@ -57,6 +56,15 @@ __weak int spl_start_uboot(void)
        puts("SPL: Direct Linux boot not active!\n");
        return 1;
 }
+
+/*
+ * Weak default function for arch specific zImage check. Return zero
+ * and fill start and end address if image is recognized.
+ */
+int __weak bootz_setup(ulong image, ulong *start, ulong *end)
+{
+        return 1;
+}
 #endif
 
 /*
@@ -125,6 +133,20 @@ int spl_parse_image_header(const struct image_header *header)
                /* Signature not found, proceed to other boot methods. */
                return -EINVAL;
 #else
+#ifdef CONFIG_SPL_OS_BOOT
+               ulong start, end;
+
+               if (!bootz_setup((ulong)header, &start, &end)) {
+                       spl_image.name = "Linux";
+                       spl_image.os = IH_OS_LINUX;
+                       spl_image.load_addr = CONFIG_SYS_LOAD_ADDR;
+                       spl_image.entry_point = CONFIG_SYS_LOAD_ADDR;
+                       spl_image.size = end - start;
+                       debug("spl: payload zImage, load addr: 0x%x size: %d\n",
+                             spl_image.load_addr, spl_image.size);
+                       return 0;
+               }
+#endif
                /* Signature not found - assume u-boot.bin */
                debug("mkimage signature not found - ih_magic = %x\n",
                        header->ih_magic);
@@ -203,7 +225,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 +233,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 +293,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
@@ -330,6 +353,11 @@ static int spl_load_image(u32 boot_device)
        case BOOT_DEVICE_MMC2_2:
                return spl_mmc_load_image(boot_device);
 #endif
+#ifdef CONFIG_SPL_UBI
+       case BOOT_DEVICE_NAND:
+       case BOOT_DEVICE_ONENAND:
+               return spl_ubi_load_image(boot_device);
+#else
 #ifdef CONFIG_SPL_NAND_SUPPORT
        case BOOT_DEVICE_NAND:
                return spl_nand_load_image();
@@ -338,6 +366,7 @@ static int spl_load_image(u32 boot_device)
        case BOOT_DEVICE_ONENAND:
                return spl_onenand_load_image();
 #endif
+#endif
 #ifdef CONFIG_SPL_NOR_SUPPORT
        case BOOT_DEVICE_NOR:
                return spl_nor_load_image();
@@ -346,7 +375,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
index db676186d354b7b07c1a96920f5ecd582f3adba3..73d33f54fc134b81c1169f97900102310d4729b6 100644 (file)
@@ -88,7 +88,8 @@ int spl_load_image_fat(struct blk_desc *block_dev,
                if (err)
                        goto end;
 
-               err = file_fat_read(filename, (u8 *)spl_image.load_addr, 0);
+               err = file_fat_read(filename,
+                                   (u8 *)(uintptr_t)spl_image.load_addr, 0);
        }
 
 end:
index 987470896c46d28c00561f5ce8f0b002862e353b..be86072c24e8138dc66be8be456d70ffe931ea4e 100644 (file)
@@ -115,8 +115,10 @@ static int get_aligned_image_overhead(struct spl_load_info *info, int offset)
 static int get_aligned_image_size(struct spl_load_info *info, int data_size,
                                  int offset)
 {
+       data_size = data_size + get_aligned_image_overhead(info, offset);
+
        if (info->filename)
-               return data_size + get_aligned_image_overhead(info, offset);
+               return data_size;
 
        return (data_size + info->bl_len - 1) / info->bl_len;
 }
@@ -132,7 +134,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 +208,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 +243,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;
 }
index c44f1b5dc84299639802e3a306f4a7ca3603ba68..6b3e9e4a17a0e6be63179c9a944fb98313d3d76e 100644 (file)
@@ -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/common/spl/spl_ubi.c b/common/spl/spl_ubi.c
new file mode 100644 (file)
index 0000000..f97e1ef
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2016
+ * Ladislav Michl <ladis@linux-mips.org>
+ *
+ * SPDX-License-Identifier: GPL 2.0+ BSD-3-Clause
+ */
+
+#include <common.h>
+#include <config.h>
+#include <nand.h>
+#include <onenand_uboot.h>
+#include <ubispl.h>
+#include <spl.h>
+
+int spl_ubi_load_image(u32 boot_device)
+{
+       struct image_header *header;
+       struct ubispl_info info;
+       struct ubispl_load volumes[2];
+       int ret = 1;
+
+       switch (boot_device) {
+#ifdef CONFIG_SPL_NAND_SUPPORT
+       case BOOT_DEVICE_NAND:
+               nand_init();
+               info.read = nand_spl_read_block;
+               info.peb_size = CONFIG_SYS_NAND_BLOCK_SIZE;
+               break;
+#endif
+#ifdef CONFIG_SPL_ONENAND_SUPPORT
+       case BOOT_DEVICE_ONENAND:
+               info.read = onenand_spl_read_block;
+               info.peb_size = CONFIG_SYS_ONENAND_BLOCK_SIZE;
+               break;
+#endif
+       default:
+               goto out;
+       }
+       info.ubi = (struct ubi_scan_info *)CONFIG_SPL_UBI_INFO_ADDR;
+       info.fastmap = 1;
+
+       info.peb_offset = CONFIG_SPL_UBI_PEB_OFFSET;
+       info.vid_offset = CONFIG_SPL_UBI_VID_OFFSET;
+       info.leb_start = CONFIG_SPL_UBI_LEB_START;
+       info.peb_count = CONFIG_SPL_UBI_MAX_PEBS - info.peb_offset;
+
+#ifdef CONFIG_SPL_OS_BOOT
+       if (!spl_start_uboot()) {
+               volumes[0].vol_id = CONFIG_SPL_UBI_LOAD_KERNEL_ID;
+               volumes[0].load_addr = (void *)CONFIG_SYS_LOAD_ADDR;
+               volumes[1].vol_id = CONFIG_SPL_UBI_LOAD_ARGS_ID;
+               volumes[1].load_addr = (void *)CONFIG_SYS_SPL_ARGS_ADDR;
+
+               ret = ubispl_load_volumes(&info, volumes, 2);
+               if (!ret) {
+                       header = (struct image_header *)volumes[0].load_addr;
+                       spl_parse_image_header(header);
+                       puts("Linux loaded.\n");
+                       goto out;
+               }
+               puts("Loading Linux failed, falling back to U-Boot.\n");
+       }
+#endif
+       header = (struct image_header *)
+               (CONFIG_SYS_TEXT_BASE - sizeof(struct image_header));
+       volumes[0].vol_id = CONFIG_SPL_UBI_LOAD_MONITOR_ID;
+       volumes[0].load_addr = (void *)header;
+
+       ret = ubispl_load_volumes(&info, volumes, 1);
+       if (!ret)
+               spl_parse_image_header(header);
+out:
+#ifdef CONFIG_SPL_NAND_SUPPORT
+       if (boot_device == BOOT_DEVICE_NAND)
+               nand_deselect();
+#endif
+       return ret;
+}
diff --git a/configs/T1042RDB_PI_NAND_SECURE_BOOT_defconfig b/configs/T1042RDB_PI_NAND_SECURE_BOOT_defconfig
new file mode 100644 (file)
index 0000000..2e16255
--- /dev/null
@@ -0,0 +1,30 @@
+CONFIG_PPC=y
+CONFIG_MPC85xx=y
+CONFIG_TARGET_T104XRDB=y
+CONFIG_SPL=y
+CONFIG_FIT=y
+CONFIG_FIT_VERBOSE=y
+CONFIG_OF_BOARD_SETUP=y
+CONFIG_OF_STDOUT_VIA_ALIAS=y
+CONFIG_SYS_EXTRA_OPTIONS="PPC_T1042,T1042RDB_PI,RAMBOOT_PBL,SPL_FSL_PBL,NAND,SECURE_BOOT"
+CONFIG_BOOTDELAY=0
+CONFIG_HUSH_PARSER=y
+CONFIG_CMD_GREPENV=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_SF=y
+CONFIG_CMD_I2C=y
+CONFIG_CMD_USB=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
+CONFIG_CMD_EXT2=y
+CONFIG_CMD_FAT=y
+CONFIG_SPI_FLASH=y
+CONFIG_SPI_FLASH_STMICRO=y
+CONFIG_NETDEVICES=y
+CONFIG_E1000=y
+CONFIG_SYS_NS16550=y
+CONFIG_FSL_ESPI=y
+CONFIG_OF_LIBFDT=y
+CONFIG_RSA=y
+CONFIG_DM=y
index 903f5180706ceb563f7c00023012869142bf6666..c2f09cb289fd9fb1fa297753d4aba1e017e1b398 100644 (file)
@@ -49,3 +49,4 @@ CONFIG_USB_GADGET_DOWNLOAD=y
 CONFIG_G_DNL_MANUFACTURER="Texas Instruments"
 CONFIG_G_DNL_VENDOR_NUM=0x0451
 CONFIG_G_DNL_PRODUCT_NUM=0xd022
+CONFIG_DM_I2C=y
index 696024c451f5cbf37f30e09faed9540fe3f20336..68852309d24db250b992c802e1300c13aac5f045 100644 (file)
@@ -49,3 +49,4 @@ CONFIG_FIT=y
 CONFIG_SPL_OF_LIBFDT=y
 CONFIG_SPL_LOAD_FIT=y
 CONFIG_OF_LIST="am335x-evm am335x-bone am335x-boneblack am335x-evmsk am335x-bonegreen am335x-icev2"
+CONFIG_DM_I2C=y
index cb3de11808a6b85921bedcf8c9f74b448290f780..0eab4add438d3383ae0b4c79e027933d23aeb6fc 100644 (file)
@@ -54,3 +54,4 @@ CONFIG_G_DNL_MANUFACTURER="Texas Instruments"
 CONFIG_G_DNL_VENDOR_NUM=0x0403
 CONFIG_G_DNL_PRODUCT_NUM=0xbd00
 CONFIG_SPL_OF_LIBFDT=y
+CONFIG_DM_I2C=y
index 4856a19f0b0bb284cda090e210348ade41618f33..c8ce72348ee76ef100e593f89a02c883291cfbbb 100644 (file)
@@ -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
@@ -57,3 +58,4 @@ CONFIG_G_DNL_MANUFACTURER="Texas Instruments"
 CONFIG_G_DNL_VENDOR_NUM=0x0403
 CONFIG_G_DNL_PRODUCT_NUM=0xbd00
 CONFIG_SPL_OF_LIBFDT=y
+CONFIG_DM_I2C=y
index c29a05a229bd2f97f432406ffc061ce3eef63856..8a8a4c9090b05f63272453cf2ca9027423060a70 100644 (file)
@@ -40,3 +40,4 @@ CONFIG_FIT=y
 CONFIG_SPL_OF_LIBFDT=y
 CONFIG_SPL_LOAD_FIT=y
 CONFIG_OF_LIST="am57xx-beagle-x15 am572x-idk"
+CONFIG_DM_I2C=y
index e01e50482a6142b3989c94cc14b4d10d46b15fe3..2ccb332ae776a2d35af822a4e2f79bbd4644a89e 100644 (file)
@@ -40,4 +40,6 @@ 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"
+CONFIG_DM_I2C=y
index 9f1d7fbca9f0553525fcc7b957efe6f615086e87..0a71bb8d08b32ddb3d53b0444ce09c268f276ee5 100644 (file)
@@ -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
index d5bc5153b1b1e0dff1f3349124eb3f6d565768f4..fd5314aae1fc9c5cc2319088fed0d321c9822f0b 100644 (file)
@@ -53,7 +53,7 @@ CONFIG_ROCKCHIP_DWMMC=y
 CONFIG_PINCTRL=y
 CONFIG_SPL_PINCTRL=y
 # CONFIG_SPL_PINCTRL_FULL is not set
-CONFIG_ROCKCHIP_PINCTRL=y
+CONFIG_ROCKCHIP_RK3288_PINCTRL=y
 CONFIG_DM_PMIC=y
 # CONFIG_SPL_PMIC_CHILDREN is not set
 CONFIG_PMIC_RK808=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 (file)
index 0000000..26f83ba
--- /dev/null
@@ -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
index 0e281a5e672c4ad10beeb005e8685c52da57158d..40ab975f02b9064ec8bd8de54230ad49c080e13f 100644 (file)
@@ -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
index 756af63c1faa3265ebb48be3bc99d95139600946..1d27e52ac38b11479101c07c597a2ae0d11949ba 100644 (file)
@@ -57,3 +57,4 @@ CONFIG_FIT=y
 CONFIG_SPL_OF_LIBFDT=y
 CONFIG_SPL_LOAD_FIT=y
 CONFIG_OF_LIST="dra7-evm dra72-evm"
+CONFIG_DM_I2C=y
index 6933ab5cc6f2c8838b0d208fb989497b4fd762c2..faf9cd57e47431433411dc8e839b6370613fe3f0 100644 (file)
@@ -58,4 +58,6 @@ 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"
+CONFIG_DM_I2C=y
index 37c5ea7761c964eed6d2e2f1c0f3e52d9751a97a..ad2e8b86900ec2633843585c6248e8b336fc24a6 100644 (file)
@@ -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
index 9894fffcca200cfa8151f4a6fba82daffc355ea2..2d5e5e053ffff191caba3c18982d31aa9ceca740 100644 (file)
@@ -32,7 +32,7 @@ CONFIG_SYSRESET=y
 CONFIG_DM_MMC=y
 CONFIG_ROCKCHIP_DWMMC=y
 CONFIG_PINCTRL=y
-CONFIG_ROCKCHIP_3036_PINCTRL=y
+CONFIG_ROCKCHIP_RK3036_PINCTRL=y
 CONFIG_RAM=y
 # CONFIG_SPL_SERIAL_PRESENT is not set
 CONFIG_DEBUG_UART=y
diff --git a/configs/evb-rk3288_defconfig b/configs/evb-rk3288_defconfig
new file mode 100644 (file)
index 0000000..41cfedd
--- /dev/null
@@ -0,0 +1,67 @@
+CONFIG_ARM=y
+CONFIG_ARCH_ROCKCHIP=y
+CONFIG_SYS_MALLOC_F_LEN=0x2000
+CONFIG_ROCKCHIP_RK3288=y
+CONFIG_TARGET_EVB_RK3288=y
+CONFIG_SPL_STACK_R_ADDR=0x80000
+CONFIG_DEFAULT_DEVICE_TREE="rk3288-evb"
+CONFIG_SPL_STACK_R=y
+CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x2000
+CONFIG_HUSH_PARSER=y
+CONFIG_CMD_BOOTZ=y
+# CONFIG_CMD_IMLS is not set
+CONFIG_CMD_MMC=y
+CONFIG_CMD_SF=y
+CONFIG_CMD_SPI=y
+CONFIG_CMD_I2C=y
+CONFIG_CMD_GPIO=y
+# CONFIG_CMD_SETEXPR is not set
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
+CONFIG_CMD_CACHE=y
+CONFIG_CMD_TIME=y
+CONFIG_CMD_PMIC=y
+CONFIG_CMD_REGULATOR=y
+CONFIG_CMD_EXT2=y
+CONFIG_CMD_EXT4=y
+CONFIG_CMD_FAT=y
+CONFIG_CMD_FS_GENERIC=y
+CONFIG_SPL_OF_CONTROL=y
+CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names clock-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents"
+CONFIG_REGMAP=y
+CONFIG_SPL_REGMAP=y
+CONFIG_SYSCON=y
+CONFIG_SPL_SYSCON=y
+CONFIG_CLK=y
+CONFIG_SPL_CLK=y
+CONFIG_ROCKCHIP_GPIO=y
+CONFIG_SYS_I2C_ROCKCHIP=y
+CONFIG_LED=y
+CONFIG_LED_GPIO=y
+CONFIG_SYSRESET=y
+CONFIG_DM_MMC=y
+CONFIG_ROCKCHIP_DWMMC=y
+CONFIG_PINCTRL=y
+# CONFIG_PINCTRL_FULL is not set
+CONFIG_SPL_PINCTRL=y
+# CONFIG_SPL_PINCTRL_FULL is not set
+CONFIG_ROCKCHIP_PINCTRL=y
+CONFIG_DM_PMIC=y
+CONFIG_PMIC_ACT8846=y
+CONFIG_DM_REGULATOR=y
+CONFIG_REGULATOR_ACT8846=y
+CONFIG_DM_REGULATOR_FIXED=y
+CONFIG_DM_PWM=y
+CONFIG_PWM_ROCKCHIP=y
+CONFIG_RAM=y
+CONFIG_SPL_RAM=y
+CONFIG_DEBUG_UART=y
+CONFIG_DEBUG_UART_BASE=0xff690000
+CONFIG_DEBUG_UART_CLOCK=24000000
+CONFIG_DEBUG_UART_SHIFT=2
+CONFIG_SYS_NS16550=y
+CONFIG_USE_PRIVATE_LIBGCC=y
+CONFIG_USE_TINY_PRINTF=y
+CONFIG_CMD_DHRYSTONE=y
+CONFIG_ERRNO_STR=y
diff --git a/configs/evb-rk3399_defconfig b/configs/evb-rk3399_defconfig
new file mode 100644 (file)
index 0000000..3f9b47e
--- /dev/null
@@ -0,0 +1,33 @@
+CONFIG_ARM=y
+CONFIG_ARCH_ROCKCHIP=y
+CONFIG_ROCKCHIP_RK3399=y
+CONFIG_TARGET_EVB_RK3399=y
+CONFIG_DEFAULT_DEVICE_TREE="rk3399-evb"
+CONFIG_HUSH_PARSER=y
+CONFIG_CMD_BOOTZ=y
+# CONFIG_CMD_IMLS is not set
+CONFIG_CMD_MMC=y
+CONFIG_CMD_SF=y
+# CONFIG_CMD_SETEXPR is not set
+CONFIG_CMD_TIME=y
+CONFIG_CMD_GPT=y
+CONFIG_CMD_EXT2=y
+CONFIG_CMD_EXT4=y
+CONFIG_CMD_FAT=y
+CONFIG_CMD_FS_GENERIC=y
+CONFIG_REGMAP=y
+CONFIG_SYSCON=y
+CONFIG_CLK=y
+CONFIG_FIT=y
+CONFIG_SYSRESET=y
+CONFIG_DM_MMC=y
+CONFIG_ROCKCHIP_SDHCI=y
+CONFIG_PINCTRL=y
+CONFIG_RAM=y
+CONFIG_SYS_NS16550=y
+CONFIG_DEBUG_UART=y
+CONFIG_DEBUG_UART_BASE=0xFF1A0000
+CONFIG_DEBUG_UART_CLOCK=24000000
+CONFIG_DEBUG_UART_SHIFT=2
+CONFIG_USE_TINY_PRINTF=y
+CONFIG_ERRNO_STR=y
index 4af91206dcf7f63982cd547d83e424d69b513b51..4122000489a93b5c64bc5795192769b8b7cba78f 100644 (file)
@@ -46,7 +46,7 @@ CONFIG_ROCKCHIP_DWMMC=y
 CONFIG_PINCTRL=y
 CONFIG_SPL_PINCTRL=y
 # CONFIG_SPL_PINCTRL_FULL is not set
-CONFIG_ROCKCHIP_PINCTRL=y
+CONFIG_ROCKCHIP_RK3288_PINCTRL=y
 CONFIG_DM_PMIC=y
 # CONFIG_SPL_PMIC_CHILDREN is not set
 CONFIG_PMIC_ACT8846=y
@@ -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
index 66dd93f0054daaf7c87aa699de776b202e739183..649dd47f3b5349436cecccac3071c015b25adb54 100644 (file)
@@ -2,7 +2,8 @@ CONFIG_ARM=y
 CONFIG_OMAP34XX=y
 CONFIG_TARGET_OMAP3_IGEP00X0=y
 CONFIG_SPL=y
-CONFIG_SYS_EXTRA_OPTIONS="MACH_TYPE=MACH_TYPE_IGEP0020,BOOT_ONENAND"
+CONFIG_SYS_EXTRA_OPTIONS="MACH_TYPE=MACH_TYPE_IGEP0020"
+CONFIG_BOOTDELAY=3
 CONFIG_HUSH_PARSER=y
 CONFIG_CMD_BOOTZ=y
 # CONFIG_CMD_IMLS is not set
@@ -24,4 +25,5 @@ CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
 CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_SYS_NS16550=y
+CONFIG_USE_TINY_PRINTF=y
 CONFIG_OF_LIBFDT=y
diff --git a/configs/igep0020_nand_defconfig b/configs/igep0020_nand_defconfig
deleted file mode 100644 (file)
index 7535d10..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-CONFIG_ARM=y
-CONFIG_OMAP34XX=y
-CONFIG_TARGET_OMAP3_IGEP00X0=y
-CONFIG_SPL=y
-CONFIG_SYS_EXTRA_OPTIONS="MACH_TYPE=MACH_TYPE_IGEP0020,BOOT_NAND"
-CONFIG_HUSH_PARSER=y
-CONFIG_CMD_BOOTZ=y
-# CONFIG_CMD_IMLS is not set
-CONFIG_CMD_ASKENV=y
-# CONFIG_CMD_FLASH is not set
-CONFIG_CMD_MMC=y
-CONFIG_CMD_SPI=y
-CONFIG_CMD_I2C=y
-CONFIG_CMD_GPIO=y
-# CONFIG_CMD_SETEXPR is not set
-CONFIG_CMD_DHCP=y
-CONFIG_CMD_MII=y
-CONFIG_CMD_PING=y
-CONFIG_CMD_CACHE=y
-CONFIG_CMD_EXT2=y
-CONFIG_CMD_EXT4=y
-CONFIG_CMD_EXT4_WRITE=y
-CONFIG_CMD_FAT=y
-CONFIG_CMD_FS_GENERIC=y
-CONFIG_NET_RANDOM_ETHADDR=y
-CONFIG_SYS_NS16550=y
-CONFIG_OF_LIBFDT=y
index 9fcdfe9b9fa75d444fe04996cde4d5bf39fa1399..65561b1393eed21cd3f65135f94030ba37dc0725 100644 (file)
@@ -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
index 8efa58c8c43af3a52240e74688d2ff949f7dbe1c..5d44e8deb3d1c59a043ed317f75521ea2557e95a 100644 (file)
@@ -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
index 278eaf32fd8de26c59b646782edc0b26c80fcf87..8623e1ca88d5d87ce7fcbe4986da4b9da73b1252 100644 (file)
@@ -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
index 8417e0ab0758703038c172f4840e8fa92469d4db..9aa429cf5fc0a8c68e75564431299869edb6e692 100644 (file)
@@ -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
index 0ff6c6b9a4aca58fb09752b6720bd7c335df0da6..51196aa0897f1a3e1364286f76422a017a2e4bde 100644 (file)
@@ -32,7 +32,7 @@ CONFIG_SYSRESET=y
 CONFIG_DM_MMC=y
 CONFIG_ROCKCHIP_DWMMC=y
 CONFIG_PINCTRL=y
-CONFIG_ROCKCHIP_3036_PINCTRL=y
+CONFIG_ROCKCHIP_RK3036_PINCTRL=y
 CONFIG_RAM=y
 CONFIG_USE_PRIVATE_LIBGCC=y
 CONFIG_CMD_DHRYSTONE=y
diff --git a/configs/ls1021atwr_sdcard_ifc_SECURE_BOOT_defconfig b/configs/ls1021atwr_sdcard_ifc_SECURE_BOOT_defconfig
new file mode 100644 (file)
index 0000000..c735d6d
--- /dev/null
@@ -0,0 +1,31 @@
+CONFIG_ARM=y
+CONFIG_TARGET_LS1021ATWR=y
+CONFIG_SPL=y
+CONFIG_OF_BOARD_SETUP=y
+CONFIG_OF_STDOUT_VIA_ALIAS=y
+CONFIG_SYS_EXTRA_OPTIONS="RAMBOOT_PBL,SPL_FSL_PBL,SD_BOOT,SECURE_BOOT"
+CONFIG_BOOTDELAY=0
+CONFIG_HUSH_PARSER=y
+CONFIG_CMD_BOOTZ=y
+CONFIG_CMD_GREPENV=y
+CONFIG_CMD_MEMTEST=y
+CONFIG_CMD_MEMINFO=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_I2C=y
+CONFIG_CMD_USB=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
+CONFIG_CMD_EXT2=y
+CONFIG_CMD_FAT=y
+CONFIG_NETDEVICES=y
+CONFIG_E1000=y
+CONFIG_SYS_NS16550=y
+CONFIG_USB=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_XHCI_DWC3=y
+CONFIG_OF_LIBFDT=y
+CONFIG_FIT=y
+CONFIG_FIT_VERBOSE=y
+CONFIG_RSA=y
+CONFIG_DM=y
index 28b837daabc2c81e7efdea1230ef227069e5674d..ba2b7dc43dbb03a122cb6827498100cee78e1894 100644 (file)
@@ -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 (file)
index 0000000..417e4f6
--- /dev/null
@@ -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
index 7eaa795b32e44d93f340b7ae07c6aa6c78dff2cd..366fa08af45a516f5b248baa0dfd5fb300c140e9 100644 (file)
@@ -4,6 +4,7 @@ CONFIG_MACH_SUN8I_H3=y
 CONFIG_DRAM_CLK=624
 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-pc"
 # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
diff --git a/configs/orangepi_pc_plus_defconfig b/configs/orangepi_pc_plus_defconfig
new file mode 100644 (file)
index 0000000..c78aec3
--- /dev/null
@@ -0,0 +1,17 @@
+CONFIG_ARM=y
+CONFIG_ARCH_SUNXI=y
+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-plus"
+# 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_SY8106A_POWER=y
+CONFIG_USB_EHCI_HCD=y
diff --git a/configs/p2771-0000-a02_defconfig b/configs/p2771-0000-a02_defconfig
new file mode 100644 (file)
index 0000000..1fe25f5
--- /dev/null
@@ -0,0 +1,31 @@
+CONFIG_ARM=y
+CONFIG_TEGRA=y
+CONFIG_TEGRA186=y
+CONFIG_TARGET_P2771_0000=y
+CONFIG_DEFAULT_DEVICE_TREE="tegra186-p2771-0000-a02"
+CONFIG_OF_SYSTEM_SETUP=y
+CONFIG_HUSH_PARSER=y
+CONFIG_SYS_PROMPT="Tegra186 (P2771-0000 A02) # "
+# CONFIG_CMD_IMI is not set
+# 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_I2C=y
+CONFIG_CMD_USB=y
+# CONFIG_CMD_FPGA is not set
+CONFIG_CMD_GPIO=y
+# CONFIG_CMD_SETEXPR is not set
+CONFIG_CMD_DHCP=y
+# CONFIG_CMD_NFS is not set
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
+CONFIG_CMD_EXT2=y
+CONFIG_CMD_EXT4=y
+CONFIG_CMD_EXT4_WRITE=y
+CONFIG_CMD_FAT=y
+CONFIG_CMD_FS_GENERIC=y
+CONFIG_SYS_NS16550=y
+CONFIG_USB=y
+CONFIG_DM_USB=y
diff --git a/configs/p2771-0000-b00_defconfig b/configs/p2771-0000-b00_defconfig
new file mode 100644 (file)
index 0000000..552fb6c
--- /dev/null
@@ -0,0 +1,31 @@
+CONFIG_ARM=y
+CONFIG_TEGRA=y
+CONFIG_TEGRA186=y
+CONFIG_TARGET_P2771_0000=y
+CONFIG_DEFAULT_DEVICE_TREE="tegra186-p2771-0000-b00"
+CONFIG_OF_SYSTEM_SETUP=y
+CONFIG_HUSH_PARSER=y
+CONFIG_SYS_PROMPT="Tegra186 (P2771-0000 B00) # "
+# CONFIG_CMD_IMI is not set
+# 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_I2C=y
+CONFIG_CMD_USB=y
+# CONFIG_CMD_FPGA is not set
+CONFIG_CMD_GPIO=y
+# CONFIG_CMD_SETEXPR is not set
+CONFIG_CMD_DHCP=y
+# CONFIG_CMD_NFS is not set
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
+CONFIG_CMD_EXT2=y
+CONFIG_CMD_EXT4=y
+CONFIG_CMD_EXT4_WRITE=y
+CONFIG_CMD_FAT=y
+CONFIG_CMD_FS_GENERIC=y
+CONFIG_SYS_NS16550=y
+CONFIG_USB=y
+CONFIG_DM_USB=y
diff --git a/configs/p2771-0000_defconfig b/configs/p2771-0000_defconfig
deleted file mode 100644 (file)
index 9f2c418..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-CONFIG_ARM=y
-CONFIG_TEGRA=y
-CONFIG_TEGRA186=y
-CONFIG_TARGET_P2771_0000=y
-CONFIG_DEFAULT_DEVICE_TREE="tegra186-p2771-0000"
-CONFIG_OF_SYSTEM_SETUP=y
-CONFIG_HUSH_PARSER=y
-CONFIG_SYS_PROMPT="Tegra186 (P2771-0000) # "
-# CONFIG_CMD_IMI is not set
-# 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_I2C=y
-CONFIG_CMD_USB=y
-# CONFIG_CMD_FPGA is not set
-CONFIG_CMD_GPIO=y
-# CONFIG_CMD_SETEXPR is not set
-CONFIG_CMD_DHCP=y
-# CONFIG_CMD_NFS is not set
-CONFIG_CMD_MII=y
-CONFIG_CMD_PING=y
-CONFIG_CMD_EXT2=y
-CONFIG_CMD_EXT4=y
-CONFIG_CMD_EXT4_WRITE=y
-CONFIG_CMD_FAT=y
-CONFIG_CMD_FS_GENERIC=y
-CONFIG_SYS_NS16550=y
-CONFIG_USB=y
-CONFIG_DM_USB=y
index 3e16b805caa8bea021465e7ea55fd527ba14f041..3b6d7d95e651ad010eb446d18299006deca15eb2 100644 (file)
@@ -44,7 +44,7 @@ CONFIG_ROCKCHIP_DWMMC=y
 CONFIG_PINCTRL=y
 CONFIG_SPL_PINCTRL=y
 # CONFIG_SPL_PINCTRL_FULL is not set
-CONFIG_ROCKCHIP_PINCTRL=y
+CONFIG_ROCKCHIP_RK3288_PINCTRL=y
 CONFIG_DM_PMIC=y
 # CONFIG_SPL_PMIC_CHILDREN is not set
 CONFIG_PMIC_ACT8846=y
index 94253a65e4f9667edaa10dc283b6e763bffa5b07..29e6d85bd4c44de25f5dcb4e41782b8ab142ad35 100644 (file)
@@ -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,8 @@ CONFIG_CROS_EC_SPI=y
 CONFIG_PWRSEQ=y
 CONFIG_SPL_PWRSEQ=y
 CONFIG_SYSRESET=y
-CONFIG_DM_MMC=y
+CONFIG_I2C_EEPROM=y
+CONFIG_DM_MMC_OPS=y
 CONFIG_SANDBOX_MMC=y
 CONFIG_SPI_FLASH_SANDBOX=y
 CONFIG_SPI_FLASH=y
@@ -119,8 +120,8 @@ 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_ROCKCHIP_RK3288_PINCTRL=y
+CONFIG_ROCKCHIP_RK3036_PINCTRL=y
 CONFIG_PINCTRL_SANDBOX=y
 CONFIG_DM_PMIC=y
 CONFIG_PMIC_ACT8846=y
index 60c73398db4cdc326ae1c8c9ed718657b84081b7..503845bb0075a2d73d9909d12f4379bf123c94a7 100644 (file)
@@ -112,8 +112,8 @@ 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_ROCKCHIP_RK3288_PINCTRL=y
+CONFIG_ROCKCHIP_RK3036_PINCTRL=y
 CONFIG_PINCTRL_SANDBOX=y
 CONFIG_DM_PMIC=y
 CONFIG_PMIC_ACT8846=y
diff --git a/configs/sandbox_spl_defconfig b/configs/sandbox_spl_defconfig
new file mode 100644 (file)
index 0000000..0f6dda8
--- /dev/null
@@ -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 (file)
index 0000000..30e093b
--- /dev/null
@@ -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
index 4a8655f9bb513d5b04c35c8682f17f9041ada37e..28797f98f19380e3c1e4ff55ebc5a53d941184fc 100644 (file)
@@ -2,7 +2,6 @@ CONFIG_ARM=y
 CONFIG_TARGET_THUNDERX_88XX=y
 CONFIG_DM_SERIAL=y
 CONFIG_DEFAULT_DEVICE_TREE="thunderx-88xx"
-CONFIG_SYS_EXTRA_OPTIONS="ARM64"
 CONFIG_BOOTDELAY=5
 CONFIG_HUSH_PARSER=y
 CONFIG_SYS_PROMPT="ThunderX_88XX> "
index ffcac79762a02b482f54c6bb8b2ee011e6caddd7..57b9c07c77b0de998c807ac729caf27522c47014 100644 (file)
@@ -21,6 +21,8 @@ CONFIG_CMD_FAT=y
 CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_SPL_OF_TRANSLATE=y
 CONFIG_GPIO_UNIPHIER=y
+CONFIG_MISC=y
+CONFIG_I2C_EEPROM=y
 CONFIG_PINCTRL=y
 CONFIG_SPL_PINCTRL=y
 CONFIG_UNIPHIER_SERIAL=y
index cbc65ddc8d146ca978271bc8f0a7fffde7e27a9a..e6aa525ca5baf1a8d60cd9077686aa840b7711a5 100644 (file)
@@ -21,6 +21,8 @@ CONFIG_CMD_FAT=y
 CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_SPL_OF_TRANSLATE=y
 CONFIG_GPIO_UNIPHIER=y
+CONFIG_MISC=y
+CONFIG_I2C_EEPROM=y
 CONFIG_MMC_UNIPHIER=y
 CONFIG_PINCTRL=y
 CONFIG_SPL_PINCTRL=y
index 22615a647cc61b56ca0d356de544538aa017e041..47b577af7c9459ff691a5fdd16feabf64de8226a 100644 (file)
@@ -22,6 +22,8 @@ CONFIG_CMD_TIME=y
 CONFIG_CMD_FAT=y
 CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_GPIO_UNIPHIER=y
+CONFIG_MISC=y
+CONFIG_I2C_EEPROM=y
 CONFIG_MMC_UNIPHIER=y
 CONFIG_NAND_DENALI=y
 CONFIG_SYS_NAND_DENALI_64BIT=y
index 18f4caf33b51601b7931945f613368a06a5934f5..e156ec533adad663261063375ad40d3f6f70f89f 100644 (file)
@@ -21,6 +21,8 @@ CONFIG_CMD_TIME=y
 CONFIG_CMD_FAT=y
 CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_GPIO_UNIPHIER=y
+CONFIG_MISC=y
+CONFIG_I2C_EEPROM=y
 CONFIG_MMC_UNIPHIER=y
 CONFIG_NAND_DENALI=y
 CONFIG_SYS_NAND_DENALI_64BIT=y
index cf6d3e423106113b29b4eb7487de05061a9f96de..f943516a90bc59fbbeeba461db86639cd7399f6f 100644 (file)
@@ -22,6 +22,8 @@ CONFIG_CMD_TIME=y
 CONFIG_CMD_FAT=y
 CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_GPIO_UNIPHIER=y
+CONFIG_MISC=y
+CONFIG_I2C_EEPROM=y
 CONFIG_MMC_UNIPHIER=y
 CONFIG_NAND_DENALI=y
 CONFIG_SYS_NAND_DENALI_64BIT=y
index 0965019318a86d81260cab6a9c5a355cc986f0c3..598cde21063d88998c9e12f62ece45571d77c712 100644 (file)
@@ -21,6 +21,8 @@ CONFIG_CMD_TIME=y
 CONFIG_CMD_FAT=y
 CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_GPIO_UNIPHIER=y
+CONFIG_MISC=y
+CONFIG_I2C_EEPROM=y
 CONFIG_MMC_UNIPHIER=y
 CONFIG_NAND_DENALI=y
 CONFIG_SYS_NAND_DENALI_64BIT=y
index 7325f190f0bd16bee66511ba91c6fcb3348432eb..79f3adc1dc3b27ac21ce432835272905dc5dc90d 100644 (file)
@@ -2,15 +2,17 @@ CONFIG_ARM=y
 CONFIG_SYS_CONFIG_NAME="xilinx_zynqmp_ep"
 CONFIG_ARCH_ZYNQMP=y
 CONFIG_SYS_MALLOC_F_LEN=0x8000
+CONFIG_SPL_SYS_MALLOC_SIMPLE=y
+CONFIG_SPL_DM=y
 CONFIG_DM_I2C=y
 CONFIG_DM_GPIO=y
 CONFIG_ZYNQMP_USB=y
 CONFIG_SYS_TEXT_BASE=0x8000000
 CONFIG_DEFAULT_DEVICE_TREE="zynqmp-ep108"
+CONFIG_SPL=y
 CONFIG_FIT=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_SPL_LOAD_FIT=y
-CONFIG_BOOTDELAY=3
 CONFIG_HUSH_PARSER=y
 CONFIG_SYS_PROMPT="ZynqMP> "
 # CONFIG_CMD_CONSOLE is not set
@@ -41,10 +43,10 @@ CONFIG_CMD_EXT4=y
 CONFIG_CMD_EXT4_WRITE=y
 CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
+CONFIG_SPL_OF_CONTROL=y
 CONFIG_OF_EMBED=y
 CONFIG_NET_RANDOM_ETHADDR=y
-CONFIG_CLK=y
-CONFIG_SPL_CLK=y
+CONFIG_SPL_DM_SEQ_ALIAS=y
 CONFIG_SYS_I2C_CADENCE=y
 CONFIG_DM_MMC=y
 CONFIG_ZYNQ_SDHCI=y
index 91af8ce3267021303ed1340d6fd5b619fb625868..51637fc96001284a24b6e87c1f4b857bd21d2213 100644 (file)
@@ -2,15 +2,17 @@ CONFIG_ARM=y
 CONFIG_SYS_CONFIG_NAME="xilinx_zynqmp_zc1751_xm015_dc1"
 CONFIG_ARCH_ZYNQMP=y
 CONFIG_SYS_MALLOC_F_LEN=0x8000
+CONFIG_SPL_SYS_MALLOC_SIMPLE=y
+CONFIG_SPL_DM=y
 CONFIG_DM_I2C=y
 CONFIG_DM_GPIO=y
 CONFIG_ZYNQMP_USB=y
 CONFIG_SYS_TEXT_BASE=0x8000000
 CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zc1751-xm015-dc1"
+CONFIG_SPL=y
 CONFIG_FIT=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_SPL_LOAD_FIT=y
-CONFIG_BOOTDELAY=3
 CONFIG_HUSH_PARSER=y
 CONFIG_SYS_PROMPT="ZynqMP> "
 # CONFIG_CMD_IMLS is not set
@@ -32,10 +34,10 @@ CONFIG_CMD_EXT4=y
 CONFIG_CMD_EXT4_WRITE=y
 CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
+CONFIG_SPL_OF_CONTROL=y
 CONFIG_OF_EMBED=y
 CONFIG_NET_RANDOM_ETHADDR=y
-CONFIG_CLK=y
-CONFIG_SPL_CLK=y
+CONFIG_SPL_DM_SEQ_ALIAS=y
 CONFIG_SYS_I2C_CADENCE=y
 CONFIG_DM_MMC=y
 CONFIG_ZYNQ_SDHCI=y
index 3e7331257c807deada60da03e1e26084ececd185..9fa156227ba2f20450b7d5320bb3746d422aaa96 100644 (file)
@@ -2,15 +2,17 @@ CONFIG_ARM=y
 CONFIG_SYS_CONFIG_NAME="xilinx_zynqmp_zc1751_xm016_dc2"
 CONFIG_ARCH_ZYNQMP=y
 CONFIG_SYS_MALLOC_F_LEN=0x8000
+CONFIG_SPL_SYS_MALLOC_SIMPLE=y
+CONFIG_SPL_DM=y
 CONFIG_DM_I2C=y
 CONFIG_DM_GPIO=y
 CONFIG_ZYNQMP_USB=y
 CONFIG_SYS_TEXT_BASE=0x8000000
 CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zc1751-xm016-dc2"
+CONFIG_SPL=y
 CONFIG_FIT=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_SPL_LOAD_FIT=y
-CONFIG_BOOTDELAY=3
 CONFIG_HUSH_PARSER=y
 CONFIG_SYS_PROMPT="ZynqMP> "
 # CONFIG_CMD_IMLS is not set
@@ -32,10 +34,10 @@ CONFIG_CMD_EXT4=y
 CONFIG_CMD_EXT4_WRITE=y
 CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
+CONFIG_SPL_OF_CONTROL=y
 CONFIG_OF_EMBED=y
 CONFIG_NET_RANDOM_ETHADDR=y
-CONFIG_CLK=y
-CONFIG_SPL_CLK=y
+CONFIG_SPL_DM_SEQ_ALIAS=y
 CONFIG_SYS_I2C_CADENCE=y
 CONFIG_DM_MMC=y
 CONFIG_NAND_ARASAN=y
index 2805219f7b1a52b4eb8654e242078adaadeb9216..efa7b8c40c53614844167d12ef32ca17873d607e 100644 (file)
@@ -2,14 +2,16 @@ CONFIG_ARM=y
 CONFIG_SYS_CONFIG_NAME="xilinx_zynqmp_zc1751_xm018_dc4"
 CONFIG_ARCH_ZYNQMP=y
 CONFIG_SYS_MALLOC_F_LEN=0x8000
+CONFIG_SPL_SYS_MALLOC_SIMPLE=y
+CONFIG_SPL_DM=y
 CONFIG_DM_I2C=y
 CONFIG_DM_GPIO=y
 CONFIG_SYS_TEXT_BASE=0x8000000
 CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zc1751-xm018-dc4"
+CONFIG_SPL=y
 CONFIG_FIT=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_SPL_LOAD_FIT=y
-CONFIG_BOOTDELAY=3
 CONFIG_HUSH_PARSER=y
 CONFIG_SYS_PROMPT="ZynqMP> "
 # CONFIG_CMD_IMLS is not set
@@ -28,10 +30,10 @@ CONFIG_CMD_EXT4=y
 CONFIG_CMD_EXT4_WRITE=y
 CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
+CONFIG_SPL_OF_CONTROL=y
 CONFIG_OF_EMBED=y
 CONFIG_NET_RANDOM_ETHADDR=y
-CONFIG_CLK=y
-CONFIG_SPL_CLK=y
+CONFIG_SPL_DM_SEQ_ALIAS=y
 CONFIG_SYS_I2C_CADENCE=y
 CONFIG_DM_MMC=y
 CONFIG_ZYNQ_SDHCI=y
index 32bea4b20de286c49bdcab8c366a64089d221d3f..a6818c16c4350256a264e1ad9fcfa735e9ed6d33 100644 (file)
@@ -2,14 +2,16 @@ CONFIG_ARM=y
 CONFIG_SYS_CONFIG_NAME="xilinx_zynqmp_zc1751_xm019_dc5"
 CONFIG_ARCH_ZYNQMP=y
 CONFIG_SYS_MALLOC_F_LEN=0x8000
+CONFIG_SPL_SYS_MALLOC_SIMPLE=y
+CONFIG_SPL_DM=y
 CONFIG_DM_I2C=y
 CONFIG_DM_GPIO=y
 CONFIG_SYS_TEXT_BASE=0x8000000
 CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zc1751-xm019-dc5"
+CONFIG_SPL=y
 CONFIG_FIT=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_SPL_LOAD_FIT=y
-CONFIG_BOOTDELAY=3
 CONFIG_HUSH_PARSER=y
 CONFIG_SYS_PROMPT="ZynqMP> "
 # CONFIG_CMD_IMLS is not set
@@ -28,9 +30,9 @@ CONFIG_CMD_EXT4=y
 CONFIG_CMD_EXT4_WRITE=y
 CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
+CONFIG_SPL_OF_CONTROL=y
 CONFIG_OF_EMBED=y
-CONFIG_CLK=y
-CONFIG_SPL_CLK=y
+CONFIG_SPL_DM_SEQ_ALIAS=y
 CONFIG_SYS_I2C_CADENCE=y
 CONFIG_DM_MMC=y
 CONFIG_ZYNQ_SDHCI=y
index d7eb8c27304120605fea3a09cebea22f54847753..b0303f6e6ec85e7265be168ccdac5027607e6c23 100644 (file)
@@ -2,14 +2,16 @@ CONFIG_ARM=y
 CONFIG_SYS_CONFIG_NAME="xilinx_zynqmp_zcu102"
 CONFIG_ARCH_ZYNQMP=y
 CONFIG_SYS_MALLOC_F_LEN=0x8000
+CONFIG_SPL_SYS_MALLOC_SIMPLE=y
+CONFIG_SPL_DM=y
 CONFIG_DM_GPIO=y
 CONFIG_ZYNQMP_USB=y
 CONFIG_SYS_TEXT_BASE=0x8000000
 CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zcu102"
+CONFIG_SPL=y
 CONFIG_FIT=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_SPL_LOAD_FIT=y
-CONFIG_BOOTDELAY=3
 CONFIG_HUSH_PARSER=y
 CONFIG_SYS_PROMPT="ZynqMP> "
 # CONFIG_CMD_IMLS is not set
@@ -31,10 +33,10 @@ CONFIG_CMD_EXT4=y
 CONFIG_CMD_EXT4_WRITE=y
 CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
+CONFIG_SPL_OF_CONTROL=y
 CONFIG_OF_EMBED=y
 CONFIG_NET_RANDOM_ETHADDR=y
-CONFIG_CLK=y
-CONFIG_SPL_CLK=y
+CONFIG_SPL_DM_SEQ_ALIAS=y
 CONFIG_DM_MMC=y
 CONFIG_ZYNQ_SDHCI=y
 CONFIG_SPI_FLASH=y
index 80a59ef07dde587e9bc76d6ce193cff0ee0afe5b..b2b520884f60a6a21d3880b6bf2e717b214af10a 100644 (file)
@@ -2,14 +2,16 @@ CONFIG_ARM=y
 CONFIG_SYS_CONFIG_NAME="xilinx_zynqmp_zcu102"
 CONFIG_ARCH_ZYNQMP=y
 CONFIG_SYS_MALLOC_F_LEN=0x8000
+CONFIG_SPL_SYS_MALLOC_SIMPLE=y
+CONFIG_SPL_DM=y
 CONFIG_DM_GPIO=y
 CONFIG_ZYNQMP_USB=y
 CONFIG_SYS_TEXT_BASE=0x8000000
 CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zcu102-revB"
+CONFIG_SPL=y
 CONFIG_FIT=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_SPL_LOAD_FIT=y
-CONFIG_BOOTDELAY=3
 CONFIG_HUSH_PARSER=y
 CONFIG_SYS_PROMPT="ZynqMP> "
 # CONFIG_CMD_IMLS is not set
@@ -31,10 +33,10 @@ CONFIG_CMD_EXT4=y
 CONFIG_CMD_EXT4_WRITE=y
 CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
+CONFIG_SPL_OF_CONTROL=y
 CONFIG_OF_EMBED=y
 CONFIG_NET_RANDOM_ETHADDR=y
-CONFIG_CLK=y
-CONFIG_SPL_CLK=y
+CONFIG_SPL_DM_SEQ_ALIAS=y
 CONFIG_DM_MMC=y
 CONFIG_ZYNQ_SDHCI=y
 CONFIG_SPI_FLASH=y
index d88c61bf4e4414bfdc9e105b8d0c195d3712f1ed..bc800573de14e8e3d01c62fa086fc948f341d635 100644 (file)
@@ -1,14 +1,14 @@
 CONFIG_ARM=y
-CONFIG_SYS_CONFIG_NAME="zynq_microzed"
+CONFIG_SYS_CONFIG_NAME="zynq-common"
 CONFIG_ARCH_ZYNQ=y
 CONFIG_DEFAULT_DEVICE_TREE="zynq-microzed"
 CONFIG_SPL=y
 CONFIG_FIT=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_FIT_SIGNATURE=y
-CONFIG_BOOTDELAY=3
 CONFIG_HUSH_PARSER=y
 CONFIG_SYS_PROMPT="Zynq> "
+CONFIG_SYS_NO_FLASH=y
 # CONFIG_CMD_IMLS is not set
 # CONFIG_CMD_FLASH is not set
 CONFIG_CMD_MMC=y
@@ -38,9 +38,12 @@ CONFIG_SPI_FLASH_WINBOND=y
 CONFIG_ZYNQ_GEM=y
 CONFIG_ZYNQ_QSPI=y
 CONFIG_USB=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI=y
 CONFIG_USB_ULPI_VIEWPORT=y
 CONFIG_USB_ULPI=y
 CONFIG_USB_GADGET=y
+CONFIG_USB_STORAGE=y
 CONFIG_CI_UDC=y
 CONFIG_USB_GADGET_DOWNLOAD=y
 CONFIG_G_DNL_MANUFACTURER="Xilinx"
index aeb127020fd6c9583c0b8d5f934a67fbc3b7fe14..8002384022d69761efc6123abd1beef5f8c69e04 100644 (file)
@@ -1,11 +1,11 @@
 CONFIG_ARM=y
-CONFIG_SYS_CONFIG_NAME="zynq_picozed"
+CONFIG_SYS_CONFIG_NAME="zynq-common"
 CONFIG_ARCH_ZYNQ=y
 CONFIG_DEFAULT_DEVICE_TREE="zynq-picozed"
 CONFIG_SPL=y
-CONFIG_BOOTDELAY=3
 CONFIG_HUSH_PARSER=y
 CONFIG_SYS_PROMPT="Zynq> "
+CONFIG_SYS_NO_FLASH=y
 # CONFIG_CMD_IMLS is not set
 # CONFIG_CMD_FLASH is not set
 CONFIG_CMD_MMC=y
@@ -28,9 +28,12 @@ CONFIG_SPL_DM_SEQ_ALIAS=y
 CONFIG_ZYNQ_SDHCI=y
 CONFIG_ZYNQ_GEM=y
 CONFIG_USB=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI=y
 CONFIG_USB_ULPI_VIEWPORT=y
 CONFIG_USB_ULPI=y
 CONFIG_USB_GADGET=y
+CONFIG_USB_STORAGE=y
 CONFIG_CI_UDC=y
 CONFIG_USB_GADGET_DOWNLOAD=y
 CONFIG_G_DNL_MANUFACTURER="Xilinx"
index d68ed0edff7b346bae43a1fddffe6cd605a83269..ba5e16d4005617e80715a76058c4002b6e62d117 100644 (file)
@@ -6,9 +6,9 @@ CONFIG_SPL=y
 CONFIG_FIT=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_FIT_SIGNATURE=y
-CONFIG_BOOTDELAY=3
 CONFIG_HUSH_PARSER=y
 CONFIG_SYS_PROMPT="Zynq> "
+CONFIG_SYS_NO_FLASH=y
 # CONFIG_CMD_IMLS is not set
 # CONFIG_CMD_FLASH is not set
 CONFIG_CMD_MMC=y
@@ -43,9 +43,12 @@ CONFIG_DEBUG_UART_BASE=0xe0001000
 CONFIG_DEBUG_UART_CLOCK=50000000
 CONFIG_ZYNQ_QSPI=y
 CONFIG_USB=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI=y
 CONFIG_USB_ULPI_VIEWPORT=y
 CONFIG_USB_ULPI=y
 CONFIG_USB_GADGET=y
+CONFIG_USB_STORAGE=y
 CONFIG_CI_UDC=y
 CONFIG_USB_GADGET_DOWNLOAD=y
 CONFIG_G_DNL_MANUFACTURER="Xilinx"
index 8bd9230580490c9ac3458867cca55b29a4ea8f1a..38ee30ab8dc5106f05148d6129cf6ed61099febe 100644 (file)
@@ -6,9 +6,9 @@ CONFIG_SPL=y
 CONFIG_FIT=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_FIT_SIGNATURE=y
-CONFIG_BOOTDELAY=3
 CONFIG_HUSH_PARSER=y
 CONFIG_SYS_PROMPT="Zynq> "
+CONFIG_SYS_NO_FLASH=y
 # CONFIG_CMD_IMLS is not set
 # CONFIG_CMD_FLASH is not set
 CONFIG_CMD_MMC=y
@@ -39,9 +39,12 @@ CONFIG_SPI_FLASH_WINBOND=y
 CONFIG_ZYNQ_GEM=y
 CONFIG_ZYNQ_QSPI=y
 CONFIG_USB=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI=y
 CONFIG_USB_ULPI_VIEWPORT=y
 CONFIG_USB_ULPI=y
 CONFIG_USB_GADGET=y
+CONFIG_USB_STORAGE=y
 CONFIG_CI_UDC=y
 CONFIG_USB_GADGET_DOWNLOAD=y
 CONFIG_G_DNL_MANUFACTURER="Xilinx"
index 81f16ec1588d48ac1ea479db3eed6735e541ac0d..341204e9b4e85c6594fe730908b38925588c9587 100644 (file)
@@ -1,5 +1,5 @@
 CONFIG_ARM=y
-CONFIG_SYS_CONFIG_NAME="zynq_zc770"
+CONFIG_SYS_CONFIG_NAME="zynq-common"
 CONFIG_ARCH_ZYNQ=y
 CONFIG_DEFAULT_DEVICE_TREE="zynq-zc770-xm010"
 CONFIG_SPL=y
@@ -7,9 +7,9 @@ CONFIG_FIT=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_FIT_SIGNATURE=y
 CONFIG_SYS_EXTRA_OPTIONS="ZC770_XM010"
-CONFIG_BOOTDELAY=3
 CONFIG_HUSH_PARSER=y
 CONFIG_SYS_PROMPT="Zynq> "
+CONFIG_SYS_NO_FLASH=y
 # CONFIG_CMD_IMLS is not set
 # CONFIG_CMD_FLASH is not set
 CONFIG_CMD_MMC=y
index 271fcfd5383644e3104cd96b49f8f0d732619bcb..4e9eb3efa7fad009653a25c7bcb62dd767e5aa0a 100644 (file)
@@ -1,5 +1,5 @@
 CONFIG_ARM=y
-CONFIG_SYS_CONFIG_NAME="zynq_zc770"
+CONFIG_SYS_CONFIG_NAME="zynq-common"
 CONFIG_ARCH_ZYNQ=y
 CONFIG_DEFAULT_DEVICE_TREE="zynq-zc770-xm011"
 CONFIG_SPL=y
@@ -7,9 +7,9 @@ CONFIG_FIT=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_FIT_SIGNATURE=y
 CONFIG_SYS_EXTRA_OPTIONS="ZC770_XM011"
-CONFIG_BOOTDELAY=3
 CONFIG_HUSH_PARSER=y
 CONFIG_SYS_PROMPT="Zynq> "
+CONFIG_SYS_NO_FLASH=y
 # CONFIG_CMD_IMLS is not set
 # CONFIG_CMD_FLASH is not set
 CONFIG_CMD_GPIO=y
index a9ea9711268920eef8a6f919e5935ac953ce9401..b3a75a637b77527a6ec7dfee15aa7d97c010fb61 100644 (file)
@@ -1,5 +1,5 @@
 CONFIG_ARM=y
-CONFIG_SYS_CONFIG_NAME="zynq_zc770"
+CONFIG_SYS_CONFIG_NAME="zynq-common"
 CONFIG_ARCH_ZYNQ=y
 CONFIG_DEFAULT_DEVICE_TREE="zynq-zc770-xm012"
 CONFIG_SPL=y
@@ -7,7 +7,6 @@ CONFIG_FIT=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_FIT_SIGNATURE=y
 CONFIG_SYS_EXTRA_OPTIONS="ZC770_XM012"
-CONFIG_BOOTDELAY=3
 CONFIG_HUSH_PARSER=y
 CONFIG_SYS_PROMPT="Zynq> "
 CONFIG_CMD_GPIO=y
index 56062b18a895d0a5fee8c154bb052fc981f7cd5e..98dbbd6796e15298d947f5412be29bdd13994374 100644 (file)
@@ -1,5 +1,5 @@
 CONFIG_ARM=y
-CONFIG_SYS_CONFIG_NAME="zynq_zc770"
+CONFIG_SYS_CONFIG_NAME="zynq-common"
 CONFIG_ARCH_ZYNQ=y
 CONFIG_DEFAULT_DEVICE_TREE="zynq-zc770-xm013"
 CONFIG_SPL=y
@@ -7,9 +7,9 @@ CONFIG_FIT=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_FIT_SIGNATURE=y
 CONFIG_SYS_EXTRA_OPTIONS="ZC770_XM013"
-CONFIG_BOOTDELAY=3
 CONFIG_HUSH_PARSER=y
 CONFIG_SYS_PROMPT="Zynq> "
+CONFIG_SYS_NO_FLASH=y
 # CONFIG_CMD_IMLS is not set
 # CONFIG_CMD_FLASH is not set
 CONFIG_CMD_GPIO=y
index c70b860b622b632e36227af481a6d874c5cd4c00..d5d6223da9a6d2f7cd0d155c4f2fc976513ebf56 100644 (file)
@@ -1,14 +1,14 @@
 CONFIG_ARM=y
-CONFIG_SYS_CONFIG_NAME="zynq_zed"
+CONFIG_SYS_CONFIG_NAME="zynq-common"
 CONFIG_ARCH_ZYNQ=y
 CONFIG_DEFAULT_DEVICE_TREE="zynq-zed"
 CONFIG_SPL=y
 CONFIG_FIT=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_FIT_SIGNATURE=y
-CONFIG_BOOTDELAY=3
 CONFIG_HUSH_PARSER=y
 CONFIG_SYS_PROMPT="Zynq> "
+CONFIG_SYS_NO_FLASH=y
 # CONFIG_CMD_IMLS is not set
 # CONFIG_CMD_FLASH is not set
 CONFIG_CMD_MMC=y
@@ -38,9 +38,12 @@ CONFIG_SPI_FLASH_WINBOND=y
 CONFIG_ZYNQ_GEM=y
 CONFIG_ZYNQ_QSPI=y
 CONFIG_USB=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI=y
 CONFIG_USB_ULPI_VIEWPORT=y
 CONFIG_USB_ULPI=y
 CONFIG_USB_GADGET=y
+CONFIG_USB_STORAGE=y
 CONFIG_CI_UDC=y
 CONFIG_USB_GADGET_DOWNLOAD=y
 CONFIG_G_DNL_MANUFACTURER="Xilinx"
index 624545edaa9ddc14c496c6ecbf0f2cdd5d3732db..679414af54fdd773f4c18494b393a6049ba66ec6 100644 (file)
@@ -6,9 +6,9 @@ CONFIG_SPL=y
 CONFIG_FIT=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_FIT_SIGNATURE=y
-CONFIG_BOOTDELAY=3
 CONFIG_HUSH_PARSER=y
 CONFIG_SYS_PROMPT="Zynq> "
+CONFIG_SYS_NO_FLASH=y
 # CONFIG_CMD_IMLS is not set
 # CONFIG_CMD_FLASH is not set
 CONFIG_CMD_MMC=y
@@ -41,9 +41,12 @@ CONFIG_DEBUG_UART_BASE=0xe0001000
 CONFIG_DEBUG_UART_CLOCK=50000000
 CONFIG_ZYNQ_QSPI=y
 CONFIG_USB=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI=y
 CONFIG_USB_ULPI_VIEWPORT=y
 CONFIG_USB_ULPI=y
 CONFIG_USB_GADGET=y
+CONFIG_USB_STORAGE=y
 CONFIG_CI_UDC=y
 CONFIG_USB_GADGET_DOWNLOAD=y
 CONFIG_G_DNL_MANUFACTURER="Xilinx"
index 0af1e9248d0f867e949c29f2a1e2ab4fc69ab65b..01f71bee79e2656a295ee1cd3505185efc9c5cf7 100644 (file)
@@ -886,9 +886,10 @@ static gpt_entry *alloc_read_gpt_entries(struct blk_desc *dev_desc,
        count = le32_to_cpu(pgpt_head->num_partition_entries) *
                le32_to_cpu(pgpt_head->sizeof_partition_entry);
 
-       debug("%s: count = %u * %u = %zu\n", __func__,
+       debug("%s: count = %u * %u = %lu\n", __func__,
              (u32) le32_to_cpu(pgpt_head->num_partition_entries),
-             (u32) le32_to_cpu(pgpt_head->sizeof_partition_entry), count);
+             (u32) le32_to_cpu(pgpt_head->sizeof_partition_entry),
+             (ulong)count);
 
        /* Allocate memory for PTE, remember to FREE */
        if (count != 0) {
@@ -897,9 +898,8 @@ static gpt_entry *alloc_read_gpt_entries(struct blk_desc *dev_desc,
        }
 
        if (count == 0 || pte == NULL) {
-               printf("%s: ERROR: Can't allocate 0x%zX "
-                      "bytes for GPT Entries\n",
-                       __func__, count);
+               printf("%s: ERROR: Can't allocate %#lX bytes for GPT Entries\n",
+                      __func__, (ulong)count);
                return NULL;
        }
 
index 9f5c50c73faba4cf2c51bd030f70401914a78092..f9a741d2973ba896932753142c3354b27db8f553 100644 (file)
@@ -233,13 +233,13 @@ static void part_print_iso(struct blk_desc *dev_desc)
        disk_partition_t info;
        int i;
 
-       if (part_get_info_iso_verb(dev_desc, 0, &info, 0) == -1) {
+       if (part_get_info_iso_verb(dev_desc, 1, &info, 0) == -1) {
                printf("** No boot partition found on device %d **\n",
                       dev_desc->devnum);
                return;
        }
        printf("Part   Start     Sect x Size Type\n");
-       i=0;
+       i=1;
        do {
                printf(" %2d " LBAFU " " LBAFU " %6ld %.32s\n",
                       i, info.start, info.size, info.blksz, info.type);
index a6f6de6a0f5f78549689f148844b708aac5b4b3e..3fcd83557f99bee1ec60d62646b9bc3c99c49951 100644 (file)
@@ -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
index e0572c80b9c7d6e22bfc695d0d73fde74f6789d5..c218a8b547fb03cfc4dd84d3b95b34f1dfa27a75 100644 (file)
@@ -36,11 +36,12 @@ You will need:
 Building
 ========
 
-At present three RK3288 boards are supported:
+At present four RK3288 boards are supported:
 
    - Firefly RK3288 - use firefly-rk3288 configuration
    - Radxa Rock 2 - use rock2 configuration
    - Hisense Chromebook - use chromebook_jerry configuration
+   - EVB RK3288 - use evb-rk3288 configuration
 
 Two RK3036 board are supported:
 
@@ -119,6 +120,20 @@ something like:
    Hit any key to stop autoboot:  0
    =>
 
+The rockchip bootrom can load and boot an initial spl, then continue to
+load a second-level bootloader(ie. U-BOOT) as soon as it returns to bootrom.
+Therefore RK3288 has another loading sequence like RK3036. The option of
+U-Boot is controlled with this setting in U-Boot:
+
+       #define CONFIG_ROCKCHIP_SPL_BACK_TO_BROM
+
+You can create the image via the following operations:
+
+   ./firefly-rk3288/tools/mkimage -n rk3288 -T rksd -d \
+       firefly-rk3288/spl/u-boot-spl-dtb.bin out && \
+   cat firefly-rk3288/u-boot-dtb.bin >> out && \
+   sudo dd if=out of=/dev/sdc seek=64
+
 If you have an HDMI cable attached you should see a video console.
 
 For evb_rk3036 board:
@@ -129,6 +144,32 @@ For evb_rk3036 board:
 Note: rk3036 SDMMC and debug uart use the same iomux, so if you boot from SD, the
       debug uart must be disabled
 
+Using fastboot on rk3288
+========================
+- Define GPT partition layout like kylin_rk3036(see include/configs/kylin_rk3036.h)
+- Write GPT partition layout to mmc device which fastboot want to use it to
+store the image
+
+        => gpt write mmc 1 $partitions
+
+- Invoke fastboot command to prepare
+
+        => fastboot 1
+
+- Start fastboot request on PC
+
+        fastboot -i 0x2207 flash loader evb-rk3288/spl/u-boot-spl-dtb.bin
+
+You should see something like:
+
+        => fastboot 1
+        WARNING: unknown variable: partition-type:loader
+        Starting download of 357796 bytes
+        ..
+        downloading of 357796 bytes finished
+        Flashing Raw Image
+        ........ wrote 357888 bytes to 'loader'
+
 Booting from SPI
 ================
 
index b7cf62df9b4da53a886ebb01ea82bc940b5d34e6..200f6708060b8e0f4090e60b47a5cb7dfc4fd8e9 100644 (file)
@@ -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...
index 7fc9b9bc30fa34ca5c3781eb8b0f7b26ef1f90f8..54c996d8f6ad0969e275248083a7d189f558d4db 100644 (file)
@@ -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.ubispl b/doc/README.ubispl
new file mode 100644 (file)
index 0000000..ff008bc
--- /dev/null
@@ -0,0 +1,141 @@
+Lightweight UBI and UBI fastmap support
+
+# Copyright (C) Thomas Gleixner <tglx@linutronix.de>
+#
+# SPDX-License-Identifier: GPL 2.0+ BSD-3-Clause
+
+Scans the UBI information and loads the requested static volumes into
+memory.
+
+Configuration Options:
+
+   CONFIG_SPL_UBI
+     Enables the SPL UBI support
+
+   CONFIG_SPL_UBI_MAX_VOL_LEBS
+     The maximum number of logical eraseblocks which a static volume
+     to load can contain. Used for sizing the scan data structure
+
+   CONFIG_SPL_UBI_MAX_PEB_SIZE
+     The maximum physical erase block size. Either a compile time
+     constant or runtime detection. Used for sizing the scan data
+     structure
+
+   CONFIG_SPL_UBI_MAX_PEBS
+     The maximum physical erase block count. Either a compile time
+     constant or runtime detection. Used for sizing the scan data
+     structure
+
+   CONFIG_SPL_UBI_VOL_IDS
+     The maximum volume ids which can be loaded. Used for sizing the
+     scan data structure.
+
+Usage notes:
+
+In the board config file define for example:
+
+#define CONFIG_SPL_UBI
+#define CONFIG_SPL_UBI_MAX_VOL_LEBS    256
+#define CONFIG_SPL_UBI_MAX_PEB_SIZE    (256*1024)
+#define CONFIG_SPL_UBI_MAX_PEBS                4096
+#define CONFIG_SPL_UBI_VOL_IDS         8
+
+The size requirement is roughly as follows:
+
+    2k for the basic data structure
+  + CONFIG_SPL_UBI_VOL_IDS * CONFIG_SPL_UBI_MAX_VOL_LEBS * 8
+  + CONFIG_SPL_UBI_MAX_PEBS * 64
+  + CONFIG_SPL_UBI_MAX_PEB_SIZE * UBI_FM_MAX_BLOCKS
+
+The last one is big, but I really don't care in that stage. Real world
+implementations only use the first couple of blocks, but the code
+handles up to UBI_FM_MAX_BLOCKS.
+
+Given the above configuration example the requirement is about 5M
+which is usually not a problem to reserve in the RAM along with the
+other areas like the kernel/dts load address.
+
+So something like this will do the trick:
+
+#define SPL_FINFO_ADDR                 0x80800000
+#define SPL_DTB_LOAD_ADDR              0x81800000
+#define SPL_KERNEL_LOAD_ADDR           0x82000000
+
+In the board file, implement the following:
+
+static struct ubispl_load myvolumes[] = {
+       {
+               .vol_id         = 0,    /* kernel volume */
+               .load_addr      = (void *)SPL_KERNEL_LOAD_ADDR,
+       },
+       {
+               .vol_id         = 1,    /* DT blob */
+               .load_addr      = (void *)SPL_DTB_LOAD_ADDR,
+       }
+};
+
+int spl_start_uboot(void)
+{
+       struct ubispl_info info;
+
+       info.ubi = (struct ubi_scan_info *) SPL_FINFO_ADDR;
+       info.fastmap = 1;
+       info.read = nand_spl_read_flash;
+
+#if COMPILE_TIME_DEFINED
+       /*
+        * MY_NAND_NR_SPL_PEBS is the number of physical erase blocks
+        * in the FLASH which are reserved for the SPL. Think about
+        * mtd partitions:
+        *
+        * part_spl { .start = 0, .end = 4 }
+        * part_ubi { .start = 4, .end = NR_PEBS }
+        */
+       info.peb_offset = MY_NAND_NR_SPL_PEBS;
+       info.peb_size = CONFIG_SYS_NAND_BLOCK_SIZE;
+       info.vid_offset = MY_NAND_UBI_VID_OFFS;
+       info.leb_start = MY_NAND_UBI_DATA_OFFS;
+       info.peb_count = MY_NAND_UBI_NUM_PEBS;
+#else
+       get_flash_info(&flash_info);
+       info.peb_offset = MY_NAND_NR_SPL_PEBS;
+       info.peb_size = flash_info.peb_size;
+
+       /*
+        * The VID and Data offset depend on the capability of the
+        * FLASH chip to do subpage writes.
+        *
+        * If the flash chip supports subpage writes, then the VID
+        * header starts at the second subpage. So for 2k pages size
+        * with 4 subpages the VID offset is 512. The DATA offset is 2k.
+        *
+        * If the flash chip does not support subpage writes then the
+        * VID offset is FLASH_PAGE_SIZE and the DATA offset
+        * 2 * FLASH_PAGE_SIZE
+        */
+       info.vid_offset = flash_info.vid_offset;
+       info.leb_start = flash_info.data_offset;
+
+       /*
+        * The flash reports the total number of erase blocks, so
+        * we need to subtract the number of blocks which are reserved
+        * for the SPL itself and not managed by UBI.
+        */
+       info.peb_count = flash_info.peb_count - MY_NAND_NR_SPL_PEBS;
+#endif
+
+       ret = ubispl_load_volumes(&info, myvolumes, ARRAY_SIZE(myvolumes);
+
+       ....
+
+}
+
+Note: you can load any payload that way. You can even load u-boot from
+UBI, so the only non UBI managed FLASH area is the one which is
+reserved for the SPL itself and read from the SoC ROM.
+
+And you can do fallback scenarios:
+
+    if (ubispl_load_volumes(&info, volumes0, ARRAY_SIZE(volumes0)))
+        if (ubispl_load_volumes(&info, volumes1, ARRAY_SIZE(volumes1)))
+           ubispl_load_volumes(&info, vol_uboot, ARRAY_SIZE(vol_uboot));
index a548b54b5b3fbb599471719667d775e633b29ad0..7d694b19cc6bdf64f39d559483e97a9ea02acd1b 100644 (file)
@@ -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/SPL/README.spl-secure-boot b/doc/SPL/README.spl-secure-boot
new file mode 100644 (file)
index 0000000..f2f8d78
--- /dev/null
@@ -0,0 +1,18 @@
+Overview of SPL verified boot on powerpc/mpc85xx & arm/layerscape platforms
+===========================================================================
+
+Introduction
+------------
+
+This document provides an overview of how SPL verified boot works on powerpc/
+mpc85xx & arm/layerscape platforms.
+
+Methodology
+-----------
+
+The SPL image is responsible for loading the next stage boot loader, which is
+the main u-boot image. For secure boot process on these platforms ROM verifies
+SPL image, so to continue chain of trust SPL image verifies U-boot image using
+spl_validate_uboot(). This function uses QorIQ Trust Architecture header
+(appended to U-boot image) to validate the U-boot binary just before passing
+control to it.
diff --git a/doc/device-tree-bindings/serial/sh.txt b/doc/device-tree-bindings/serial/sh.txt
new file mode 100644 (file)
index 0000000..99634a5
--- /dev/null
@@ -0,0 +1,6 @@
+* Renesas SCI serial interface
+
+Required properties:
+- compatible: must be "renesas,scif", "renesas,scifa" or "renesas,sci"
+- reg: exactly one register range with length
+- clock: input clock frequency for the SCI unit
diff --git a/doc/driver-model/of-plat.txt b/doc/driver-model/of-plat.txt
new file mode 100644 (file)
index 0000000..86e5e25
--- /dev/null
@@ -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
index 4ed30df707ecd8f32b1e62d60c98cf695378efd3..b5a70da2962a527216cad4abf58b971cd7b14e2d 100644 (file)
@@ -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>
index 17239588570ccfa01be890fbeaac48d763ac4c33..ad5cbae7caa565dfc0ec0fd7cc18148a3677afef 100644 (file)
@@ -19,14 +19,15 @@ obj-$(CONFIG_ARMADA_38X) += ddr/marvell/a38x/
 obj-$(CONFIG_ARMADA_XP) += ddr/marvell/axp/
 obj-$(CONFIG_ALTERA_SDRAM) += ddr/altera/
 obj-$(CONFIG_SPL_SERIAL_SUPPORT) += serial/
-obj-$(CONFIG_SPL_SPI_FLASH_SUPPORT) += mtd/spi/
 obj-$(CONFIG_SPL_SPI_SUPPORT) += spi/
 obj-$(CONFIG_SPL_POWER_SUPPORT) += power/ power/pmic/
 obj-$(CONFIG_SPL_POWER_SUPPORT) += power/regulator/
+obj-$(CONFIG_SPL_DRIVERS_MISC_SUPPORT) += misc/
 obj-$(CONFIG_SPL_MTD_SUPPORT) += mtd/
 obj-$(CONFIG_SPL_NAND_SUPPORT) += mtd/nand/
-obj-$(CONFIG_SPL_DRIVERS_MISC_SUPPORT) += misc/
 obj-$(CONFIG_SPL_ONENAND_SUPPORT) += mtd/onenand/
+obj-$(CONFIG_SPL_SPI_FLASH_SUPPORT) += mtd/spi/
+obj-$(CONFIG_SPL_UBI) += mtd/ubispl/
 obj-$(CONFIG_SPL_DMA_SUPPORT) += dma/
 obj-$(CONFIG_SPL_ETH_SUPPORT) += net/
 obj-$(CONFIG_SPL_ETH_SUPPORT) += net/phy/
index 0ba9c0c105dd14cd2c17614da5ff71e84efca7c1..c2db1213fe66262145e6f790a75aef2012c6ceac 100644 (file)
@@ -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.
 *
 ****************************************************************************/
 
index 6e4d67220a1685ccf8ce3dca91cd83300783203c..4d78e3fcac43d586ea5f2dc02cd5bb7fb48ab51c 100644 (file)
@@ -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;
@@ -20,31 +21,22 @@ static inline struct clk_ops *clk_dev_ops(struct udevice *dev)
 }
 
 #if CONFIG_IS_ENABLED(OF_CONTROL)
-#ifdef CONFIG_SPL_BUILD
-int clk_get_by_index(struct udevice *dev, int index, struct clk *clk)
+# 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;
-       u32 cell[2];
 
        if (index != 0)
                return -ENOSYS;
-       assert(clk);
        ret = uclass_get_device(UCLASS_CLK, 0, &clk->dev);
        if (ret)
                return ret;
-       ret = fdtdec_get_int_array(gd->fdt_blob, dev->of_offset, "clocks",
-                                  cell, 2);
-       if (ret)
-               return ret;
-       clk->id = cell[1];
-       return 0;
-}
+       clk->id = cells[0].id;
 
-int clk_get_by_name(struct udevice *dev, const char *name, struct clk *clk)
-{
-       return -ENOSYS;
+       return 0;
 }
-#else
+# else
 static int clk_of_xlate_default(struct clk *clk,
                                struct fdtdec_phandle_args *args)
 {
@@ -101,6 +93,7 @@ int clk_get_by_index(struct udevice *dev, int index, struct clk *clk)
 
        return clk_request(dev_clk, clk);
 }
+# endif /* OF_PLATDATA */
 
 int clk_get_by_name(struct udevice *dev, const char *name, struct clk *clk)
 {
@@ -117,8 +110,7 @@ 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 /* OF_CONTROL */
 
 int clk_request(struct udevice *dev, struct clk *clk)
 {
index 797e5379075da87e5dac71ed7d61106c8dd9fbff..9c4d2b322f707e63cf43407792a740074f1b1939 100644 (file)
@@ -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;
 }
index 2285453e8de284b93731370e73ee48490781b4f7..e00feb08091e8b47273363a3b272afc9ca2b4a24 100644 (file)
@@ -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>
 
 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;
@@ -39,7 +47,7 @@ enum {
        OUTPUT_MAX_HZ   = 2200U * 1000000,
        OUTPUT_MIN_HZ   = 27500000,
        FREF_MAX_HZ     = 2200U * 1000000,
-       FREF_MIN_HZ     = 269 * 1000000,
+       FREF_MIN_HZ     = 269 * 1000,
 };
 
 enum {
@@ -137,7 +145,7 @@ void *rockchip_get_cru(void)
        struct udevice *dev;
        int ret;
 
-       ret = uclass_get_device(UCLASS_CLK, 0, &dev);
+       ret = rockchip_get_clk(&dev);
        if (ret)
                return ERR_PTR(ret);
 
@@ -439,7 +447,7 @@ static void rkclk_init(struct rk3288_cru *cru, struct rk3288_grf *grf)
 }
 #endif
 
-void rkclk_configure_cpu(struct rk3288_cru *cru, struct rk3288_grf *grf)
+void rk3288_clk_configure_cpu(struct rk3288_cru *cru, struct rk3288_grf *grf)
 {
        /* pll enter slow-mode */
        rk_clrsetreg(&cru->cru_mode_con,
@@ -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,
 };
index 2f5d4d839101440d946a29c8de9bdd0a9da57325..a91924e8a4e083ddd6574658c081f1e39549afcc 100644 (file)
@@ -1,11 +1,11 @@
 /*
- * Copyright (C) 2016 Masahiro Yamada <yamada.masahiro@socionext.com>
+ * Copyright (C) 2016 Socionext Inc.
+ *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
  *
  * SPDX-License-Identifier:    GPL-2.0+
  */
 
 #include <common.h>
-#include <mapmem.h>
 #include <linux/bitops.h>
 #include <linux/io.h>
 #include <linux/sizes.h>
@@ -137,7 +137,7 @@ int uniphier_clk_probe(struct udevice *dev)
        if (addr == FDT_ADDR_T_NONE)
                return -EINVAL;
 
-       priv->base = map_sysmem(addr, SZ_4K);
+       priv->base = devm_ioremap(dev, addr, SZ_4K);
        if (!priv->base)
                return -ENOMEM;
 
@@ -145,12 +145,3 @@ int uniphier_clk_probe(struct udevice *dev)
 
        return 0;
 }
-
-int uniphier_clk_remove(struct udevice *dev)
-{
-       struct uniphier_clk_priv *priv = dev_get_priv(dev);
-
-       unmap_sysmem(priv->base);
-
-       return 0;
-}
index 2dd3fc074a731ad374a9dce0b7eb51b64bcdfef2..2eea5ebc2ae2a0684d58c0b04175f8e1cfeeb4f8 100644 (file)
@@ -1,5 +1,6 @@
 /*
- * Copyright (C) 2016 Masahiro Yamada <yamada.masahiro@socionext.com>
+ * Copyright (C) 2016 Socionext Inc.
+ *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
  *
  * SPDX-License-Identifier:    GPL-2.0+
  */
@@ -179,7 +180,6 @@ U_BOOT_DRIVER(uniphier_mio_clk) = {
        .id = UCLASS_CLK,
        .of_match = uniphier_mio_clk_match,
        .probe = uniphier_clk_probe,
-       .remove = uniphier_clk_remove,
        .priv_auto_alloc_size = sizeof(struct uniphier_clk_priv),
        .ops = &uniphier_clk_ops,
 };
index 560b3f81129c371da92c6b9b1c3fd341e72297ed..18aa88849b349f4e79b4d62a43b0646b64ac72f0 100644 (file)
@@ -1,5 +1,6 @@
 /*
- * Copyright (C) 2016 Masahiro Yamada <yamada.masahiro@socionext.com>
+ * Copyright (C) 2016 Socionext Inc.
+ *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
  *
  * SPDX-License-Identifier:    GPL-2.0+
  */
@@ -52,6 +53,5 @@ struct uniphier_clk_priv {
 
 extern const struct clk_ops uniphier_clk_ops;
 int uniphier_clk_probe(struct udevice *dev);
-int uniphier_clk_remove(struct udevice *dev);
 
 #endif /* __CLK_UNIPHIER_H__ */
index 0e56b23fbbf44b059b6e38afd1c8366ee245e764..a7f77b4a21dc33efbdc62b2983de5fb970cd8979 100644 (file)
@@ -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);
 
index eb75b1734f9b973e406c8cfca80c8f6a9231c0e9..5bb1d7793dd687a9fed5475409b382e32effab92 100644 (file)
@@ -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)
index 0c277177909666e1dedfd12efbd6ca3b531549f1..6a634e695180cd35b35619ee6bdb10dbfa31ec08 100644 (file)
@@ -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
  *
index 519832f173307e95a9862e33679c9f0707218696..0299ff087937f406a939a15a585046b900584143 100644 (file)
 
 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)
 {
index 95886add2381fc864a75f976b3fe4e8f444b7bb6..158702406ed19e617307de370a9ba4d6ab6b1565 100644 (file)
@@ -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);
index e03f46af5739d7156ad0270a438e4744496e535f..01bd9683a7a757ccf20a9a769c83ee1555350cd6 100644 (file)
@@ -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)
index 1141ce1ba3ccd0d22a081674e2f038b9a1b93c81..de602ae52dcbd2d7d7a823a4e470b81beb6d178b 100644 (file)
@@ -311,6 +311,26 @@ static int uclass_find_device_by_phandle(enum uclass_id id,
 }
 #endif
 
+int uclass_get_device_by_driver(enum uclass_id id,
+                               const struct driver *find_drv,
+                               struct udevice **devp)
+{
+       struct udevice *dev;
+       struct uclass *uc;
+       int ret;
+
+       ret = uclass_get(id, &uc);
+       if (ret)
+               return ret;
+
+       list_for_each_entry(dev, &uc->dev_head, uclass_node) {
+               if (dev->driver == find_drv)
+                       return uclass_get_device_tail(dev, 0, devp);
+       }
+
+       return -ENODEV;
+}
+
 int uclass_get_device_tail(struct udevice *dev, int ret,
                                  struct udevice **devp)
 {
index 1ac3a09dffe275f6e2e1dbb2abf79c9113705d80..081bce53cff2290aff7cad871b83676cc2b52a47 100644 (file)
  */
 #define HDR_REVERSE            0x00000800
 
-/* Propogate DNR property to SharedDesc */
+/* Propagate DNR property to SharedDesc */
 #define HDR_PROP_DNR           0x00000800
 
 /* JobDesc/SharedDesc share property */
index cf1c4c1d458ad05a01729c5868bc174986ebd8e9..5471504b6e9cad5589dd73d3508cd76193dfbec5 100644 (file)
@@ -53,6 +53,7 @@ U_BOOT_DRIVER(fsl_rsa_mod_exp) = {
        .name   = "fsl_rsa_mod_exp",
        .id     = UCLASS_MOD_EXP,
        .ops    = &fsl_mod_exp_ops,
+       .flags  = DM_FLAG_PRE_RELOC,
 };
 
 U_BOOT_DEVICE(fsl_rsa) = {
index 510fa4e37601cb72ec552def4fff963c23891115..4a8cc3295a4a4eb116a2fbddc5c9ba5543aea115 100644 (file)
@@ -599,9 +599,26 @@ int sec_init_idx(uint8_t sec_idx)
        sec_out32(&sec->mcfgr, mcr);
 
 #ifdef CONFIG_FSL_CORENET
+#ifdef CONFIG_SPL_BUILD
+       /*
+        * For SPL Build, Set the Liodns in SEC JR0 for
+        * creating PAMU entries corresponding to these.
+        * For normal build, these are set in set_liodns().
+        */
+       liodn_ns = CONFIG_SPL_JR0_LIODN_NS & JRNSLIODN_MASK;
+       liodn_s = CONFIG_SPL_JR0_LIODN_S & JRSLIODN_MASK;
+
+       liodnr = sec_in32(&sec->jrliodnr[0].ls) &
+                ~(JRNSLIODN_MASK | JRSLIODN_MASK);
+       liodnr = liodnr |
+                (liodn_ns << JRNSLIODN_SHIFT) |
+                (liodn_s << JRSLIODN_SHIFT);
+       sec_out32(&sec->jrliodnr[0].ls, liodnr);
+#else
        liodnr = sec_in32(&sec->jrliodnr[0].ls);
        liodn_ns = (liodnr & JRNSLIODN_MASK) >> JRNSLIODN_SHIFT;
        liodn_s = (liodnr & JRSLIODN_MASK) >> JRSLIODN_SHIFT;
+#endif
 #endif
 
        ret = jr_init(sec_idx);
index 1d5cec662ce1c94f4af5ca9282aa457e3ace1473..abd576b9350787c3e2db3a181688ca8f38c8cc1f 100644 (file)
@@ -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;
                /*
index 78724e467b24c7f816fef09767022bd8876b42a8..926ccbd2ef5e9eac95d2083f6047c9abcee2ef0a 100644 (file)
@@ -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;
 
index 7e2f3e17a7649a6bdddb3e41eef6f75c660b3c7c..e0fb1b4e783b7527bf43185cf7c053fc7c3fa0d9 100644 (file)
@@ -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");
 }
 
 
index bde51eab15bb1f561bb4eaacfcc939dceddba10c..afb27a396ff04fa4dc96d6d907d00fd3e0b0f2d3 100644 (file)
@@ -1,12 +1,12 @@
 /*
- * Copyright (C) 2016 Masahiro Yamada <yamada.masahiro@socionext.com>
+ * Copyright (C) 2016 Socionext Inc.
+ *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
  *
  * SPDX-License-Identifier:    GPL-2.0+
  */
 
 #include <common.h>
 #include <dm/device.h>
-#include <mapmem.h>
 #include <linux/bitops.h>
 #include <linux/io.h>
 #include <linux/sizes.h>
@@ -99,7 +99,7 @@ static int uniphier_gpio_probe(struct udevice *dev)
        if (addr == FDT_ADDR_T_NONE)
                return -EINVAL;
 
-       priv->base = map_sysmem(addr, SZ_8);
+       priv->base = devm_ioremap(dev, addr, SZ_8);
        if (!priv->base)
                return -ENOMEM;
 
@@ -119,15 +119,6 @@ static int uniphier_gpio_probe(struct udevice *dev)
        return 0;
 }
 
-static int uniphier_gpio_remove(struct udevice *dev)
-{
-       struct uniphier_gpio_priv *priv = dev_get_priv(dev);
-
-       unmap_sysmem(priv->base);
-
-       return 0;
-}
-
 /* .data = the number of GPIO banks */
 static const struct udevice_id uniphier_gpio_match[] = {
        { .compatible = "socionext,uniphier-gpio" },
@@ -139,7 +130,6 @@ U_BOOT_DRIVER(uniphier_gpio) = {
        .id     = UCLASS_GPIO,
        .of_match = uniphier_gpio_match,
        .probe  = uniphier_gpio_probe,
-       .remove = uniphier_gpio_remove,
        .priv_auto_alloc_size = sizeof(struct uniphier_gpio_priv),
        .ops    = &uniphier_gpio_ops,
 };
index 04773e2b31c3074e322dff41debfb5bc63522f4f..3754a8215c3630db7c33cc50a13eff8959fa6b04 100644 (file)
@@ -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),
 };
index 6e22bbadff2d54d24fd34f8500896ce970cec325..b3e84052ebbf10b46e986cd1144c91b08c04c5ac 100644 (file)
@@ -154,6 +154,13 @@ config SYS_I2C_UNIPHIER_F
          Support for UniPhier FIFO-builtin I2C controller driver.
          This I2C controller is used on PH1-Pro4 or newer UniPhier SoCs.
 
+config SYS_I2C_MVTWSI
+       bool "Marvell I2C driver"
+       depends on DM_I2C
+       help
+         Support for Marvell I2C controllers as used on the orion5x and
+         kirkwood SoC families.
+
 source "drivers/i2c/muxes/Kconfig"
 
 endmenu
index b8cc647bd3900c4375dea5dbf8277556f81bf969..407c4a7b10b86c9b38eeac3b0f76527cbf4e7024 100644 (file)
@@ -583,12 +583,11 @@ static int fsl_i2c_set_bus_speed(struct udevice *bus, unsigned int speed)
 static int fsl_i2c_ofdata_to_platdata(struct udevice *bus)
 {
        struct fsl_i2c_dev *dev = dev_get_priv(bus);
-       u64 reg;
-       u32 addr, size;
+       fdt_addr_t addr;
+       fdt_size_t size;
 
-       reg = fdtdec_get_addr(gd->fdt_blob, bus->of_offset, "reg");
-       addr = reg >> 32;
-       size = reg & 0xFFFFFFFF;
+       addr = fdtdec_get_addr_size_auto_noparent(gd->fdt_blob, bus->of_offset,
+                                                 "reg", 0, &size);
 
        dev->base = map_sysmem(CONFIG_SYS_IMMR + addr, size);
 
index 50b99ead3d9fb4179940d2c6566a698d954028f5..20b30ffbeb5197217c382a84fa37f5b87c6b96e9 100644 (file)
@@ -467,6 +467,7 @@ int i2c_deblock(struct udevice *bus)
        return ops->deblock(bus);
 }
 
+#if CONFIG_IS_ENABLED(OF_CONTROL)
 int i2c_chip_ofdata_to_platdata(const void *blob, int node,
                                struct dm_i2c_chip *chip)
 {
@@ -482,31 +483,44 @@ int i2c_chip_ofdata_to_platdata(const void *blob, int node,
 
        return 0;
 }
+#endif
 
 static int i2c_post_probe(struct udevice *dev)
 {
+#if CONFIG_IS_ENABLED(OF_CONTROL)
        struct dm_i2c_bus *i2c = dev_get_uclass_priv(dev);
 
        i2c->speed_hz = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
                                     "clock-frequency", 100000);
 
        return dm_i2c_set_bus_speed(dev, i2c->speed_hz);
+#else
+       return 0;
+#endif
 }
 
 static int i2c_post_bind(struct udevice *dev)
 {
+#if CONFIG_IS_ENABLED(OF_CONTROL)
        /* Scan the bus for devices */
        return dm_scan_fdt_node(dev, gd->fdt_blob, dev->of_offset, false);
+#else
+       return 0;
+#endif
 }
 
 static int i2c_child_post_bind(struct udevice *dev)
 {
+#if CONFIG_IS_ENABLED(OF_CONTROL)
        struct dm_i2c_chip *plat = dev_get_parent_platdata(dev);
 
        if (dev->of_offset == -1)
                return 0;
 
        return i2c_chip_ofdata_to_platdata(gd->fdt_blob, dev->of_offset, plat);
+#else
+       return 0;
+#endif
 }
 
 UCLASS_DRIVER(i2c) = {
index aebdcfcec3052701efd4882b0ccbab8e47192254..a56e058d569213c90ea2f4184ed458774c03df22 100644 (file)
@@ -1,5 +1,7 @@
 /*
- * Copyright (C) 2014-2015 Masahiro Yamada <yamada.masahiro@socionext.com>
+ * Copyright (C) 2014      Panasonic Corporation
+ * Copyright (C) 2015-2016 Socionext Inc.
+ *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
  *
  * SPDX-License-Identifier:    GPL-2.0+
  */
@@ -13,7 +15,6 @@
 #include <dm/root.h>
 #include <i2c.h>
 #include <fdtdec.h>
-#include <mapmem.h>
 
 struct uniphier_fi2c_regs {
        u32 cr;                         /* control register */
@@ -118,7 +119,7 @@ static int uniphier_fi2c_probe(struct udevice *dev)
        if (addr == FDT_ADDR_T_NONE)
                return -EINVAL;
 
-       priv->regs = map_sysmem(addr, SZ_128);
+       priv->regs = devm_ioremap(dev, addr, SZ_128);
        if (!priv->regs)
                return -ENOMEM;
 
@@ -134,15 +135,6 @@ static int uniphier_fi2c_probe(struct udevice *dev)
        return 0;
 }
 
-static int uniphier_fi2c_remove(struct udevice *dev)
-{
-       struct uniphier_fi2c_dev *priv = dev_get_priv(dev);
-
-       unmap_sysmem(priv->regs);
-
-       return 0;
-}
-
 static int wait_for_irq(struct uniphier_fi2c_dev *dev, u32 flags,
                        bool *stop)
 {
@@ -359,7 +351,6 @@ U_BOOT_DRIVER(uniphier_fi2c) = {
        .id = UCLASS_I2C,
        .of_match = uniphier_fi2c_of_match,
        .probe = uniphier_fi2c_probe,
-       .remove = uniphier_fi2c_remove,
        .priv_auto_alloc_size = sizeof(struct uniphier_fi2c_dev),
        .ops = &uniphier_fi2c_ops,
 };
index f8221da82e4f76da198e9cf018e40f0ee4edb0dd..39a3ebdfc16b72311a4d960b2fb30a3b56a6db7b 100644 (file)
@@ -1,5 +1,7 @@
 /*
- * Copyright (C) 2014-2015 Masahiro Yamada <yamada.masahiro@socionext.com>
+ * Copyright (C) 2014      Panasonic Corporation
+ * Copyright (C) 2015-2016 Socionext Inc.
+ *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
  *
  * SPDX-License-Identifier:    GPL-2.0+
  */
@@ -13,7 +15,6 @@
 #include <dm/root.h>
 #include <i2c.h>
 #include <fdtdec.h>
-#include <mapmem.h>
 
 struct uniphier_i2c_regs {
        u32 dtrm;                       /* data transmission */
@@ -53,7 +54,7 @@ static int uniphier_i2c_probe(struct udevice *dev)
        if (addr == FDT_ADDR_T_NONE)
                return -EINVAL;
 
-       priv->regs = map_sysmem(addr, SZ_64);
+       priv->regs = devm_ioremap(dev, addr, SZ_64);
        if (!priv->regs)
                return -ENOMEM;
 
@@ -65,15 +66,6 @@ static int uniphier_i2c_probe(struct udevice *dev)
        return 0;
 }
 
-static int uniphier_i2c_remove(struct udevice *dev)
-{
-       struct uniphier_i2c_dev *priv = dev_get_priv(dev);
-
-       unmap_sysmem(priv->regs);
-
-       return 0;
-}
-
 static int send_and_recv_byte(struct uniphier_i2c_dev *dev, u32 dtrm)
 {
        writel(dtrm, &dev->regs->dtrm);
@@ -220,7 +212,6 @@ U_BOOT_DRIVER(uniphier_i2c) = {
        .id = UCLASS_I2C,
        .of_match = uniphier_i2c_of_match,
        .probe = uniphier_i2c_probe,
-       .remove = uniphier_i2c_remove,
        .priv_auto_alloc_size = sizeof(struct uniphier_i2c_dev),
        .ops = &uniphier_i2c_ops,
 };
index bf4443287fd2977fe3a61f3f653327ab3e013323..ab7481a0d4a9ec80e6d3e792715679b893270424 100644 (file)
 #include <i2c.h>
 #include <asm/errno.h>
 #include <asm/io.h>
+#include <linux/compat.h>
+#ifdef CONFIG_DM_I2C
+#include <dm.h>
+#endif
+
+DECLARE_GLOBAL_DATA_PTR;
 
 /*
- * include a file that will provide CONFIG_I2C_MVTWSI_BASE*
- * and possibly other settings
+ * Include a file that will provide CONFIG_I2C_MVTWSI_BASE*, and possibly other
+ * settings
  */
 
+#ifndef CONFIG_DM_I2C
 #if defined(CONFIG_ORION5X)
 #include <asm/arch/orion5x.h>
 #elif (defined(CONFIG_KIRKWOOD) || defined(CONFIG_ARCH_MVEBU))
@@ -27,6 +34,7 @@
 #else
 #error Driver mvtwsi not supported by SoC or board
 #endif
+#endif /* CONFIG_DM_I2C */
 
 /*
  * TWSI register structure
@@ -51,8 +59,8 @@ struct  mvtwsi_registers {
        u32 data;
        u32 control;
        union {
-               u32 status;     /* when reading */
-               u32 baudrate;   /* when writing */
+               u32 status;     /* When reading */
+               u32 baudrate;   /* When writing */
        };
        u32 xtnd_slave_addr;
        u32 reserved[2];
@@ -61,20 +69,43 @@ struct  mvtwsi_registers {
 
 #endif
 
+#ifdef CONFIG_DM_I2C
+struct mvtwsi_i2c_dev {
+       /* TWSI Register base for the device */
+       struct mvtwsi_registers *base;
+       /* Number of the device (determined from cell-index property) */
+       int index;
+       /* The I2C slave address for the device */
+       u8 slaveadd;
+       /* The configured I2C speed in Hz */
+       uint speed;
+       /* The current length of a clock period (depending on speed) */
+       uint tick;
+};
+#endif /* CONFIG_DM_I2C */
+
 /*
- * Control register fields
+ * enum mvtwsi_ctrl_register_fields - Bit masks for flags in the control
+ * register
  */
-
-#define        MVTWSI_CONTROL_ACK      0x00000004
-#define        MVTWSI_CONTROL_IFLG     0x00000008
-#define        MVTWSI_CONTROL_STOP     0x00000010
-#define        MVTWSI_CONTROL_START    0x00000020
-#define        MVTWSI_CONTROL_TWSIEN   0x00000040
-#define        MVTWSI_CONTROL_INTEN    0x00000080
+enum mvtwsi_ctrl_register_fields {
+       /* Acknowledge bit */
+       MVTWSI_CONTROL_ACK      = 0x00000004,
+       /* Interrupt flag */
+       MVTWSI_CONTROL_IFLG     = 0x00000008,
+       /* Stop bit */
+       MVTWSI_CONTROL_STOP     = 0x00000010,
+       /* Start bit */
+       MVTWSI_CONTROL_START    = 0x00000020,
+       /* I2C enable */
+       MVTWSI_CONTROL_TWSIEN   = 0x00000040,
+       /* Interrupt enable */
+       MVTWSI_CONTROL_INTEN    = 0x00000080,
+};
 
 /*
- * On sun6i and newer IFLG is a write-clear bit which is cleared by writing 1,
- * on other platforms it is a normal r/w bit which is cleared by writing 0.
+ * On sun6i and newer, IFLG is a write-clear bit, which is cleared by writing 1;
+ * on other platforms, it is a normal r/w bit, which is cleared by writing 0.
  */
 
 #ifdef CONFIG_SUNXI_GEN_SUN6I
@@ -84,53 +115,95 @@ struct  mvtwsi_registers {
 #endif
 
 /*
- * Status register values -- only those expected in normal master
- * operation on non-10-bit-address devices; whatever status we don't
- * expect in nominal conditions (bus errors, arbitration losses,
- * missing ACKs...) we just pass back to the caller as an error
+ * enum mvstwsi_status_values - Possible values of I2C controller's status
+ * register
+ *
+ * Only those statuses expected in normal master operation on
+ * non-10-bit-address devices are specified.
+ *
+ * Every status that's unexpected during normal operation (bus errors,
+ * arbitration losses, missing ACKs...) is passed back to the caller as an error
  * code.
  */
+enum mvstwsi_status_values {
+       /* START condition transmitted */
+       MVTWSI_STATUS_START             = 0x08,
+       /* Repeated START condition transmitted */
+       MVTWSI_STATUS_REPEATED_START    = 0x10,
+       /* Address + write bit transmitted, ACK received */
+       MVTWSI_STATUS_ADDR_W_ACK        = 0x18,
+       /* Data transmitted, ACK received */
+       MVTWSI_STATUS_DATA_W_ACK        = 0x28,
+       /* Address + read bit transmitted, ACK received */
+       MVTWSI_STATUS_ADDR_R_ACK        = 0x40,
+       /* Address + read bit transmitted, ACK not received */
+       MVTWSI_STATUS_ADDR_R_NAK        = 0x48,
+       /* Data received, ACK transmitted */
+       MVTWSI_STATUS_DATA_R_ACK        = 0x50,
+       /* Data received, ACK not transmitted */
+       MVTWSI_STATUS_DATA_R_NAK        = 0x58,
+       /* No relevant status */
+       MVTWSI_STATUS_IDLE              = 0xF8,
+};
 
-#define        MVTWSI_STATUS_START             0x08
-#define        MVTWSI_STATUS_REPEATED_START    0x10
-#define        MVTWSI_STATUS_ADDR_W_ACK        0x18
-#define        MVTWSI_STATUS_DATA_W_ACK        0x28
-#define        MVTWSI_STATUS_ADDR_R_ACK        0x40
-#define        MVTWSI_STATUS_ADDR_R_NAK        0x48
-#define        MVTWSI_STATUS_DATA_R_ACK        0x50
-#define        MVTWSI_STATUS_DATA_R_NAK        0x58
-#define        MVTWSI_STATUS_IDLE              0xF8
+/*
+ * enum mvstwsi_ack_flags - Determine whether a read byte should be
+ * acknowledged or not.
+ */
+enum mvtwsi_ack_flags {
+       /* Send NAK after received byte */
+       MVTWSI_READ_NAK = 0,
+       /* Send ACK after received byte */
+       MVTWSI_READ_ACK = 1,
+};
 
 /*
- * MVTWSI controller base
+ * calc_tick() - Calculate the duration of a clock cycle from the I2C speed
+ *
+ * @speed:     The speed in Hz to calculate the clock cycle duration for.
+ * @return The duration of a clock cycle in ns.
  */
+inline uint calc_tick(uint speed)
+{
+       /* One tick = the duration of a period at the specified speed in ns (we
+        * add 100 ns to be on the safe side) */
+       return (1000000000u / speed) + 100;
+}
 
+#ifndef CONFIG_DM_I2C
+
+/*
+ * twsi_get_base() - Get controller register base for specified adapter
+ *
+ * @adap:      Adapter to get the register base for.
+ * @return Register base for the specified adapter.
+ */
 static struct mvtwsi_registers *twsi_get_base(struct i2c_adapter *adap)
 {
        switch (adap->hwadapnr) {
 #ifdef CONFIG_I2C_MVTWSI_BASE0
        case 0:
-               return (struct mvtwsi_registers *) CONFIG_I2C_MVTWSI_BASE0;
+               return (struct mvtwsi_registers *)CONFIG_I2C_MVTWSI_BASE0;
 #endif
 #ifdef CONFIG_I2C_MVTWSI_BASE1
        case 1:
-               return (struct mvtwsi_registers *) CONFIG_I2C_MVTWSI_BASE1;
+               return (struct mvtwsi_registers *)CONFIG_I2C_MVTWSI_BASE1;
 #endif
 #ifdef CONFIG_I2C_MVTWSI_BASE2
        case 2:
-               return (struct mvtwsi_registers *) CONFIG_I2C_MVTWSI_BASE2;
+               return (struct mvtwsi_registers *)CONFIG_I2C_MVTWSI_BASE2;
 #endif
 #ifdef CONFIG_I2C_MVTWSI_BASE3
        case 3:
-               return (struct mvtwsi_registers *) CONFIG_I2C_MVTWSI_BASE3;
+               return (struct mvtwsi_registers *)CONFIG_I2C_MVTWSI_BASE3;
 #endif
 #ifdef CONFIG_I2C_MVTWSI_BASE4
        case 4:
-               return (struct mvtwsi_registers *) CONFIG_I2C_MVTWSI_BASE4;
+               return (struct mvtwsi_registers *)CONFIG_I2C_MVTWSI_BASE4;
 #endif
 #ifdef CONFIG_I2C_MVTWSI_BASE5
        case 5:
-               return (struct mvtwsi_registers *) CONFIG_I2C_MVTWSI_BASE5;
+               return (struct mvtwsi_registers *)CONFIG_I2C_MVTWSI_BASE5;
 #endif
        default:
                printf("Missing mvtwsi controller %d base\n", adap->hwadapnr);
@@ -139,30 +212,48 @@ static struct mvtwsi_registers *twsi_get_base(struct i2c_adapter *adap)
 
        return NULL;
 }
+#endif
 
 /*
- * Returned statuses are 0 for success and nonzero otherwise.
- * Currently, cmd_i2c and cmd_eeprom do not interpret an error status.
- * Thus to ease debugging, the return status contains some debug info:
- * - bits 31..24 are error class: 1 is timeout, 2 is 'status mismatch'.
- * - bits 23..16 are the last value of the control register.
- * - bits 15..8 are the last value of the status register.
- * - bits 7..0 are the expected value of the status register.
+ * enum mvtwsi_error_class - types of I2C errors
  */
+enum mvtwsi_error_class {
+       /* The controller returned a different status than expected */
+       MVTWSI_ERROR_WRONG_STATUS       = 0x01,
+       /* The controller timed out */
+       MVTWSI_ERROR_TIMEOUT            = 0x02,
+};
 
-#define MVTWSI_ERROR_WRONG_STATUS      0x01
-#define MVTWSI_ERROR_TIMEOUT           0x02
-
-#define MVTWSI_ERROR(ec, lc, ls, es) (((ec << 24) & 0xFF000000) | \
-       ((lc << 16) & 0x00FF0000) | ((ls<<8) & 0x0000FF00) | (es & 0xFF))
+/*
+ * mvtwsi_error() - Build I2C return code from error information
+ *
+ * For debugging purposes, this function packs some information of an occurred
+ * error into a return code. These error codes are returned from I2C API
+ * functions (i2c_{read,write}, dm_i2c_{read,write}, etc.).
+ *
+ * @ec:                The error class of the error (enum mvtwsi_error_class).
+ * @lc:                The last value of the control register.
+ * @ls:                The last value of the status register.
+ * @es:                The expected value of the status register.
+ * @return The generated error code.
+ */
+inline uint mvtwsi_error(uint ec, uint lc, uint ls, uint es)
+{
+       return ((ec << 24) & 0xFF000000)
+              | ((lc << 16) & 0x00FF0000)
+              | ((ls << 8) & 0x0000FF00)
+              | (es & 0xFF);
+}
 
 /*
- * Wait for IFLG to raise, or return 'timeout'; then if status is as expected,
- * return 0 (ok) or return 'wrong status'.
+ * twsi_wait() - Wait for I2C bus interrupt flag and check status, or time out.
+ *
+ * @return Zero if status is as expected, or a non-zero code if either a time
+ *        out occurred, or the status was not the expected one.
  */
-static int twsi_wait(struct i2c_adapter *adap, int expected_status)
+static int twsi_wait(struct mvtwsi_registers *twsi, int expected_status,
+                    uint tick)
 {
-       struct mvtwsi_registers *twsi = twsi_get_base(adap);
        int control, status;
        int timeout = 1000;
 
@@ -173,105 +264,140 @@ static int twsi_wait(struct i2c_adapter *adap, int expected_status)
                        if (status == expected_status)
                                return 0;
                        else
-                               return MVTWSI_ERROR(
+                               return mvtwsi_error(
                                        MVTWSI_ERROR_WRONG_STATUS,
                                        control, status, expected_status);
                }
-               udelay(10); /* one clock cycle at 100 kHz */
+               ndelay(tick); /* One clock cycle */
        } while (timeout--);
        status = readl(&twsi->status);
-       return MVTWSI_ERROR(
-               MVTWSI_ERROR_TIMEOUT, control, status, expected_status);
+       return mvtwsi_error(MVTWSI_ERROR_TIMEOUT, control, status,
+                           expected_status);
 }
 
 /*
- * Assert the START condition, either in a single I2C transaction
- * or inside back-to-back ones (repeated starts).
+ * twsi_start() - Assert a START condition on the bus.
+ *
+ * This function is used in both single I2C transactions and inside
+ * back-to-back transactions (repeated starts).
+ *
+ * @twsi:              The MVTWSI register structure to use.
+ * @expected_status:   The I2C bus status expected to be asserted after the
+ *                     operation completion.
+ * @tick:              The duration of a clock cycle at the current I2C speed.
+ * @return Zero if status is as expected, or a non-zero code if either a time
+ *        out occurred or the status was not the expected one.
  */
-static int twsi_start(struct i2c_adapter *adap, int expected_status, u8 *flags)
+static int twsi_start(struct mvtwsi_registers *twsi, int expected_status,
+                     uint tick)
 {
-       struct mvtwsi_registers *twsi = twsi_get_base(adap);
-
-       /* globally set TWSIEN in case it was not */
-       *flags |= MVTWSI_CONTROL_TWSIEN;
-       /* assert START */
-       writel(*flags | MVTWSI_CONTROL_START |
-                                   MVTWSI_CONTROL_CLEAR_IFLG, &twsi->control);
-       /* wait for controller to process START */
-       return twsi_wait(adap, expected_status);
+       /* Assert START */
+       writel(MVTWSI_CONTROL_TWSIEN | MVTWSI_CONTROL_START |
+              MVTWSI_CONTROL_CLEAR_IFLG, &twsi->control);
+       /* Wait for controller to process START */
+       return twsi_wait(twsi, expected_status, tick);
 }
 
 /*
- * Send a byte (i2c address or data).
+ * twsi_send() - Send a byte on the I2C bus.
+ *
+ * The byte may be part of an address byte or data.
+ *
+ * @twsi:              The MVTWSI register structure to use.
+ * @byte:              The byte to send.
+ * @expected_status:   The I2C bus status expected to be asserted after the
+ *                     operation completion.
+ * @tick:              The duration of a clock cycle at the current I2C speed.
+ * @return Zero if status is as expected, or a non-zero code if either a time
+ *        out occurred or the status was not the expected one.
  */
-static int twsi_send(struct i2c_adapter *adap, u8 byte, int expected_status,
-                    u8 *flags)
+static int twsi_send(struct mvtwsi_registers *twsi, u8 byte,
+                    int expected_status, uint tick)
 {
-       struct mvtwsi_registers *twsi = twsi_get_base(adap);
-
-       /* put byte in data register for sending */
+       /* Write byte to data register for sending */
        writel(byte, &twsi->data);
-       /* clear any pending interrupt -- that'll cause sending */
-       writel(*flags | MVTWSI_CONTROL_CLEAR_IFLG, &twsi->control);
-       /* wait for controller to receive byte and check ACK */
-       return twsi_wait(adap, expected_status);
+       /* Clear any pending interrupt -- that will cause sending */
+       writel(MVTWSI_CONTROL_TWSIEN | MVTWSI_CONTROL_CLEAR_IFLG,
+              &twsi->control);
+       /* Wait for controller to receive byte, and check ACK */
+       return twsi_wait(twsi, expected_status, tick);
 }
 
 /*
- * Receive a byte.
- * Global mvtwsi_control_flags variable says if we should ack or nak.
+ * twsi_recv() - Receive a byte on the I2C bus.
+ *
+ * The static variable mvtwsi_control_flags controls whether we ack or nak.
+ *
+ * @twsi:              The MVTWSI register structure to use.
+ * @byte:              The byte to send.
+ * @ack_flag:          Flag that determines whether the received byte should
+ *                     be acknowledged by the controller or not (sent ACK/NAK).
+ * @tick:              The duration of a clock cycle at the current I2C speed.
+ * @return Zero if status is as expected, or a non-zero code if either a time
+ *        out occurred or the status was not the expected one.
  */
-static int twsi_recv(struct i2c_adapter *adap, u8 *byte, u8 *flags)
+static int twsi_recv(struct mvtwsi_registers *twsi, u8 *byte, int ack_flag,
+                    uint tick)
 {
-       struct mvtwsi_registers *twsi = twsi_get_base(adap);
-       int expected_status, status;
-
-       /* compute expected status based on ACK bit in global control flags */
-       if (*flags & MVTWSI_CONTROL_ACK)
-               expected_status = MVTWSI_STATUS_DATA_R_ACK;
-       else
-               expected_status = MVTWSI_STATUS_DATA_R_NAK;
-       /* acknowledge *previous state* and launch receive */
-       writel(*flags | MVTWSI_CONTROL_CLEAR_IFLG, &twsi->control);
-       /* wait for controller to receive byte and assert ACK or NAK */
-       status = twsi_wait(adap, expected_status);
-       /* if we did receive expected byte then store it */
+       int expected_status, status, control;
+
+       /* Compute expected status based on passed ACK flag */
+       expected_status = ack_flag ? MVTWSI_STATUS_DATA_R_ACK :
+                         MVTWSI_STATUS_DATA_R_NAK;
+       /* Acknowledge *previous state*, and launch receive */
+       control = MVTWSI_CONTROL_TWSIEN;
+       control |= ack_flag == MVTWSI_READ_ACK ? MVTWSI_CONTROL_ACK : 0;
+       writel(control | MVTWSI_CONTROL_CLEAR_IFLG, &twsi->control);
+       /* Wait for controller to receive byte, and assert ACK or NAK */
+       status = twsi_wait(twsi, expected_status, tick);
+       /* If we did receive the expected byte, store it */
        if (status == 0)
                *byte = readl(&twsi->data);
-       /* return status */
        return status;
 }
 
 /*
- * Assert the STOP condition.
- * This is also used to force the bus back in idle (SDA=SCL=1).
+ * twsi_stop() - Assert a STOP condition on the bus.
+ *
+ * This function is also used to force the bus back to idle state (SDA =
+ * SCL = 1).
+ *
+ * @twsi:      The MVTWSI register structure to use.
+ * @tick:      The duration of a clock cycle at the current I2C speed.
+ * @return Zero if the operation succeeded, or a non-zero code if a time out
+ *        occurred.
  */
-static int twsi_stop(struct i2c_adapter *adap, int status)
+static int twsi_stop(struct mvtwsi_registers *twsi, uint tick)
 {
-       struct mvtwsi_registers *twsi = twsi_get_base(adap);
        int control, stop_status;
+       int status = 0;
        int timeout = 1000;
 
-       /* assert STOP */
+       /* Assert STOP */
        control = MVTWSI_CONTROL_TWSIEN | MVTWSI_CONTROL_STOP;
        writel(control | MVTWSI_CONTROL_CLEAR_IFLG, &twsi->control);
-       /* wait for IDLE; IFLG won't rise so twsi_wait() is no use. */
+       /* Wait for IDLE; IFLG won't rise, so we can't use twsi_wait() */
        do {
                stop_status = readl(&twsi->status);
                if (stop_status == MVTWSI_STATUS_IDLE)
                        break;
-               udelay(10); /* one clock cycle at 100 kHz */
+               ndelay(tick); /* One clock cycle */
        } while (timeout--);
        control = readl(&twsi->control);
        if (stop_status != MVTWSI_STATUS_IDLE)
-               if (status == 0)
-                       status = MVTWSI_ERROR(
-                               MVTWSI_ERROR_TIMEOUT,
-                               control, status, MVTWSI_STATUS_IDLE);
+               status = mvtwsi_error(MVTWSI_ERROR_TIMEOUT,
+                                     control, status, MVTWSI_STATUS_IDLE);
        return status;
 }
 
-static unsigned int twsi_calc_freq(const int n, const int m)
+/*
+ * twsi_calc_freq() - Compute I2C frequency depending on m and n parameters.
+ *
+ * @n:         Parameter 'n' for the frequency calculation algorithm.
+ * @m:         Parameter 'm' for the frequency calculation algorithm.
+ * @return The I2C frequency corresponding to the passed m and n parameters.
+ */
+static uint twsi_calc_freq(const int n, const int m)
 {
 #ifdef CONFIG_SUNXI
        return CONFIG_SYS_TCLK / (10 * (m + 1) * (1 << n));
@@ -281,176 +407,303 @@ static unsigned int twsi_calc_freq(const int n, const int m)
 }
 
 /*
- * Reset controller.
- * Controller reset also resets the baud rate and slave address, so
- * they must be re-established afterwards.
+ * twsi_reset() - Reset the I2C controller.
+ *
+ * Resetting the controller also resets the baud rate and slave address, hence
+ * they must be re-established after the reset.
+ *
+ * @twsi:      The MVTWSI register structure to use.
  */
-static void twsi_reset(struct i2c_adapter *adap)
+static void twsi_reset(struct mvtwsi_registers *twsi)
 {
-       struct mvtwsi_registers *twsi = twsi_get_base(adap);
-
-       /* reset controller */
+       /* Reset controller */
        writel(0, &twsi->soft_reset);
-       /* wait 2 ms -- this is what the Marvell LSP does */
+       /* Wait 2 ms -- this is what the Marvell LSP does */
        udelay(20000);
 }
 
 /*
- * I2C init called by cmd_i2c when doing 'i2c reset'.
- * Sets baud to the highest possible value not exceeding requested one.
+ * __twsi_i2c_set_bus_speed() - Set the speed of the I2C controller.
+ *
+ * This function sets baud rate to the highest possible value that does not
+ * exceed the requested rate.
+ *
+ * @twsi:              The MVTWSI register structure to use.
+ * @requested_speed:   The desired frequency the controller should run at
+ *                     in Hz.
+ * @return The actual frequency the controller was configured to.
  */
-static unsigned int twsi_i2c_set_bus_speed(struct i2c_adapter *adap,
-                                          unsigned int requested_speed)
+static uint __twsi_i2c_set_bus_speed(struct mvtwsi_registers *twsi,
+                                    uint requested_speed)
 {
-       struct mvtwsi_registers *twsi = twsi_get_base(adap);
-       unsigned int tmp_speed, highest_speed, n, m;
-       unsigned int baud = 0x44; /* baudrate at controller reset */
+       uint tmp_speed, highest_speed, n, m;
+       uint baud = 0x44; /* Baud rate after controller reset */
 
-       /* use actual speed to collect progressively higher values */
        highest_speed = 0;
-       /* compute m, n setting for highest speed not above requested speed */
+       /* Successively try m, n combinations, and use the combination
+        * resulting in the largest speed that's not above the requested
+        * speed */
        for (n = 0; n < 8; n++) {
                for (m = 0; m < 16; m++) {
                        tmp_speed = twsi_calc_freq(n, m);
-                       if ((tmp_speed <= requested_speed)
-                        && (tmp_speed > highest_speed)) {
+                       if ((tmp_speed <= requested_speed) &&
+                           (tmp_speed > highest_speed)) {
                                highest_speed = tmp_speed;
                                baud = (m << 3) | n;
                        }
                }
        }
        writel(baud, &twsi->baudrate);
-       return 0;
+
+       /* Wait for controller for one tick */
+#ifdef CONFIG_DM_I2C
+       ndelay(calc_tick(highest_speed));
+#else
+       ndelay(10000);
+#endif
+       return highest_speed;
 }
 
-static void twsi_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd)
+/*
+ * __twsi_i2c_init() - Initialize the I2C controller.
+ *
+ * @twsi:              The MVTWSI register structure to use.
+ * @speed:             The initial frequency the controller should run at
+ *                     in Hz.
+ * @slaveadd:          The I2C address to be set for the I2C master.
+ * @actual_speed:      A output parameter that receives the actual frequency
+ *                     in Hz the controller was set to by the function.
+ * @return Zero if the operation succeeded, or a non-zero code if a time out
+ *        occurred.
+ */
+static void __twsi_i2c_init(struct mvtwsi_registers *twsi, int speed,
+                           int slaveadd, uint *actual_speed)
 {
-       struct mvtwsi_registers *twsi = twsi_get_base(adap);
-
-       /* reset controller */
-       twsi_reset(adap);
-       /* set speed */
-       twsi_i2c_set_bus_speed(adap, speed);
-       /* set slave address even though we don't use it */
+       /* Reset controller */
+       twsi_reset(twsi);
+       /* Set speed */
+       *actual_speed = __twsi_i2c_set_bus_speed(twsi, speed);
+       /* Set slave address; even though we don't use it */
        writel(slaveadd, &twsi->slave_address);
        writel(0, &twsi->xtnd_slave_addr);
-       /* assert STOP but don't care for the result */
-       (void) twsi_stop(adap, 0);
+       /* Assert STOP, but don't care for the result */
+#ifdef CONFIG_DM_I2C
+       (void) twsi_stop(twsi, calc_tick(*actual_speed));
+#else
+       (void) twsi_stop(twsi, 10000);
+#endif
 }
 
 /*
- * Begin I2C transaction with expected start status, at given address.
- * Common to i2c_probe, i2c_read and i2c_write.
- * Expected address status will derive from direction bit (bit 0) in addr.
+ * i2c_begin() - Start a I2C transaction.
+ *
+ * Begin a I2C transaction with a given expected start status and chip address.
+ * A START is asserted, and the address byte is sent to the I2C controller. The
+ * expected address status will be derived from the direction bit (bit 0) of
+ * the address byte.
+ *
+ * @twsi:                      The MVTWSI register structure to use.
+ * @expected_start_status:     The I2C status the controller is expected to
+ *                             assert after the address byte was sent.
+ * @addr:                      The address byte to be sent.
+ * @tick:                      The duration of a clock cycle at the current
+ *                             I2C speed.
+ * @return Zero if the operation succeeded, or a non-zero code if a time out or
+ *        unexpected I2C status occurred.
  */
-static int i2c_begin(struct i2c_adapter *adap, int expected_start_status,
-                    u8 addr, u8 *flags)
+static int i2c_begin(struct mvtwsi_registers *twsi, int expected_start_status,
+                    u8 addr, uint tick)
 {
        int status, expected_addr_status;
 
-       /* compute expected address status from direction bit in addr */
-       if (addr & 1) /* reading */
+       /* Compute the expected address status from the direction bit in
+        * the address byte */
+       if (addr & 1) /* Reading */
                expected_addr_status = MVTWSI_STATUS_ADDR_R_ACK;
-       else /* writing */
+       else /* Writing */
                expected_addr_status = MVTWSI_STATUS_ADDR_W_ACK;
-       /* assert START */
-       status = twsi_start(adap, expected_start_status, flags);
-       /* send out the address if the start went well */
+       /* Assert START */
+       status = twsi_start(twsi, expected_start_status, tick);
+       /* Send out the address if the start went well */
        if (status == 0)
-               status = twsi_send(adap, addr, expected_addr_status,
-                                  flags);
-       /* return ok or status of first failure to caller */
+               status = twsi_send(twsi, addr, expected_addr_status, tick);
+       /* Return 0, or the status of the first failure */
        return status;
 }
 
 /*
- * I2C probe called by cmd_i2c when doing 'i2c probe'.
- * Begin read, nak data byte, end.
+ * __twsi_i2c_probe_chip() - Probe the given I2C chip address.
+ *
+ * This function begins a I2C read transaction, does a dummy read and NAKs; if
+ * the procedure succeeds, the chip is considered to be present.
+ *
+ * @twsi:      The MVTWSI register structure to use.
+ * @chip:      The chip address to probe.
+ * @tick:      The duration of a clock cycle at the current I2C speed.
+ * @return Zero if the operation succeeded, or a non-zero code if a time out or
+ *        unexpected I2C status occurred.
  */
-static int twsi_i2c_probe(struct i2c_adapter *adap, uchar chip)
+static int __twsi_i2c_probe_chip(struct mvtwsi_registers *twsi, uchar chip,
+                                uint tick)
 {
        u8 dummy_byte;
-       u8 flags = 0;
        int status;
 
-       /* begin i2c read */
-       status = i2c_begin(adap, MVTWSI_STATUS_START, (chip << 1) | 1, &flags);
-       /* dummy read was accepted: receive byte but NAK it. */
+       /* Begin i2c read */
+       status = i2c_begin(twsi, MVTWSI_STATUS_START, (chip << 1) | 1, tick);
+       /* Dummy read was accepted: receive byte, but NAK it. */
        if (status == 0)
-               status = twsi_recv(adap, &dummy_byte, &flags);
+               status = twsi_recv(twsi, &dummy_byte, MVTWSI_READ_NAK, tick);
        /* Stop transaction */
-       twsi_stop(adap, 0);
-       /* return 0 or status of first failure */
+       twsi_stop(twsi, tick);
+       /* Return 0, or the status of the first failure */
        return status;
 }
 
 /*
- * I2C read called by cmd_i2c when doing 'i2c read' and by cmd_eeprom.c
- * Begin write, send address byte(s), begin read, receive data bytes, end.
- *
- * NOTE: some EEPROMS want a stop right before the second start, while
- * some will choke if it is there. Deciding which we should do is eeprom
- * stuff, not i2c, but at the moment the APIs won't let us put it in
- * cmd_eeprom, so we have to choose here, and for the moment that'll be
- * a repeated start without a preceding stop.
+ * __twsi_i2c_read() - Read data from a I2C chip.
+ *
+ * This function begins a I2C write transaction, and transmits the address
+ * bytes; then begins a I2C read transaction, and receives the data bytes.
+ *
+ * NOTE: Some devices want a stop right before the second start, while some
+ * will choke if it is there. Since deciding this is not yet supported in
+ * higher level APIs, we need to make a decision here, and for the moment that
+ * will be a repeated start without a preceding stop.
+ *
+ * @twsi:      The MVTWSI register structure to use.
+ * @chip:      The chip address to read from.
+ * @addr:      The address bytes to send.
+ * @alen:      The length of the address bytes in bytes.
+ * @data:      The buffer to receive the data read from the chip (has to have
+ *             a size of at least 'length' bytes).
+ * @length:    The amount of data to be read from the chip in bytes.
+ * @tick:      The duration of a clock cycle at the current I2C speed.
+ * @return Zero if the operation succeeded, or a non-zero code if a time out or
+ *        unexpected I2C status occurred.
  */
-static int twsi_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr,
-                       int alen, uchar *data, int length)
+static int __twsi_i2c_read(struct mvtwsi_registers *twsi, uchar chip,
+                          u8 *addr, int alen, uchar *data, int length,
+                          uint tick)
 {
-       int status;
-       u8 flags = 0;
-
-       /* begin i2c write to send the address bytes */
-       status = i2c_begin(adap, MVTWSI_STATUS_START, (chip << 1), &flags);
-       /* send addr bytes */
-       while ((status == 0) && alen--)
-               status = twsi_send(adap, addr >> (8*alen),
-                       MVTWSI_STATUS_DATA_W_ACK, &flags);
-       /* begin i2c read to receive eeprom data bytes */
-       if (status == 0)
-               status = i2c_begin(adap, MVTWSI_STATUS_REPEATED_START,
-                                  (chip << 1) | 1, &flags);
-       /* prepare ACK if at least one byte must be received */
-       if (length > 0)
-               flags |= MVTWSI_CONTROL_ACK;
-       /* now receive actual bytes */
-       while ((status == 0) && length--) {
-               /* reset NAK if we if no more to read now */
-               if (length == 0)
-                       flags &= ~MVTWSI_CONTROL_ACK;
-               /* read current byte */
-               status = twsi_recv(adap, data++, &flags);
+       int status = 0;
+       int stop_status;
+       int expected_start = MVTWSI_STATUS_START;
+
+       if (alen > 0) {
+               /* Begin i2c write to send the address bytes */
+               status = i2c_begin(twsi, expected_start, (chip << 1), tick);
+               /* Send address bytes */
+               while ((status == 0) && alen--)
+                       status = twsi_send(twsi, *(addr++),
+                                          MVTWSI_STATUS_DATA_W_ACK, tick);
+               /* Send repeated STARTs after the initial START */
+               expected_start = MVTWSI_STATUS_REPEATED_START;
        }
+       /* Begin i2c read to receive data bytes */
+       if (status == 0)
+               status = i2c_begin(twsi, expected_start, (chip << 1) | 1, tick);
+       /* Receive actual data bytes; set NAK if we if we have nothing more to
+        * read */
+       while ((status == 0) && length--)
+               status = twsi_recv(twsi, data++,
+                                  length > 0 ?
+                                  MVTWSI_READ_ACK : MVTWSI_READ_NAK, tick);
        /* Stop transaction */
-       status = twsi_stop(adap, status);
-       /* return 0 or status of first failure */
-       return status;
+       stop_status = twsi_stop(twsi, tick);
+       /* Return 0, or the status of the first failure */
+       return status != 0 ? status : stop_status;
 }
 
 /*
- * I2C write called by cmd_i2c when doing 'i2c write' and by cmd_eeprom.c
- * Begin write, send address byte(s), send data bytes, end.
+ * __twsi_i2c_write() - Send data to a I2C chip.
+ *
+ * This function begins a I2C write transaction, and transmits the address
+ * bytes; then begins a new I2C write transaction, and sends the data bytes.
+ *
+ * @twsi:      The MVTWSI register structure to use.
+ * @chip:      The chip address to read from.
+ * @addr:      The address bytes to send.
+ * @alen:      The length of the address bytes in bytes.
+ * @data:      The buffer containing the data to be sent to the chip.
+ * @length:    The length of data to be sent to the chip in bytes.
+ * @tick:      The duration of a clock cycle at the current I2C speed.
+ * @return Zero if the operation succeeded, or a non-zero code if a time out or
+ *        unexpected I2C status occurred.
  */
-static int twsi_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr,
-                       int alen, uchar *data, int length)
+static int __twsi_i2c_write(struct mvtwsi_registers *twsi, uchar chip,
+                           u8 *addr, int alen, uchar *data, int length,
+                           uint tick)
 {
-       int status;
-       u8 flags = 0;
-
-       /* begin i2c write to send the eeprom adress bytes then data bytes */
-       status = i2c_begin(adap, MVTWSI_STATUS_START, (chip << 1), &flags);
-       /* send addr bytes */
-       while ((status == 0) && alen--)
-               status = twsi_send(adap, addr >> (8*alen),
-                       MVTWSI_STATUS_DATA_W_ACK, &flags);
-       /* send data bytes */
+       int status, stop_status;
+
+       /* Begin i2c write to send first the address bytes, then the
+        * data bytes */
+       status = i2c_begin(twsi, MVTWSI_STATUS_START, (chip << 1), tick);
+       /* Send address bytes */
+       while ((status == 0) && (alen-- > 0))
+               status = twsi_send(twsi, *(addr++), MVTWSI_STATUS_DATA_W_ACK,
+                                  tick);
+       /* Send data bytes */
        while ((status == 0) && (length-- > 0))
-               status = twsi_send(adap, *(data++), MVTWSI_STATUS_DATA_W_ACK,
-                                  &flags);
+               status = twsi_send(twsi, *(data++), MVTWSI_STATUS_DATA_W_ACK,
+                                  tick);
        /* Stop transaction */
-       status = twsi_stop(adap, status);
-       /* return 0 or status of first failure */
-       return status;
+       stop_status = twsi_stop(twsi, tick);
+       /* Return 0, or the status of the first failure */
+       return status != 0 ? status : stop_status;
+}
+
+#ifndef CONFIG_DM_I2C
+static void twsi_i2c_init(struct i2c_adapter *adap, int speed,
+                         int slaveadd)
+{
+       struct mvtwsi_registers *twsi = twsi_get_base(adap);
+       __twsi_i2c_init(twsi, speed, slaveadd, NULL);
+}
+
+static uint twsi_i2c_set_bus_speed(struct i2c_adapter *adap,
+                                  uint requested_speed)
+{
+       struct mvtwsi_registers *twsi = twsi_get_base(adap);
+       __twsi_i2c_set_bus_speed(twsi, requested_speed);
+       return 0;
+}
+
+static int twsi_i2c_probe(struct i2c_adapter *adap, uchar chip)
+{
+       struct mvtwsi_registers *twsi = twsi_get_base(adap);
+       return __twsi_i2c_probe_chip(twsi, chip, 10000);
+}
+
+static int twsi_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr,
+                        int alen, uchar *data, int length)
+{
+       struct mvtwsi_registers *twsi = twsi_get_base(adap);
+       u8 addr_bytes[4];
+
+       addr_bytes[0] = (addr >> 0) & 0xFF;
+       addr_bytes[1] = (addr >> 8) & 0xFF;
+       addr_bytes[2] = (addr >> 16) & 0xFF;
+       addr_bytes[3] = (addr >> 24) & 0xFF;
+
+       return __twsi_i2c_read(twsi, chip, addr_bytes, alen, data, length,
+                              10000);
+}
+
+static int twsi_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr,
+                         int alen, uchar *data, int length)
+{
+       struct mvtwsi_registers *twsi = twsi_get_base(adap);
+       u8 addr_bytes[4];
+
+       addr_bytes[0] = (addr >> 0) & 0xFF;
+       addr_bytes[1] = (addr >> 8) & 0xFF;
+       addr_bytes[2] = (addr >> 16) & 0xFF;
+       addr_bytes[3] = (addr >> 24) & 0xFF;
+
+       return __twsi_i2c_write(twsi, chip, addr_bytes, alen, data, length,
+                               10000);
 }
 
 #ifdef CONFIG_I2C_MVTWSI_BASE0
@@ -494,3 +747,99 @@ U_BOOT_I2C_ADAP_COMPLETE(twsi5, twsi_i2c_init, twsi_i2c_probe,
                         CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE, 5)
 
 #endif
+#else /* CONFIG_DM_I2C */
+
+static int mvtwsi_i2c_probe_chip(struct udevice *bus, u32 chip_addr,
+                                u32 chip_flags)
+{
+       struct mvtwsi_i2c_dev *dev = dev_get_priv(bus);
+       return __twsi_i2c_probe_chip(dev->base, chip_addr, dev->tick);
+}
+
+static int mvtwsi_i2c_set_bus_speed(struct udevice *bus, uint speed)
+{
+       struct mvtwsi_i2c_dev *dev = dev_get_priv(bus);
+
+       dev->speed = __twsi_i2c_set_bus_speed(dev->base, speed);
+       dev->tick = calc_tick(dev->speed);
+
+       return 0;
+}
+
+static int mvtwsi_i2c_ofdata_to_platdata(struct udevice *bus)
+{
+       struct mvtwsi_i2c_dev *dev = dev_get_priv(bus);
+
+       dev->base = dev_get_addr_ptr(bus);
+
+       if (!dev->base)
+               return -ENOMEM;
+
+       dev->index = fdtdec_get_int(gd->fdt_blob, bus->of_offset,
+                                   "cell-index", -1);
+       dev->slaveadd = fdtdec_get_int(gd->fdt_blob, bus->of_offset,
+                                      "u-boot,i2c-slave-addr", 0x0);
+       dev->speed = fdtdec_get_int(gd->fdt_blob, bus->of_offset,
+                                   "clock-frequency", 100000);
+       return 0;
+}
+
+static int mvtwsi_i2c_probe(struct udevice *bus)
+{
+       struct mvtwsi_i2c_dev *dev = dev_get_priv(bus);
+       uint actual_speed;
+
+       __twsi_i2c_init(dev->base, dev->speed, dev->slaveadd, &actual_speed);
+       dev->speed = actual_speed;
+       dev->tick = calc_tick(dev->speed);
+       return 0;
+}
+
+static int mvtwsi_i2c_xfer(struct udevice *bus, struct i2c_msg *msg, int nmsgs)
+{
+       struct mvtwsi_i2c_dev *dev = dev_get_priv(bus);
+       struct i2c_msg *dmsg, *omsg, dummy;
+
+       memset(&dummy, 0, sizeof(struct i2c_msg));
+
+       /* We expect either two messages (one with an offset and one with the
+        * actual data) or one message (just data or offset/data combined) */
+       if (nmsgs > 2 || nmsgs == 0) {
+               debug("%s: Only one or two messages are supported.", __func__);
+               return -1;
+       }
+
+       omsg = nmsgs == 1 ? &dummy : msg;
+       dmsg = nmsgs == 1 ? msg : msg + 1;
+
+       if (dmsg->flags & I2C_M_RD)
+               return __twsi_i2c_read(dev->base, dmsg->addr, omsg->buf,
+                                      omsg->len, dmsg->buf, dmsg->len,
+                                      dev->tick);
+       else
+               return __twsi_i2c_write(dev->base, dmsg->addr, omsg->buf,
+                                       omsg->len, dmsg->buf, dmsg->len,
+                                       dev->tick);
+}
+
+static const struct dm_i2c_ops mvtwsi_i2c_ops = {
+       .xfer           = mvtwsi_i2c_xfer,
+       .probe_chip     = mvtwsi_i2c_probe_chip,
+       .set_bus_speed  = mvtwsi_i2c_set_bus_speed,
+};
+
+static const struct udevice_id mvtwsi_i2c_ids[] = {
+       { .compatible = "marvell,mv64xxx-i2c", },
+       { /* sentinel */ }
+};
+
+U_BOOT_DRIVER(i2c_mvtwsi) = {
+       .name = "i2c_mvtwsi",
+       .id = UCLASS_I2C,
+       .of_match = mvtwsi_i2c_ids,
+       .probe = mvtwsi_i2c_probe,
+       .ofdata_to_platdata = mvtwsi_i2c_ofdata_to_platdata,
+       .priv_auto_alloc_size = sizeof(struct mvtwsi_i2c_dev),
+       .ops = &mvtwsi_i2c_ops,
+};
+#endif /* CONFIG_DM_I2C */
index a7f3fb4a7996d5f6188494ca7f09b23662673d18..00063431040313e5240c096e9f4fb7349acd2cf9 100644 (file)
@@ -39,6 +39,7 @@
  */
 
 #include <common.h>
+#include <dm.h>
 #include <i2c.h>
 
 #include <asm/arch/i2c.h>
@@ -53,10 +54,14 @@ DECLARE_GLOBAL_DATA_PTR;
 /* Absolutely safe for status update at 100 kHz I2C: */
 #define I2C_WAIT       200
 
-static int wait_for_bb(struct i2c_adapter *adap);
-static struct i2c *omap24_get_base(struct i2c_adapter *adap);
-static u16 wait_for_event(struct i2c_adapter *adap);
-static void flush_fifo(struct i2c_adapter *adap);
+struct omap_i2c {
+       struct udevice *clk;
+       struct i2c *regs;
+       unsigned int speed;
+       int waitdelay;
+       int clk_id;
+};
+
 static int omap24_i2c_findpsc(u32 *pscl, u32 *psch, uint speed)
 {
        unsigned int sampleclk, prescaler;
@@ -90,9 +95,96 @@ static int omap24_i2c_findpsc(u32 *pscl, u32 *psch, uint speed)
        }
        return -1;
 }
-static uint omap24_i2c_setspeed(struct i2c_adapter *adap, uint speed)
+
+/*
+ * Wait for the bus to be free by checking the Bus Busy (BB)
+ * bit to become clear
+ */
+static int wait_for_bb(struct i2c *i2c_base, int waitdelay)
+{
+       int timeout = I2C_TIMEOUT;
+       u16 stat;
+
+       writew(0xFFFF, &i2c_base->stat);        /* clear current interrupts...*/
+#if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX)
+       while ((stat = readw(&i2c_base->stat) & I2C_STAT_BB) && timeout--) {
+#else
+       /* Read RAW status */
+       while ((stat = readw(&i2c_base->irqstatus_raw) &
+               I2C_STAT_BB) && timeout--) {
+#endif
+               writew(stat, &i2c_base->stat);
+               udelay(waitdelay);
+       }
+
+       if (timeout <= 0) {
+               printf("Timed out in wait_for_bb: status=%04x\n",
+                      stat);
+               return 1;
+       }
+       writew(0xFFFF, &i2c_base->stat);         /* clear delayed stuff*/
+       return 0;
+}
+
+/*
+ * Wait for the I2C controller to complete current action
+ * and update status
+ */
+static u16 wait_for_event(struct i2c *i2c_base, int waitdelay)
+{
+       u16 status;
+       int timeout = I2C_TIMEOUT;
+
+       do {
+               udelay(waitdelay);
+#if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX)
+               status = readw(&i2c_base->stat);
+#else
+               /* Read RAW status */
+               status = readw(&i2c_base->irqstatus_raw);
+#endif
+       } while (!(status &
+                  (I2C_STAT_ROVR | I2C_STAT_XUDF | I2C_STAT_XRDY |
+                   I2C_STAT_RRDY | I2C_STAT_ARDY | I2C_STAT_NACK |
+                   I2C_STAT_AL)) && timeout--);
+
+       if (timeout <= 0) {
+               printf("Timed out in wait_for_event: status=%04x\n",
+                      status);
+               /*
+                * If status is still 0 here, probably the bus pads have
+                * not been configured for I2C, and/or pull-ups are missing.
+                */
+               printf("Check if pads/pull-ups of bus are properly configured\n");
+               writew(0xFFFF, &i2c_base->stat);
+               status = 0;
+       }
+
+       return status;
+}
+
+static void flush_fifo(struct i2c *i2c_base)
+{
+       u16 stat;
+
+       /*
+        * note: if you try and read data when its not there or ready
+        * you get a bus error
+        */
+       while (1) {
+               stat = readw(&i2c_base->stat);
+               if (stat == I2C_STAT_RRDY) {
+                       readb(&i2c_base->data);
+                       writew(I2C_STAT_RRDY, &i2c_base->stat);
+                       udelay(1000);
+               } else
+                       break;
+       }
+}
+
+static int __omap24_i2c_setspeed(struct i2c *i2c_base, uint speed,
+                                int *waitdelay)
 {
-       struct i2c *i2c_base = omap24_get_base(adap);
        int psc, fsscll = 0, fssclh = 0;
        int hsscll = 0, hssclh = 0;
        u32 scll = 0, sclh = 0;
@@ -142,8 +234,7 @@ static uint omap24_i2c_setspeed(struct i2c_adapter *adap, uint speed)
                }
        }
 
-       adap->speed     = speed;
-       adap->waitdelay = (10000000 / speed) * 2; /* wait for 20 clkperiods */
+       *waitdelay = (10000000 / speed) * 2; /* wait for 20 clkperiods */
        writew(0, &i2c_base->con);
        writew(psc, &i2c_base->psc);
        writew(scll, &i2c_base->scll);
@@ -154,9 +245,8 @@ static uint omap24_i2c_setspeed(struct i2c_adapter *adap, uint speed)
        return 0;
 }
 
-static void omap24_i2c_deblock(struct i2c_adapter *adap)
+static void omap24_i2c_deblock(struct i2c *i2c_base)
 {
-       struct i2c *i2c_base = omap24_get_base(adap);
        int i;
        u16 systest;
        u16 orgsystest;
@@ -200,9 +290,9 @@ static void omap24_i2c_deblock(struct i2c_adapter *adap)
        writew(orgsystest, &i2c_base->systest);
 }
 
-static void omap24_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd)
+static void __omap24_i2c_init(struct i2c *i2c_base, int speed, int slaveadd,
+                             int *waitdelay)
 {
-       struct i2c *i2c_base = omap24_get_base(adap);
        int timeout = I2C_TIMEOUT;
        int deblock = 1;
 
@@ -224,7 +314,7 @@ retry:
                udelay(1000);
        }
 
-       if (0 != omap24_i2c_setspeed(adap, speed)) {
+       if (0 != __omap24_i2c_setspeed(i2c_base, speed, waitdelay)) {
                printf("ERROR: failed to setup I2C bus-speed!\n");
                return;
        }
@@ -241,45 +331,24 @@ retry:
               I2C_IE_NACK_IE | I2C_IE_AL_IE, &i2c_base->ie);
 #endif
        udelay(1000);
-       flush_fifo(adap);
+       flush_fifo(i2c_base);
        writew(0xFFFF, &i2c_base->stat);
 
        /* Handle possible failed I2C state */
-       if (wait_for_bb(adap))
+       if (wait_for_bb(i2c_base, *waitdelay))
                if (deblock == 1) {
-                       omap24_i2c_deblock(adap);
+                       omap24_i2c_deblock(i2c_base);
                        deblock = 0;
                        goto retry;
                }
 }
 
-static void flush_fifo(struct i2c_adapter *adap)
-{
-       struct i2c *i2c_base = omap24_get_base(adap);
-       u16 stat;
-
-       /*
-        * note: if you try and read data when its not there or ready
-        * you get a bus error
-        */
-       while (1) {
-               stat = readw(&i2c_base->stat);
-               if (stat == I2C_STAT_RRDY) {
-                       readb(&i2c_base->data);
-                       writew(I2C_STAT_RRDY, &i2c_base->stat);
-                       udelay(1000);
-               } else
-                       break;
-       }
-}
-
 /*
  * i2c_probe: Use write access. Allows to identify addresses that are
  *            write-only (like the config register of dual-port EEPROMs)
  */
-static int omap24_i2c_probe(struct i2c_adapter *adap, uchar chip)
+static int __omap24_i2c_probe(struct i2c *i2c_base, int waitdelay, uchar chip)
 {
-       struct i2c *i2c_base = omap24_get_base(adap);
        u16 status;
        int res = 1; /* default = fail */
 
@@ -287,7 +356,7 @@ static int omap24_i2c_probe(struct i2c_adapter *adap, uchar chip)
                return res;
 
        /* Wait until bus is free */
-       if (wait_for_bb(adap))
+       if (wait_for_bb(i2c_base, waitdelay))
                return res;
 
        /* No data transfer, slave addr only */
@@ -296,7 +365,7 @@ static int omap24_i2c_probe(struct i2c_adapter *adap, uchar chip)
        writew(I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX |
               I2C_CON_STP, &i2c_base->con);
 
-       status = wait_for_event(adap);
+       status = wait_for_event(i2c_base, waitdelay);
 
        if ((status & ~I2C_STAT_XRDY) == 0 || (status & I2C_STAT_AL)) {
                /*
@@ -306,8 +375,8 @@ static int omap24_i2c_probe(struct i2c_adapter *adap, uchar chip)
                 * following 'if' section:
                 */
                if (status == I2C_STAT_XRDY)
-                       printf("i2c_probe: pads on bus %d probably not configured (status=0x%x)\n",
-                              adap->hwadapnr, status);
+                       printf("i2c_probe: pads on bus probably not configured (status=0x%x)\n",
+                              status);
 
                goto pr_exit;
        }
@@ -315,7 +384,7 @@ static int omap24_i2c_probe(struct i2c_adapter *adap, uchar chip)
        /* Check for ACK (!NAK) */
        if (!(status & I2C_STAT_NACK)) {
                res = 0;                                /* Device found */
-               udelay(adap->waitdelay);/* Required by AM335X in SPL */
+               udelay(waitdelay);/* Required by AM335X in SPL */
                /* Abort transfer (force idle state) */
                writew(I2C_CON_MST | I2C_CON_TRX, &i2c_base->con); /* Reset */
                udelay(1000);
@@ -323,7 +392,7 @@ static int omap24_i2c_probe(struct i2c_adapter *adap, uchar chip)
                       I2C_CON_STP, &i2c_base->con);            /* STP */
        }
 pr_exit:
-       flush_fifo(adap);
+       flush_fifo(i2c_base);
        writew(0xFFFF, &i2c_base->stat);
        return res;
 }
@@ -341,10 +410,9 @@ pr_exit:
  *           or that do not need a register address at all (such as some clock
  *           distributors).
  */
-static int omap24_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr,
-                          int alen, uchar *buffer, int len)
+static int __omap24_i2c_read(struct i2c *i2c_base, int waitdelay, uchar chip,
+                            uint addr, int alen, uchar *buffer, int len)
 {
-       struct i2c *i2c_base = omap24_get_base(adap);
        int i2c_error = 0;
        u16 status;
 
@@ -389,7 +457,7 @@ static int omap24_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr,
 #endif
 
        /* Wait until bus not busy */
-       if (wait_for_bb(adap))
+       if (wait_for_bb(i2c_base, waitdelay))
                return 1;
 
        /* Zero, one or two bytes reg address (offset) */
@@ -410,12 +478,12 @@ static int omap24_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr,
 #endif
                /* Send register offset */
                while (1) {
-                       status = wait_for_event(adap);
+                       status = wait_for_event(i2c_base, waitdelay);
                        /* Try to identify bus that is not padconf'd for I2C */
                        if (status == I2C_STAT_XRDY) {
                                i2c_error = 2;
-                               printf("i2c_read (addr phase): pads on bus %d probably not configured (status=0x%x)\n",
-                                      adap->hwadapnr, status);
+                               printf("i2c_read (addr phase): pads on bus probably not configured (status=0x%x)\n",
+                                      status);
                                goto rd_exit;
                        }
                        if (status == 0 || (status & I2C_STAT_NACK)) {
@@ -450,7 +518,7 @@ static int omap24_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr,
 
        /* Receive data */
        while (1) {
-               status = wait_for_event(adap);
+               status = wait_for_event(i2c_base, waitdelay);
                /*
                 * Try to identify bus that is not padconf'd for I2C. This
                 * state could be left over from previous transactions if
@@ -458,8 +526,8 @@ static int omap24_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr,
                 */
                if (status == I2C_STAT_XRDY) {
                        i2c_error = 2;
-                       printf("i2c_read (data phase): pads on bus %d probably not configured (status=0x%x)\n",
-                              adap->hwadapnr, status);
+                       printf("i2c_read (data phase): pads on bus probably not configured (status=0x%x)\n",
+                              status);
                        goto rd_exit;
                }
                if (status == 0 || (status & I2C_STAT_NACK)) {
@@ -477,16 +545,15 @@ static int omap24_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr,
        }
 
 rd_exit:
-       flush_fifo(adap);
+       flush_fifo(i2c_base);
        writew(0xFFFF, &i2c_base->stat);
        return i2c_error;
 }
 
 /* i2c_write: Address (reg offset) may be 0, 1 or 2 bytes long. */
-static int omap24_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr,
-                           int alen, uchar *buffer, int len)
+static int __omap24_i2c_write(struct i2c *i2c_base, int waitdelay, uchar chip,
+                             uint addr, int alen, uchar *buffer, int len)
 {
-       struct i2c *i2c_base = omap24_get_base(adap);
        int i;
        u16 status;
        int i2c_error = 0;
@@ -536,7 +603,7 @@ static int omap24_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr,
 #endif
 
        /* Wait until bus not busy */
-       if (wait_for_bb(adap))
+       if (wait_for_bb(i2c_base, waitdelay))
                return 1;
 
        /* Start address phase - will write regoffset + len bytes data */
@@ -549,12 +616,12 @@ static int omap24_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr,
 
        while (alen) {
                /* Must write reg offset (one or two bytes) */
-               status = wait_for_event(adap);
+               status = wait_for_event(i2c_base, waitdelay);
                /* Try to identify bus that is not padconf'd for I2C */
                if (status == I2C_STAT_XRDY) {
                        i2c_error = 2;
-                       printf("i2c_write: pads on bus %d probably not configured (status=0x%x)\n",
-                              adap->hwadapnr, status);
+                       printf("i2c_write: pads on bus probably not configured (status=0x%x)\n",
+                              status);
                        goto wr_exit;
                }
                if (status == 0 || (status & I2C_STAT_NACK)) {
@@ -576,7 +643,7 @@ static int omap24_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr,
        }
        /* Address phase is over, now write data */
        for (i = 0; i < len; i++) {
-               status = wait_for_event(adap);
+               status = wait_for_event(i2c_base, waitdelay);
                if (status == 0 || (status & I2C_STAT_NACK)) {
                        i2c_error = 1;
                        printf("i2c_write: error waiting for data ACK (status=0x%x)\n",
@@ -598,87 +665,22 @@ static int omap24_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr,
         * transferred on the bus.
         */
        do {
-               status = wait_for_event(adap);
+               status = wait_for_event(i2c_base, waitdelay);
        } while (!(status & I2C_STAT_ARDY) && timeout--);
        if (timeout <= 0)
                printf("i2c_write: timed out writig last byte!\n");
 
 wr_exit:
-       flush_fifo(adap);
+       flush_fifo(i2c_base);
        writew(0xFFFF, &i2c_base->stat);
        return i2c_error;
 }
 
+#ifndef CONFIG_DM_I2C
 /*
- * Wait for the bus to be free by checking the Bus Busy (BB)
- * bit to become clear
- */
-static int wait_for_bb(struct i2c_adapter *adap)
-{
-       struct i2c *i2c_base = omap24_get_base(adap);
-       int timeout = I2C_TIMEOUT;
-       u16 stat;
-
-       writew(0xFFFF, &i2c_base->stat);        /* clear current interrupts...*/
-#if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX)
-       while ((stat = readw(&i2c_base->stat) & I2C_STAT_BB) && timeout--) {
-#else
-       /* Read RAW status */
-       while ((stat = readw(&i2c_base->irqstatus_raw) &
-               I2C_STAT_BB) && timeout--) {
-#endif
-               writew(stat, &i2c_base->stat);
-               udelay(adap->waitdelay);
-       }
-
-       if (timeout <= 0) {
-               printf("Timed out in wait_for_bb: status=%04x\n",
-                      stat);
-               return 1;
-       }
-       writew(0xFFFF, &i2c_base->stat);         /* clear delayed stuff*/
-       return 0;
-}
-
-/*
- * Wait for the I2C controller to complete current action
- * and update status
+ * The legacy I2C functions. These need to get removed once
+ * all users of this driver are converted to DM.
  */
-static u16 wait_for_event(struct i2c_adapter *adap)
-{
-       struct i2c *i2c_base = omap24_get_base(adap);
-       u16 status;
-       int timeout = I2C_TIMEOUT;
-
-       do {
-               udelay(adap->waitdelay);
-#if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX)
-               status = readw(&i2c_base->stat);
-#else
-               /* Read RAW status */
-               status = readw(&i2c_base->irqstatus_raw);
-#endif
-       } while (!(status &
-                  (I2C_STAT_ROVR | I2C_STAT_XUDF | I2C_STAT_XRDY |
-                   I2C_STAT_RRDY | I2C_STAT_ARDY | I2C_STAT_NACK |
-                   I2C_STAT_AL)) && timeout--);
-
-       if (timeout <= 0) {
-               printf("Timed out in wait_for_event: status=%04x\n",
-                      status);
-               /*
-                * If status is still 0 here, probably the bus pads have
-                * not been configured for I2C, and/or pull-ups are missing.
-                */
-               printf("Check if pads/pull-ups of bus %d are properly configured\n",
-                      adap->hwadapnr);
-               writew(0xFFFF, &i2c_base->stat);
-               status = 0;
-       }
-
-       return status;
-}
-
 static struct i2c *omap24_get_base(struct i2c_adapter *adap)
 {
        switch (adap->hwadapnr) {
@@ -710,6 +712,56 @@ static struct i2c *omap24_get_base(struct i2c_adapter *adap)
        return NULL;
 }
 
+
+static int omap24_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr,
+                          int alen, uchar *buffer, int len)
+{
+       struct i2c *i2c_base = omap24_get_base(adap);
+
+       return __omap24_i2c_read(i2c_base, adap->waitdelay, chip, addr,
+                                alen, buffer, len);
+}
+
+
+static int omap24_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr,
+                           int alen, uchar *buffer, int len)
+{
+       struct i2c *i2c_base = omap24_get_base(adap);
+
+       return __omap24_i2c_write(i2c_base, adap->waitdelay, chip, addr,
+                                 alen, buffer, len);
+}
+
+static uint omap24_i2c_setspeed(struct i2c_adapter *adap, uint speed)
+{
+       struct i2c *i2c_base = omap24_get_base(adap);
+       int ret;
+
+       ret = __omap24_i2c_setspeed(i2c_base, speed, &adap->waitdelay);
+       if (ret) {
+               error("%s: set i2c speed failed\n", __func__);
+               return ret;
+       }
+
+       adap->speed = speed;
+
+       return 0;
+}
+
+static void omap24_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd)
+{
+       struct i2c *i2c_base = omap24_get_base(adap);
+
+       return __omap24_i2c_init(i2c_base, speed, slaveadd, &adap->waitdelay);
+}
+
+static int omap24_i2c_probe(struct i2c_adapter *adap, uchar chip)
+{
+       struct i2c *i2c_base = omap24_get_base(adap);
+
+       return __omap24_i2c_probe(i2c_base, adap->waitdelay, chip);
+}
+
 #if !defined(CONFIG_SYS_OMAP24_I2C_SPEED1)
 #define CONFIG_SYS_OMAP24_I2C_SPEED1 CONFIG_SYS_OMAP24_I2C_SPEED
 #endif
@@ -769,3 +821,92 @@ U_BOOT_I2C_ADAP_COMPLETE(omap24_4, omap24_i2c_init, omap24_i2c_probe,
 #endif
 #endif
 #endif
+
+#else /* CONFIG_DM_I2C */
+
+static int omap_i2c_xfer(struct udevice *bus, struct i2c_msg *msg, int nmsgs)
+{
+       struct omap_i2c *priv = dev_get_priv(bus);
+       int ret;
+
+       debug("i2c_xfer: %d messages\n", nmsgs);
+       for (; nmsgs > 0; nmsgs--, msg++) {
+               debug("i2c_xfer: chip=0x%x, len=0x%x\n", msg->addr, msg->len);
+               if (msg->flags & I2C_M_RD) {
+                       ret = __omap24_i2c_read(priv->regs, priv->waitdelay,
+                                               msg->addr, 0, 0, msg->buf,
+                                               msg->len);
+               } else {
+                       ret = __omap24_i2c_write(priv->regs, priv->waitdelay,
+                                                msg->addr, 0, 0, msg->buf,
+                                                msg->len);
+               }
+               if (ret) {
+                       debug("i2c_write: error sending\n");
+                       return -EREMOTEIO;
+               }
+       }
+
+       return 0;
+}
+
+static int omap_i2c_set_bus_speed(struct udevice *bus, unsigned int speed)
+{
+       struct omap_i2c *priv = dev_get_priv(bus);
+
+       priv->speed = speed;
+
+       return __omap24_i2c_setspeed(priv->regs, speed, &priv->waitdelay);
+}
+
+static int omap_i2c_probe_chip(struct udevice *bus, uint chip_addr,
+                                    uint chip_flags)
+{
+       struct omap_i2c *priv = dev_get_priv(bus);
+
+       return __omap24_i2c_probe(priv->regs, priv->waitdelay, chip_addr);
+}
+
+static int omap_i2c_probe(struct udevice *bus)
+{
+       struct omap_i2c *priv = dev_get_priv(bus);
+
+       __omap24_i2c_init(priv->regs, priv->speed, 0, &priv->waitdelay);
+
+       return 0;
+}
+
+static int omap_i2c_ofdata_to_platdata(struct udevice *bus)
+{
+       struct omap_i2c *priv = dev_get_priv(bus);
+
+       priv->regs = map_physmem(dev_get_addr(bus), sizeof(void *),
+                                MAP_NOCACHE);
+       priv->speed = CONFIG_SYS_OMAP24_I2C_SPEED;
+
+       return 0;
+}
+
+static const struct dm_i2c_ops omap_i2c_ops = {
+       .xfer           = omap_i2c_xfer,
+       .probe_chip     = omap_i2c_probe_chip,
+       .set_bus_speed  = omap_i2c_set_bus_speed,
+};
+
+static const struct udevice_id omap_i2c_ids[] = {
+       { .compatible = "ti,omap4-i2c" },
+       { }
+};
+
+U_BOOT_DRIVER(i2c_omap) = {
+       .name   = "i2c_omap",
+       .id     = UCLASS_I2C,
+       .of_match = omap_i2c_ids,
+       .ofdata_to_platdata = omap_i2c_ofdata_to_platdata,
+       .probe  = omap_i2c_probe,
+       .priv_auto_alloc_size = sizeof(struct omap_i2c),
+       .ops    = &omap_i2c_ops,
+       .flags  = DM_FLAG_PRE_RELOC,
+};
+
+#endif /* CONFIG_DM_I2C */
index 2373037685c2762558fe1c3993057d7fdb7d298d..b84e351da7cf86c7c29ef7bed32afc99f7520053 100644 (file)
@@ -144,4 +144,9 @@ config QFW
          Hidden option to enable QEMU fw_cfg interface. This will be selected by
          either CONFIG_CMD_QFW or CONFIG_GENERATE_ACPI_TABLE.
 
+config I2C_EEPROM
+       bool "Enable driver for generic I2C-attached EEPROMs"
+       depends on MISC
+       help
+         Enable a generic driver for EEPROMs attached via I2C.
 endmenu
index 066639ba1f10018595baedf75006567b94c6ef98..fff6f0cdf95bc1bf5a821d002cd02658bfd3e68b 100644 (file)
@@ -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
index 98f19a68bf6fb4b0650e69dcf06bcfebc2c349e8..c4fbca0d3ae129a260d3073fe7387b4f6688ff6b 100644 (file)
@@ -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)) {
index 814134a2cb1e076747464098e50fc06a160d10bf..c9f4174bad42f928e707e7a2570e24a827bca536 100644 (file)
@@ -13,7 +13,7 @@
 static int i2c_eeprom_read(struct udevice *dev, int offset, uint8_t *buf,
                           int size)
 {
-       return -ENODEV;
+       return dm_i2c_read(dev, offset, buf, size);
 }
 
 static int i2c_eeprom_write(struct udevice *dev, int offset,
@@ -27,23 +27,46 @@ struct i2c_eeprom_ops i2c_eeprom_std_ops = {
        .write  = i2c_eeprom_write,
 };
 
+static int i2c_eeprom_std_ofdata_to_platdata(struct udevice *dev)
+{
+       struct i2c_eeprom *priv = dev_get_priv(dev);
+       u64 data = dev_get_driver_data(dev);
+
+       /* 6 bit -> page size of up to 2^63 (should be sufficient) */
+       priv->pagewidth = data & 0x3F;
+       priv->pagesize = (1 << priv->pagewidth);
+
+       return 0;
+}
+
 int i2c_eeprom_std_probe(struct udevice *dev)
 {
        return 0;
 }
 
 static const struct udevice_id i2c_eeprom_std_ids[] = {
-       { .compatible = "i2c-eeprom" },
+       { .compatible = "i2c-eeprom", .data = 0 },
+       { .compatible = "atmel,24c01a", .data = 3 },
+       { .compatible = "atmel,24c02", .data = 3 },
+       { .compatible = "atmel,24c04", .data = 4 },
+       { .compatible = "atmel,24c08a", .data = 4 },
+       { .compatible = "atmel,24c16a", .data = 4 },
+       { .compatible = "atmel,24c32", .data = 5 },
+       { .compatible = "atmel,24c64", .data = 5 },
+       { .compatible = "atmel,24c128", .data = 6 },
+       { .compatible = "atmel,24c256", .data = 6 },
+       { .compatible = "atmel,24c512", .data = 6 },
        { }
 };
 
 U_BOOT_DRIVER(i2c_eeprom_std) = {
-       .name           = "i2c_eeprom",
-       .id             = UCLASS_I2C_EEPROM,
-       .of_match       = i2c_eeprom_std_ids,
-       .probe          = i2c_eeprom_std_probe,
-       .priv_auto_alloc_size = sizeof(struct i2c_eeprom),
-       .ops            = &i2c_eeprom_std_ops,
+       .name                   = "i2c_eeprom",
+       .id                     = UCLASS_I2C_EEPROM,
+       .of_match               = i2c_eeprom_std_ids,
+       .probe                  = i2c_eeprom_std_probe,
+       .ofdata_to_platdata     = i2c_eeprom_std_ofdata_to_platdata,
+       .priv_auto_alloc_size   = sizeof(struct i2c_eeprom),
+       .ops                    = &i2c_eeprom_std_ops,
 };
 
 UCLASS_DRIVER(i2c_eeprom) = {
diff --git a/drivers/misc/spltest_sandbox.c b/drivers/misc/spltest_sandbox.c
new file mode 100644 (file)
index 0000000..1fef825
--- /dev/null
@@ -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,
+};
index c80efc39a791872aab2216bd7fb518b437e270b2..dc8f2b6852e8b6ba685ea40fd23667e210d8ff62 100644 (file)
@@ -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
@@ -52,6 +61,12 @@ config ZYNQ_SDHCI
        help
          Support for Arasan SDHCI host controller on Zynq/ZynqMP ARM SoCs platform
 
+config ROCKCHIP_SDHCI
+       bool "Arasan SDHCI controller for Rockchip support"
+       depends on DM_MMC && BLK && DM_MMC_OPS
+       help
+         Support for Arasan SDHCI host controller on Rockchip ARM SoCs platform
+
 config MMC_UNIPHIER
        bool "UniPhier SD/MMC Host Controller support"
        depends on ARCH_UNIPHIER
index 3da4817a189c6e00b8e780e8837509b38e3021c1..18351fb48a87b6cc4a3e611721827e0a8431cfca 100644 (file)
@@ -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
@@ -53,6 +56,7 @@ obj-$(CONFIG_SPEAR_SDHCI) += spear_sdhci.o
 obj-$(CONFIG_TEGRA_MMC) += tegra_mmc.o
 obj-$(CONFIG_MMC_UNIPHIER) += uniphier-sd.o
 obj-$(CONFIG_ZYNQ_SDHCI) += zynq_sdhci.o
+obj-$(CONFIG_ROCKCHIP_SDHCI) += rockchip_sdhci.o
 
 ifdef CONFIG_SPL_BUILD
 obj-$(CONFIG_SPL_MMC_BOOT) += fsl_esdhc_spl.o
index af6e04aa28b6926006a408ee5a3efabdad31b825..2cf7bae79232dac03f45ca30e293097179537870 100644 (file)
@@ -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;
 
index 863bbb3f64b27ea6ef1e860a7a7bd743426567ba..283befccfbe6ceca869b4cc51c1df0628570aaa1 100644 (file)
 #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
index 1b967d982bc74946ccd61fe1c74ae5826662cb6f..38ced4102e1073c146759d9d030e6d930514e944 100644 (file)
@@ -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) = {
index aabfc711e5d6fe40d001c3b6eabec9e37f43000b..f8e5f7a6089667434d363b12000df19961d5e733 100644 (file)
@@ -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 (file)
index 0000000..756a982
--- /dev/null
@@ -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);
+}
index 3ec649f2b82d391b4f359c5e9d866d3459394112..040728b45d3c9f415b31bdb330f506319457e45a 100644 (file)
@@ -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,
+};
index 9f0d5c2384a8a8a06c3e388e75ff3c9b3386c55b..49ec022a9e9cd96ebaf9404a3de1959c4dfb245d 100644 (file)
@@ -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_ */
index 96dcdbec5196106cfebf93878436c4fda06a2bd6..70a8d96eeef33d6c59d8723bef69fdd903256f72 100644 (file)
 /* 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),
 };
index d41d60ce3582767b96cb874d51d59448e4377484..020a59b92187a96ca9426d59e9ea578bd83f3a43 100644 (file)
@@ -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/rockchip_sdhci.c b/drivers/mmc/rockchip_sdhci.c
new file mode 100644 (file)
index 0000000..023c29b
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * (C) Copyright 2016 Fuzhou Rockchip Electronics Co., Ltd
+ *
+ * Rockchip SD Host Controller Interface
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <fdtdec.h>
+#include <libfdt.h>
+#include <malloc.h>
+#include <sdhci.h>
+
+/* 400KHz is max freq for card ID etc. Use that as min */
+#define EMMC_MIN_FREQ  400000
+
+struct rockchip_sdhc_plat {
+       struct mmc_config cfg;
+       struct mmc mmc;
+};
+
+struct rockchip_sdhc {
+       struct sdhci_host host;
+       void *base;
+};
+
+static int arasan_sdhci_probe(struct udevice *dev)
+{
+       struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
+       struct rockchip_sdhc_plat *plat = dev_get_platdata(dev);
+       struct rockchip_sdhc *prv = dev_get_priv(dev);
+       struct sdhci_host *host = &prv->host;
+       int ret;
+       u32 caps;
+
+       host->version = sdhci_readw(host, SDHCI_HOST_VERSION);
+       host->quirks = SDHCI_QUIRK_WAIT_SEND_CMD;
+
+       caps = sdhci_readl(host, SDHCI_CAPABILITIES);
+       ret = sdhci_setup_cfg(&plat->cfg, dev->name, host->bus_width,
+                       caps, CONFIG_ROCKCHIP_SDHCI_MAX_FREQ, EMMC_MIN_FREQ,
+                       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 sdhci_probe(dev);
+}
+
+static int arasan_sdhci_ofdata_to_platdata(struct udevice *dev)
+{
+       struct sdhci_host *host = dev_get_priv(dev);
+
+       host->name = dev->name;
+       host->ioaddr = dev_get_addr_ptr(dev);
+
+       return 0;
+}
+
+static int rockchip_sdhci_bind(struct udevice *dev)
+{
+       struct rockchip_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 arasan_sdhci_ids[] = {
+       { .compatible = "arasan,sdhci-5.1" },
+       { }
+};
+
+U_BOOT_DRIVER(arasan_sdhci_drv) = {
+       .name           = "arasan_sdhci",
+       .id             = UCLASS_MMC,
+       .of_match       = arasan_sdhci_ids,
+       .ofdata_to_platdata = arasan_sdhci_ofdata_to_platdata,
+       .ops            = &sdhci_ops,
+       .bind           = rockchip_sdhci_bind,
+       .probe          = arasan_sdhci_probe,
+       .priv_auto_alloc_size = sizeof(struct rockchip_sdhc),
+       .platdata_auto_alloc_size = sizeof(struct rockchip_sdhc_plat),
+};
index 7da059c43cd69650911572183b777d85fdb23612..5f1333b7480ce174763101b65e83fe6484d48326 100644 (file)
@@ -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,
index 604f18dcc96f764d8ff05ec67ccf2d5fc43a349e..9fdbed8aa9e3471656a6de743591caba0cb985f7 100644 (file)
@@ -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;
@@ -304,7 +313,7 @@ static int sdhci_set_clock(struct mmc *mmc, unsigned int clock)
        }
 
        reg = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
-       reg &= ~SDHCI_CLOCK_CARD_EN;
+       reg &= ~(SDHCI_CLOCK_CARD_EN | SDHCI_CLOCK_INT_EN);
        sdhci_writew(host, reg, SDHCI_CLOCK_CONTROL);
 
        if (clock == 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
index ce2dc4ae41c363c6d2c597e54d66227dde2b9a04..5d8abdc8974cf8bde3924138c983a4b7cfe379bf 100644 (file)
@@ -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,
index 152e9873970b3a80e6e14f44fba9c4598ad696c4..02df809bcfd5bfbe8db614bcd4d346c13335fd0a 100644 (file)
@@ -1,5 +1,6 @@
 /*
- * Copyright (C) 2016 Masahiro Yamada <yamada.masahiro@socionext.com>
+ * Copyright (C) 2016 Socionext Inc.
+ *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
  *
  * SPDX-License-Identifier:    GPL-2.0+
  */
@@ -7,7 +8,6 @@
 #include <common.h>
 #include <clk.h>
 #include <fdtdec.h>
-#include <mapmem.h>
 #include <mmc.h>
 #include <dm/device.h>
 #include <linux/compat.h>
@@ -660,7 +660,7 @@ int uniphier_sd_probe(struct udevice *dev)
        if (base == FDT_ADDR_T_NONE)
                return -EINVAL;
 
-       priv->regbase = map_sysmem(base, SZ_2K);
+       priv->regbase = devm_ioremap(dev, base, SZ_2K);
        if (!priv->regbase)
                return -ENOMEM;
 
@@ -735,7 +735,6 @@ int uniphier_sd_remove(struct udevice *dev)
 {
        struct uniphier_sd_priv *priv = dev_get_priv(dev);
 
-       unmap_sysmem(priv->regbase);
        mmc_destroy(priv->mmc);
 
        return 0;
index 8ccaff0e63a2e9a6778d47dc439bf2c39b1c05fc..33c4a9342f8ebf6d328fc0e919300ad495b0c60b 100644 (file)
@@ -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]);
index 8c46a2ff8e1a3f9a85a06ae06aaed680d8fa8c42..5ce7d6d06cea39099c50b039727ec622d9d5ea54 100644 (file)
@@ -64,12 +64,14 @@ config NAND_PXA3XX
          PXA3xx processors (NFCv1) and also on Armada 370/XP (NFCv2).
 
 config NAND_SUNXI
-       bool "Support for NAND on Allwinner SoCs in SPL"
+       bool "Support for NAND on Allwinner SoCs"
        depends on MACH_SUN4I || MACH_SUN5I || MACH_SUN7I
        select SYS_NAND_SELF_INIT
        ---help---
-       Enable support for NAND. This option allows SPL to read from
-       sunxi NAND using DMA transfers.
+       Enable support for NAND. This option enables the standard and
+       SPL drivers.
+       The SPL driver only supports reading from the NAND using DMA
+       transfers.
 
 config NAND_ARASAN
        bool "Configure Arasan Nand"
index 837d397bdafb03df17552d11a3ce2c60b48d6f03..1df9273cdd1114f64f161a9d987ce2ae89f590d2 100644 (file)
@@ -66,6 +66,7 @@ obj-$(CONFIG_TEGRA_NAND) += tegra_nand.o
 obj-$(CONFIG_NAND_OMAP_GPMC) += omap_gpmc.o
 obj-$(CONFIG_NAND_OMAP_ELM) += omap_elm.o
 obj-$(CONFIG_NAND_PLAT) += nand_plat.o
+obj-$(CONFIG_NAND_SUNXI) += sunxi_nand.o
 
 else  # minimal SPL drivers
 
index cbeb74a5bb8e777a041925185c226977f97835e4..4e49a4e15465a762b1d08bd5f8ebe579954b9973 100644 (file)
@@ -11,6 +11,9 @@
 #include <asm/io.h>
 #include <fsl_ifc.h>
 #include <linux/mtd/nand.h>
+#ifdef CONFIG_CHAIN_OF_TRUST
+#include <fsl_validate.h>
+#endif
 
 static inline int is_blank(uchar *addr, int page_size)
 {
@@ -268,6 +271,27 @@ void nand_boot(void)
         */
        flush_cache(CONFIG_SYS_NAND_U_BOOT_DST, CONFIG_SYS_NAND_U_BOOT_SIZE);
 #endif
+
+#ifdef CONFIG_CHAIN_OF_TRUST
+       /*
+        * U-Boot header is appended at end of U-boot image, so
+        * calculate U-boot header address using U-boot header size.
+        */
+#define CONFIG_U_BOOT_HDR_ADDR \
+               ((CONFIG_SYS_NAND_U_BOOT_START + \
+                 CONFIG_SYS_NAND_U_BOOT_SIZE) - \
+                CONFIG_U_BOOT_HDR_SIZE)
+       spl_validate_uboot(CONFIG_U_BOOT_HDR_ADDR,
+                          CONFIG_SYS_NAND_U_BOOT_START);
+       /*
+        * In case of failure in validation, spl_validate_uboot would
+        * not return back in case of Production environment with ITS=1.
+        * Thus U-Boot will not start.
+        * In Development environment (ITS=0 and SB_EN=1), the function
+        * may return back in case of non-fatal failures.
+        */
+#endif
+
        uboot = (void *)CONFIG_SYS_NAND_U_BOOT_START;
        uboot();
 }
index c90a3a7bd2cb596f5bd5d7ea75a5454faa12418c..94fc5c18a0765e6c401afec22b3bdad0ce181bf4 100644 (file)
@@ -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.
  */
index 689716753ae646f35ba697367314a7f6b0bf4001..d1287bc3be9f880d4776683d8f4d267e3f34d643 100644 (file)
@@ -29,6 +29,9 @@
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 #include <common.h>
+#if CONFIG_IS_ENABLED(OF_CONTROL)
+#include <fdtdec.h>
+#endif
 #include <malloc.h>
 #include <watchdog.h>
 #include <linux/err.h>
@@ -2411,7 +2414,7 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to,
                int cached = writelen > bytes && page != blockmask;
                uint8_t *wbuf = buf;
                int use_bufpoi;
-               int part_pagewr = (column || writelen < (mtd->writesize - 1));
+               int part_pagewr = (column || writelen < mtd->writesize);
 
                if (part_pagewr)
                        use_bufpoi = 1;
@@ -3763,6 +3766,66 @@ ident_done:
        return type;
 }
 
+#if CONFIG_IS_ENABLED(OF_CONTROL)
+DECLARE_GLOBAL_DATA_PTR;
+
+static int nand_dt_init(struct mtd_info *mtd, struct nand_chip *chip, int node)
+{
+       int ret, ecc_mode = -1, ecc_strength, ecc_step;
+       const void *blob = gd->fdt_blob;
+       const char *str;
+
+       ret = fdtdec_get_int(blob, node, "nand-bus-width", -1);
+       if (ret == 16)
+               chip->options |= NAND_BUSWIDTH_16;
+
+       if (fdtdec_get_bool(blob, node, "nand-on-flash-bbt"))
+               chip->bbt_options |= NAND_BBT_USE_FLASH;
+
+       str = fdt_getprop(blob, node, "nand-ecc-mode", NULL);
+       if (str) {
+               if (!strcmp(str, "none"))
+                       ecc_mode = NAND_ECC_NONE;
+               else if (!strcmp(str, "soft"))
+                       ecc_mode = NAND_ECC_SOFT;
+               else if (!strcmp(str, "hw"))
+                       ecc_mode = NAND_ECC_HW;
+               else if (!strcmp(str, "hw_syndrome"))
+                       ecc_mode = NAND_ECC_HW_SYNDROME;
+               else if (!strcmp(str, "hw_oob_first"))
+                       ecc_mode = NAND_ECC_HW_OOB_FIRST;
+               else if (!strcmp(str, "soft_bch"))
+                       ecc_mode = NAND_ECC_SOFT_BCH;
+       }
+
+
+       ecc_strength = fdtdec_get_int(blob, node, "nand-ecc-strength", -1);
+       ecc_step = fdtdec_get_int(blob, node, "nand-ecc-step-size", -1);
+
+       if ((ecc_step >= 0 && !(ecc_strength >= 0)) ||
+           (!(ecc_step >= 0) && ecc_strength >= 0)) {
+               pr_err("must set both strength and step size in DT\n");
+               return -EINVAL;
+       }
+
+       if (ecc_mode >= 0)
+               chip->ecc.mode = ecc_mode;
+
+       if (ecc_strength >= 0)
+               chip->ecc.strength = ecc_strength;
+
+       if (ecc_step > 0)
+               chip->ecc.size = ecc_step;
+
+       return 0;
+}
+#else
+static int nand_dt_init(struct mtd_info *mtd, struct nand_chip *chip, int node)
+{
+       return 0;
+}
+#endif /* CONFIG_IS_ENABLED(OF_CONTROL) */
+
 /**
  * nand_scan_ident - [NAND Interface] Scan for the NAND device
  * @mtd: MTD device structure
@@ -3779,6 +3842,13 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips,
        int i, nand_maf_id, nand_dev_id;
        struct nand_chip *chip = mtd_to_nand(mtd);
        struct nand_flash_dev *type;
+       int ret;
+
+       if (chip->flash_node) {
+               ret = nand_dt_init(mtd, chip, chip->flash_node);
+               if (ret)
+                       return ret;
+       }
 
        /* Set the default functions */
        nand_set_defaults(chip, chip->options & NAND_BUSWIDTH_16);
index 561d2cd63bbebc7f3c371be84a6e388f9522c917..ce0a14e28abb60972648ab5ba7a2ffeed95b2038 100644 (file)
@@ -62,6 +62,10 @@ struct nand_flash_dev nand_flash_ids[] = {
                { .id = {0xad, 0xde, 0x94, 0xda, 0x74, 0xc4} },
                  SZ_8K, SZ_8K, SZ_2M, NAND_NEED_SCRAMBLING, 6, 640,
                  NAND_ECC_INFO(40, SZ_1K), 4 },
+       {"H27QCG8T2E5R‐BCF 64G 3.3V 8-bit",
+               { .id = {0xad, 0xde, 0x14, 0xa7, 0x42, 0x4a} },
+                 SZ_16K, SZ_8K, SZ_4M, NAND_NEED_SCRAMBLING, 6, 1664,
+                 NAND_ECC_INFO(56, SZ_1K), 1 },
 
        LEGACY_ID_NAND("NAND 4MiB 5V 8-bit",   0x6B, 4, SZ_8K, SP_OPTIONS),
        LEGACY_ID_NAND("NAND 4MiB 3,3V 8-bit", 0xE3, 4, SZ_8K, SP_OPTIONS),
index 60a7607073337954d3e0ea89f38f2fda5f5d2dee..55f48d3a142b666d43b56a664d11f82d6b73576d 100644 (file)
@@ -209,6 +209,68 @@ static int nand_read_page(int block, int page, void *dst)
 }
 #endif
 
+#ifdef CONFIG_SPL_UBI
+/*
+ * Temporary storage for non NAND page aligned and non NAND page sized
+ * reads. Note: This does not support runtime detected FLASH yet, but
+ * that should be reasonably easy to fix by making the buffer large
+ * enough :)
+ */
+static u8 scratch_buf[CONFIG_SYS_NAND_PAGE_SIZE];
+
+/**
+ * nand_spl_read_block - Read data from physical eraseblock into a buffer
+ * @block:     Number of the physical eraseblock
+ * @offset:    Data offset from the start of @peb
+ * @len:       Data size to read
+ * @dst:       Address of the destination buffer
+ *
+ * This could be further optimized if we'd have a subpage read
+ * function in the simple code. On NAND which allows subpage reads
+ * this would spare quite some time to readout e.g. the VID header of
+ * UBI.
+ *
+ * Notes:
+ *     @offset + @len are not allowed to be larger than a physical
+ *     erase block. No sanity check done for simplicity reasons.
+ *
+ * To support runtime detected flash this needs to be extended by
+ * information about the actual flash geometry, but thats beyond the
+ * scope of this effort and for most applications where fast boot is
+ * required it is not an issue anyway.
+ */
+int nand_spl_read_block(int block, int offset, int len, void *dst)
+{
+       int page, read;
+
+       /* Calculate the page number */
+       page = offset / CONFIG_SYS_NAND_PAGE_SIZE;
+
+       /* Offset to the start of a flash page */
+       offset = offset % CONFIG_SYS_NAND_PAGE_SIZE;
+
+       while (len) {
+               /*
+                * Non page aligned reads go to the scratch buffer.
+                * Page aligned reads go directly to the destination.
+                */
+               if (offset || len < CONFIG_SYS_NAND_PAGE_SIZE) {
+                       nand_read_page(block, page, scratch_buf);
+                       read = min(len, CONFIG_SYS_NAND_PAGE_SIZE - offset);
+                       memcpy(dst, scratch_buf + offset, read);
+                       offset = 0;
+               } else {
+                       nand_read_page(block, page, dst);
+                       read = CONFIG_SYS_NAND_PAGE_SIZE;
+               }
+               page++;
+               len -= read;
+               dst += read;
+       }
+       return 0;
+}
+#endif
+
 int nand_spl_load_image(uint32_t offs, unsigned int size, void *dst)
 {
        unsigned int block, lastblock;
index 67f293dcd0169de92b669d83cf7eeeb88b25735c..6e201d68e5135671b9d5c8f4324c1bc34bf89a10 100644 (file)
@@ -264,7 +264,8 @@ static int omap_calculate_ecc(struct mtd_info *mtd, const uint8_t *dat,
 {
        struct nand_chip *chip = mtd_to_nand(mtd);
        struct omap_nand_info *info = nand_get_controller_data(chip);
-       uint32_t *ptr, val = 0;
+       const uint32_t *ptr;
+       uint32_t val = 0;
        int8_t i = 0, j;
 
        switch (info->ecc_scheme) {
diff --git a/drivers/mtd/nand/sunxi_nand.c b/drivers/mtd/nand/sunxi_nand.c
new file mode 100644 (file)
index 0000000..c4e2cd7
--- /dev/null
@@ -0,0 +1,1845 @@
+/*
+ * Copyright (C) 2013 Boris BREZILLON <b.brezillon.dev@gmail.com>
+ * Copyright (C) 2015 Roy Spliet <r.spliet@ultimaker.com>
+ *
+ * Derived from:
+ *     https://github.com/yuq/sunxi-nfc-mtd
+ *     Copyright (C) 2013 Qiang Yu <yuq825@gmail.com>
+ *
+ *     https://github.com/hno/Allwinner-Info
+ *     Copyright (C) 2013 Henrik Nordström <Henrik Nordström>
+ *
+ *     Copyright (C) 2013 Dmitriy B. <rzk333@gmail.com>
+ *     Copyright (C) 2013 Sergey Lapin <slapin@ossfans.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <fdtdec.h>
+#include <memalign.h>
+#include <nand.h>
+
+#include <linux/kernel.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+#include <linux/io.h>
+
+#include <asm/gpio.h>
+#include <asm/arch/clock.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define NFC_REG_CTL            0x0000
+#define NFC_REG_ST             0x0004
+#define NFC_REG_INT            0x0008
+#define NFC_REG_TIMING_CTL     0x000C
+#define NFC_REG_TIMING_CFG     0x0010
+#define NFC_REG_ADDR_LOW       0x0014
+#define NFC_REG_ADDR_HIGH      0x0018
+#define NFC_REG_SECTOR_NUM     0x001C
+#define NFC_REG_CNT            0x0020
+#define NFC_REG_CMD            0x0024
+#define NFC_REG_RCMD_SET       0x0028
+#define NFC_REG_WCMD_SET       0x002C
+#define NFC_REG_IO_DATA                0x0030
+#define NFC_REG_ECC_CTL                0x0034
+#define NFC_REG_ECC_ST         0x0038
+#define NFC_REG_DEBUG          0x003C
+#define NFC_REG_ECC_ERR_CNT(x) ((0x0040 + (x)) & ~0x3)
+#define NFC_REG_USER_DATA(x)   (0x0050 + ((x) * 4))
+#define NFC_REG_SPARE_AREA     0x00A0
+#define NFC_REG_PAT_ID         0x00A4
+#define NFC_RAM0_BASE          0x0400
+#define NFC_RAM1_BASE          0x0800
+
+/* define bit use in NFC_CTL */
+#define NFC_EN                 BIT(0)
+#define NFC_RESET              BIT(1)
+#define NFC_BUS_WIDTH_MSK      BIT(2)
+#define NFC_BUS_WIDTH_8                (0 << 2)
+#define NFC_BUS_WIDTH_16       (1 << 2)
+#define NFC_RB_SEL_MSK         BIT(3)
+#define NFC_RB_SEL(x)          ((x) << 3)
+#define NFC_CE_SEL_MSK         (0x7 << 24)
+#define NFC_CE_SEL(x)          ((x) << 24)
+#define NFC_CE_CTL             BIT(6)
+#define NFC_PAGE_SHIFT_MSK     (0xf << 8)
+#define NFC_PAGE_SHIFT(x)      (((x) < 10 ? 0 : (x) - 10) << 8)
+#define NFC_SAM                        BIT(12)
+#define NFC_RAM_METHOD         BIT(14)
+#define NFC_DEBUG_CTL          BIT(31)
+
+/* define bit use in NFC_ST */
+#define NFC_RB_B2R             BIT(0)
+#define NFC_CMD_INT_FLAG       BIT(1)
+#define NFC_DMA_INT_FLAG       BIT(2)
+#define NFC_CMD_FIFO_STATUS    BIT(3)
+#define NFC_STA                        BIT(4)
+#define NFC_NATCH_INT_FLAG     BIT(5)
+#define NFC_RB_STATE(x)                BIT(x + 8)
+
+/* define bit use in NFC_INT */
+#define NFC_B2R_INT_ENABLE     BIT(0)
+#define NFC_CMD_INT_ENABLE     BIT(1)
+#define NFC_DMA_INT_ENABLE     BIT(2)
+#define NFC_INT_MASK           (NFC_B2R_INT_ENABLE | \
+                                NFC_CMD_INT_ENABLE | \
+                                NFC_DMA_INT_ENABLE)
+
+/* define bit use in NFC_TIMING_CTL */
+#define NFC_TIMING_CTL_EDO     BIT(8)
+
+/* define NFC_TIMING_CFG register layout */
+#define NFC_TIMING_CFG(tWB, tADL, tWHR, tRHW, tCAD)            \
+       (((tWB) & 0x3) | (((tADL) & 0x3) << 2) |                \
+       (((tWHR) & 0x3) << 4) | (((tRHW) & 0x3) << 6) |         \
+       (((tCAD) & 0x7) << 8))
+
+/* define bit use in NFC_CMD */
+#define NFC_CMD_LOW_BYTE_MSK   0xff
+#define NFC_CMD_HIGH_BYTE_MSK  (0xff << 8)
+#define NFC_CMD(x)             (x)
+#define NFC_ADR_NUM_MSK                (0x7 << 16)
+#define NFC_ADR_NUM(x)         (((x) - 1) << 16)
+#define NFC_SEND_ADR           BIT(19)
+#define NFC_ACCESS_DIR         BIT(20)
+#define NFC_DATA_TRANS         BIT(21)
+#define NFC_SEND_CMD1          BIT(22)
+#define NFC_WAIT_FLAG          BIT(23)
+#define NFC_SEND_CMD2          BIT(24)
+#define NFC_SEQ                        BIT(25)
+#define NFC_DATA_SWAP_METHOD   BIT(26)
+#define NFC_ROW_AUTO_INC       BIT(27)
+#define NFC_SEND_CMD3          BIT(28)
+#define NFC_SEND_CMD4          BIT(29)
+#define NFC_CMD_TYPE_MSK       (0x3 << 30)
+#define NFC_NORMAL_OP          (0 << 30)
+#define NFC_ECC_OP             (1 << 30)
+#define NFC_PAGE_OP            (2 << 30)
+
+/* define bit use in NFC_RCMD_SET */
+#define NFC_READ_CMD_MSK       0xff
+#define NFC_RND_READ_CMD0_MSK  (0xff << 8)
+#define NFC_RND_READ_CMD1_MSK  (0xff << 16)
+
+/* define bit use in NFC_WCMD_SET */
+#define NFC_PROGRAM_CMD_MSK    0xff
+#define NFC_RND_WRITE_CMD_MSK  (0xff << 8)
+#define NFC_READ_CMD0_MSK      (0xff << 16)
+#define NFC_READ_CMD1_MSK      (0xff << 24)
+
+/* define bit use in NFC_ECC_CTL */
+#define NFC_ECC_EN             BIT(0)
+#define NFC_ECC_PIPELINE       BIT(3)
+#define NFC_ECC_EXCEPTION      BIT(4)
+#define NFC_ECC_BLOCK_SIZE_MSK BIT(5)
+#define NFC_ECC_BLOCK_512      (1 << 5)
+#define NFC_RANDOM_EN          BIT(9)
+#define NFC_RANDOM_DIRECTION   BIT(10)
+#define NFC_ECC_MODE_MSK       (0xf << 12)
+#define NFC_ECC_MODE(x)                ((x) << 12)
+#define NFC_RANDOM_SEED_MSK    (0x7fff << 16)
+#define NFC_RANDOM_SEED(x)     ((x) << 16)
+
+/* define bit use in NFC_ECC_ST */
+#define NFC_ECC_ERR(x)         BIT(x)
+#define NFC_ECC_PAT_FOUND(x)   BIT(x + 16)
+#define NFC_ECC_ERR_CNT(b, x)  (((x) >> ((b) * 8)) & 0xff)
+
+#define NFC_DEFAULT_TIMEOUT_MS 1000
+
+#define NFC_SRAM_SIZE          1024
+
+#define NFC_MAX_CS             7
+
+/*
+ * Ready/Busy detection type: describes the Ready/Busy detection modes
+ *
+ * @RB_NONE:   no external detection available, rely on STATUS command
+ *             and software timeouts
+ * @RB_NATIVE: use sunxi NAND controller Ready/Busy support. The Ready/Busy
+ *             pin of the NAND flash chip must be connected to one of the
+ *             native NAND R/B pins (those which can be muxed to the NAND
+ *             Controller)
+ * @RB_GPIO:   use a simple GPIO to handle Ready/Busy status. The Ready/Busy
+ *             pin of the NAND flash chip must be connected to a GPIO capable
+ *             pin.
+ */
+enum sunxi_nand_rb_type {
+       RB_NONE,
+       RB_NATIVE,
+       RB_GPIO,
+};
+
+/*
+ * Ready/Busy structure: stores information related to Ready/Busy detection
+ *
+ * @type:      the Ready/Busy detection mode
+ * @info:      information related to the R/B detection mode. Either a gpio
+ *             id or a native R/B id (those supported by the NAND controller).
+ */
+struct sunxi_nand_rb {
+       enum sunxi_nand_rb_type type;
+       union {
+               struct gpio_desc gpio;
+               int nativeid;
+       } info;
+};
+
+/*
+ * Chip Select structure: stores information related to NAND Chip Select
+ *
+ * @cs:                the NAND CS id used to communicate with a NAND Chip
+ * @rb:                the Ready/Busy description
+ */
+struct sunxi_nand_chip_sel {
+       u8 cs;
+       struct sunxi_nand_rb rb;
+};
+
+/*
+ * sunxi HW ECC infos: stores information related to HW ECC support
+ *
+ * @mode:      the sunxi ECC mode field deduced from ECC requirements
+ * @layout:    the OOB layout depending on the ECC requirements and the
+ *             selected ECC mode
+ */
+struct sunxi_nand_hw_ecc {
+       int mode;
+       struct nand_ecclayout layout;
+};
+
+/*
+ * NAND chip structure: stores NAND chip device related information
+ *
+ * @node:              used to store NAND chips into a list
+ * @nand:              base NAND chip structure
+ * @mtd:               base MTD structure
+ * @clk_rate:          clk_rate required for this NAND chip
+ * @timing_cfg         TIMING_CFG register value for this NAND chip
+ * @selected:          current active CS
+ * @nsels:             number of CS lines required by the NAND chip
+ * @sels:              array of CS lines descriptions
+ */
+struct sunxi_nand_chip {
+       struct list_head node;
+       struct nand_chip nand;
+       unsigned long clk_rate;
+       u32 timing_cfg;
+       u32 timing_ctl;
+       int selected;
+       int addr_cycles;
+       u32 addr[2];
+       int cmd_cycles;
+       u8 cmd[2];
+       int nsels;
+       struct sunxi_nand_chip_sel sels[0];
+};
+
+static inline struct sunxi_nand_chip *to_sunxi_nand(struct nand_chip *nand)
+{
+       return container_of(nand, struct sunxi_nand_chip, nand);
+}
+
+/*
+ * NAND Controller structure: stores sunxi NAND controller information
+ *
+ * @controller:                base controller structure
+ * @dev:               parent device (used to print error messages)
+ * @regs:              NAND controller registers
+ * @ahb_clk:           NAND Controller AHB clock
+ * @mod_clk:           NAND Controller mod clock
+ * @assigned_cs:       bitmask describing already assigned CS lines
+ * @clk_rate:          NAND controller current clock rate
+ * @chips:             a list containing all the NAND chips attached to
+ *                     this NAND controller
+ * @complete:          a completion object used to wait for NAND
+ *                     controller events
+ */
+struct sunxi_nfc {
+       struct nand_hw_control controller;
+       struct device *dev;
+       void __iomem *regs;
+       struct clk *ahb_clk;
+       struct clk *mod_clk;
+       unsigned long assigned_cs;
+       unsigned long clk_rate;
+       struct list_head chips;
+};
+
+static inline struct sunxi_nfc *to_sunxi_nfc(struct nand_hw_control *ctrl)
+{
+       return container_of(ctrl, struct sunxi_nfc, controller);
+}
+
+static void sunxi_nfc_set_clk_rate(unsigned long hz)
+{
+       struct sunxi_ccm_reg *const ccm =
+       (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
+       int div_m, div_n;
+
+       div_m = (clock_get_pll6() + hz - 1) / hz;
+       for (div_n = 0; div_n < 3 && div_m > 16; div_n++) {
+               if (div_m % 2)
+                       div_m++;
+               div_m >>= 1;
+       }
+       if (div_m > 16)
+               div_m = 16;
+
+       /* config mod clock */
+       writel(CCM_NAND_CTRL_ENABLE | CCM_NAND_CTRL_PLL6 |
+              CCM_NAND_CTRL_N(div_n) | CCM_NAND_CTRL_M(div_m),
+              &ccm->nand0_clk_cfg);
+
+       /* gate on nand clock */
+       setbits_le32(&ccm->ahb_gate0, (1 << AHB_GATE_OFFSET_NAND0));
+#ifdef CONFIG_MACH_SUN9I
+       setbits_le32(&ccm->ahb_gate1, (1 << AHB_GATE_OFFSET_DMA));
+#else
+       setbits_le32(&ccm->ahb_gate0, (1 << AHB_GATE_OFFSET_DMA));
+#endif
+}
+
+static int sunxi_nfc_wait_int(struct sunxi_nfc *nfc, u32 flags,
+                             unsigned int timeout_ms)
+{
+       unsigned int timeout_ticks;
+       u32 time_start, status;
+       int ret = -ETIMEDOUT;
+
+       if (!timeout_ms)
+               timeout_ms = NFC_DEFAULT_TIMEOUT_MS;
+
+       timeout_ticks = (timeout_ms * CONFIG_SYS_HZ) / 1000;
+
+       time_start = get_timer(0);
+
+       do {
+               status = readl(nfc->regs + NFC_REG_ST);
+               if ((status & flags) == flags) {
+                       ret = 0;
+                       break;
+               }
+
+               udelay(1);
+       } while (get_timer(time_start) < timeout_ticks);
+
+       writel(status & flags, nfc->regs + NFC_REG_ST);
+
+       return ret;
+}
+
+static int sunxi_nfc_wait_cmd_fifo_empty(struct sunxi_nfc *nfc)
+{
+       unsigned long timeout = (CONFIG_SYS_HZ *
+                                NFC_DEFAULT_TIMEOUT_MS) / 1000;
+       u32 time_start;
+
+       time_start = get_timer(0);
+       do {
+               if (!(readl(nfc->regs + NFC_REG_ST) & NFC_CMD_FIFO_STATUS))
+                       return 0;
+       } while (get_timer(time_start) < timeout);
+
+       dev_err(nfc->dev, "wait for empty cmd FIFO timedout\n");
+       return -ETIMEDOUT;
+}
+
+static int sunxi_nfc_rst(struct sunxi_nfc *nfc)
+{
+       unsigned long timeout = (CONFIG_SYS_HZ *
+                                NFC_DEFAULT_TIMEOUT_MS) / 1000;
+       u32 time_start;
+
+       writel(0, nfc->regs + NFC_REG_ECC_CTL);
+       writel(NFC_RESET, nfc->regs + NFC_REG_CTL);
+
+       time_start = get_timer(0);
+       do {
+               if (!(readl(nfc->regs + NFC_REG_CTL) & NFC_RESET))
+                       return 0;
+       } while (get_timer(time_start) < timeout);
+
+       dev_err(nfc->dev, "wait for NAND controller reset timedout\n");
+       return -ETIMEDOUT;
+}
+
+static int sunxi_nfc_dev_ready(struct mtd_info *mtd)
+{
+       struct nand_chip *nand = mtd_to_nand(mtd);
+       struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand);
+       struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
+       struct sunxi_nand_rb *rb;
+       unsigned long timeo = (sunxi_nand->nand.state == FL_ERASING ? 400 : 20);
+       int ret;
+
+       if (sunxi_nand->selected < 0)
+               return 0;
+
+       rb = &sunxi_nand->sels[sunxi_nand->selected].rb;
+
+       switch (rb->type) {
+       case RB_NATIVE:
+               ret = !!(readl(nfc->regs + NFC_REG_ST) &
+                        NFC_RB_STATE(rb->info.nativeid));
+               if (ret)
+                       break;
+
+               sunxi_nfc_wait_int(nfc, NFC_RB_B2R, timeo);
+               ret = !!(readl(nfc->regs + NFC_REG_ST) &
+                        NFC_RB_STATE(rb->info.nativeid));
+               break;
+       case RB_GPIO:
+               ret = dm_gpio_get_value(&rb->info.gpio);
+               break;
+       case RB_NONE:
+       default:
+               ret = 0;
+               dev_err(nfc->dev, "cannot check R/B NAND status!\n");
+               break;
+       }
+
+       return ret;
+}
+
+static void sunxi_nfc_select_chip(struct mtd_info *mtd, int chip)
+{
+       struct nand_chip *nand = mtd_to_nand(mtd);
+       struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand);
+       struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
+       struct sunxi_nand_chip_sel *sel;
+       u32 ctl;
+
+       if (chip > 0 && chip >= sunxi_nand->nsels)
+               return;
+
+       if (chip == sunxi_nand->selected)
+               return;
+
+       ctl = readl(nfc->regs + NFC_REG_CTL) &
+             ~(NFC_PAGE_SHIFT_MSK | NFC_CE_SEL_MSK | NFC_RB_SEL_MSK | NFC_EN);
+
+       if (chip >= 0) {
+               sel = &sunxi_nand->sels[chip];
+
+               ctl |= NFC_CE_SEL(sel->cs) | NFC_EN |
+                      NFC_PAGE_SHIFT(nand->page_shift - 10);
+               if (sel->rb.type == RB_NONE) {
+                       nand->dev_ready = NULL;
+               } else {
+                       nand->dev_ready = sunxi_nfc_dev_ready;
+                       if (sel->rb.type == RB_NATIVE)
+                               ctl |= NFC_RB_SEL(sel->rb.info.nativeid);
+               }
+
+               writel(mtd->writesize, nfc->regs + NFC_REG_SPARE_AREA);
+
+               if (nfc->clk_rate != sunxi_nand->clk_rate) {
+                       sunxi_nfc_set_clk_rate(sunxi_nand->clk_rate);
+                       nfc->clk_rate = sunxi_nand->clk_rate;
+               }
+       }
+
+       writel(sunxi_nand->timing_ctl, nfc->regs + NFC_REG_TIMING_CTL);
+       writel(sunxi_nand->timing_cfg, nfc->regs + NFC_REG_TIMING_CFG);
+       writel(ctl, nfc->regs + NFC_REG_CTL);
+
+       sunxi_nand->selected = chip;
+}
+
+static void sunxi_nfc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
+{
+       struct nand_chip *nand = mtd_to_nand(mtd);
+       struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand);
+       struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
+       int ret;
+       int cnt;
+       int offs = 0;
+       u32 tmp;
+
+       while (len > offs) {
+               cnt = min(len - offs, NFC_SRAM_SIZE);
+
+               ret = sunxi_nfc_wait_cmd_fifo_empty(nfc);
+               if (ret)
+                       break;
+
+               writel(cnt, nfc->regs + NFC_REG_CNT);
+               tmp = NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD;
+               writel(tmp, nfc->regs + NFC_REG_CMD);
+
+               ret = sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0);
+               if (ret)
+                       break;
+
+               if (buf)
+                       memcpy_fromio(buf + offs, nfc->regs + NFC_RAM0_BASE,
+                                     cnt);
+               offs += cnt;
+       }
+}
+
+static void sunxi_nfc_write_buf(struct mtd_info *mtd, const uint8_t *buf,
+                               int len)
+{
+       struct nand_chip *nand = mtd_to_nand(mtd);
+       struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand);
+       struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
+       int ret;
+       int cnt;
+       int offs = 0;
+       u32 tmp;
+
+       while (len > offs) {
+               cnt = min(len - offs, NFC_SRAM_SIZE);
+
+               ret = sunxi_nfc_wait_cmd_fifo_empty(nfc);
+               if (ret)
+                       break;
+
+               writel(cnt, nfc->regs + NFC_REG_CNT);
+               memcpy_toio(nfc->regs + NFC_RAM0_BASE, buf + offs, cnt);
+               tmp = NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD |
+                     NFC_ACCESS_DIR;
+               writel(tmp, nfc->regs + NFC_REG_CMD);
+
+               ret = sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0);
+               if (ret)
+                       break;
+
+               offs += cnt;
+       }
+}
+
+static uint8_t sunxi_nfc_read_byte(struct mtd_info *mtd)
+{
+       uint8_t ret;
+
+       sunxi_nfc_read_buf(mtd, &ret, 1);
+
+       return ret;
+}
+
+static void sunxi_nfc_cmd_ctrl(struct mtd_info *mtd, int dat,
+                              unsigned int ctrl)
+{
+       struct nand_chip *nand = mtd_to_nand(mtd);
+       struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand);
+       struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
+       int ret;
+       u32 tmp;
+
+       ret = sunxi_nfc_wait_cmd_fifo_empty(nfc);
+       if (ret)
+               return;
+
+       if (ctrl & NAND_CTRL_CHANGE) {
+               tmp = readl(nfc->regs + NFC_REG_CTL);
+               if (ctrl & NAND_NCE)
+                       tmp |= NFC_CE_CTL;
+               else
+                       tmp &= ~NFC_CE_CTL;
+               writel(tmp, nfc->regs + NFC_REG_CTL);
+       }
+
+       if (dat == NAND_CMD_NONE && (ctrl & NAND_NCE) &&
+           !(ctrl & (NAND_CLE | NAND_ALE))) {
+               u32 cmd = 0;
+
+               if (!sunxi_nand->addr_cycles && !sunxi_nand->cmd_cycles)
+                       return;
+
+               if (sunxi_nand->cmd_cycles--)
+                       cmd |= NFC_SEND_CMD1 | sunxi_nand->cmd[0];
+
+               if (sunxi_nand->cmd_cycles--) {
+                       cmd |= NFC_SEND_CMD2;
+                       writel(sunxi_nand->cmd[1],
+                              nfc->regs + NFC_REG_RCMD_SET);
+               }
+
+               sunxi_nand->cmd_cycles = 0;
+
+               if (sunxi_nand->addr_cycles) {
+                       cmd |= NFC_SEND_ADR |
+                              NFC_ADR_NUM(sunxi_nand->addr_cycles);
+                       writel(sunxi_nand->addr[0],
+                              nfc->regs + NFC_REG_ADDR_LOW);
+               }
+
+               if (sunxi_nand->addr_cycles > 4)
+                       writel(sunxi_nand->addr[1],
+                              nfc->regs + NFC_REG_ADDR_HIGH);
+
+               writel(cmd, nfc->regs + NFC_REG_CMD);
+               sunxi_nand->addr[0] = 0;
+               sunxi_nand->addr[1] = 0;
+               sunxi_nand->addr_cycles = 0;
+               sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0);
+       }
+
+       if (ctrl & NAND_CLE) {
+               sunxi_nand->cmd[sunxi_nand->cmd_cycles++] = dat;
+       } else if (ctrl & NAND_ALE) {
+               sunxi_nand->addr[sunxi_nand->addr_cycles / 4] |=
+                               dat << ((sunxi_nand->addr_cycles % 4) * 8);
+               sunxi_nand->addr_cycles++;
+       }
+}
+
+/* These seed values have been extracted from Allwinner's BSP */
+static const u16 sunxi_nfc_randomizer_page_seeds[] = {
+       0x2b75, 0x0bd0, 0x5ca3, 0x62d1, 0x1c93, 0x07e9, 0x2162, 0x3a72,
+       0x0d67, 0x67f9, 0x1be7, 0x077d, 0x032f, 0x0dac, 0x2716, 0x2436,
+       0x7922, 0x1510, 0x3860, 0x5287, 0x480f, 0x4252, 0x1789, 0x5a2d,
+       0x2a49, 0x5e10, 0x437f, 0x4b4e, 0x2f45, 0x216e, 0x5cb7, 0x7130,
+       0x2a3f, 0x60e4, 0x4dc9, 0x0ef0, 0x0f52, 0x1bb9, 0x6211, 0x7a56,
+       0x226d, 0x4ea7, 0x6f36, 0x3692, 0x38bf, 0x0c62, 0x05eb, 0x4c55,
+       0x60f4, 0x728c, 0x3b6f, 0x2037, 0x7f69, 0x0936, 0x651a, 0x4ceb,
+       0x6218, 0x79f3, 0x383f, 0x18d9, 0x4f05, 0x5c82, 0x2912, 0x6f17,
+       0x6856, 0x5938, 0x1007, 0x61ab, 0x3e7f, 0x57c2, 0x542f, 0x4f62,
+       0x7454, 0x2eac, 0x7739, 0x42d4, 0x2f90, 0x435a, 0x2e52, 0x2064,
+       0x637c, 0x66ad, 0x2c90, 0x0bad, 0x759c, 0x0029, 0x0986, 0x7126,
+       0x1ca7, 0x1605, 0x386a, 0x27f5, 0x1380, 0x6d75, 0x24c3, 0x0f8e,
+       0x2b7a, 0x1418, 0x1fd1, 0x7dc1, 0x2d8e, 0x43af, 0x2267, 0x7da3,
+       0x4e3d, 0x1338, 0x50db, 0x454d, 0x764d, 0x40a3, 0x42e6, 0x262b,
+       0x2d2e, 0x1aea, 0x2e17, 0x173d, 0x3a6e, 0x71bf, 0x25f9, 0x0a5d,
+       0x7c57, 0x0fbe, 0x46ce, 0x4939, 0x6b17, 0x37bb, 0x3e91, 0x76db,
+};
+
+/*
+ * sunxi_nfc_randomizer_ecc512_seeds and sunxi_nfc_randomizer_ecc1024_seeds
+ * have been generated using
+ * sunxi_nfc_randomizer_step(seed, (step_size * 8) + 15), which is what
+ * the randomizer engine does internally before de/scrambling OOB data.
+ *
+ * Those tables are statically defined to avoid calculating randomizer state
+ * at runtime.
+ */
+static const u16 sunxi_nfc_randomizer_ecc512_seeds[] = {
+       0x3346, 0x367f, 0x1f18, 0x769a, 0x4f64, 0x068c, 0x2ef1, 0x6b64,
+       0x28a9, 0x15d7, 0x30f8, 0x3659, 0x53db, 0x7c5f, 0x71d4, 0x4409,
+       0x26eb, 0x03cc, 0x655d, 0x47d4, 0x4daa, 0x0877, 0x712d, 0x3617,
+       0x3264, 0x49aa, 0x7f9e, 0x588e, 0x4fbc, 0x7176, 0x7f91, 0x6c6d,
+       0x4b95, 0x5fb7, 0x3844, 0x4037, 0x0184, 0x081b, 0x0ee8, 0x5b91,
+       0x293d, 0x1f71, 0x0e6f, 0x402b, 0x5122, 0x1e52, 0x22be, 0x3d2d,
+       0x75bc, 0x7c60, 0x6291, 0x1a2f, 0x61d4, 0x74aa, 0x4140, 0x29ab,
+       0x472d, 0x2852, 0x017e, 0x15e8, 0x5ec2, 0x17cf, 0x7d0f, 0x06b8,
+       0x117a, 0x6b94, 0x789b, 0x3126, 0x6ac5, 0x5be7, 0x150f, 0x51f8,
+       0x7889, 0x0aa5, 0x663d, 0x77e8, 0x0b87, 0x3dcb, 0x360d, 0x218b,
+       0x512f, 0x7dc9, 0x6a4d, 0x630a, 0x3547, 0x1dd2, 0x5aea, 0x69a5,
+       0x7bfa, 0x5e4f, 0x1519, 0x6430, 0x3a0e, 0x5eb3, 0x5425, 0x0c7a,
+       0x5540, 0x3670, 0x63c1, 0x31e9, 0x5a39, 0x2de7, 0x5979, 0x2891,
+       0x1562, 0x014b, 0x5b05, 0x2756, 0x5a34, 0x13aa, 0x6cb5, 0x2c36,
+       0x5e72, 0x1306, 0x0861, 0x15ef, 0x1ee8, 0x5a37, 0x7ac4, 0x45dd,
+       0x44c4, 0x7266, 0x2f41, 0x3ccc, 0x045e, 0x7d40, 0x7c66, 0x0fa0,
+};
+
+static const u16 sunxi_nfc_randomizer_ecc1024_seeds[] = {
+       0x2cf5, 0x35f1, 0x63a4, 0x5274, 0x2bd2, 0x778b, 0x7285, 0x32b6,
+       0x6a5c, 0x70d6, 0x757d, 0x6769, 0x5375, 0x1e81, 0x0cf3, 0x3982,
+       0x6787, 0x042a, 0x6c49, 0x1925, 0x56a8, 0x40a9, 0x063e, 0x7bd9,
+       0x4dbf, 0x55ec, 0x672e, 0x7334, 0x5185, 0x4d00, 0x232a, 0x7e07,
+       0x445d, 0x6b92, 0x528f, 0x4255, 0x53ba, 0x7d82, 0x2a2e, 0x3a4e,
+       0x75eb, 0x450c, 0x6844, 0x1b5d, 0x581a, 0x4cc6, 0x0379, 0x37b2,
+       0x419f, 0x0e92, 0x6b27, 0x5624, 0x01e3, 0x07c1, 0x44a5, 0x130c,
+       0x13e8, 0x5910, 0x0876, 0x60c5, 0x54e3, 0x5b7f, 0x2269, 0x509f,
+       0x7665, 0x36fd, 0x3e9a, 0x0579, 0x6295, 0x14ef, 0x0a81, 0x1bcc,
+       0x4b16, 0x64db, 0x0514, 0x4f07, 0x0591, 0x3576, 0x6853, 0x0d9e,
+       0x259f, 0x38b7, 0x64fb, 0x3094, 0x4693, 0x6ddd, 0x29bb, 0x0bc8,
+       0x3f47, 0x490e, 0x0c0e, 0x7933, 0x3c9e, 0x5840, 0x398d, 0x3e68,
+       0x4af1, 0x71f5, 0x57cf, 0x1121, 0x64eb, 0x3579, 0x15ac, 0x584d,
+       0x5f2a, 0x47e2, 0x6528, 0x6eac, 0x196e, 0x6b96, 0x0450, 0x0179,
+       0x609c, 0x06e1, 0x4626, 0x42c7, 0x273e, 0x486f, 0x0705, 0x1601,
+       0x145b, 0x407e, 0x062b, 0x57a5, 0x53f9, 0x5659, 0x4410, 0x3ccd,
+};
+
+static u16 sunxi_nfc_randomizer_step(u16 state, int count)
+{
+       state &= 0x7fff;
+
+       /*
+        * This loop is just a simple implementation of a Fibonacci LFSR using
+        * the x16 + x15 + 1 polynomial.
+        */
+       while (count--)
+               state = ((state >> 1) |
+                        (((state ^ (state >> 1)) & 1) << 14)) & 0x7fff;
+
+       return state;
+}
+
+static u16 sunxi_nfc_randomizer_state(struct mtd_info *mtd, int page, bool ecc)
+{
+       const u16 *seeds = sunxi_nfc_randomizer_page_seeds;
+       int mod = mtd->erasesize / mtd->writesize;
+
+       if (mod > ARRAY_SIZE(sunxi_nfc_randomizer_page_seeds))
+               mod = ARRAY_SIZE(sunxi_nfc_randomizer_page_seeds);
+
+       if (ecc) {
+               if (mtd->ecc_step_size == 512)
+                       seeds = sunxi_nfc_randomizer_ecc512_seeds;
+               else
+                       seeds = sunxi_nfc_randomizer_ecc1024_seeds;
+       }
+
+       return seeds[page % mod];
+}
+
+static void sunxi_nfc_randomizer_config(struct mtd_info *mtd,
+                                       int page, bool ecc)
+{
+       struct nand_chip *nand = mtd_to_nand(mtd);
+       struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
+       u32 ecc_ctl = readl(nfc->regs + NFC_REG_ECC_CTL);
+       u16 state;
+
+       if (!(nand->options & NAND_NEED_SCRAMBLING))
+               return;
+
+       ecc_ctl = readl(nfc->regs + NFC_REG_ECC_CTL);
+       state = sunxi_nfc_randomizer_state(mtd, page, ecc);
+       ecc_ctl = readl(nfc->regs + NFC_REG_ECC_CTL) & ~NFC_RANDOM_SEED_MSK;
+       writel(ecc_ctl | NFC_RANDOM_SEED(state), nfc->regs + NFC_REG_ECC_CTL);
+}
+
+static void sunxi_nfc_randomizer_enable(struct mtd_info *mtd)
+{
+       struct nand_chip *nand = mtd_to_nand(mtd);
+       struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
+
+       if (!(nand->options & NAND_NEED_SCRAMBLING))
+               return;
+
+       writel(readl(nfc->regs + NFC_REG_ECC_CTL) | NFC_RANDOM_EN,
+              nfc->regs + NFC_REG_ECC_CTL);
+}
+
+static void sunxi_nfc_randomizer_disable(struct mtd_info *mtd)
+{
+       struct nand_chip *nand = mtd_to_nand(mtd);
+       struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
+
+       if (!(nand->options & NAND_NEED_SCRAMBLING))
+               return;
+
+       writel(readl(nfc->regs + NFC_REG_ECC_CTL) & ~NFC_RANDOM_EN,
+              nfc->regs + NFC_REG_ECC_CTL);
+}
+
+static void sunxi_nfc_randomize_bbm(struct mtd_info *mtd, int page, u8 *bbm)
+{
+       u16 state = sunxi_nfc_randomizer_state(mtd, page, true);
+
+       bbm[0] ^= state;
+       bbm[1] ^= sunxi_nfc_randomizer_step(state, 8);
+}
+
+static void sunxi_nfc_randomizer_write_buf(struct mtd_info *mtd,
+                                          const uint8_t *buf, int len,
+                                          bool ecc, int page)
+{
+       sunxi_nfc_randomizer_config(mtd, page, ecc);
+       sunxi_nfc_randomizer_enable(mtd);
+       sunxi_nfc_write_buf(mtd, buf, len);
+       sunxi_nfc_randomizer_disable(mtd);
+}
+
+static void sunxi_nfc_randomizer_read_buf(struct mtd_info *mtd, uint8_t *buf,
+                                         int len, bool ecc, int page)
+{
+       sunxi_nfc_randomizer_config(mtd, page, ecc);
+       sunxi_nfc_randomizer_enable(mtd);
+       sunxi_nfc_read_buf(mtd, buf, len);
+       sunxi_nfc_randomizer_disable(mtd);
+}
+
+static void sunxi_nfc_hw_ecc_enable(struct mtd_info *mtd)
+{
+       struct nand_chip *nand = mtd_to_nand(mtd);
+       struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
+       struct sunxi_nand_hw_ecc *data = nand->ecc.priv;
+       u32 ecc_ctl;
+
+       ecc_ctl = readl(nfc->regs + NFC_REG_ECC_CTL);
+       ecc_ctl &= ~(NFC_ECC_MODE_MSK | NFC_ECC_PIPELINE |
+                    NFC_ECC_BLOCK_SIZE_MSK);
+       ecc_ctl |= NFC_ECC_EN | NFC_ECC_MODE(data->mode) | NFC_ECC_EXCEPTION;
+
+       if (nand->ecc.size == 512)
+               ecc_ctl |= NFC_ECC_BLOCK_512;
+
+       writel(ecc_ctl, nfc->regs + NFC_REG_ECC_CTL);
+}
+
+static void sunxi_nfc_hw_ecc_disable(struct mtd_info *mtd)
+{
+       struct nand_chip *nand = mtd_to_nand(mtd);
+       struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
+
+       writel(readl(nfc->regs + NFC_REG_ECC_CTL) & ~NFC_ECC_EN,
+              nfc->regs + NFC_REG_ECC_CTL);
+}
+
+static inline void sunxi_nfc_user_data_to_buf(u32 user_data, u8 *buf)
+{
+       buf[0] = user_data;
+       buf[1] = user_data >> 8;
+       buf[2] = user_data >> 16;
+       buf[3] = user_data >> 24;
+}
+
+static int sunxi_nfc_hw_ecc_read_chunk(struct mtd_info *mtd,
+                                      u8 *data, int data_off,
+                                      u8 *oob, int oob_off,
+                                      int *cur_off,
+                                      unsigned int *max_bitflips,
+                                      bool bbm, int page)
+{
+       struct nand_chip *nand = mtd_to_nand(mtd);
+       struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
+       struct nand_ecc_ctrl *ecc = &nand->ecc;
+       int raw_mode = 0;
+       u32 status;
+       int ret;
+
+       if (*cur_off != data_off)
+               nand->cmdfunc(mtd, NAND_CMD_RNDOUT, data_off, -1);
+
+       sunxi_nfc_randomizer_read_buf(mtd, NULL, ecc->size, false, page);
+
+       if (data_off + ecc->size != oob_off)
+               nand->cmdfunc(mtd, NAND_CMD_RNDOUT, oob_off, -1);
+
+       ret = sunxi_nfc_wait_cmd_fifo_empty(nfc);
+       if (ret)
+               return ret;
+
+       sunxi_nfc_randomizer_enable(mtd);
+       writel(NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD | NFC_ECC_OP,
+              nfc->regs + NFC_REG_CMD);
+
+       ret = sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0);
+       sunxi_nfc_randomizer_disable(mtd);
+       if (ret)
+               return ret;
+
+       *cur_off = oob_off + ecc->bytes + 4;
+
+       status = readl(nfc->regs + NFC_REG_ECC_ST);
+       if (status & NFC_ECC_PAT_FOUND(0)) {
+               u8 pattern = 0xff;
+
+               if (unlikely(!(readl(nfc->regs + NFC_REG_PAT_ID) & 0x1)))
+                       pattern = 0x0;
+
+               memset(data, pattern, ecc->size);
+               memset(oob, pattern, ecc->bytes + 4);
+
+               return 1;
+       }
+
+       ret = NFC_ECC_ERR_CNT(0, readl(nfc->regs + NFC_REG_ECC_ERR_CNT(0)));
+
+       memcpy_fromio(data, nfc->regs + NFC_RAM0_BASE, ecc->size);
+
+       nand->cmdfunc(mtd, NAND_CMD_RNDOUT, oob_off, -1);
+       sunxi_nfc_randomizer_read_buf(mtd, oob, ecc->bytes + 4, true, page);
+
+       if (status & NFC_ECC_ERR(0)) {
+               /*
+                * Re-read the data with the randomizer disabled to identify
+                * bitflips in erased pages.
+                */
+               if (nand->options & NAND_NEED_SCRAMBLING) {
+                       nand->cmdfunc(mtd, NAND_CMD_RNDOUT, data_off, -1);
+                       nand->read_buf(mtd, data, ecc->size);
+                       nand->cmdfunc(mtd, NAND_CMD_RNDOUT, oob_off, -1);
+                       nand->read_buf(mtd, oob, ecc->bytes + 4);
+               }
+
+               ret = nand_check_erased_ecc_chunk(data, ecc->size,
+                                                 oob, ecc->bytes + 4,
+                                                 NULL, 0, ecc->strength);
+               if (ret >= 0)
+                       raw_mode = 1;
+       } else {
+               /*
+                * The engine protects 4 bytes of OOB data per chunk.
+                * Retrieve the corrected OOB bytes.
+                */
+               sunxi_nfc_user_data_to_buf(readl(nfc->regs +
+                                                NFC_REG_USER_DATA(0)),
+                                          oob);
+
+               /* De-randomize the Bad Block Marker. */
+               if (bbm && nand->options & NAND_NEED_SCRAMBLING)
+                       sunxi_nfc_randomize_bbm(mtd, page, oob);
+       }
+
+       if (ret < 0) {
+               mtd->ecc_stats.failed++;
+       } else {
+               mtd->ecc_stats.corrected += ret;
+               *max_bitflips = max_t(unsigned int, *max_bitflips, ret);
+       }
+
+       return raw_mode;
+}
+
+static void sunxi_nfc_hw_ecc_read_extra_oob(struct mtd_info *mtd,
+                                           u8 *oob, int *cur_off,
+                                           bool randomize, int page)
+{
+       struct nand_chip *nand = mtd_to_nand(mtd);
+       struct nand_ecc_ctrl *ecc = &nand->ecc;
+       int offset = ((ecc->bytes + 4) * ecc->steps);
+       int len = mtd->oobsize - offset;
+
+       if (len <= 0)
+               return;
+
+       if (*cur_off != offset)
+               nand->cmdfunc(mtd, NAND_CMD_RNDOUT,
+                             offset + mtd->writesize, -1);
+
+       if (!randomize)
+               sunxi_nfc_read_buf(mtd, oob + offset, len);
+       else
+               sunxi_nfc_randomizer_read_buf(mtd, oob + offset, len,
+                                             false, page);
+
+       *cur_off = mtd->oobsize + mtd->writesize;
+}
+
+static inline u32 sunxi_nfc_buf_to_user_data(const u8 *buf)
+{
+       return buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
+}
+
+static int sunxi_nfc_hw_ecc_write_chunk(struct mtd_info *mtd,
+                                       const u8 *data, int data_off,
+                                       const u8 *oob, int oob_off,
+                                       int *cur_off, bool bbm,
+                                       int page)
+{
+       struct nand_chip *nand = mtd_to_nand(mtd);
+       struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
+       struct nand_ecc_ctrl *ecc = &nand->ecc;
+       int ret;
+
+       if (data_off != *cur_off)
+               nand->cmdfunc(mtd, NAND_CMD_RNDIN, data_off, -1);
+
+       sunxi_nfc_randomizer_write_buf(mtd, data, ecc->size, false, page);
+
+       /* Fill OOB data in */
+       if ((nand->options & NAND_NEED_SCRAMBLING) && bbm) {
+               u8 user_data[4];
+
+               memcpy(user_data, oob, 4);
+               sunxi_nfc_randomize_bbm(mtd, page, user_data);
+               writel(sunxi_nfc_buf_to_user_data(user_data),
+                      nfc->regs + NFC_REG_USER_DATA(0));
+       } else {
+               writel(sunxi_nfc_buf_to_user_data(oob),
+                      nfc->regs + NFC_REG_USER_DATA(0));
+       }
+
+       if (data_off + ecc->size != oob_off)
+               nand->cmdfunc(mtd, NAND_CMD_RNDIN, oob_off, -1);
+
+       ret = sunxi_nfc_wait_cmd_fifo_empty(nfc);
+       if (ret)
+               return ret;
+
+       sunxi_nfc_randomizer_enable(mtd);
+       writel(NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD |
+              NFC_ACCESS_DIR | NFC_ECC_OP,
+              nfc->regs + NFC_REG_CMD);
+
+       ret = sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0);
+       sunxi_nfc_randomizer_disable(mtd);
+       if (ret)
+               return ret;
+
+       *cur_off = oob_off + ecc->bytes + 4;
+
+       return 0;
+}
+
+static void sunxi_nfc_hw_ecc_write_extra_oob(struct mtd_info *mtd,
+                                            u8 *oob, int *cur_off,
+                                            int page)
+{
+       struct nand_chip *nand = mtd_to_nand(mtd);
+       struct nand_ecc_ctrl *ecc = &nand->ecc;
+       int offset = ((ecc->bytes + 4) * ecc->steps);
+       int len = mtd->oobsize - offset;
+
+       if (len <= 0)
+               return;
+
+       if (*cur_off != offset)
+               nand->cmdfunc(mtd, NAND_CMD_RNDIN,
+                             offset + mtd->writesize, -1);
+
+       sunxi_nfc_randomizer_write_buf(mtd, oob + offset, len, false, page);
+
+       *cur_off = mtd->oobsize + mtd->writesize;
+}
+
+static int sunxi_nfc_hw_ecc_read_page(struct mtd_info *mtd,
+                                     struct nand_chip *chip, uint8_t *buf,
+                                     int oob_required, int page)
+{
+       struct nand_ecc_ctrl *ecc = &chip->ecc;
+       unsigned int max_bitflips = 0;
+       int ret, i, cur_off = 0;
+       bool raw_mode = false;
+
+       sunxi_nfc_hw_ecc_enable(mtd);
+
+       for (i = 0; i < ecc->steps; i++) {
+               int data_off = i * ecc->size;
+               int oob_off = i * (ecc->bytes + 4);
+               u8 *data = buf + data_off;
+               u8 *oob = chip->oob_poi + oob_off;
+
+               ret = sunxi_nfc_hw_ecc_read_chunk(mtd, data, data_off, oob,
+                                                 oob_off + mtd->writesize,
+                                                 &cur_off, &max_bitflips,
+                                                 !i, page);
+               if (ret < 0)
+                       return ret;
+               else if (ret)
+                       raw_mode = true;
+       }
+
+       if (oob_required)
+               sunxi_nfc_hw_ecc_read_extra_oob(mtd, chip->oob_poi, &cur_off,
+                                               !raw_mode, page);
+
+       sunxi_nfc_hw_ecc_disable(mtd);
+
+       return max_bitflips;
+}
+
+static int sunxi_nfc_hw_ecc_read_subpage(struct mtd_info *mtd,
+                                        struct nand_chip *chip,
+                                        uint32_t data_offs, uint32_t readlen,
+                                        uint8_t *bufpoi, int page)
+{
+       struct nand_ecc_ctrl *ecc = &chip->ecc;
+       int ret, i, cur_off = 0;
+       unsigned int max_bitflips = 0;
+
+       sunxi_nfc_hw_ecc_enable(mtd);
+
+       chip->cmdfunc(mtd, NAND_CMD_READ0, 0, page);
+       for (i = data_offs / ecc->size;
+            i < DIV_ROUND_UP(data_offs + readlen, ecc->size); i++) {
+               int data_off = i * ecc->size;
+               int oob_off = i * (ecc->bytes + 4);
+               u8 *data = bufpoi + data_off;
+               u8 *oob = chip->oob_poi + oob_off;
+
+               ret = sunxi_nfc_hw_ecc_read_chunk(mtd, data, data_off,
+                       oob, oob_off + mtd->writesize,
+                       &cur_off, &max_bitflips, !i, page);
+               if (ret < 0)
+                       return ret;
+       }
+
+       sunxi_nfc_hw_ecc_disable(mtd);
+
+       return max_bitflips;
+}
+
+static int sunxi_nfc_hw_ecc_write_page(struct mtd_info *mtd,
+                                      struct nand_chip *chip,
+                                      const uint8_t *buf, int oob_required,
+                                      int page)
+{
+       struct nand_ecc_ctrl *ecc = &chip->ecc;
+       int ret, i, cur_off = 0;
+
+       sunxi_nfc_hw_ecc_enable(mtd);
+
+       for (i = 0; i < ecc->steps; i++) {
+               int data_off = i * ecc->size;
+               int oob_off = i * (ecc->bytes + 4);
+               const u8 *data = buf + data_off;
+               const u8 *oob = chip->oob_poi + oob_off;
+
+               ret = sunxi_nfc_hw_ecc_write_chunk(mtd, data, data_off, oob,
+                                                  oob_off + mtd->writesize,
+                                                  &cur_off, !i, page);
+               if (ret)
+                       return ret;
+       }
+
+       if (oob_required || (chip->options & NAND_NEED_SCRAMBLING))
+               sunxi_nfc_hw_ecc_write_extra_oob(mtd, chip->oob_poi,
+                                                &cur_off, page);
+
+       sunxi_nfc_hw_ecc_disable(mtd);
+
+       return 0;
+}
+
+static int sunxi_nfc_hw_ecc_write_subpage(struct mtd_info *mtd,
+                                         struct nand_chip *chip,
+                                         u32 data_offs, u32 data_len,
+                                         const u8 *buf, int oob_required,
+                                         int page)
+{
+       struct nand_ecc_ctrl *ecc = &chip->ecc;
+       int ret, i, cur_off = 0;
+
+       sunxi_nfc_hw_ecc_enable(mtd);
+
+       for (i = data_offs / ecc->size;
+            i < DIV_ROUND_UP(data_offs + data_len, ecc->size); i++) {
+               int data_off = i * ecc->size;
+               int oob_off = i * (ecc->bytes + 4);
+               const u8 *data = buf + data_off;
+               const u8 *oob = chip->oob_poi + oob_off;
+
+               ret = sunxi_nfc_hw_ecc_write_chunk(mtd, data, data_off, oob,
+                                                  oob_off + mtd->writesize,
+                                                  &cur_off, !i, page);
+               if (ret)
+                       return ret;
+       }
+
+       sunxi_nfc_hw_ecc_disable(mtd);
+
+       return 0;
+}
+
+static int sunxi_nfc_hw_syndrome_ecc_read_page(struct mtd_info *mtd,
+                                              struct nand_chip *chip,
+                                              uint8_t *buf, int oob_required,
+                                              int page)
+{
+       struct nand_ecc_ctrl *ecc = &chip->ecc;
+       unsigned int max_bitflips = 0;
+       int ret, i, cur_off = 0;
+       bool raw_mode = false;
+
+       sunxi_nfc_hw_ecc_enable(mtd);
+
+       for (i = 0; i < ecc->steps; i++) {
+               int data_off = i * (ecc->size + ecc->bytes + 4);
+               int oob_off = data_off + ecc->size;
+               u8 *data = buf + (i * ecc->size);
+               u8 *oob = chip->oob_poi + (i * (ecc->bytes + 4));
+
+               ret = sunxi_nfc_hw_ecc_read_chunk(mtd, data, data_off, oob,
+                                                 oob_off, &cur_off,
+                                                 &max_bitflips, !i, page);
+               if (ret < 0)
+                       return ret;
+               else if (ret)
+                       raw_mode = true;
+       }
+
+       if (oob_required)
+               sunxi_nfc_hw_ecc_read_extra_oob(mtd, chip->oob_poi, &cur_off,
+                                               !raw_mode, page);
+
+       sunxi_nfc_hw_ecc_disable(mtd);
+
+       return max_bitflips;
+}
+
+static int sunxi_nfc_hw_syndrome_ecc_write_page(struct mtd_info *mtd,
+                                               struct nand_chip *chip,
+                                               const uint8_t *buf,
+                                               int oob_required, int page)
+{
+       struct nand_ecc_ctrl *ecc = &chip->ecc;
+       int ret, i, cur_off = 0;
+
+       sunxi_nfc_hw_ecc_enable(mtd);
+
+       for (i = 0; i < ecc->steps; i++) {
+               int data_off = i * (ecc->size + ecc->bytes + 4);
+               int oob_off = data_off + ecc->size;
+               const u8 *data = buf + (i * ecc->size);
+               const u8 *oob = chip->oob_poi + (i * (ecc->bytes + 4));
+
+               ret = sunxi_nfc_hw_ecc_write_chunk(mtd, data, data_off,
+                                                  oob, oob_off, &cur_off,
+                                                  false, page);
+               if (ret)
+                       return ret;
+       }
+
+       if (oob_required || (chip->options & NAND_NEED_SCRAMBLING))
+               sunxi_nfc_hw_ecc_write_extra_oob(mtd, chip->oob_poi,
+                                                &cur_off, page);
+
+       sunxi_nfc_hw_ecc_disable(mtd);
+
+       return 0;
+}
+
+static const s32 tWB_lut[] = {6, 12, 16, 20};
+static const s32 tRHW_lut[] = {4, 8, 12, 20};
+
+static int _sunxi_nand_lookup_timing(const s32 *lut, int lut_size, u32 duration,
+               u32 clk_period)
+{
+       u32 clk_cycles = DIV_ROUND_UP(duration, clk_period);
+       int i;
+
+       for (i = 0; i < lut_size; i++) {
+               if (clk_cycles <= lut[i])
+                       return i;
+       }
+
+       /* Doesn't fit */
+       return -EINVAL;
+}
+
+#define sunxi_nand_lookup_timing(l, p, c) \
+                       _sunxi_nand_lookup_timing(l, ARRAY_SIZE(l), p, c)
+
+static int sunxi_nand_chip_set_timings(struct sunxi_nand_chip *chip,
+                                      const struct nand_sdr_timings *timings)
+{
+       u32 min_clk_period = 0;
+       s32 tWB, tADL, tWHR, tRHW, tCAD;
+
+       /* T1 <=> tCLS */
+       if (timings->tCLS_min > min_clk_period)
+               min_clk_period = timings->tCLS_min;
+
+       /* T2 <=> tCLH */
+       if (timings->tCLH_min > min_clk_period)
+               min_clk_period = timings->tCLH_min;
+
+       /* T3 <=> tCS */
+       if (timings->tCS_min > min_clk_period)
+               min_clk_period = timings->tCS_min;
+
+       /* T4 <=> tCH */
+       if (timings->tCH_min > min_clk_period)
+               min_clk_period = timings->tCH_min;
+
+       /* T5 <=> tWP */
+       if (timings->tWP_min > min_clk_period)
+               min_clk_period = timings->tWP_min;
+
+       /* T6 <=> tWH */
+       if (timings->tWH_min > min_clk_period)
+               min_clk_period = timings->tWH_min;
+
+       /* T7 <=> tALS */
+       if (timings->tALS_min > min_clk_period)
+               min_clk_period = timings->tALS_min;
+
+       /* T8 <=> tDS */
+       if (timings->tDS_min > min_clk_period)
+               min_clk_period = timings->tDS_min;
+
+       /* T9 <=> tDH */
+       if (timings->tDH_min > min_clk_period)
+               min_clk_period = timings->tDH_min;
+
+       /* T10 <=> tRR */
+       if (timings->tRR_min > (min_clk_period * 3))
+               min_clk_period = DIV_ROUND_UP(timings->tRR_min, 3);
+
+       /* T11 <=> tALH */
+       if (timings->tALH_min > min_clk_period)
+               min_clk_period = timings->tALH_min;
+
+       /* T12 <=> tRP */
+       if (timings->tRP_min > min_clk_period)
+               min_clk_period = timings->tRP_min;
+
+       /* T13 <=> tREH */
+       if (timings->tREH_min > min_clk_period)
+               min_clk_period = timings->tREH_min;
+
+       /* T14 <=> tRC */
+       if (timings->tRC_min > (min_clk_period * 2))
+               min_clk_period = DIV_ROUND_UP(timings->tRC_min, 2);
+
+       /* T15 <=> tWC */
+       if (timings->tWC_min > (min_clk_period * 2))
+               min_clk_period = DIV_ROUND_UP(timings->tWC_min, 2);
+
+       /* T16 - T19 + tCAD */
+       tWB  = sunxi_nand_lookup_timing(tWB_lut, timings->tWB_max,
+                                       min_clk_period);
+       if (tWB < 0) {
+               dev_err(nfc->dev, "unsupported tWB\n");
+               return tWB;
+       }
+
+       tADL = DIV_ROUND_UP(timings->tADL_min, min_clk_period) >> 3;
+       if (tADL > 3) {
+               dev_err(nfc->dev, "unsupported tADL\n");
+               return -EINVAL;
+       }
+
+       tWHR = DIV_ROUND_UP(timings->tWHR_min, min_clk_period) >> 3;
+       if (tWHR > 3) {
+               dev_err(nfc->dev, "unsupported tWHR\n");
+               return -EINVAL;
+       }
+
+       tRHW = sunxi_nand_lookup_timing(tRHW_lut, timings->tRHW_min,
+                                       min_clk_period);
+       if (tRHW < 0) {
+               dev_err(nfc->dev, "unsupported tRHW\n");
+               return tRHW;
+       }
+
+       /*
+        * TODO: according to ONFI specs this value only applies for DDR NAND,
+        * but Allwinner seems to set this to 0x7. Mimic them for now.
+        */
+       tCAD = 0x7;
+
+       /* TODO: A83 has some more bits for CDQSS, CS, CLHZ, CCS, WC */
+       chip->timing_cfg = NFC_TIMING_CFG(tWB, tADL, tWHR, tRHW, tCAD);
+
+       /*
+        * ONFI specification 3.1, paragraph 4.15.2 dictates that EDO data
+        * output cycle timings shall be used if the host drives tRC less than
+        * 30 ns.
+        */
+       chip->timing_ctl = (timings->tRC_min < 30000) ? NFC_TIMING_CTL_EDO : 0;
+
+       /* Convert min_clk_period from picoseconds to nanoseconds */
+       min_clk_period = DIV_ROUND_UP(min_clk_period, 1000);
+
+       /*
+        * Convert min_clk_period into a clk frequency, then get the
+        * appropriate rate for the NAND controller IP given this formula
+        * (specified in the datasheet):
+        * nand clk_rate = min_clk_rate
+        */
+       chip->clk_rate = 1000000000L / min_clk_period;
+
+       return 0;
+}
+
+static int sunxi_nand_chip_init_timings(struct sunxi_nand_chip *chip)
+{
+       struct mtd_info *mtd = nand_to_mtd(&chip->nand);
+       const struct nand_sdr_timings *timings;
+       int ret;
+       int mode;
+
+       mode = onfi_get_async_timing_mode(&chip->nand);
+       if (mode == ONFI_TIMING_MODE_UNKNOWN) {
+               mode = chip->nand.onfi_timing_mode_default;
+       } else {
+               uint8_t feature[ONFI_SUBFEATURE_PARAM_LEN] = {};
+               int i;
+
+               mode = fls(mode) - 1;
+               if (mode < 0)
+                       mode = 0;
+
+               feature[0] = mode;
+               for (i = 0; i < chip->nsels; i++) {
+                       chip->nand.select_chip(mtd, i);
+                       ret = chip->nand.onfi_set_features(mtd,
+                                               &chip->nand,
+                                               ONFI_FEATURE_ADDR_TIMING_MODE,
+                                               feature);
+                       chip->nand.select_chip(mtd, -1);
+                       if (ret)
+                               return ret;
+               }
+       }
+
+       timings = onfi_async_timing_mode_to_sdr_timings(mode);
+       if (IS_ERR(timings))
+               return PTR_ERR(timings);
+
+       return sunxi_nand_chip_set_timings(chip, timings);
+}
+
+static int sunxi_nand_hw_common_ecc_ctrl_init(struct mtd_info *mtd,
+                                             struct nand_ecc_ctrl *ecc)
+{
+       static const u8 strengths[] = { 16, 24, 28, 32, 40, 48, 56, 60, 64 };
+       struct sunxi_nand_hw_ecc *data;
+       struct nand_ecclayout *layout;
+       int nsectors;
+       int ret;
+       int i;
+
+       data = kzalloc(sizeof(*data), GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
+
+       if (ecc->size != 512 && ecc->size != 1024)
+               return -EINVAL;
+
+       /* Prefer 1k ECC chunk over 512 ones */
+       if (ecc->size == 512 && mtd->writesize > 512) {
+               ecc->size = 1024;
+               ecc->strength *= 2;
+       }
+
+       /* Add ECC info retrieval from DT */
+       for (i = 0; i < ARRAY_SIZE(strengths); i++) {
+               if (ecc->strength <= strengths[i])
+                       break;
+       }
+
+       if (i >= ARRAY_SIZE(strengths)) {
+               dev_err(nfc->dev, "unsupported strength\n");
+               ret = -ENOTSUPP;
+               goto err;
+       }
+
+       data->mode = i;
+
+       /* HW ECC always request ECC bytes for 1024 bytes blocks */
+       ecc->bytes = DIV_ROUND_UP(ecc->strength * fls(8 * 1024), 8);
+
+       /* HW ECC always work with even numbers of ECC bytes */
+       ecc->bytes = ALIGN(ecc->bytes, 2);
+
+       layout = &data->layout;
+       nsectors = mtd->writesize / ecc->size;
+
+       if (mtd->oobsize < ((ecc->bytes + 4) * nsectors)) {
+               ret = -EINVAL;
+               goto err;
+       }
+
+       layout->eccbytes = (ecc->bytes * nsectors);
+
+       ecc->layout = layout;
+       ecc->priv = data;
+
+       return 0;
+
+err:
+       kfree(data);
+
+       return ret;
+}
+
+#ifndef __UBOOT__
+static void sunxi_nand_hw_common_ecc_ctrl_cleanup(struct nand_ecc_ctrl *ecc)
+{
+       kfree(ecc->priv);
+}
+#endif /* __UBOOT__ */
+
+static int sunxi_nand_hw_ecc_ctrl_init(struct mtd_info *mtd,
+                                      struct nand_ecc_ctrl *ecc)
+{
+       struct nand_ecclayout *layout;
+       int nsectors;
+       int i, j;
+       int ret;
+
+       ret = sunxi_nand_hw_common_ecc_ctrl_init(mtd, ecc);
+       if (ret)
+               return ret;
+
+       ecc->read_page = sunxi_nfc_hw_ecc_read_page;
+       ecc->write_page = sunxi_nfc_hw_ecc_write_page;
+       ecc->read_subpage = sunxi_nfc_hw_ecc_read_subpage;
+       ecc->write_subpage = sunxi_nfc_hw_ecc_write_subpage;
+       layout = ecc->layout;
+       nsectors = mtd->writesize / ecc->size;
+
+       for (i = 0; i < nsectors; i++) {
+               if (i) {
+                       layout->oobfree[i].offset =
+                               layout->oobfree[i - 1].offset +
+                               layout->oobfree[i - 1].length +
+                               ecc->bytes;
+                       layout->oobfree[i].length = 4;
+               } else {
+                       /*
+                        * The first 2 bytes are used for BB markers, hence we
+                        * only have 2 bytes available in the first user data
+                        * section.
+                        */
+                       layout->oobfree[i].length = 2;
+                       layout->oobfree[i].offset = 2;
+               }
+
+               for (j = 0; j < ecc->bytes; j++)
+                       layout->eccpos[(ecc->bytes * i) + j] =
+                                       layout->oobfree[i].offset +
+                                       layout->oobfree[i].length + j;
+       }
+
+       if (mtd->oobsize > (ecc->bytes + 4) * nsectors) {
+               layout->oobfree[nsectors].offset =
+                               layout->oobfree[nsectors - 1].offset +
+                               layout->oobfree[nsectors - 1].length +
+                               ecc->bytes;
+               layout->oobfree[nsectors].length = mtd->oobsize -
+                               ((ecc->bytes + 4) * nsectors);
+       }
+
+       return 0;
+}
+
+static int sunxi_nand_hw_syndrome_ecc_ctrl_init(struct mtd_info *mtd,
+                                               struct nand_ecc_ctrl *ecc)
+{
+       struct nand_ecclayout *layout;
+       int nsectors;
+       int i;
+       int ret;
+
+       ret = sunxi_nand_hw_common_ecc_ctrl_init(mtd, ecc);
+       if (ret)
+               return ret;
+
+       ecc->prepad = 4;
+       ecc->read_page = sunxi_nfc_hw_syndrome_ecc_read_page;
+       ecc->write_page = sunxi_nfc_hw_syndrome_ecc_write_page;
+
+       layout = ecc->layout;
+       nsectors = mtd->writesize / ecc->size;
+
+       for (i = 0; i < (ecc->bytes * nsectors); i++)
+               layout->eccpos[i] = i;
+
+       layout->oobfree[0].length = mtd->oobsize - i;
+       layout->oobfree[0].offset = i;
+
+       return 0;
+}
+
+#ifndef __UBOOT__
+static void sunxi_nand_ecc_cleanup(struct nand_ecc_ctrl *ecc)
+{
+       switch (ecc->mode) {
+       case NAND_ECC_HW:
+       case NAND_ECC_HW_SYNDROME:
+               sunxi_nand_hw_common_ecc_ctrl_cleanup(ecc);
+               break;
+       case NAND_ECC_NONE:
+               kfree(ecc->layout);
+       default:
+               break;
+       }
+}
+#endif /* __UBOOT__ */
+
+static int sunxi_nand_ecc_init(struct mtd_info *mtd, struct nand_ecc_ctrl *ecc)
+{
+       struct nand_chip *nand = mtd_to_nand(mtd);
+       int ret;
+
+       if (!ecc->size) {
+               ecc->size = nand->ecc_step_ds;
+               ecc->strength = nand->ecc_strength_ds;
+       }
+
+       if (!ecc->size || !ecc->strength)
+               return -EINVAL;
+
+       switch (ecc->mode) {
+       case NAND_ECC_SOFT_BCH:
+               break;
+       case NAND_ECC_HW:
+               ret = sunxi_nand_hw_ecc_ctrl_init(mtd, ecc);
+               if (ret)
+                       return ret;
+               break;
+       case NAND_ECC_HW_SYNDROME:
+               ret = sunxi_nand_hw_syndrome_ecc_ctrl_init(mtd, ecc);
+               if (ret)
+                       return ret;
+               break;
+       case NAND_ECC_NONE:
+               ecc->layout = kzalloc(sizeof(*ecc->layout), GFP_KERNEL);
+               if (!ecc->layout)
+                       return -ENOMEM;
+               ecc->layout->oobfree[0].length = mtd->oobsize;
+       case NAND_ECC_SOFT:
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int sunxi_nand_chip_init(int node, struct sunxi_nfc *nfc, int devnum)
+{
+       const struct nand_sdr_timings *timings;
+       const void *blob = gd->fdt_blob;
+       struct sunxi_nand_chip *chip;
+       struct mtd_info *mtd;
+       struct nand_chip *nand;
+       int nsels;
+       int ret;
+       int i;
+       u32 cs[8], rb[8];
+
+       if (!fdt_getprop(blob, node, "reg", &nsels))
+               return -EINVAL;
+
+       nsels /= sizeof(u32);
+       if (!nsels || nsels > 8) {
+               dev_err(dev, "invalid reg property size\n");
+               return -EINVAL;
+       }
+
+       chip = kzalloc(sizeof(*chip) +
+                      (nsels * sizeof(struct sunxi_nand_chip_sel)),
+                      GFP_KERNEL);
+       if (!chip) {
+               dev_err(dev, "could not allocate chip\n");
+               return -ENOMEM;
+       }
+
+       chip->nsels = nsels;
+       chip->selected = -1;
+
+       for (i = 0; i < nsels; i++) {
+               cs[i] = -1;
+               rb[i] = -1;
+       }
+
+       ret = fdtdec_get_int_array(gd->fdt_blob, node, "reg", cs, nsels);
+       if (ret) {
+               dev_err(dev, "could not retrieve reg property: %d\n", ret);
+               return ret;
+       }
+
+       ret = fdtdec_get_int_array(gd->fdt_blob, node, "allwinner,rb", rb,
+                                  nsels);
+       if (ret) {
+               dev_err(dev, "could not retrieve reg property: %d\n", ret);
+               return ret;
+       }
+
+       for (i = 0; i < nsels; i++) {
+               int tmp = cs[i];
+
+               if (tmp > NFC_MAX_CS) {
+                       dev_err(dev,
+                               "invalid reg value: %u (max CS = 7)\n",
+                               tmp);
+                       return -EINVAL;
+               }
+
+               if (test_and_set_bit(tmp, &nfc->assigned_cs)) {
+                       dev_err(dev, "CS %d already assigned\n", tmp);
+                       return -EINVAL;
+               }
+
+               chip->sels[i].cs = tmp;
+
+               tmp = rb[i];
+               if (tmp >= 0 && tmp < 2) {
+                       chip->sels[i].rb.type = RB_NATIVE;
+                       chip->sels[i].rb.info.nativeid = tmp;
+               } else {
+                       ret = gpio_request_by_name_nodev(blob, node,
+                                               "rb-gpios", i,
+                                               &chip->sels[i].rb.info.gpio,
+                                               GPIOD_IS_IN);
+                       if (ret)
+                               chip->sels[i].rb.type = RB_GPIO;
+                       else
+                               chip->sels[i].rb.type = RB_NONE;
+               }
+       }
+
+       timings = onfi_async_timing_mode_to_sdr_timings(0);
+       if (IS_ERR(timings)) {
+               ret = PTR_ERR(timings);
+               dev_err(dev,
+                       "could not retrieve timings for ONFI mode 0: %d\n",
+                       ret);
+               return ret;
+       }
+
+       ret = sunxi_nand_chip_set_timings(chip, timings);
+       if (ret) {
+               dev_err(dev, "could not configure chip timings: %d\n", ret);
+               return ret;
+       }
+
+       nand = &chip->nand;
+       /* Default tR value specified in the ONFI spec (chapter 4.15.1) */
+       nand->chip_delay = 200;
+       nand->controller = &nfc->controller;
+       /*
+        * Set the ECC mode to the default value in case nothing is specified
+        * in the DT.
+        */
+       nand->ecc.mode = NAND_ECC_HW;
+       nand->flash_node = node;
+       nand->select_chip = sunxi_nfc_select_chip;
+       nand->cmd_ctrl = sunxi_nfc_cmd_ctrl;
+       nand->read_buf = sunxi_nfc_read_buf;
+       nand->write_buf = sunxi_nfc_write_buf;
+       nand->read_byte = sunxi_nfc_read_byte;
+
+       mtd = nand_to_mtd(nand);
+       ret = nand_scan_ident(mtd, nsels, NULL);
+       if (ret)
+               return ret;
+
+       if (nand->bbt_options & NAND_BBT_USE_FLASH)
+               nand->bbt_options |= NAND_BBT_NO_OOB;
+
+       if (nand->options & NAND_NEED_SCRAMBLING)
+               nand->options |= NAND_NO_SUBPAGE_WRITE;
+
+       nand->options |= NAND_SUBPAGE_READ;
+
+       ret = sunxi_nand_chip_init_timings(chip);
+       if (ret) {
+               dev_err(dev, "could not configure chip timings: %d\n", ret);
+               return ret;
+       }
+
+       ret = sunxi_nand_ecc_init(mtd, &nand->ecc);
+       if (ret) {
+               dev_err(dev, "ECC init failed: %d\n", ret);
+               return ret;
+       }
+
+       ret = nand_scan_tail(mtd);
+       if (ret) {
+               dev_err(dev, "nand_scan_tail failed: %d\n", ret);
+               return ret;
+       }
+
+       ret = nand_register(devnum, mtd);
+       if (ret) {
+               dev_err(dev, "failed to register mtd device: %d\n", ret);
+               return ret;
+       }
+
+       list_add_tail(&chip->node, &nfc->chips);
+
+       return 0;
+}
+
+static int sunxi_nand_chips_init(int node, struct sunxi_nfc *nfc)
+{
+       const void *blob = gd->fdt_blob;
+       int nand_node;
+       int ret, i = 0;
+
+       for (nand_node = fdt_first_subnode(blob, node); nand_node >= 0;
+            nand_node = fdt_next_subnode(blob, nand_node))
+               i++;
+
+       if (i > 8) {
+               dev_err(dev, "too many NAND chips: %d (max = 8)\n", i);
+               return -EINVAL;
+       }
+
+       i = 0;
+       for (nand_node = fdt_first_subnode(blob, node); nand_node >= 0;
+            nand_node = fdt_next_subnode(blob, nand_node)) {
+               ret = sunxi_nand_chip_init(nand_node, nfc, i++);
+               if (ret)
+                       return ret;
+       }
+
+       return 0;
+}
+
+#ifndef __UBOOT__
+static void sunxi_nand_chips_cleanup(struct sunxi_nfc *nfc)
+{
+       struct sunxi_nand_chip *chip;
+
+       while (!list_empty(&nfc->chips)) {
+               chip = list_first_entry(&nfc->chips, struct sunxi_nand_chip,
+                                       node);
+               nand_release(&chip->mtd);
+               sunxi_nand_ecc_cleanup(&chip->nand.ecc);
+               list_del(&chip->node);
+               kfree(chip);
+       }
+}
+#endif /* __UBOOT__ */
+
+void sunxi_nand_init(void)
+{
+       const void *blob = gd->fdt_blob;
+       struct sunxi_nfc *nfc;
+       fdt_addr_t regs;
+       int node;
+       int ret;
+
+       nfc = kzalloc(sizeof(*nfc), GFP_KERNEL);
+       if (!nfc)
+               return;
+
+       spin_lock_init(&nfc->controller.lock);
+       init_waitqueue_head(&nfc->controller.wq);
+       INIT_LIST_HEAD(&nfc->chips);
+
+       node = fdtdec_next_compatible(blob, 0, COMPAT_SUNXI_NAND);
+       if (node < 0) {
+               pr_err("unable to find nfc node in device tree\n");
+               goto err;
+       }
+
+       if (!fdtdec_get_is_enabled(blob, node)) {
+               pr_err("nfc disabled in device tree\n");
+               goto err;
+       }
+
+       regs = fdtdec_get_addr(blob, node, "reg");
+       if (regs == FDT_ADDR_T_NONE) {
+               pr_err("unable to find nfc address in device tree\n");
+               goto err;
+       }
+
+       nfc->regs = (void *)regs;
+
+       ret = sunxi_nfc_rst(nfc);
+       if (ret)
+               goto err;
+
+       ret = sunxi_nand_chips_init(node, nfc);
+       if (ret) {
+               dev_err(dev, "failed to init nand chips\n");
+               goto err;
+       }
+
+       return;
+
+err:
+       kfree(nfc);
+}
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Boris BREZILLON");
+MODULE_DESCRIPTION("Allwinner NAND Flash Controller driver");
index 2032f658129c5b5608d2f5d8b433bc5fb565c10f..38bd7a5578b37227cd637e38338bf2e378e35b74 100644 (file)
@@ -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)
index 03deabce102341881a7b430f35164eea9c455ce6..0e35dc5b88f7176bd4e4037068b8e117c6666c82 100644 (file)
@@ -20,6 +20,7 @@
  */
 
 #include <common.h>
+#include <watchdog.h>
 #include <linux/compat.h>
 #include <linux/mtd/mtd.h>
 #include "linux/mtd/flashchip.h"
@@ -467,15 +468,18 @@ static int onenand_read_ecc(struct onenand_chip *this)
 static int onenand_wait(struct mtd_info *mtd, int state)
 {
        struct onenand_chip *this = mtd->priv;
-       unsigned int flags = ONENAND_INT_MASTER;
        unsigned int interrupt = 0;
        unsigned int ctrl;
 
-       while (1) {
+       /* Wait at most 20ms ... */
+       u32 timeo = (CONFIG_SYS_HZ * 20) / 1000;
+       u32 time_start = get_timer(0);
+       do {
+               WATCHDOG_RESET();
+               if (get_timer(time_start) > timeo)
+                       return -EIO;
                interrupt = this->read_word(this->base + ONENAND_REG_INTERRUPT);
-               if (interrupt & flags)
-                       break;
-       }
+       } while ((interrupt & ONENAND_INT_MASTER) == 0);
 
        ctrl = this->read_word(this->base + ONENAND_REG_CTRL_STATUS);
 
@@ -1154,15 +1158,18 @@ int onenand_read_oob(struct mtd_info *mtd, loff_t from,
 static int onenand_bbt_wait(struct mtd_info *mtd, int state)
 {
        struct onenand_chip *this = mtd->priv;
-       unsigned int flags = ONENAND_INT_MASTER;
        unsigned int interrupt;
        unsigned int ctrl;
 
-       while (1) {
+       /* Wait at most 20ms ... */
+       u32 timeo = (CONFIG_SYS_HZ * 20) / 1000;
+       u32 time_start = get_timer(0);
+       do {
+               WATCHDOG_RESET();
+               if (get_timer(time_start) > timeo)
+                       return ONENAND_BBT_READ_FATAL_ERROR;
                interrupt = this->read_word(this->base + ONENAND_REG_INTERRUPT);
-               if (interrupt & flags)
-                       break;
-       }
+       } while ((interrupt & ONENAND_INT_MASTER) == 0);
 
        /* To get correct interrupt status in timeout case */
        interrupt = this->read_word(this->base + ONENAND_REG_INTERRUPT);
@@ -2536,7 +2543,8 @@ static int onenand_chip_probe(struct mtd_info *mtd)
        this->write_word(ONENAND_CMD_RESET, this->base + ONENAND_BOOTRAM);
 
        /* Wait reset */
-       this->wait(mtd, FL_RESETING);
+       if (this->wait(mtd, FL_RESETING))
+               return -ENXIO;
 
        /* Restore system configuration 1 */
        this->write_word(syscfg, this->base + ONENAND_REG_SYS_CFG1);
@@ -2649,6 +2657,7 @@ int onenand_probe(struct mtd_info *mtd)
        mtd->_sync = onenand_sync;
        mtd->_block_isbad = onenand_block_isbad;
        mtd->_block_markbad = onenand_block_markbad;
+       mtd->writebufsize = mtd->writesize;
 
        return 0;
 }
index fe6b7d923ccc56bf75d9c07d116e50240f5c98be..1925f41d8a22ee020417b794c67e347bd511c4cb 100644 (file)
@@ -93,6 +93,54 @@ static int onenand_spl_read_page(uint32_t block, uint32_t page, uint32_t *buf,
        return 0;
 }
 
+#ifdef CONFIG_SPL_UBI
+/* Temporary storage for non page aligned and non page sized reads. */
+static u8 scratch_buf[PAGE_4K];
+
+/**
+ * onenand_spl_read_block - Read data from physical eraseblock into a buffer
+ * @block:     Number of the physical eraseblock
+ * @offset:    Data offset from the start of @peb
+ * @len:       Data size to read
+ * @dst:       Address of the destination buffer
+ *
+ * Notes:
+ *     @offset + @len are not allowed to be larger than a physical
+ *     erase block. No sanity check done for simplicity reasons.
+ */
+int onenand_spl_read_block(int block, int offset, int len, void *dst)
+{
+       int page, read, psize;
+
+       psize = onenand_spl_get_geometry();
+       /* Calculate the page number */
+       page = offset / psize;
+       /* Offset to the start of a flash page */
+       offset = offset % psize;
+
+       while (len) {
+               /*
+                * Non page aligned reads go to the scratch buffer.
+                * Page aligned reads go directly to the destination.
+                */
+               if (offset || len < psize) {
+                       onenand_spl_read_page(block, page,
+                                             (uint32_t *)scratch_buf, psize);
+                       read = min(len, psize - offset);
+                       memcpy(dst, scratch_buf + offset, read);
+                       offset = 0;
+               } else {
+                       onenand_spl_read_page(block, page, dst, psize);
+                       read = psize;
+               }
+               page++;
+               len -= read;
+               dst += read;
+       }
+       return 0;
+}
+#endif
+
 void onenand_spl_load_image(uint32_t offs, uint32_t size, void *dst)
 {
        uint32_t *addr = (uint32_t *)dst;
index ae60c3bb71dffd2203fb8fbca5d821aa12c8a60d..c15ec9df079eb124d15ce1321713816e4f1fb4c6 100644 (file)
@@ -24,33 +24,33 @@ static __attribute__((unused)) char dev_name[] = "onenand0";
 
 void onenand_init(void)
 {
+       int err = 0;
        memset(&onenand_mtd, 0, sizeof(struct mtd_info));
        memset(&onenand_chip, 0, sizeof(struct onenand_chip));
 
        onenand_mtd.priv = &onenand_chip;
 
 #ifdef CONFIG_USE_ONENAND_BOARD_INIT
-       /*
-        * It's used for some board init required
-        */
-       onenand_board_init(&onenand_mtd);
+       /* It's used for some board init required */
+       err = onenand_board_init(&onenand_mtd);
 #else
        onenand_chip.base = (void *) CONFIG_SYS_ONENAND_BASE;
 #endif
 
-       onenand_scan(&onenand_mtd, 1);
+       if (!err && !(onenand_scan(&onenand_mtd, 1))) {
 
-       if (onenand_chip.device_id & DEVICE_IS_FLEXONENAND)
-               puts("Flex-");
-       puts("OneNAND: ");
-       print_size(onenand_chip.chipsize, "\n");
+               if (onenand_chip.device_id & DEVICE_IS_FLEXONENAND)
+                       puts("Flex-");
+               puts("OneNAND: ");
 
 #ifdef CONFIG_MTD_DEVICE
-       /*
-        * Add MTD device so that we can reference it later
-        * via the mtdcore infrastructure (e.g. ubi).
-        */
-       onenand_mtd.name = dev_name;
-       add_mtd_device(&onenand_mtd);
+               /*
+                * Add MTD device so that we can reference it later
+                * via the mtdcore infrastructure (e.g. ubi).
+                */
+               onenand_mtd.name = dev_name;
+               add_mtd_device(&onenand_mtd);
 #endif
+       }
+       print_size(onenand_chip.chipsize, "\n");
 }
index 3f7433cbc214b76a7120886f858047d64b51744c..1f23c8e34e6f0579df67694924164d72f3e10f1a 100644 (file)
@@ -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"
index c665836f9560ed4c3f34f601041a4da35bf71a6f..6f47a66f400654c9456570f160e474aa71d1b3c5 100644 (file)
@@ -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 (file)
index 0000000..e3ded5b
--- /dev/null
@@ -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/mtd/ubispl/Makefile b/drivers/mtd/ubispl/Makefile
new file mode 100644 (file)
index 0000000..740dbed
--- /dev/null
@@ -0,0 +1 @@
+obj-y += ubispl.o ../ubi/crc32.o
diff --git a/drivers/mtd/ubispl/ubi-wrapper.h b/drivers/mtd/ubispl/ubi-wrapper.h
new file mode 100644 (file)
index 0000000..72b9dcb
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ * The parts taken from the kernel implementation are:
+ *
+ * Copyright (c) International Business Machines Corp., 2006
+ *
+ * UBISPL specific defines:
+ *
+ * Copyright (c) Thomas Gleixner <tglx@linutronix.de>
+ *
+ * SPDX-License-Identifier: GPL 2.0+ BSD-3-Clause
+ */
+
+/*
+ * Contains various defines copy&pasted from ubi.h and ubi-user.h to make
+ * the upstream fastboot code happy.
+ */
+#ifndef __UBOOT_UBI_WRAPPER_H
+#define __UBOOT_UBI_WRAPPER_H
+
+/*
+ * Error codes returned by the I/O sub-system.
+ *
+ * UBI_IO_FF: the read region of flash contains only 0xFFs
+ * UBI_IO_FF_BITFLIPS: the same as %UBI_IO_FF, but also also there was a data
+ *                     integrity error reported by the MTD driver
+ *                     (uncorrectable ECC error in case of NAND)
+ * UBI_IO_BAD_HDR: the EC or VID header is corrupted (bad magic or CRC)
+ * UBI_IO_BAD_HDR_EBADMSG: the same as %UBI_IO_BAD_HDR, but also there was a
+ *                         data integrity error reported by the MTD driver
+ *                         (uncorrectable ECC error in case of NAND)
+ * UBI_IO_BITFLIPS: bit-flips were detected and corrected
+ *
+ * UBI_FASTMAP_ANCHOR:  u-boot SPL add on to tell the caller that the fastmap
+ *                     anchor block has been found
+ *
+ * Note, it is probably better to have bit-flip and ebadmsg as flags which can
+ * be or'ed with other error code. But this is a big change because there are
+ * may callers, so it does not worth the risk of introducing a bug
+ */
+enum {
+       UBI_IO_FF = 1,
+       UBI_IO_FF_BITFLIPS,
+       UBI_IO_BAD_HDR,
+       UBI_IO_BAD_HDR_EBADMSG,
+       UBI_IO_BITFLIPS,
+       UBI_FASTMAP_ANCHOR,
+};
+
+/*
+ * UBI volume type constants.
+ *
+ * @UBI_DYNAMIC_VOLUME: dynamic volume
+ * @UBI_STATIC_VOLUME:  static volume
+ */
+enum {
+       UBI_DYNAMIC_VOLUME = 3,
+       UBI_STATIC_VOLUME  = 4,
+};
+
+/*
+ * Return codes of the fastmap sub-system
+ *
+ * UBI_NO_FASTMAP: No fastmap super block was found
+ * UBI_BAD_FASTMAP: A fastmap was found but it's unusable
+ */
+enum {
+       UBI_NO_FASTMAP = 1,
+       UBI_BAD_FASTMAP,
+};
+
+/**
+ * struct ubi_fastmap_layout - in-memory fastmap data structure.
+ * @e: PEBs used by the current fastmap
+ * @to_be_tortured: if non-zero tortured this PEB
+ * @used_blocks: number of used PEBs
+ * @max_pool_size: maximal size of the user pool
+ * @max_wl_pool_size: maximal size of the pool used by the WL sub-system
+ */
+struct ubi_fastmap_layout {
+       struct ubi_wl_entry *e[UBI_FM_MAX_BLOCKS];
+       int to_be_tortured[UBI_FM_MAX_BLOCKS];
+       int used_blocks;
+       int max_pool_size;
+       int max_wl_pool_size;
+};
+
+/**
+ * struct ubi_fm_pool - in-memory fastmap pool
+ * @pebs: PEBs in this pool
+ * @used: number of used PEBs
+ * @size: total number of PEBs in this pool
+ * @max_size: maximal size of the pool
+ *
+ * A pool gets filled with up to max_size.
+ * If all PEBs within the pool are used a new fastmap will be written
+ * to the flash and the pool gets refilled with empty PEBs.
+ *
+ */
+struct ubi_fm_pool {
+       int pebs[UBI_FM_MAX_POOL_SIZE];
+       int used;
+       int size;
+       int max_size;
+};
+
+#endif
diff --git a/drivers/mtd/ubispl/ubispl.c b/drivers/mtd/ubispl/ubispl.c
new file mode 100644 (file)
index 0000000..a81a8e7
--- /dev/null
@@ -0,0 +1,926 @@
+/*
+ * Copyright (c) Thomas Gleixner <tglx@linutronix.de>
+ *
+ * The parts taken from the kernel implementation are:
+ *
+ * Copyright (c) International Business Machines Corp., 2006
+ *
+ * SPDX-License-Identifier: GPL 2.0+ BSD-3-Clause
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <ubispl.h>
+
+#include <linux/crc32.h>
+
+#include "ubispl.h"
+
+/**
+ * ubi_calc_fm_size - calculates the fastmap size in bytes for an UBI device.
+ * @ubi: UBI device description object
+ */
+static size_t ubi_calc_fm_size(struct ubi_scan_info *ubi)
+{
+       size_t size;
+
+       size = sizeof(struct ubi_fm_sb) +
+               sizeof(struct ubi_fm_hdr) +
+               sizeof(struct ubi_fm_scan_pool) +
+               sizeof(struct ubi_fm_scan_pool) +
+               (ubi->peb_count * sizeof(struct ubi_fm_ec)) +
+               (sizeof(struct ubi_fm_eba) +
+               (ubi->peb_count * sizeof(__be32))) +
+               sizeof(struct ubi_fm_volhdr) * UBI_MAX_VOLUMES;
+       return roundup(size, ubi->leb_size);
+}
+
+static int ubi_io_read(struct ubi_scan_info *ubi, void *buf, int pnum,
+                      unsigned long from, unsigned long len)
+{
+       return ubi->read(pnum + ubi->peb_offset, from, len, buf);
+}
+
+static int ubi_io_is_bad(struct ubi_scan_info *ubi, int peb)
+{
+       return peb >= ubi->peb_count || peb < 0;
+}
+
+static int ubi_io_read_vid_hdr(struct ubi_scan_info *ubi, int pnum,
+                              struct ubi_vid_hdr *vh, int unused)
+{
+       u32 magic;
+       int res;
+
+       /* No point in rescanning a corrupt block */
+       if (test_bit(pnum, ubi->corrupt))
+               return UBI_IO_BAD_HDR;
+       /*
+        * If the block has been scanned already, no need to rescan
+        */
+       if (test_and_set_bit(pnum, ubi->scanned))
+               return 0;
+
+       res = ubi_io_read(ubi, vh, pnum, ubi->vid_offset, sizeof(*vh));
+
+       /*
+        * Bad block, unrecoverable ECC error, skip the block
+        */
+       if (res) {
+               ubi_dbg("Skipping bad or unreadable block %d", pnum);
+               vh->magic = 0;
+               generic_set_bit(pnum, ubi->corrupt);
+               return res;
+       }
+
+       /* Magic number available ? */
+       magic = be32_to_cpu(vh->magic);
+       if (magic != UBI_VID_HDR_MAGIC) {
+               generic_set_bit(pnum, ubi->corrupt);
+               if (magic == 0xffffffff)
+                       return UBI_IO_FF;
+               ubi_msg("Bad magic in block 0%d %08x", pnum, magic);
+               return UBI_IO_BAD_HDR;
+       }
+
+       /* Header CRC correct ? */
+       if (crc32(UBI_CRC32_INIT, vh, UBI_VID_HDR_SIZE_CRC) !=
+           be32_to_cpu(vh->hdr_crc)) {
+               ubi_msg("Bad CRC in block 0%d", pnum);
+               generic_set_bit(pnum, ubi->corrupt);
+               return UBI_IO_BAD_HDR;
+       }
+
+       ubi_dbg("RV: pnum: %i sqnum %llu", pnum, be64_to_cpu(vh->sqnum));
+
+       return 0;
+}
+
+static int ubi_rescan_fm_vid_hdr(struct ubi_scan_info *ubi,
+                                struct ubi_vid_hdr *vh,
+                                u32 fm_pnum, u32 fm_vol_id, u32 fm_lnum)
+{
+       int res;
+
+       if (ubi_io_is_bad(ubi, fm_pnum))
+               return -EINVAL;
+
+       res = ubi_io_read_vid_hdr(ubi, fm_pnum, vh, 0);
+       if (!res) {
+               /* Check volume id, volume type and lnum */
+               if (be32_to_cpu(vh->vol_id) == fm_vol_id &&
+                   vh->vol_type == UBI_VID_STATIC &&
+                   be32_to_cpu(vh->lnum) == fm_lnum)
+                       return 0;
+               ubi_dbg("RS: PEB %u vol: %u : %u typ %u lnum %u %u",
+                       fm_pnum, fm_vol_id, vh->vol_type,
+                       be32_to_cpu(vh->vol_id),
+                       fm_lnum, be32_to_cpu(vh->lnum));
+       }
+       return res;
+}
+
+/* Insert the logic block into the volume info */
+static int ubi_add_peb_to_vol(struct ubi_scan_info *ubi,
+                             struct ubi_vid_hdr *vh, u32 vol_id,
+                             u32 pnum, u32 lnum)
+{
+       struct ubi_vol_info *vi = ubi->volinfo + vol_id;
+       u32 *ltp;
+
+       /*
+        * If the volume is larger than expected, yell and give up :(
+        */
+       if (lnum >= UBI_MAX_VOL_LEBS) {
+               ubi_warn("Vol: %u LEB %d > %d", vol_id, lnum, UBI_MAX_VOL_LEBS);
+               return -EINVAL;
+       }
+
+       ubi_dbg("SC: Add PEB %u to Vol %u as LEB %u fnd %d sc %d",
+               pnum, vol_id, lnum, !!test_bit(lnum, vi->found),
+               !!test_bit(pnum, ubi->scanned));
+
+       /* Points to the translation entry */
+       ltp = vi->lebs_to_pebs + lnum;
+
+       /* If the block is already assigned, check sqnum */
+       if (__test_and_set_bit(lnum, vi->found)) {
+               u32 cur_pnum = *ltp;
+               struct ubi_vid_hdr *cur = ubi->blockinfo + cur_pnum;
+
+               /*
+                * If the current block hase not yet been scanned, we
+                * need to do that. The other block might be stale or
+                * the current block corrupted and the FM not yet
+                * updated.
+                */
+               if (!test_bit(cur_pnum, ubi->scanned)) {
+                       /*
+                        * If the scan fails, we use the valid block
+                        */
+                       if (ubi_rescan_fm_vid_hdr(ubi, cur, cur_pnum, vol_id,
+                                                 lnum)) {
+                               *ltp = pnum;
+                               return 0;
+                       }
+               }
+
+               /*
+                * Should not happen ....
+                */
+               if (test_bit(cur_pnum, ubi->corrupt)) {
+                       *ltp = pnum;
+                       return 0;
+               }
+
+               ubi_dbg("Vol %u LEB %u PEB %u->sqnum %llu NPEB %u->sqnum %llu",
+                       vol_id, lnum, cur_pnum, be64_to_cpu(cur->sqnum), pnum,
+                       be64_to_cpu(vh->sqnum));
+
+               /*
+                * Compare sqnum and take the newer one
+                */
+               if (be64_to_cpu(cur->sqnum) < be64_to_cpu(vh->sqnum))
+                       *ltp = pnum;
+       } else {
+               *ltp = pnum;
+               if (lnum > vi->last_block)
+                       vi->last_block = lnum;
+       }
+
+       return 0;
+}
+
+static int ubi_scan_vid_hdr(struct ubi_scan_info *ubi, struct ubi_vid_hdr *vh,
+                           u32 pnum)
+{
+       u32 vol_id, lnum;
+       int res;
+
+       if (ubi_io_is_bad(ubi, pnum))
+               return -EINVAL;
+
+       res = ubi_io_read_vid_hdr(ubi, pnum, vh, 0);
+       if (res)
+               return res;
+
+       /* Get volume id */
+       vol_id = be32_to_cpu(vh->vol_id);
+
+       /* If this is the fastmap anchor, return right away */
+       if (vol_id == UBI_FM_SB_VOLUME_ID)
+               return ubi->fm_enabled ? UBI_FASTMAP_ANCHOR : 0;
+
+       /* We only care about static volumes with an id < UBI_SPL_VOL_IDS */
+       if (vol_id >= UBI_SPL_VOL_IDS || vh->vol_type != UBI_VID_STATIC)
+               return 0;
+
+       /* We are only interested in the volumes to load */
+       if (!test_bit(vol_id, ubi->toload))
+               return 0;
+
+       lnum = be32_to_cpu(vh->lnum);
+       return ubi_add_peb_to_vol(ubi, vh, vol_id, pnum, lnum);
+}
+
+static int assign_aeb_to_av(struct ubi_scan_info *ubi, u32 pnum, u32 lnum,
+                            u32 vol_id, u32 vol_type, u32 used)
+{
+       struct ubi_vid_hdr *vh;
+
+       if (ubi_io_is_bad(ubi, pnum))
+               return -EINVAL;
+
+       ubi->fastmap_pebs++;
+
+       if (vol_id >= UBI_SPL_VOL_IDS || vol_type != UBI_STATIC_VOLUME)
+               return 0;
+
+       /* We are only interested in the volumes to load */
+       if (!test_bit(vol_id, ubi->toload))
+               return 0;
+
+       vh = ubi->blockinfo + pnum;
+
+       return ubi_scan_vid_hdr(ubi, vh, pnum);
+}
+
+static int scan_pool(struct ubi_scan_info *ubi, __be32 *pebs, int pool_size)
+{
+       struct ubi_vid_hdr *vh;
+       u32 pnum;
+       int i;
+
+       ubi_dbg("Scanning pool size: %d", pool_size);
+
+       for (i = 0; i < pool_size; i++) {
+               pnum = be32_to_cpu(pebs[i]);
+
+               if (ubi_io_is_bad(ubi, pnum)) {
+                       ubi_err("FM: Bad PEB in fastmap pool! %u", pnum);
+                       return UBI_BAD_FASTMAP;
+               }
+
+               vh = ubi->blockinfo + pnum;
+               /*
+                * We allow the scan to fail here. The loader will notice
+                * and look for a replacement.
+                */
+               ubi_scan_vid_hdr(ubi, vh, pnum);
+       }
+       return 0;
+}
+
+/*
+ * Fastmap code is stolen from Linux kernel and this stub structure is used
+ * to make it happy.
+ */
+struct ubi_attach_info {
+       int i;
+};
+
+static int ubi_attach_fastmap(struct ubi_scan_info *ubi,
+                             struct ubi_attach_info *ai,
+                             struct ubi_fastmap_layout *fm)
+{
+       struct ubi_fm_hdr *fmhdr;
+       struct ubi_fm_scan_pool *fmpl1, *fmpl2;
+       struct ubi_fm_ec *fmec;
+       struct ubi_fm_volhdr *fmvhdr;
+       struct ubi_fm_eba *fm_eba;
+       int ret, i, j, pool_size, wl_pool_size;
+       size_t fm_pos = 0, fm_size = ubi->fm_size;
+       void *fm_raw = ubi->fm_buf;
+
+       memset(ubi->fm_used, 0, sizeof(ubi->fm_used));
+
+       fm_pos += sizeof(struct ubi_fm_sb);
+       if (fm_pos >= fm_size)
+               goto fail_bad;
+
+       fmhdr = (struct ubi_fm_hdr *)(fm_raw + fm_pos);
+       fm_pos += sizeof(*fmhdr);
+       if (fm_pos >= fm_size)
+               goto fail_bad;
+
+       if (be32_to_cpu(fmhdr->magic) != UBI_FM_HDR_MAGIC) {
+               ubi_err("bad fastmap header magic: 0x%x, expected: 0x%x",
+                       be32_to_cpu(fmhdr->magic), UBI_FM_HDR_MAGIC);
+               goto fail_bad;
+       }
+
+       fmpl1 = (struct ubi_fm_scan_pool *)(fm_raw + fm_pos);
+       fm_pos += sizeof(*fmpl1);
+       if (fm_pos >= fm_size)
+               goto fail_bad;
+       if (be32_to_cpu(fmpl1->magic) != UBI_FM_POOL_MAGIC) {
+               ubi_err("bad fastmap pool magic: 0x%x, expected: 0x%x",
+                       be32_to_cpu(fmpl1->magic), UBI_FM_POOL_MAGIC);
+               goto fail_bad;
+       }
+
+       fmpl2 = (struct ubi_fm_scan_pool *)(fm_raw + fm_pos);
+       fm_pos += sizeof(*fmpl2);
+       if (fm_pos >= fm_size)
+               goto fail_bad;
+       if (be32_to_cpu(fmpl2->magic) != UBI_FM_POOL_MAGIC) {
+               ubi_err("bad fastmap pool magic: 0x%x, expected: 0x%x",
+                       be32_to_cpu(fmpl2->magic), UBI_FM_POOL_MAGIC);
+               goto fail_bad;
+       }
+
+       pool_size = be16_to_cpu(fmpl1->size);
+       wl_pool_size = be16_to_cpu(fmpl2->size);
+       fm->max_pool_size = be16_to_cpu(fmpl1->max_size);
+       fm->max_wl_pool_size = be16_to_cpu(fmpl2->max_size);
+
+       if (pool_size > UBI_FM_MAX_POOL_SIZE || pool_size < 0) {
+               ubi_err("bad pool size: %i", pool_size);
+               goto fail_bad;
+       }
+
+       if (wl_pool_size > UBI_FM_MAX_POOL_SIZE || wl_pool_size < 0) {
+               ubi_err("bad WL pool size: %i", wl_pool_size);
+               goto fail_bad;
+       }
+
+       if (fm->max_pool_size > UBI_FM_MAX_POOL_SIZE ||
+           fm->max_pool_size < 0) {
+               ubi_err("bad maximal pool size: %i", fm->max_pool_size);
+               goto fail_bad;
+       }
+
+       if (fm->max_wl_pool_size > UBI_FM_MAX_POOL_SIZE ||
+           fm->max_wl_pool_size < 0) {
+               ubi_err("bad maximal WL pool size: %i", fm->max_wl_pool_size);
+               goto fail_bad;
+       }
+
+       /* read EC values from free list */
+       for (i = 0; i < be32_to_cpu(fmhdr->free_peb_count); i++) {
+               fmec = (struct ubi_fm_ec *)(fm_raw + fm_pos);
+               fm_pos += sizeof(*fmec);
+               if (fm_pos >= fm_size)
+                       goto fail_bad;
+       }
+
+       /* read EC values from used list */
+       for (i = 0; i < be32_to_cpu(fmhdr->used_peb_count); i++) {
+               fmec = (struct ubi_fm_ec *)(fm_raw + fm_pos);
+               fm_pos += sizeof(*fmec);
+               if (fm_pos >= fm_size)
+                       goto fail_bad;
+
+               generic_set_bit(be32_to_cpu(fmec->pnum), ubi->fm_used);
+       }
+
+       /* read EC values from scrub list */
+       for (i = 0; i < be32_to_cpu(fmhdr->scrub_peb_count); i++) {
+               fmec = (struct ubi_fm_ec *)(fm_raw + fm_pos);
+               fm_pos += sizeof(*fmec);
+               if (fm_pos >= fm_size)
+                       goto fail_bad;
+       }
+
+       /* read EC values from erase list */
+       for (i = 0; i < be32_to_cpu(fmhdr->erase_peb_count); i++) {
+               fmec = (struct ubi_fm_ec *)(fm_raw + fm_pos);
+               fm_pos += sizeof(*fmec);
+               if (fm_pos >= fm_size)
+                       goto fail_bad;
+       }
+
+       /* Iterate over all volumes and read their EBA table */
+       for (i = 0; i < be32_to_cpu(fmhdr->vol_count); i++) {
+               u32 vol_id, vol_type, used, reserved;
+
+               fmvhdr = (struct ubi_fm_volhdr *)(fm_raw + fm_pos);
+               fm_pos += sizeof(*fmvhdr);
+               if (fm_pos >= fm_size)
+                       goto fail_bad;
+
+               if (be32_to_cpu(fmvhdr->magic) != UBI_FM_VHDR_MAGIC) {
+                       ubi_err("bad fastmap vol header magic: 0x%x, " \
+                               "expected: 0x%x",
+                               be32_to_cpu(fmvhdr->magic), UBI_FM_VHDR_MAGIC);
+                       goto fail_bad;
+               }
+
+               vol_id = be32_to_cpu(fmvhdr->vol_id);
+               vol_type = fmvhdr->vol_type;
+               used = be32_to_cpu(fmvhdr->used_ebs);
+
+               fm_eba = (struct ubi_fm_eba *)(fm_raw + fm_pos);
+               fm_pos += sizeof(*fm_eba);
+               fm_pos += (sizeof(__be32) * be32_to_cpu(fm_eba->reserved_pebs));
+               if (fm_pos >= fm_size)
+                       goto fail_bad;
+
+               if (be32_to_cpu(fm_eba->magic) != UBI_FM_EBA_MAGIC) {
+                       ubi_err("bad fastmap EBA header magic: 0x%x, " \
+                               "expected: 0x%x",
+                               be32_to_cpu(fm_eba->magic), UBI_FM_EBA_MAGIC);
+                       goto fail_bad;
+               }
+
+               reserved = be32_to_cpu(fm_eba->reserved_pebs);
+               ubi_dbg("FA: vol %u used %u res: %u", vol_id, used, reserved);
+               for (j = 0; j < reserved; j++) {
+                       int pnum = be32_to_cpu(fm_eba->pnum[j]);
+
+                       if ((int)be32_to_cpu(fm_eba->pnum[j]) < 0)
+                               continue;
+
+                       if (!__test_and_clear_bit(pnum, ubi->fm_used))
+                               continue;
+
+                       /*
+                        * We only handle static volumes so used_ebs
+                        * needs to be handed in. And we do not assign
+                        * the reserved blocks
+                        */
+                       if (j >= used)
+                               continue;
+
+                       ret = assign_aeb_to_av(ubi, pnum, j, vol_id,
+                                              vol_type, used);
+                       if (!ret)
+                               continue;
+
+                       /*
+                        * Nasty: The fastmap claims that the volume
+                        * has one block more than it, but that block
+                        * is always empty and the other blocks have
+                        * the correct number of total LEBs in the
+                        * headers. Deal with it.
+                        */
+                       if (ret != UBI_IO_FF && j != used - 1)
+                               goto fail_bad;
+                       ubi_dbg("FA: Vol: %u Ignoring empty LEB %d of %d",
+                               vol_id, j, used);
+               }
+       }
+
+       ret = scan_pool(ubi, fmpl1->pebs, pool_size);
+       if (ret)
+               goto fail;
+
+       ret = scan_pool(ubi, fmpl2->pebs, wl_pool_size);
+       if (ret)
+               goto fail;
+
+#ifdef CHECKME
+       /*
+        * If fastmap is leaking PEBs (must not happen), raise a
+        * fat warning and fall back to scanning mode.
+        * We do this here because in ubi_wl_init() it's too late
+        * and we cannot fall back to scanning.
+        */
+       if (WARN_ON(count_fastmap_pebs(ai) != ubi->peb_count -
+                   ai->bad_peb_count - fm->used_blocks))
+               goto fail_bad;
+#endif
+
+       return 0;
+
+fail_bad:
+       ret = UBI_BAD_FASTMAP;
+fail:
+       return ret;
+}
+
+static int ubi_scan_fastmap(struct ubi_scan_info *ubi,
+                           struct ubi_attach_info *ai,
+                           int fm_anchor)
+{
+       struct ubi_fm_sb *fmsb, *fmsb2;
+       struct ubi_vid_hdr *vh;
+       struct ubi_fastmap_layout *fm;
+       int i, used_blocks, pnum, ret = 0;
+       size_t fm_size;
+       __be32 crc, tmp_crc;
+       unsigned long long sqnum = 0;
+
+       fmsb = &ubi->fm_sb;
+       fm = &ubi->fm_layout;
+
+       ret = ubi_io_read(ubi, fmsb, fm_anchor, ubi->leb_start, sizeof(*fmsb));
+       if (ret && ret != UBI_IO_BITFLIPS)
+               goto free_fm_sb;
+       else if (ret == UBI_IO_BITFLIPS)
+               fm->to_be_tortured[0] = 1;
+
+       if (be32_to_cpu(fmsb->magic) != UBI_FM_SB_MAGIC) {
+               ubi_err("bad super block magic: 0x%x, expected: 0x%x",
+                       be32_to_cpu(fmsb->magic), UBI_FM_SB_MAGIC);
+               ret = UBI_BAD_FASTMAP;
+               goto free_fm_sb;
+       }
+
+       if (fmsb->version != UBI_FM_FMT_VERSION) {
+               ubi_err("bad fastmap version: %i, expected: %i",
+                       fmsb->version, UBI_FM_FMT_VERSION);
+               ret = UBI_BAD_FASTMAP;
+               goto free_fm_sb;
+       }
+
+       used_blocks = be32_to_cpu(fmsb->used_blocks);
+       if (used_blocks > UBI_FM_MAX_BLOCKS || used_blocks < 1) {
+               ubi_err("number of fastmap blocks is invalid: %i", used_blocks);
+               ret = UBI_BAD_FASTMAP;
+               goto free_fm_sb;
+       }
+
+       fm_size = ubi->leb_size * used_blocks;
+       if (fm_size != ubi->fm_size) {
+               ubi_err("bad fastmap size: %zi, expected: %zi", fm_size,
+                       ubi->fm_size);
+               ret = UBI_BAD_FASTMAP;
+               goto free_fm_sb;
+       }
+
+       vh = &ubi->fm_vh;
+
+       for (i = 0; i < used_blocks; i++) {
+               pnum = be32_to_cpu(fmsb->block_loc[i]);
+
+               if (ubi_io_is_bad(ubi, pnum)) {
+                       ret = UBI_BAD_FASTMAP;
+                       goto free_hdr;
+               }
+
+#ifdef LATER
+               int image_seq;
+               ret = ubi_io_read_ec_hdr(ubi, pnum, ech, 0);
+               if (ret && ret != UBI_IO_BITFLIPS) {
+                       ubi_err("unable to read fastmap block# %i EC (PEB: %i)",
+                               i, pnum);
+                       if (ret > 0)
+                               ret = UBI_BAD_FASTMAP;
+                       goto free_hdr;
+               } else if (ret == UBI_IO_BITFLIPS)
+                       fm->to_be_tortured[i] = 1;
+
+               image_seq = be32_to_cpu(ech->image_seq);
+               if (!ubi->image_seq)
+                       ubi->image_seq = image_seq;
+               /*
+                * Older UBI implementations have image_seq set to zero, so
+                * we shouldn't fail if image_seq == 0.
+                */
+               if (image_seq && (image_seq != ubi->image_seq)) {
+                       ubi_err("wrong image seq:%d instead of %d",
+                               be32_to_cpu(ech->image_seq), ubi->image_seq);
+                       ret = UBI_BAD_FASTMAP;
+                       goto free_hdr;
+               }
+#endif
+               ret = ubi_io_read_vid_hdr(ubi, pnum, vh, 0);
+               if (ret && ret != UBI_IO_BITFLIPS) {
+                       ubi_err("unable to read fastmap block# %i (PEB: %i)",
+                               i, pnum);
+                       goto free_hdr;
+               }
+
+               /*
+                * Mainline code rescans the anchor header. We've done
+                * that already so we merily copy it over.
+                */
+               if (pnum == fm_anchor)
+                       memcpy(vh, ubi->blockinfo + pnum, sizeof(*fm));
+
+               if (i == 0) {
+                       if (be32_to_cpu(vh->vol_id) != UBI_FM_SB_VOLUME_ID) {
+                               ubi_err("bad fastmap anchor vol_id: 0x%x," \
+                                       " expected: 0x%x",
+                                       be32_to_cpu(vh->vol_id),
+                                       UBI_FM_SB_VOLUME_ID);
+                               ret = UBI_BAD_FASTMAP;
+                               goto free_hdr;
+                       }
+               } else {
+                       if (be32_to_cpu(vh->vol_id) != UBI_FM_DATA_VOLUME_ID) {
+                               ubi_err("bad fastmap data vol_id: 0x%x," \
+                                       " expected: 0x%x",
+                                       be32_to_cpu(vh->vol_id),
+                                       UBI_FM_DATA_VOLUME_ID);
+                               ret = UBI_BAD_FASTMAP;
+                               goto free_hdr;
+                       }
+               }
+
+               if (sqnum < be64_to_cpu(vh->sqnum))
+                       sqnum = be64_to_cpu(vh->sqnum);
+
+               ret = ubi_io_read(ubi, ubi->fm_buf + (ubi->leb_size * i), pnum,
+                                 ubi->leb_start, ubi->leb_size);
+               if (ret && ret != UBI_IO_BITFLIPS) {
+                       ubi_err("unable to read fastmap block# %i (PEB: %i, " \
+                               "err: %i)", i, pnum, ret);
+                       goto free_hdr;
+               }
+       }
+
+       fmsb2 = (struct ubi_fm_sb *)(ubi->fm_buf);
+       tmp_crc = be32_to_cpu(fmsb2->data_crc);
+       fmsb2->data_crc = 0;
+       crc = crc32(UBI_CRC32_INIT, ubi->fm_buf, fm_size);
+       if (crc != tmp_crc) {
+               ubi_err("fastmap data CRC is invalid");
+               ubi_err("CRC should be: 0x%x, calc: 0x%x", tmp_crc, crc);
+               ret = UBI_BAD_FASTMAP;
+               goto free_hdr;
+       }
+
+       fmsb2->sqnum = sqnum;
+
+       fm->used_blocks = used_blocks;
+
+       ret = ubi_attach_fastmap(ubi, ai, fm);
+       if (ret) {
+               if (ret > 0)
+                       ret = UBI_BAD_FASTMAP;
+               goto free_hdr;
+       }
+
+       ubi->fm = fm;
+       ubi->fm_pool.max_size = ubi->fm->max_pool_size;
+       ubi->fm_wl_pool.max_size = ubi->fm->max_wl_pool_size;
+       ubi_msg("attached by fastmap %uMB %u blocks",
+               ubi->fsize_mb, ubi->peb_count);
+       ubi_dbg("fastmap pool size: %d", ubi->fm_pool.max_size);
+       ubi_dbg("fastmap WL pool size: %d", ubi->fm_wl_pool.max_size);
+
+out:
+       if (ret)
+               ubi_err("Attach by fastmap failed, doing a full scan!");
+       return ret;
+
+free_hdr:
+free_fm_sb:
+       goto out;
+}
+
+/*
+ * Scan the flash and attempt to attach via fastmap
+ */
+static void ipl_scan(struct ubi_scan_info *ubi)
+{
+       unsigned int pnum;
+       int res;
+
+       /*
+        * Scan first for the fastmap super block
+        */
+       for (pnum = 0; pnum < UBI_FM_MAX_START; pnum++) {
+               res = ubi_scan_vid_hdr(ubi, ubi->blockinfo + pnum, pnum);
+               /*
+                * We ignore errors here as we are meriliy scanning
+                * the headers.
+                */
+               if (res != UBI_FASTMAP_ANCHOR)
+                       continue;
+
+               /*
+                * If fastmap is disabled, continue scanning. This
+                * might happen because the previous attempt failed or
+                * the caller disabled it right away.
+                */
+               if (!ubi->fm_enabled)
+                       continue;
+
+               /*
+                * Try to attach the fastmap, if that fails continue
+                * scanning.
+                */
+               if (!ubi_scan_fastmap(ubi, NULL, pnum))
+                       return;
+               /*
+                * Fastmap failed. Clear everything we have and start
+                * over. We are paranoid and do not trust anything.
+                */
+               memset(ubi->volinfo, 0, sizeof(ubi->volinfo));
+               pnum = 0;
+               break;
+       }
+
+       /*
+        * Continue scanning, ignore errors, we might find what we are
+        * looking for,
+        */
+       for (; pnum < ubi->peb_count; pnum++)
+               ubi_scan_vid_hdr(ubi, ubi->blockinfo + pnum, pnum);
+}
+
+/*
+ * Load a logical block of a volume into memory
+ */
+static int ubi_load_block(struct ubi_scan_info *ubi, uint8_t *laddr,
+                         struct ubi_vol_info *vi, u32 vol_id, u32 lnum,
+                         u32 last)
+{
+       struct ubi_vid_hdr *vh, *vrepl;
+       u32 pnum, crc, dlen;
+
+retry:
+       /*
+        * If this is a fastmap run, we try to rescan full, otherwise
+        * we simply give up.
+        */
+       if (!test_bit(lnum, vi->found)) {
+               ubi_warn("LEB %d of %d is missing", lnum, last);
+               return -EINVAL;
+       }
+
+       pnum = vi->lebs_to_pebs[lnum];
+
+       ubi_dbg("Load vol %u LEB %u PEB %u", vol_id, lnum, pnum);
+
+       if (ubi_io_is_bad(ubi, pnum)) {
+               ubi_warn("Corrupted mapping block %d PB %d\n", lnum, pnum);
+               return -EINVAL;
+       }
+
+       if (test_bit(pnum, ubi->corrupt))
+               goto find_other;
+
+       /*
+        * Lets try to read that block
+        */
+       vh = ubi->blockinfo + pnum;
+
+       if (!test_bit(pnum, ubi->scanned)) {
+               ubi_warn("Vol: %u LEB %u PEB %u not yet scanned", vol_id,
+                        lnum, pnum);
+               if (ubi_rescan_fm_vid_hdr(ubi, vh, pnum, vol_id, lnum))
+                       goto find_other;
+       }
+
+       /*
+        * Check, if the total number of blocks is correct
+        */
+       if (be32_to_cpu(vh->used_ebs) != last) {
+               ubi_dbg("Block count missmatch.");
+               ubi_dbg("vh->used_ebs: %d nrblocks: %d",
+                       be32_to_cpu(vh->used_ebs), last);
+               generic_set_bit(pnum, ubi->corrupt);
+               goto find_other;
+       }
+
+       /*
+        * Get the data length of this block.
+        */
+       dlen = be32_to_cpu(vh->data_size);
+
+       /*
+        * Read the data into RAM. We ignore the return value
+        * here as the only thing which might go wrong are
+        * bitflips. Try nevertheless.
+        */
+       ubi_io_read(ubi, laddr, pnum, ubi->leb_start, dlen);
+
+       /* Calculate CRC over the data */
+       crc = crc32(UBI_CRC32_INIT, laddr, dlen);
+
+       if (crc != be32_to_cpu(vh->data_crc)) {
+               ubi_warn("Vol: %u LEB %u PEB %u data CRC failure", vol_id,
+                        lnum, pnum);
+               generic_set_bit(pnum, ubi->corrupt);
+               goto find_other;
+       }
+
+       /* We are good. Return the data length we read */
+       return dlen;
+
+find_other:
+       ubi_dbg("Find replacement for LEB %u PEB %u", lnum, pnum);
+       generic_clear_bit(lnum, vi->found);
+       vrepl = NULL;
+
+       for (pnum = 0; pnum < ubi->peb_count; pnum++) {
+               struct ubi_vid_hdr *tmp = ubi->blockinfo + pnum;
+               u32 t_vol_id = be32_to_cpu(tmp->vol_id);
+               u32 t_lnum = be32_to_cpu(tmp->lnum);
+
+               if (test_bit(pnum, ubi->corrupt))
+                       continue;
+
+               if (t_vol_id != vol_id || t_lnum != lnum)
+                       continue;
+
+               if (!test_bit(pnum, ubi->scanned)) {
+                       ubi_warn("Vol: %u LEB %u PEB %u not yet scanned",
+                                vol_id, lnum, pnum);
+                       if (ubi_rescan_fm_vid_hdr(ubi, tmp, pnum, vol_id, lnum))
+                               continue;
+               }
+
+               /*
+                * We found one. If its the first, assign it otherwise
+                * compare the sqnum
+                */
+               generic_set_bit(lnum, vi->found);
+
+               if (!vrepl) {
+                       vrepl = tmp;
+                       continue;
+               }
+
+               if (be64_to_cpu(vrepl->sqnum) < be64_to_cpu(tmp->sqnum))
+                       vrepl = tmp;
+       }
+
+       if (vrepl) {
+               /* Update the vi table */
+               pnum = vrepl - ubi->blockinfo;
+               vi->lebs_to_pebs[lnum] = pnum;
+               ubi_dbg("Trying PEB %u for LEB %u", pnum, lnum);
+               vh = vrepl;
+       }
+       goto retry;
+}
+
+/*
+ * Load a volume into RAM
+ */
+static int ipl_load(struct ubi_scan_info *ubi, const u32 vol_id, uint8_t *laddr)
+{
+       struct ubi_vol_info *vi;
+       u32 lnum, last, len;
+
+       if (vol_id >= UBI_SPL_VOL_IDS)
+               return -EINVAL;
+
+       len = 0;
+       vi = ubi->volinfo + vol_id;
+       last = vi->last_block + 1;
+
+       /* Read the blocks to RAM, check CRC */
+       for (lnum = 0 ; lnum < last; lnum++) {
+               int res = ubi_load_block(ubi, laddr, vi, vol_id, lnum, last);
+
+               if (res < 0) {
+                       ubi_warn("Failed to load volume %u", vol_id);
+                       return res;
+               }
+               /* res is the data length of the read block */
+               laddr += res;
+               len += res;
+       }
+       return len;
+}
+
+int ubispl_load_volumes(struct ubispl_info *info, struct ubispl_load *lvols,
+                       int nrvols)
+{
+       struct ubi_scan_info *ubi = info->ubi;
+       int res, i, fastmap = info->fastmap;
+       u32 fsize;
+
+retry:
+       /*
+        * We do a partial initializiation of @ubi. Cleaning fm_buf is
+        * not necessary.
+        */
+       memset(ubi, 0, offsetof(struct ubi_scan_info, fm_buf));
+
+       ubi->read = info->read;
+
+       /* Precalculate the offsets */
+       ubi->vid_offset = info->vid_offset;
+       ubi->leb_start = info->leb_start;
+       ubi->leb_size = info->peb_size - ubi->leb_start;
+       ubi->peb_count = info->peb_count;
+       ubi->peb_offset = info->peb_offset;
+
+       fsize = info->peb_size * info->peb_count;
+       ubi->fsize_mb = fsize >> 20;
+
+       /* Fastmap init */
+       ubi->fm_size = ubi_calc_fm_size(ubi);
+       ubi->fm_enabled = fastmap;
+
+       for (i = 0; i < nrvols; i++) {
+               struct ubispl_load *lv = lvols + i;
+
+               generic_set_bit(lv->vol_id, ubi->toload);
+       }
+
+       ipl_scan(ubi);
+
+       for (i = 0; i < nrvols; i++) {
+               struct ubispl_load *lv = lvols + i;
+
+               ubi_msg("Loading VolId #%d", lv->vol_id);
+               res = ipl_load(ubi, lv->vol_id, lv->load_addr);
+               if (res < 0) {
+                       if (fastmap) {
+                               fastmap = 0;
+                               goto retry;
+                       }
+                       ubi_warn("Failed");
+                       return res;
+               }
+       }
+       return 0;
+}
diff --git a/drivers/mtd/ubispl/ubispl.h b/drivers/mtd/ubispl/ubispl.h
new file mode 100644 (file)
index 0000000..9227881
--- /dev/null
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) Thomas Gleixner <tglx@linutronix.de>
+ *
+ * SPDX-License-Identifier: GPL 2.0+ BSD-3-Clause
+ */
+
+#ifndef _UBOOT_MTD_UBISPL_H
+#define _UBOOT_MTD_UBISPL_H
+
+#include "../ubi/ubi-media.h"
+#include "ubi-wrapper.h"
+
+/*
+ * The maximum number of volume ids we scan. So you can load volume id
+ * 0 to (CONFIG_SPL_UBI_VOL_ID_MAX - 1)
+ */
+#define UBI_SPL_VOL_IDS                CONFIG_SPL_UBI_VOL_IDS
+/*
+ * The size of the read buffer for the fastmap blocks. In theory up to
+ * UBI_FM_MAX_BLOCKS * CONFIG_SPL_MAX_PEB_SIZE. In practice today
+ * one or two blocks.
+ */
+#define UBI_FM_BUF_SIZE                (UBI_FM_MAX_BLOCKS*CONFIG_SPL_UBI_MAX_PEB_SIZE)
+/*
+ * The size of the bitmaps for the attach/ scan
+ */
+#define UBI_FM_BM_SIZE         ((CONFIG_SPL_UBI_MAX_PEBS / BITS_PER_LONG) + 1)
+/*
+ * The maximum number of logical erase blocks per loadable volume
+ */
+#define UBI_MAX_VOL_LEBS       CONFIG_SPL_UBI_MAX_VOL_LEBS
+/*
+ * The bitmap size for the above to denote the found blocks inside the volume
+ */
+#define UBI_VOL_BM_SIZE                ((UBI_MAX_VOL_LEBS / BITS_PER_LONG) + 1)
+
+/**
+ * struct ubi_vol_info - UBISPL internal volume represenation
+ * @last_block:                The last block (highest LEB) found for this volume
+ * @found:             Bitmap to mark found LEBS
+ * @lebs_to_pebs:      LEB to PEB translation table
+ */
+struct ubi_vol_info {
+       u32                             last_block;
+       unsigned long                   found[UBI_VOL_BM_SIZE];
+       u32                             lebs_to_pebs[UBI_MAX_VOL_LEBS];
+};
+
+/**
+ * struct ubi_scan_info - UBISPL internal data for FM attach and full scan
+ *
+ * @read:              Read function to access the flash provided by the caller
+ * @peb_count:         Number of physical erase blocks in the UBI FLASH area
+ *                     aka MTD partition.
+ * @peb_offset:                Offset of PEB0 in the UBI FLASH area (aka MTD partition)
+ *                     to the real start of the FLASH in erase blocks.
+ * @fsize_mb:          Size of the scanned FLASH area in MB (stats only)
+ * @vid_offset:                Offset from the start of a PEB to the VID header
+ * @leb_start:         Offset from the start of a PEB to the data area
+ * @leb_size:          Size of the data area
+ *
+ * @fastmap_pebs:      Counter of PEBs "attached" by fastmap
+ * @fastmap_anchor:    The anchor PEB of the fastmap
+ * @fm_sb:             The fastmap super block data
+ * @fm_vh:             The fastmap VID header
+ * @fm:                        Pointer to the fastmap layout
+ * @fm_layout:         The fastmap layout itself
+ * @fm_pool:           The pool of PEBs to scan at fastmap attach time
+ * @fm_wl_pool:                The pool of PEBs scheduled for wearleveling
+ *
+ * @fm_enabled:                Indicator whether fastmap attachment is enabled.
+ * @fm_used:           Bitmap to indicate the PEBS covered by fastmap
+ * @scanned:           Bitmap to indicate the PEBS of which the VID header
+ *                     hase been physically scanned.
+ * @corrupt:           Bitmap to indicate corrupt blocks
+ * @toload:            Bitmap to indicate the volumes which should be loaded
+ *
+ * @blockinfo:         The vid headers of the scanned blocks
+ * @volinfo:           The volume information of the interesting (toload)
+ *                     volumes
+ *
+ * @fm_buf:            The large fastmap attach buffer
+ */
+struct ubi_scan_info {
+       ubispl_read_flash               read;
+       unsigned int                    fsize_mb;
+       unsigned int                    peb_count;
+       unsigned int                    peb_offset;
+
+       unsigned long                   vid_offset;
+       unsigned long                   leb_start;
+       unsigned long                   leb_size;
+
+       /* Fastmap: The upstream required fields */
+       int                             fastmap_pebs;
+       int                             fastmap_anchor;
+       size_t                          fm_size;
+       struct ubi_fm_sb                fm_sb;
+       struct ubi_vid_hdr              fm_vh;
+       struct ubi_fastmap_layout       *fm;
+       struct ubi_fastmap_layout       fm_layout;
+       struct ubi_fm_pool              fm_pool;
+       struct ubi_fm_pool              fm_wl_pool;
+
+       /* Fastmap: UBISPL specific data */
+       int                             fm_enabled;
+       unsigned long                   fm_used[UBI_FM_BM_SIZE];
+       unsigned long                   scanned[UBI_FM_BM_SIZE];
+       unsigned long                   corrupt[UBI_FM_BM_SIZE];
+       unsigned long                   toload[UBI_FM_BM_SIZE];
+
+       /* Data for storing the VID and volume information */
+       struct ubi_vol_info             volinfo[UBI_SPL_VOL_IDS];
+       struct ubi_vid_hdr              blockinfo[CONFIG_SPL_UBI_MAX_PEBS];
+
+       /* The large buffer for the fastmap */
+       uint8_t                         fm_buf[UBI_FM_BUF_SIZE];
+};
+
+#ifdef CFG_DEBUG
+#define ubi_dbg(fmt, ...) printf("UBI: debug:" fmt "\n", ##__VA_ARGS__)
+#else
+#define ubi_dbg(fmt, ...)
+#endif
+
+#ifdef CONFIG_UBI_SILENCE_MSG
+#define ubi_msg(fmt, ...)
+#else
+#define ubi_msg(fmt, ...) printf("UBI: " fmt "\n", ##__VA_ARGS__)
+#endif
+/* UBI warning messages */
+#define ubi_warn(fmt, ...) printf("UBI warning: " fmt "\n", ##__VA_ARGS__)
+/* UBI error messages */
+#define ubi_err(fmt, ...) printf("UBI error: " fmt "\n", ##__VA_ARGS__)
+
+#endif
index c1cb689ccf337338d0e5d76e473313102c56bddf..88d8e83906a10b314db1d4730b4e9be8e3dcf896 100644 (file)
@@ -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
index 57025921698028fe6e9d8af831e4a0875df0098c..a4485266d45732a66279fbc32bcdee23632e2552 100644 (file)
@@ -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
index 493cdc6d48e18eb0358249079eeaa4450832275b..344fbe20a566ce5c3de39c4dc3937a8750160efa 100644 (file)
@@ -39,3 +39,4 @@ obj-$(CONFIG_PPC_T4080) += t4240.o
 obj-$(CONFIG_PPC_B4420) += b4860.o
 obj-$(CONFIG_PPC_B4860) += b4860.o
 obj-$(CONFIG_LS1043A)  += ls1043.o
+obj-$(CONFIG_LS1046A)  += ls1046.o
diff --git a/drivers/net/fm/ls1046.c b/drivers/net/fm/ls1046.c
new file mode 100644 (file)
index 0000000..bf55554
--- /dev/null
@@ -0,0 +1,123 @@
+/*
+ * Copyright 2016 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+#include <common.h>
+#include <phy.h>
+#include <fm_eth.h>
+#include <asm/io.h>
+#include <asm/arch/fsl_serdes.h>
+
+#define FSL_CHASSIS2_RCWSR13_EC1               0xe0000000 /* bits 416..418 */
+#define FSL_CHASSIS2_RCWSR13_EC1_DTSEC3_RGMII  0x00000000
+#define FSL_CHASSIS2_RCWSR13_EC1_GPIO          0x20000000
+#define FSL_CHASSIS2_RCWSR13_EC1_FTM           0xa0000000
+#define FSL_CHASSIS2_RCWSR13_EC2               0x1c000000 /* bits 419..421 */
+#define FSL_CHASSIS2_RCWSR13_EC2_DTSEC4_RGMII  0x00000000
+#define FSL_CHASSIS2_RCWSR13_EC2_GPIO          0x04000000
+#define FSL_CHASSIS2_RCWSR13_EC2_1588          0x08000000
+#define FSL_CHASSIS2_RCWSR13_EC2_FTM           0x14000000
+
+u32 port_to_devdisr[] = {
+       [FM1_DTSEC1] = FSL_CHASSIS2_DEVDISR2_DTSEC1_1,
+       [FM1_DTSEC2] = FSL_CHASSIS2_DEVDISR2_DTSEC1_2,
+       [FM1_DTSEC3] = FSL_CHASSIS2_DEVDISR2_DTSEC1_3,
+       [FM1_DTSEC4] = FSL_CHASSIS2_DEVDISR2_DTSEC1_4,
+       [FM1_DTSEC5] = FSL_CHASSIS2_DEVDISR2_DTSEC1_5,
+       [FM1_DTSEC6] = FSL_CHASSIS2_DEVDISR2_DTSEC1_6,
+       [FM1_DTSEC9] = FSL_CHASSIS2_DEVDISR2_DTSEC1_9,
+       [FM1_DTSEC10] = FSL_CHASSIS2_DEVDISR2_DTSEC1_10,
+       [FM1_10GEC1] = FSL_CHASSIS2_DEVDISR2_10GEC1_1,
+       [FM1_10GEC2] = FSL_CHASSIS2_DEVDISR2_10GEC1_2,
+       [FM1_10GEC3] = FSL_CHASSIS2_DEVDISR2_10GEC1_3,
+       [FM1_10GEC4] = FSL_CHASSIS2_DEVDISR2_10GEC1_4,
+};
+
+static int is_device_disabled(enum fm_port port)
+{
+       struct ccsr_gur *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
+       u32 devdisr2 = in_be32(&gur->devdisr2);
+
+       return port_to_devdisr[port] & devdisr2;
+}
+
+void fman_disable_port(enum fm_port port)
+{
+       struct ccsr_gur *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
+
+       setbits_be32(&gur->devdisr2, port_to_devdisr[port]);
+}
+
+phy_interface_t fman_port_enet_if(enum fm_port port)
+{
+       struct ccsr_gur *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
+       u32 rcwsr13 = in_be32(&gur->rcwsr[13]);
+
+       if (is_device_disabled(port))
+               return PHY_INTERFACE_MODE_NONE;
+
+       if ((port == FM1_10GEC1) && (is_serdes_configured(XFI_FM1_MAC9)))
+               return PHY_INTERFACE_MODE_XGMII;
+
+       if ((port == FM1_DTSEC9) && (is_serdes_configured(XFI_FM1_MAC9)))
+               return PHY_INTERFACE_MODE_NONE;
+
+       if ((port == FM1_10GEC2) && (is_serdes_configured(XFI_FM1_MAC10)))
+               return PHY_INTERFACE_MODE_XGMII;
+
+       if ((port == FM1_DTSEC10) && (is_serdes_configured(XFI_FM1_MAC10)))
+               return PHY_INTERFACE_MODE_NONE;
+
+       if (port == FM1_DTSEC3)
+               if ((rcwsr13 & FSL_CHASSIS2_RCWSR13_EC1) ==
+                               FSL_CHASSIS2_RCWSR13_EC1_DTSEC3_RGMII)
+                       return PHY_INTERFACE_MODE_RGMII;
+
+       if (port == FM1_DTSEC4)
+               if ((rcwsr13 & FSL_CHASSIS2_RCWSR13_EC2) ==
+                               FSL_CHASSIS2_RCWSR13_EC2_DTSEC4_RGMII)
+                       return PHY_INTERFACE_MODE_RGMII;
+
+       /* handle SGMII, only MAC 2/5/6/9/10 available */
+       switch (port) {
+       case FM1_DTSEC2:
+       case FM1_DTSEC5:
+       case FM1_DTSEC6:
+       case FM1_DTSEC9:
+       case FM1_DTSEC10:
+               if (is_serdes_configured(SGMII_FM1_DTSEC2 + port - FM1_DTSEC2))
+                       return PHY_INTERFACE_MODE_SGMII;
+               break;
+       default:
+               break;
+       }
+
+       /* handle 2.5G SGMII, only MAC 5/9/10 available */
+       switch (port) {
+       case FM1_DTSEC5:
+       case FM1_DTSEC9:
+       case FM1_DTSEC10:
+               if (is_serdes_configured(SGMII_2500_FM1_DTSEC5 +
+                                        port - FM1_DTSEC5))
+                       return PHY_INTERFACE_MODE_SGMII_2500;
+               break;
+       default:
+               break;
+       }
+
+       /* handle QSGMII, only MAC 1/5/6/10 available */
+       switch (port) {
+       case FM1_DTSEC1:
+       case FM1_DTSEC5:
+       case FM1_DTSEC6:
+       case FM1_DTSEC10:
+               if (is_serdes_configured(QSGMII_FM1_A))
+                       return PHY_INTERFACE_MODE_QSGMII;
+               break;
+       default:
+               break;
+       }
+
+       return PHY_INTERFACE_MODE_NONE;
+}
diff --git a/drivers/net/sun8i_emac.c b/drivers/net/sun8i_emac.c
new file mode 100644 (file)
index 0000000..7c088c3
--- /dev/null
@@ -0,0 +1,778 @@
+/*
+ * (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 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));
+
+               /* 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));
+
+       /* 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_emac_set_syscon(priv);
+
+       sun8i_mdio_init(dev->name, priv);
+       priv->bus = miiphy_get_dev_by_name(dev->name);
+
+       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,
+};
index 9eb605be74297794e3411af0d436a603d5f31bad..399055b07813da939d3ef1230b38d0fc70ed523a 100644 (file)
@@ -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);
index 1785e3b28cf5cabd962017e8bb173e27d2ec4e99..2972dba1f98279c2472638c687a13887afc51e7c 100644 (file)
@@ -123,21 +123,21 @@ config QCA953X_PINCTRL
          both the GPIO definitions and pin control functions for each
          available multiplex function.
 
-config ROCKCHIP_PINCTRL
-       bool "Rockchip pin control driver"
+config ROCKCHIP_RK3036_PINCTRL
+       bool "Rockchip rk3036 pin control driver"
        depends on DM
        help
-         Support pin multiplexing control on Rockchip SoCs. The driver is
+         Support pin multiplexing control on Rockchip rk3036 SoCs. The driver is
          controlled by a device tree node which contains both the GPIO
          definitions and pin control functions for each available multiplex
          function.
 
-config ROCKCHIP_3036_PINCTRL
-       bool "Rockchip rk3036 pin control driver"
+config ROCKCHIP_RK3288_PINCTRL
+       bool "Rockchip pin control driver"
        depends on DM
        help
-         Support pin multiplexing control on Rockchip rk3036 SoCs. The driver is
-         controlled by a device tree node which contains both the GPIO
+         Support pin multiplexing control on Rockchip rk3288 SoCs. The driver
+         is controlled by a device tree node which contains both the GPIO
          definitions and pin control functions for each available multiplex
          function.
 
index 6fa7d00d0d8d4c1780f9cc774360c2d26af3ba54..64e9587cce4895c18ebbd8f83ebe491574c4083a 100644 (file)
@@ -5,5 +5,5 @@
 # SPDX-License-Identifier:     GPL-2.0+
 #
 
-obj-$(CONFIG_ROCKCHIP_PINCTRL) += pinctrl_rk3288.o
-obj-$(CONFIG_ROCKCHIP_3036_PINCTRL) += pinctrl_rk3036.o
+obj-$(CONFIG_ROCKCHIP_RK3036_PINCTRL) += pinctrl_rk3036.o
+obj-$(CONFIG_ROCKCHIP_RK3288_PINCTRL) += pinctrl_rk3288.o
index 1fa1daa939c75c296d62bbf240bd667eb691e1fc..8cb3b8228ed3aa4f61e68d8684e045448505a2d3 100644 (file)
@@ -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),
index 225a05c56d09f366cb46018e2b836fd8bcae1e74..3f891f158197c8f8ba48214bae795232d2a859d0 100644 (file)
@@ -1,11 +1,10 @@
 /*
- * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com>
+ * Copyright (C) 2015-2016 Socionext Inc.
+ *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
  *
  * SPDX-License-Identifier:    GPL-2.0+
  */
 
-#include <common.h>
-#include <mapmem.h>
 #include <linux/io.h>
 #include <linux/err.h>
 #include <linux/sizes.h>
@@ -188,7 +187,7 @@ int uniphier_pinctrl_probe(struct udevice *dev,
        if (addr == FDT_ADDR_T_NONE)
                return -EINVAL;
 
-       priv->base = map_sysmem(addr, SZ_4K);
+       priv->base = devm_ioremap(dev, addr, SZ_4K);
        if (!priv->base)
                return -ENOMEM;
 
@@ -196,12 +195,3 @@ int uniphier_pinctrl_probe(struct udevice *dev,
 
        return 0;
 }
-
-int uniphier_pinctrl_remove(struct udevice *dev)
-{
-       struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
-
-       unmap_sysmem(priv->base);
-
-       return 0;
-}
index e95870f2c1e1bc0c3cdf0ca3e7b60cbaa9bd0eea..e42602bc828ef096063756aa30d21bf5346a4f62 100644 (file)
@@ -101,7 +101,6 @@ U_BOOT_DRIVER(uniphier_ld11_pinctrl) = {
        .id = UCLASS_PINCTRL,
        .of_match = of_match_ptr(uniphier_ld11_pinctrl_match),
        .probe = uniphier_ld11_pinctrl_probe,
-       .remove = uniphier_pinctrl_remove,
        .priv_auto_alloc_size = sizeof(struct uniphier_pinctrl_priv),
        .ops = &uniphier_pinctrl_ops,
 };
index e9031966d013e90a7552d6d682592929473106ce..d6ae51248a9771c7e59e7f08cd7eedfc5f714297 100644 (file)
@@ -115,7 +115,6 @@ U_BOOT_DRIVER(uniphier_ld20_pinctrl) = {
        .id = UCLASS_PINCTRL,
        .of_match = of_match_ptr(uniphier_ld20_pinctrl_match),
        .probe = uniphier_ld20_pinctrl_probe,
-       .remove = uniphier_pinctrl_remove,
        .priv_auto_alloc_size = sizeof(struct uniphier_pinctrl_priv),
        .ops = &uniphier_pinctrl_ops,
 };
index dbb9499313252c4515f6ade622e3d08c386d84ab..955858a6aae721f1c3e91fc239652cfe043bc9c5 100644 (file)
@@ -1,5 +1,6 @@
 /*
- * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com>
+ * Copyright (C) 2015-2016 Socionext Inc.
+ *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
  *
  * SPDX-License-Identifier:    GPL-2.0+
  */
@@ -135,7 +136,6 @@ U_BOOT_DRIVER(uniphier_ld4_pinctrl) = {
        .id = UCLASS_PINCTRL,
        .of_match = of_match_ptr(uniphier_ld4_pinctrl_match),
        .probe = uniphier_ld4_pinctrl_probe,
-       .remove = uniphier_pinctrl_remove,
        .priv_auto_alloc_size = sizeof(struct uniphier_pinctrl_priv),
        .ops = &uniphier_pinctrl_ops,
 };
index 8b40801175d1e5fa5154dc5f0377e9c923dc7781..5f9407ed21b934ccf23c072e812e667dcd67a1b5 100644 (file)
@@ -1,5 +1,6 @@
 /*
- * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com>
+ * Copyright (C) 2015-2016 Socionext Inc.
+ *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
  *
  * SPDX-License-Identifier:    GPL-2.0+
  */
@@ -135,7 +136,6 @@ U_BOOT_DRIVER(uniphier_ld6b_pinctrl) = {
        .id = UCLASS_PINCTRL,
        .of_match = of_match_ptr(uniphier_ld6b_pinctrl_match),
        .probe = uniphier_ld6b_pinctrl_probe,
-       .remove = uniphier_pinctrl_remove,
        .priv_auto_alloc_size = sizeof(struct uniphier_pinctrl_priv),
        .ops = &uniphier_pinctrl_ops,
 };
index dace726b0838d4d44a6bfbae82c872f51f895aa3..6f349dcd2e21a0b026fe281d930edd59fa901854 100644 (file)
@@ -1,5 +1,6 @@
 /*
- * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com>
+ * Copyright (C) 2015-2016 Socionext Inc.
+ *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
  *
  * SPDX-License-Identifier:    GPL-2.0+
  */
@@ -143,7 +144,6 @@ U_BOOT_DRIVER(uniphier_pro4_pinctrl) = {
        .id = UCLASS_PINCTRL,
        .of_match = of_match_ptr(uniphier_pro4_pinctrl_match),
        .probe = uniphier_pro4_pinctrl_probe,
-       .remove = uniphier_pinctrl_remove,
        .priv_auto_alloc_size = sizeof(struct uniphier_pinctrl_priv),
        .ops = &uniphier_pinctrl_ops,
        .flags = DM_FLAG_PRE_RELOC,
index 50b41cc37c0638cc07125a3c002fff58c472dc13..268cdea42a2d6ae447449edf3364bbe25636e26f 100644 (file)
@@ -1,5 +1,6 @@
 /*
- * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com>
+ * Copyright (C) 2015-2016 Socionext Inc.
+ *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
  *
  * SPDX-License-Identifier:    GPL-2.0+
  */
@@ -134,7 +135,6 @@ U_BOOT_DRIVER(uniphier_pro5_pinctrl) = {
        .id = UCLASS_PINCTRL,
        .of_match = of_match_ptr(uniphier_pro5_pinctrl_match),
        .probe = uniphier_pro5_pinctrl_probe,
-       .remove = uniphier_pinctrl_remove,
        .priv_auto_alloc_size = sizeof(struct uniphier_pinctrl_priv),
        .ops = &uniphier_pinctrl_ops,
        .flags = DM_FLAG_PRE_RELOC,
index 9223eebc89d626e0efdb0a80e19057131e6361ab..b5342743177d79ad33a6ae5d05533fd986e52eb9 100644 (file)
@@ -1,5 +1,6 @@
 /*
- * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com>
+ * Copyright (C) 2015-2016 Socionext Inc.
+ *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
  *
  * SPDX-License-Identifier:    GPL-2.0+
  */
@@ -147,7 +148,6 @@ U_BOOT_DRIVER(uniphier_pxs2_pinctrl) = {
        .id = UCLASS_PINCTRL,
        .of_match = of_match_ptr(uniphier_pxs2_pinctrl_match),
        .probe = uniphier_pxs2_pinctrl_probe,
-       .remove = uniphier_pinctrl_remove,
        .priv_auto_alloc_size = sizeof(struct uniphier_pinctrl_priv),
        .ops = &uniphier_pinctrl_ops,
 };
index cee0eb1abdd19f5faa0c72b6afc28292506030ea..a85e055dae7621d4d4196bc5c0ccc9df73d43d6e 100644 (file)
@@ -1,5 +1,6 @@
 /*
- * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com>
+ * Copyright (C) 2015-2016 Socionext Inc.
+ *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
  *
  * SPDX-License-Identifier:    GPL-2.0+
  */
@@ -143,7 +144,6 @@ U_BOOT_DRIVER(uniphier_sld8_pinctrl) = {
        .id = UCLASS_PINCTRL,
        .of_match = of_match_ptr(uniphier_sld8_pinctrl_match),
        .probe = uniphier_sld8_pinctrl_probe,
-       .remove = uniphier_pinctrl_remove,
        .priv_auto_alloc_size = sizeof(struct uniphier_pinctrl_priv),
        .ops = &uniphier_pinctrl_ops,
 };
index 4bb893218a47ff9d90001848b5e7b438c1dbb471..4de5b03c8d747b035c2b3371c474f43981ce70fb 100644 (file)
@@ -1,5 +1,6 @@
 /*
- * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com>
+ * Copyright (C) 2015-2016 Socionext Inc.
+ *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
  *
  * SPDX-License-Identifier:    GPL-2.0+
  */
@@ -119,6 +120,4 @@ extern const struct pinctrl_ops uniphier_pinctrl_ops;
 int uniphier_pinctrl_probe(struct udevice *dev,
                           struct uniphier_pinctrl_socdata *socdata);
 
-int uniphier_pinctrl_remove(struct udevice *dev);
-
 #endif /* __PINCTRL_UNIPHIER_H__ */
index 8c643a0b460c81afe4aeb9113bb020d16033aa68..bfa2e1378e22467cbe9c9049a868f7567ef46eee 100644 (file)
@@ -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;
        }
 
index 0e3890391b24342429b8ea2ad1b89273424bd6bb..9ff7234d61e787ce4f2a201f0a1569ed220ea06c 100644 (file)
@@ -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
index 92cbea59135abeabee0e7133f1bba417a9aae8cc..6986d659ab05e0f7fa29c1bd29733205cfad4354 100644 (file)
@@ -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
index c6cb3eb500cae251509f3979a688469dedd4d3c4..88fca15357e6414915427d79d561669d67a156d9 100644 (file)
@@ -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 */
index 58f882b22a607b4b698e8c0d5e89642e56b208f5..bcc3465312e8819c71ff3667b3847b09e6de84bd 100644 (file)
@@ -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 */
 
index 0ce5c44f3315ca5244a8d097ba093bc2654350d4..19f38e162e0fcebb1e8488a2c7bde041108039c0 100644 (file)
@@ -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 (file)
index 0000000..6bac95a
--- /dev/null
@@ -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,
+};
index 8693c1ed140bedb5232038b9f1c332f21b5dcf8e..ef7cf0f26c84673799b79d08f66ceb777e568ffa 100644 (file)
@@ -17,6 +17,8 @@
 #include <dm/platform_data/serial_sh.h>
 #include "serial_sh.h"
 
+DECLARE_GLOBAL_DATA_PTR;
+
 #if defined(CONFIG_CPU_SH7760) || \
        defined(CONFIG_CPU_SH7780) || \
        defined(CONFIG_CPU_SH7785) || \
@@ -201,9 +203,36 @@ static const struct dm_serial_ops sh_serial_ops = {
        .setbrg = sh_serial_setbrg,
 };
 
+#ifdef CONFIG_OF_CONTROL
+static const struct udevice_id sh_serial_id[] ={
+       {.compatible = "renesas,sci", .data = PORT_SCI},
+       {.compatible = "renesas,scif", .data = PORT_SCIF},
+       {.compatible = "renesas,scifa", .data = PORT_SCIFA},
+       {}
+};
+
+static int sh_serial_ofdata_to_platdata(struct udevice *dev)
+{
+       struct sh_serial_platdata *plat = dev_get_platdata(dev);
+       fdt_addr_t addr;
+
+       addr = fdtdec_get_addr(gd->fdt_blob, dev->of_offset, "reg");
+       if (addr == FDT_ADDR_T_NONE)
+               return -EINVAL;
+
+       plat->base = addr;
+       plat->clk = fdtdec_get_int(gd->fdt_blob, dev->of_offset, "clock", 1);
+       plat->type = dev_get_driver_data(dev);
+       return 0;
+}
+#endif
+
 U_BOOT_DRIVER(serial_sh) = {
        .name   = "serial_sh",
        .id     = UCLASS_SERIAL,
+       .of_match = of_match_ptr(sh_serial_id),
+       .ofdata_to_platdata = of_match_ptr(sh_serial_ofdata_to_platdata),
+       .platdata_auto_alloc_size = sizeof(struct sh_serial_platdata),
        .probe  = sh_serial_probe,
        .ops    = &sh_serial_ops,
        .flags  = DM_FLAG_PRE_RELOC,
@@ -234,6 +263,8 @@ U_BOOT_DRIVER(serial_sh) = {
 
 #if defined(CONFIG_SCIF_A)
        #define SCIF_BASE_PORT  PORT_SCIFA
+#elif defined(CONFIG_SCI)
+       #define SCIF_BASE_PORT  PORT_SCI
 #else
        #define SCIF_BASE_PORT  PORT_SCIF
 #endif
index cfbfab7e414ffc6106bed56febe44b226cff30d1..592c0bde3680006786bafde2f8df8f4faf22298c 100644 (file)
@@ -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;
 }
index 525f0a441754efef2fe5e62f0cf30b139a4b4bd4..ab607b7e65966e321cfcf8f1e1e1d37fc673525b 100644 (file)
@@ -1,5 +1,7 @@
 /*
- * Copyright (C) 2012-2015 Masahiro Yamada <yamada.masahiro@socionext.com>
+ * Copyright (C) 2012-2015 Panasonic Corporation
+ * Copyright (C) 2015-2016 Socionext Inc.
+ *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
  *
  * SPDX-License-Identifier:    GPL-2.0+
  */
@@ -9,7 +11,6 @@
 #include <linux/sizes.h>
 #include <asm/errno.h>
 #include <dm/device.h>
-#include <mapmem.h>
 #include <serial.h>
 #include <fdtdec.h>
 
@@ -98,7 +99,7 @@ static int uniphier_serial_probe(struct udevice *dev)
        if (base == FDT_ADDR_T_NONE)
                return -EINVAL;
 
-       port = map_sysmem(base, SZ_64);
+       port = devm_ioremap(dev, base, SZ_64);
        if (!port)
                return -ENOMEM;
 
@@ -115,13 +116,6 @@ static int uniphier_serial_probe(struct udevice *dev)
        return 0;
 }
 
-static int uniphier_serial_remove(struct udevice *dev)
-{
-       unmap_sysmem(uniphier_serial_port(dev));
-
-       return 0;
-}
-
 static const struct udevice_id uniphier_uart_of_match[] = {
        { .compatible = "socionext,uniphier-uart" },
        { /* sentinel */ }
@@ -139,7 +133,6 @@ U_BOOT_DRIVER(uniphier_serial) = {
        .id = UCLASS_SERIAL,
        .of_match = uniphier_uart_of_match,
        .probe = uniphier_serial_probe,
-       .remove = uniphier_serial_remove,
        .priv_auto_alloc_size = sizeof(struct uniphier_serial_private_data),
        .ops = &uniphier_serial_ops,
 };
index 66d54e32ab3884df382ba452889d686236dc1fdf..4f6e7e442fa2288f5e4d502302f9c5ac3ad0c968 100644 (file)
@@ -5,6 +5,7 @@
  * SPDX-License-Identifier:    GPL-2.0+
  */
 
+#include <clk.h>
 #include <common.h>
 #include <debug_uart.h>
 #include <dm.h>
@@ -108,8 +109,33 @@ static int _uart_zynq_serial_putc(struct uart_zynq *regs, const char c)
 int zynq_serial_setbrg(struct udevice *dev, int baudrate)
 {
        struct zynq_uart_priv *priv = dev_get_priv(dev);
-       unsigned long clock = get_uart_clk(0);
+       unsigned long clock;
 
+#if defined(CONFIG_CLK) || defined(CONFIG_SPL_CLK)
+       int ret;
+       struct clk clk;
+
+       ret = clk_get_by_index(dev, 0, &clk);
+       if (ret < 0) {
+               dev_err(dev, "failed to get clock\n");
+               return ret;
+       }
+
+       clock = clk_get_rate(&clk);
+       if (IS_ERR_VALUE(clock)) {
+               dev_err(dev, "failed to get rate\n");
+               return clock;
+       }
+       debug("%s: CLK %ld\n", __func__, clock);
+
+       ret = clk_enable(&clk);
+       if (ret && ret != -ENOSYS) {
+               dev_err(dev, "failed to enable clock\n");
+               return ret;
+       }
+#else
+       clock = get_uart_clk(0);
+#endif
        _uart_zynq_serial_setbrg(priv->regs, clock, baudrate);
 
        return 0;
index 4f7fd5253220882c7074ac62bdcb5e4461a48b07..a5244fff4d9506b339b20bb5ec0bed933527f6e6 100644 (file)
@@ -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);
index 2912e36a53f7601f1d1251a1888c922ab6a7532c..a849f7b199736eb2ba445b1c490f1238e6703172 100644 (file)
@@ -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,
index a71531d3093594e2b2d2109de202aef9049c470a..1a35d558a6df0c76eaf96d57e3217cbdaf294a30 100644 (file)
@@ -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 */
index 0bd4f88926f142bd264625a8ede2f84128f554d7..20aa99a451dc7cab03e33625d8da6e291e3f8bf8 100644 (file)
@@ -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
index 84b6786517cc667ebd04d6542003bac26dc85175..8003f9bfc8635cb32d0f7808f7c5a3e11bf2c2ed 100644 (file)
@@ -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);
index a23278d957a6a184e4d04b184c860afa0a401c66..029927f8ac15bf07c6c9183132f69b9e0ebb80bc 100644 (file)
@@ -403,6 +403,7 @@ static void reconfig_usbd(struct dwc2_udc *dev)
        int i;
        unsigned int uTemp = writel(CORE_SOFT_RESET, &reg->grstctl);
        uint32_t dflt_gusbcfg;
+       uint32_t rx_fifo_sz, tx_fifo_sz, np_tx_fifo_sz;
 
        debug("Reseting OTG controller\n");
 
@@ -467,18 +468,27 @@ static void reconfig_usbd(struct dwc2_udc *dev)
        /* 10. Unmask device IN EP common interrupts*/
        writel(DIEPMSK_INIT, &reg->diepmsk);
 
+       rx_fifo_sz = RX_FIFO_SIZE;
+       np_tx_fifo_sz = NPTX_FIFO_SIZE;
+       tx_fifo_sz = PTX_FIFO_SIZE;
+
+       if (dev->pdata->rx_fifo_sz)
+               rx_fifo_sz = dev->pdata->rx_fifo_sz;
+       if (dev->pdata->np_tx_fifo_sz)
+               np_tx_fifo_sz = dev->pdata->np_tx_fifo_sz;
+       if (dev->pdata->tx_fifo_sz)
+               tx_fifo_sz = dev->pdata->tx_fifo_sz;
+
        /* 11. Set Rx FIFO Size (in 32-bit words) */
-       writel(RX_FIFO_SIZE >> 2, &reg->grxfsiz);
+       writel(rx_fifo_sz, &reg->grxfsiz);
 
        /* 12. Set Non Periodic Tx FIFO Size */
-       writel((NPTX_FIFO_SIZE >> 2) << 16 | ((RX_FIFO_SIZE >> 2)) << 0,
+       writel((np_tx_fifo_sz << 16) | rx_fifo_sz,
               &reg->gnptxfsiz);
 
        for (i = 1; i < DWC2_MAX_HW_ENDPOINTS; i++)
-               writel((PTX_FIFO_SIZE >> 2) << 16 |
-                      ((RX_FIFO_SIZE + NPTX_FIFO_SIZE +
-                        PTX_FIFO_SIZE*(i-1)) >> 2) << 0,
-                      &reg->dieptxf[i-1]);
+               writel((rx_fifo_sz + np_tx_fifo_sz + tx_fifo_sz*(i-1)) |
+                       tx_fifo_sz << 16, &reg->dieptxf[i-1]);
 
        /* Flush the RX FIFO */
        writel(RX_FIFO_FLUSH, &reg->grstctl);
index 78ec90ea9f4387632cfa9796be0cd14d61c17871..c94396afc02648828fe9b81ef11fe7e647d49a51 100644 (file)
@@ -130,9 +130,9 @@ struct dwc2_usbotg_reg {
 #define HIGH_SPEED_CONTROL_PKT_SIZE    64
 #define HIGH_SPEED_BULK_PKT_SIZE       512
 
-#define RX_FIFO_SIZE                   (1024*4)
-#define NPTX_FIFO_SIZE                 (1024*4)
-#define PTX_FIFO_SIZE                  (1536*1)
+#define RX_FIFO_SIZE                   (1024)
+#define NPTX_FIFO_SIZE                 (1024)
+#define PTX_FIFO_SIZE                  (384)
 
 #define DEPCTL_TXFNUM_0                (0x0<<22)
 #define DEPCTL_TXFNUM_1                (0x1<<22)
index 12f5c85c310e09cd3750f1bdd26f63c84270c66d..0d6d2fba8a0f3f22c8f69be5531a4f9282814be9 100644 (file)
@@ -110,6 +110,9 @@ static int setdma_rx(struct dwc2_ep *ep, struct dwc2_request *req)
 
        ctrl =  readl(&reg->out_endp[ep_num].doepctl);
 
+       invalidate_dcache_range((unsigned long) ep->dma_buf,
+                               (unsigned long) ep->dma_buf + ep->len);
+
        writel((unsigned int) ep->dma_buf, &reg->out_endp[ep_num].doepdma);
        writel(DOEPT_SIZ_PKT_CNT(pktcnt) | DOEPT_SIZ_XFER_SIZE(length),
               &reg->out_endp[ep_num].doeptsiz);
index 89580cc31f786b936096c0cc94cff0009b9f0623..5092251ee0b7ef0222f937b07fe4b5ad2d1a9494 100644 (file)
@@ -85,6 +85,13 @@ config USB_EHCI_MSM
          This driver supports combination of Chipidea USB controller
          and Synapsys USB PHY in host mode only.
 
+config USB_EHCI_ZYNQ
+       bool "Support for Xilinx Zynq on-chip EHCI USB controller"
+       depends on ARCH_ZYNQ
+       default y
+       ---help---
+         Enable support for Zynq on-chip EHCI USB controller
+
 config USB_EHCI_GENERIC
        bool "Support for generic EHCI USB controller"
        depends on OF_CONTROL
index bb7c9522927e3ceac46c58845ba236752ab727cd..a71db76d7c7c4b44c073dda60ddfaa13c82951ad 100644 (file)
@@ -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;
        }
index 93d147e26f17fb985e803db7c79d7d9eb054bf63..4e548c24ec859cf92749afea8ecd8bf16b46401b 100644 (file)
@@ -7,3 +7,4 @@
 
 obj-$(CONFIG_TWL4030_USB) += twl4030.o
 obj-$(CONFIG_OMAP_USB_PHY) += omap_usb_phy.o
+obj-$(CONFIG_ROCKCHIP_USB2_PHY) += rockchip_usb2_phy.o
diff --git a/drivers/usb/phy/rockchip_usb2_phy.c b/drivers/usb/phy/rockchip_usb2_phy.c
new file mode 100644 (file)
index 0000000..1958478
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2016 Rockchip Electronics Co., Ltd
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <libfdt.h>
+
+#include "../gadget/dwc2_udc_otg_priv.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define BIT_WRITEABLE_SHIFT    16
+
+struct usb2phy_reg {
+       unsigned int offset;
+       unsigned int bitend;
+       unsigned int bitstart;
+       unsigned int disable;
+       unsigned int enable;
+};
+
+/**
+ * struct rockchip_usb2_phy_cfg: usb-phy port configuration
+ * @port_reset: usb otg per-port reset register
+ * @soft_con: software control usb otg register
+ * @suspend: phy suspend register
+ */
+struct rockchip_usb2_phy_cfg {
+       struct usb2phy_reg port_reset;
+       struct usb2phy_reg soft_con;
+       struct usb2phy_reg suspend;
+};
+
+struct rockchip_usb2_phy_dt_id {
+       char            compatible[128];
+       const void      *data;
+};
+
+static const struct rockchip_usb2_phy_cfg rk3288_pdata = {
+       .port_reset     = {0x00, 12, 12, 0, 1},
+       .soft_con       = {0x08, 2, 2, 0, 1},
+       .suspend        = {0x0c, 5, 0, 0x01, 0x2A},
+};
+
+static struct rockchip_usb2_phy_dt_id rockchip_usb2_phy_dt_ids[] = {
+       { .compatible = "rockchip,rk3288-usb-phy", .data = &rk3288_pdata },
+       {}
+};
+
+static void property_enable(struct dwc2_plat_otg_data *pdata,
+                                 const struct usb2phy_reg *reg, bool en)
+{
+       unsigned int val, mask, tmp;
+
+       tmp = en ? reg->enable : reg->disable;
+       mask = GENMASK(reg->bitend, reg->bitstart);
+       val = (tmp << reg->bitstart) | (mask << BIT_WRITEABLE_SHIFT);
+
+       writel(val, pdata->regs_phy + reg->offset);
+}
+
+
+void otg_phy_init(struct dwc2_udc *dev)
+{
+       struct dwc2_plat_otg_data *pdata = dev->pdata;
+       struct rockchip_usb2_phy_cfg *phy_cfg = NULL;
+       struct rockchip_usb2_phy_dt_id *of_id;
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(rockchip_usb2_phy_dt_ids); i++) {
+               of_id = &rockchip_usb2_phy_dt_ids[i];
+               if (fdt_node_check_compatible(gd->fdt_blob, pdata->phy_of_node,
+                                             of_id->compatible) == 0) {
+                       phy_cfg = (struct rockchip_usb2_phy_cfg *)of_id->data;
+                       break;
+               }
+       }
+       if (!phy_cfg) {
+               debug("Can't find device platform data\n");
+
+               hang();
+               return;
+       }
+       pdata->priv = phy_cfg;
+       /* disable software control */
+       property_enable(pdata, &phy_cfg->soft_con, false);
+
+       /* reset otg port */
+       property_enable(pdata, &phy_cfg->port_reset, true);
+       mdelay(1);
+       property_enable(pdata, &phy_cfg->port_reset, false);
+       udelay(1);
+}
+
+void otg_phy_off(struct dwc2_udc *dev)
+{
+       struct dwc2_plat_otg_data *pdata = dev->pdata;
+       struct rockchip_usb2_phy_cfg *phy_cfg = pdata->priv;
+
+       /* enable software control */
+       property_enable(pdata, &phy_cfg->soft_con, true);
+       /* enter suspend */
+       property_enable(pdata, &phy_cfg->suspend, true);
+}
index cc26f1956d39a7569c70d7b3c49ed545c168ca55..c6d88d9225d7c9fa66cf46208b7eb85e01b09d50 100644 (file)
@@ -238,7 +238,7 @@ int rk_display_init(struct udevice *dev, ulong fbbase,
                return ret;
        }
 
-       ret = uclass_get_device(UCLASS_CLK, 0, &dev_clk);
+       ret = rockchip_get_clk(&dev_clk);
        if (!ret) {
                clk.id = DCLK_VOP0 + remote_vop_id;
                ret = clk_request(dev_clk, &clk);
index 217f05f9e2ec26cfc90acbf48b154b672723c4bd..92214d61b279210e173c845b058a0fe94ea2a952 100644 (file)
@@ -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.
  *
index c56c1299c09f65e445e80fe1da6e12516b74834c..4b7d8b15cc04d7f3a81ab7edf50268901ee4cf8c 100644 (file)
@@ -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
index 0abcbe4c0b3a533301fd1e5eda7e3b7dfe3309be..a6d1d2ab3f412f03ce95499069336910b06b8b1a 100644 (file)
@@ -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 */
index 2f31cf70e3de8dbf1cf3a5ee471911dede1b2ea1..161bc2825fc0f77f3281035271cb736651bf4990 100644 (file)
@@ -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.
  *
index 3feaae641c797d5802319969fa309298e4ff2b90..e9f0dea3084212eaa836306e97496565d1b617ef 100644 (file)
@@ -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,
index 566fd80a05c8769e4e2c77df1a2ec4b00cad9d16..eb45e9851f0d767dd2e5b8e3e11626ba4e665254 100644 (file)
 #ifdef CONFIG_BOOTSCRIPT_COPY_RAM
 #define CONFIG_BS_COPY_ENV \
        "setenv bs_hdr_ram " __stringify(CONFIG_BS_HDR_ADDR_RAM)";" \
-       "setenv bs_hdr_flash " __stringify(CONFIG_BS_HDR_ADDR_FLASH)";" \
+       "setenv bs_hdr_device " __stringify(CONFIG_BS_HDR_ADDR_DEVICE)";" \
        "setenv bs_hdr_size " __stringify(CONFIG_BS_HDR_SIZE)";" \
        "setenv bs_ram " __stringify(CONFIG_BS_ADDR_RAM)";" \
-       "setenv bs_flash " __stringify(CONFIG_BS_ADDR_FLASH)";" \
+       "setenv bs_device " __stringify(CONFIG_BS_ADDR_DEVICE)";" \
        "setenv bs_size " __stringify(CONFIG_BS_SIZE)";"
 
 /* For secure boot flow, default environment used will be used */
 #if defined(CONFIG_SYS_RAMBOOT)
 #if defined(CONFIG_RAMBOOT_NAND)
 #define CONFIG_BS_COPY_CMD \
-       "nand read $bs_hdr_ram $bs_hdr_flash $bs_hdr_size ;" \
-       "nand read $bs_ram $bs_flash $bs_size ;"
+       "nand read $bs_hdr_ram $bs_hdr_device $bs_hdr_size ;" \
+       "nand read $bs_ram $bs_device $bs_size ;"
 #endif /* CONFIG_RAMBOOT_NAND */
-#else
+#elif defined(CONFIG_SD_BOOT)
+#define CONFIG_BS_COPY_CMD \
+       "mmc read $bs_hdr_ram $bs_hdr_device $bs_hdr_size ;" \
+       "mmc read $bs_ram $bs_device $bs_size ;"
+#else /* CONFIG_SD_BOOT */
 #define CONFIG_BS_COPY_CMD \
-       "cp.b $bs_hdr_flash $bs_hdr_ram  $bs_hdr_size ;" \
-       "cp.b $bs_flash $bs_ram  $bs_size ;"
+       "cp.b $bs_hdr_device $bs_hdr_ram  $bs_hdr_size ;" \
+       "cp.b $bs_device $bs_ram  $bs_size ;"
 #endif
 #endif /* CONFIG_BOOTSCRIPT_COPY_RAM */
 
index 2c3c4ac093305e85bec57fa4716e5a21fe6c9677..5de9bb72cf3359acb9c1d98868e0ae18b814eae0 100644 (file)
@@ -830,7 +830,7 @@ unsigned long get_board_ddr_clk(void);
        "consoledev=ttyS0\0"                                    \
        "ramdiskaddr=2000000\0"                                 \
        "ramdiskfile=b4860qds/ramdisk.uboot\0"                  \
-       "fdtaddr=c00000\0"                                      \
+       "fdtaddr=1e00000\0"                                     \
        "fdtfile=b4860qds/b4860qds.dtb\0"                               \
        "bdev=sda3\0"
 
@@ -868,7 +868,7 @@ unsigned long get_board_ddr_clk(void);
  "setenv bootargs root=/dev/ram rw "           \
  "console=$consoledev,$baudrate $othbootargs;" \
  "setenv ramdiskaddr 0x02000000;"              \
- "setenv fdtaddr 0x00c00000;"                  \
+ "setenv fdtaddr 0x01e00000;"                  \
  "setenv loadaddr 0x1000000;"                  \
  "bootm $loadaddr $ramdiskaddr $fdtaddr"
 
index 0a9d8a64aff8ace7105bb402ebdcf683c9f2297b..f2a7c69ad2c72d5a422aa89cf477bcca05a681a4 100644 (file)
@@ -403,7 +403,7 @@ extern unsigned long get_sdram_size(void);
        "consoledev=ttyS0\0"                            \
        "ramdiskaddr=2000000\0"                 \
        "ramdiskfile=rootfs.ext2.gz.uboot\0"            \
-       "fdtaddr=c00000\0"                              \
+       "fdtaddr=1e00000\0"                             \
        "fdtfile=bsc9131rdb.dtb\0"              \
        "bdev=sda1\0"   \
        "hwconfig=usb1:dr_mode=host,phy_type=ulpi\0"    \
index 756beec61b775d79085a5e2bff8e5793d56afa0e..4744f08c9ad56729bb4fae85b3f53b62e73b71c5 100644 (file)
@@ -647,7 +647,7 @@ combinations. this should be removed later
        "consoledev=ttyS0\0"                            \
        "ramdiskaddr=2000000\0"                 \
        "ramdiskfile=rootfs.ext2.gz.uboot\0"            \
-       "fdtaddr=c00000\0"                              \
+       "fdtaddr=1e00000\0"                             \
        "fdtfile=bsc9132qds.dtb\0"              \
        "bdev=sda1\0"   \
        CONFIG_DEF_HWCONFIG\
index 69a9798540efe1c33fd8674abcd71587f7327194..cc5359fe44c2ca2265d4117dd28d67779d063ac0 100644 (file)
        "consoledev=ttyS0\0"                            \
        "ramdiskaddr=2000000\0"                         \
        "ramdiskfile=rootfs.ext2.gz.uboot\0"            \
-       "fdtaddr=c00000\0"                              \
+       "fdtaddr=1e00000\0"                             \
        "fdtfile=name/of/device-tree.dtb\0"                     \
        "othbootargs=ramdisk_size=600000\0"             \
 
index 578325cd05ebf3a31e28893bf66a03d932aefdd1..5b804648edb8c2e3daabd782d251272b0d31231a 100644 (file)
  */
 #define CONFIG_SYS_MONITOR_BASE        CONFIG_SYS_TEXT_BASE /* start of monitor */
 
-#define CONFIG_SYS_MONITOR_LEN (384 * 1024) /* Reserve 384 kB for Mon */
+#define CONFIG_SYS_MONITOR_LEN (512 * 1024) /* Reserve 512 kB for Mon */
 #define CONFIG_SYS_MALLOC_LEN  (512 * 1024) /* Reserved for malloc */
 
 /*
  * the maximum mapped by the Linux kernel during initialization.
  */
 #define CONFIG_SYS_BOOTMAPSZ   (256 << 20) /* Initial Memory map for Linux */
+#define CONFIG_SYS_BOOTM_LEN   (64 << 20)      /* Increase max gunzip size */
 
 /*
  * Core HID Setup
index 5613a4a0cd28f3dc47f4d0e7b7146c861aeaa672..1c4e082d4ec6357d4b4804ac8ad9c356d0a045f1 100644 (file)
 #define CONFIG_SYS_INIT_SP_OFFSET      CONFIG_SYS_GBL_DATA_OFFSET
 
 /* CONFIG_SYS_MONITOR_LEN must be a multiple of CONFIG_ENV_SECT_SIZE */
-#define CONFIG_SYS_MONITOR_LEN (384 * 1024)    /* Reserve 384 kB for Mon */
+#define CONFIG_SYS_MONITOR_LEN (512 * 1024)    /* Reserve 512 kB for Mon */
 #define CONFIG_SYS_MALLOC_LEN  (512 * 1024)    /* Reserved for malloc */
 
 /*
 #define CONFIG_CMD_MTDPARTS
 #define MTDIDS_DEFAULT                 "nand0=e2800000.flash"
 #define MTDPARTS_DEFAULT               \
-       "mtdparts=e2800000.flash:512k(uboot),128k(env),3m@1m(kernel),-(fs)"
+       "mtdparts=e2800000.flash:512k(uboot),128k(env),6m@1m(kernel),-(fs)"
 
 #define CONFIG_SYS_MAX_NAND_DEVICE     1
 #define CONFIG_CMD_NAND 1
  */
                                /* Initial Memory map for Linux*/
 #define CONFIG_SYS_BOOTMAPSZ   (256 << 20)
+#define CONFIG_SYS_BOOTM_LEN   (64 << 20)      /* Increase max gunzip size */
 
 #define CONFIG_SYS_RCWH_PCIHOST 0x80000000     /* PCIHOST  */
 
index 7ce5f599373635c8dd2f5dfcd6b8ad6f749a7afd..23a2e34ce729b2692c196409be1891c89acf8113 100644 (file)
 /*
  * The reserved memory
  */
-#define CONFIG_SYS_MONITOR_LEN (384 * 1024) /* Reserve 384 kB for Mon */
+#define CONFIG_SYS_MONITOR_LEN (512 * 1024) /* Reserve 512 kB for Mon */
 #define CONFIG_SYS_MALLOC_LEN  (512 * 1024) /* Reserved for malloc */
 
 /*
 #define CONFIG_CMD_MTDPARTS
 #define MTDIDS_DEFAULT                 "nand0=e0600000.flash"
 #define MTDPARTS_DEFAULT               \
-       "mtdparts=e0600000.flash:512k(uboot),128k(env),3m@1m(kernel),-(fs)"
+       "mtdparts=e0600000.flash:512k(uboot),128k(env),6m@1m(kernel),-(fs)"
 
 #define CONFIG_SYS_MAX_NAND_DEVICE     1
 #define CONFIG_CMD_NAND                        1
  * the maximum mapped by the Linux kernel during initialization.
  */
 #define CONFIG_SYS_BOOTMAPSZ   (256 << 20) /* Initial Memory map for Linux */
+#define CONFIG_SYS_BOOTM_LEN   (64 << 20)      /* Increase max gunzip size */
 
 /*
  * Core HID Setup
index 13f954d00edd2fede1c5e6ab7f762b9063fbb254..095c0d8dcadc2cfbb2693c8ff91b5046369be62b 100644 (file)
 #endif
 
 /* CONFIG_SYS_MONITOR_LEN must be a multiple of CONFIG_ENV_SECT_SIZE */
-#define CONFIG_SYS_MONITOR_LEN (384 * 1024)    /* Reserve 384 kB for Mon */
+#define CONFIG_SYS_MONITOR_LEN (512 * 1024)    /* Reserve 512 kB for Mon */
 #define CONFIG_SYS_MALLOC_LEN  (256 * 1024)    /* Reserved for malloc */
 
 /*
  */
                                        /* Initial Memory map for Linux */
 #define CONFIG_SYS_BOOTMAPSZ           (256 << 20)
+#define CONFIG_SYS_BOOTM_LEN   (64 << 20)      /* Increase max gunzip size */
 
 /*
  * Core HID Setup
index fd482606adab4ec883ea6b80d70c6b8f2fb4b02f..18418e398e53bc0022771a495110556d669ad5df 100644 (file)
 #endif
 
 /* CONFIG_SYS_MONITOR_LEN must be a multiple of CONFIG_ENV_SECT_SIZE */
-#define CONFIG_SYS_MONITOR_LEN (384 * 1024)    /* Reserve 384 kB for Mon */
+#define CONFIG_SYS_MONITOR_LEN (512 * 1024)    /* Reserve 512 kB for Mon */
 #define CONFIG_SYS_MALLOC_LEN  (256 * 1024)    /* Reserved for malloc */
 
 /*
  */
                                        /* Initial Memory map for Linux */
 #define CONFIG_SYS_BOOTMAPSZ           (256 << 20)
+#define CONFIG_SYS_BOOTM_LEN   (64 << 20)      /* Increase max gunzip size */
 
 /*
  * Core HID Setup
index 288b126d02ef56cb677293d8c1db2198e7a26999..a2fa783a77e97ee6cc5795f5ab2729863c0e4ed4 100644 (file)
                        (CONFIG_SYS_INIT_RAM_SIZE - GENERATED_GBL_DATA_SIZE)
 #define CONFIG_SYS_INIT_SP_OFFSET      CONFIG_SYS_GBL_DATA_OFFSET
 
-#define CONFIG_SYS_MONITOR_LEN (384 * 1024)    /* Reserve 384 kB for Mon */
+#define CONFIG_SYS_MONITOR_LEN (512 * 1024)    /* Reserve 512 kB for Mon */
 #define CONFIG_SYS_MALLOC_LEN  (256 * 1024)    /* Reserved for malloc */
 
 /*
  */
                                /* Initial Memory map for Linux*/
 #define CONFIG_SYS_BOOTMAPSZ   (256 << 20)
+#define CONFIG_SYS_BOOTM_LEN   (64 << 20)      /* Increase max gunzip size */
 
 #define CONFIG_SYS_RCWH_PCIHOST 0x80000000 /* PCIHOST  */
 
index 2721255254fbf520a82e1c42ab4c1aba2d0d8267..c11c0cf8250d2a9351a5bf850804540c23b5ad8c 100644 (file)
@@ -330,7 +330,7 @@ boards, we say we have two, but don't display a message if we find only one. */
 #define CONFIG_SYS_INIT_SP_OFFSET      CONFIG_SYS_GBL_DATA_OFFSET
 
 /* CONFIG_SYS_MONITOR_LEN must be a multiple of CONFIG_ENV_SECT_SIZE */
-#define CONFIG_SYS_MONITOR_LEN (384 * 1024) /* Reserve 384 kB for Mon */
+#define CONFIG_SYS_MONITOR_LEN (512 * 1024) /* Reserve 512 kB for Mon */
 #define CONFIG_SYS_MALLOC_LEN  (256 * 1024) /* Reserved for malloc */
 
 /*
@@ -544,6 +544,7 @@ boards, we say we have two, but don't display a message if we find only one. */
  */
                                /* Initial Memory map for Linux*/
 #define CONFIG_SYS_BOOTMAPSZ   (256 << 20)
+#define CONFIG_SYS_BOOTM_LEN   (64 << 20)      /* Increase max gunzip size */
 
 #define CONFIG_SYS_HRCW_LOW (\
        HRCWL_LCL_BUS_TO_SCB_CLK_1X1 |\
index 921d5f399d25eb93440c347ea9f6d38c1dc9fed0..b2dc1890c743a348ca889dac165ce23c79c5b285 100644 (file)
 #endif
 
 /* CONFIG_SYS_MONITOR_LEN must be a multiple of CONFIG_ENV_SECT_SIZE */
-#define CONFIG_SYS_MONITOR_LEN (384 * 1024) /* Reserve 384 kB for Mon */
+#define CONFIG_SYS_MONITOR_LEN (512 * 1024) /* Reserve 512 kB for Mon */
 #define CONFIG_SYS_MALLOC_LEN  (512 * 1024) /* Reserved for malloc */
 
 /*
@@ -522,6 +522,7 @@ extern int board_pci_host_broken(void);
  * the maximum mapped by the Linux kernel during initialization.
  */
 #define CONFIG_SYS_BOOTMAPSZ   (256 << 20) /* Initial Memory map for Linux */
+#define CONFIG_SYS_BOOTM_LEN   (64 << 20)      /* Increase max gunzip size */
 
 /*
  * Core HID Setup
index bb06e89b4ea00e9d13acbe5967c43a492b097f6a..8eb87ebde502d46071cc2c247fc33fde3a9b9103 100644 (file)
 #undef CONFIG_SYS_RAMBOOT
 #endif
 
-#define CONFIG_SYS_MONITOR_LEN (384 * 1024) /* Reserve 384 kB for Mon */
+#define CONFIG_SYS_MONITOR_LEN (512 * 1024) /* Reserve 512 kB for Mon */
 #define CONFIG_SYS_MALLOC_LEN  (512 * 1024) /* Reserved for malloc */
 
 /*
  * the maximum mapped by the Linux kernel during initialization.
  */
 #define CONFIG_SYS_BOOTMAPSZ   (256 << 20) /* Initial Memory map for Linux */
+#define CONFIG_SYS_BOOTM_LEN   (64 << 20)      /* Increase max gunzip size */
 
 /*
  * Core HID Setup
index 7c19ff84bccaab3fe1b237a08396841e5380cc67..874261a146d66768caa413d2efd1eab956bf91c7 100644 (file)
 "consoledev=ttyS0\0"                           \
 "ramdiskaddr=2000000\0"                        \
 "ramdiskfile=8536ds/ramdisk.uboot\0"           \
-"fdtaddr=c00000\0"                             \
+"fdtaddr=1e00000\0"                            \
 "fdtfile=8536ds/mpc8536ds.dtb\0"               \
 "bdev=sda3\0"                                  \
 "hwconfig=usb1:dr_mode=host,phy_type=ulpi\0"
index b9d97c10069d50097022d37cac0cfabed943c344..cd1043204f10e03167b03450d4b8ca347c7d7089 100644 (file)
@@ -209,7 +209,7 @@ extern unsigned long get_board_sys_clk(unsigned long dummy);
 #define CONFIG_SYS_I2C_FSL
 #define CONFIG_SYS_FSL_I2C_SPEED       400000
 #define CONFIG_SYS_FSL_I2C_SLAVE       0x7F
-#define CONFIG_SYS_FSL_I2C_OFFSET      0x3000
+#define CONFIG_SYS_FSL_I2C_OFFSET      0x3100
 #define CONFIG_SYS_I2C_NOPROBES                { {0, 0x69} }
 #define CONFIG_SYS_I2C_EEPROM_ADDR     0x57
 
@@ -462,7 +462,7 @@ extern unsigned long get_board_sys_clk(unsigned long dummy);
 "consoledev=ttyS0\0"                           \
 "ramdiskaddr=2000000\0"                        \
 "ramdiskfile=8544ds/ramdisk.uboot\0"           \
-"fdtaddr=c00000\0"                             \
+"fdtaddr=1e00000\0"                            \
 "fdtfile=8544ds/mpc8544ds.dtb\0"               \
 "bdev=sda3\0"
 
index e73be48d5189402127be4e2b618d1963a0db4657..b81a4eddd784c53da3c2ca894390992ce38b77e7 100644 (file)
@@ -562,7 +562,7 @@ extern unsigned long get_clock_freq(void);
        "consoledev=ttyS1\0"                    \
        "ramdiskaddr=2000000\0"                 \
        "ramdiskfile=ramdisk.uboot\0"           \
-       "fdtaddr=c00000\0"                      \
+       "fdtaddr=1e00000\0"                     \
        "fdtfile=mpc8548cds.dtb\0"
 
 #define CONFIG_NFSBOOTCOMMAND                                          \
index 2e6989f81602403f53e5137f2dfa1270a1d2dacf..390b1ef61b0c40b533ee910fe631a91a44bf2cc9 100644 (file)
 "consoledev=ttyS0\0"                           \
 "ramdiskaddr=2000000\0"                        \
 "ramdiskfile=8572ds/ramdisk.uboot\0"           \
-"fdtaddr=c00000\0"                             \
+"fdtaddr=1e00000\0"                            \
 "fdtfile=8572ds/mpc8572ds.dtb\0"               \
 "bdev=sda3\0"
 
index 5384584c184749e975165240db5d2a9b194bdea0..5b6b4bd5d8098519c245885aa4fadaf0d611f0db 100644 (file)
@@ -862,7 +862,7 @@ extern unsigned long get_sdram_size(void);
        "consoledev=ttyS0\0"                            \
        "ramdiskaddr=2000000\0"                 \
        "ramdiskfile=rootfs.ext2.gz.uboot\0"            \
-       "fdtaddr=c00000\0"                              \
+       "fdtaddr=1e00000\0"                             \
        "fdtfile=p1010rdb.dtb\0"                \
        "bdev=sda1\0"   \
        "hwconfig=usb1:dr_mode=host,phy_type=utmi\0"    \
index bdf0323bfc764959be60a8c7518f077d9c520b34..fe19957c39ee882b63186ece62a7d82a59c95e0a 100644 (file)
        "consoledev=ttyS0\0"                                    \
        "ramdiskaddr=2000000\0"                                 \
        "ramdiskfile=rootfs.ext2.gz.uboot\0"                    \
-       "fdtaddr=c00000\0"                                      \
+       "fdtaddr=1e00000\0"                                     \
        "fdtfile=p1022ds.dtb\0"                                 \
        "bdev=sda3\0"                                           \
        "hwconfig=esdhc;audclk:12\0"
index 07a594d15dbe3b66deea228fc9cc8acf4d6cc7b9..d044c7bc2eeb9f345565dff9a6fa3358376c8ba7 100644 (file)
@@ -375,7 +375,7 @@ extern unsigned long get_clock_freq(void);
        "consoledev=ttyS0\0"                                    \
        "ramdiskaddr=2000000\0"                                 \
        "ramdiskfile=rootfs.ext2.gz.uboot\0"                    \
-       "fdtaddr=c00000\0"                                      \
+       "fdtaddr=1e00000\0"                                     \
        "fdtfile=p1023rdb.dtb\0"                                \
        "othbootargs=ramdisk_size=600000\0"                     \
        "bdev=sda1\0"                                           \
index 24e54318452d5426ec9a1cc01492e0ef32edb2aa..8479410ee749eda77809ce0ce45f274efd061680 100644 (file)
@@ -698,7 +698,7 @@ unsigned long get_board_sys_clk(unsigned long dummy);
        "usb_dr_mode=host\0"                                    \
        "ramdiskaddr=2000000\0"                                 \
        "ramdiskfile=p2041rdb/ramdisk.uboot\0"                  \
-       "fdtaddr=c00000\0"                                      \
+       "fdtaddr=1e00000\0"                                     \
        "fdtfile=p2041rdb/p2041rdb.dtb\0"                       \
        "bdev=sda3\0"
 
index 06d1d0fc497148112347e585f7ee32a0f8c23096..25a0652b5b05bd9421b1feeec1de3c62db753c14 100644 (file)
@@ -897,7 +897,7 @@ unsigned long get_board_ddr_clk(void);
        "cmp.b $loadaddr $ubootaddr $filesize\0"                \
        "consoledev=ttyS0\0"                                    \
        "ramdiskaddr=2000000\0"                                 \
-       "fdtaddr=c00000\0"                                      \
+       "fdtaddr=1e00000\0"                                     \
        "bdev=sda3\0"
 
 #define CONFIG_LINUX                                   \
index 9f5063c33378438b607ff6be1349e2178beaf1d7..7ce6420d4863ad134af61b14d3a5c636d002bbf6 100644 (file)
@@ -770,7 +770,7 @@ unsigned long get_board_ddr_clk(void);
        "consoledev=ttyS0\0"                                    \
        "ramdiskaddr=2000000\0"                                 \
        "ramdiskfile=t1040qds/ramdisk.uboot\0"                  \
-       "fdtaddr=c00000\0"                                      \
+       "fdtaddr=1e00000\0"                                     \
        "fdtfile=t1040qds/t1040qds.dtb\0"                       \
        "bdev=sda3\0"
 
index a8f4f742e621c3914bcd6c877c07d131b8dafd3c..ae1acbdd0415ff236e7c11555822f924906be53d 100644 (file)
 #include <asm/config_mpc85xx.h>
 
 #ifdef CONFIG_RAMBOOT_PBL
+
+#ifndef CONFIG_SECURE_BOOT
 #define CONFIG_SYS_FSL_PBL_PBI $(SRCTREE)/board/freescale/t104xrdb/t104x_pbi.cfg
+#else
+#define CONFIG_SYS_FSL_PBL_PBI \
+               $(SRCTREE)/board/freescale/t104xrdb/t104x_pbi_sb.cfg
+#endif
+
 #ifdef CONFIG_T1040RDB
 #define CONFIG_SYS_FSL_PBL_RCW $(SRCTREE)/board/freescale/t104xrdb/t1040_rcw.cfg
 #endif
@@ -62,7 +69,17 @@ $(SRCTREE)/board/freescale/t104xrdb/t1042d4_rcw.cfg
 
 #ifdef CONFIG_NAND
 #define CONFIG_SPL_NAND_SUPPORT
+#ifdef CONFIG_SECURE_BOOT
+#define CONFIG_U_BOOT_HDR_SIZE         (16 << 10)
+/*
+ * HDR would be appended at end of image and copied to DDR along
+ * with U-Boot image.
+ */
+#define CONFIG_SYS_NAND_U_BOOT_SIZE    ((768 << 10) + \
+                                        CONFIG_U_BOOT_HDR_SIZE)
+#else
 #define CONFIG_SYS_NAND_U_BOOT_SIZE    (768 << 10)
+#endif
 #define CONFIG_SYS_NAND_U_BOOT_DST     0x30000000
 #define CONFIG_SYS_NAND_U_BOOT_START   0x30000000
 #define CONFIG_SYS_NAND_U_BOOT_OFFS    (256 << 10)
@@ -161,6 +178,10 @@ $(SRCTREE)/board/freescale/t104xrdb/t1042d4_rcw.cfg
 #define CONFIG_ENV_SIZE                        0x2000
 #define CONFIG_ENV_OFFSET              (512 * 0x800)
 #elif defined(CONFIG_NAND)
+#ifdef CONFIG_SECURE_BOOT
+#define CONFIG_RAMBOOT_NAND
+#define CONFIG_BOOTSCRIPT_COPY_RAM
+#endif
 #define CONFIG_SYS_EXTRA_ENV_RELOC
 #define CONFIG_ENV_IS_IN_NAND
 #define CONFIG_ENV_SIZE                        0x2000
@@ -202,8 +223,14 @@ $(SRCTREE)/board/freescale/t104xrdb/t1042d4_rcw.cfg
  *  Config the L3 Cache as L3 SRAM
  */
 #define CONFIG_SYS_INIT_L3_ADDR                0xFFFC0000
+/*
+ * For Secure Boot CONFIG_SYS_INIT_L3_ADDR will be redefined and hence
+ * Physical address (CONFIG_SYS_INIT_L3_ADDR) and virtual address
+ * (CONFIG_SYS_INIT_L3_VADDR) will be different.
+ */
+#define CONFIG_SYS_INIT_L3_VADDR       0xFFFC0000
 #define CONFIG_SYS_L3_SIZE             256 << 10
-#define CONFIG_SPL_GD_ADDR             (CONFIG_SYS_INIT_L3_ADDR + 32 * 1024)
+#define CONFIG_SPL_GD_ADDR             (CONFIG_SYS_INIT_L3_VADDR + 32 * 1024)
 #ifdef CONFIG_RAMBOOT_PBL
 #define CONFIG_ENV_ADDR                        (CONFIG_SPL_GD_ADDR + 4 * 1024)
 #endif
@@ -873,7 +900,7 @@ $(SRCTREE)/board/freescale/t104xrdb/t1042d4_rcw.cfg
        "consoledev=ttyS0\0"                                    \
        "ramdiskaddr=2000000\0"                                 \
        "ramdiskfile=" __stringify(RAMDISKFILE) "\0"            \
-       "fdtaddr=c00000\0"                                      \
+       "fdtaddr=1e00000\0"                                     \
        "fdtfile=" __stringify(FDTFILE) "\0"                    \
        "bdev=sda3\0"
 
index 1f07a83a1a742800b9c2882142b67dd4a0355fb8..621755526a0271a7596be36a1c579b6a4625c8b9 100644 (file)
@@ -840,7 +840,7 @@ unsigned long get_board_ddr_clk(void);
        "consoledev=ttyS0\0"                                    \
        "ramdiskaddr=2000000\0"                                 \
        "ramdiskfile=t2080qds/ramdisk.uboot\0"                  \
-       "fdtaddr=c00000\0"                                      \
+       "fdtaddr=1e00000\0"                                     \
        "fdtfile=t2080qds/t2080qds.dtb\0"                       \
        "bdev=sda3\0"
 
index 0ded41e0dd5229810d6dc6de755c8d08972fdcb5..7a7de9703fc24c97d6f9c358f3e37ae872ec6e46 100644 (file)
@@ -792,7 +792,7 @@ unsigned long get_board_ddr_clk(void);
        "consoledev=ttyS0\0"                                    \
        "ramdiskaddr=2000000\0"                                 \
        "ramdiskfile=t2080rdb/ramdisk.uboot\0"                  \
-       "fdtaddr=c00000\0"                                      \
+       "fdtaddr=1e00000\0"                                     \
        "fdtfile=t2080rdb/t2080rdb.dtb\0"                       \
        "bdev=sda3\0"
 
index f075dfb5f05859f21c223dbc3f217930134f6a08..85aab183ff009d51659627e1c61a5099d509acfe 100644 (file)
@@ -577,7 +577,7 @@ unsigned long get_board_ddr_clk(void);
        "consoledev=ttyS0\0"                                    \
        "ramdiskaddr=2000000\0"                                 \
        "ramdiskfile=t4240qds/ramdisk.uboot\0"                  \
-       "fdtaddr=c00000\0"                                      \
+       "fdtaddr=1e00000\0"                                     \
        "fdtfile=t4240qds/t4240qds.dtb\0"                               \
        "bdev=sda3\0"
 
index 9ba69a1d1237c1b92470bc77d291e3cdb4a70fdc..4133165ea8225f97118aa51d78b0c83da9ac0e2b 100644 (file)
@@ -770,7 +770,7 @@ unsigned long get_board_ddr_clk(void);
        "consoledev=ttyS0\0"                                    \
        "ramdiskaddr=2000000\0"                                 \
        "ramdiskfile=t4240rdb/ramdisk.uboot\0"                  \
-       "fdtaddr=c00000\0"                                      \
+       "fdtaddr=1e00000\0"                                     \
        "fdtfile=t4240rdb/t4240rdb.dtb\0"                       \
        "bdev=sda3\0"
 
index b08f341227543efd4acb5dca78282fd9c8b1661b..18e59fc73a748c1d5ef9249abb73bf83d21d33d8 100644 (file)
@@ -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
index d5888e8a2f633eaad64cd1cfa050d5a8a9a04c27..50cd7430b59b915d14a4d4a09eda553b2b44c8a0 100644 (file)
@@ -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 */
index 30c283185bcba7be66e7f4c841d69bc2d2aedbc7..44e115da6d9c915935c82899a11567fac12b6f5f 100644 (file)
        "consoledev=ttyS1\0"                                    \
        "ramdiskaddr=2000000\0"                                 \
        "ramdiskfile=rootfs.ext2.gz.uboot\0"                    \
-       "fdtaddr=c00000\0"                                      \
+       "fdtaddr=1e00000\0"                                     \
        "fdtfile=controlcenterd.dtb\0"                          \
        "bdev=sda3\0"
 
index 4a770b05460a14c8a84cb924ea6731bef79fb75a..0c99e9f5e6d4d3d2ee80188a6eb41e838dd101b6 100644 (file)
        "consoledev=ttyS0\0"                                    \
        "ramdiskaddr=2000000\0"                                 \
        "ramdiskfile=p4080ds/ramdisk.uboot\0"                   \
-       "fdtaddr=c00000\0"                                      \
+       "fdtaddr=1e00000\0"                                     \
        "fdtfile=p4080ds/p4080ds.dtb\0"                         \
        "bdev=sda3\0"
 
index 708d5f730ddc867361d8d59b1809d2c3bf7d9e08..da38709fbf5ea63c64d84bad1361f86e1e431834 100644 (file)
 "ubootaddr=" __stringify(CONFIG_SYS_TEXT_BASE) "\0"                    \
 "consoledev=ttyS0\0"                                   \
 "ramdiskaddr=2000000\0"                                        \
-"fdtaddr=c00000\0"                                     \
+"fdtaddr=1e00000\0"                                    \
 "bdev=sda3\0"
 
 #define CONFIG_HDBOOT                                  \
index 4b009223b2f5567c065ac7fdc761d520045fdf7f..1dbe2194f86c55ef52ae9f5f8a754a712fda7c08 100644 (file)
@@ -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/evb-rk3288.h b/include/configs/evb-rk3288.h
new file mode 100644 (file)
index 0000000..342557f
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * (C) Copyright 2016 Rockchip Electronics Co., Ltd
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#define ROCKCHIP_DEVICE_SETTINGS
+#include <configs/rk3288_common.h>
+
+#define CONFIG_SPL_MMC_SUPPORT
+
+#define CONFIG_ENV_IS_IN_MMC
+#define CONFIG_SYS_MMC_ENV_DEV 1
+/* SPL @ 32k for ~36k
+ * ENV @ 96k
+ * u-boot @ 128K
+ */
+#define CONFIG_ENV_OFFSET (96 * 1024)
+
+#define CONFIG_SYS_WHITE_ON_BLACK
+#define CONFIG_CONSOLE_SCROLL_LINES            10
+
+#endif
diff --git a/include/configs/evb_rk3399.h b/include/configs/evb_rk3399.h
new file mode 100644 (file)
index 0000000..047850a
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * (C) Copyright 2016 Rockchip Electronics Co., Ltd
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#ifndef __EVB_RK3399_H
+#define __EVB_RK3399_H
+
+#include <configs/rk3399_common.h>
+
+#define CONFIG_ENV_IS_IN_MMC
+#define CONFIG_SYS_MMC_ENV_DEV 0
+/*
+ * SPL @ 32k for ~36k
+ * ENV @ 96k
+ * u-boot @ 128K
+ */
+#define CONFIG_ENV_OFFSET (96 * 1024)
+
+#define SDRAM_BANK_SIZE                        (2UL << 30)
+
+#define CONFIG_SYS_WHITE_ON_BLACK
+#define CONFIG_CONSOLE_SCROLL_LINES            10
+
+#endif
index 953c0880501d8bc21e5ce5a195529b9f5bbb1bf5..2b172a50730a49f1a330dd67eaa4c5cd4862ab42 100644 (file)
@@ -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
index f8bba6710dba82b3b173c96c8eb5671891a10695..71b00378ffb6f15edc03466384521a0b0a696b9a 100644 (file)
 #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 */
index db684d25582cc9790c6ae2fabb6ed3bbddd2fee9..47180f9ce8b9d6cf13e4612099ab1726a2d1d063 100644 (file)
 #define CONFIG_LS102XA
 
 #define CONFIG_ARMV7_PSCI
+#define CONFIG_ARMV7_PSCI_1_0
+#define CONFIG_ARMV7_PSCI_NR_CPUS      CONFIG_MAX_CPUS
+
+#define CONFIG_ARMV7_SECURE_BASE       OCRAM_BASE_S_ADDR
 
 #define CONFIG_SYS_FSL_CLK
 
@@ -279,6 +283,8 @@ unsigned long get_board_ddr_clk(void);
 #define QIXIS_LBMAP_SHIFT              0
 #define QIXIS_LBMAP_DFLTBANK           0x00
 #define QIXIS_LBMAP_ALTBANK            0x04
+#define QIXIS_PWR_CTL                  0x21
+#define QIXIS_PWR_CTL_POWEROFF         0x80
 #define QIXIS_RST_CTL_RESET            0x44
 #define QIXIS_RCFG_CTL_RECONFIG_IDLE   0x20
 #define QIXIS_RCFG_CTL_RECONFIG_START  0x21
index 0fb28eff557434265edcaa1f756a60cb7998713a..2f19950dffe0b04bb9263f8b217454f6c1d48c8b 100644 (file)
 #define CONFIG_LS102XA
 
 #define CONFIG_ARMV7_PSCI
+#define CONFIG_ARMV7_PSCI_1_0
+#define CONFIG_ARMV7_PSCI_NR_CPUS      CONFIG_MAX_CPUS
+
+#define CONFIG_ARMV7_SECURE_BASE       OCRAM_BASE_S_ADDR
 
 #define CONFIG_SYS_FSL_CLK
 
 #define CONFIG_SPL_SERIAL_SUPPORT
 #define CONFIG_SPL_MMC_SUPPORT
 #define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR                0xe8
+
+#ifdef CONFIG_SECURE_BOOT
+#define CONFIG_U_BOOT_HDR_SIZE                         (16 << 10)
+/*
+ * HDR would be appended at end of image and copied to DDR along
+ * with U-Boot image.
+ */
+#define CONFIG_SYS_U_BOOT_MAX_SIZE_SECTORS             (0x400 + \
+               (CONFIG_U_BOOT_HDR_SIZE / 512)
+#else
 #define CONFIG_SYS_U_BOOT_MAX_SIZE_SECTORS             0x400
+#endif /* ifdef CONFIG_SECURE_BOOT */
 
 #define CONFIG_SPL_TEXT_BASE           0x10000000
 #define CONFIG_SPL_MAX_SIZE            0x1a000
 #define CONFIG_SYS_SPL_MALLOC_SIZE     0x100000
 #define CONFIG_SPL_BSS_START_ADDR      0x80100000
 #define CONFIG_SPL_BSS_MAX_SIZE                0x80000
+
+#ifdef CONFIG_U_BOOT_HDR_SIZE
+/*
+ * HDR would be appended at end of image and copied to DDR along
+ * with U-Boot image. Here u-boot max. size is 512K. So if binary
+ * size increases then increase this size in case of secure boot as
+ * it uses raw u-boot image instead of fit image.
+ */
+#define CONFIG_SYS_MONITOR_LEN         (0x80000 + CONFIG_U_BOOT_HDR_SIZE)
+#else
 #define CONFIG_SYS_MONITOR_LEN         0x80000
+#endif /* ifdef CONFIG_U_BOOT_HDR_SIZE */
 #endif
 
 #ifdef CONFIG_QSPI_BOOT
index b0d4a8d10acf6e4e234a488b4d66adb50883ae63..0ad5261c56711287a98bcc7f72efeaeebd4b819e 100644 (file)
 #define CONFIG_HWCONFIG
 #define HWCONFIG_BUFFER_SIZE           128
 
+#if defined(CONFIG_QSPI_BOOT) || defined(CONFIG_SD_BOOT_QSPI)
+#define MTDPARTS_DEFAULT "mtdparts=spi0.0:1m(uboot)," \
+                       "5m(kernel),1m(dtb),9m(file_system)"
+#else
+#define MTDPARTS_DEFAULT "mtdparts=60000000.nor:1m(nor_bank0_rcw)," \
+                       "1m(nor_bank0_uboot),1m(nor_bank0_uboot_env)," \
+                       "1m(nor_bank0_fman_uconde),40m(nor_bank0_fit)," \
+                       "1m(nor_bank4_rcw),1m(nor_bank4_uboot)," \
+                       "1m(nor_bank4_uboot_env),1m(nor_bank4_fman_ucode)," \
+                       "40m(nor_bank4_fit);7e800000.flash:" \
+                       "1m(nand_uboot),1m(nand_uboot_env)," \
+                       "20m(nand_fit);spi0.0:1m(uboot)," \
+                       "5m(kernel),1m(dtb),9m(file_system)"
+#endif
+
 /* Initial environment variables */
 #define CONFIG_EXTRA_ENV_SETTINGS              \
        "hwconfig=fsl_ddr:bank_intlv=auto\0"    \
        "loadaddr=0x80100000\0"                 \
-       "kernel_addr=0x100000\0"                \
-       "ramdisk_addr=0x800000\0"               \
-       "ramdisk_size=0x2000000\0"              \
        "fdt_high=0xffffffffffffffff\0"         \
        "initrd_high=0xffffffffffffffff\0"      \
        "kernel_start=0x61100000\0"             \
        "kernel_load=0xa0000000\0"              \
        "kernel_size=0x2800000\0"               \
-       "console=ttyAMA0,38400n8\0"
+       "console=ttyS0,115200\0"                \
+       "mtdparts=" MTDPARTS_DEFAULT "\0"
 
 #define CONFIG_BOOTARGS                        "console=ttyS0,115200 root=/dev/ram0 " \
-                                       "earlycon=uart8250,mmio,0x21c0500"
+                                       "earlycon=uart8250,mmio,0x21c0500 "    \
+                                       MTDPARTS_DEFAULT
+
 #if defined(CONFIG_QSPI_BOOT) || defined(CONFIG_SD_BOOT_QSPI)
 #define CONFIG_BOOTCOMMAND             "sf probe && sf read $kernel_load "    \
                                        "e0000 f00000 && bootm $kernel_load"
index 94ddfb1797650da0c966b643a2a35877735fa003..44f86fabd5e46dbbce4cf88645c3166e44b26f82 100644 (file)
@@ -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
 
index 93fb166665ee94a1cea9e13adec3c8367e964104..047e756e71d95894dfa11e2300a3a8c2655e3b02 100644 (file)
 #define CONFIG_CMD_IRQ
 #define CONFIG_CMD_MFSL
 
-#if defined(CONFIG_DCACHE) || defined(CONFIG_ICACHE)
-#else
-#endif
-
 #if defined(FLASH)
 # define CONFIG_CMD_JFFS2
 # define CONFIG_CMD_UBI
index 0882d5d8f2d5f84a47cb6183d13d7a808125cd20..238b16d17f1785c28c86723ed63fcd4b456397ac 100644 (file)
 #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
index 9bd891586cd86e6b8596535fea995c5a03fae6db..e0d25937f73586eb0b3a77179f593a218890f8aa 100644 (file)
 #ifndef __IGEP00X0_H
 #define __IGEP00X0_H
 
-#ifdef CONFIG_BOOT_NAND
-#define CONFIG_NAND
-#endif
-
 #define CONFIG_NR_DRAM_BANKS            2
+#define CONFIG_NAND
 
 #include <configs/ti_omap3_common.h>
 #include <asm/mach-types.h>
@@ -76,9 +73,9 @@
 #define CONFIG_USBD_MANUFACTURER       "Texas Instruments"
 #define CONFIG_USBD_PRODUCT_NAME       "IGEP"
 
-#ifdef CONFIG_BOOT_ONENAND
-#define CONFIG_CMD_ONENAND     /* ONENAND support              */
-#endif
+#define CONFIG_CMD_MTDPARTS
+#define CONFIG_CMD_ONENAND
+#define CONFIG_CMD_UBI
 
 #ifndef CONFIG_SPL_BUILD
 
 
 #endif
 
-/*
- * FLASH and environment organization
- */
-
-#ifdef CONFIG_BOOT_ONENAND
-#define CONFIG_SYS_ONENAND_BASE                ONENAND_MAP
-
-#define ONENAND_ENV_OFFSET             0x260000 /* environment starts here */
-
-#define CONFIG_ENV_IS_IN_ONENAND       1
-#define CONFIG_ENV_SIZE                        (512 << 10) /* Total Size Environment */
-#define CONFIG_ENV_ADDR                        ONENAND_ENV_OFFSET
-#endif
-
-#ifdef CONFIG_NAND
-#define CONFIG_ENV_OFFSET              0x260000 /* environment starts here */
-#define CONFIG_ENV_IS_IN_NAND          1
-#define CONFIG_ENV_SIZE                        (512 << 10) /* Total Size Environment */
-#define CONFIG_ENV_ADDR                        NAND_ENV_OFFSET
-#endif
-
 /*
  * SMSC911x Ethernet
  */
 #define CONFIG_SMC911X_BASE            0x2C000000
 #endif /* (CONFIG_CMD_NET) */
 
-/* OneNAND boot config */
-#ifdef CONFIG_BOOT_ONENAND
-#define CONFIG_SPL_ONENAND_SUPPORT
-#define CONFIG_SYS_ONENAND_U_BOOT_OFFS  0x80000
-#define CONFIG_SYS_ONENAND_PAGE_SIZE   2048
-#define CONFIG_SPL_ONENAND_LOAD_ADDR    0x80000
-#define CONFIG_SPL_ONENAND_LOAD_SIZE    \
-       (512 * 1024 - CONFIG_SPL_ONENAND_LOAD_ADDR)
+#define CONFIG_RBTREE
+#define CONFIG_MTD_PARTITIONS
+#define CONFIG_SYS_MTDPARTS_RUNTIME
 
-#endif
+/* OneNAND config */
+#define CONFIG_SPL_ONENAND_SUPPORT
+#define CONFIG_USE_ONENAND_BOARD_INIT
+#define CONFIG_SYS_ONENAND_BASE                ONENAND_MAP
+#define CONFIG_SYS_ONENAND_BLOCK_SIZE  (128*1024)
 
-/* NAND boot config */
-#ifdef CONFIG_NAND
+/* NAND config */
+#define CONFIG_SPL_NAND_SUPPORT
+#define CONFIG_SPL_OMAP3_ID_NAND
 #define CONFIG_SYS_NAND_BUSWIDTH_16BIT
 #define CONFIG_SYS_NAND_5_ADDR_CYCLE
 #define CONFIG_SYS_NAND_PAGE_COUNT     64
 #define CONFIG_NAND_OMAP_GPMC
 #define CONFIG_BCH
 
-#define CONFIG_SYS_NAND_U_BOOT_OFFS    0x80000
-/* NAND: SPL falcon mode configs */
-#ifdef CONFIG_SPL_OS_BOOT
-#define CONFIG_CMD_SPL_NAND_OFS                0x240000
-#define CONFIG_SYS_NAND_SPL_KERNEL_OFFS        0x280000
-#define CONFIG_CMD_SPL_WRITE_SIZE      0x2000
-#endif
-#endif
+/* UBI configuration */
+#define CONFIG_SPL_UBI                 1
+#define CONFIG_SPL_UBI_MAX_VOL_LEBS    256
+#define CONFIG_SPL_UBI_MAX_PEB_SIZE    (256*1024)
+#define CONFIG_SPL_UBI_MAX_PEBS                4096
+#define CONFIG_SPL_UBI_VOL_IDS         8
+#define CONFIG_SPL_UBI_LOAD_MONITOR_ID 0
+#define CONFIG_SPL_UBI_LOAD_KERNEL_ID  3
+#define CONFIG_SPL_UBI_LOAD_ARGS_ID    4
+#define CONFIG_SPL_UBI_PEB_OFFSET      4
+#define CONFIG_SPL_UBI_VID_OFFSET      512
+#define CONFIG_SPL_UBI_LEB_START       2048
+#define CONFIG_SPL_UBI_INFO_ADDR       0x88080000
+
+/* environment organization */
+#define CONFIG_ENV_IS_IN_UBI           1
+#define CONFIG_ENV_UBI_PART            "UBI"
+#define CONFIG_ENV_UBI_VOLUME          "config"
+#define CONFIG_ENV_UBI_VOLUME_REDUND   "config_r"
+#define CONFIG_UBI_SILENCE_MSG         1
+#define CONFIG_UBIFS_SILENCE_MSG       1
+#define CONFIG_ENV_SIZE                        (32*1024)
+
+#undef CONFIG_SPL_EXT_SUPPORT
 
 #endif /* __IGEP00X0_H */
index 4f22d12a3f2bbb3c676e41d9390ff97d3f2dfe9b..3d3342141dda072e8eed5f5e9fa1a30b077cc72c 100644 (file)
@@ -989,7 +989,7 @@ i2c mw 18 3 __SW_BOOT_MASK 1; reset
 "consoledev=ttyS0\0"   \
 "ramdiskaddr=2000000\0"        \
 "ramdiskfile=rootfs.ext2.gz.uboot\0"   \
-"fdtaddr=c00000\0"     \
+"fdtaddr=1e00000\0"    \
 "bdev=sda1\0" \
 "jffs2nor=mtdblock3\0" \
 "norbootaddr=ef080000\0"       \
index 30bfbf44f5c3354632e3d8680cd8cc0427ce5fea..79e4991563af68861330c32e33ee98e2873205c2 100644 (file)
@@ -513,7 +513,7 @@ extern unsigned long get_board_sys_clk(unsigned long dummy);
 "consoledev=ttyS0\0"   \
 "ramdiskaddr=2000000\0"        \
 "ramdiskfile=rootfs.ext2.gz.uboot\0"   \
-"fdtaddr=c00000\0"     \
+"fdtaddr=1e00000\0"    \
 "bdev=sda1\0"  \
 "norbootaddr=ef080000\0"       \
 "norfdtaddr=ef040000\0"        \
index 1bdcf9d0248a9afb5b0eaf3cfa689a31e1c35ddf..ae4b101e444df558a26b7301ab9d202752e9f292 100644 (file)
@@ -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
 
index 9d50d834db493340da8fff90941ab153a161c9e3..2a36c1706bd447443190b48bfb82e66236f7990b 100644 (file)
 #define CONFIG_SYS_NS16550_MEM32
 #define CONFIG_SPL_BOARD_INIT
 
+#ifdef CONFIG_ROCKCHIP_SPL_BACK_TO_BROM
+/* Bootrom will load u-boot binary to 0x0 once return from SPL */
+#define CONFIG_SYS_TEXT_BASE           0x00000000
+#else
 #define CONFIG_SYS_TEXT_BASE           0x00100000
+#endif
 #define CONFIG_SYS_INIT_SP_ADDR                0x00100000
 #define CONFIG_SYS_LOAD_ADDR           0x00800800
 #define CONFIG_SPL_STACK               0xff718000
@@ -51,7 +56,6 @@
 /* MMC/SD IP block */
 #define CONFIG_MMC
 #define CONFIG_GENERIC_MMC
-#define CONFIG_SDHCI
 #define CONFIG_DWMMC
 #define CONFIG_BOUNCE_BUFFER
 
 #define CONFIG_SPI
 #define CONFIG_SF_DEFAULT_SPEED 20000000
 
+/* usb otg */
+#define CONFIG_USB_GADGET
+#define CONFIG_USB_GADGET_DUALSPEED
+#define CONFIG_USB_GADGET_DWC2_OTG
+#define CONFIG_ROCKCHIP_USB2_PHY
+#define CONFIG_USB_GADGET_VBUS_DRAW    0
+
+/* fastboot  */
+#define CONFIG_CMD_FASTBOOT
+#define CONFIG_USB_FUNCTION_FASTBOOT
+#define CONFIG_FASTBOOT_FLASH
+#define CONFIG_FASTBOOT_FLASH_MMC_DEV  1       /* eMMC */
+/* stroe safely fastboot buffer data to the middle of bank */
+#define CONFIG_FASTBOOT_BUF_ADDR       (CONFIG_SYS_SDRAM_BASE \
+                                       + SDRAM_BANK_SIZE / 2)
+#define CONFIG_FASTBOOT_BUF_SIZE       0x08000000
+
+#define CONFIG_USB_GADGET_DOWNLOAD
+#define CONFIG_G_DNL_MANUFACTURER      "Rockchip"
+#define CONFIG_G_DNL_VENDOR_NUM                0x2207
+#define CONFIG_G_DNL_PRODUCT_NUM       0x320a
+
+/* Enable gpt partition table */
+#define CONFIG_CMD_GPT
+#define CONFIG_EFI_PARTITION
+
 #ifndef CONFIG_SPL_BUILD
 #include <config_distro_defaults.h>
 
diff --git a/include/configs/rk3399_common.h b/include/configs/rk3399_common.h
new file mode 100644 (file)
index 0000000..6ce1aa7
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * (C) Copyright 2016 Rockchip Electronics Co., Ltd
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#ifndef __CONFIG_RK3399_COMMON_H
+#define __CONFIG_RK3399_COMMON_H
+
+#define CONFIG_SYS_CACHELINE_SIZE      64
+
+#define CONFIG_SYS_NO_FLASH
+#define CONFIG_NR_DRAM_BANKS           1
+#define CONFIG_ENV_SIZE                        0x2000
+#define CONFIG_SYS_MAXARGS             16
+#define CONFIG_BAUDRATE                        1500000
+#define CONFIG_SYS_MALLOC_LEN          (32 << 20)
+#define CONFIG_SYS_CBSIZE              1024
+#define CONFIG_SKIP_LOWLEVEL_INIT
+#define CONFIG_DISPLAY_BOARDINFO
+
+#define CONFIG_SYS_NS16550_MEM32
+
+#define CONFIG_SYS_TEXT_BASE           0x00200000
+#define CONFIG_SYS_INIT_SP_ADDR                0x00300000
+#define CONFIG_SYS_LOAD_ADDR           0x00800800
+
+#define CONFIG_SYS_BOOTM_LEN   (64 << 20)      /* 64M */
+
+/* MMC/SD IP block */
+#define CONFIG_MMC
+#define CONFIG_GENERIC_MMC
+#define CONFIG_SDHCI
+#define CONFIG_BOUNCE_BUFFER
+#define CONFIG_ROCKCHIP_SDHCI_MAX_FREQ 200000000
+
+#define CONFIG_FAT_WRITE
+
+/* RAW SD card / eMMC locations. */
+#define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR        256
+#define CONFIG_SYS_SPI_U_BOOT_OFFS     (128 << 10)
+
+/* FAT sd card locations. */
+#define CONFIG_SYS_MMCSD_FS_BOOT_PARTITION     1
+#define CONFIG_SYS_SDRAM_BASE          0
+#define CONFIG_NR_DRAM_BANKS           1
+
+#define CONFIG_SPI_FLASH
+#define CONFIG_SPI
+#define CONFIG_SF_DEFAULT_SPEED 20000000
+
+#ifndef CONFIG_SPL_BUILD
+#include <config_distro_defaults.h>
+
+#define ENV_MEM_LAYOUT_SETTINGS \
+       "scriptaddr=0x00000000\0" \
+       "pxefile_addr_r=0x00100000\0" \
+       "fdt_addr_r=0x01f00000\0" \
+       "kernel_addr_r=0x02000000\0" \
+       "ramdisk_addr_r=0x04000000\0"
+
+/* First try to boot from SD (index 0), then eMMC (index 1) */
+#define BOOT_TARGET_DEVICES(func) \
+       func(MMC, mmc, 0) \
+       func(MMC, mmc, 1)
+
+#include <config_distro_bootcmd.h>
+#define CONFIG_EXTRA_ENV_SETTINGS \
+       BOOTENV
+
+#endif
+
+#endif
index 23a0c40ca528a8377416d4036f6d46ffdeff29e2..94e024bfb2013ec6536d55da9c44f955b9e44371 100644 (file)
 
 #endif
 
+#ifndef CONFIG_SPL_BUILD
 #define CONFIG_IO_TRACE
 #define CONFIG_CMD_IOTRACE
+#endif
 
 #ifndef CONFIG_TIMER
 #define CONFIG_SYS_TIMER_RATE          1000000
 
 #define CONFIG_SYS_STDIO_DEREGISTER
 
-/* Number of bits in a C 'long' on this architecture */
+/*
+ * Number of bits in a C 'long' on this architecture. Set this to 32 when
+ * building on a 32-bit machine.
+ */
 #define CONFIG_SANDBOX_BITS_PER_LONG   64
 
 #define CONFIG_LMB
@@ -80,7 +85,6 @@
 #define CONFIG_CMD_SF_TEST
 
 #define CONFIG_I2C_EDID
-#define CONFIG_I2C_EEPROM
 
 /* Memory things - we don't really want a memory test */
 #define CONFIG_SYS_LOAD_ADDR           0x00000000
 #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
 #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 (file)
index 0000000..ffc3098
--- /dev/null
@@ -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
index 46766a6779752bbc40beff4c7ad9b974178fc185..ec9ad4556785a8561d45dddc89d267076d2caee3 100644 (file)
 "consoledev=ttyS0\0"                           \
 "ramdiskaddr=2000000\0"                        \
 "ramdiskfile=uRamdisk\0"                       \
-"fdtaddr=c00000\0"                             \
+"fdtaddr=1e00000\0"                            \
 "fdtfile=sbc8548.dtb\0"
 
 #define CONFIG_NFSBOOTCOMMAND                                          \
diff --git a/include/configs/som-db5800-som-6867.h b/include/configs/som-db5800-som-6867.h
new file mode 100644 (file)
index 0000000..a4b343e
--- /dev/null
@@ -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 */
index e544a218dd75b23e551bcddfaebbf2317fdc36d6..4391bff1cc8725cece7b76196a2487cb2949a4a0 100644 (file)
  * 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
index 95ccc35708a7ecba89b9c3a1b2cddd5d8b515d29..0625502f44b49fa4980b59834540a7f2eb623b0d 100644 (file)
@@ -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
index 0dd29029b9b3368af216195c4deec8751d32104a..e9074d5dfbf9817cdb483d6d495c8282619981de 100644 (file)
@@ -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
index 94275a7183ffc35547893dedcc933bb6b8d61c7a..b9aa62b2af684ec0304eb04119a3726fe89fe22e 100644 (file)
 #define CONFIG_SERIAL_TAG
 
 #ifdef CONFIG_NAND_SUNXI
+#define CONFIG_SYS_NAND_MAX_ECCPOS 1664
 #define CONFIG_SPL_NAND_SUPPORT 1
+#define CONFIG_SYS_NAND_ONFI_DETECTION
+#define CONFIG_SYS_MAX_NAND_DEVICE 8
+#endif
+
+#ifdef CONFIG_SPL_SPI_SUNXI
+#define CONFIG_SPL_SPI_FLASH_SUPPORT   1
+#define CONFIG_SYS_SPI_U_BOOT_OFFS     0x8000
 #endif
 
 /* mmc config */
index ba7cf15242f6422011b05ac4045d949269ea033b..9f947eeb87eda98d859b983e649adfc7ab9b33d0 100644 (file)
 /* Timer information. */
 #define CONFIG_SYS_PTV                 2       /* Divisor: 2^(PTV+1) => 8 */
 
+/*
+ * Disable DM_* for SPL build and can be re-enabled after adding
+ * DM support in SPL
+ */
+#ifdef CONFIG_SPL_BUILD
+#undef CONFIG_DM_I2C
+#endif
+
 /* I2C IP block */
 #define CONFIG_I2C
+#ifndef CONFIG_DM_I2C
 #define CONFIG_SYS_I2C
+#else
+/*
+ * Enable CONFIG_DM_I2C_COMPAT temporarily until all the i2c client
+ * devices are adopted to DM
+ */
+#define CONFIG_DM_I2C_COMPAT
+#endif
 
 /* MMC/SD IP block */
 #define CONFIG_MMC
index 2ee26c40367077d67d88d717ea6b232358c48f9a..4aa262e1a8710dec3fb6f9812da431deff5864ab 100644 (file)
 #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
index 4ebaf841ecbc6ffd89c756638bfe5092abcf804d..e485583f21dd50683b67e009ee9fba310a700590 100644 (file)
@@ -9,7 +9,6 @@
 #ifndef __CONFIG_UNIPHIER_COMMON_H__
 #define __CONFIG_UNIPHIER_COMMON_H__
 
-#define CONFIG_I2C_EEPROM
 #define CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS  10
 
 #define CONFIG_SMC911X
                "tftpboot $fdt_addr_r $fdt_file &&" \
                "run boot_common\0" \
        "__nfsboot=tftpboot $kernel_addr_r $bootfile &&" \
-               "tftpboot $fdt_addr_r $fdt_file &&" \
                "tftpboot $fdt_addr_r $fdt_file &&" \
                "setenv ramdisk_addr_r - &&" \
                "run boot_common\0"
index 28c748d074c7e4b930a665f8fbcf020214edec22..5ebdf5b40240076c5c62d76a042ec1d38a0b21bf 100644 (file)
@@ -55,7 +55,7 @@
 #define SDRAM_TAPDELAY         0x10000000
 
 /*
- * PCI - no suport
+ * PCI - no support
  */
 #undef CONFIG_PCI
 
index b509a9cfd4e57308530c8f4d53fc2b40c6366891..9583e8c08187e69d1e0f3d7f023c025c0ab697c3 100644 (file)
@@ -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
index c5bd5da43c5e198697b658d1cb6bf6206d4b9342..44434aab7bf02d5fbfde7b92d13f8f7d78a2f5fc 100644 (file)
@@ -17,6 +17,7 @@
 #define CONFIG_ZYNQ_SDHCI_MIN_FREQ     (CONFIG_ZYNQ_SDHCI_MAX_FREQ << 9)
 #define CONFIG_ZYNQ_EEPROM
 #define CONFIG_AHCI
+#define CONFIG_SATA_CEVA
 #define CONFIG_ZYNQMP_XHCI_LIST {ZYNQMP_USB0_XHCI_BASEADDR, \
                                 ZYNQMP_USB1_XHCI_BASEADDR}
 
index 73c8d5b6fd4d230fcaf160166546d1cd9d9d5add..bc91714cf7bf98e251ecb5b7ddf872e33c78d347 100644 (file)
@@ -304,7 +304,7 @@ extern void out32(unsigned int, unsigned long);
        "osfile=/home/user/board.uImage\0"                              \
        "fdtfile=/home/user/board.dtb\0"                                \
        "ubootfile=/home/user/u-boot.bin\0"                             \
-       "fdtaddr=c00000\0"                                              \
+       "fdtaddr=0x1e00000\0"                                           \
        "osaddr=0x1000000\0"                                            \
        "loadaddr=0x1000000\0"                                          \
        "prog_uboot="CONFIG_PROG_UBOOT"\0"                              \
index 9f3158d056bb36be5c3cf9c24336d1ca01a76068..eaea33babfb9b25997fbca24d1703e79810041e5 100644 (file)
@@ -699,7 +699,7 @@ extern unsigned long get_board_sys_clk(unsigned long dummy);
        "osfile=/home/user/board.uImage\0"                              \
        "fdtfile=/home/user/board.dtb\0"                                \
        "ubootfile=/home/user/u-boot.bin\0"                             \
-       "fdtaddr=c00000\0"                                              \
+       "fdtaddr=0x1e00000\0"                                           \
        "osaddr=0x1000000\0"                                            \
        "loadaddr=0x1000000\0"                                          \
        "prog_uboot1="CONFIG_PROG_UBOOT1"\0"                            \
index a418fc5c9e267071e7622f0aa5a0f23f5e693504..f7cfc9ea865fbab6873d9f15c48bcdfb9fc573dd 100644 (file)
        "osfile=/home/user/board.uImage\0"                              \
        "fdtfile=/home/user/board.dtb\0"                                \
        "ubootfile=/home/user/u-boot.bin\0"                             \
-       "fdtaddr=c00000\0"                                              \
+       "fdtaddr=0x1e00000\0"                                           \
        "osaddr=0x1000000\0"                                            \
        "loadaddr=0x1000000\0"                                          \
        "prog_uboot1="CONFIG_PROG_UBOOT1"\0"                            \
index 36df6682b280492f2708dad07fa8636c197870e3..3306e44a6d0d6f26d0df5c62b65fc043fbdbcb81 100644 (file)
@@ -554,7 +554,7 @@ extern unsigned long get_board_ddr_clk(unsigned long dummy);
        "osfile=/home/user/board.uImage\0"                              \
        "fdtfile=/home/user/board.dtb\0"                                \
        "ubootfile=/home/user/u-boot.bin\0"                             \
-       "fdtaddr=c00000\0"                                              \
+       "fdtaddr=0x1e00000\0"                                           \
        "osaddr=0x1000000\0"                                            \
        "loadaddr=0x1000000\0"                                          \
        "prog_uboot1="CONFIG_PROG_UBOOT1"\0"                            \
index 1794ba10a37bf4f3b59cbf0adf94ac822ddb141c..276dde7d3e32ed3f09ea051e4f03581bb87f9250 100644 (file)
@@ -538,7 +538,7 @@ extern unsigned long get_board_ddr_clk(unsigned long dummy);
        "osfile=/home/user/board.uImage\0"                              \
        "fdtfile=/home/user/board.dtb\0"                                \
        "ubootfile=/home/user/u-boot.bin\0"                             \
-       "fdtaddr=c00000\0"                                              \
+       "fdtaddr=0x1e00000\0"                                           \
        "osaddr=0x1000000\0"                                            \
        "loadaddr=0x1000000\0"                                          \
        "prog_uboot1="CONFIG_PROG_UBOOT1"\0"                            \
index 8dbac8728f050dda7e9329e5a0ca753705c80e19..e59e412d58a62ba3c39b97662659da839408ea14 100644 (file)
 # define CONFIG_ZYNQ_SDHCI_MAX_FREQ    52000000
 #endif
 
-#ifdef CONFIG_ZYNQ_USB
-# define CONFIG_USB_EHCI
-# define CONFIG_USB_STORAGE
-# define CONFIG_USB_EHCI_ZYNQ
+#ifdef CONFIG_USB_EHCI_ZYNQ
 # define CONFIG_EHCI_IS_TDI
 # define CONFIG_USB_MAX_CONTROLLER_COUNT       2
 
diff --git a/include/configs/zynq_microzed.h b/include/configs/zynq_microzed.h
deleted file mode 100644 (file)
index ec7bb1c..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * (C) Copyright 2013 Xilinx, Inc.
- *
- * Configuration for Micro Zynq Evaluation and Development Board - MicroZedBoard
- * See zynq-common.h for Zynq common configs
- *
- * SPDX-License-Identifier:    GPL-2.0+
- */
-
-#ifndef __CONFIG_ZYNQ_MICROZED_H
-#define __CONFIG_ZYNQ_MICROZED_H
-
-#define CONFIG_SYS_NO_FLASH
-
-#define CONFIG_ZYNQ_USB
-
-#include <configs/zynq-common.h>
-
-#endif /* __CONFIG_ZYNQ_MICROZED_H */
diff --git a/include/configs/zynq_picozed.h b/include/configs/zynq_picozed.h
deleted file mode 100644 (file)
index adc4d0f..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * (C) Copyright 2015 Xilinx, Inc.
- *
- * Configuration for PicoZed
- * See zynq-common.h for Zynq common configs
- *
- * SPDX-License-Identifier:    GPL-2.0+
- */
-
-#ifndef __CONFIG_ZYNQ_PICOZED_H
-#define __CONFIG_ZYNQ_PICOZED_H
-
-#define CONFIG_SYS_NO_FLASH
-
-#define CONFIG_ZYNQ_USB
-
-#include <configs/zynq-common.h>
-
-#endif /* __CONFIG_ZYNQ_PICOZED_H */
index 8a045900f62dce7af24a46593b4a49ca7e190f9a..fc46fec9cc8e1c06940926f000e986de5035cf82 100644 (file)
@@ -10,9 +10,6 @@
 #ifndef __CONFIG_ZYNQ_ZC70X_H
 #define __CONFIG_ZYNQ_ZC70X_H
 
-#define CONFIG_SYS_NO_FLASH
-
-#define CONFIG_ZYNQ_USB
 #define CONFIG_ZYNQ_I2C0
 #define CONFIG_ZYNQ_EEPROM
 
diff --git a/include/configs/zynq_zc770.h b/include/configs/zynq_zc770.h
deleted file mode 100644 (file)
index 35622ae..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * (C) Copyright 2013 Xilinx, Inc.
- *
- * Configuration settings for the Xilinx Zynq ZC770 board.
- * See zynq-common.h for Zynq common configs
- *
- * SPDX-License-Identifier:     GPL-2.0+
- */
-
-#ifndef __CONFIG_ZYNQ_ZC770_H
-#define __CONFIG_ZYNQ_ZC770_H
-
-#define CONFIG_SYS_NO_FLASH
-
-#if defined(CONFIG_ZC770_XM012)
-# undef CONFIG_SYS_NO_FLASH
-
-#endif
-
-#include <configs/zynq-common.h>
-
-#endif /* __CONFIG_ZYNQ_ZC770_H */
diff --git a/include/configs/zynq_zed.h b/include/configs/zynq_zed.h
deleted file mode 100644 (file)
index 150cb4a..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * (C) Copyright 2013 Xilinx, Inc.
- *
- * Configuration for Zynq Evaluation and Development Board - ZedBoard
- * See zynq-common.h for Zynq common configs
- *
- * SPDX-License-Identifier:    GPL-2.0+
- */
-
-#ifndef __CONFIG_ZYNQ_ZED_H
-#define __CONFIG_ZYNQ_ZED_H
-
-#define CONFIG_SYS_NO_FLASH
-
-#define CONFIG_ZYNQ_USB
-
-#include <configs/zynq-common.h>
-
-#endif /* __CONFIG_ZYNQ_ZED_H */
index 637b1c5ffe9134aeb7a1310db5003b49f2cb1a36..b9ff39145873ac2911f04ddb15eda520e4be80c2 100644 (file)
@@ -11,9 +11,6 @@
 #ifndef __CONFIG_ZYNQ_ZYBO_H
 #define __CONFIG_ZYNQ_ZYBO_H
 
-#define CONFIG_SYS_NO_FLASH
-
-#define CONFIG_ZYNQ_USB
 #define CONFIG_ZYNQ_I2C0
 #define CONFIG_ZYNQ_I2C1
 #define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 1
index f03bcd3b49ee45f962126f67272587364ec52356..705849b228c648b427a2b1c2d58d7b3e19867380 100644 (file)
@@ -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
@@ -205,6 +207,10 @@ struct driver {
 #define U_BOOT_DRIVER(__name)                                          \
        ll_entry_declare(struct driver, __name, driver)
 
+/* Get a pointer to a given driver */
+#define DM_GET_DRIVER(__name)                                          \
+       ll_entry_get(struct driver, __name, driver)
+
 /**
  * dev_get_platdata() - Get the platform data for a device
  *
@@ -466,6 +472,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
  *
@@ -540,7 +559,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
index 6f4f00140e5690f404b3169e2dce4e2c0133e735..488b2ab0aea446f524b7edede8cc7ee583b920b5 100644 (file)
  *
  * @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
 };
 
 /**
index b768660e85679b53450fca4cff99d76e91972f65..c5cdfc79d101103f153cdc039e01c739818cbd17 100644 (file)
@@ -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 */
index fd368b6bd0ead819db389afb776d287d22cd081c..84f05bcfceaac482011aed97eca320dfeddecd14 100644 (file)
@@ -38,6 +38,7 @@ struct uclass {
        struct list_head sibling_node;
 };
 
+struct driver;
 struct udevice;
 
 /* Members of this uclass sequence themselves with aliases */
@@ -193,6 +194,23 @@ int uclass_get_device_by_of_offset(enum uclass_id id, int node,
 int uclass_get_device_by_phandle(enum uclass_id id, struct udevice *parent,
                                 const char *name, struct udevice **devp);
 
+/**
+ * uclass_get_device_by_driver() - Get a uclass device for a driver
+ *
+ * This searches the devices in the uclass for one that uses the given
+ * driver. Use DM_GET_DRIVER(name) for the @drv argument, where 'name' is
+ * the driver name - as used in U_BOOT_DRIVER(name).
+ *
+ * The device is probed to activate it ready for use.
+ *
+ * @id: ID to look up
+ * @drv: Driver to look for
+ * @devp: Returns pointer to the first device with that driver
+ * @return 0 if OK, -ve on error
+ */
+int uclass_get_device_by_driver(enum uclass_id id, const struct driver *drv,
+                               struct udevice **devp);
+
 /**
  * uclass_first_device() - Get the first device in a uclass
  *
diff --git a/include/dt-bindings/clock/rk3399-cru.h b/include/dt-bindings/clock/rk3399-cru.h
new file mode 100644 (file)
index 0000000..0a86aec
--- /dev/null
@@ -0,0 +1,746 @@
+/*
+ * Copyright (c) 2016 Rockchip Electronics Co. Ltd.
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#ifndef _DT_BINDINGS_CLK_ROCKCHIP_RK3399_H
+#define _DT_BINDINGS_CLK_ROCKCHIP_RK3399_H
+
+/* core clocks */
+#define PLL_APLLL                      1
+#define PLL_APLLB                      2
+#define PLL_DPLL                       3
+#define PLL_CPLL                       4
+#define PLL_GPLL                       5
+#define PLL_NPLL                       6
+#define PLL_VPLL                       7
+#define ARMCLKL                                8
+#define ARMCLKB                                9
+
+/* sclk gates (special clocks) */
+#define SCLK_I2C1                      65
+#define SCLK_I2C2                      66
+#define SCLK_I2C3                      67
+#define SCLK_I2C5                      68
+#define SCLK_I2C6                      69
+#define SCLK_I2C7                      70
+#define SCLK_SPI0                      71
+#define SCLK_SPI1                      72
+#define SCLK_SPI2                      73
+#define SCLK_SPI4                      74
+#define SCLK_SPI5                      75
+#define SCLK_SDMMC                     76
+#define SCLK_SDIO                      77
+#define SCLK_EMMC                      78
+#define SCLK_TSADC                     79
+#define SCLK_SARADC                    80
+#define SCLK_UART0                     81
+#define SCLK_UART1                     82
+#define SCLK_UART2                     83
+#define SCLK_UART3                     84
+#define SCLK_SPDIF_8CH                 85
+#define SCLK_I2S0_8CH                  86
+#define SCLK_I2S1_8CH                  87
+#define SCLK_I2S2_8CH                  88
+#define SCLK_I2S_8CH_OUT               89
+#define SCLK_TIMER00                   90
+#define SCLK_TIMER01                   91
+#define SCLK_TIMER02                   92
+#define SCLK_TIMER03                   93
+#define SCLK_TIMER04                   94
+#define SCLK_TIMER05                   95
+#define SCLK_TIMER06                   96
+#define SCLK_TIMER07                   97
+#define SCLK_TIMER08                   98
+#define SCLK_TIMER09                   99
+#define SCLK_TIMER10                   100
+#define SCLK_TIMER11                   101
+#define SCLK_MACREF                    102
+#define SCLK_MAC_RX                    103
+#define SCLK_MAC_TX                    104
+#define SCLK_MAC                       105
+#define SCLK_MACREF_OUT                        106
+#define SCLK_VOP0_PWM                  107
+#define SCLK_VOP1_PWM                  108
+#define SCLK_RGA_CORE                  109
+#define SCLK_ISP0                      110
+#define SCLK_ISP1                      111
+#define SCLK_HDMI_CEC                  112
+#define SCLK_HDMI_SFR                  113
+#define SCLK_DP_CORE                   114
+#define SCLK_PVTM_CORE_L               115
+#define SCLK_PVTM_CORE_B               116
+#define SCLK_PVTM_GPU                  117
+#define SCLK_PVTM_DDR                  118
+#define SCLK_MIPIDPHY_REF              119
+#define SCLK_MIPIDPHY_CFG              120
+#define SCLK_HSICPHY                   121
+#define SCLK_USBPHY480M                        122
+#define SCLK_USB2PHY0_REF              123
+#define SCLK_USB2PHY1_REF              124
+#define SCLK_UPHY0_TCPDPHY_REF         125
+#define SCLK_UPHY0_TCPDCORE            126
+#define SCLK_UPHY1_TCPDPHY_REF         127
+#define SCLK_UPHY1_TCPDCORE            128
+#define SCLK_USB3OTG0_REF              129
+#define SCLK_USB3OTG1_REF              130
+#define SCLK_USB3OTG0_SUSPEND          131
+#define SCLK_USB3OTG1_SUSPEND          132
+#define SCLK_CRYPTO0                   133
+#define SCLK_CRYPTO1                   134
+#define SCLK_CCI_TRACE                 135
+#define SCLK_CS                                136
+#define SCLK_CIF_OUT                   137
+#define SCLK_PCIEPHY_REF               138
+#define SCLK_PCIE_CORE                 139
+#define SCLK_M0_PERILP                 140
+#define SCLK_M0_PERILP_DEC             141
+#define SCLK_CM0S                      142
+#define SCLK_DBG_NOC                   143
+#define SCLK_DBG_PD_CORE_B             144
+#define SCLK_DBG_PD_CORE_L             145
+#define SCLK_DFIMON0_TIMER             146
+#define SCLK_DFIMON1_TIMER             147
+#define SCLK_INTMEM0                   148
+#define SCLK_INTMEM1                   149
+#define SCLK_INTMEM2                   150
+#define SCLK_INTMEM3                   151
+#define SCLK_INTMEM4                   152
+#define SCLK_INTMEM5                   153
+#define SCLK_SDMMC_DRV                 154
+#define SCLK_SDMMC_SAMPLE              155
+#define SCLK_SDIO_DRV                  156
+#define SCLK_SDIO_SAMPLE               157
+#define SCLK_VDU_CORE                  158
+#define SCLK_VDU_CA                    159
+#define SCLK_PCIE_PM                   160
+#define SCLK_SPDIF_REC_DPTX            161
+#define SCLK_DPHY_PLL                  162
+#define SCLK_DPHY_TX0_CFG              163
+#define SCLK_DPHY_TX1RX1_CFG           164
+#define SCLK_DPHY_RX0_CFG              165
+#define SCLK_RMII_SRC                  166
+#define SCLK_PCIEPHY_REF100M           167
+
+#define DCLK_VOP0                      180
+#define DCLK_VOP1                      181
+#define DCLK_VOP0_DIV                  182
+#define DCLK_VOP1_DIV                  183
+#define DCLK_M0_PERILP                 184
+
+#define FCLK_CM0S                      190
+
+/* aclk gates */
+#define ACLK_PERIHP                    192
+#define ACLK_PERIHP_NOC                        193
+#define ACLK_PERILP0                   194
+#define ACLK_PERILP0_NOC               195
+#define ACLK_PERF_PCIE                 196
+#define ACLK_PCIE                      197
+#define ACLK_INTMEM                    198
+#define ACLK_TZMA                      199
+#define ACLK_DCF                       200
+#define ACLK_CCI                       201
+#define ACLK_CCI_NOC0                  202
+#define ACLK_CCI_NOC1                  203
+#define ACLK_CCI_GRF                   204
+#define ACLK_CENTER                    205
+#define ACLK_CENTER_MAIN_NOC           206
+#define ACLK_CENTER_PERI_NOC           207
+#define ACLK_GPU                       208
+#define ACLK_PERF_GPU                  209
+#define ACLK_GPU_GRF                   210
+#define ACLK_DMAC0_PERILP              211
+#define ACLK_DMAC1_PERILP              212
+#define ACLK_GMAC                      213
+#define ACLK_GMAC_NOC                  214
+#define ACLK_PERF_GMAC                 215
+#define ACLK_VOP0_NOC                  216
+#define ACLK_VOP0                      217
+#define ACLK_VOP1_NOC                  218
+#define ACLK_VOP1                      219
+#define ACLK_RGA                       220
+#define ACLK_RGA_NOC                   221
+#define ACLK_HDCP                      222
+#define ACLK_HDCP_NOC                  223
+#define ACLK_HDCP22                    224
+#define ACLK_IEP                       225
+#define ACLK_IEP_NOC                   226
+#define ACLK_VIO                       227
+#define ACLK_VIO_NOC                   228
+#define ACLK_ISP0                      229
+#define ACLK_ISP1                      230
+#define ACLK_ISP0_NOC                  231
+#define ACLK_ISP1_NOC                  232
+#define ACLK_ISP0_WRAPPER              233
+#define ACLK_ISP1_WRAPPER              234
+#define ACLK_VCODEC                    235
+#define ACLK_VCODEC_NOC                        236
+#define ACLK_VDU                       237
+#define ACLK_VDU_NOC                   238
+#define ACLK_PERI                      239
+#define ACLK_EMMC                      240
+#define ACLK_EMMC_CORE                 241
+#define ACLK_EMMC_NOC                  242
+#define ACLK_EMMC_GRF                  243
+#define ACLK_USB3                      244
+#define ACLK_USB3_NOC                  245
+#define ACLK_USB3OTG0                  246
+#define ACLK_USB3OTG1                  247
+#define ACLK_USB3_RKSOC_AXI_PERF       248
+#define ACLK_USB3_GRF                  249
+#define ACLK_GIC                       250
+#define ACLK_GIC_NOC                   251
+#define ACLK_GIC_ADB400_CORE_L_2_GIC   252
+#define ACLK_GIC_ADB400_CORE_B_2_GIC   253
+#define ACLK_GIC_ADB400_GIC_2_CORE_L   254
+#define ACLK_GIC_ADB400_GIC_2_CORE_B   255
+#define ACLK_CORE_ADB400_CORE_L_2_CCI500 256
+#define ACLK_CORE_ADB400_CORE_B_2_CCI500 257
+#define ACLK_ADB400M_PD_CORE_L         258
+#define ACLK_ADB400M_PD_CORE_B         259
+#define ACLK_PERF_CORE_L               260
+#define ACLK_PERF_CORE_B               261
+#define ACLK_GIC_PRE                   262
+#define ACLK_VOP0_PRE                  263
+#define ACLK_VOP1_PRE                  264
+
+/* pclk gates */
+#define PCLK_PERIHP                    320
+#define PCLK_PERIHP_NOC                        321
+#define PCLK_PERILP0                   322
+#define PCLK_PERILP1                   323
+#define PCLK_PERILP1_NOC               324
+#define PCLK_PERILP_SGRF               325
+#define PCLK_PERIHP_GRF                        326
+#define PCLK_PCIE                      327
+#define PCLK_SGRF                      328
+#define PCLK_INTR_ARB                  329
+#define PCLK_CENTER_MAIN_NOC           330
+#define PCLK_CIC                       331
+#define PCLK_COREDBG_B                 332
+#define PCLK_COREDBG_L                 333
+#define PCLK_DBG_CXCS_PD_CORE_B                334
+#define PCLK_DCF                       335
+#define PCLK_GPIO2                     336
+#define PCLK_GPIO3                     337
+#define PCLK_GPIO4                     338
+#define PCLK_GRF                       339
+#define PCLK_HSICPHY                   340
+#define PCLK_I2C1                      341
+#define PCLK_I2C2                      342
+#define PCLK_I2C3                      343
+#define PCLK_I2C5                      344
+#define PCLK_I2C6                      345
+#define PCLK_I2C7                      346
+#define PCLK_SPI0                      347
+#define PCLK_SPI1                      348
+#define PCLK_SPI2                      349
+#define PCLK_SPI4                      350
+#define PCLK_SPI5                      351
+#define PCLK_UART0                     352
+#define PCLK_UART1                     353
+#define PCLK_UART2                     354
+#define PCLK_UART3                     355
+#define PCLK_TSADC                     356
+#define PCLK_SARADC                    357
+#define PCLK_GMAC                      358
+#define PCLK_GMAC_NOC                  359
+#define PCLK_TIMER0                    360
+#define PCLK_TIMER1                    361
+#define PCLK_EDP                       362
+#define PCLK_EDP_NOC                   363
+#define PCLK_EDP_CTRL                  364
+#define PCLK_VIO                       365
+#define PCLK_VIO_NOC                   366
+#define PCLK_VIO_GRF                   367
+#define PCLK_MIPI_DSI0                 368
+#define PCLK_MIPI_DSI1                 369
+#define PCLK_HDCP                      370
+#define PCLK_HDCP_NOC                  371
+#define PCLK_HDMI_CTRL                 372
+#define PCLK_DP_CTRL                   373
+#define PCLK_HDCP22                    374
+#define PCLK_GASKET                    375
+#define PCLK_DDR                       376
+#define PCLK_DDR_MON                   377
+#define PCLK_DDR_SGRF                  378
+#define PCLK_ISP1_WRAPPER              379
+#define PCLK_WDT                       380
+#define PCLK_EFUSE1024NS               381
+#define PCLK_EFUSE1024S                        382
+#define PCLK_PMU_INTR_ARB              383
+#define PCLK_MAILBOX0                  384
+#define PCLK_USBPHY_MUX_G              385
+#define PCLK_UPHY0_TCPHY_G             386
+#define PCLK_UPHY0_TCPD_G              387
+#define PCLK_UPHY1_TCPHY_G             388
+#define PCLK_UPHY1_TCPD_G              389
+#define PCLK_ALIVE                     390
+
+/* hclk gates */
+#define HCLK_PERIHP                    448
+#define HCLK_PERILP0                   449
+#define HCLK_PERILP1                   450
+#define HCLK_PERILP0_NOC               451
+#define HCLK_PERILP1_NOC               452
+#define HCLK_M0_PERILP                 453
+#define HCLK_M0_PERILP_NOC             454
+#define HCLK_AHB1TOM                   455
+#define HCLK_HOST0                     456
+#define HCLK_HOST0_ARB                 457
+#define HCLK_HOST1                     458
+#define HCLK_HOST1_ARB                 459
+#define HCLK_HSIC                      460
+#define HCLK_SD                                461
+#define HCLK_SDMMC                     462
+#define HCLK_SDMMC_NOC                 463
+#define HCLK_M_CRYPTO0                 464
+#define HCLK_M_CRYPTO1                 465
+#define HCLK_S_CRYPTO0                 466
+#define HCLK_S_CRYPTO1                 467
+#define HCLK_I2S0_8CH                  468
+#define HCLK_I2S1_8CH                  469
+#define HCLK_I2S2_8CH                  470
+#define HCLK_SPDIF                     471
+#define HCLK_VOP0_NOC                  472
+#define HCLK_VOP0                      473
+#define HCLK_VOP1_NOC                  474
+#define HCLK_VOP1                      475
+#define HCLK_ROM                       476
+#define HCLK_IEP                       477
+#define HCLK_IEP_NOC                   478
+#define HCLK_ISP0                      479
+#define HCLK_ISP1                      480
+#define HCLK_ISP0_NOC                  481
+#define HCLK_ISP1_NOC                  482
+#define HCLK_ISP0_WRAPPER              483
+#define HCLK_ISP1_WRAPPER              484
+#define HCLK_RGA                       485
+#define HCLK_RGA_NOC                   486
+#define HCLK_HDCP                      487
+#define HCLK_HDCP_NOC                  488
+#define HCLK_HDCP22                    489
+#define HCLK_VCODEC                    490
+#define HCLK_VCODEC_NOC                        491
+#define HCLK_VDU                       492
+#define HCLK_VDU_NOC                   493
+#define HCLK_SDIO                      494
+#define HCLK_SDIO_NOC                  495
+#define HCLK_SDIOAUDIO_NOC             496
+
+#define CLK_NR_CLKS                    (HCLK_SDIOAUDIO_NOC + 1)
+
+/* pmu-clocks indices */
+
+#define PLL_PPLL                       1
+
+#define SCLK_32K_SUSPEND_PMU           2
+#define SCLK_SPI3_PMU                  3
+#define SCLK_TIMER12_PMU               4
+#define SCLK_TIMER13_PMU               5
+#define SCLK_UART4_PMU                 6
+#define SCLK_PVTM_PMU                  7
+#define SCLK_WIFI_PMU                  8
+#define SCLK_I2C0_PMU                  9
+#define SCLK_I2C4_PMU                  10
+#define SCLK_I2C8_PMU                  11
+
+#define PCLK_SRC_PMU                   19
+#define PCLK_PMU                       20
+#define PCLK_PMUGRF_PMU                        21
+#define PCLK_INTMEM1_PMU               22
+#define PCLK_GPIO0_PMU                 23
+#define PCLK_GPIO1_PMU                 24
+#define PCLK_SGRF_PMU                  25
+#define PCLK_NOC_PMU                   26
+#define PCLK_I2C0_PMU                  27
+#define PCLK_I2C4_PMU                  28
+#define PCLK_I2C8_PMU                  29
+#define PCLK_RKPWM_PMU                 30
+#define PCLK_SPI3_PMU                  31
+#define PCLK_TIMER_PMU                 32
+#define PCLK_MAILBOX_PMU               33
+#define PCLK_UART4_PMU                 34
+#define PCLK_WDT_M0_PMU                        35
+
+#define FCLK_CM0S_SRC_PMU              44
+#define FCLK_CM0S_PMU                  45
+#define SCLK_CM0S_PMU                  46
+#define HCLK_CM0S_PMU                  47
+#define DCLK_CM0S_PMU                  48
+#define PCLK_INTR_ARB_PMU              49
+#define HCLK_NOC_PMU                   50
+
+#define CLKPMU_NR_CLKS                 (HCLK_NOC_PMU + 1)
+
+/* soft-reset indices */
+
+/* cru_softrst_con0 */
+#define SRST_CORE_L0                   0
+#define SRST_CORE_B0                   1
+#define SRST_CORE_PO_L0                        2
+#define SRST_CORE_PO_B0                        3
+#define SRST_L2_L                      4
+#define SRST_L2_B                      5
+#define SRST_ADB_L                     6
+#define SRST_ADB_B                     7
+#define SRST_A_CCI                     8
+#define SRST_A_CCIM0_NOC               9
+#define SRST_A_CCIM1_NOC               10
+#define SRST_DBG_NOC                   11
+
+/* cru_softrst_con1 */
+#define SRST_CORE_L0_T                 16
+#define SRST_CORE_L1                   17
+#define SRST_CORE_L2                   18
+#define SRST_CORE_L3                   19
+#define SRST_CORE_PO_L0_T              20
+#define SRST_CORE_PO_L1                        21
+#define SRST_CORE_PO_L2                        22
+#define SRST_CORE_PO_L3                        23
+#define SRST_A_ADB400_GIC2COREL                24
+#define SRST_A_ADB400_COREL2GIC                25
+#define SRST_P_DBG_L                   26
+#define SRST_L2_L_T                    28
+#define SRST_ADB_L_T                   29
+#define SRST_A_RKPERF_L                        30
+#define SRST_PVTM_CORE_L               31
+
+/* cru_softrst_con2 */
+#define SRST_CORE_B0_T                 32
+#define SRST_CORE_B1                   33
+#define SRST_CORE_PO_B0_T              36
+#define SRST_CORE_PO_B1                        37
+#define SRST_A_ADB400_GIC2COREB                40
+#define SRST_A_ADB400_COREB2GIC                41
+#define SRST_P_DBG_B                   42
+#define SRST_L2_B_T                    43
+#define SRST_ADB_B_T                   45
+#define SRST_A_RKPERF_B                        46
+#define SRST_PVTM_CORE_B               47
+
+/* cru_softrst_con3 */
+#define SRST_A_CCI_T                   50
+#define SRST_A_CCIM0_NOC_T             51
+#define SRST_A_CCIM1_NOC_T             52
+#define SRST_A_ADB400M_PD_CORE_B_T     53
+#define SRST_A_ADB400M_PD_CORE_L_T     54
+#define SRST_DBG_NOC_T                 55
+#define SRST_DBG_CXCS                  56
+#define SRST_CCI_TRACE                 57
+#define SRST_P_CCI_GRF                 58
+
+/* cru_softrst_con4 */
+#define SRST_A_CENTER_MAIN_NOC         64
+#define SRST_A_CENTER_PERI_NOC         65
+#define SRST_P_CENTER_MAIN             66
+#define SRST_P_DDRMON                  67
+#define SRST_P_CIC                     68
+#define SRST_P_CENTER_SGRF             69
+#define SRST_DDR0_MSCH                 70
+#define SRST_DDRCFG0_MSCH              71
+#define SRST_DDR0                      72
+#define SRST_DDRPHY0                   73
+#define SRST_DDR1_MSCH                 74
+#define SRST_DDRCFG1_MSCH              75
+#define SRST_DDR1                      76
+#define SRST_DDRPHY1                   77
+#define SRST_DDR_CIC                   78
+#define SRST_PVTM_DDR                  79
+
+/* cru_softrst_con5 */
+#define SRST_A_VCODEC_NOC              80
+#define SRST_A_VCODEC                  81
+#define SRST_H_VCODEC_NOC              82
+#define SRST_H_VCODEC                  83
+#define SRST_A_VDU_NOC                 88
+#define SRST_A_VDU                     89
+#define SRST_H_VDU_NOC                 90
+#define SRST_H_VDU                     91
+#define SRST_VDU_CORE                  92
+#define SRST_VDU_CA                    93
+
+/* cru_softrst_con6 */
+#define SRST_A_IEP_NOC                 96
+#define SRST_A_VOP_IEP                 97
+#define SRST_A_IEP                     98
+#define SRST_H_IEP_NOC                 99
+#define SRST_H_IEP                     100
+#define SRST_A_RGA_NOC                 102
+#define SRST_A_RGA                     103
+#define SRST_H_RGA_NOC                 104
+#define SRST_H_RGA                     105
+#define SRST_RGA_CORE                  106
+#define SRST_EMMC_NOC                  108
+#define SRST_EMMC                      109
+#define SRST_EMMC_GRF                  110
+
+/* cru_softrst_con7 */
+#define SRST_A_PERIHP_NOC              112
+#define SRST_P_PERIHP_GRF              113
+#define SRST_H_PERIHP_NOC              114
+#define SRST_USBHOST0                  115
+#define SRST_HOSTC0_AUX                        116
+#define SRST_HOST0_ARB                 117
+#define SRST_USBHOST1                  118
+#define SRST_HOSTC1_AUX                        119
+#define SRST_HOST1_ARB                 120
+#define SRST_SDIO0                     121
+#define SRST_SDMMC                     122
+#define SRST_HSIC                      123
+#define SRST_HSIC_AUX                  124
+#define SRST_AHB1TOM                   125
+#define SRST_P_PERIHP_NOC              126
+#define SRST_HSICPHY                   127
+
+/* cru_softrst_con8 */
+#define SRST_A_PCIE                    128
+#define SRST_P_PCIE                    129
+#define SRST_PCIE_CORE                 130
+#define SRST_PCIE_MGMT                 131
+#define SRST_PCIE_MGMT_STICKY          132
+#define SRST_PCIE_PIPE                 133
+#define SRST_PCIE_PM                   134
+#define SRST_PCIEPHY                   135
+#define SRST_A_GMAC_NOC                        136
+#define SRST_A_GMAC                    137
+#define SRST_P_GMAC_NOC                        138
+#define SRST_P_GMAC_GRF                        140
+#define SRST_HSICPHY_POR               142
+#define SRST_HSICPHY_UTMI              143
+
+/* cru_softrst_con9 */
+#define SRST_USB2PHY0_POR              144
+#define SRST_USB2PHY0_UTMI_PORT0       145
+#define SRST_USB2PHY0_UTMI_PORT1       146
+#define SRST_USB2PHY0_EHCIPHY          147
+#define SRST_UPHY0_PIPE_L00            148
+#define SRST_UPHY0                     149
+#define SRST_UPHY0_TCPDPWRUP           150
+#define SRST_USB2PHY1_POR              152
+#define SRST_USB2PHY1_UTMI_PORT0       153
+#define SRST_USB2PHY1_UTMI_PORT1       154
+#define SRST_USB2PHY1_EHCIPHY          155
+#define SRST_UPHY1_PIPE_L00            156
+#define SRST_UPHY1                     157
+#define SRST_UPHY1_TCPDPWRUP           158
+
+/* cru_softrst_con10 */
+#define SRST_A_PERILP0_NOC             160
+#define SRST_A_DCF                     161
+#define SRST_GIC500                    162
+#define SRST_DMAC0_PERILP0             163
+#define SRST_DMAC1_PERILP0             164
+#define SRST_TZMA                      165
+#define SRST_INTMEM                    166
+#define SRST_ADB400_MST0               167
+#define SRST_ADB400_MST1               168
+#define SRST_ADB400_SLV0               169
+#define SRST_ADB400_SLV1               170
+#define SRST_H_PERILP0                 171
+#define SRST_H_PERILP0_NOC             172
+#define SRST_ROM                       173
+#define SRST_CRYPTO_S                  174
+#define SRST_CRYPTO_M                  175
+
+/* cru_softrst_con11 */
+#define SRST_P_DCF                     176
+#define SRST_CM0S_NOC                  177
+#define SRST_CM0S                      178
+#define SRST_CM0S_DBG                  179
+#define SRST_CM0S_PO                   180
+#define SRST_CRYPTO                    181
+#define SRST_P_PERILP1_SGRF            182
+#define SRST_P_PERILP1_GRF             183
+#define SRST_CRYPTO1_S                 184
+#define SRST_CRYPTO1_M                 185
+#define SRST_CRYPTO1                   186
+#define SRST_GIC_NOC                   188
+#define SRST_SD_NOC                    189
+#define SRST_SDIOAUDIO_BRG             190
+
+/* cru_softrst_con12 */
+#define SRST_H_PERILP1                 192
+#define SRST_H_PERILP1_NOC             193
+#define SRST_H_I2S0_8CH                        194
+#define SRST_H_I2S1_8CH                        195
+#define SRST_H_I2S2_8CH                        196
+#define SRST_H_SPDIF_8CH               197
+#define SRST_P_PERILP1_NOC             198
+#define SRST_P_EFUSE_1024              199
+#define SRST_P_EFUSE_1024S             200
+#define SRST_P_I2C0                    201
+#define SRST_P_I2C1                    202
+#define SRST_P_I2C2                    203
+#define SRST_P_I2C3                    204
+#define SRST_P_I2C4                    205
+#define SRST_P_I2C5                    206
+#define SRST_P_MAILBOX0                        207
+
+/* cru_softrst_con13 */
+#define SRST_P_UART0                   208
+#define SRST_P_UART1                   209
+#define SRST_P_UART2                   210
+#define SRST_P_UART3                   211
+#define SRST_P_SARADC                  212
+#define SRST_P_TSADC                   213
+#define SRST_P_SPI0                    214
+#define SRST_P_SPI1                    215
+#define SRST_P_SPI2                    216
+#define SRST_P_SPI3                    217
+#define SRST_P_SPI4                    218
+#define SRST_SPI0                      219
+#define SRST_SPI1                      220
+#define SRST_SPI2                      221
+#define SRST_SPI3                      222
+#define SRST_SPI4                      223
+
+/* cru_softrst_con14 */
+#define SRST_I2S0_8CH                  224
+#define SRST_I2S1_8CH                  225
+#define SRST_I2S2_8CH                  226
+#define SRST_SPDIF_8CH                 227
+#define SRST_UART0                     228
+#define SRST_UART1                     229
+#define SRST_UART2                     230
+#define SRST_UART3                     231
+#define SRST_TSADC                     232
+#define SRST_I2C0                      233
+#define SRST_I2C1                      234
+#define SRST_I2C2                      235
+#define SRST_I2C3                      236
+#define SRST_I2C4                      237
+#define SRST_I2C5                      238
+#define SRST_SDIOAUDIO_NOC             239
+
+/* cru_softrst_con15 */
+#define SRST_A_VIO_NOC                 240
+#define SRST_A_HDCP_NOC                        241
+#define SRST_A_HDCP                    242
+#define SRST_H_HDCP_NOC                        243
+#define SRST_H_HDCP                    244
+#define SRST_P_HDCP_NOC                        245
+#define SRST_P_HDCP                    246
+#define SRST_P_HDMI_CTRL               247
+#define SRST_P_DP_CTRL                 248
+#define SRST_S_DP_CTRL                 249
+#define SRST_C_DP_CTRL                 250
+#define SRST_P_MIPI_DSI0               251
+#define SRST_P_MIPI_DSI1               252
+#define SRST_DP_CORE                   253
+#define SRST_DP_I2S                    254
+
+/* cru_softrst_con16 */
+#define SRST_GASKET                    256
+#define SRST_VIO_GRF                   258
+#define SRST_DPTX_SPDIF_REC            259
+#define SRST_HDMI_CTRL                 260
+#define SRST_HDCP_CTRL                 261
+#define SRST_A_ISP0_NOC                        262
+#define SRST_A_ISP1_NOC                        263
+#define SRST_H_ISP0_NOC                        266
+#define SRST_H_ISP1_NOC                        267
+#define SRST_H_ISP0                    268
+#define SRST_H_ISP1                    269
+#define SRST_ISP0                      270
+#define SRST_ISP1                      271
+
+/* cru_softrst_con17 */
+#define SRST_A_VOP0_NOC                        272
+#define SRST_A_VOP1_NOC                        273
+#define SRST_A_VOP0                    274
+#define SRST_A_VOP1                    275
+#define SRST_H_VOP0_NOC                        276
+#define SRST_H_VOP1_NOC                        277
+#define SRST_H_VOP0                    278
+#define SRST_H_VOP1                    279
+#define SRST_D_VOP0                    280
+#define SRST_D_VOP1                    281
+#define SRST_VOP0_PWM                  282
+#define SRST_VOP1_PWM                  283
+#define SRST_P_EDP_NOC                 284
+#define SRST_P_EDP_CTRL                        285
+
+/* cru_softrst_con18 */
+#define SRST_A_GPU                     288
+#define SRST_A_GPU_NOC                 289
+#define SRST_A_GPU_GRF                 290
+#define SRST_PVTM_GPU                  291
+#define SRST_A_USB3_NOC                        292
+#define SRST_A_USB3_OTG0               293
+#define SRST_A_USB3_OTG1               294
+#define SRST_A_USB3_GRF                        295
+#define SRST_PMU                       296
+
+/* cru_softrst_con19 */
+#define SRST_P_TIMER0_5                        304
+#define SRST_TIMER0                    305
+#define SRST_TIMER1                    306
+#define SRST_TIMER2                    307
+#define SRST_TIMER3                    308
+#define SRST_TIMER4                    309
+#define SRST_TIMER5                    310
+#define SRST_P_TIMER6_11               311
+#define SRST_TIMER6                    312
+#define SRST_TIMER7                    313
+#define SRST_TIMER8                    314
+#define SRST_TIMER9                    315
+#define SRST_TIMER10                   316
+#define SRST_TIMER11                   317
+#define SRST_P_INTR_ARB_PMU            318
+#define SRST_P_ALIVE_SGRF              319
+
+/* cru_softrst_con20 */
+#define SRST_P_GPIO2                   320
+#define SRST_P_GPIO3                   321
+#define SRST_P_GPIO4                   322
+#define SRST_P_GRF                     323
+#define SRST_P_ALIVE_NOC               324
+#define SRST_P_WDT0                    325
+#define SRST_P_WDT1                    326
+#define SRST_P_INTR_ARB                        327
+#define SRST_P_UPHY0_DPTX              328
+#define SRST_P_UPHY0_APB               330
+#define SRST_P_UPHY0_TCPHY             332
+#define SRST_P_UPHY1_TCPHY             333
+#define SRST_P_UPHY0_TCPDCTRL          334
+#define SRST_P_UPHY1_TCPDCTRL          335
+
+/* pmu soft-reset indices */
+
+/* pmu_cru_softrst_con0 */
+#define SRST_P_NOC                     0
+#define SRST_P_INTMEM                  1
+#define SRST_H_CM0S                    2
+#define SRST_H_CM0S_NOC                        3
+#define SRST_DBG_CM0S                  4
+#define SRST_PO_CM0S                   5
+#define SRST_P_SPI6                    6
+#define SRST_SPI6                      7
+#define SRST_P_TIMER_0_1               8
+#define SRST_P_TIMER_0                 9
+#define SRST_P_TIMER_1                 10
+#define SRST_P_UART4                   11
+#define SRST_UART4                     12
+#define SRST_P_WDT                     13
+
+/* pmu_cru_softrst_con1 */
+#define SRST_P_I2C6                    16
+#define SRST_P_I2C7                    17
+#define SRST_P_I2C8                    18
+#define SRST_P_MAILBOX                 19
+#define SRST_P_RKPWM                   20
+#define SRST_P_PMUGRF                  21
+#define SRST_P_SGRF                    22
+#define SRST_P_GPIO0                   23
+#define SRST_P_GPIO1                   24
+#define SRST_P_CRU                     25
+#define SRST_P_INTR                    26
+#define SRST_PVTM                      27
+#define SRST_I2C6                      28
+#define SRST_I2C7                      29
+#define SRST_I2C8                      30
+
+#endif
diff --git a/include/dt-structs.h b/include/dt-structs.h
new file mode 100644 (file)
index 0000000..e13afa6
--- /dev/null
@@ -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
index 335af51fdf42e72f4e19058cfdff4a1f29dfe520..6aebe96b97bc795b711e51ef33a4d2d5434fca5c 100644 (file)
@@ -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 */
index 05d70c4b9b3ec208ebfb3c15a4bdd7de5b97d201..70ea0bfc0bae28ebd74f395e79e56cca26a35a83 100644 (file)
@@ -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,20 +146,16 @@ 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 */
        COMPAT_INTEL_BAYTRAIL_FSP,      /* Intel Bay Trail FSP */
        COMPAT_INTEL_BAYTRAIL_FSP_MDP,  /* Intel FSP memory-down params */
        COMPAT_INTEL_IVYBRIDGE_FSP,     /* Intel Ivy Bridge FSP */
+       COMPAT_SUNXI_NAND,              /* SUNXI NAND controller */
 
        COMPAT_COUNT,
 };
index a71e1ce2b0e1c8dc486e83f216772ab6b2a822b2..c350938d1ffc92142f7dfeba5616b7dbf694e55b 100644 (file)
@@ -254,4 +254,11 @@ int fsl_secboot_blob_decap(cmd_tbl_t *cmdtp, int flag, int argc,
 
 int fsl_check_boot_mode_secure(void);
 int fsl_setenv_chain_of_trust(void);
+
+/*
+ * This function is used to validate the main U-boot binary from
+ * SPL just before passing control to it using QorIQ Trust
+ * Architecture header (appended to U-boot image).
+ */
+void spl_validate_uboot(uint32_t hdr_addr, uintptr_t img_addr);
 #endif
index e1b9c646266c94cb331ad659ef2aec7250443ef1..bb8e144e04900f41bd6dd94c85410763adcf7b39 100644 (file)
@@ -17,7 +17,6 @@ enum {
 };
 
 int get_fpga_state(unsigned dev);
-void print_fpga_state(unsigned dev);
 
 int fpga_set_reg(u32 fpga, u16 *reg, off_t regoff, u16 data);
 int fpga_get_reg(u32 fpga, u16 *reg, off_t regoff, u16 *data);
index ea6c962a3932f3bc7a28276a93e2bc9c45f2a2cf..04528928126606807f477cd3bac0dfae6c69cd84 100644 (file)
@@ -14,6 +14,10 @@ struct i2c_eeprom_ops {
 };
 
 struct i2c_eeprom {
+       /* The EEPROM's page size in byte */
+       unsigned long pagesize;
+       /* The EEPROM's page width in bits (pagesize = 2^pagewidth) */
+       unsigned pagewidth;
 };
 
 #endif
index d788c260e30aeebd345bd65fb7144d1cf5c8cdb8..734def31178438b758404f3daba40b63cd1b31dc 100644 (file)
@@ -123,62 +123,86 @@ 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
+ *
+ * The following are exposed to uImage header.
+ * Do not change values for backward compatibility.
  */
-#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)
+ *
+ * The following are exposed to uImage header.
+ * Do not change values for backward compatibility.
  */
-#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_NIOS,                   /* Nios-32      */
+       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
@@ -217,49 +241,62 @@ struct lmb;
  *     U-Boot's command interpreter; this feature is especially
  *     useful when you configure U-Boot to use a real shell (hush)
  *     as command interpreter (=> Shell Scripts).
+ *
+ * The following are exposed to uImage header.
+ * Do not change values for backward compatibility.
  */
 
-#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
+ *
+ * The following are exposed to uImage header.
+ * Do not change values for backward compatibility.
  */
-#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 +491,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 +1244,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__ */
index 1b36a2299e1b095f298e550242207f5141852fde..a104b7e69f7c871d267f7a541683b831aed3a071 100644 (file)
@@ -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 */
index cf20674549c56385e09e9ce1efd4ef0957f72825..779eea035c81827cc600aca5d37efcf3e61fc10f 100644 (file)
@@ -500,5 +500,10 @@ int mtd_arg_off(const char *arg, int *idx, loff_t *off, loff_t *size,
 int mtd_arg_off_size(int argc, char *const argv[], int *idx, loff_t *off,
                     loff_t *size, loff_t *maxsize, int devtype,
                     uint64_t chipsize);
+
+/* drivers/mtd/mtdcore.c */
+void mtd_get_len_incl_bad(struct mtd_info *mtd, uint64_t offset,
+                         const uint64_t length, uint64_t *len_incl_bad,
+                         int *truncated);
 #endif
 #endif /* __MTD_MTD_H__ */
index b5a02c3382cacf0b24c8bdcf05141f6d632e3dc6..87d72dbad6681387f19b9f2235779e89535d86bc 100644 (file)
@@ -48,7 +48,7 @@ extern void nand_wait_ready(struct mtd_info *mtd);
  * is supported now. If you add a chip with bigger oobsize/page
  * adjust this accordingly.
  */
-#define NAND_MAX_OOBSIZE       1216
+#define NAND_MAX_OOBSIZE       1664
 #define NAND_MAX_PAGESIZE      16384
 
 /*
@@ -590,6 +590,7 @@ struct nand_buffers {
  *                     flash device
  * @IO_ADDR_W:         [BOARDSPECIFIC] address to write the 8 I/O lines of the
  *                     flash device.
+ * @flash_node:                [BOARDSPECIFIC] device node describing this instance
  * @read_byte:         [REPLACEABLE] read one byte from the chip
  * @read_word:         [REPLACEABLE] read one word from the chip
  * @write_byte:                [REPLACEABLE] write a single byte to the chip on the
@@ -689,6 +690,8 @@ struct nand_chip {
        void __iomem *IO_ADDR_R;
        void __iomem *IO_ADDR_W;
 
+       int flash_node;
+
        uint8_t (*read_byte)(struct mtd_info *mtd);
        u16 (*read_word)(struct mtd_info *mtd);
        void (*write_byte)(struct mtd_info *mtd, uint8_t byte);
index 3a7567435929efcd4281b2b7bc6c27353beb4bfe..be3ce9d203de874552abfa08f85e9d98e89bc20a 100644 (file)
@@ -92,6 +92,7 @@ struct gpmc {
 };
 
 /* Used for board specific gpmc initialization */
-extern struct gpmc *gpmc_cfg;
+extern const struct gpmc *gpmc_cfg;
+extern char gpmc_cs0_flash;
 
 #endif /* __ASM_OMAP_GPMC_H */
index 6f75be4253786888b7717febfadc74a22afb29d3..416fa6628482d8cb5afa356df2f3e34f2411fa8d 100644 (file)
@@ -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.
index 253eddf1590bd89cc810b64247431a9476dca360..199f3667eb4f4371d9813ba2a68defc7354f2c3c 100644 (file)
@@ -51,22 +51,18 @@ struct fsl_xhci {
        struct dwc3 *dwc3_reg;
 };
 
-#if defined(CONFIG_LS102XA)
-#define CONFIG_SYS_FSL_XHCI_USB1_ADDR CONFIG_SYS_LS102XA_XHCI_USB1_ADDR
+#if defined(CONFIG_LS102XA) || defined(CONFIG_LS1012A)
+#define CONFIG_SYS_FSL_XHCI_USB1_ADDR CONFIG_SYS_XHCI_USB1_ADDR
 #define CONFIG_SYS_FSL_XHCI_USB2_ADDR 0
 #define CONFIG_SYS_FSL_XHCI_USB3_ADDR 0
 #elif defined(CONFIG_LS2080A)
-#define CONFIG_SYS_FSL_XHCI_USB1_ADDR CONFIG_SYS_LS2080A_XHCI_USB1_ADDR
-#define CONFIG_SYS_FSL_XHCI_USB2_ADDR CONFIG_SYS_LS2080A_XHCI_USB2_ADDR
-#define CONFIG_SYS_FSL_XHCI_USB3_ADDR 0
-#elif defined(CONFIG_LS1043A) || defined(CONFIG_LS1012A)
-#define CONFIG_SYS_FSL_XHCI_USB1_ADDR CONFIG_SYS_LS1043A_XHCI_USB1_ADDR
-#define CONFIG_SYS_FSL_XHCI_USB2_ADDR CONFIG_SYS_LS1043A_XHCI_USB2_ADDR
-#define CONFIG_SYS_FSL_XHCI_USB3_ADDR CONFIG_SYS_LS1043A_XHCI_USB3_ADDR
-#elif defined(CONFIG_LS1012A)
-#define CONFIG_SYS_FSL_XHCI_USB1_ADDR CONFIG_SYS_LS1043A_XHCI_USB1_ADDR
-#define CONFIG_SYS_FSL_XHCI_USB2_ADDR 0
+#define CONFIG_SYS_FSL_XHCI_USB1_ADDR CONFIG_SYS_XHCI_USB1_ADDR
+#define CONFIG_SYS_FSL_XHCI_USB2_ADDR CONFIG_SYS_XHCI_USB2_ADDR
 #define CONFIG_SYS_FSL_XHCI_USB3_ADDR 0
+#elif defined(CONFIG_LS1043A)
+#define CONFIG_SYS_FSL_XHCI_USB1_ADDR CONFIG_SYS_XHCI_USB1_ADDR
+#define CONFIG_SYS_FSL_XHCI_USB2_ADDR CONFIG_SYS_XHCI_USB2_ADDR
+#define CONFIG_SYS_FSL_XHCI_USB3_ADDR CONFIG_SYS_XHCI_USB3_ADDR
 #endif
 
 #define FSL_USB_XHCI_ADDR      {CONFIG_SYS_FSL_XHCI_USB1_ADDR, \
index f383925ade2c5a846952175158997591035e357a..8f309f1f71c510b10b6ed81403b2b00bcf4b9c52 100644 (file)
@@ -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,
index a4f0f9253d830c9a099affc49e635e4cc2e6a26a..b6eb223fb6f3c34786e7f9af7415d14e41476656 100644 (file)
@@ -122,6 +122,7 @@ int nand_unlock(struct mtd_info *mtd, loff_t start, size_t length,
 int nand_get_lock_status(struct mtd_info *mtd, loff_t offset);
 
 int nand_spl_load_image(uint32_t offs, unsigned int size, void *dst);
+int nand_spl_read_block(int block, int offset, int len, void *dst);
 void nand_deselect(void);
 
 #ifdef CONFIG_SYS_NAND_SELECT_DEVICE
@@ -141,3 +142,6 @@ __attribute__((noreturn)) void nand_boot(void);
 int get_nand_env_oob(struct mtd_info *mtd, unsigned long *result);
 #endif
 int spl_nand_erase_one(int block, int page);
+
+/* platform specific init functions */
+void sunxi_nand_init(void);
index 5ee5929beb8626dab694e838e8735324e17062f8..06320c6514c9543923f109a0300e8e0e91a78057 100644 (file)
@@ -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.
index fd01040817bdda5ff1016ae290182bc52c35285a..995f0aa6fecb4e6d696f13a4e2c3855f1966e3af 100644 (file)
@@ -26,7 +26,7 @@ extern struct mtd_info onenand_mtd;
 extern struct onenand_chip onenand_chip;
 
 /* board */
-extern void onenand_board_init(struct mtd_info *);
+extern int onenand_board_init(struct mtd_info *);
 
 /* Functions */
 extern void onenand_init(void);
@@ -49,6 +49,7 @@ extern int flexonenand_set_boundary(struct mtd_info *mtd, int die,
                                        int boundary, int lock);
 
 /* SPL */
+int onenand_spl_read_block(int block, int offset, int len, void *dst);
 void onenand_spl_load_image(uint32_t offs, uint32_t size, void *dst);
 
 #endif /* __UBOOT_ONENAND_H */
index 954a48c9919e78a9259b615d6be12aa01c1ef4b3..1782e50e77511769b19b7a83679d5521107e5f8e 100644 (file)
@@ -286,6 +286,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
  *
index eccf7707f456568de6cd371d6d971e71bd403ee6..1eed94e47a32d4eaa67e01a6ba22d05f5951ffe7 100644 (file)
@@ -56,6 +56,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
  *
index e0f66670b6a926aa4feacdf26fa467eed0149eb6..c4d3b552d19dd8f30b2f0e757fe29a3fcae55461 100644 (file)
@@ -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 */
index 23604667fa72d37d2b51fb50725a1f95ce3a515b..8afa0856c5889ec9dab554a89f75f47e2b34032e 100644 (file)
@@ -71,6 +71,7 @@ void spl_set_header_raw_uboot(void);
 int spl_parse_image_header(const struct image_header *header);
 void spl_board_prepare_for_linux(void);
 void spl_board_prepare_for_boot(void);
+int spl_board_ubi_load_image(u32 boot_device);
 void __noreturn jump_to_image_linux(void *arg);
 int spl_start_uboot(void);
 void spl_display_print(void);
@@ -84,6 +85,9 @@ int spl_onenand_load_image(void);
 /* NOR SPL functions */
 int spl_nor_load_image(void);
 
+/* UBI SPL functions */
+int spl_ubi_load_image(u32 boot_device);
+
 /* MMC SPL functions */
 int spl_mmc_load_image(u32 boot_device);
 
index 4593b6e3ebfdb96e7869cc9cc88045eaa42cb35d..34842aa4705891928df2f1346f22803f80116caa 100644 (file)
@@ -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/include/ubispl.h b/include/ubispl.h
new file mode 100644 (file)
index 0000000..944653e
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) Thomas Gleixner <tglx@linutronix.de>
+ *
+ * SPDX-License-Identifier: GPL 2.0+ BSD-3-Clause
+ */
+#ifndef __UBOOT_UBISPL_H
+#define __UBOOT_UBISPL_H
+
+/*
+ * The following CONFIG options are relevant for UBISPL
+ *
+ * #define CONFIG_SPL_UBI_MAX_VOL_LEBS         256
+ *
+ * Defines the maximum number of logical erase blocks per loadable
+ * (static) volume to size the ubispl internal arrays.
+ *
+ * #define CONFIG_SPL_UBI_MAX_PEB_SIZE         (256*1024)
+ *
+ * Defines the maximum physical erase block size to size the fastmap
+ * buffer for ubispl.
+ *
+ * #define CONFIG_SPL_UBI_MAX_PEBS             4096
+ *
+ * Define the maximum number of physical erase blocks to size the
+ * ubispl internal arrays.
+ *
+ * #define CONFIG_SPL_UBI_VOL_IDS              8
+ *
+ * Defines the maximum number of volumes in which UBISPL is
+ * interested. Limits the amount of memory for the scan data and
+ * speeds up the scan process as we simply ignore stuff which we dont
+ * want to load from the SPL anyway. So the volumes which can be
+ * loaded in the above example are ids 0 - 7
+ */
+
+/*
+ * The struct definition is in drivers/mtd/ubispl/ubispl.h. It does
+ * not fit into the BSS due to the large buffer requirement of the
+ * upstream fastmap code. So the caller of ubispl_load_volumes needs
+ * to hand in a pointer to a free memory area where ubispl will place
+ * its data. The area is not required to be initialized.
+ */
+struct ubi_scan_info;
+
+typedef int (*ubispl_read_flash)(int pnum, int offset, int len, void *dst);
+
+/**
+ * struct ubispl_info - description structure for fast ubi scan
+ * @ubi:               Pointer to memory space for ubi scan info structure
+ * @peb_size:          Physical erase block size
+ * @vid_offset:                Offset of the VID header
+ * @leb_start:         Start of the logical erase block, i.e. offset of data
+ * @peb_count:         Number of physical erase blocks in the UBI FLASH area
+ *                     aka MTD partition.
+ * @peb_offset:                Offset of PEB0 in the UBI FLASH area (aka MTD partition)
+ *                     to the real start of the FLASH in erase blocks.
+ * @fastmap:           Enable fastmap attachment
+ * @read:              Read function to access the flash
+ */
+struct ubispl_info {
+       struct ubi_scan_info    *ubi;
+       u32                     peb_size;
+       u32                     vid_offset;
+       u32                     leb_start;
+       u32                     peb_count;
+       u32                     peb_offset;
+       int                     fastmap;
+       ubispl_read_flash       read;
+};
+
+/**
+ * struct ubispl_load - structure to describe a volume to load
+ * @vol_id:    Volume id
+ * @load_addr: Load address of the volume
+ */
+struct ubispl_load {
+       int             vol_id;
+       void            *load_addr;
+};
+
+/**
+ * ubispl_load_volumes - Scan flash and load volumes
+ * @info:      Pointer to the ubi scan info structure
+ * @lovls:     Pointer to array of volumes to load
+ * @nrvols:    Array size of @lovls
+ */
+int ubispl_load_volumes(struct ubispl_info *info,
+                       struct ubispl_load *lvols, int nrvols);
+
+#endif
index 302e9a35a23389c82925a7ec0c9bcc9746f0fa5b..7324d8a62db49b5f0f62bbcec3be4bcbe1564d03 100644 (file)
 #define PHY0_SLEEP              (1 << 5)
 
 struct dwc2_plat_otg_data {
+       void            *priv;
+       int             phy_of_node;
        int             (*phy_control)(int on);
        unsigned int    regs_phy;
        unsigned int    regs_otg;
        unsigned int    usb_phy_ctrl;
        unsigned int    usb_flags;
        unsigned int    usb_gusbcfg;
+       unsigned int    rx_fifo_sz;
+       unsigned int    np_tx_fifo_sz;
+       unsigned int    tx_fifo_sz;
 };
 
 int dwc2_udc_probe(struct dwc2_plat_otg_data *pdata);
index 586d32ab52d181a0aa342e56c107bd8916982d15..882aed4a5f09e02d1c6e787d4bc084eae282d66d 100644 (file)
 #define CONFIG_SYS_FSL_USB1_ADDR CONFIG_SYS_MPC512x_USB1_ADDR
 #define CONFIG_SYS_FSL_USB2_ADDR       0
 #elif defined(CONFIG_LS102XA)
-#define CONFIG_SYS_FSL_USB1_ADDR CONFIG_SYS_LS102XA_USB1_ADDR
+#define CONFIG_SYS_FSL_USB1_ADDR CONFIG_SYS_EHCI_USB1_ADDR
 #define CONFIG_SYS_FSL_USB2_ADDR        0
 #endif
 
index f48d90103d2134f841912ff9c82450d6b8707087..f6a8ba1227f00f45d0a8b5cbf4412ea14b665f27 100644 (file)
@@ -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
index df2381e42c2a82764ced80daba124f48142aba31..df3547c47f7e83498068b3c1b0d4d713a7da53b3 100644 (file)
@@ -130,6 +130,9 @@ uint64_t efi_add_memory_map(uint64_t start, uint64_t pages, int memory_type,
        bool carve_again;
        uint64_t carved_pages = 0;
 
+       debug("%s: 0x%" PRIx64 " 0x%" PRIx64 " %d %s\n", __func__,
+             start, pages, memory_type, overlap_only_ram ? "yes" : "no");
+
        if (!pages)
                return start;
 
index 0534c0b767d8d548e07cacd37a02eba7aa52bd41..462a24f96a97f3bdf364cb0164d0cca52d764678 100644 (file)
@@ -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,16 @@ 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"),
+       COMPAT(COMPAT_SUNXI_NAND, "allwinner,sun4i-a10-nand"),
 };
 
 const char *fdtdec_get_compatible(enum fdt_compat_id id)
index 02b41050a44f6656e9605e288f5f6a97faf3539c..4e52b368e44db20668b69367b9b98ceb54f3a073 100644 (file)
@@ -602,8 +602,8 @@ ssize_t hexport_r(struct hsearch_data *htab, const char sep, int flag,
                return (-1);
        }
 
-       debug("EXPORT  table = %p, htab.size = %d, htab.filled = %d, "
-               "size = %zu\n", htab, htab->size, htab->filled, size);
+       debug("EXPORT  table = %p, htab.size = %d, htab.filled = %d, size = %lu\n",
+             htab, htab->size, htab->filled, (ulong)size);
        /*
         * Pass 1:
         * search used entries,
@@ -657,8 +657,8 @@ ssize_t hexport_r(struct hsearch_data *htab, const char sep, int flag,
        /* Check if the user supplied buffer size is sufficient */
        if (size) {
                if (size < totlen + 1) {        /* provided buffer too small */
-                       printf("Env export buffer too small: %zu, "
-                               "but need %zu\n", size, totlen + 1);
+                       printf("Env export buffer too small: %lu, but need %lu\n",
+                              (ulong)size, (ulong)totlen + 1);
                        __set_errno(ENOMEM);
                        return (-1);
                }
@@ -790,7 +790,7 @@ int himport_r(struct hsearch_data *htab,
 
        /* we allocate new space to make sure we can write to the array */
        if ((data = malloc(size + 1)) == NULL) {
-               debug("himport_r: can't malloc %zu bytes\n", size + 1);
+               debug("himport_r: can't malloc %lu bytes\n", (ulong)size + 1);
                __set_errno(ENOMEM);
                return 0;
        }
@@ -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 (file)
index 0000000..14f583d
--- /dev/null
@@ -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 (file)
index 0000000..62e7bcc
--- /dev/null
@@ -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 (file)
index 0000000..14d0da4
--- /dev/null
@@ -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")
index 5d9716f01349f4074653f2735fa3e6204ddba8e7..c26f74128f2814e75e9032c89ffe569bb44eef8f 100644 (file)
@@ -420,11 +420,13 @@ static int fdt_add_bignum(void *blob, int noffset, const char *prop_name,
                BN_rshift(num, num, 32); /*  N = N/B */
        }
 
+       /*
+        * We try signing with successively increasing size values, so this
+        * might fail several times
+        */
        ret = fdt_setprop(blob, noffset, prop_name, buf, size);
-       if (ret) {
-               fprintf(stderr, "Failed to write public key to FIT\n");
-               return -ENOSPC;
-       }
+       if (ret)
+               return -FDT_ERR_NOSPACE;
        free(buf);
        BN_free(tmp);
        BN_free(big2);
@@ -508,7 +510,7 @@ int rsa_add_verify_data(struct image_sign_info *info, void *keydest)
                ret = fdt_setprop_string(keydest, node, FIT_ALGO_PROP,
                                         info->algo->name);
        }
-       if (info->require_keys) {
+       if (!ret && info->require_keys) {
                ret = fdt_setprop_string(keydest, node, "required",
                                         info->require_keys);
        }
index b334f053cc0ee2645aa3669701f0ec22419bb572..1aa43aba44b5b2428033638574f49e76058f80bc 100644 (file)
@@ -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();
+}
index 6e4753cd0dd0d0570a71c67b7e466a55571ec875..a14b20844f896148be0af43aad950ba36e69ea8e 100644 (file)
@@ -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.
index 4c9a39b52675759b23850de1f8c0384d6db51251..8a4c56b7d622ead7495710294a3a64b69a88b352 100644 (file)
@@ -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>
index bff8b5bc614c25ee89e3e74e73b6b542a46567e4..763a699c4ce7b37ea018006880fc5b059534d846 100644 (file)
@@ -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)
index 0997fd9fddfc862dec9164bc7ccc82cf96986b9c..3ba974226b8bc0fbdf4b68747367504a971c94f3 100644 (file)
@@ -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 (file)
index 0000000..ee55972
--- /dev/null
@@ -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.
index 449f98bee39cb1ecc2d7758af18e72e98d7283a0..5b3a92316bbfae2969f76fc11a61e713b649f30b 100644 (file)
@@ -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:
index 68917eb0ea9644d4e922ebcba2a07065a6e8e7bf..35a32fb5c0514fdbd8e697680bac8e338b74edb9 100644 (file)
@@ -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 (file)
index 0000000..457c405
--- /dev/null
@@ -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 (file)
index 0000000..14ec85b
--- /dev/null
@@ -0,0 +1,186 @@
+# 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.boardspec('sandbox')
+@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 = cons.config.source_dir + '/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/py/tests/vboot/sandbox-kernel.dts b/test/py/tests/vboot/sandbox-kernel.dts
new file mode 100644 (file)
index 0000000..a1e853c
--- /dev/null
@@ -0,0 +1,7 @@
+/dts-v1/;
+
+/ {
+       model = "Sandbox Verified Boot Test";
+       compatible = "sandbox";
+
+};
diff --git a/test/py/tests/vboot/sandbox-u-boot.dts b/test/py/tests/vboot/sandbox-u-boot.dts
new file mode 100644 (file)
index 0000000..63f8f40
--- /dev/null
@@ -0,0 +1,10 @@
+/dts-v1/;
+
+/ {
+       model = "Sandbox Verified Boot Test";
+       compatible = "sandbox";
+
+       reset@0 {
+               compatible = "sandbox,reset";
+       };
+};
diff --git a/test/py/tests/vboot/sign-configs-sha1.its b/test/py/tests/vboot/sign-configs-sha1.its
new file mode 100644 (file)
index 0000000..db2ed79
--- /dev/null
@@ -0,0 +1,45 @@
+/dts-v1/;
+
+/ {
+       description = "Chrome OS kernel image with one or more FDT blobs";
+       #address-cells = <1>;
+
+       images {
+               kernel@1 {
+                       data = /incbin/("test-kernel.bin");
+                       type = "kernel_noload";
+                       arch = "sandbox";
+                       os = "linux";
+                       compression = "none";
+                       load = <0x4>;
+                       entry = <0x8>;
+                       kernel-version = <1>;
+                       hash@1 {
+                               algo = "sha1";
+                       };
+               };
+               fdt@1 {
+                       description = "snow";
+                       data = /incbin/("sandbox-kernel.dtb");
+                       type = "flat_dt";
+                       arch = "sandbox";
+                       compression = "none";
+                       fdt-version = <1>;
+                       hash@1 {
+                               algo = "sha1";
+                       };
+               };
+       };
+       configurations {
+               default = "conf@1";
+               conf@1 {
+                       kernel = "kernel@1";
+                       fdt = "fdt@1";
+                       signature@1 {
+                               algo = "sha1,rsa2048";
+                               key-name-hint = "dev";
+                               sign-images = "fdt", "kernel";
+                       };
+               };
+       };
+};
diff --git a/test/py/tests/vboot/sign-configs-sha256.its b/test/py/tests/vboot/sign-configs-sha256.its
new file mode 100644 (file)
index 0000000..1b3432e
--- /dev/null
@@ -0,0 +1,45 @@
+/dts-v1/;
+
+/ {
+       description = "Chrome OS kernel image with one or more FDT blobs";
+       #address-cells = <1>;
+
+       images {
+               kernel@1 {
+                       data = /incbin/("test-kernel.bin");
+                       type = "kernel_noload";
+                       arch = "sandbox";
+                       os = "linux";
+                       compression = "none";
+                       load = <0x4>;
+                       entry = <0x8>;
+                       kernel-version = <1>;
+                       hash@1 {
+                               algo = "sha256";
+                       };
+               };
+               fdt@1 {
+                       description = "snow";
+                       data = /incbin/("sandbox-kernel.dtb");
+                       type = "flat_dt";
+                       arch = "sandbox";
+                       compression = "none";
+                       fdt-version = <1>;
+                       hash@1 {
+                               algo = "sha256";
+                       };
+               };
+       };
+       configurations {
+               default = "conf@1";
+               conf@1 {
+                       kernel = "kernel@1";
+                       fdt = "fdt@1";
+                       signature@1 {
+                               algo = "sha256,rsa2048";
+                               key-name-hint = "dev";
+                               sign-images = "fdt", "kernel";
+                       };
+               };
+       };
+};
diff --git a/test/py/tests/vboot/sign-images-sha1.its b/test/py/tests/vboot/sign-images-sha1.its
new file mode 100644 (file)
index 0000000..f69326a
--- /dev/null
@@ -0,0 +1,42 @@
+/dts-v1/;
+
+/ {
+       description = "Chrome OS kernel image with one or more FDT blobs";
+       #address-cells = <1>;
+
+       images {
+               kernel@1 {
+                       data = /incbin/("test-kernel.bin");
+                       type = "kernel_noload";
+                       arch = "sandbox";
+                       os = "linux";
+                       compression = "none";
+                       load = <0x4>;
+                       entry = <0x8>;
+                       kernel-version = <1>;
+                       signature@1 {
+                               algo = "sha1,rsa2048";
+                               key-name-hint = "dev";
+                       };
+               };
+               fdt@1 {
+                       description = "snow";
+                       data = /incbin/("sandbox-kernel.dtb");
+                       type = "flat_dt";
+                       arch = "sandbox";
+                       compression = "none";
+                       fdt-version = <1>;
+                       signature@1 {
+                               algo = "sha1,rsa2048";
+                               key-name-hint = "dev";
+                       };
+               };
+       };
+       configurations {
+               default = "conf@1";
+               conf@1 {
+                       kernel = "kernel@1";
+                       fdt = "fdt@1";
+               };
+       };
+};
diff --git a/test/py/tests/vboot/sign-images-sha256.its b/test/py/tests/vboot/sign-images-sha256.its
new file mode 100644 (file)
index 0000000..e6aa9fc
--- /dev/null
@@ -0,0 +1,42 @@
+/dts-v1/;
+
+/ {
+       description = "Chrome OS kernel image with one or more FDT blobs";
+       #address-cells = <1>;
+
+       images {
+               kernel@1 {
+                       data = /incbin/("test-kernel.bin");
+                       type = "kernel_noload";
+                       arch = "sandbox";
+                       os = "linux";
+                       compression = "none";
+                       load = <0x4>;
+                       entry = <0x8>;
+                       kernel-version = <1>;
+                       signature@1 {
+                               algo = "sha256,rsa2048";
+                               key-name-hint = "dev";
+                       };
+               };
+               fdt@1 {
+                       description = "snow";
+                       data = /incbin/("sandbox-kernel.dtb");
+                       type = "flat_dt";
+                       arch = "sandbox";
+                       compression = "none";
+                       fdt-version = <1>;
+                       signature@1 {
+                               algo = "sha256,rsa2048";
+                               key-name-hint = "dev";
+                       };
+               };
+       };
+       configurations {
+               default = "conf@1";
+               conf@1 {
+                       kernel = "kernel@1";
+                       fdt = "fdt@1";
+               };
+       };
+};
index 815fa64d5ff344ba7dc6470e714862d6f59c568c..4606ad48bf5d49d7c90c2ade5418347f08b577bf 100644 (file)
@@ -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.
 
index 04654ae8c9fee10a84944cbddcd632ce40114d72..647e1f879fcadcbaf1487e6ad728597959e6f577 100644 (file)
@@ -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)
 
index d15517389e510fa8ddd7d96cfa5dd4b73f86e285..3a0fbfad90f25b39aad147d046ee4d2a2c0d085b 100644 (file)
@@ -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,6 +37,7 @@ class Spawn(object):
 
         self.waited = False
         self.buf = ''
+        self.output = ''
         self.logfile_read = None
         self.before = ''
         self.after = ''
@@ -154,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()
@@ -198,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
index e4765e38c1474bf5122423683d92f2cbfeb5b738..e358c585bf888f71ee55d326df9126f1111d1a46 100644 (file)
@@ -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):
diff --git a/test/run b/test/run
new file mode 100755 (executable)
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 (file)
index 4631242..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-/*.dtb
-/test.fit
-/dev-keys
diff --git a/test/vboot/sandbox-kernel.dts b/test/vboot/sandbox-kernel.dts
deleted file mode 100644 (file)
index a1e853c..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-/dts-v1/;
-
-/ {
-       model = "Sandbox Verified Boot Test";
-       compatible = "sandbox";
-
-};
diff --git a/test/vboot/sandbox-u-boot.dts b/test/vboot/sandbox-u-boot.dts
deleted file mode 100644 (file)
index 63f8f40..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-/dts-v1/;
-
-/ {
-       model = "Sandbox Verified Boot Test";
-       compatible = "sandbox";
-
-       reset@0 {
-               compatible = "sandbox,reset";
-       };
-};
diff --git a/test/vboot/sign-configs-sha1.its b/test/vboot/sign-configs-sha1.its
deleted file mode 100644 (file)
index db2ed79..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/dts-v1/;
-
-/ {
-       description = "Chrome OS kernel image with one or more FDT blobs";
-       #address-cells = <1>;
-
-       images {
-               kernel@1 {
-                       data = /incbin/("test-kernel.bin");
-                       type = "kernel_noload";
-                       arch = "sandbox";
-                       os = "linux";
-                       compression = "none";
-                       load = <0x4>;
-                       entry = <0x8>;
-                       kernel-version = <1>;
-                       hash@1 {
-                               algo = "sha1";
-                       };
-               };
-               fdt@1 {
-                       description = "snow";
-                       data = /incbin/("sandbox-kernel.dtb");
-                       type = "flat_dt";
-                       arch = "sandbox";
-                       compression = "none";
-                       fdt-version = <1>;
-                       hash@1 {
-                               algo = "sha1";
-                       };
-               };
-       };
-       configurations {
-               default = "conf@1";
-               conf@1 {
-                       kernel = "kernel@1";
-                       fdt = "fdt@1";
-                       signature@1 {
-                               algo = "sha1,rsa2048";
-                               key-name-hint = "dev";
-                               sign-images = "fdt", "kernel";
-                       };
-               };
-       };
-};
diff --git a/test/vboot/sign-configs-sha256.its b/test/vboot/sign-configs-sha256.its
deleted file mode 100644 (file)
index 1b3432e..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/dts-v1/;
-
-/ {
-       description = "Chrome OS kernel image with one or more FDT blobs";
-       #address-cells = <1>;
-
-       images {
-               kernel@1 {
-                       data = /incbin/("test-kernel.bin");
-                       type = "kernel_noload";
-                       arch = "sandbox";
-                       os = "linux";
-                       compression = "none";
-                       load = <0x4>;
-                       entry = <0x8>;
-                       kernel-version = <1>;
-                       hash@1 {
-                               algo = "sha256";
-                       };
-               };
-               fdt@1 {
-                       description = "snow";
-                       data = /incbin/("sandbox-kernel.dtb");
-                       type = "flat_dt";
-                       arch = "sandbox";
-                       compression = "none";
-                       fdt-version = <1>;
-                       hash@1 {
-                               algo = "sha256";
-                       };
-               };
-       };
-       configurations {
-               default = "conf@1";
-               conf@1 {
-                       kernel = "kernel@1";
-                       fdt = "fdt@1";
-                       signature@1 {
-                               algo = "sha256,rsa2048";
-                               key-name-hint = "dev";
-                               sign-images = "fdt", "kernel";
-                       };
-               };
-       };
-};
diff --git a/test/vboot/sign-images-sha1.its b/test/vboot/sign-images-sha1.its
deleted file mode 100644 (file)
index f69326a..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/dts-v1/;
-
-/ {
-       description = "Chrome OS kernel image with one or more FDT blobs";
-       #address-cells = <1>;
-
-       images {
-               kernel@1 {
-                       data = /incbin/("test-kernel.bin");
-                       type = "kernel_noload";
-                       arch = "sandbox";
-                       os = "linux";
-                       compression = "none";
-                       load = <0x4>;
-                       entry = <0x8>;
-                       kernel-version = <1>;
-                       signature@1 {
-                               algo = "sha1,rsa2048";
-                               key-name-hint = "dev";
-                       };
-               };
-               fdt@1 {
-                       description = "snow";
-                       data = /incbin/("sandbox-kernel.dtb");
-                       type = "flat_dt";
-                       arch = "sandbox";
-                       compression = "none";
-                       fdt-version = <1>;
-                       signature@1 {
-                               algo = "sha1,rsa2048";
-                               key-name-hint = "dev";
-                       };
-               };
-       };
-       configurations {
-               default = "conf@1";
-               conf@1 {
-                       kernel = "kernel@1";
-                       fdt = "fdt@1";
-               };
-       };
-};
diff --git a/test/vboot/sign-images-sha256.its b/test/vboot/sign-images-sha256.its
deleted file mode 100644 (file)
index e6aa9fc..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/dts-v1/;
-
-/ {
-       description = "Chrome OS kernel image with one or more FDT blobs";
-       #address-cells = <1>;
-
-       images {
-               kernel@1 {
-                       data = /incbin/("test-kernel.bin");
-                       type = "kernel_noload";
-                       arch = "sandbox";
-                       os = "linux";
-                       compression = "none";
-                       load = <0x4>;
-                       entry = <0x8>;
-                       kernel-version = <1>;
-                       signature@1 {
-                               algo = "sha256,rsa2048";
-                               key-name-hint = "dev";
-                       };
-               };
-               fdt@1 {
-                       description = "snow";
-                       data = /incbin/("sandbox-kernel.dtb");
-                       type = "flat_dt";
-                       arch = "sandbox";
-                       compression = "none";
-                       fdt-version = <1>;
-                       signature@1 {
-                               algo = "sha256,rsa2048";
-                               key-name-hint = "dev";
-                       };
-               };
-       };
-       configurations {
-               default = "conf@1";
-               conf@1 {
-                       kernel = "kernel@1";
-                       fdt = "fdt@1";
-               };
-       };
-};
diff --git a/test/vboot/vboot_test.sh b/test/vboot/vboot_test.sh
deleted file mode 100755 (executable)
index 6d7abb8..0000000
+++ /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
index f72294a98a583fee5cfb43ec15cc61615b7e8e88..421414bc154b0a596cb5833148f2c19c614d5fa9 100644 (file)
@@ -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 (file)
index 0000000..0d20b64
--- /dev/null
@@ -0,0 +1 @@
+*.pyc
diff --git a/tools/dtoc/dtoc b/tools/dtoc/dtoc
new file mode 120000 (symlink)
index 0000000..896ca44
--- /dev/null
@@ -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 (executable)
index 0000000..ec80abe
--- /dev/null
@@ -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 (file)
index 0000000..1d913a9
--- /dev/null
@@ -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 (file)
index 0000000..9ed11e4
--- /dev/null
@@ -0,0 +1,213 @@
+#!/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
+
+        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:
+        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 (file)
index 0000000..929b524
--- /dev/null
@@ -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]
index 692abda7318fc07b2ae7b1fc0b14ef44c2e1f2a0..6b0dcaa943ef9607bbda7d77f6d450dafefc4da8 100644 (file)
@@ -14,6 +14,7 @@
 #include <errno.h>
 #include <env_flags.h>
 #include <fcntl.h>
+#include <linux/fs.h>
 #include <linux/stringify.h>
 #include <ctype.h>
 #include <stdio.h>
@@ -51,7 +52,7 @@ struct env_opts default_opts = {
 
 struct envdev_s {
        const char *devname;            /* Device name */
-       ulong devoff;                   /* Device offset */
+       long long devoff;               /* Device offset */
        ulong env_size;                 /* environment size */
        ulong erase_size;               /* device erase size */
        ulong env_sectors;              /* number of environment sectors */
@@ -121,7 +122,6 @@ static unsigned char obsolete_flag = 0;
 #include <env_default.h>
 
 static int flash_io (int mode);
-static char *envmatch (char * s1, char * s2);
 static int parse_config(struct env_opts *opts);
 
 #if defined(CONFIG_FILE)
@@ -147,6 +147,24 @@ static char *skip_blanks(char *s)
 }
 
 /*
+ * s1 is either a simple 'name', or a 'name=value' pair.
+ * s2 is a 'name=value' pair.
+ * If the names match, return the value of s2, else NULL.
+ */
+static char *envmatch(char *s1, char *s2)
+{
+       if (s1 == NULL || s2 == NULL)
+               return NULL;
+
+       while (*s1 == *s2++)
+               if (*s1++ == '=')
+                       return s2;
+       if (*s1 == '\0' && *(s2 - 1) == '=')
+               return s2;
+       return NULL;
+}
+
+/**
  * Search the environment for a variable.
  * Return the value, if found, or NULL, if not found.
  */
@@ -232,9 +250,14 @@ int parse_aes_key(char *key, uint8_t *bin_key)
  */
 int fw_printenv(int argc, char *argv[], int value_only, struct env_opts *opts)
 {
-       char *env, *nxt;
        int i, rc = 0;
 
+       if (value_only && argc != 1) {
+               fprintf(stderr,
+                       "## Error: `-n' option requires exactly one argument\n");
+               return -1;
+       }
+
        if (!opts)
                opts = &default_opts;
 
@@ -242,6 +265,7 @@ int fw_printenv(int argc, char *argv[], int value_only, struct env_opts *opts)
                return -1;
 
        if (argc == 0) {                /* Print all env variables  */
+               char *env, *nxt;
                for (env = environment.data; *env; env = nxt + 1) {
                        for (nxt = env; *nxt; ++nxt) {
                                if (nxt >= &environment.data[ENV_SIZE]) {
@@ -256,39 +280,23 @@ int fw_printenv(int argc, char *argv[], int value_only, struct env_opts *opts)
                return 0;
        }
 
-       if (value_only && argc != 1) {
-               fprintf(stderr,
-                       "## Error: `-n' option requires exactly one argument\n");
-               return -1;
-       }
-
-       for (i = 0; i < argc; ++i) {    /* print single env variables   */
+       for (i = 0; i < argc; ++i) {    /* print a subset of env variables */
                char *name = argv[i];
                char *val = NULL;
 
-               for (env = environment.data; *env; env = nxt + 1) {
-
-                       for (nxt = env; *nxt; ++nxt) {
-                               if (nxt >= &environment.data[ENV_SIZE]) {
-                                       fprintf (stderr, "## Error: "
-                                               "environment not terminated\n");
-                                       return -1;
-                               }
-                       }
-                       val = envmatch (name, env);
-                       if (val) {
-                               if (!value_only) {
-                                       fputs (name, stdout);
-                                       putc ('=', stdout);
-                               }
-                               puts (val);
-                               break;
-                       }
-               }
+               val = fw_getenv(name);
                if (!val) {
                        fprintf (stderr, "## Error: \"%s\" not defined\n", name);
                        rc = -1;
+                       continue;
+               }
+
+               if (value_only) {
+                       puts(val);
+                       break;
                }
+
+               printf("%s=%s\n", name, val);
        }
 
        return rc;
@@ -483,7 +491,7 @@ int fw_setenv(int argc, char *argv[], struct env_opts *opts)
        valc = argc - 1;
 
        if (env_flags_validate_env_set_params(name, valv, valc) < 0)
-               return 1;
+               return -1;
 
        len = 0;
        for (i = 0; i < valc; ++i) {
@@ -653,8 +661,8 @@ static int flash_bad_block (int fd, uint8_t mtd_type, loff_t *blockstart)
 
                if (badblock) {
 #ifdef DEBUG
-                       fprintf (stderr, "Bad block at 0x%llx, "
-                                "skipping\n", *blockstart);
+                       fprintf (stderr, "Bad block at 0x%llx, skipping\n",
+                               (unsigned long long) *blockstart);
 #endif
                        return badblock;
                }
@@ -741,7 +749,8 @@ static int flash_read_buf (int dev, int fd, void *buf, size_t count,
                }
 #ifdef DEBUG
                fprintf(stderr, "Read 0x%x bytes at 0x%llx on %s\n",
-                        rc, blockstart + block_seek, DEVNAME(dev));
+                       rc, (unsigned long long) blockstart + block_seek,
+                       DEVNAME(dev));
 #endif
                processed += readlen;
                readlen = min (blocklen, count - processed);
@@ -839,8 +848,9 @@ static int flash_write_buf (int dev, int fd, void *buf, size_t count,
                if (block_seek + count != write_total) {
                        if (block_seek != 0)
                                fprintf(stderr, " and ");
-                       fprintf(stderr, "0x%lx - 0x%x",
-                               block_seek + count, write_total - 1);
+                       fprintf(stderr, "0x%lx - 0x%lx",
+                               (unsigned long) block_seek + count,
+                               (unsigned long) write_total - 1);
                }
                fprintf(stderr, "\n");
 #endif
@@ -903,8 +913,9 @@ static int flash_write_buf (int dev, int fd, void *buf, size_t count,
                }
 
 #ifdef DEBUG
-               fprintf(stderr, "Write 0x%x bytes at 0x%llx\n", erasesize,
-                       blockstart);
+               fprintf(stderr, "Write 0x%llx bytes at 0x%llx\n",
+                       (unsigned long long) erasesize,
+                       (unsigned long long) blockstart);
 #endif
                if (write (fd, data + processed, erasesize) != erasesize) {
                        fprintf (stderr, "Write error on %s: %s\n",
@@ -994,7 +1005,7 @@ static int flash_write (int fd_current, int fd_target, int dev_target)
        }
 
 #ifdef DEBUG
-       fprintf(stderr, "Writing new environment at 0x%lx on %s\n",
+       fprintf(stderr, "Writing new environment at 0x%llx on %s\n",
                DEVOFFSET (dev_target), DEVNAME (dev_target));
 #endif
 
@@ -1010,7 +1021,7 @@ static int flash_write (int fd_current, int fd_target, int dev_target)
                        offsetof (struct env_image_redundant, flags);
 #ifdef DEBUG
                fprintf(stderr,
-                       "Setting obsolete flag in environment at 0x%lx on %s\n",
+                       "Setting obsolete flag in environment at 0x%llx on %s\n",
                        DEVOFFSET (dev_current), DEVNAME (dev_current));
 #endif
                flash_flag_obsolete (dev_current, fd_current, offset);
@@ -1021,41 +1032,10 @@ static int flash_write (int fd_current, int fd_target, int dev_target)
 
 static int flash_read (int fd)
 {
-       struct mtd_info_user mtdinfo;
-       struct stat st;
        int rc;
 
-       rc = fstat(fd, &st);
-       if (rc < 0) {
-               fprintf(stderr, "Cannot stat the file %s\n",
-                       DEVNAME(dev_current));
-               return -1;
-       }
-
-       if (S_ISCHR(st.st_mode)) {
-               rc = ioctl(fd, MEMGETINFO, &mtdinfo);
-               if (rc < 0) {
-                       fprintf(stderr, "Cannot get MTD information for %s\n",
-                               DEVNAME(dev_current));
-                       return -1;
-               }
-               if (mtdinfo.type != MTD_NORFLASH &&
-                   mtdinfo.type != MTD_NANDFLASH &&
-                   mtdinfo.type != MTD_DATAFLASH &&
-                   mtdinfo.type != MTD_UBIVOLUME) {
-                       fprintf (stderr, "Unsupported flash type %u on %s\n",
-                                mtdinfo.type, DEVNAME(dev_current));
-                       return -1;
-               }
-       } else {
-               memset(&mtdinfo, 0, sizeof(mtdinfo));
-               mtdinfo.type = MTD_ABSENT;
-       }
-
-       DEVTYPE(dev_current) = mtdinfo.type;
-
        rc = flash_read_buf(dev_current, fd, environment.image, CUR_ENVSIZE,
-                            DEVOFFSET (dev_current), mtdinfo.type);
+                           DEVOFFSET(dev_current), DEVTYPE(dev_current));
        if (rc != CUR_ENVSIZE)
                return -1;
 
@@ -1120,25 +1100,6 @@ exit:
        return rc;
 }
 
-/*
- * s1 is either a simple 'name', or a 'name=value' pair.
- * s2 is a 'name=value' pair.
- * If the names match, return the value of s2, else NULL.
- */
-
-static char *envmatch (char * s1, char * s2)
-{
-       if (s1 == NULL || s2 == NULL)
-               return NULL;
-
-       while (*s1 == *s2++)
-               if (*s1++ == '=')
-                       return s2;
-       if (*s1 == '\0' && *(s2 - 1) == '=')
-               return s2;
-       return NULL;
-}
-
 /*
  * Prevent confusion if running from erased flash memory
  */
@@ -1328,10 +1289,75 @@ int fw_env_open(struct env_opts *opts)
        return 0;
 }
 
+static int check_device_config(int dev)
+{
+       struct stat st;
+       int fd, rc = 0;
+
+       fd = open(DEVNAME(dev), O_RDONLY);
+       if (fd < 0) {
+               fprintf(stderr,
+                       "Cannot open %s: %s\n",
+                       DEVNAME(dev), strerror(errno));
+               return -1;
+       }
+
+       rc = fstat(fd, &st);
+       if (rc < 0) {
+               fprintf(stderr, "Cannot stat the file %s\n",
+                       DEVNAME(dev));
+               goto err;
+       }
+
+       if (S_ISCHR(st.st_mode)) {
+               struct mtd_info_user mtdinfo;
+               rc = ioctl(fd, MEMGETINFO, &mtdinfo);
+               if (rc < 0) {
+                       fprintf(stderr, "Cannot get MTD information for %s\n",
+                               DEVNAME(dev));
+                       goto err;
+               }
+               if (mtdinfo.type != MTD_NORFLASH &&
+                   mtdinfo.type != MTD_NANDFLASH &&
+                   mtdinfo.type != MTD_DATAFLASH &&
+                   mtdinfo.type != MTD_UBIVOLUME) {
+                       fprintf(stderr, "Unsupported flash type %u on %s\n",
+                               mtdinfo.type, DEVNAME(dev));
+                       goto err;
+               }
+               DEVTYPE(dev) = mtdinfo.type;
+       } else {
+               uint64_t size;
+               DEVTYPE(dev) = MTD_ABSENT;
+
+               /*
+                * Check for negative offsets, treat it as backwards offset
+                * from the end of the block device
+                */
+               if (DEVOFFSET(dev) < 0) {
+                       rc = ioctl(fd, BLKGETSIZE64, &size);
+                       if (rc < 0) {
+                               fprintf(stderr, "Could not get block device size on %s\n",
+                                       DEVNAME(dev));
+                               goto err;
+                       }
+
+                       DEVOFFSET(dev) = DEVOFFSET(dev) + size;
+#ifdef DEBUG
+                       fprintf(stderr, "Calculated device offset 0x%llx on %s\n",
+                               DEVOFFSET(dev), DEVNAME(dev));
+#endif
+               }
+       }
+
+err:
+       close(fd);
+       return rc;
+}
 
 static int parse_config(struct env_opts *opts)
 {
-       struct stat st;
+       int rc;
 
        if (!opts)
                opts = &default_opts;
@@ -1375,25 +1401,21 @@ static int parse_config(struct env_opts *opts)
        HaveRedundEnv = 1;
 #endif
 #endif
-       if (stat (DEVNAME (0), &st)) {
-               fprintf (stderr,
-                       "Cannot access MTD device %s: %s\n",
-                       DEVNAME (0), strerror (errno));
-               return -1;
-       }
+       rc = check_device_config(0);
+       if (rc < 0)
+               return rc;
 
-       if (HaveRedundEnv && stat (DEVNAME (1), &st)) {
-               fprintf (stderr,
-                       "Cannot access MTD device %s: %s\n",
-                       DEVNAME (1), strerror (errno));
-               return -1;
-       }
+       if (HaveRedundEnv) {
+               rc = check_device_config(1);
+               if (rc < 0)
+                       return rc;
 
-       if (HaveRedundEnv && ENVSIZE(0) != ENVSIZE(1)) {
-               ENVSIZE(0) = ENVSIZE(1) = min(ENVSIZE(0), ENVSIZE(1));
-               fprintf(stderr,
-                       "Redundant environments have inequal size, set to 0x%08lx\n",
-                       ENVSIZE(1));
+               if (ENVSIZE(0) != ENVSIZE(1)) {
+                       ENVSIZE(0) = ENVSIZE(1) = min(ENVSIZE(0), ENVSIZE(1));
+                       fprintf(stderr,
+                               "Redundant environments have inequal size, set to 0x%08lx\n",
+                               ENVSIZE(1));
+               }
        }
 
        usable_envsize = CUR_ENVSIZE - sizeof(uint32_t);
@@ -1424,12 +1446,12 @@ static int get_config (char *fname)
                if (dump[0] == '#')
                        continue;
 
-               rc = sscanf (dump, "%ms %lx %lx %lx %lx",
-                            &devname,
-                            &DEVOFFSET (i),
-                            &ENVSIZE (i),
-                            &DEVESIZE (i),
-                            &ENVSECTORS (i));
+               rc = sscanf(dump, "%ms %lli %lx %lx %lx",
+                           &devname,
+                           &DEVOFFSET(i),
+                           &ENVSIZE(i),
+                           &DEVESIZE(i),
+                           &ENVSECTORS(i));
 
                if (rc < 3)
                        continue;
index 6f216f9c64c6ec1acf40fcc28fe2af08a4e9ffaf..7916ebdb1f6d1836c49d9374cf4ebfac2bcf0009 100644 (file)
@@ -2,8 +2,9 @@
 # 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
+# Device offset must be prefixed with 0x to be parsed as a hexadecimal value.
 
 # NOR example
 # MTD device name      Device offset   Env. size       Flash sector size       Number of sectors
 # NAND example
 #/dev/mtd0             0x4000          0x4000          0x20000                 2
 
+# On a block device a negative offset is treated as a backwards offset from the
+# end of the device/partition, rather than a forwards offset from the start.
+
 # Block device example
 #/dev/mmcblk0          0xc0000         0x20000
+#/dev/mmcblk0          -0x20000        0x20000
 
 # VFAT example
 #/boot/uboot.env       0x0000          0x4000
index dac964d933fe85a6adf363e47249858b8c0a2f37..436eca9ddc128282ba7709fbd6a1b1af6790ccee 100644 (file)
@@ -67,12 +67,125 @@ struct env_opts {
 
 int parse_aes_key(char *key, uint8_t *bin_key);
 
+/**
+ * fw_printenv() - print one or several environment variables
+ *
+ * @argc: number of variables names to be printed, prints all if 0
+ * @argv: array of variable names to be printed, if argc != 0
+ * @value_only: do not repeat the variable name, print the bare value,
+ *          only one variable allowed with this option, argc must be 1
+ * @opts: encryption key, configuration file, defaults are used if NULL
+ *
+ * Description:
+ *  Uses fw_env_open, fw_getenv
+ *
+ * Return:
+ *  0 on success, -1 on failure (modifies errno)
+ */
 int fw_printenv(int argc, char *argv[], int value_only, struct env_opts *opts);
-char *fw_getenv(char *name);
+
+/**
+ * fw_setenv() - adds or removes one variable to the environment
+ *
+ * @argc: number of strings in argv, argv[0] is variable name,
+ *          argc==1 means erase variable, argc > 1 means add a variable
+ * @argv: argv[0] is variable name, argv[1..argc-1] are concatenated separated
+ *           by single blank and set as the new value of the variable
+ * @opts: how to retrieve environment from flash, defaults are used if NULL
+ *
+ * Description:
+ *  Uses fw_env_open, fw_env_write, fw_env_close
+ *
+ * Return:
+ *  0 on success, -1 on failure (modifies errno)
+ *
+ * ERRORS:
+ *  EROFS - some variables ("ethaddr", "serial#") cannot be modified
+ */
 int fw_setenv(int argc, char *argv[], struct env_opts *opts);
+
+/**
+ * fw_parse_script() - adds or removes multiple variables with a batch script
+ *
+ * @fname: batch script file name
+ * @opts: encryption key, configuration file, defaults are used if NULL
+ *
+ * Description:
+ *  Uses fw_env_open, fw_env_write, fw_env_close
+ *
+ * Return:
+ *  0 success, -1 on failure (modifies errno)
+ *
+ * Script Syntax:
+ *
+ *  key [ [space]+ value]
+ *
+ *  lines starting with '#' treated as comment
+ *
+ *  A variable without value will be deleted. Any number of spaces are allowed
+ *  between key and value. The value starts with the first non-space character
+ *  and ends with newline. No comments allowed on these lines.  Spaces inside
+ *  the value are preserved verbatim.
+ *
+ * Script Example:
+ *
+ *  netdev         eth0
+ *
+ *  kernel_addr    400000
+ *
+ *  foo            spaces           are copied verbatim
+ *
+ *  # delete variable bar
+ *
+ *  bar
+ */
 int fw_parse_script(char *fname, struct env_opts *opts);
+
+
+/**
+ * fw_env_open() - read enviroment from flash into RAM cache
+ *
+ * @opts: encryption key, configuration file, defaults are used if NULL
+ *
+ * Return:
+ *  0 on success, -1 on failure (modifies errno)
+ */
 int fw_env_open(struct env_opts *opts);
+
+/**
+ * fw_getenv() - lookup variable in the RAM cache
+ *
+ * @name: variable to be searched
+ * Return:
+ *  pointer to start of value, NULL if not found
+ */
+char *fw_getenv(char *name);
+
+/**
+ * fw_env_write() - modify a variable held in the RAM cache
+ *
+ * @name: variable
+ * @value: delete variable if NULL, otherwise create or overwrite the variable
+ *
+ * This is called in sequence to update the environment in RAM without updating
+ * the copy in flash after each set
+ *
+ * Return:
+ *  0 on success, -1 on failure (modifies errno)
+ *
+ * ERRORS:
+ *  EROFS - some variables ("ethaddr", "serial#") cannot be modified
+ */
 int fw_env_write(char *name, char *value);
+
+/**
+ * fw_env_close - write the environment from RAM cache back to flash
+ *
+ * @opts: encryption key, configuration file, defaults are used if NULL
+ *
+ * Return:
+ *  0 on success, -1 on failure (modifies errno)
+ */
 int fw_env_close(struct env_opts *opts);
 
 unsigned long crc32(unsigned long, const unsigned char *, unsigned);
index 58aa8e27db3ee19db661bde16ef4675c6ee775ba..10fd6d4929374728732efd63e327cab36275766e 100644 (file)
@@ -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;
        }
 
index 7effb6cea59e2a084e253e26661949f058c8b534..11046952fcf0d4b65cdd85bd1362d5bc43c25c23 100644 (file)
@@ -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;
@@ -236,12 +238,18 @@ static int fit_image_process_sig(const char *keydir, void *keydest,
        /* Get keyname again, as FDT has changed and invalidated our pointer */
        info.keyname = fdt_getprop(fit, noffset, "key-name-hint", NULL);
 
-       /* Write the public key into the supplied FDT file */
-       if (keydest && info.algo->add_verify_data(&info, keydest)) {
-               printf("Failed to add verification data for '%s' signature node in '%s' image node\n",
-                      node_name, image_name);
+       if (keydest)
+               ret = info.algo->add_verify_data(&info, keydest);
+       else
                return -1;
-       }
+
+       /*
+        * Write the public key into the supplied FDT file; this might fail
+        * several times, since we try signing with successively increasing
+        * size values
+        */
+       if (keydest && ret)
+               return ret;
 
        return 0;
 }
@@ -322,7 +330,7 @@ int fit_image_add_verification_data(const char *keydir, void *keydest,
                                comment, require_keys);
                }
                if (ret)
-                       return -1;
+                       return ret;
        }
 
        return 0;
index ff3024a8f172c8557bfaa02612d995bdcdd04f2d..d9939583f5533cd044b32e98b66aa34468dd9157 100644 (file)
@@ -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;
index 27d031ef59c19472c800eec6f73ff4e3e81b7b22..69d5cfb7a8ea8fc66572180d02334e5a8b7d8654 100644 (file)
@@ -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
 
index 72621fd095c69b69e7db9878b17b5bac30e8636b..0a072aa83ce8b8c793d3f1c125c1b929f98df9a6 100644 (file)
@@ -56,6 +56,7 @@ struct spl_info {
 static struct spl_info spl_infos[] = {
        { "rk3036", "RK30", 0x1000 },
        { "rk3288", "RK32", 0x8000 },
+       { "rk3399", "RK33", 0x20000 },
 };
 
 static unsigned char rc4_key[16] = {