]> git.kernelconcepts.de Git - karo-tx-uboot.git/commitdiff
Merge branch 'master' of git://git.denx.de/u-boot-imx
authorTom Rini <trini@ti.com>
Mon, 27 Oct 2014 13:08:42 +0000 (09:08 -0400)
committerTom Rini <trini@ti.com>
Mon, 27 Oct 2014 13:08:42 +0000 (09:08 -0400)
561 files changed:
Makefile
README
arch/Kconfig
arch/arm/Kconfig
arch/arm/cpu/arm926ejs/at91/led.c
arch/arm/cpu/arm926ejs/kirkwood/Makefile
arch/arm/cpu/arm926ejs/kirkwood/cpu.c
arch/arm/cpu/arm926ejs/kirkwood/mpp.c
arch/arm/cpu/armv7/am33xx/board.c
arch/arm/cpu/armv7/armada-xp/Makefile [new file with mode: 0644]
arch/arm/cpu/armv7/armada-xp/cpu.c [new file with mode: 0644]
arch/arm/cpu/armv7/exynos/pinmux.c
arch/arm/cpu/armv7/keystone/Kconfig
arch/arm/cpu/armv7/keystone/Makefile
arch/arm/cpu/armv7/keystone/clock-k2l.c [new file with mode: 0644]
arch/arm/cpu/armv7/keystone/clock.c
arch/arm/cpu/armv7/keystone/cmd_clock.c
arch/arm/cpu/armv7/keystone/cmd_ddr3.c [new file with mode: 0644]
arch/arm/cpu/armv7/keystone/ddr3.c
arch/arm/cpu/armv7/keystone/init.c
arch/arm/cpu/armv7/keystone/msmc.c
arch/arm/cpu/armv7/keystone/spl.c [deleted file]
arch/arm/cpu/armv7/mx6/soc.c
arch/arm/cpu/armv7/omap3/Kconfig
arch/arm/cpu/armv7/omap3/board.c
arch/arm/cpu/armv7/omap3/emif4.c
arch/arm/cpu/armv7/omap3/sys_info.c
arch/arm/cpu/armv7/socfpga/misc.c
arch/arm/cpu/armv7/socfpga/u-boot-spl.lds
arch/arm/cpu/armv7/sunxi/Makefile
arch/arm/cpu/armv7/sunxi/board.c
arch/arm/cpu/armv7/sunxi/clock_sun4i.c
arch/arm/cpu/armv7/sunxi/clock_sun6i.c [new file with mode: 0644]
arch/arm/cpu/armv7/sunxi/cpu_info.c
arch/arm/cpu/armv7/sunxi/dram.c
arch/arm/cpu/armv7/sunxi/prcm.c [new file with mode: 0644]
arch/arm/cpu/armv7/tegra-common/Kconfig
arch/arm/cpu/armv7/tegra20/display.c
arch/arm/cpu/armv7/tegra30/Kconfig
arch/arm/cpu/armv7/uniphier/ph1-ld4/Makefile
arch/arm/cpu/armv7/uniphier/ph1-ld4/platdevice.c [new file with mode: 0644]
arch/arm/cpu/armv7/uniphier/ph1-pro4/Makefile
arch/arm/cpu/armv7/uniphier/ph1-pro4/platdevice.c [new file with mode: 0644]
arch/arm/cpu/armv7/uniphier/ph1-sld8/Makefile
arch/arm/cpu/armv7/uniphier/ph1-sld8/platdevice.c [new file with mode: 0644]
arch/arm/cpu/tegra-common/board.c
arch/arm/cpu/tegra-common/sys_info.c
arch/arm/dts/Makefile
arch/arm/dts/am335x-bone-common.dtsi
arch/arm/dts/dt-bindings/gpio/gpio.h [deleted file]
arch/arm/dts/exynos4.dtsi
arch/arm/dts/exynos4210-origen.dts
arch/arm/dts/exynos4210-pinctrl-uboot.dtsi [new file with mode: 0644]
arch/arm/dts/exynos4210-pinctrl.dtsi [new file with mode: 0644]
arch/arm/dts/exynos4210-smdkv310.dts
arch/arm/dts/exynos4210-trats.dts
arch/arm/dts/exynos4210-universal_c210.dts
arch/arm/dts/exynos4210.dtsi [new file with mode: 0644]
arch/arm/dts/exynos4412-odroid.dts
arch/arm/dts/exynos4412-trats2.dts
arch/arm/dts/exynos4412.dtsi [new file with mode: 0644]
arch/arm/dts/exynos4x12-pinctrl-uboot.dtsi [new file with mode: 0644]
arch/arm/dts/exynos4x12-pinctrl.dtsi [new file with mode: 0644]
arch/arm/dts/exynos4x12.dtsi [new file with mode: 0644]
arch/arm/dts/exynos5.dtsi
arch/arm/dts/exynos5250-pinctrl-uboot.dtsi [new file with mode: 0644]
arch/arm/dts/exynos5250-pinctrl.dtsi [new file with mode: 0644]
arch/arm/dts/exynos5250-smdk5250.dts
arch/arm/dts/exynos5250-snow.dts
arch/arm/dts/exynos5250.dtsi
arch/arm/dts/exynos5420-peach-pit.dts
arch/arm/dts/exynos5420-smdk5420.dts
arch/arm/dts/exynos54xx-pinctrl-uboot.dtsi [new file with mode: 0644]
arch/arm/dts/exynos54xx-pinctrl.dtsi [new file with mode: 0644]
arch/arm/dts/exynos54xx.dtsi
arch/arm/dts/s5pc100-pinctrl.dtsi [new file with mode: 0644]
arch/arm/dts/s5pc110-pinctrl.dtsi [new file with mode: 0644]
arch/arm/dts/s5pc1xx-goni.dts
arch/arm/dts/s5pc1xx-smdkc100.dts
arch/arm/dts/tegra20-trimslice.dts
arch/arm/dts/tegra30-apalis.dts [new file with mode: 0644]
arch/arm/dts/tegra30-beaver.dts
arch/arm/dts/tegra30-cardhu.dts
arch/arm/dts/tegra30-colibri.dts
arch/arm/imx-common/cpu.c
arch/arm/imx-common/i2c-mxv7.c
arch/arm/imx-common/misc.c
arch/arm/include/asm/arch-am33xx/mux.h
arch/arm/include/asm/arch-armada-xp/config.h [new file with mode: 0644]
arch/arm/include/asm/arch-armada-xp/cpu.h [new file with mode: 0644]
arch/arm/include/asm/arch-armada-xp/soc.h [new file with mode: 0644]
arch/arm/include/asm/arch-bcm2835/gpio.h
arch/arm/include/asm/arch-bcm2835/mbox.h
arch/arm/include/asm/arch-exynos/gpio.h
arch/arm/include/asm/arch-keystone/clock-k2e.h
arch/arm/include/asm/arch-keystone/clock-k2hk.h
arch/arm/include/asm/arch-keystone/clock-k2l.h [new file with mode: 0644]
arch/arm/include/asm/arch-keystone/clock.h
arch/arm/include/asm/arch-keystone/ddr3.h
arch/arm/include/asm/arch-keystone/emac_defs.h [deleted file]
arch/arm/include/asm/arch-keystone/hardware-k2e.h
arch/arm/include/asm/arch-keystone/hardware-k2hk.h
arch/arm/include/asm/arch-keystone/hardware-k2l.h [new file with mode: 0644]
arch/arm/include/asm/arch-keystone/hardware.h
arch/arm/include/asm/arch-keystone/msmc.h
arch/arm/include/asm/arch-keystone/spl.h [deleted file]
arch/arm/include/asm/arch-keystone/xhci-keystone.h [new file with mode: 0644]
arch/arm/include/asm/arch-kirkwood/config.h
arch/arm/include/asm/arch-kirkwood/cpu.h
arch/arm/include/asm/arch-kirkwood/gpio.h
arch/arm/include/asm/arch-kirkwood/soc.h [moved from arch/arm/include/asm/arch-kirkwood/kirkwood.h with 90% similarity]
arch/arm/include/asm/arch-ls102xa/config.h
arch/arm/include/asm/arch-mvebu/spi.h [moved from arch/arm/include/asm/arch-kirkwood/spi.h with 100% similarity]
arch/arm/include/asm/arch-mxs/sys_proto.h
arch/arm/include/asm/arch-omap3/mux.h
arch/arm/include/asm/arch-omap3/sys_proto.h
arch/arm/include/asm/arch-s5pc1xx/gpio.h
arch/arm/include/asm/arch-socfpga/spl.h [deleted file]
arch/arm/include/asm/arch-sunxi/clock.h
arch/arm/include/asm/arch-sunxi/clock_sun4i.h
arch/arm/include/asm/arch-sunxi/clock_sun6i.h [new file with mode: 0644]
arch/arm/include/asm/arch-sunxi/cpu.h
arch/arm/include/asm/arch-sunxi/gpio.h
arch/arm/include/asm/arch-sunxi/mmc.h
arch/arm/include/asm/arch-sunxi/prcm.h [new file with mode: 0644]
arch/arm/include/asm/arch-sunxi/timer.h
arch/arm/include/asm/arch-sunxi/watchdog.h [new file with mode: 0644]
arch/arm/include/asm/arch-tegra/board.h
arch/arm/include/asm/arch-tegra114/mc.h [new file with mode: 0644]
arch/arm/include/asm/arch-tegra114/tegra.h
arch/arm/include/asm/arch-tegra114/tegra114_spi.h [deleted file]
arch/arm/include/asm/arch-tegra20/mc.h [new file with mode: 0644]
arch/arm/include/asm/arch-tegra20/tegra.h
arch/arm/include/asm/arch-tegra20/tegra20_sflash.h [deleted file]
arch/arm/include/asm/arch-tegra20/tegra20_slink.h [deleted file]
arch/arm/include/asm/arch-tegra30/mc.h [new file with mode: 0644]
arch/arm/include/asm/arch-tegra30/tegra.h
arch/arm/include/asm/arch-uniphier/platdevice.h [new file with mode: 0644]
arch/arm/include/asm/imx-common/mxc_i2c.h
arch/arm/include/asm/mach-types.h
arch/arm/include/asm/omap_gpio.h
arch/arm/include/asm/spl.h
arch/arm/include/asm/ti-common/keystone_nav.h [moved from arch/arm/include/asm/arch-keystone/keystone_nav.h with 91% similarity]
arch/arm/include/asm/ti-common/keystone_net.h [new file with mode: 0644]
arch/arm/include/asm/ti-common/keystone_serdes.h [new file with mode: 0644]
arch/arm/include/asm/ti-common/ti-edma3.h [new file with mode: 0644]
arch/arm/include/asm/u-boot-arm.h
arch/arm/lib/board.c
arch/arm/lib/bootm.c
arch/arm/lib/interrupts.c
arch/arm/mvebu-common/Makefile [new file with mode: 0644]
arch/arm/mvebu-common/dram.c [moved from arch/arm/cpu/arm926ejs/kirkwood/dram.c with 57% similarity]
arch/arm/mvebu-common/gpio.c [new file with mode: 0644]
arch/arm/mvebu-common/mbus.c [new file with mode: 0644]
arch/arm/mvebu-common/timer.c [moved from arch/arm/cpu/arm926ejs/kirkwood/timer.c with 63% similarity]
arch/mips/Kconfig
arch/powerpc/cpu/mpc85xx/cpu_init.c
arch/powerpc/cpu/mpc85xx/fdt.c
arch/powerpc/cpu/mpc85xx/liodn.c
arch/powerpc/cpu/mpc8xxx/fdt.c
arch/powerpc/include/asm/config_mpc85xx.h
arch/powerpc/include/asm/immap_85xx.h
arch/powerpc/include/asm/types.h
arch/sandbox/dts/sandbox.dts
arch/sandbox/include/asm/spi.h
arch/sandbox/include/asm/state.h
arch/x86/Kconfig
arch/x86/config.mk
arch/x86/cpu/Makefile
arch/x86/cpu/start.S
arch/x86/cpu/start16.S
arch/x86/dts/coreboot.dtsi
arch/x86/dts/link.dts
arch/x86/include/asm/arch-coreboot/gpio.h [new file with mode: 0644]
arch/x86/include/asm/bootm.h [new file with mode: 0644]
arch/x86/include/asm/config.h
arch/x86/include/asm/gpio.h
arch/x86/include/asm/ibmpc.h
arch/x86/lib/Makefile
arch/x86/lib/bootm.c
arch/x86/lib/zimage.c
board/8dtech/eco5pk/eco5pk.h
board/LaCie/net2big_v2/net2big_v2.c
board/LaCie/netspace_v2/netspace_v2.c
board/LaCie/wireless_space/wireless_space.c
board/Marvell/db-mv784mp-gp/Kconfig [new file with mode: 0644]
board/Marvell/db-mv784mp-gp/MAINTAINERS [new file with mode: 0644]
board/Marvell/db-mv784mp-gp/Makefile [new file with mode: 0644]
board/Marvell/db-mv784mp-gp/db-mv784mp-gp.c [new file with mode: 0644]
board/Marvell/db-mv784mp-gp/kwbimage.cfg [new file with mode: 0644]
board/Marvell/dreamplug/dreamplug.c
board/Marvell/guruplug/guruplug.c
board/Marvell/mv88f6281gtw_ge/mv88f6281gtw_ge.c
board/Marvell/openrd/openrd.c
board/Marvell/rd6281a/rd6281a.c
board/Marvell/sheevaplug/sheevaplug.c
board/Seagate/dockstar/dockstar.c
board/Seagate/goflexhome/goflexhome.c
board/atmel/at91rm9200ek/led.c
board/atmel/at91sam9260ek/led.c
board/buffalo/lsxl/lsxl.c
board/chromebook-x86/coreboot/Makefile
board/chromebook-x86/coreboot/coreboot.c [new file with mode: 0644]
board/cloudengines/pogo_e02/pogo_e02.c
board/compulab/cm_fx6/cm_fx6.c
board/compulab/cm_t35/cm_t35.c
board/d-link/dns325/dns325.c
board/freescale/ls1021aqds/MAINTAINERS
board/freescale/ls1021aqds/ls1021aqds.c
board/freescale/ls1021atwr/MAINTAINERS
board/freescale/ls1021atwr/ls1021atwr.c
board/htkw/mcx/mcx.h
board/iomega/iconnect/iconnect.c
board/isee/igep00x0/igep00x0.c
board/karo/tk71/tk71.c
board/keymile/km_arm/km_arm.c
board/logicpd/am3517evm/am3517evm.h
board/logicpd/omap3som/omap3logic.c
board/logicpd/zoom1/zoom1.c
board/maxbcm/Kconfig [new file with mode: 0644]
board/maxbcm/MAINTAINERS [new file with mode: 0644]
board/maxbcm/Makefile [new file with mode: 0644]
board/maxbcm/kwbimage.cfg [new file with mode: 0644]
board/maxbcm/maxbcm.c [new file with mode: 0644]
board/nvidia/common/board.c
board/nvidia/common/emc.c
board/nvidia/jetson-tk1/pinmux-config-jetson-tk1.h
board/nvidia/seaboard/seaboard.c
board/overo/overo.c
board/overo/overo.h
board/pandora/pandora.h
board/raidsonic/ib62x0/ib62x0.c
board/raspberrypi/rpi_b/rpi_b.c
board/renesas/sh7752evb/sh7752evb.c
board/renesas/sh7753evb/sh7753evb.c
board/renesas/sh7757lcr/sh7757lcr.c
board/samsung/arndale/arndale.c
board/samsung/common/board.c
board/samsung/common/misc.c
board/samsung/goni/goni.c
board/samsung/origen/origen.c
board/samsung/smdk5250/exynos5-dt.c
board/samsung/smdk5420/smdk5420.c
board/samsung/smdkc100/smdkc100.c
board/samsung/smdkv310/smdkv310.c
board/samsung/trats/trats.c
board/samsung/trats2/trats2.c
board/samsung/universal_c210/universal.c
board/sunxi/Kconfig
board/sunxi/MAINTAINERS
board/sunxi/Makefile
board/sunxi/board.c
board/sunxi/dram_a20_olinuxino_l2.c [new file with mode: 0644]
board/technexion/tao3530/tao3530.h
board/technexion/twister/twister.c
board/technexion/twister/twister.h
board/teejet/mt_ventoux/mt_ventoux.h
board/ti/am335x/mux.c
board/ti/am3517crane/am3517crane.h
board/ti/beagle/beagle.c
board/ti/beagle/led.c
board/ti/evm/evm.h
board/ti/ks2_evm/Kconfig
board/ti/ks2_evm/MAINTAINERS
board/ti/ks2_evm/Makefile
board/ti/ks2_evm/board.c
board/ti/ks2_evm/board.h
board/ti/ks2_evm/board_k2e.c
board/ti/ks2_evm/board_k2hk.c
board/ti/ks2_evm/board_k2l.c [new file with mode: 0644]
board/ti/ks2_evm/ddr3_cfg.c
board/ti/ks2_evm/ddr3_cfg.h
board/ti/ks2_evm/ddr3_k2hk.c
board/ti/ks2_evm/ddr3_k2l.c [new file with mode: 0644]
board/ti/sdp3430/sdp.h
board/toradex/apalis_t30/Kconfig [new file with mode: 0644]
board/toradex/apalis_t30/MAINTAINERS [new file with mode: 0644]
board/toradex/apalis_t30/Makefile [new file with mode: 0644]
board/toradex/apalis_t30/apalis_t30.c [new file with mode: 0644]
board/toradex/apalis_t30/pinmux-config-apalis_t30.h [new file with mode: 0644]
board/toradex/colibri_t30/colibri_t30.c
board/w7o/fsboot.c
common/Makefile
common/board_f.c
common/board_r.c
common/bootm.c
common/cmd_blob.c [new file with mode: 0644]
common/cmd_bootm.c
common/cmd_elf.c
common/cmd_gpio.c
common/cmd_sf.c
common/cmd_spi.c
common/console.c
common/cros_ec.c
common/env_nand.c
common/env_sf.c
common/exports.c
common/image-fit.c
common/image.c
common/lcd.c
common/menu.c
common/modem.c
common/stdio.c
config.mk
configs/A10s-OLinuXino-M_defconfig
configs/A20-OLinuXino-Lime2_defconfig [new file with mode: 0644]
configs/A20-OLinuXino_MICRO_defconfig
configs/Colombus_defconfig [new file with mode: 0644]
configs/Ippo_q8h_defconfig [new file with mode: 0644]
configs/Mele_M3_defconfig [new file with mode: 0644]
configs/am335x_boneblack_defconfig
configs/am335x_boneblack_vboot_defconfig
configs/apalis_t30_defconfig [new file with mode: 0644]
configs/db-mv784mp-gp_defconfig [new file with mode: 0644]
configs/k2l_evm_defconfig [new file with mode: 0644]
configs/ls1021aqds_nor_SECURE_BOOT_defconfig [new file with mode: 0644]
configs/ls1021atwr_nor_SECURE_BOOT_defconfig [new file with mode: 0644]
configs/maxbcm_defconfig [new file with mode: 0644]
configs/ph1_ld4_defconfig
configs/ph1_pro4_defconfig
configs/ph1_sld8_defconfig
disk/part.c
doc/device-tree-bindings/mtd/spi/spi-flash.txt [new file with mode: 0644]
doc/device-tree-bindings/spi/soft-spi.txt [new file with mode: 0644]
doc/driver-model/README.txt
doc/driver-model/spi-howto.txt [new file with mode: 0644]
doc/uImage.FIT/kernel.its
doc/uImage.FIT/source_file_format.txt
doc/uImage.FIT/x86-fit-boot.txt [new file with mode: 0644]
drivers/Makefile
drivers/block/mvsata_ide.c
drivers/core/Kconfig
drivers/core/Makefile
drivers/core/device.c
drivers/core/lists.c
drivers/core/simple-bus.c [new file with mode: 0644]
drivers/core/uclass.c
drivers/crypto/Makefile
drivers/crypto/fsl/Makefile [new file with mode: 0644]
drivers/crypto/fsl/desc.h [new file with mode: 0644]
drivers/crypto/fsl/desc_constr.h [new file with mode: 0644]
drivers/crypto/fsl/error.c [new file with mode: 0644]
drivers/crypto/fsl/fsl_blob.c [new file with mode: 0644]
drivers/crypto/fsl/fsl_hash.c [new file with mode: 0644]
drivers/crypto/fsl/jobdesc.c [new file with mode: 0644]
drivers/crypto/fsl/jobdesc.h [new file with mode: 0644]
drivers/crypto/fsl/jr.c [new file with mode: 0644]
drivers/crypto/fsl/jr.h [new file with mode: 0644]
drivers/dfu/dfu_sf.c
drivers/dma/Makefile
drivers/dma/keystone_nav.c [moved from arch/arm/cpu/armv7/keystone/keystone_nav.c with 53% similarity]
drivers/dma/keystone_nav_cfg.c [new file with mode: 0644]
drivers/dma/ti-edma3.c [new file with mode: 0644]
drivers/gpio/Kconfig
drivers/gpio/bcm2835_gpio.c
drivers/gpio/gpio-uclass.c
drivers/gpio/intel_ich6_gpio.c
drivers/gpio/kw_gpio.c
drivers/gpio/mxc_gpio.c
drivers/gpio/omap_gpio.c
drivers/gpio/s5p_gpio.c
drivers/gpio/sandbox.c
drivers/gpio/tegra_gpio.c
drivers/i2c/designware_i2c.c
drivers/i2c/mvtwsi.c
drivers/i2c/tegra_i2c.c
drivers/input/tegra-kbc.c
drivers/misc/cros_ec.c
drivers/misc/cros_ec_lpc.c
drivers/misc/cros_ec_sandbox.c
drivers/misc/cros_ec_spi.c
drivers/mmc/bcm2835_sdhci.c
drivers/mmc/mvebu_mmc.c
drivers/mmc/omap_hsmmc.c
drivers/mmc/s5p_sdhci.c
drivers/mmc/sdhci.c
drivers/mmc/sunxi_mmc.c
drivers/mmc/tegra_mmc.c
drivers/mtd/cfi_flash.c
drivers/mtd/nand/kirkwood_nand.c
drivers/mtd/nand/omap_gpmc.c
drivers/mtd/spi/Makefile
drivers/mtd/spi/ramtron.c
drivers/mtd/spi/sandbox.c
drivers/mtd/spi/sf-uclass.c [new file with mode: 0644]
drivers/mtd/spi/sf_internal.h
drivers/mtd/spi/sf_params.c
drivers/mtd/spi/sf_probe.c
drivers/mtd/spi/spi_spl_load.c
drivers/net/Makefile
drivers/net/davinci_emac.c
drivers/net/fec_mxc.c
drivers/net/keystone_net.c
drivers/net/mvgbe.c
drivers/net/mvneta.c [new file with mode: 0644]
drivers/net/phy/phy.c
drivers/pci/pci.c
drivers/rtc/mvrtc.h
drivers/serial/Kconfig
drivers/serial/Makefile
drivers/serial/ns16550.c
drivers/serial/serial-uclass.c
drivers/serial/serial.c
drivers/serial/serial_coreboot.c [new file with mode: 0644]
drivers/serial/serial_mxc.c
drivers/serial/serial_ns16550.c
drivers/serial/serial_omap.c [new file with mode: 0644]
drivers/serial/serial_pl01x.c
drivers/serial/serial_pl01x_internal.h [moved from drivers/serial/serial_pl01x.h with 100% similarity]
drivers/serial/serial_s3c24x0.c
drivers/serial/serial_s5p.c
drivers/serial/serial_sh.c
drivers/serial/serial_uniphier.c
drivers/soc/Makefile [new file with mode: 0644]
drivers/soc/keystone/Makefile [new file with mode: 0644]
drivers/soc/keystone/keystone_serdes.c [new file with mode: 0644]
drivers/spi/Kconfig
drivers/spi/Makefile
drivers/spi/exynos_spi.c
drivers/spi/fdt_spi.c [deleted file]
drivers/spi/kirkwood_spi.c
drivers/spi/sandbox_spi.c
drivers/spi/soft_spi.c
drivers/spi/soft_spi_legacy.c [new file with mode: 0644]
drivers/spi/spi-emul-uclass.c [new file with mode: 0644]
drivers/spi/spi-uclass.c [new file with mode: 0644]
drivers/spi/tegra114_spi.c
drivers/spi/tegra20_sflash.c
drivers/spi/tegra20_slink.c
drivers/spi/tegra_spi.h [new file with mode: 0644]
drivers/usb/eth/asix.c
drivers/usb/host/Makefile
drivers/usb/host/dwc2.c [new file with mode: 0644]
drivers/usb/host/dwc2.h [new file with mode: 0644]
drivers/usb/host/ehci-hcd.c
drivers/usb/host/ehci-marvell.c
drivers/usb/host/xhci-keystone.c [new file with mode: 0644]
drivers/video/cfb_console.c
drivers/video/exynos_fb.c
drivers/video/ipu_common.c
drivers/video/ipu_disp.c
drivers/video/mxc_ipuv3_fb.c
include/asm-generic/gpio.h
include/bootm.h
include/bootstage.h
include/common.h
include/config_fallbacks.h
include/configs/B4860QDS.h
include/configs/BSC9131RDB.h
include/configs/BSC9132QDS.h
include/configs/C29XPCIE.h
include/configs/P1010RDB.h
include/configs/P2041RDB.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/am335x_evm.h
include/configs/am43xx_evm.h
include/configs/apalis_t30.h [new file with mode: 0644]
include/configs/cm_fx6.h
include/configs/colibri_t30.h
include/configs/coreboot.h
include/configs/corenet_ds.h
include/configs/db-mv784mp-gp.h [new file with mode: 0644]
include/configs/edb93xx.h
include/configs/exynos-common.h
include/configs/k2e_evm.h
include/configs/k2hk_evm.h
include/configs/k2l_evm.h [new file with mode: 0644]
include/configs/ks2_evm.h
include/configs/ls1021aqds.h
include/configs/ls1021atwr.h
include/configs/ls2085a_common.h
include/configs/maxbcm.h [new file with mode: 0644]
include/configs/omap3_overo.h
include/configs/peach-pit.h
include/configs/ph1_ld4.h
include/configs/ph1_pro4.h
include/configs/ph1_sld8.h
include/configs/rpi_b.h
include/configs/s5p_goni.h
include/configs/s5pc210_universal.h
include/configs/sacsng.h
include/configs/sandbox.h
include/configs/smdkc100.h
include/configs/socfpga_common.h
include/configs/socfpga_cyclone5.h
include/configs/sun4i.h
include/configs/sun5i.h
include/configs/sun6i.h [new file with mode: 0644]
include/configs/sun7i.h
include/configs/sun8i.h [new file with mode: 0644]
include/configs/sunxi-common.h
include/configs/tegra-common-post.h
include/configs/tegra-common.h
include/configs/ti_am335x_common.h
include/configs/ti_omap3_common.h
include/configs/tqma6.h
include/configs/uniphier-common.h
include/configs/zipitz2.h
include/cros_ec.h
include/dm/device-internal.h
include/dm/device.h
include/dm/lists.h
include/dm/platdata.h
include/dm/platform_data/serial-uniphier.h [new file with mode: 0644]
include/dm/platform_data/serial_mxc.h [new file with mode: 0644]
include/dm/platform_data/serial_pl01x.h [new file with mode: 0644]
include/dm/test.h
include/dm/uclass-id.h
include/dm/uclass.h
include/dm/util.h
include/dt-bindings/pinctrl/am33xx.h [moved from arch/arm/dts/dt-bindings/pinctrl/am33xx.h with 100% similarity]
include/dt-bindings/pinctrl/omap.h [moved from arch/arm/dts/dt-bindings/pinctrl/omap.h with 100% similarity]
include/elf.h
include/fdt_support.h
include/fdtdec.h
include/fsl_sec.h [new file with mode: 0644]
include/ide.h
include/image.h
include/libfdt.h
include/linker_lists.h
include/linux/mbus.h [new file with mode: 0644]
include/linux/string.h
include/linux/usb/dwc3.h
include/linux/usb/musb.h
include/mmc.h
include/netdev.h
include/ns16550.h
include/phy.h
include/spi.h
include/spi_flash.h
include/spl.h
include/usb.h
lib/Kconfig
lib/fdtdec.c
lib/initcall.c
lib/libfdt/fdt_ro.c
lib/lmb.c
lib/time.c
net/eth.c
net/tftp.c
post/post.c
scripts/Makefile.spl
scripts/multiconfig.sh
test/dm/Makefile
test/dm/bus.c
test/dm/core.c
test/dm/gpio.c
test/dm/sf.c [new file with mode: 0644]
test/dm/spi.c [new file with mode: 0644]
test/dm/test-dm.sh
test/dm/test-main.c
test/dm/test.dts
tools/Makefile
tools/kwbimage.c
tools/kwboot.c
tools/socfpgaimage.c

index 99097e1e57288ebab699a4678f3635f36f67837c..26dacee98e07d0c203e0156bae557ea95a006d29 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -652,6 +652,10 @@ ifneq (,$(filter $(SOC), mx25 mx27 mx5 mx6 mx31 mx35 mxs vf610))
 libs-y += arch/$(ARCH)/imx-common/
 endif
 
+ifneq (,$(filter $(SOC), armada-xp kirkwood))
+libs-y += arch/$(ARCH)/mvebu-common/
+endif
+
 libs-$(CONFIG_ARM) += arch/arm/cpu/
 libs-$(CONFIG_PPC) += arch/powerpc/cpu/
 
@@ -670,13 +674,9 @@ u-boot-main := $(libs-y)
 
 
 # Add GCC lib
-ifdef CONFIG_USE_PRIVATE_LIBGCC
 ifeq ($(CONFIG_USE_PRIVATE_LIBGCC),y)
 PLATFORM_LIBGCC = arch/$(ARCH)/lib/lib.a
 else
-PLATFORM_LIBGCC = -L $(CONFIG_USE_PRIVATE_LIBGCC) -lgcc
-endif
-else
 PLATFORM_LIBGCC := -L $(shell dirname `$(CC) $(c_flags) -print-libgcc-file-name`) -lgcc
 endif
 PLATFORM_LIBS += $(PLATFORM_LIBGCC)
@@ -754,6 +754,11 @@ endif
 endif
 endif
 
+# Add optional build target if defined in board/cpu/soc headers
+ifneq ($(CONFIG_BUILD_TARGET),)
+ALL-y += $(CONFIG_BUILD_TARGET:"%"=%)
+endif
+
 LDFLAGS_u-boot += $(LDFLAGS_FINAL)
 ifneq ($(CONFIG_SYS_TEXT_BASE),)
 LDFLAGS_u-boot += -Ttext $(CONFIG_SYS_TEXT_BASE)
diff --git a/README b/README
index 46def0086b8f3d95c77a78bda532eacdbab91c6e..2808dd1eb9a27cdacadb86f1a2dd9eb26121ec29 100644 (file)
--- a/README
+++ b/README
@@ -544,6 +544,12 @@ The following options need to be configured:
                CONFIG_SYS_FSL_OTHER_DDR_NUM_CTRLS
                Number of controllers used for other than main memory.
 
+               CONFIG_SYS_FSL_SEC_BE
+               Defines the SEC controller register space as Big Endian
+
+               CONFIG_SYS_FSL_SEC_LE
+               Defines the SEC controller register space as Little Endian
+
 - Intel Monahans options:
                CONFIG_SYS_MONAHANS_RUN_MODE_OSC_RATIO
 
@@ -617,13 +623,6 @@ The following options need to be configured:
                exists, unlike the similar options in the Linux kernel. Do not
                set these options unless they apply!
 
-- CPU timer options:
-               CONFIG_SYS_HZ
-
-               The frequency of the timer returned by get_timer().
-               get_timer() must operate in milliseconds and this CONFIG
-               option must be set to 1000.
-
 - Linux Kernel Interface:
                CONFIG_CLOCKS_IN_MHZ
 
@@ -1459,6 +1458,9 @@ The following options need to be configured:
                CONFIG_USB_EHCI_TXFIFO_THRESH enables setting of the
                txfilltuning field in the EHCI controller on reset.
 
+               CONFIG_USB_DWC2_REG_ADDR the physical CPU address of the DWC2
+               HW module registers.
+
 - USB Device:
                Define the below if you wish to use the USB console.
                Once firmware is rebuilt from a serial console issue the
@@ -2716,6 +2718,14 @@ CBFS (Coreboot Filesystem) support
                200 ms.
 
 - Configuration Management:
+               CONFIG_BUILD_TARGET
+
+               Some SoCs need special image types (e.g. U-Boot binary
+               with a special header) as build targets. By defining
+               CONFIG_BUILD_TARGET in the SoC / board header, this
+               special image will be automatically built upon calling
+               make / MAKEALL.
+
                CONFIG_IDENT_STRING
 
                If defined, this string will be added to the U-Boot
@@ -2824,10 +2834,6 @@ CBFS (Coreboot Filesystem) support
 
                Enable auto completion of commands using TAB.
 
-               Note that this feature has NOT been implemented yet
-               for the "hush" shell.
-
-
                CONFIG_SYS_HUSH_PARSER
 
                Define this variable to enable the "hush" shell (from
index bf2676469c7131dd924139cf42dd392b0902bbc3..f63cc5a7e9440416c351e612eb5c8615693aa037 100644 (file)
@@ -7,6 +7,7 @@ config ARC
 
 config ARM
        bool "ARM architecture"
+       select HAVE_PRIVATE_LIBGCC
        select SUPPORT_OF_CONTROL
 
 config AVR32
@@ -24,6 +25,7 @@ config MICROBLAZE
 
 config MIPS
        bool "MIPS architecture"
+       select HAVE_PRIVATE_LIBGCC
 
 config NDS32
        bool "NDS32 architecture"
@@ -36,6 +38,7 @@ config OPENRISC
 
 config PPC
        bool "PowerPC architecture"
+       select HAVE_PRIVATE_LIBGCC
 
 config SANDBOX
        bool "Sandbox"
@@ -43,12 +46,14 @@ config SANDBOX
 
 config SH
        bool "SuperH architecture"
+       select HAVE_PRIVATE_LIBGCC
 
 config SPARC
        bool "SPARC architecture"
 
 config X86
        bool "x86 architecture"
+       select HAVE_PRIVATE_LIBGCC
        select SUPPORT_OF_CONTROL
 
 endchoice
index 72558b85620a638c2945a58ccb3ebbc1faea06b6..8f910f39a37ec5350d094070fdfdd6a2986519b8 100644 (file)
@@ -141,6 +141,12 @@ config ARCH_DAVINCI
 config KIRKWOOD
        bool "Marvell Kirkwood"
 
+config TARGET_DB_MV784MP_GP
+       bool "Support db-mv784mp-gp"
+
+config TARGET_MAXBCM
+       bool "Support maxbcm"
+
 config TARGET_DEVKIT3250
        bool "Support devkit3250"
 
@@ -444,9 +450,15 @@ config TARGET_SUN4I
 config TARGET_SUN5I
        bool "Support sun5i"
 
+config TARGET_SUN6I
+       bool "Support sun6i"
+
 config TARGET_SUN7I
        bool "Support sun7i"
 
+config TARGET_SUN8I
+       bool "Support sun8i"
+
 config TARGET_SNOWBALL
        bool "Support snowball"
 
@@ -567,6 +579,7 @@ source "board/BuS/eb_cpux9k2/Kconfig"
 source "board/BuS/vl_ma2sc/Kconfig"
 source "board/CarMediaLab/flea3/Kconfig"
 source "board/Marvell/aspenite/Kconfig"
+source "board/Marvell/db-mv784mp-gp/Kconfig"
 source "board/Marvell/dkb/Kconfig"
 source "board/Marvell/gplugd/Kconfig"
 source "board/afeb9260/Kconfig"
@@ -648,6 +661,7 @@ source "board/jornada/Kconfig"
 source "board/karo/tx25/Kconfig"
 source "board/logicpd/imx27lite/Kconfig"
 source "board/logicpd/imx31_litekit/Kconfig"
+source "board/maxbcm/Kconfig"
 source "board/mpl/vcma9/Kconfig"
 source "board/olimex/mx23_olinuxino/Kconfig"
 source "board/palmld/Kconfig"
index 46ed055023978aee455ccfdb74155c31705ebb41..b8d5c785df4d36557168e3f178738fdc9f717006 100644 (file)
@@ -9,6 +9,7 @@
 #include <common.h>
 #include <asm/gpio.h>
 #include <asm/arch/gpio.h>
+#include <status_led.h>
 
 #ifdef CONFIG_RED_LED
 void red_led_on(void)
index c230ce8994e7f5ec3e0b069758f5982d89190cd1..df4756e4bdb1fd072e5356a65e9d4ec7e51b54fa 100644 (file)
@@ -7,7 +7,5 @@
 #
 
 obj-y  = cpu.o
-obj-y  += dram.o
-obj-y  += mpp.o
-obj-y  += timer.o
 obj-y  += cache.o
+obj-y  += mpp.o
index 881e2de81b328ca71d106a0bdd8630202537268d..9e412bbb04d585c949f321ddd04032a652a92e00 100644 (file)
@@ -9,14 +9,11 @@
 #include <common.h>
 #include <netdev.h>
 #include <asm/cache.h>
-#include <u-boot/md5.h>
 #include <asm/io.h>
 #include <asm/arch/cpu.h>
-#include <asm/arch/kirkwood.h>
+#include <asm/arch/soc.h>
 #include <mvebu_mmc.h>
 
-#define BUFLEN 16
-
 void reset_cpu(unsigned long ignored)
 {
        struct kwcpu_registers *cpureg =
@@ -29,31 +26,6 @@ void reset_cpu(unsigned long ignored)
        while (1) ;
 }
 
-/*
- * Generates Ramdom hex number reading some time varient system registers
- * and using md5 algorithm
- */
-unsigned char get_random_hex(void)
-{
-       int i;
-       u32 inbuf[BUFLEN];
-       u8 outbuf[BUFLEN];
-
-       /*
-        * in case of 88F6281/88F6282/88F6192 A0,
-        * Bit7 need to reset to generate random values in KW_REG_UNDOC_0x1470
-        * Soc reg offsets KW_REG_UNDOC_0x1470 and KW_REG_UNDOC_0x1478 are
-        * reserved regs and does not have names at this moment
-        * (no errata available)
-        */
-       writel(readl(KW_REG_UNDOC_0x1478) & ~(1 << 7), KW_REG_UNDOC_0x1478);
-       for (i = 0; i < BUFLEN; i++) {
-               inbuf[i] = readl(KW_REG_UNDOC_0x1470);
-       }
-       md5((u8 *) inbuf, (BUFLEN * sizeof(u32)), outbuf);
-       return outbuf[outbuf[7] % 0x0f];
-}
-
 /*
  * Window Size
  * Used with the Base register to set the address window size and location.
@@ -139,50 +111,6 @@ int kw_config_adr_windows(void)
        return 0;
 }
 
-/*
- * kw_config_gpio - GPIO configuration
- */
-void kw_config_gpio(u32 gpp0_oe_val, u32 gpp1_oe_val, u32 gpp0_oe, u32 gpp1_oe)
-{
-       struct kwgpio_registers *gpio0reg =
-               (struct kwgpio_registers *)KW_GPIO0_BASE;
-       struct kwgpio_registers *gpio1reg =
-               (struct kwgpio_registers *)KW_GPIO1_BASE;
-
-       /* Init GPIOS to default values as per board requirement */
-       writel(gpp0_oe_val, &gpio0reg->dout);
-       writel(gpp1_oe_val, &gpio1reg->dout);
-       writel(gpp0_oe, &gpio0reg->oe);
-       writel(gpp1_oe, &gpio1reg->oe);
-}
-
-/*
- * kw_config_mpp - Multi-Purpose Pins Functionality configuration
- *
- * Each MPP can be configured to different functionality through
- * MPP control register, ref (sec 6.1 of kirkwood h/w specification)
- *
- * There are maximum 64 Multi-Pourpose Pins on Kirkwood
- * Each MPP functionality can be configuration by a 4bit value
- * of MPP control reg, the value and associated functionality depends
- * upon used SoC varient
- */
-int kw_config_mpp(u32 mpp0_7, u32 mpp8_15, u32 mpp16_23, u32 mpp24_31,
-               u32 mpp32_39, u32 mpp40_47, u32 mpp48_55)
-{
-       u32 *mppreg = (u32 *) KW_MPP_BASE;
-
-       /* program mpp registers */
-       writel(mpp0_7, &mppreg[0]);
-       writel(mpp8_15, &mppreg[1]);
-       writel(mpp16_23, &mppreg[2]);
-       writel(mpp24_31, &mppreg[3]);
-       writel(mpp32_39, &mppreg[4]);
-       writel(mpp40_47, &mppreg[5]);
-       writel(mpp48_55, &mppreg[6]);
-       return 0;
-}
-
 /*
  * SYSRSTn Duration Counter Support
  *
index 0ba6f098cb6b2c6486dc1a79375a6482634327f9..7222504ed3a43033d93959af3c9857f310642865 100644 (file)
@@ -12,7 +12,7 @@
 #include <common.h>
 #include <asm/io.h>
 #include <asm/arch/cpu.h>
-#include <asm/arch/kirkwood.h>
+#include <asm/arch/soc.h>
 #include <asm/arch/mpp.h>
 
 static u32 kirkwood_variant(void)
index 828d10bb5a4e59bf9aaa1a0ddf0775af22749dc3..29b1d734382a3c8a83a41cad409a8b5b6e217d7e 100644 (file)
@@ -9,7 +9,9 @@
  */
 
 #include <common.h>
+#include <dm.h>
 #include <errno.h>
+#include <ns16550.h>
 #include <spl.h>
 #include <asm/arch/cpu.h>
 #include <asm/arch/hardware.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
+#ifdef CONFIG_DM_GPIO
+static const struct omap_gpio_platdata am33xx_gpio[] = {
+       { 0, AM33XX_GPIO0_BASE, METHOD_GPIO_24XX },
+       { 1, AM33XX_GPIO1_BASE, METHOD_GPIO_24XX },
+       { 2, AM33XX_GPIO2_BASE, METHOD_GPIO_24XX },
+       { 3, AM33XX_GPIO3_BASE, METHOD_GPIO_24XX },
+#ifdef CONFIG_AM43XX
+       { 4, AM33XX_GPIO4_BASE, METHOD_GPIO_24XX },
+       { 5, AM33XX_GPIO5_BASE, METHOD_GPIO_24XX },
+#endif
+};
+
+U_BOOT_DEVICES(am33xx_gpios) = {
+       { "gpio_omap", &am33xx_gpio[0] },
+       { "gpio_omap", &am33xx_gpio[1] },
+       { "gpio_omap", &am33xx_gpio[2] },
+       { "gpio_omap", &am33xx_gpio[3] },
+#ifdef CONFIG_AM43XX
+       { "gpio_omap", &am33xx_gpio[4] },
+       { "gpio_omap", &am33xx_gpio[5] },
+#endif
+};
+
+# ifndef CONFIG_OF_CONTROL
+/*
+ * TODO(sjg@chromium.org): When we can move SPL serial to DM, we can remove
+ * the CONFIGs. At the same time, we should move this to the board files.
+ */
+static const struct ns16550_platdata am33xx_serial[] = {
+       { CONFIG_SYS_NS16550_COM1, 2, CONFIG_SYS_NS16550_CLK },
+#  ifdef CONFIG_SYS_NS16550_COM2
+       { CONFIG_SYS_NS16550_COM2, 2, CONFIG_SYS_NS16550_CLK },
+#   ifdef CONFIG_SYS_NS16550_COM3
+       { CONFIG_SYS_NS16550_COM3, 2, CONFIG_SYS_NS16550_CLK },
+       { CONFIG_SYS_NS16550_COM4, 2, CONFIG_SYS_NS16550_CLK },
+       { CONFIG_SYS_NS16550_COM5, 2, CONFIG_SYS_NS16550_CLK },
+       { CONFIG_SYS_NS16550_COM6, 2, CONFIG_SYS_NS16550_CLK },
+#   endif
+#  endif
+};
+
+U_BOOT_DEVICES(am33xx_uarts) = {
+       { "serial_omap", &am33xx_serial[0] },
+#  ifdef CONFIG_SYS_NS16550_COM2
+       { "serial_omap", &am33xx_serial[1] },
+#   ifdef CONFIG_SYS_NS16550_COM3
+       { "serial_omap", &am33xx_serial[2] },
+       { "serial_omap", &am33xx_serial[3] },
+       { "serial_omap", &am33xx_serial[4] },
+       { "serial_omap", &am33xx_serial[5] },
+#   endif
+#  endif
+};
+# endif
+
+#else
+
 static const struct gpio_bank gpio_bank_am33xx[] = {
        { (void *)AM33XX_GPIO0_BASE, METHOD_GPIO_24XX },
        { (void *)AM33XX_GPIO1_BASE, METHOD_GPIO_24XX },
@@ -49,6 +108,8 @@ static const struct gpio_bank gpio_bank_am33xx[] = {
 
 const struct gpio_bank *const omap_gpio_bank = gpio_bank_am33xx;
 
+#endif
+
 #if defined(CONFIG_OMAP_HSMMC) && !defined(CONFIG_SPL_BUILD)
 int cpu_mmc_init(bd_t *bis)
 {
diff --git a/arch/arm/cpu/armv7/armada-xp/Makefile b/arch/arm/cpu/armv7/armada-xp/Makefile
new file mode 100644 (file)
index 0000000..885dcee
--- /dev/null
@@ -0,0 +1,7 @@
+#
+# Copyright (C) 2014 Stefan Roese <sr@denx.de>
+#
+# SPDX-License-Identifier:     GPL-2.0+
+#
+
+obj-y  = cpu.o
diff --git a/arch/arm/cpu/armv7/armada-xp/cpu.c b/arch/arm/cpu/armv7/armada-xp/cpu.c
new file mode 100644 (file)
index 0000000..1cf70a9
--- /dev/null
@@ -0,0 +1,193 @@
+/*
+ * Copyright (C) 2014 Stefan Roese <sr@denx.de>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <netdev.h>
+#include <asm/io.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/soc.h>
+
+#define DDR_BASE_CS_OFF(n)     (0x0000 + ((n) << 3))
+#define DDR_SIZE_CS_OFF(n)     (0x0004 + ((n) << 3))
+
+static struct mbus_win windows[] = {
+       /* PCIE MEM address space */
+       { DEFADR_PCI_MEM, 256 << 20, CPU_TARGET_PCIE13, CPU_ATTR_PCIE_MEM },
+
+       /* PCIE IO address space */
+       { DEFADR_PCI_IO, 64 << 10, CPU_TARGET_PCIE13, CPU_ATTR_PCIE_IO },
+
+       /* SPI */
+       { DEFADR_SPIF, 8 << 20, CPU_TARGET_DEVICEBUS_BOOTROM_SPI,
+         CPU_ATTR_SPIFLASH },
+
+       /* NOR */
+       { DEFADR_BOOTROM, 8 << 20, CPU_TARGET_DEVICEBUS_BOOTROM_SPI,
+         CPU_ATTR_BOOTROM },
+};
+
+void reset_cpu(unsigned long ignored)
+{
+       struct mvebu_system_registers *reg =
+               (struct mvebu_system_registers *)MVEBU_SYSTEM_REG_BASE;
+
+       writel(readl(&reg->rstoutn_mask) | 1, &reg->rstoutn_mask);
+       writel(readl(&reg->sys_soft_rst) | 1, &reg->sys_soft_rst);
+       while (1)
+               ;
+}
+
+#if defined(CONFIG_DISPLAY_CPUINFO)
+int print_cpuinfo(void)
+{
+       u16 devid = (readl(MVEBU_REG_PCIE_DEVID) >> 16) & 0xffff;
+       u8 revid = readl(MVEBU_REG_PCIE_REVID) & 0xff;
+
+       puts("SoC:   ");
+
+       switch (devid) {
+       case SOC_MV78460_ID:
+               puts("MV78460-");
+               break;
+       default:
+               puts("Unknown-");
+               break;
+       }
+
+       switch (revid) {
+       case 1:
+               puts("A0\n");
+               break;
+       case 2:
+               puts("B0\n");
+               break;
+       default:
+               puts("??\n");
+               break;
+       }
+
+       return 0;
+}
+#endif /* CONFIG_DISPLAY_CPUINFO */
+
+/*
+ * This function initialize Controller DRAM Fastpath windows.
+ * It takes the CS size information from the 0x1500 scratch registers
+ * and sets the correct windows sizes and base addresses accordingly.
+ *
+ * These values are set in the scratch registers by the Marvell
+ * DDR3 training code, which is executed by the BootROM before the
+ * main payload (U-Boot) is executed. This training code is currently
+ * only available in the Marvell U-Boot version. It needs to be
+ * ported to mainline U-Boot SPL at some point.
+ */
+static void update_sdram_window_sizes(void)
+{
+       u64 base = 0;
+       u32 size, temp;
+       int i;
+
+       for (i = 0; i < SDRAM_MAX_CS; i++) {
+               size = readl((MVEBU_SDRAM_SCRATCH + (i * 8))) & SDRAM_ADDR_MASK;
+               if (size != 0) {
+                       size |= ~(SDRAM_ADDR_MASK);
+
+                       /* Set Base Address */
+                       temp = (base & 0xFF000000ll) | ((base >> 32) & 0xF);
+                       writel(temp, MVEBU_SDRAM_BASE + DDR_BASE_CS_OFF(i));
+
+                       /*
+                        * Check if out of max window size and resize
+                        * the window
+                        */
+                       temp = (readl(MVEBU_SDRAM_BASE + DDR_SIZE_CS_OFF(i)) &
+                               ~(SDRAM_ADDR_MASK)) | 1;
+                       temp |= (size & SDRAM_ADDR_MASK);
+                       writel(temp, MVEBU_SDRAM_BASE + DDR_SIZE_CS_OFF(i));
+
+                       base += ((u64)size + 1);
+               } else {
+                       /*
+                        * Disable window if not used, otherwise this
+                        * leads to overlapping enabled windows with
+                        * pretty strange results
+                        */
+                       clrbits_le32(MVEBU_SDRAM_BASE + DDR_SIZE_CS_OFF(i), 1);
+               }
+       }
+}
+
+#ifdef CONFIG_ARCH_CPU_INIT
+int arch_cpu_init(void)
+{
+       /* Linux expects the internal registers to be at 0xf1000000 */
+       writel(SOC_REGS_PHY_BASE, INTREG_BASE_ADDR_REG);
+
+       /*
+        * We need to call mvebu_mbus_probe() before calling
+        * update_sdram_window_sizes() as it disables all previously
+        * configured mbus windows and then configures them as
+        * required for U-Boot. Calling update_sdram_window_sizes()
+        * without this configuration will not work, as the internal
+        * registers can't be accessed reliably because of potenial
+        * double mapping.
+        * After updating the SDRAM access windows we need to call
+        * mvebu_mbus_probe() again, as this now correctly configures
+        * the SDRAM areas that are later used by the MVEBU drivers
+        * (e.g. USB, NETA).
+        */
+
+       /*
+        * First disable all windows
+        */
+       mvebu_mbus_probe(NULL, 0);
+
+       /*
+        * Now the SDRAM access windows can be reconfigured using
+        * the information in the SDRAM scratch pad registers
+        */
+       update_sdram_window_sizes();
+
+       /*
+        * Finally the mbus windows can be configured with the
+        * updated SDRAM sizes
+        */
+       mvebu_mbus_probe(windows, ARRAY_SIZE(windows));
+
+       return 0;
+}
+#endif /* CONFIG_ARCH_CPU_INIT */
+
+/*
+ * SOC specific misc init
+ */
+#if defined(CONFIG_ARCH_MISC_INIT)
+int arch_misc_init(void)
+{
+       /* Nothing yet, perhaps we need something here later */
+       return 0;
+}
+#endif /* CONFIG_ARCH_MISC_INIT */
+
+#ifdef CONFIG_MVNETA
+int cpu_eth_init(bd_t *bis)
+{
+       mvneta_initialize(bis, MVEBU_EGIGA0_BASE, 0, CONFIG_PHY_BASE_ADDR + 0);
+       mvneta_initialize(bis, MVEBU_EGIGA1_BASE, 1, CONFIG_PHY_BASE_ADDR + 1);
+       mvneta_initialize(bis, MVEBU_EGIGA2_BASE, 2, CONFIG_PHY_BASE_ADDR + 2);
+       mvneta_initialize(bis, MVEBU_EGIGA3_BASE, 3, CONFIG_PHY_BASE_ADDR + 3);
+
+       return 0;
+}
+#endif
+
+#ifndef CONFIG_SYS_DCACHE_OFF
+void enable_caches(void)
+{
+       /* Enable D-cache. I-cache is already enabled in start.S */
+       dcache_enable();
+}
+#endif
index b929486da9c2c99766084bf5440d19a81016a3a1..3d95dc3339e6ee87859748d529510a7036b6cece 100644 (file)
@@ -7,7 +7,7 @@
 
 #include <common.h>
 #include <fdtdec.h>
-#include <asm/arch/gpio.h>
+#include <asm/gpio.h>
 #include <asm/arch/pinmux.h>
 #include <asm/arch/sromc.h>
 
@@ -172,6 +172,9 @@ static int exynos5420_mmc_config(int peripheral, int flags)
                 * this same assumption.
                 */
                if ((peripheral == PERIPH_ID_SDMMC0) && (i == (start + 2))) {
+#ifndef CONFIG_SPL_BUILD
+                       gpio_request(i, "sdmmc0_vdden");
+#endif
                        gpio_set_value(i, 1);
                        gpio_cfg_pin(i, S5P_GPIO_OUTPUT);
                } else {
index 8249b5e27036f7380ef19252792e59553f4f1b1f..393885f710d21ac50931c9b7e3c02046b8123159 100644 (file)
@@ -9,6 +9,9 @@ config TARGET_K2HK_EVM
 config TARGET_K2E_EVM
        bool "TI Keystone 2 Edison EVM"
 
+config TARGET_K2L_EVM
+       bool "TI Keystone 2 Lamar EVM"
+
 endchoice
 
 config SYS_CPU
index f8519c040355f4202e4c701c3a710c96689051d9..ed030db2c888db153db3674d49c5cdec157627e1 100644 (file)
@@ -10,10 +10,9 @@ obj-y        += psc.o
 obj-y  += clock.o
 obj-$(CONFIG_SOC_K2HK) += clock-k2hk.o
 obj-$(CONFIG_SOC_K2E) += clock-k2e.o
+obj-$(CONFIG_SOC_K2L) += clock-k2l.o
 obj-y  += cmd_clock.o
 obj-y  += cmd_mon.o
-obj-$(CONFIG_DRIVER_TI_KEYSTONE_NET) += keystone_nav.o
 obj-y  += msmc.o
-obj-$(CONFIG_SPL_BUILD)        += spl.o
-obj-y  += ddr3.o
+obj-y  += ddr3.o cmd_ddr3.o
 obj-y  += keystone.o
diff --git a/arch/arm/cpu/armv7/keystone/clock-k2l.c b/arch/arm/cpu/armv7/keystone/clock-k2l.c
new file mode 100644 (file)
index 0000000..1c5e4d5
--- /dev/null
@@ -0,0 +1,138 @@
+/*
+ * Keystone2: get clk rate for K2L
+ *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/clock_defs.h>
+
+const struct keystone_pll_regs keystone_pll_regs[] = {
+       [CORE_PLL] = {KS2_MAINPLLCTL0, KS2_MAINPLLCTL1},
+       [PASS_PLL] = {KS2_PASSPLLCTL0, KS2_PASSPLLCTL1},
+       [TETRIS_PLL] = {KS2_ARMPLLCTL0,  KS2_ARMPLLCTL1},
+       [DDR3_PLL] = {KS2_DDR3APLLCTL0, KS2_DDR3APLLCTL1},
+};
+
+int dev_speeds[] = {
+       SPD800,
+       SPD1000,
+       SPD1200,
+       SPD800,
+       SPD800,
+       SPD800,
+       SPD800,
+       SPD800,
+       SPD1200,
+       SPD1000,
+       SPD800,
+       SPD800,
+       SPD800,
+};
+
+int arm_speeds[] = {
+       SPD800,
+       SPD1000,
+       SPD1200,
+       SPD1350,
+       SPD1400,
+       SPD800,
+       SPD1400,
+       SPD1350,
+       SPD1200,
+       SPD1000,
+       SPD800,
+       SPD800,
+       SPD800,
+};
+
+/**
+ * pll_freq_get - get pll frequency
+ * Fout = Fref * NF(mult) / NR(prediv) / OD
+ * @pll:       pll identifier
+ */
+static unsigned long pll_freq_get(int pll)
+{
+       unsigned long mult = 1, prediv = 1, output_div = 2;
+       unsigned long ret;
+       u32 tmp, reg;
+
+       if (pll == CORE_PLL) {
+               ret = external_clk[sys_clk];
+               if (pllctl_reg_read(pll, ctl) & PLLCTL_PLLEN) {
+                       /* PLL mode */
+                       tmp = __raw_readl(KS2_MAINPLLCTL0);
+                       prediv = (tmp & PLL_DIV_MASK) + 1;
+                       mult = (((tmp & PLLM_MULT_HI_SMASK) >> 6) |
+                               (pllctl_reg_read(pll, mult) &
+                               PLLM_MULT_LO_MASK)) + 1;
+                       output_div = ((pllctl_reg_read(pll, secctl) >>
+                                       PLL_CLKOD_SHIFT) & PLL_CLKOD_MASK) + 1;
+
+                       ret = ret / prediv / output_div * mult;
+               }
+       } else {
+               switch (pll) {
+               case PASS_PLL:
+                       ret = external_clk[pa_clk];
+                       reg = KS2_PASSPLLCTL0;
+                       break;
+               case TETRIS_PLL:
+                       ret = external_clk[tetris_clk];
+                       reg = KS2_ARMPLLCTL0;
+                       break;
+               case DDR3_PLL:
+                       ret = external_clk[ddr3_clk];
+                       reg = KS2_DDR3APLLCTL0;
+                       break;
+               default:
+                       return 0;
+               }
+
+               tmp = __raw_readl(reg);
+               if (!(tmp & PLLCTL_BYPASS)) {
+                       /* Bypass disabled */
+                       prediv = (tmp & PLL_DIV_MASK) + 1;
+                       mult = ((tmp >> PLL_MULT_SHIFT) & PLL_MULT_MASK) + 1;
+                       output_div = ((tmp >> PLL_CLKOD_SHIFT) &
+                                     PLL_CLKOD_MASK) + 1;
+                       ret = ((ret / prediv) * mult) / output_div;
+               }
+       }
+
+       return ret;
+}
+
+unsigned long clk_get_rate(unsigned int clk)
+{
+       switch (clk) {
+       case core_pll_clk:      return pll_freq_get(CORE_PLL);
+       case pass_pll_clk:      return pll_freq_get(PASS_PLL);
+       case tetris_pll_clk:    return pll_freq_get(TETRIS_PLL);
+       case ddr3_pll_clk:      return pll_freq_get(DDR3_PLL);
+       case sys_clk0_1_clk:
+       case sys_clk0_clk:      return pll_freq_get(CORE_PLL) / pll0div_read(1);
+       case sys_clk1_clk:      return pll_freq_get(CORE_PLL) / pll0div_read(2);
+       case sys_clk2_clk:      return pll_freq_get(CORE_PLL) / pll0div_read(3);
+       case sys_clk3_clk:      return pll_freq_get(CORE_PLL) / pll0div_read(4);
+       case sys_clk0_2_clk:    return clk_get_rate(sys_clk0_clk) / 2;
+       case sys_clk0_3_clk:    return clk_get_rate(sys_clk0_clk) / 3;
+       case sys_clk0_4_clk:    return clk_get_rate(sys_clk0_clk) / 4;
+       case sys_clk0_6_clk:    return clk_get_rate(sys_clk0_clk) / 6;
+       case sys_clk0_8_clk:    return clk_get_rate(sys_clk0_clk) / 8;
+       case sys_clk0_12_clk:   return clk_get_rate(sys_clk0_clk) / 12;
+       case sys_clk0_24_clk:   return clk_get_rate(sys_clk0_clk) / 24;
+       case sys_clk1_3_clk:    return clk_get_rate(sys_clk1_clk) / 3;
+       case sys_clk1_4_clk:    return clk_get_rate(sys_clk1_clk) / 4;
+       case sys_clk1_6_clk:    return clk_get_rate(sys_clk1_clk) / 6;
+       case sys_clk1_12_clk:   return clk_get_rate(sys_clk1_clk) / 12;
+       default:
+               break;
+       }
+
+       return 0;
+}
index 47fc89398d44123441ade21d9bf017e7621bd4d6..d13fbc1a4bb99cb4e59bb62663644e7462e58cba 100644 (file)
@@ -185,10 +185,6 @@ void init_pll(const struct pll_init_data *data)
                tmp &= ~(PLL_BWADJ_HI_MASK);
                tmp |= ((bwadj >> 8) & PLL_BWADJ_HI_MASK);
 
-               /* set PLL Select (bit 13) for PASS PLL */
-               if (data->pll == PASS_PLL)
-                       tmp |= PLLCTL_PAPLL;
-
                __raw_writel(tmp, keystone_pll_regs[data->pll].reg1);
 
                /* Reset bit: bit 14 for both DDR3 & PASS PLL */
@@ -261,3 +257,16 @@ inline int get_max_arm_speed(void)
        return get_max_speed((read_efuse_bootrom() >> 16) & 0xffff, arm_speeds);
 }
 #endif
+
+void pass_pll_pa_clk_enable(void)
+{
+       u32 reg;
+
+       reg = readl(keystone_pll_regs[PASS_PLL].reg1);
+
+       reg |= PLLCTL_PAPLL;
+       writel(reg, keystone_pll_regs[PASS_PLL].reg1);
+
+       /* wait till clock is enabled */
+       sdelay(15000);
+}
index d97c95be11ddad8ff8b99cad1e1dafc91c5c24c6..af1b701e826930a087cd7822f5b121fc011e8791 100644 (file)
@@ -58,20 +58,11 @@ pll_cmd_usage:
        return cmd_usage(cmdtp);
 }
 
-#ifdef CONFIG_SOC_K2HK
-U_BOOT_CMD(
-       pllset, 5,      0,      do_pll_cmd,
-       "set pll multiplier and pre divider",
-       "<pa|arm|ddr3a|ddr3b> <mult> <div> <OD>\n"
-);
-#endif
-#ifdef CONFIG_SOC_K2E
 U_BOOT_CMD(
        pllset, 5,      0,      do_pll_cmd,
        "set pll multiplier and pre divider",
-       "<pa|ddr3> <mult> <div> <OD>\n"
+       PLLSET_CMD_LIST " <mult> <div> <OD>\n"
 );
-#endif
 
 int do_getclk_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
@@ -95,12 +86,8 @@ U_BOOT_CMD(
        getclk, 2,      0,      do_getclk_cmd,
        "get clock rate",
        "<clk index>\n"
-#ifdef CONFIG_SOC_K2HK
-       "See the 'enum clk_e' in the clock-k2hk.h for clk indexes\n"
-#endif
-#ifdef CONFIG_SOC_K2E
-       "See the 'enum clk_e' in the clock-k2e.h for clk indexes\n"
-#endif
+       "The indexes for clocks:\n"
+       CLOCK_INDEXES_LIST
 );
 
 int do_psc_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
@@ -141,5 +128,8 @@ U_BOOT_CMD(
        psc,    3,      0,      do_psc_cmd,
        "<enable/disable psc module os disable domain>",
        "<mod/domain index> <en|di|domain>\n"
-       "See the hardware.h for Power and Sleep Controller (PSC) Domains\n"
+       "Intended to control Power and Sleep Controller (PSC) domains and\n"
+       "modules. The module or domain index exectly corresponds to ones\n"
+       "listed in official TRM. For instance, to enable MSMC RAM clock\n"
+       "domain use command: psc 14 en.\n"
 );
diff --git a/arch/arm/cpu/armv7/keystone/cmd_ddr3.c b/arch/arm/cpu/armv7/keystone/cmd_ddr3.c
new file mode 100644 (file)
index 0000000..ea78ad8
--- /dev/null
@@ -0,0 +1,248 @@
+/*
+ * Keystone2: DDR3 test commands
+ *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <asm/arch/hardware.h>
+#include <asm/arch/ddr3.h>
+#include <common.h>
+#include <command.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define DDR_MIN_ADDR           CONFIG_SYS_SDRAM_BASE
+
+#define DDR_REMAP_ADDR         0x80000000
+#define ECC_START_ADDR1                ((DDR_MIN_ADDR - DDR_REMAP_ADDR) >> 17)
+
+#define ECC_END_ADDR1          (((gd->start_addr_sp - DDR_REMAP_ADDR - \
+                                CONFIG_STACKSIZE) >> 17) - 2)
+
+#define DDR_TEST_BURST_SIZE    1024
+
+static int ddr_memory_test(u32 start_address, u32 end_address, int quick)
+{
+       u32 index_start, value, index;
+
+       index_start = start_address;
+
+       while (1) {
+               /* Write a pattern */
+               for (index = index_start;
+                               index < index_start + DDR_TEST_BURST_SIZE;
+                               index += 4)
+                       __raw_writel(index, index);
+
+               /* Read and check the pattern */
+               for (index = index_start;
+                               index < index_start + DDR_TEST_BURST_SIZE;
+                               index += 4) {
+                       value = __raw_readl(index);
+                       if (value != index) {
+                               printf("ddr_memory_test: Failed at address index = 0x%x value = 0x%x *(index) = 0x%x\n",
+                                      index, value, __raw_readl(index));
+
+                               return -1;
+                       }
+               }
+
+               index_start += DDR_TEST_BURST_SIZE;
+               if (index_start >= end_address)
+                       break;
+
+               if (quick)
+                       continue;
+
+               /* Write a pattern for complementary values */
+               for (index = index_start;
+                    index < index_start + DDR_TEST_BURST_SIZE;
+                    index += 4)
+                       __raw_writel((u32)~index, index);
+
+               /* Read and check the pattern */
+               for (index = index_start;
+                    index < index_start + DDR_TEST_BURST_SIZE;
+                    index += 4) {
+                       value = __raw_readl(index);
+                       if (value != ~index) {
+                               printf("ddr_memory_test: Failed at address index = 0x%x value = 0x%x *(index) = 0x%x\n",
+                                      index, value, __raw_readl(index));
+
+                               return -1;
+                       }
+               }
+
+               index_start += DDR_TEST_BURST_SIZE;
+               if (index_start >= end_address)
+                       break;
+
+               /* Write a pattern */
+               for (index = index_start;
+                    index < index_start + DDR_TEST_BURST_SIZE;
+                    index += 2)
+                       __raw_writew((u16)index, index);
+
+               /* Read and check the pattern */
+               for (index = index_start;
+                    index < index_start + DDR_TEST_BURST_SIZE;
+                    index += 2) {
+                       value = __raw_readw(index);
+                       if (value != (u16)index) {
+                               printf("ddr_memory_test: Failed at address index = 0x%x value = 0x%x *(index) = 0x%x\n",
+                                      index, value, __raw_readw(index));
+
+                               return -1;
+                       }
+               }
+
+               index_start += DDR_TEST_BURST_SIZE;
+               if (index_start >= end_address)
+                       break;
+
+               /* Write a pattern */
+               for (index = index_start;
+                    index < index_start + DDR_TEST_BURST_SIZE;
+                    index += 1)
+                       __raw_writeb((u8)index, index);
+
+               /* Read and check the pattern */
+               for (index = index_start;
+                    index < index_start + DDR_TEST_BURST_SIZE;
+                    index += 1) {
+                       value = __raw_readb(index);
+                       if (value != (u8)index) {
+                               printf("ddr_memory_test: Failed at address index = 0x%x value = 0x%x *(index) = 0x%x\n",
+                                      index, value, __raw_readb(index));
+
+                               return -1;
+                       }
+               }
+
+               index_start += DDR_TEST_BURST_SIZE;
+               if (index_start >= end_address)
+                       break;
+       }
+
+       puts("ddr memory test PASSED!\n");
+       return 0;
+}
+
+static int ddr_memory_compare(u32 address1, u32 address2, u32 size)
+{
+       u32 index, value, index2, value2;
+
+       for (index = address1, index2 = address2;
+            index < address1 + size;
+            index += 4, index2 += 4) {
+               value = __raw_readl(index);
+               value2 = __raw_readl(index2);
+
+               if (value != value2) {
+                       printf("ddr_memory_test: Compare failed at address = 0x%x value = 0x%x, address2 = 0x%x value2 = 0x%x\n",
+                              index, value, index2, value2);
+
+                       return -1;
+               }
+       }
+
+       puts("ddr memory compare PASSED!\n");
+       return 0;
+}
+
+static int ddr_memory_ecc_err(u32 base, u32 address, u32 ecc_err)
+{
+       u32 value1, value2, value3;
+
+       puts("Disabling DDR ECC ...\n");
+       ddr3_disable_ecc(base);
+
+       value1 = __raw_readl(address);
+       value2 = value1 ^ ecc_err;
+       __raw_writel(value2, address);
+
+       value3 = __raw_readl(address);
+       printf("ECC err test, addr 0x%x, read data 0x%x, wrote data 0x%x, err pattern: 0x%x, read after write data 0x%x\n",
+              address, value1, value2, ecc_err, value3);
+
+       __raw_writel(ECC_START_ADDR1 | (ECC_END_ADDR1 << 16),
+                    base + KS2_DDR3_ECC_ADDR_RANGE1_OFFSET);
+
+       puts("Enabling DDR ECC ...\n");
+       ddr3_enable_ecc(base, 1);
+
+       value1 = __raw_readl(address);
+       printf("ECC err test, addr 0x%x, read data 0x%x\n", address, value1);
+
+       ddr3_check_ecc_int(base);
+       return 0;
+}
+
+static int do_ddr_test(cmd_tbl_t *cmdtp,
+                      int flag, int argc, char * const argv[])
+{
+       u32 start_addr, end_addr, size, ecc_err;
+
+       if ((argc == 4) && (strncmp(argv[1], "ecc_err", 8) == 0)) {
+               if (!ddr3_ecc_support_rmw(KS2_DDR3A_EMIF_CTRL_BASE)) {
+                       puts("ECC RMW isn't supported for this SOC\n");
+                       return 1;
+               }
+
+               start_addr = simple_strtoul(argv[2], NULL, 16);
+               ecc_err = simple_strtoul(argv[3], NULL, 16);
+
+               if ((start_addr < CONFIG_SYS_SDRAM_BASE) ||
+                   (start_addr > (CONFIG_SYS_SDRAM_BASE +
+                    CONFIG_MAX_RAM_BANK_SIZE - 1))) {
+                       puts("Invalid address!\n");
+                       return cmd_usage(cmdtp);
+               }
+
+               ddr_memory_ecc_err(KS2_DDR3A_EMIF_CTRL_BASE,
+                                  start_addr, ecc_err);
+               return 0;
+       }
+
+       if (!(((argc == 4) && (strncmp(argv[1], "test", 5) == 0)) ||
+             ((argc == 5) && (strncmp(argv[1], "compare", 8) == 0))))
+               return cmd_usage(cmdtp);
+
+       start_addr = simple_strtoul(argv[2], NULL, 16);
+       end_addr = simple_strtoul(argv[3], NULL, 16);
+
+       if ((start_addr < CONFIG_SYS_SDRAM_BASE) ||
+           (start_addr > (CONFIG_SYS_SDRAM_BASE +
+            CONFIG_MAX_RAM_BANK_SIZE - 1)) ||
+           (end_addr < CONFIG_SYS_SDRAM_BASE) ||
+           (end_addr > (CONFIG_SYS_SDRAM_BASE +
+            CONFIG_MAX_RAM_BANK_SIZE - 1)) || (start_addr >= end_addr)) {
+               puts("Invalid start or end address!\n");
+               return cmd_usage(cmdtp);
+       }
+
+       puts("Please wait ...\n");
+       if (argc == 5) {
+               size = simple_strtoul(argv[4], NULL, 16);
+               ddr_memory_compare(start_addr, end_addr, size);
+       } else {
+               ddr_memory_test(start_addr, end_addr, 0);
+       }
+
+       return 0;
+}
+
+U_BOOT_CMD(ddr,        5, 1, do_ddr_test,
+          "DDR3 test",
+          "test <start_addr in hex> <end_addr in hex> - test DDR from start\n"
+          "    address to end address\n"
+          "ddr compare <start_addr in hex> <end_addr in hex> <size in hex> -\n"
+          "    compare DDR data of (size) bytes from start address to end\n"
+          "    address\n"
+          "ddr ecc_err <addr in hex> <bit_err in hex> - generate bit errors\n"
+          "    in DDR data at <addr>, the command will read a 32-bit data\n"
+          "    from <addr>, and write (data ^ bit_err) back to <addr>\n"
+);
index 2eabec10f95f6e207ced63295f170a7bf9e2ae3f..923906afb5bec2ab2ff10d149e891cc387918738 100644 (file)
@@ -9,9 +9,19 @@
 
 #include <asm/io.h>
 #include <common.h>
+#include <asm/arch/msmc.h>
 #include <asm/arch/ddr3.h>
 #include <asm/arch/psc_defs.h>
 
+#include <asm/ti-common/ti-edma3.h>
+
+#define DDR3_EDMA_BLK_SIZE_SHIFT       10
+#define DDR3_EDMA_BLK_SIZE             (1 << DDR3_EDMA_BLK_SIZE_SHIFT)
+#define DDR3_EDMA_BCNT                 0x8000
+#define DDR3_EDMA_CCNT                 1
+#define DDR3_EDMA_XF_SIZE              (DDR3_EDMA_BLK_SIZE * DDR3_EDMA_BCNT)
+#define DDR3_EDMA_SLOT_NUM             1
+
 void ddr3_init_ddrphy(u32 base, struct ddr3_phy_config *phy_cfg)
 {
        unsigned int tmp;
@@ -70,6 +80,240 @@ void ddr3_init_ddremif(u32 base, struct ddr3_emif_config *emif_cfg)
        __raw_writel(emif_cfg->sdrfc,  base + KS2_DDR3_SDRFC_OFFSET);
 }
 
+int ddr3_ecc_support_rmw(u32 base)
+{
+       u32 value = __raw_readl(base + KS2_DDR3_MIDR_OFFSET);
+
+       /* Check the DDR3 controller ID reg if the controllers
+          supports ECC RMW or not */
+       if (value == 0x40461C02)
+               return 1;
+
+       return 0;
+}
+
+static void ddr3_ecc_config(u32 base, u32 value)
+{
+       u32 data;
+
+       __raw_writel(value,  base + KS2_DDR3_ECC_CTRL_OFFSET);
+       udelay(100000); /* delay required to synchronize across clock domains */
+
+       if (value & KS2_DDR3_ECC_EN) {
+               /* Clear the 1-bit error count */
+               data = __raw_readl(base + KS2_DDR3_ONE_BIT_ECC_ERR_CNT_OFFSET);
+               __raw_writel(data, base + KS2_DDR3_ONE_BIT_ECC_ERR_CNT_OFFSET);
+
+               /* enable the ECC interrupt */
+               __raw_writel(KS2_DDR3_1B_ECC_ERR_SYS | KS2_DDR3_2B_ECC_ERR_SYS |
+                            KS2_DDR3_WR_ECC_ERR_SYS,
+                            base + KS2_DDR3_ECC_INT_ENABLE_SET_SYS_OFFSET);
+
+               /* Clear the ECC error interrupt status */
+               __raw_writel(KS2_DDR3_1B_ECC_ERR_SYS | KS2_DDR3_2B_ECC_ERR_SYS |
+                            KS2_DDR3_WR_ECC_ERR_SYS,
+                            base + KS2_DDR3_ECC_INT_STATUS_OFFSET);
+       }
+}
+
+static void ddr3_reset_data(u32 base, u32 ddr3_size)
+{
+       u32 mpax[2];
+       u32 seg_num;
+       u32 seg, blks, dst, edma_blks;
+       struct edma3_slot_config slot;
+       struct edma3_channel_config edma_channel;
+       u32 edma_src[DDR3_EDMA_BLK_SIZE/4] __aligned(16) = {0, };
+
+       /* Setup an edma to copy the 1k block to the entire DDR */
+       puts("\nClear entire DDR3 memory to enable ECC\n");
+
+       /* save the SES MPAX regs */
+       msmc_get_ses_mpax(8, 0, mpax);
+
+       /* setup edma slot 1 configuration */
+       slot.opt = EDMA3_SLOPT_TRANS_COMP_INT_ENB |
+                  EDMA3_SLOPT_COMP_CODE(0) |
+                  EDMA3_SLOPT_STATIC | EDMA3_SLOPT_AB_SYNC;
+       slot.bcnt = DDR3_EDMA_BCNT;
+       slot.acnt = DDR3_EDMA_BLK_SIZE;
+       slot.ccnt = DDR3_EDMA_CCNT;
+       slot.src_bidx = 0;
+       slot.dst_bidx = DDR3_EDMA_BLK_SIZE;
+       slot.src_cidx = 0;
+       slot.dst_cidx = 0;
+       slot.link = EDMA3_PARSET_NULL_LINK;
+       slot.bcntrld = 0;
+       edma3_slot_configure(KS2_EDMA0_BASE, DDR3_EDMA_SLOT_NUM, &slot);
+
+       /* configure quik edma channel */
+       edma_channel.slot = DDR3_EDMA_SLOT_NUM;
+       edma_channel.chnum = 0;
+       edma_channel.complete_code = 0;
+       /* event trigger after dst update */
+       edma_channel.trigger_slot_word = EDMA3_TWORD(dst);
+       qedma3_start(KS2_EDMA0_BASE, &edma_channel);
+
+       /* DDR3 size in segments (4KB seg size) */
+       seg_num = ddr3_size << (30 - KS2_MSMC_SEG_SIZE_SHIFT);
+
+       for (seg = 0; seg < seg_num; seg += KS2_MSMC_MAP_SEG_NUM) {
+               /* map 2GB 36-bit DDR address to 32-bit DDR address in EMIF
+                  access slave interface so that edma driver can access */
+               msmc_map_ses_segment(8, 0, base >> KS2_MSMC_SEG_SIZE_SHIFT,
+                                    KS2_MSMC_DST_SEG_BASE + seg, MPAX_SEG_2G);
+
+               if ((seg_num - seg) > KS2_MSMC_MAP_SEG_NUM)
+                       edma_blks = KS2_MSMC_MAP_SEG_NUM <<
+                                       (KS2_MSMC_SEG_SIZE_SHIFT
+                                       - DDR3_EDMA_BLK_SIZE_SHIFT);
+               else
+                       edma_blks = (seg_num - seg) << (KS2_MSMC_SEG_SIZE_SHIFT
+                                       - DDR3_EDMA_BLK_SIZE_SHIFT);
+
+               /* Use edma driver to scrub 2GB DDR memory */
+               for (dst = base, blks = 0; blks < edma_blks;
+                    blks += DDR3_EDMA_BCNT, dst += DDR3_EDMA_XF_SIZE) {
+                       edma3_set_src_addr(KS2_EDMA0_BASE,
+                                          edma_channel.slot, (u32)edma_src);
+                       edma3_set_dest_addr(KS2_EDMA0_BASE,
+                                           edma_channel.slot, (u32)dst);
+
+                       while (edma3_check_for_transfer(KS2_EDMA0_BASE,
+                                                       &edma_channel))
+                               udelay(10);
+               }
+       }
+
+       qedma3_stop(KS2_EDMA0_BASE, &edma_channel);
+
+       /* restore the SES MPAX regs */
+       msmc_set_ses_mpax(8, 0, mpax);
+}
+
+static void ddr3_ecc_init_range(u32 base)
+{
+       u32 ecc_val = KS2_DDR3_ECC_EN;
+       u32 rmw = ddr3_ecc_support_rmw(base);
+
+       if (rmw)
+               ecc_val |= KS2_DDR3_ECC_RMW_EN;
+
+       __raw_writel(0, base + KS2_DDR3_ECC_ADDR_RANGE1_OFFSET);
+
+       ddr3_ecc_config(base, ecc_val);
+}
+
+void ddr3_enable_ecc(u32 base, int test)
+{
+       u32 ecc_val = KS2_DDR3_ECC_ENABLE;
+       u32 rmw = ddr3_ecc_support_rmw(base);
+
+       if (test)
+               ecc_val |= KS2_DDR3_ECC_ADDR_RNG_1_EN;
+
+       if (!rmw) {
+               if (!test)
+                       /* by default, disable ecc when rmw = 0 and no
+                          ecc test */
+                       ecc_val = 0;
+       } else {
+               ecc_val |= KS2_DDR3_ECC_RMW_EN;
+       }
+
+       ddr3_ecc_config(base, ecc_val);
+}
+
+void ddr3_disable_ecc(u32 base)
+{
+       ddr3_ecc_config(base, 0);
+}
+
+#if defined(CONFIG_SOC_K2HK) || defined(CONFIG_SOC_K2L)
+static void cic_init(u32 base)
+{
+       /* Disable CIC global interrupts */
+       __raw_writel(0, base + KS2_CIC_GLOBAL_ENABLE);
+
+       /* Set to normal mode, no nesting, no priority hold */
+       __raw_writel(0, base + KS2_CIC_CTRL);
+       __raw_writel(0, base + KS2_CIC_HOST_CTRL);
+
+       /* Enable CIC global interrupts */
+       __raw_writel(1, base + KS2_CIC_GLOBAL_ENABLE);
+}
+
+static void cic_map_cic_to_gic(u32 base, u32 chan_num, u32 irq_num)
+{
+       /* Map the system interrupt to a CIC channel */
+       __raw_writeb(chan_num, base + KS2_CIC_CHAN_MAP(0) + irq_num);
+
+       /* Enable CIC system interrupt */
+       __raw_writel(irq_num, base + KS2_CIC_SYS_ENABLE_IDX_SET);
+
+       /* Enable CIC Host interrupt */
+       __raw_writel(chan_num, base + KS2_CIC_HOST_ENABLE_IDX_SET);
+}
+
+static void ddr3_map_ecc_cic2_irq(u32 base)
+{
+       cic_init(base);
+       cic_map_cic_to_gic(base, KS2_CIC2_DDR3_ECC_CHAN_NUM,
+                          KS2_CIC2_DDR3_ECC_IRQ_NUM);
+}
+#endif
+
+void ddr3_init_ecc(u32 base)
+{
+       u32 ddr3_size;
+
+       if (!ddr3_ecc_support_rmw(base)) {
+               ddr3_disable_ecc(base);
+               return;
+       }
+
+       ddr3_ecc_init_range(base);
+       ddr3_size = ddr3_get_size();
+       ddr3_reset_data(CONFIG_SYS_SDRAM_BASE, ddr3_size);
+
+       /* mapping DDR3 ECC system interrupt from CIC2 to GIC */
+#if defined(CONFIG_SOC_K2HK) || defined(CONFIG_SOC_K2L)
+       ddr3_map_ecc_cic2_irq(KS2_CIC2_BASE);
+#endif
+       ddr3_enable_ecc(base, 0);
+}
+
+void ddr3_check_ecc_int(u32 base)
+{
+       char *env;
+       int ecc_test = 0;
+       u32 value = __raw_readl(base + KS2_DDR3_ECC_INT_STATUS_OFFSET);
+
+       env = getenv("ecc_test");
+       if (env)
+               ecc_test = simple_strtol(env, NULL, 0);
+
+       if (value & KS2_DDR3_WR_ECC_ERR_SYS)
+               puts("DDR3 ECC write error interrupted\n");
+
+       if (value & KS2_DDR3_2B_ECC_ERR_SYS) {
+               puts("DDR3 ECC 2-bit error interrupted\n");
+
+               if (!ecc_test) {
+                       puts("Reseting the device ...\n");
+                       reset_cpu(0);
+               }
+       }
+
+       value = __raw_readl(base + KS2_DDR3_ONE_BIT_ECC_ERR_CNT_OFFSET);
+       if (value) {
+               printf("1-bit ECC err count: 0x%x\n", value);
+               value = __raw_readl(base +
+                                   KS2_DDR3_ONE_BIT_ECC_ERR_ADDR_LOG_OFFSET);
+               printf("1-bit ECC err address log: 0x%x\n", value);
+       }
+}
+
 void ddr3_reset_ddrphy(void)
 {
        u32 tmp;
index a8f8aee8ab45d4df9c5d76132120d5af8d7663d6..c2b947839d292a14090e15d951703eb99e517f6e 100644 (file)
@@ -13,6 +13,7 @@
 #include <asm/arch/msmc.h>
 #include <asm/arch/clock.h>
 #include <asm/arch/hardware.h>
+#include <asm/arch/psc_defs.h>
 
 void chip_configuration_unlock(void)
 {
@@ -20,17 +21,67 @@ void chip_configuration_unlock(void)
        __raw_writel(KS2_KICK1_MAGIC, KS2_KICK1);
 }
 
+#ifdef CONFIG_SOC_K2L
+void osr_init(void)
+{
+       u32 i;
+       u32 j;
+       u32 val;
+       u32 base = KS2_OSR_CFG_BASE;
+       u32 ecc_ctrl[KS2_OSR_NUM_RAM_BANKS];
+
+       /* Enable the OSR clock domain */
+       psc_enable_module(KS2_LPSC_OSR);
+
+       /* Disable OSR ECC check for all the ram banks */
+       for (i = 0; i < KS2_OSR_NUM_RAM_BANKS; i++) {
+               val = i | KS2_OSR_ECC_VEC_TRIG_RD |
+                       (KS2_OSR_ECC_CTRL << KS2_OSR_ECC_VEC_RD_ADDR_SH);
+
+               writel(val , base + KS2_OSR_ECC_VEC);
+
+               /**
+                * wait till read is done.
+                * Print should be added after earlyprintk support is added.
+                */
+               for (j = 0; j < 10000; j++) {
+                       val = readl(base + KS2_OSR_ECC_VEC);
+                       if (val & KS2_OSR_ECC_VEC_RD_DONE)
+                               break;
+               }
+
+               ecc_ctrl[i] = readl(base + KS2_OSR_ECC_CTRL) ^
+                                               KS2_OSR_ECC_CTRL_CHK;
+
+               writel(ecc_ctrl[i], KS2_MSMC_DATA_BASE + i * 4);
+               writel(ecc_ctrl[i], base + KS2_OSR_ECC_CTRL);
+       }
+
+       /* Reset OSR memory to all zeros */
+       for (i = 0; i < KS2_OSR_SIZE; i += 4)
+               writel(0, KS2_OSR_DATA_BASE + i);
+
+       /* Enable OSR ECC check for all the ram banks */
+       for (i = 0; i < KS2_OSR_NUM_RAM_BANKS; i++)
+               writel(ecc_ctrl[i] |
+                      KS2_OSR_ECC_CTRL_CHK, base + KS2_OSR_ECC_CTRL);
+}
+#endif
+
 int arch_cpu_init(void)
 {
        chip_configuration_unlock();
        icache_enable();
 
-       msmc_share_all_segments(8);  /* TETRIS */
-       msmc_share_all_segments(9);  /* NETCP */
-       msmc_share_all_segments(10); /* QM PDSP */
-       msmc_share_all_segments(11); /* PCIE 0 */
-#ifdef CONFIG_SOC_K2E
-       msmc_share_all_segments(13); /* PCIE 1 */
+       msmc_share_all_segments(KS2_MSMC_SEGMENT_TETRIS);
+       msmc_share_all_segments(KS2_MSMC_SEGMENT_NETCP);
+       msmc_share_all_segments(KS2_MSMC_SEGMENT_QM_PDSP);
+       msmc_share_all_segments(KS2_MSMC_SEGMENT_PCIE0);
+#if defined(CONFIG_SOC_K2E) || defined(CONFIG_SOC_K2L)
+       msmc_share_all_segments(KS2_MSMC_SEGMENT_PCIE1);
+#endif
+#ifdef CONFIG_SOC_K2L
+       osr_init();
 #endif
 
        /*
index 7d8e5978dfad307a5bbe97afa7a8aae59265b56b..7899141d543a2f7426366c908f4a728797d8fa5d 100644 (file)
@@ -66,3 +66,29 @@ void msmc_share_all_segments(int priv_id)
                msmc->ses[priv_id][j].mpaxh &= 0xffffff7ful;
        }
 }
+
+void msmc_map_ses_segment(int priv_id, int ses_pair,
+                         u32 src_pfn, u32 dst_pfn, enum mpax_seg_size size)
+{
+       struct msms_regs *msmc = (struct msms_regs *)KS2_MSMC_CTRL_BASE;
+
+       msmc->ses[priv_id][ses_pair].mpaxh = src_pfn << 12 |
+                                            (size & 0x1f) | 0x80;
+       msmc->ses[priv_id][ses_pair].mpaxl = dst_pfn << 8 | 0x3f;
+}
+
+void msmc_get_ses_mpax(int priv_id, int ses_pair, u32 *mpax)
+{
+       struct msms_regs *msmc = (struct msms_regs *)KS2_MSMC_CTRL_BASE;
+
+       *mpax++ = msmc->ses[priv_id][ses_pair].mpaxl;
+       *mpax = msmc->ses[priv_id][ses_pair].mpaxh;
+}
+
+void msmc_set_ses_mpax(int priv_id, int ses_pair, u32 *mpax)
+{
+       struct msms_regs *msmc = (struct msms_regs *)KS2_MSMC_CTRL_BASE;
+
+       msmc->ses[priv_id][ses_pair].mpaxl = *mpax++;
+       msmc->ses[priv_id][ses_pair].mpaxh = *mpax;
+}
diff --git a/arch/arm/cpu/armv7/keystone/spl.c b/arch/arm/cpu/armv7/keystone/spl.c
deleted file mode 100644 (file)
index d4b0e9b..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * common spl init code
- *
- * (C) Copyright 2012-2014
- *     Texas Instruments Incorporated, <www.ti.com>
- *
- * SPDX-License-Identifier:     GPL-2.0+
- */
-#include <common.h>
-#include <config.h>
-#include <ns16550.h>
-#include <malloc.h>
-#include <spl.h>
-#include <spi_flash.h>
-
-#include <asm/u-boot.h>
-#include <asm/utils.h>
-
-DECLARE_GLOBAL_DATA_PTR;
-
-#ifdef CONFIG_K2HK_EVM
-static struct pll_init_data spl_pll_config[] = {
-       CORE_PLL_799,
-       TETRIS_PLL_500,
-};
-#endif
-
-#ifdef CONFIG_K2E_EVM
-static struct pll_init_data spl_pll_config[] = {
-       CORE_PLL_800,
-};
-#endif
-
-void spl_init_keystone_plls(void)
-{
-       init_plls(ARRAY_SIZE(spl_pll_config), spl_pll_config);
-}
-
-void spl_board_init(void)
-{
-       spl_init_keystone_plls();
-       preloader_console_init();
-}
-
-u32 spl_boot_device(void)
-{
-#if defined(CONFIG_SPL_SPI_LOAD)
-       return BOOT_DEVICE_SPI;
-#else
-       puts("Unknown boot device\n");
-       hang();
-#endif
-}
index 6dc26003b692cbab444a1136f7f85d3eef3aca76..dd5aaa286a68d708fda6814e6d107adba4d70231 100644 (file)
@@ -9,6 +9,7 @@
 
 #include <common.h>
 #include <asm/armv7.h>
+#include <asm/bootm.h>
 #include <asm/pl310.h>
 #include <asm/errno.h>
 #include <asm/io.h>
index 6fae1e5f36e5a3ea416e68275c5cd51f2f19fe20..4a48f847814496472469a1c64531c67c3b46cf3b 100644 (file)
@@ -16,7 +16,7 @@ config TARGET_OMAP3_BEAGLE
        bool "TI OMAP3 BeagleBoard"
 
 config TARGET_CM_T35
-       bool "CompuLab CM-T35"
+       bool "CompuLab CM-T3530 and CM-T3730 boards"
 
 config TARGET_DEVKIT8000
        bool "TimLL OMAP3 Devkit8000"
index 667e77ff05ba22429fdf101e0884856e5eb54e62..c942fe67eeb2148c0dcce6abbaea21d3193653c2 100644 (file)
  * SPDX-License-Identifier:    GPL-2.0+
  */
 #include <common.h>
+#include <dm.h>
+#include <mmc.h>
 #include <spl.h>
 #include <asm/io.h>
 #include <asm/arch/sys_proto.h>
 #include <asm/arch/mem.h>
 #include <asm/cache.h>
 #include <asm/armv7.h>
-#include <asm/arch/gpio.h>
+#include <asm/gpio.h>
 #include <asm/omap_common.h>
 #include <asm/arch/mmc_host_def.h>
 #include <i2c.h>
@@ -38,6 +40,27 @@ static void omap3_setup_aux_cr(void);
 static void omap3_invalidate_l2_cache_secure(void);
 #endif
 
+#ifdef CONFIG_DM_GPIO
+static const struct omap_gpio_platdata omap34xx_gpio[] = {
+       { 0, OMAP34XX_GPIO1_BASE, METHOD_GPIO_24XX },
+       { 1, OMAP34XX_GPIO2_BASE, METHOD_GPIO_24XX },
+       { 2, OMAP34XX_GPIO3_BASE, METHOD_GPIO_24XX },
+       { 3, OMAP34XX_GPIO4_BASE, METHOD_GPIO_24XX },
+       { 4, OMAP34XX_GPIO5_BASE, METHOD_GPIO_24XX },
+       { 5, OMAP34XX_GPIO6_BASE, METHOD_GPIO_24XX },
+};
+
+U_BOOT_DEVICES(am33xx_gpios) = {
+       { "gpio_omap", &omap34xx_gpio[0] },
+       { "gpio_omap", &omap34xx_gpio[1] },
+       { "gpio_omap", &omap34xx_gpio[2] },
+       { "gpio_omap", &omap34xx_gpio[3] },
+       { "gpio_omap", &omap34xx_gpio[4] },
+       { "gpio_omap", &omap34xx_gpio[5] },
+};
+
+#else
+
 static const struct gpio_bank gpio_bank_34xx[6] = {
        { (void *)OMAP34XX_GPIO1_BASE, METHOD_GPIO_24XX },
        { (void *)OMAP34XX_GPIO2_BASE, METHOD_GPIO_24XX },
@@ -49,6 +72,8 @@ static const struct gpio_bank gpio_bank_34xx[6] = {
 
 const struct gpio_bank *const omap_gpio_bank = gpio_bank_34xx;
 
+#endif
+
 #ifdef CONFIG_SPL_BUILD
 /*
 * We use static variables because global data is not ready yet.
@@ -266,7 +291,7 @@ int __weak misc_init_r(void)
  * Routine: wait_for_command_complete
  * Description: Wait for posting to finish on watchdog
  *****************************************************************************/
-void wait_for_command_complete(struct watchdog *wd_base)
+static void wait_for_command_complete(struct watchdog *wd_base)
 {
        int pending = 1;
        do {
index 6c7330a0cabdec269698bad41aa2cf0e3a733fdb..a2aadc9816975e7ec00da1a8874ce4ebf414a188 100644 (file)
@@ -61,7 +61,7 @@ u32 get_sdr_cs_offset(u32 cs)
  *  - Init the emif4 module for DDR access
  *  - Early init routines, called from flash or SRAM.
  */
-void do_emif4_init(void)
+static void do_emif4_init(void)
 {
        unsigned int regval;
        /* Set the DDR PHY parameters in PHY ctrl registers */
index bef5f05eaa71e36e0323f12e82c2377435c2421e..bbb65bbe7263674c2b47b97ee05a9f588ed1c58f 100644 (file)
@@ -16,6 +16,8 @@
 #include <asm/io.h>
 #include <asm/arch/mem.h>      /* get mem tables */
 #include <asm/arch/sys_proto.h>
+#include <asm/bootm.h>
+
 #include <i2c.h>
 #include <linux/compiler.h>
 
@@ -202,7 +204,7 @@ u32 __weak get_board_rev(void)
 /********************************************************
  *  get_base(); get upper addr of current execution
  *******************************************************/
-u32 get_base(void)
+static u32 get_base(void)
 {
        u32 val;
 
index 0eab264668c8502b775b219fffea48797a9f7447..8c3e5f7cd423c608ade2409fc233c0c706251b9d 100644 (file)
@@ -176,7 +176,7 @@ static void socfpga_nic301_slave_ns(void)
 
 static uint32_t iswgrp_handoff[8];
 
-int misc_init_r(void)
+int arch_early_init_r(void)
 {
        int i;
        for (i = 0; i < 8; i++) /* Cache initial SW setting regs */
index db9bdad7d6c94e62308b89574719c75d17ed5054..569fa418f465683a1d40d553d3921728b99b2b77 100644 (file)
@@ -42,13 +42,4 @@ SECTIONS
                . = ALIGN(4);
                __bss_end = .;
        } >.sdram
-
-       . = ALIGN(8);
-       __malloc_start = .;
-       . = . + CONFIG_SPL_MALLOC_SIZE;
-       __malloc_end = .;
-
-       . = . + CONFIG_SPL_STACK_SIZE;
-       . = ALIGN(8);
-       __stack_start = .;
 }
index e9721b27b64595d27918a396954329ae68acc44c..24f1daee64766d1631122a65dcb13dcb88dbc8ea 100644 (file)
@@ -11,9 +11,13 @@ obj-y        += timer.o
 obj-y  += board.o
 obj-y  += clock.o
 obj-y  += pinmux.o
+obj-$(CONFIG_SUN6I)    += prcm.o
+obj-$(CONFIG_SUN8I)    += prcm.o
 obj-$(CONFIG_SUN4I)    += clock_sun4i.o
 obj-$(CONFIG_SUN5I)    += clock_sun4i.o
+obj-$(CONFIG_SUN6I)    += clock_sun6i.o
 obj-$(CONFIG_SUN7I)    += clock_sun4i.o
+obj-$(CONFIG_SUN8I)    += clock_sun6i.o
 
 ifndef CONFIG_SPL_BUILD
 obj-y  += cpu_info.o
index f2cedbb1568a8eaf5dd7c8a3c6ef4acc085286a1..06eb6768e8f2b58ddbe1b2408157f8e4e89ccaab 100644 (file)
@@ -50,18 +50,35 @@ u32 spl_boot_mode(void)
 
 int gpio_init(void)
 {
-#if CONFIG_CONS_INDEX == 1 && (defined(CONFIG_SUN4I) || defined(CONFIG_SUN7I))
+#if CONFIG_CONS_INDEX == 1 && defined(CONFIG_UART0_PORT_F)
+#if defined(CONFIG_SUN4I) || defined(CONFIG_SUN7I)
+       /* disable GPB22,23 as uart0 tx,rx to avoid conflict */
+       sunxi_gpio_set_cfgpin(SUNXI_GPB(22), SUNXI_GPIO_INPUT);
+       sunxi_gpio_set_cfgpin(SUNXI_GPB(23), SUNXI_GPIO_INPUT);
+#endif
+       sunxi_gpio_set_cfgpin(SUNXI_GPF(2), SUNXI_GPF2_UART0_TX);
+       sunxi_gpio_set_cfgpin(SUNXI_GPF(4), SUNXI_GPF4_UART0_RX);
+       sunxi_gpio_set_pull(SUNXI_GPF(4), 1);
+#elif CONFIG_CONS_INDEX == 1 && (defined(CONFIG_SUN4I) || defined(CONFIG_SUN7I))
        sunxi_gpio_set_cfgpin(SUNXI_GPB(22), SUN4I_GPB22_UART0_TX);
        sunxi_gpio_set_cfgpin(SUNXI_GPB(23), SUN4I_GPB23_UART0_RX);
-       sunxi_gpio_set_pull(SUNXI_GPB(23), 1);
+       sunxi_gpio_set_pull(SUNXI_GPB(23), SUNXI_GPIO_PULL_UP);
 #elif CONFIG_CONS_INDEX == 1 && defined(CONFIG_SUN5I)
        sunxi_gpio_set_cfgpin(SUNXI_GPB(19), SUN5I_GPB19_UART0_TX);
        sunxi_gpio_set_cfgpin(SUNXI_GPB(20), SUN5I_GPB20_UART0_RX);
-       sunxi_gpio_set_pull(SUNXI_GPB(20), 1);
+       sunxi_gpio_set_pull(SUNXI_GPB(20), SUNXI_GPIO_PULL_UP);
+#elif CONFIG_CONS_INDEX == 1 && defined(CONFIG_SUN6I)
+       sunxi_gpio_set_cfgpin(SUNXI_GPH(20), SUN6I_GPH20_UART0_TX);
+       sunxi_gpio_set_cfgpin(SUNXI_GPH(21), SUN6I_GPH21_UART0_RX);
+       sunxi_gpio_set_pull(SUNXI_GPH(21), SUNXI_GPIO_PULL_UP);
 #elif CONFIG_CONS_INDEX == 2 && defined(CONFIG_SUN5I)
        sunxi_gpio_set_cfgpin(SUNXI_GPG(3), SUN5I_GPG3_UART1_TX);
        sunxi_gpio_set_cfgpin(SUNXI_GPG(4), SUN5I_GPG4_UART1_RX);
-       sunxi_gpio_set_pull(SUNXI_GPG(4), 1);
+       sunxi_gpio_set_pull(SUNXI_GPG(4), SUNXI_GPIO_PULL_UP);
+#elif CONFIG_CONS_INDEX == 5 && defined(CONFIG_SUN8I)
+       sunxi_gpio_set_cfgpin(SUNXI_GPL(2), SUN8I_GPL2_R_UART_TX);
+       sunxi_gpio_set_cfgpin(SUNXI_GPL(3), SUN8I_GPL3_R_UART_RX);
+       sunxi_gpio_set_pull(SUNXI_GPL(3), SUNXI_GPIO_PULL_UP);
 #else
 #error Unsupported console port number. Please fix pin mux settings in board.c
 #endif
@@ -71,6 +88,7 @@ int gpio_init(void)
 
 void reset_cpu(ulong addr)
 {
+#if defined(CONFIG_SUN4I) || defined(CONFIG_SUN5I) || defined(CONFIG_SUN7I)
        static const struct sunxi_wdog *wdog =
                 &((struct sunxi_timer_reg *)SUNXI_TIMER_BASE)->wdog;
 
@@ -82,12 +100,22 @@ void reset_cpu(ulong addr)
                /* sun5i sometimes gets stuck without this */
                writel(WDT_MODE_RESET_EN | WDT_MODE_EN, &wdog->mode);
        }
+#else /* CONFIG_SUN6I || CONFIG_SUN8I || .. */
+       static const struct sunxi_wdog *wdog =
+                ((struct sunxi_timer_reg *)SUNXI_TIMER_BASE)->wdog;
+
+       /* Set the watchdog for its shortest interval (.5s) and wait */
+       writel(WDT_CFG_RESET, &wdog->cfg);
+       writel(WDT_MODE_EN, &wdog->mode);
+       writel(WDT_CTRL_KEY | WDT_CTRL_RESTART, &wdog->ctl);
+#endif
 }
 
 /* do some early init */
 void s_init(void)
 {
-#if !defined CONFIG_SPL_BUILD && (defined CONFIG_SUN7I || defined CONFIG_SUN6I)
+#if !defined CONFIG_SPL_BUILD && (defined CONFIG_SUN7I || \
+               defined CONFIG_SUN6I || defined CONFIG_SUN8I)
        /* Enable SMP mode for CPU0, by setting bit 6 of Auxiliary Ctl reg */
        asm volatile(
                "mrc p15, 0, r0, c1, c0, 1\n"
index ecbdb0162b2efcd17f6c6ee2a357543e2a71cab2..4a0d64fb30e64db6b996d35e4134469a0ccfd385 100644 (file)
@@ -180,6 +180,17 @@ void clock_set_pll1(unsigned int hz)
 }
 #endif
 
+unsigned int clock_get_pll5p(void)
+{
+       struct sunxi_ccm_reg *const ccm =
+               (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
+       uint32_t rval = readl(&ccm->pll5_cfg);
+       int n = ((rval & CCM_PLL5_CTRL_N_MASK) >> CCM_PLL5_CTRL_N_SHIFT);
+       int k = ((rval & CCM_PLL5_CTRL_K_MASK) >> CCM_PLL5_CTRL_K_SHIFT) + 1;
+       int p = ((rval & CCM_PLL5_CTRL_P_MASK) >> CCM_PLL5_CTRL_P_SHIFT);
+       return (24000000 * n * k) >> p;
+}
+
 unsigned int clock_get_pll6(void)
 {
        struct sunxi_ccm_reg *const ccm =
diff --git a/arch/arm/cpu/armv7/sunxi/clock_sun6i.c b/arch/arm/cpu/armv7/sunxi/clock_sun6i.c
new file mode 100644 (file)
index 0000000..1eae976
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * sun6i specific clock code
+ *
+ * (C) Copyright 2007-2012
+ * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
+ * Tom Cubie <tangliang@allwinnertech.com>
+ *
+ * (C) Copyright 2013 Luke Kenneth Casson Leighton <lkcl@lkcl.net>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/prcm.h>
+#include <asm/arch/sys_proto.h>
+
+void clock_init_uart(void)
+{
+       struct sunxi_ccm_reg *const ccm =
+               (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
+
+#if CONFIG_CONS_INDEX < 5
+       /* uart clock source is apb2 */
+       writel(APB2_CLK_SRC_OSC24M|
+              APB2_CLK_RATE_N_1|
+              APB2_CLK_RATE_M(1),
+              &ccm->apb2_div);
+
+       /* open the clock for uart */
+       setbits_le32(&ccm->apb2_gate,
+                    CLK_GATE_OPEN << (APB2_GATE_UART_SHIFT +
+                                      CONFIG_CONS_INDEX - 1));
+
+       /* deassert uart reset */
+       setbits_le32(&ccm->apb2_reset_cfg,
+                    1 << (APB2_RESET_UART_SHIFT +
+                          CONFIG_CONS_INDEX - 1));
+#else
+       /* enable R_PIO and R_UART clocks, and de-assert resets */
+       prcm_apb0_enable(PRCM_APB0_GATE_PIO | PRCM_APB0_GATE_UART);
+#endif
+
+       /* Dup with clock_init_safe(), drop once sun6i SPL support lands */
+       writel(PLL6_CFG_DEFAULT, &ccm->pll6_cfg);
+}
+
+int clock_twi_onoff(int port, int state)
+{
+       struct sunxi_ccm_reg *const ccm =
+               (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
+
+       if (port > 3)
+               return -1;
+
+       /* set the apb clock gate for twi */
+       if (state)
+               setbits_le32(&ccm->apb2_gate,
+                            CLK_GATE_OPEN << (APB2_GATE_TWI_SHIFT+port));
+       else
+               clrbits_le32(&ccm->apb2_gate,
+                            CLK_GATE_OPEN << (APB2_GATE_TWI_SHIFT+port));
+
+       return 0;
+}
+
+unsigned int clock_get_pll6(void)
+{
+       struct sunxi_ccm_reg *const ccm =
+               (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
+       uint32_t rval = readl(&ccm->pll6_cfg);
+       int n = ((rval & CCM_PLL6_CTRL_N_MASK) >> CCM_PLL6_CTRL_N_SHIFT) + 1;
+       int k = ((rval & CCM_PLL6_CTRL_K_MASK) >> CCM_PLL6_CTRL_K_SHIFT) + 1;
+       return 24000000 * n * k / 2;
+}
index 5cf35acc1e60127df04bc9b2c178ed5f46d8671c..4f2a09cd2e28cbd69a498bab61c06341f4235473 100644 (file)
@@ -23,8 +23,12 @@ int print_cpuinfo(void)
        case 7: puts("CPU:   Allwinner A10s (SUN5I)\n"); break;
        default: puts("CPU:   Allwinner A1X (SUN5I)\n");
        }
+#elif defined CONFIG_SUN6I
+       puts("CPU:   Allwinner A31 (SUN6I)\n");
 #elif defined CONFIG_SUN7I
        puts("CPU:   Allwinner A20 (SUN7I)\n");
+#elif defined CONFIG_SUN8I
+       puts("CPU:   Allwinner A23 (SUN8I)\n");
 #else
 #warning Please update cpu_info.c with correct CPU information
        puts("CPU:   SUNXI Family\n");
index 584f7420d7d239098e8924db9185fd2a7f24c5a3..3cf3cbf19adb25fce553a4f88a8d35ca6909999a 100644 (file)
@@ -252,15 +252,9 @@ static void mctl_setup_dram_clock(u32 clk, u32 mbus_clk)
 {
        u32 reg_val;
        struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
-
-       /* PLL5P and PLL6 are the potential clock sources for MBUS */
-       u32 pll6x_div, pll5p_div;
-       u32 pll6x_clk = clock_get_pll6() / 1000000;
-       u32 pll5p_clk = clk / 24 * 48;
+       u32 pll5p_clk, pll6x_clk;
+       u32 pll5p_div, pll6x_div;
        u32 pll5p_rate, pll6x_rate;
-#ifdef CONFIG_SUN7I
-       pll6x_clk *= 2; /* sun7i uses PLL6*2, sun5i uses just PLL6 */
-#endif
 
        /* setup DRAM PLL */
        reg_val = readl(&ccm->pll5_cfg);
@@ -268,33 +262,32 @@ static void mctl_setup_dram_clock(u32 clk, u32 mbus_clk)
        reg_val &= ~CCM_PLL5_CTRL_K_MASK;               /* set K to 0 (x1) */
        reg_val &= ~CCM_PLL5_CTRL_N_MASK;               /* set N to 0 (x0) */
        reg_val &= ~CCM_PLL5_CTRL_P_MASK;               /* set P to 0 (x1) */
+#ifdef CONFIG_OLD_SUNXI_KERNEL_COMPAT
+       /* Old kernels are hardcoded to P=1 (divide by 2) */
+       reg_val |= CCM_PLL5_CTRL_P(1);
+#endif
        if (clk >= 540 && clk < 552) {
-               /* dram = 540MHz, pll5p = 1080MHz */
-               pll5p_clk = 1080;
+               /* dram = 540MHz */
                reg_val |= CCM_PLL5_CTRL_M(CCM_PLL5_CTRL_M_X(2));
                reg_val |= CCM_PLL5_CTRL_K(CCM_PLL5_CTRL_K_X(3));
                reg_val |= CCM_PLL5_CTRL_N(CCM_PLL5_CTRL_N_X(15));
        } else if (clk >= 512 && clk < 528) {
-               /* dram = 512MHz, pll5p = 1536MHz */
-               pll5p_clk = 1536;
+               /* dram = 512MHz */
                reg_val |= CCM_PLL5_CTRL_M(CCM_PLL5_CTRL_M_X(3));
                reg_val |= CCM_PLL5_CTRL_K(CCM_PLL5_CTRL_K_X(4));
                reg_val |= CCM_PLL5_CTRL_N(CCM_PLL5_CTRL_N_X(16));
        } else if (clk >= 496 && clk < 504) {
-               /* dram = 496MHz, pll5p = 1488MHz */
-               pll5p_clk = 1488;
+               /* dram = 496MHz */
                reg_val |= CCM_PLL5_CTRL_M(CCM_PLL5_CTRL_M_X(3));
                reg_val |= CCM_PLL5_CTRL_K(CCM_PLL5_CTRL_K_X(2));
                reg_val |= CCM_PLL5_CTRL_N(CCM_PLL5_CTRL_N_X(31));
        } else if (clk >= 468 && clk < 480) {
-               /* dram = 468MHz, pll5p = 936MHz */
-               pll5p_clk = 936;
+               /* dram = 468MHz */
                reg_val |= CCM_PLL5_CTRL_M(CCM_PLL5_CTRL_M_X(2));
                reg_val |= CCM_PLL5_CTRL_K(CCM_PLL5_CTRL_K_X(3));
                reg_val |= CCM_PLL5_CTRL_N(CCM_PLL5_CTRL_N_X(13));
        } else if (clk >= 396 && clk < 408) {
-               /* dram = 396MHz, pll5p = 792MHz */
-               pll5p_clk = 792;
+               /* dram = 396MHz */
                reg_val |= CCM_PLL5_CTRL_M(CCM_PLL5_CTRL_M_X(2));
                reg_val |= CCM_PLL5_CTRL_K(CCM_PLL5_CTRL_K_X(3));
                reg_val |= CCM_PLL5_CTRL_N(CCM_PLL5_CTRL_N_X(11));
@@ -322,6 +315,13 @@ static void mctl_setup_dram_clock(u32 clk, u32 mbus_clk)
        /* setup MBUS clock */
        if (!mbus_clk)
                mbus_clk = 300;
+
+       /* PLL5P and PLL6 are the potential clock sources for MBUS */
+       pll6x_clk = clock_get_pll6() / 1000000;
+#ifdef CONFIG_SUN7I
+       pll6x_clk *= 2; /* sun7i uses PLL6*2, sun5i uses just PLL6 */
+#endif
+       pll5p_clk = clock_get_pll5p() / 1000000;
        pll6x_div = DIV_ROUND_UP(pll6x_clk, mbus_clk);
        pll5p_div = DIV_ROUND_UP(pll5p_clk, mbus_clk);
        pll6x_rate = pll6x_clk / pll6x_div;
diff --git a/arch/arm/cpu/armv7/sunxi/prcm.c b/arch/arm/cpu/armv7/sunxi/prcm.c
new file mode 100644 (file)
index 0000000..19b4938
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Sunxi A31 Power Management Unit
+ *
+ * (C) Copyright 2013 Oliver Schinagl <oliver@schinagl.nl>
+ * http://linux-sunxi.org
+ *
+ * Based on sun6i sources and earlier U-Boot Allwinner A10 SPL work
+ *
+ * (C) Copyright 2006-2013
+ * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
+ * Berg Xing <bergxing@allwinnertech.com>
+ * Tom Cubie <tangliang@allwinnertech.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <asm/io.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/prcm.h>
+#include <asm/arch/sys_proto.h>
+
+/* APB0 clock gate and reset bit offsets are the same. */
+void prcm_apb0_enable(u32 flags)
+{
+       struct sunxi_prcm_reg *prcm =
+               (struct sunxi_prcm_reg *)SUNXI_PRCM_BASE;
+
+       /* open the clock for module */
+       setbits_le32(&prcm->apb0_gate, flags);
+
+       /* deassert reset for module */
+       setbits_le32(&prcm->apb0_reset, flags);
+}
index bcae2d60334c9f6999073ce96dc1c74b35a1cb6a..3ea6d7651cb7fd87af753248aa91465a8e95863a 100644 (file)
@@ -17,6 +17,9 @@ config TEGRA124
 
 endchoice
 
+config USE_PRIVATE_LIBGCC
+       default y if SPL_BUILD
+
 config SYS_CPU
        default "arm720t" if SPL_BUILD
        default "armv7" if !SPL_BUILD
index fd77f3f0eff368e5a0a83762390826b79f3eada3..d98cec90180f5d133432d57c68bf6759649c0c0c 100644 (file)
@@ -194,7 +194,8 @@ static void rgb_enable(struct dc_com_reg *com)
                writel(rgb_sel_tab[i], &com->pin_output_sel[i]);
 }
 
-int setup_window(struct disp_ctl_win *win, struct fdt_disp_config *config)
+static int setup_window(struct disp_ctl_win *win,
+                       struct fdt_disp_config *config)
 {
        win->x = 0;
        win->y = 0;
index 54aec4ed509ecae278a83c69d397272b21ce03e7..3abdc7ba17392a702a5c30a3fc6ade7beaba3e52 100644 (file)
@@ -3,6 +3,9 @@ if TEGRA30
 choice
        prompt "Tegra30 board select"
 
+config TARGET_APALIS_T30
+       bool "Toradex Apalis T30 board"
+
 config TARGET_BEAVER
        bool "NVIDIA Tegra30 Beaver evaluation board"
 
@@ -20,6 +23,7 @@ endchoice
 config SYS_SOC
        default "tegra30"
 
+source "board/toradex/apalis_t30/Kconfig"
 source "board/nvidia/beaver/Kconfig"
 source "board/nvidia/cardhu/Kconfig"
 source "board/toradex/colibri_t30/Kconfig"
index b385e195447a71b3de2a762228458248999ce5b2..781b511a97b499090b4485f78a57d60070b10673 100644 (file)
@@ -3,6 +3,7 @@
 #
 
 obj-$(CONFIG_DISPLAY_BOARDINFO) += board_info.o
+obj-y += platdevice.o
 obj-y += boot-mode.o
 obj-$(CONFIG_BOARD_POSTCLK_INIT) += board_postclk_init.o bcu_init.o \
                sbc_init.o sg_init.o pll_init.o clkrst_init.o pinctrl.o
diff --git a/arch/arm/cpu/armv7/uniphier/ph1-ld4/platdevice.c b/arch/arm/cpu/armv7/uniphier/ph1-ld4/platdevice.c
new file mode 100644 (file)
index 0000000..0047223
--- /dev/null
@@ -0,0 +1,15 @@
+/*
+ * Copyright (C) 2014 Panasonic Corporation
+ *   Author: Masahiro Yamada <yamada.m@jp.panasonic.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <asm/arch/platdevice.h>
+
+#define UART_MASTER_CLK                36864000
+
+SERIAL_DEVICE(0, 0x54006800, UART_MASTER_CLK)
+SERIAL_DEVICE(1, 0x54006900, UART_MASTER_CLK)
+SERIAL_DEVICE(2, 0x54006a00, UART_MASTER_CLK)
+SERIAL_DEVICE(3, 0x54006b00, UART_MASTER_CLK)
index 712afd1beebe74f0163041ee0adf517c68acd12c..e11f4f6d8b3f36c44d340f5bafdf9d8fd4858b12 100644 (file)
@@ -3,6 +3,7 @@
 #
 
 obj-$(CONFIG_DISPLAY_BOARDINFO) += board_info.o
+obj-y += platdevice.o
 obj-y += boot-mode.o
 obj-$(CONFIG_BOARD_POSTCLK_INIT) += board_postclk_init.o sbc_init.o \
                                sg_init.o pll_init.o clkrst_init.o pinctrl.o
diff --git a/arch/arm/cpu/armv7/uniphier/ph1-pro4/platdevice.c b/arch/arm/cpu/armv7/uniphier/ph1-pro4/platdevice.c
new file mode 100644 (file)
index 0000000..6da921e
--- /dev/null
@@ -0,0 +1,15 @@
+/*
+ * Copyright (C) 2014 Panasonic Corporation
+ *   Author: Masahiro Yamada <yamada.m@jp.panasonic.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <asm/arch/platdevice.h>
+
+#define UART_MASTER_CLK                73728000
+
+SERIAL_DEVICE(0, 0x54006800, UART_MASTER_CLK)
+SERIAL_DEVICE(1, 0x54006900, UART_MASTER_CLK)
+SERIAL_DEVICE(2, 0x54006a00, UART_MASTER_CLK)
+SERIAL_DEVICE(3, 0x54006b00, UART_MASTER_CLK)
index b385e195447a71b3de2a762228458248999ce5b2..781b511a97b499090b4485f78a57d60070b10673 100644 (file)
@@ -3,6 +3,7 @@
 #
 
 obj-$(CONFIG_DISPLAY_BOARDINFO) += board_info.o
+obj-y += platdevice.o
 obj-y += boot-mode.o
 obj-$(CONFIG_BOARD_POSTCLK_INIT) += board_postclk_init.o bcu_init.o \
                sbc_init.o sg_init.o pll_init.o clkrst_init.o pinctrl.o
diff --git a/arch/arm/cpu/armv7/uniphier/ph1-sld8/platdevice.c b/arch/arm/cpu/armv7/uniphier/ph1-sld8/platdevice.c
new file mode 100644 (file)
index 0000000..59d054a
--- /dev/null
@@ -0,0 +1,15 @@
+/*
+ * Copyright (C) 2014 Panasonic Corporation
+ *   Author: Masahiro Yamada <yamada.m@jp.panasonic.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <asm/arch/platdevice.h>
+
+#define UART_MASTER_CLK                80000000
+
+SERIAL_DEVICE(0, 0x54006800, UART_MASTER_CLK)
+SERIAL_DEVICE(1, 0x54006900, UART_MASTER_CLK)
+SERIAL_DEVICE(2, 0x54006a00, UART_MASTER_CLK)
+SERIAL_DEVICE(3, 0x54006b00, UART_MASTER_CLK)
index 433da09d10c2ad59efa3fb2db9c8bf971951039c..b6a84a577478a11374ad3e46ed75bc2c437f59ea 100644 (file)
@@ -9,6 +9,7 @@
 #include <asm/io.h>
 #include <asm/arch/clock.h>
 #include <asm/arch/funcmux.h>
+#include <asm/arch/mc.h>
 #include <asm/arch/tegra.h>
 #include <asm/arch-tegra/board.h>
 #include <asm/arch-tegra/pmc.h>
@@ -27,55 +28,6 @@ enum {
        UART_COUNT = 5,
 };
 
-#if defined(CONFIG_TEGRA20) || defined(CONFIG_TEGRA30) || \
-       defined(CONFIG_TEGRA114)
-/*
- * Boot ROM initializes the odmdata in APBDEV_PMC_SCRATCH20_0,
- * so we are using this value to identify memory size.
- */
-unsigned int query_sdram_size(void)
-{
-       struct pmc_ctlr *const pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE;
-       u32 reg;
-
-       reg = readl(&pmc->pmc_scratch20);
-       debug("pmc->pmc_scratch20 (ODMData) = 0x%08x\n", reg);
-
-#if defined(CONFIG_TEGRA20)
-       /* bits 30:28 in OdmData are used for RAM size on T20  */
-       reg &= 0x70000000;
-
-       switch ((reg) >> 28) {
-       case 1:
-               return 0x10000000;      /* 256 MB */
-       case 0:
-       case 2:
-       default:
-               return 0x20000000;      /* 512 MB */
-       case 3:
-               return 0x40000000;      /* 1GB */
-       }
-#else  /* Tegra30/Tegra114 */
-       /* bits 31:28 in OdmData are used for RAM size on T30  */
-       switch ((reg) >> 28) {
-       case 0:
-       case 1:
-       default:
-               return 0x10000000;      /* 256 MB */
-       case 2:
-               return 0x20000000;      /* 512 MB */
-       case 3:
-               return 0x30000000;      /* 768 MB */
-       case 4:
-               return 0x40000000;      /* 1GB */
-       case 8:
-               return 0x7ff00000;      /* 2GB - 1MB */
-       }
-#endif
-}
-#else
-#include <asm/arch/mc.h>
-
 /* Read the RAM size directly from the memory controller */
 unsigned int query_sdram_size(void)
 {
@@ -83,12 +35,22 @@ unsigned int query_sdram_size(void)
        u32 size_mb;
 
        size_mb = readl(&mc->mc_emem_cfg);
+#if defined(CONFIG_TEGRA20)
+       debug("mc->mc_emem_cfg (MEM_SIZE_KB) = 0x%08x\n", size_mb);
+       size_mb = get_ram_size((void *)PHYS_SDRAM_1, size_mb * 1024);
+#else
        debug("mc->mc_emem_cfg (MEM_SIZE_MB) = 0x%08x\n", size_mb);
+       size_mb = get_ram_size((void *)PHYS_SDRAM_1, size_mb * 1024 * 1024);
+#endif
 
-       return size_mb * 1024 * 1024;
-}
+#if defined(CONFIG_TEGRA30) || defined(CONFIG_TEGRA114)
+       /* External memory limited to 2047 MB due to IROM/HI-VEC */
+       if (size_mb == SZ_2G) size_mb -= SZ_1M;
 #endif
 
+       return size_mb;
+}
+
 int dram_init(void)
 {
        /* We do not initialise DRAM here. We just query the size */
index de20325ecf3239666e5da6e5d23cbcba5811108c..5933c35ddd43e9b4242f33fc3d9952404d82088a 100644 (file)
@@ -8,7 +8,7 @@
 #include <common.h>
 #include <linux/ctype.h>
 
-void upstring(char *s)
+static void upstring(char *s)
 {
        while (*s) {
                *s = toupper(*s);
index c37580ed842e6fddb459efb631b2e4796afbff04..c34606334dbea34363aba579097eed3bc8a20200 100644 (file)
@@ -22,6 +22,7 @@ dtb-$(CONFIG_TEGRA) += tegra20-harmony.dtb \
        tegra20-ventana.dtb \
        tegra20-whistler.dtb \
        tegra20-colibri_t20_iris.dtb \
+       tegra30-apalis.dtb \
        tegra30-beaver.dtb \
        tegra30-cardhu.dtb \
        tegra30-colibri.dtb \
index 2f66deda9f5c171b4394046e14dba7b4814588df..e70b4d1f1facc8fa8d8fa520dc8996c4a6348eb7 100644 (file)
        model = "TI AM335x BeagleBone";
        compatible = "ti,am335x-bone", "ti,am33xx";
 
+       chosen {
+               stdout-path = &uart0;
+       };
+
        cpus {
                cpu@0 {
                        cpu0-supply = <&dcdc2_reg>;
diff --git a/arch/arm/dts/dt-bindings/gpio/gpio.h b/arch/arm/dts/dt-bindings/gpio/gpio.h
deleted file mode 100644 (file)
index e6b1e0a..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * This header provides constants for most GPIO bindings.
- *
- * Most GPIO bindings include a flags cell as part of the GPIO specifier.
- * In most cases, the format of the flags cell uses the standard values
- * defined in this header.
- */
-
-#ifndef _DT_BINDINGS_GPIO_GPIO_H
-#define _DT_BINDINGS_GPIO_GPIO_H
-
-#define GPIO_ACTIVE_HIGH 0
-#define GPIO_ACTIVE_LOW 1
-
-#endif
index 110eb43a2f8b4aa9af5323e2c22937badd2a79f3..77fad48fb4bd72614d575660af1ae81d2188f9c1 100644 (file)
@@ -7,9 +7,16 @@
  * SPDX-License-Identifier:    GPL-2.0+
  */
 
-/include/ "skeleton.dtsi"
+#include "skeleton.dtsi"
 
 / {
+       combiner: interrupt-controller@10440000 {
+               compatible = "samsung,exynos4210-combiner";
+               #interrupt-cells = <2>;
+               interrupt-controller;
+               reg = <0x10440000 0x1000>;
+       };
+
        serial@13800000 {
                compatible = "samsung,exynos4210-uart";
                reg = <0x13800000 0x3c>;
index 15059d22022738954eea77af7f8e30b07bd8696e..dd2476c1a39e35f74beb2f21d2cde8a44dcdbd04 100644 (file)
@@ -8,8 +8,8 @@
  */
 
 /dts-v1/;
-/include/ "skeleton.dtsi"
-/include/ "exynos4.dtsi"
+#include "skeleton.dtsi"
+#include "exynos4210.dtsi"
 
 / {
        model = "Insignal Origen evaluation board based on Exynos4210";
diff --git a/arch/arm/dts/exynos4210-pinctrl-uboot.dtsi b/arch/arm/dts/exynos4210-pinctrl-uboot.dtsi
new file mode 100644 (file)
index 0000000..ee071c1
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * U-Boot additions to enable a generic Exynos GPIO driver
+ *
+ * Copyright (c) 2014 Google, Inc
+ */
+
+/{
+       pinctrl_0: pinctrl@11400000 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "samsung,exynos4210-pinctrl";
+       };
+
+       pinctrl_1: pinctrl@11000000 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               gpy0: gpy0 {
+                       reg = <0xc00>;
+               };
+       };
+
+       pinctrl_2: pinctrl@03860000 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+       };
+
+};
diff --git a/arch/arm/dts/exynos4210-pinctrl.dtsi b/arch/arm/dts/exynos4210-pinctrl.dtsi
new file mode 100644 (file)
index 0000000..bda17f7
--- /dev/null
@@ -0,0 +1,304 @@
+/*
+ * Samsung's Exynos4210 SoC pin-mux and pin-config device tree source
+ *
+ * Copyright (c) 2011-2012 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ * Copyright (c) 2011-2012 Linaro Ltd.
+ *             www.linaro.org
+ *
+ * Samsung's Exynos4210 SoC pin-mux and pin-config optiosn are listed as device
+ * tree nodes are listed in this file.
+ *
+ * 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.
+*/
+
+/ {
+       pinctrl@11400000 {
+               gpa0: gpa0 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpa1: gpa1 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpb: gpb {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpc0: gpc0 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpc1: gpc1 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpd0: gpd0 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpd1: gpd1 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpe0: gpe0 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpe1: gpe1 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpe2: gpe2 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpe3: gpe3 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpe4: gpe4 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpf0: gpf0 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpf1: gpf1 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpf2: gpf2 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpf3: gpf3 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+       };
+
+       pinctrl@11000000 {
+               gpj0: gpj0 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpj1: gpj1 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpk0: gpk0 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpk1: gpk1 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpk2: gpk2 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpk3: gpk3 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpl0: gpl0 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpl1: gpl1 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpl2: gpl2 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpy0: gpy0 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpy1: gpy1 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpy2: gpy2 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpy3: gpy3 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpy4: gpy4 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpy5: gpy5 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpy6: gpy6 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpx0: gpx0 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       interrupt-parent = <&gic>;
+                       interrupts = <0 16 0>, <0 17 0>, <0 18 0>, <0 19 0>,
+                                    <0 20 0>, <0 21 0>, <0 22 0>, <0 23 0>;
+                       #interrupt-cells = <2>;
+               };
+
+               gpx1: gpx1 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       interrupt-parent = <&gic>;
+                       interrupts = <0 24 0>, <0 25 0>, <0 26 0>, <0 27 0>,
+                                    <0 28 0>, <0 29 0>, <0 30 0>, <0 31 0>;
+                       #interrupt-cells = <2>;
+               };
+
+               gpx2: gpx2 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpx3: gpx3 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+       };
+
+       pinctrl@03860000 {
+               gpz: gpz {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+       };
+};
index c390c8f0c8afae80b3f807c95fec89330ad22907..00cad0447d8fbb3b29e6ce393a2f0cdb6269bf66 100644 (file)
@@ -7,7 +7,7 @@
  */
 
 /dts-v1/;
-/include/ "exynos4.dtsi"
+#include "exynos4.dtsi"
 
 / {
        model = "Samsung SMDKV310 on Exynos4210";
index 0ff69393b758621eb5d9d953cce61269ca2d5fba..81188bca13b429a8c761db4020c2d507fbeb1078 100644 (file)
@@ -8,7 +8,7 @@
  */
 
 /dts-v1/;
-/include/ "exynos4.dtsi"
+#include "exynos4210.dtsi"
 
 / {
        model = "Samsung Trats based on Exynos4210";
index 6941906aaa353b3a2ebcd5bb405a824937fc5a72..9139810b1a924e7fab07b306f5c121103ff90c4a 100644 (file)
@@ -8,7 +8,7 @@
  */
 
 /dts-v1/;
-/include/ "exynos4.dtsi"
+#include "exynos4210.dtsi"
 
 / {
        model = "Samsung Universal C210 based on Exynos4210 rev0";
                status = "disabled";
        };
 
+       soft-spi {
+               compatible = "u-boot,soft-spi";
+               cs-gpio = <&gpio 235 0>;        /* Y43 */
+               sclk-gpio = <&gpio 225 0>;      /* Y31 */
+               mosi-gpio = <&gpio 227 0>;      /* Y33 */
+               miso-gpio = <&gpio 224 0>;      /* Y30 */
+               spi-delay-us = <1>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               cs@0 {
+               };
+       };
+
        fimd@11c00000 {
                compatible = "samsung,exynos-fimd";
                reg = <0x11c00000 0xa4>;
diff --git a/arch/arm/dts/exynos4210.dtsi b/arch/arm/dts/exynos4210.dtsi
new file mode 100644 (file)
index 0000000..634a5c1
--- /dev/null
@@ -0,0 +1,156 @@
+/*
+ * Samsung's Exynos4210 SoC device tree source
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ * Copyright (c) 2010-2011 Linaro Ltd.
+ *             www.linaro.org
+ *
+ * Samsung's Exynos4210 SoC device nodes are listed in this file. Exynos4210
+ * based board files can include this file and provide values for board specfic
+ * bindings.
+ *
+ * Note: This file does not include device nodes for all the controllers in
+ * Exynos4210 SoC. As device tree coverage for Exynos4210 increases, additional
+ * nodes can be added to this file.
+ *
+ * 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.
+*/
+
+#include "exynos4.dtsi"
+#include "exynos4210-pinctrl.dtsi"
+#include "exynos4210-pinctrl-uboot.dtsi"
+
+/ {
+       compatible = "samsung,exynos4210";
+
+       aliases {
+               pinctrl0 = &pinctrl_0;
+               pinctrl1 = &pinctrl_1;
+               pinctrl2 = &pinctrl_2;
+       };
+
+       pd_lcd1: lcd1-power-domain@10023CA0 {
+               compatible = "samsung,exynos4210-pd";
+               reg = <0x10023CA0 0x20>;
+       };
+
+       gic: interrupt-controller@10490000 {
+               cpu-offset = <0x8000>;
+       };
+
+       combiner: interrupt-controller@10440000 {
+               samsung,combiner-nr = <16>;
+               interrupts = <0 0 0>, <0 1 0>, <0 2 0>, <0 3 0>,
+                            <0 4 0>, <0 5 0>, <0 6 0>, <0 7 0>,
+                            <0 8 0>, <0 9 0>, <0 10 0>, <0 11 0>,
+                            <0 12 0>, <0 13 0>, <0 14 0>, <0 15 0>;
+       };
+
+       mct@10050000 {
+               compatible = "samsung,exynos4210-mct";
+               reg = <0x10050000 0x800>;
+               interrupt-parent = <&mct_map>;
+               interrupts = <0>, <1>, <2>, <3>, <4>, <5>;
+               clocks = <&clock 3>, <&clock 344>;
+               clock-names = "fin_pll", "mct";
+
+               mct_map: mct-map {
+                       #interrupt-cells = <1>;
+                       #address-cells = <0>;
+                       #size-cells = <0>;
+                       interrupt-map = <0 &gic 0 57 0>,
+                                       <1 &gic 0 69 0>,
+                                       <2 &combiner 12 6>,
+                                       <3 &combiner 12 7>,
+                                       <4 &gic 0 42 0>,
+                                       <5 &gic 0 48 0>;
+               };
+       };
+
+       clock: clock-controller@10030000 {
+               compatible = "samsung,exynos4210-clock";
+               reg = <0x10030000 0x20000>;
+               #clock-cells = <1>;
+       };
+
+       pmu {
+               compatible = "arm,cortex-a9-pmu";
+               interrupt-parent = <&combiner>;
+               interrupts = <2 2>, <3 2>;
+       };
+
+       pinctrl_0: pinctrl@11400000 {
+               compatible = "samsung,exynos4210-pinctrl";
+               reg = <0x11400000 0x1000>;
+               interrupts = <0 47 0>;
+       };
+
+       pinctrl_1: pinctrl@11000000 {
+               compatible = "samsung,exynos4210-pinctrl";
+               reg = <0x11000000 0x1000>;
+               interrupts = <0 46 0>;
+
+               wakup_eint: wakeup-interrupt-controller {
+                       compatible = "samsung,exynos4210-wakeup-eint";
+                       interrupt-parent = <&gic>;
+                       interrupts = <0 32 0>;
+               };
+       };
+
+       pinctrl_2: pinctrl@03860000 {
+               compatible = "samsung,exynos4210-pinctrl";
+               reg = <0x03860000 0x1000>;
+       };
+
+       tmu@100C0000 {
+               compatible = "samsung,exynos4210-tmu";
+               interrupt-parent = <&combiner>;
+               reg = <0x100C0000 0x100>;
+               interrupts = <2 4>;
+               clocks = <&clock 383>;
+               clock-names = "tmu_apbif";
+               status = "disabled";
+       };
+
+       g2d@12800000 {
+               compatible = "samsung,s5pv210-g2d";
+               reg = <0x12800000 0x1000>;
+               interrupts = <0 89 0>;
+               clocks = <&clock 177>, <&clock 277>;
+               clock-names = "sclk_fimg2d", "fimg2d";
+               status = "disabled";
+       };
+
+       camera {
+               clocks = <&clock 132>, <&clock 133>, <&clock 351>, <&clock 352>;
+               clock-names = "sclk_cam0", "sclk_cam1", "pxl_async0", "pxl_async1";
+
+               fimc_0: fimc@11800000 {
+                       samsung,pix-limits = <4224 8192 1920 4224>;
+                       samsung,mainscaler-ext;
+                       samsung,cam-if;
+               };
+
+               fimc_1: fimc@11810000 {
+                       samsung,pix-limits = <4224 8192 1920 4224>;
+                       samsung,mainscaler-ext;
+                       samsung,cam-if;
+               };
+
+               fimc_2: fimc@11820000 {
+                       samsung,pix-limits = <4224 8192 1920 4224>;
+                       samsung,mainscaler-ext;
+                       samsung,lcd-wb;
+               };
+
+               fimc_3: fimc@11830000 {
+                       samsung,pix-limits = <1920 8192 1366 1920>;
+                       samsung,rotators = <0>;
+                       samsung,mainscaler-ext;
+                       samsung,lcd-wb;
+               };
+       };
+};
index 24d0bf18e3e7654c3dac33566edb4cfc14f4174b..4c5e2b39be5cb51181287e6390872b0016df7f5f 100644 (file)
@@ -8,7 +8,7 @@
  */
 
 /dts-v1/;
-/include/ "exynos4.dtsi"
+#include "exynos4.dtsi"
 
 / {
        model = "Odroid based on Exynos4412";
index cc58c878b82ba713f5ca8325642440dafcfd6d1f..3b1e4588b54b3cfb9bd0b5c6bcf3424239eb76c8 100644 (file)
@@ -8,7 +8,7 @@
  */
 
 /dts-v1/;
-/include/ "exynos4.dtsi"
+#include "exynos4412.dtsi"
 
 / {
        model = "Samsung Trats2 based on Exynos4412";
diff --git a/arch/arm/dts/exynos4412.dtsi b/arch/arm/dts/exynos4412.dtsi
new file mode 100644 (file)
index 0000000..87b339c
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Samsung's Exynos4412 SoC device tree source
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * Samsung's Exynos4412 SoC device nodes are listed in this file. Exynos4412
+ * based board files can include this file and provide values for board specfic
+ * bindings.
+ *
+ * Note: This file does not include device nodes for all the controllers in
+ * Exynos4412 SoC. As device tree coverage for Exynos4412 increases, additional
+ * nodes can be added to this file.
+ *
+ * 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.
+*/
+
+#include "exynos4x12.dtsi"
+
+/ {
+       compatible = "samsung,exynos4412";
+
+       gic: interrupt-controller@10490000 {
+               cpu-offset = <0x4000>;
+       };
+
+       interrupt-controller@10440000 {
+               samsung,combiner-nr = <20>;
+               interrupts = <0 0 0>, <0 1 0>, <0 2 0>, <0 3 0>,
+                            <0 4 0>, <0 5 0>, <0 6 0>, <0 7 0>,
+                            <0 8 0>, <0 9 0>, <0 10 0>, <0 11 0>,
+                            <0 12 0>, <0 13 0>, <0 14 0>, <0 15 0>,
+                            <0 107 0>, <0 108 0>, <0 48 0>, <0 42 0>;
+       };
+
+};
diff --git a/arch/arm/dts/exynos4x12-pinctrl-uboot.dtsi b/arch/arm/dts/exynos4x12-pinctrl-uboot.dtsi
new file mode 100644 (file)
index 0000000..c02796d
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * U-Boot additions to enable a generic Exynos GPIO driver
+ *
+ * Copyright (c) 2014 Google, Inc
+ */
+
+/{
+       pinctrl_0: pinctrl@11400000 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               gpf0: gpf0 {
+                       reg = <0xc180>;
+               };
+               gpj0: gpj0 {
+                       reg = <0x240>;
+               };
+       };
+
+       pinctrl_1: pinctrl@11000000 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               gpk0: gpk0 {
+                       reg = <0x40>;
+               };
+               gpm0: gpm0 {
+                       reg = <0x260>;
+               };
+               gpy0: gpy0 {
+                       reg = <0x120>;
+               };
+               gpx0: gpx0 {
+                       reg = <0xc00>;
+               };
+       };
+
+       pinctrl_2: pinctrl@03860000 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+       };
+
+       pinctrl_3: pinctrl@106E0000 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+       };
+
+};
diff --git a/arch/arm/dts/exynos4x12-pinctrl.dtsi b/arch/arm/dts/exynos4x12-pinctrl.dtsi
new file mode 100644 (file)
index 0000000..93f3998
--- /dev/null
@@ -0,0 +1,344 @@
+/*
+ * Samsung's Exynos4x12 SoCs pin-mux and pin-config device tree source
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * Samsung's Exynos4x12 SoCs pin-mux and pin-config optiosn are listed as device
+ * tree nodes are listed in this file.
+ *
+ * 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.
+*/
+
+/ {
+       pinctrl@11400000 {
+               gpa0: gpa0 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpa1: gpa1 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpb: gpb {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpc0: gpc0 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpc1: gpc1 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpd0: gpd0 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpd1: gpd1 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpf0: gpf0 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpf1: gpf1 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpf2: gpf2 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpf3: gpf3 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpj0: gpj0 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpj1: gpj1 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+       };
+
+       pinctrl@11000000 {
+               gpk0: gpk0 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpk1: gpk1 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpk2: gpk2 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpk3: gpk3 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpl0: gpl0 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpl1: gpl1 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpl2: gpl2 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpm0: gpm0 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpm1: gpm1 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpm2: gpm2 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpm3: gpm3 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpm4: gpm4 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpy0: gpy0 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpy1: gpy1 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpy2: gpy2 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpy3: gpy3 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpy4: gpy4 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpy5: gpy5 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpy6: gpy6 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpx0: gpx0 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       interrupt-parent = <&gic>;
+                       interrupts = <0 16 0>, <0 17 0>, <0 18 0>, <0 19 0>,
+                                    <0 20 0>, <0 21 0>, <0 22 0>, <0 23 0>;
+                       #interrupt-cells = <2>;
+               };
+
+               gpx1: gpx1 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       interrupt-parent = <&gic>;
+                       interrupts = <0 24 0>, <0 25 0>, <0 26 0>, <0 27 0>,
+                                    <0 28 0>, <0 29 0>, <0 30 0>, <0 31 0>;
+                       #interrupt-cells = <2>;
+               };
+
+               gpx2: gpx2 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpx3: gpx3 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+       };
+
+       pinctrl@03860000 {
+               gpz: gpz {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+       };
+
+       pinctrl@106E0000 {
+               gpv0: gpv0 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpv1: gpv1 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpv2: gpv2 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpv3: gpv3 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpv4: gpv4 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+       };
+};
diff --git a/arch/arm/dts/exynos4x12.dtsi b/arch/arm/dts/exynos4x12.dtsi
new file mode 100644 (file)
index 0000000..5d58c6e
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ * Samsung's Exynos4x12 SoCs device tree source
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * Samsung's Exynos4x12 SoCs device nodes are listed in this file. Exynos4x12
+ * based board files can include this file and provide values for board specfic
+ * bindings.
+ *
+ * Note: This file does not include device nodes for all the controllers in
+ * Exynos4x12 SoC. As device tree coverage for Exynos4x12 increases, additional
+ * nodes can be added to this file.
+ *
+ * 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.
+*/
+
+#include "exynos4.dtsi"
+#include "exynos4x12-pinctrl.dtsi"
+#include "exynos4x12-pinctrl-uboot.dtsi"
+
+/ {
+       aliases {
+               pinctrl0 = &pinctrl_0;
+               pinctrl1 = &pinctrl_1;
+               pinctrl2 = &pinctrl_2;
+               pinctrl3 = &pinctrl_3;
+               mshc0 = &mshc_0;
+       };
+
+       pd_isp: isp-power-domain@10023CA0 {
+               compatible = "samsung,exynos4210-pd";
+               reg = <0x10023CA0 0x20>;
+       };
+
+       clock: clock-controller@10030000 {
+               compatible = "samsung,exynos4412-clock";
+               reg = <0x10030000 0x20000>;
+               #clock-cells = <1>;
+       };
+
+       mct@10050000 {
+               compatible = "samsung,exynos4412-mct";
+               reg = <0x10050000 0x800>;
+               interrupt-parent = <&mct_map>;
+               interrupts = <0>, <1>, <2>, <3>, <4>;
+               clocks = <&clock 3>, <&clock 344>;
+               clock-names = "fin_pll", "mct";
+
+               mct_map: mct-map {
+                       #interrupt-cells = <1>;
+                       #address-cells = <0>;
+                       #size-cells = <0>;
+                       interrupt-map = <0 &gic 0 57 0>,
+                                       <1 &combiner 12 5>,
+                                       <2 &combiner 12 6>,
+                                       <3 &combiner 12 7>,
+                                       <4 &gic 1 12 0>;
+               };
+       };
+
+       pinctrl_0: pinctrl@11400000 {
+               compatible = "samsung,exynos4x12-pinctrl";
+               reg = <0x11400000 0x1000>;
+               interrupts = <0 47 0>;
+       };
+
+       pinctrl_1: pinctrl@11000000 {
+               compatible = "samsung,exynos4x12-pinctrl";
+               reg = <0x11000000 0x1000>;
+               interrupts = <0 46 0>;
+
+               wakup_eint: wakeup-interrupt-controller {
+                       compatible = "samsung,exynos4210-wakeup-eint";
+                       interrupt-parent = <&gic>;
+                       interrupts = <0 32 0>;
+               };
+       };
+
+       pinctrl_2: pinctrl@03860000 {
+               compatible = "samsung,exynos4x12-pinctrl";
+               reg = <0x03860000 0x1000>;
+               interrupt-parent = <&combiner>;
+               interrupts = <10 0>;
+       };
+
+       pinctrl_3: pinctrl@106E0000 {
+               compatible = "samsung,exynos4x12-pinctrl";
+               reg = <0x106E0000 0x1000>;
+               interrupts = <0 72 0>;
+       };
+
+       g2d@10800000 {
+               compatible = "samsung,exynos4212-g2d";
+               reg = <0x10800000 0x1000>;
+               interrupts = <0 89 0>;
+               clocks = <&clock 177>, <&clock 277>;
+               clock-names = "sclk_fimg2d", "fimg2d";
+               status = "disabled";
+       };
+
+       mshc_0: mmc@12550000 {
+               compatible = "samsung,exynos4412-dw-mshc";
+               reg = <0x12550000 0x1000>;
+               interrupts = <0 77 0>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               fifo-depth = <0x80>;
+               clocks = <&clock 301>, <&clock 149>;
+               clock-names = "biu", "ciu";
+               status = "disabled";
+       };
+};
index a2b533a1368ccb503701cb8c77eeaf7f092c37c7..e53906892c82de8b0ba922927fff25c64c859045 100644 (file)
@@ -5,11 +5,38 @@
  * SPDX-License-Identifier:    GPL-2.0+
  */
 
-/include/ "skeleton.dtsi"
+#include "skeleton.dtsi"
 
 / {
        compatible = "samsung,exynos5";
 
+       combiner: interrupt-controller@10440000 {
+               compatible = "samsung,exynos4210-combiner";
+               #interrupt-cells = <2>;
+               interrupt-controller;
+               samsung,combiner-nr = <32>;
+               reg = <0x10440000 0x1000>;
+               interrupts =    <0 0 0>, <0 1 0>, <0 2 0>, <0 3 0>,
+                               <0 4 0>, <0 5 0>, <0 6 0>, <0 7 0>,
+                               <0 8 0>, <0 9 0>, <0 10 0>, <0 11 0>,
+                               <0 12 0>, <0 13 0>, <0 14 0>, <0 15 0>,
+                               <0 16 0>, <0 17 0>, <0 18 0>, <0 19 0>,
+                               <0 20 0>, <0 21 0>, <0 22 0>, <0 23 0>,
+                               <0 24 0>, <0 25 0>, <0 26 0>, <0 27 0>,
+                               <0 28 0>, <0 29 0>, <0 30 0>, <0 31 0>;
+       };
+
+       gic: interrupt-controller@10481000 {
+               compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic";
+               #interrupt-cells = <3>;
+               interrupt-controller;
+               reg =   <0x10481000 0x1000>,
+                       <0x10482000 0x1000>,
+                       <0x10484000 0x2000>,
+                       <0x10486000 0x2000>;
+               interrupts = <1 9 0xf04>;
+       };
+
        sromc@12250000 {
                compatible = "samsung,exynos-sromc";
                reg = <0x12250000 0x20>;
                #size-cells = <0>;
        };
 
+       combiner: interrupt-controller@10440000 {
+               compatible = "samsung,exynos4210-combiner";
+               #interrupt-cells = <2>;
+               interrupt-controller;
+               samsung,combiner-nr = <32>;
+               reg = <0x10440000 0x1000>;
+               interrupts =    <0 0 0>, <0 1 0>, <0 2 0>, <0 3 0>,
+                               <0 4 0>, <0 5 0>, <0 6 0>, <0 7 0>,
+                               <0 8 0>, <0 9 0>, <0 10 0>, <0 11 0>,
+                               <0 12 0>, <0 13 0>, <0 14 0>, <0 15 0>,
+                               <0 16 0>, <0 17 0>, <0 18 0>, <0 19 0>,
+                               <0 20 0>, <0 21 0>, <0 22 0>, <0 23 0>,
+                               <0 24 0>, <0 25 0>, <0 26 0>, <0 27 0>,
+                               <0 28 0>, <0 29 0>, <0 30 0>, <0 31 0>;
+       };
+
+       gic: interrupt-controller@10481000 {
+               compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic";
+               #interrupt-cells = <3>;
+               interrupt-controller;
+               reg =   <0x10481000 0x1000>,
+                       <0x10482000 0x1000>,
+                       <0x10484000 0x2000>,
+                       <0x10486000 0x2000>;
+               interrupts = <1 9 0xf04>;
+       };
+
        i2c@12c60000 {
                #address-cells = <1>;
                #size-cells = <0>;
                compatible = "samsung,exynos4210-uart";
                reg = <0x12C30000 0x100>;
                interrupts = <0 54 0>;
+               u-boot,dm-pre-reloc;
                id = <3>;
        };
 
diff --git a/arch/arm/dts/exynos5250-pinctrl-uboot.dtsi b/arch/arm/dts/exynos5250-pinctrl-uboot.dtsi
new file mode 100644 (file)
index 0000000..7edb0ca
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * U-Boot additions to enable a generic Exynos GPIO driver
+ *
+ * Copyright (c) 2014 Google, Inc
+ */
+
+/{
+       pinctrl_0: pinctrl@11400000 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               gpc4: gpc4 {
+                       reg = <0x2e0>;
+               };
+               gpx0: gpx0 {
+                       reg = <0xc00>;
+               };
+       };
+
+       pinctrl_1: pinctrl@13400000 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+       };
+
+       pinctrl_2: pinctrl@10d10000 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               gpv2: gpv2 {
+                       reg = <0x060>;
+               };
+               gpv4: gpv4 {
+                       reg = <0xc0>;
+               };
+       };
+
+       pinctrl_3: pinctrl@03860000 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+       };
+
+};
diff --git a/arch/arm/dts/exynos5250-pinctrl.dtsi b/arch/arm/dts/exynos5250-pinctrl.dtsi
new file mode 100644 (file)
index 0000000..67755a1
--- /dev/null
@@ -0,0 +1,331 @@
+/*
+ * Samsung's Exynos5250 SoC pin-mux and pin-config device tree source
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * Samsung's Exynos5250 SoC pin-mux and pin-config optiosn are listed as device
+ * tree nodes are listed in this file.
+ *
+ * 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.
+*/
+
+/ {
+       pinctrl@11400000 {
+               gpa0: gpa0 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpa1: gpa1 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpa2: gpa2 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpb0: gpb0 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpb1: gpb1 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpb2: gpb2 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpb3: gpb3 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpc0: gpc0 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpc1: gpc1 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpc2: gpc2 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpc3: gpc3 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpd0: gpd0 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpd1: gpd1 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpy0: gpy0 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpy1: gpy1 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpy2: gpy2 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpy3: gpy3 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpy4: gpy4 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpy5: gpy5 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpy6: gpy6 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpc4: gpc4 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpx0: gpx0 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       interrupt-parent = <&combiner>;
+                       #interrupt-cells = <2>;
+                       interrupts = <23 0>, <24 0>, <25 0>, <25 1>,
+                                    <26 0>, <26 1>, <27 0>, <27 1>;
+               };
+
+               gpx1: gpx1 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       interrupt-parent = <&combiner>;
+                       #interrupt-cells = <2>;
+                       interrupts = <28 0>, <28 1>, <29 0>, <29 1>,
+                                    <30 0>, <30 1>, <31 0>, <31 1>;
+               };
+
+               gpx2: gpx2 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpx3: gpx3 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+       };
+
+       pinctrl@13400000 {
+               gpe0: gpe0 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpe1: gpe1 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpf0: gpf0 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpf1: gpf1 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpg0: gpg0 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpg1: gpg1 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpg2: gpg2 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gph0: gph0 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gph1: gph1 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+       };
+
+       pinctrl@10d10000 {
+               gpv0: gpv0 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpv1: gpv1 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpv2: gpv2 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpv3: gpv3 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpv4: gpv4 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+       };
+
+       pinctrl@03860000 {
+               gpz: gpz {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+       };
+};
index 9020382d97cf4df92f7ba13513248c58a8f5f5f1..885040920c077cad8aa26f8360daed79bc4d0d81 100644 (file)
@@ -10,7 +10,7 @@
 */
 
 /dts-v1/;
-/include/ "exynos5250.dtsi"
+#include "exynos5250.dtsi"
 
 / {
        model = "SAMSUNG SMDK5250 board based on EXYNOS5250";
index ab4f2f858151c7710b2c114bcca9f11820c2cc57..6fd9275c4ef789134344bd4a774de154e18c4c5a 100644 (file)
@@ -10,7 +10,7 @@
 */
 
 /dts-v1/;
-/include/ "exynos5250.dtsi"
+#include "exynos5250.dtsi"
 
 / {
        model = "Google Snow";
                };
        };
 
+       spi@12d30000 {
+               spi-max-frequency = <50000000>;
+               firmware_storage_spi: flash@0 {
+                       compatible = "spi-flash";
+                       reg = <0>;
+               };
+       };
+
        spi@131b0000 {
                spi-max-frequency = <1000000>;
                spi-deactivate-delay = <100>;
index 0c644e7cac8ce563af433f726ece26abaf8922bc..ccbafe9b07d7500569c4be9a82f3cb57bdf5d322 100644 (file)
@@ -5,9 +5,48 @@
  * SPDX-License-Identifier:    GPL-2.0+
  */
 
-/include/ "exynos5.dtsi"
+#include "exynos5.dtsi"
+#include "exynos5250-pinctrl.dtsi"
+#include "exynos5250-pinctrl-uboot.dtsi"
 
 / {
+       aliases {
+               pinctrl0 = &pinctrl_0;
+               pinctrl1 = &pinctrl_1;
+               pinctrl2 = &pinctrl_2;
+               pinctrl3 = &pinctrl_3;
+       };
+
+       pinctrl_0: pinctrl@11400000 {
+               compatible = "samsung,exynos5250-pinctrl";
+               reg = <0x11400000 0x1000>;
+               interrupts = <0 46 0>;
+
+               wakup_eint: wakeup-interrupt-controller {
+                       compatible = "samsung,exynos4210-wakeup-eint";
+                       interrupt-parent = <&gic>;
+                       interrupts = <0 32 0>;
+               };
+       };
+
+       pinctrl_1: pinctrl@13400000 {
+               compatible = "samsung,exynos5250-pinctrl";
+               reg = <0x13400000 0x1000>;
+               interrupts = <0 45 0>;
+       };
+
+       pinctrl_2: pinctrl@10d10000 {
+               compatible = "samsung,exynos5250-pinctrl";
+               reg = <0x10d10000 0x1000>;
+               interrupts = <0 50 0>;
+       };
+
+       pinctrl_3: pinctrl@03860000 {
+               compatible = "samsung,exynos5250-pinctrl";
+               reg = <0x03860000 0x1000>;
+               interrupts = <0 47 0>;
+       };
+
        i2c@12ca0000 {
                #address-cells = <1>;
                #size-cells = <0>;
index 995e62b33721fe345dce5c705a0427382c1c2643..fde863de3cf6b00b9b5fbcc3aa7585f3026044fc 100644 (file)
@@ -8,7 +8,7 @@
  */
 
 /dts-v1/;
-/include/ "exynos54xx.dtsi"
+#include "exynos54xx.dtsi"
 
 / {
        model = "Samsung/Google Peach Pit board based on Exynos5420";
        spi@12d30000 { /* spi1 */
                spi-max-frequency = <50000000>;
                firmware_storage_spi: flash@0 {
+                       compatible = "spi-flash";
                        reg = <0>;
 
                        /*
index 1bc62562835f045b686a9cf3099055d8186fcc97..6855027389d8d84cf7ad59decc7a377d62034e39 100644 (file)
@@ -8,7 +8,7 @@
  */
 
 /dts-v1/;
-/include/ "exynos54xx.dtsi"
+#include "exynos54xx.dtsi"
 
 / {
        model = "SAMSUNG SMDK5420 board based on EXYNOS5420";
diff --git a/arch/arm/dts/exynos54xx-pinctrl-uboot.dtsi b/arch/arm/dts/exynos54xx-pinctrl-uboot.dtsi
new file mode 100644 (file)
index 0000000..5a86211
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * U-Boot additions to enable a generic Exynos GPIO driver
+ *
+ * Copyright (c) 2014 Google, Inc
+ */
+
+/{
+       /*
+        * Replicate the ordering of arch/arm/include/asm/arch-exynos/gpio.h
+        * TODO(sjg@chromium.org): This ordering ceases to matter once GPIO
+        * numbers are not needed in U-Boot for exynos.
+        */
+       pinctrl@14010000 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+       };
+       pinctrl@13400000 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               gpy7 {
+               };
+
+               gpx0 {
+                       reg = <0xc00>;
+               };
+       };
+       pinctrl@13410000 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+       };
+       pinctrl@14000000 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+       };
+       pinctrl@03860000 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+       };
+
+};
diff --git a/arch/arm/dts/exynos54xx-pinctrl.dtsi b/arch/arm/dts/exynos54xx-pinctrl.dtsi
new file mode 100644 (file)
index 0000000..775d956
--- /dev/null
@@ -0,0 +1,305 @@
+/*
+ * Samsung's Exynos5420 SoC pin-mux and pin-config device tree source
+ *
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * Samsung's Exynos5420 SoC pin-mux and pin-config options are listed as device
+ * tree nodes are listed in this file.
+ *
+ * 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.
+*/
+
+#include "exynos54xx-pinctrl-uboot.dtsi"
+
+/ {
+       pinctrl@13400000 {
+               gpy7: gpy7 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpx0: gpx0 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       interrupt-parent = <&combiner>;
+                       #interrupt-cells = <2>;
+                       interrupts = <23 0>, <24 0>, <25 0>, <25 1>,
+                                    <26 0>, <26 1>, <27 0>, <27 1>;
+               };
+
+               gpx1: gpx1 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       interrupt-parent = <&combiner>;
+                       #interrupt-cells = <2>;
+                       interrupts = <28 0>, <28 1>, <29 0>, <29 1>,
+                                    <30 0>, <30 1>, <31 0>, <31 1>;
+               };
+
+               gpx2: gpx2 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpx3: gpx3 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+       };
+
+       pinctrl@13410000 {
+               gpc0: gpc0 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpc1: gpc1 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpc2: gpc2 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpc3: gpc3 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpc4: gpc4 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpd1: gpd1 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpy0: gpy0 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpy1: gpy1 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpy2: gpy2 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpy3: gpy3 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpy4: gpy4 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpy5: gpy5 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpy6: gpy6 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+       };
+
+       pinctrl@14000000 {
+               gpe0: gpe0 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpe1: gpe1 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpf0: gpf0 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpf1: gpf1 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpg0: gpg0 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpg1: gpg1 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpg2: gpg2 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpj4: gpj4 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+       };
+
+       pinctrl@14010000 {
+               gpa0: gpa0 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpa1: gpa1 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpa2: gpa2 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpb0: gpb0 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpb1: gpb1 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpb2: gpb2 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpb3: gpb3 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpb4: gpb4 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gph0: gph0 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+       };
+
+       pinctrl@03860000 {
+               gpz: gpz {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+       };
+};
index c21d798a23d0b54a295d6f0a90a8f5c578f925dc..916cf3a5b6681dd72d061eb7e48ab88d2ab8c270 100644 (file)
@@ -5,7 +5,8 @@
  * SPDX-License-Identifier:    GPL-2.0+
  */
 
-/include/ "exynos5.dtsi"
+#include "exynos5.dtsi"
+#include "exynos54xx-pinctrl.dtsi"
 
 / {
        config {
                i2c8 = "/i2c@12e00000";
                i2c9 = "/i2c@12e10000";
                i2c10 = "/i2c@12e20000";
+               pinctrl0 = &pinctrl_0;
+               pinctrl1 = &pinctrl_1;
+               pinctrl2 = &pinctrl_2;
+               pinctrl3 = &pinctrl_3;
+               pinctrl4 = &pinctrl_4;
                spi0 = "/spi@12d20000";
                spi1 = "/spi@12d30000";
                spi2 = "/spi@12d40000";
                reg = <0x14680000 0x100>;
        };
 
+       pinctrl_0: pinctrl@13400000 {
+               compatible = "samsung,exynos5420-pinctrl";
+               reg = <0x13400000 0x1000>;
+               interrupts = <0 45 0>;
+
+               wakeup-interrupt-controller {
+                       compatible = "samsung,exynos4210-wakeup-eint";
+                       interrupt-parent = <&gic>;
+                       interrupts = <0 32 0>;
+               };
+       };
+
+       pinctrl_1: pinctrl@13410000 {
+               compatible = "samsung,exynos5420-pinctrl";
+               reg = <0x13410000 0x1000>;
+               interrupts = <0 78 0>;
+       };
+
+       pinctrl_2: pinctrl@14000000 {
+               compatible = "samsung,exynos5420-pinctrl";
+               reg = <0x14000000 0x1000>;
+               interrupts = <0 46 0>;
+       };
+
+       pinctrl_3: pinctrl@14010000 {
+               compatible = "samsung,exynos5420-pinctrl";
+               reg = <0x14010000 0x1000>;
+               interrupts = <0 50 0>;
+       };
+
+       pinctrl_4: pinctrl@03860000 {
+               compatible = "samsung,exynos5420-pinctrl";
+               reg = <0x03860000 0x1000>;
+               interrupts = <0 47 0>;
+       };
+
        fimd@14400000 {
                /* sysmmu is not used in U-Boot */
                samsung,disable-sysmmu;
diff --git a/arch/arm/dts/s5pc100-pinctrl.dtsi b/arch/arm/dts/s5pc100-pinctrl.dtsi
new file mode 100644 (file)
index 0000000..bd9f97c
--- /dev/null
@@ -0,0 +1,180 @@
+/*
+ * U-Boot additions to enable a generic Exynos GPIO driver
+ *
+ * Copyright (c) 2014 Google, Inc
+ */
+
+/ {
+       pinctrl@e0300000 {
+               gpa0: gpa0 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpa1: gpa1 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpb: gpb {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpc: gpc {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpd: gpd {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpe0: gpe0 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpe1: gpe1 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpf0: gpf0 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpf1: gpf1 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpf2: gpf2 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpf3: gpf3 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpg0: gpg0 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpg1: gpg1 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpg2: gpg2 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpg3: gpg3 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpi: gpi {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpj0: gpj0 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpj1: gpj1 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpj2: gpj2 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpj3: gpj3 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpj4: gpj4 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpk0: gpk0 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpk1: gpk1 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpk2: gpk2 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpk3: gpk3 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpl0: gpl0 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpl1: gpl1 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpl2: gpl2 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpl3: gpl3 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpl4: gpl4 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gph0: gph0 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gph1: gph1 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gph2: gph2 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gph3: gph3 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+       };
+};
diff --git a/arch/arm/dts/s5pc110-pinctrl.dtsi b/arch/arm/dts/s5pc110-pinctrl.dtsi
new file mode 100644 (file)
index 0000000..d21b6ab
--- /dev/null
@@ -0,0 +1,273 @@
+/*
+ * U-Boot additions to enable a generic Exynos GPIO driver
+ *
+ * Copyright (c) 2014 Google, Inc
+ */
+
+/ {
+       pinctrl@e0200000 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               gpa0: gpa0 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpa1: gpa1 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpb: gpb {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpc0: gpc0 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpc1: gpc1 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpd0: gpd0 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpd1: gpd1 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpe0: gpe0 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpe1: gpe1 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpf0: gpf0 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpf1: gpf1 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpf2: gpf2 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpf3: gpf3 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpg0: gpg0 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpg1: gpg1 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpg2: gpg2 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpg3: gpg3 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpi: gpi {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpj0: gpj0 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpj1: gpj1 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpj2: gpj2 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpj3: gpj3 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpj4: gpj4 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpmp01: gpmp01 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpmp02: gpmp02 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpmp03: gpmp03 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpmp04: gpmp04 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpmp05: gpmp05 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpmp06: gpmp06 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpmp07: gpmp07 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpmp10: gpmp10 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpmp11: gpmp11 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpmp12: gpmp12 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpmp13: gpmp13 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpmp14: gpmp14 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpmp15: gpmp15 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpmp16: gpmp16 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpmp17: gpmp17 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpmp18: gpmp18 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpmp20: gpmp20 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpmp21: gpmp21 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpmp22: gpmp22 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpmp23: gpmp23 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpmp24: gpmp24 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpmp25: gpmp25 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpmp26: gpmp26 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpmp27: gpmp27 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpmp28: gpmp28 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gph0: gph0 {
+                       reg = <0xc00>;
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gph1: gph1 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gph2: gph2 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gph3: gph3 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+       };
+};
index 2e671bbf7e9a99f54ad5c4b0d0e26c43ff49c5f5..7bbfe591cd88e1ae45bc25e7cbaf5d8a2fe5c67c 100644 (file)
@@ -9,6 +9,7 @@
 /dts-v1/;
 
 #include "skeleton.dtsi"
+#include "s5pc110-pinctrl.dtsi"
 
 / {
        model = "Samsung Goni based on S5PC110";
        aliases {
                serial2 = "/serial@e2900800";
                console = "/serial@e2900800";
+               pinctrl0 = &pinctrl0;
+       };
+
+       pinctrl0: pinctrl@e0200000 {
+               compatible = "samsung,s5pc110-pinctrl";
+               reg = <0xe0200000 0x1000>;
        };
 
        serial@e2900800 {
index 42754ce811c7c5eab93a298e23309181b728d765..95f15ed48d39ccd57e029f7abe3124ddcc1e9319 100644 (file)
@@ -9,6 +9,7 @@
 /dts-v1/;
 
 #include "skeleton.dtsi"
+#include "s5pc100-pinctrl.dtsi"
 
 / {
        model = "Samsung SMDKC100 based on S5PC100";
        aliases {
                serial0 = "/serial@ec000000";
                console = "/serial@ec000000";
+               pinctrl0 = &pinctrl0;
+       };
+
+       pinctrl0: pinctrl@e0300000 {
+               compatible = "samsung,s5pc100-pinctrl";
+               reg = <0xe0200000 0x1000>;
        };
 
        serial@ec000000 {
index cee5cfe0d2dbb8c6024fffba353e22eec57fc2ef..74e8a16280bd85afa150c77ef52861e734272d46 100644 (file)
@@ -15,6 +15,7 @@
                usb1 = "/usb@c5000000";
                sdhci0 = "/sdhci@c8000600";
                sdhci1 = "/sdhci@c8000000";
+               spi0 = "/spi@7000c380";
        };
 
        memory {
diff --git a/arch/arm/dts/tegra30-apalis.dts b/arch/arm/dts/tegra30-apalis.dts
new file mode 100644 (file)
index 0000000..5bad3e7
--- /dev/null
@@ -0,0 +1,304 @@
+/dts-v1/;
+
+#include "tegra30.dtsi"
+
+/ {
+       model = "Toradex Apalis T30";
+       compatible = "toradex,apalis_t30", "nvidia,tegra30";
+
+       chosen {
+               stdout-path = &uarta;
+       };
+
+       aliases {
+               i2c0 = "/i2c@7000d000";
+               i2c1 = "/i2c@7000c000";
+               i2c2 = "/i2c@7000c500";
+               i2c3 = "/i2c@7000c700";
+               sdhci0 = "/sdhci@78000600";
+               sdhci1 = "/sdhci@78000400";
+               sdhci2 = "/sdhci@78000000";
+               usb0 = "/usb@7d000000";
+               usb1 = "/usb@7d004000";
+               usb2 = "/usb@7d008000";
+       };
+
+       memory {
+               device_type = "memory";
+               reg = <0x80000000 0x40000000>;
+       };
+
+       pcie-controller@00003000 {
+               status = "okay";
+               avdd-pexa-supply = <&vdd2_reg>;
+               vdd-pexa-supply = <&vdd2_reg>;
+               avdd-pexb-supply = <&vdd2_reg>;
+               vdd-pexb-supply = <&vdd2_reg>;
+               avdd-pex-pll-supply = <&vdd2_reg>;
+               avdd-plle-supply = <&ldo6_reg>;
+               vddio-pex-ctl-supply = <&sys_3v3_reg>;
+               hvdd-pex-supply = <&sys_3v3_reg>;
+
+               pci@1,0 {
+                       nvidia,num-lanes = <4>;
+               };
+
+               pci@2,0 {
+                       nvidia,num-lanes = <1>;
+               };
+
+               pci@3,0 {
+                       status = "okay";
+                       nvidia,num-lanes = <1>;
+               };
+       };
+
+       /*
+        * GEN1_I2C: I2C1_SDA/SCL on MXM3 pin 209/211 (e.g. RTC on carrier
+        * board)
+        */
+       i2c@7000c000 {
+               status = "okay";
+               clock-frequency = <100000>;
+       };
+
+       /* GEN2_I2C: unused */
+
+       /*
+        * CAM_I2C: I2C3_SDA/SCL on MXM3 pin 201/203 (e.g. camera sensor on
+        * carrier board)
+        */
+       i2c@7000c500 {
+               status = "okay";
+               clock-frequency = <100000>;
+       };
+
+       /* DDC: I2C2_SDA/SCL on MXM3 pin 205/207 (e.g. display EDID) */
+       i2c@7000c700 {
+               status = "okay";
+               clock-frequency = <100000>;
+       };
+
+       /*
+        * PWR_I2C: power I2C to audio codec, PMIC, temperature sensor and
+        * touch screen controller
+        */
+       i2c@7000d000 {
+               status = "okay";
+               clock-frequency = <100000>;
+
+               pmic: tps65911@2d {
+                       compatible = "ti,tps65911";
+                       reg = <0x2d>;
+
+                       interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
+                       #interrupt-cells = <2>;
+                       interrupt-controller;
+
+                       ti,system-power-controller;
+
+                       #gpio-cells = <2>;
+                       gpio-controller;
+
+                       vcc1-supply = <&sys_3v3_reg>;
+                       vcc2-supply = <&sys_3v3_reg>;
+                       vcc3-supply = <&vio_reg>;
+                       vcc4-supply = <&sys_3v3_reg>;
+                       vcc5-supply = <&sys_3v3_reg>;
+                       vcc6-supply = <&vio_reg>;
+                       vcc7-supply = <&charge_pump_5v0_reg>;
+                       vccio-supply = <&sys_3v3_reg>;
+
+                       regulators {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               /* SW1: +V1.35_VDDIO_DDR */
+                               vdd1_reg: vdd1 {
+                                       regulator-name = "vddio_ddr_1v35";
+                                       regulator-min-microvolt = <1350000>;
+                                       regulator-max-microvolt = <1350000>;
+                                       regulator-always-on;
+                               };
+
+                               /* SW2: +V1.05 */
+                               vdd2_reg: vdd2 {
+                                       regulator-name =
+                                               "vdd_pexa,vdd_pexb,vdd_sata";
+                                       regulator-min-microvolt = <1050000>;
+                                       regulator-max-microvolt = <1050000>;
+                               };
+
+                               /* SW CTRL: +V1.0_VDD_CPU */
+                               vddctrl_reg: vddctrl {
+                                       regulator-name = "vdd_cpu,vdd_sys";
+                                       regulator-min-microvolt = <1150000>;
+                                       regulator-max-microvolt = <1150000>;
+                                       regulator-always-on;
+                               };
+
+                               /* SWIO: +V1.8 */
+                               vio_reg: vio {
+                                       regulator-name = "vdd_1v8_gen";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                                       regulator-always-on;
+                               };
+
+                               /* LDO1: unused */
+
+                               /*
+                                * EN_+V3.3 switching via FET:
+                                * +V3.3_AUDIO_AVDD_S, +V3.3 and +V1.8_VDD_LAN
+                                * see also v3_3 fixed supply
+                                */
+                               ldo2_reg: ldo2 {
+                                       regulator-name = "en_3v3";
+                                       regulator-min-microvolt = <3300000>;
+                                       regulator-max-microvolt = <3300000>;
+                                       regulator-always-on;
+                               };
+
+                               /* +V1.2_CSI */
+                               ldo3_reg: ldo3 {
+                                       regulator-name =
+                                               "avdd_dsi_csi,pwrdet_mipi";
+                                       regulator-min-microvolt = <1200000>;
+                                       regulator-max-microvolt = <1200000>;
+                               };
+
+                               /* +V1.2_VDD_RTC */
+                               ldo4_reg: ldo4 {
+                                       regulator-name = "vdd_rtc";
+                                       regulator-min-microvolt = <1200000>;
+                                       regulator-max-microvolt = <1200000>;
+                                       regulator-always-on;
+                               };
+
+                               /*
+                                * +V2.8_AVDD_VDAC:
+                                * only required for analog RGB
+                                */
+                               ldo5_reg: ldo5 {
+                                       regulator-name = "avdd_vdac";
+                                       regulator-min-microvolt = <2800000>;
+                                       regulator-max-microvolt = <2800000>;
+                                       regulator-always-on;
+                               };
+
+                               /*
+                                * +V1.05_AVDD_PLLE: avdd_plle should be 1.05V
+                                * but LDO6 can't set voltage in 50mV
+                                * granularity
+                                */
+                               ldo6_reg: ldo6 {
+                                       regulator-name = "avdd_plle";
+                                       regulator-min-microvolt = <1100000>;
+                                       regulator-max-microvolt = <1100000>;
+                               };
+
+                               /* +V1.2_AVDD_PLL */
+                               ldo7_reg: ldo7 {
+                                       regulator-name = "avdd_pll";
+                                       regulator-min-microvolt = <1200000>;
+                                       regulator-max-microvolt = <1200000>;
+                                       regulator-always-on;
+                               };
+
+                               /* +V1.0_VDD_DDR_HS */
+                               ldo8_reg: ldo8 {
+                                       regulator-name = "vdd_ddr_hs";
+                                       regulator-min-microvolt = <1000000>;
+                                       regulator-max-microvolt = <1000000>;
+                                       regulator-always-on;
+                               };
+                       };
+               };
+       };
+
+       /* SPI1: Apalis SPI1 */
+       spi@7000d400 {
+               status = "okay";
+               spi-max-frequency = <25000000>;
+       };
+
+       /* SPI4: CAN2 */
+       spi@7000da00 {
+               status = "okay";
+               spi-max-frequency = <25000000>;
+       };
+
+       /* SPI5: Apalis SPI2 */
+       spi@7000dc00 {
+               status = "okay";
+               spi-max-frequency = <25000000>;
+       };
+
+       /* SPI6: CAN1 */
+       spi@7000de00 {
+               status = "okay";
+               spi-max-frequency = <25000000>;
+       };
+
+       sdhci@78000000 {
+               status = "okay";
+               bus-width = <4>;
+               cd-gpios = <&gpio 229 1>; /* PCC5, SD1_CD# */
+       };
+
+       sdhci@78000400 {
+               status = "okay";
+               bus-width = <8>;
+               cd-gpios = <&gpio 171 1>; /* PV3, MMC1_CD# */
+       };
+
+       sdhci@78000600 {
+               status = "okay";
+               bus-width = <8>;
+               non-removable;
+       };
+
+       /* EHCI instance 0: USB1_DP/N -> USBO1_DP/N */
+       usb@7d000000 {
+               status = "okay";
+               dr_mode = "peripheral";
+               nvidia,vbus-gpio = <&gpio 157 0>;       /* PT5, USBO1_EN */
+       };
+
+       /* EHCI instance 1: USB2_DP/N -> USBH2_DP/N */
+       usb@7d004000 {
+               status = "okay";
+               nvidia,vbus-gpio = <&gpio 233 0>;       /* PDD1, USBH_EN */
+               phy_type = "utmi";
+       };
+
+       /* EHCI instance 2: USB3_DP/N -> USBH3_DP/N */
+       usb@7d008000 {
+               status = "okay";
+               nvidia,vbus-gpio = <&gpio 233 0>;       /* PDD1, USBH_EN */
+       };
+
+       regulators {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               sys_3v3_reg: regulator@100 {
+                       compatible = "regulator-fixed";
+                       reg = <100>;
+                       regulator-name = "3v3";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       regulator-always-on;
+               };
+
+               charge_pump_5v0_reg: regulator@101 {
+                       compatible = "regulator-fixed";
+                       reg = <101>;
+                       regulator-name = "5v0";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       regulator-always-on;
+               };
+       };
+};
index ad140def95f4d630e11519554f16d71fbfb10f25..9acd84d80296fa367f6e1196051cf9f9b200497c 100644 (file)
@@ -18,6 +18,7 @@
                i2c4 = "/i2c@7000c700";
                sdhci0 = "/sdhci@78000600";
                sdhci1 = "/sdhci@78000000";
+               spi0 = "/spi@7000da00";
                usb0 = "/usb@7d000000";
                usb1 = "/usb@7d008000";
        };
index b4fbe71aa534c01d60b541b790bd25b921fc7211..1b8ed737e049707f0cec91f491bdb2e84e3099f0 100644 (file)
@@ -18,6 +18,7 @@
                i2c4 = "/i2c@7000c700";
                sdhci0 = "/sdhci@78000600";
                sdhci1 = "/sdhci@78000000";
+               spi0 = "/spi@7000da00";
                usb0 = "/usb@7d008000";
        };
 
index 43d03ca4fa53a256bfe79cd3abdfe8fa937d2507..572520a00ec5e330d5bbacd4b187967d45db8ec8 100644 (file)
@@ -6,12 +6,17 @@
        model = "Toradex Colibri T30";
        compatible = "toradex,colibri_t30", "nvidia,tegra30";
 
+       chosen {
+               stdout-path = &uarta;
+       };
+
        aliases {
                i2c0 = "/i2c@7000d000";
                i2c1 = "/i2c@7000c000";
                i2c2 = "/i2c@7000c700";
                sdhci0 = "/sdhci@78000600";
                sdhci1 = "/sdhci@78000200";
+               spi0 = "/spi@7000d400";
                usb0 = "/usb@7d000000";
                usb1 = "/usb@7d004000"; /* on module only, for ASIX */
                usb2 = "/usb@7d008000";
index ed826a0e19c99b8cd76337aa46440a831e2b477a..09fc22760d0c6e973359f121f92c63feed26793d 100644 (file)
@@ -7,7 +7,9 @@
  * SPDX-License-Identifier:    GPL-2.0+
  */
 
+#include <bootm.h>
 #include <common.h>
+#include <netdev.h>
 #include <asm/errno.h>
 #include <asm/io.h>
 #include <asm/arch/imx-regs.h>
index a58087399cedc8786983d5a41268e97976ee07e9..34f53872e89b3d0674f9cff2227a8d10ea510c45 100644 (file)
@@ -4,6 +4,7 @@
  * SPDX-License-Identifier:    GPL-2.0+
  */
 #include <common.h>
+#include <malloc.h>
 #include <asm/arch/clock.h>
 #include <asm/arch/imx-regs.h>
 #include <asm/errno.h>
@@ -69,15 +70,53 @@ static void * const i2c_bases[] = {
 };
 
 /* i2c_index can be from 0 - 2 */
-void setup_i2c(unsigned i2c_index, int speed, int slave_addr,
-               struct i2c_pads_info *p)
+int setup_i2c(unsigned i2c_index, int speed, int slave_addr,
+             struct i2c_pads_info *p)
 {
+       char *name1, *name2;
+       int ret;
+
        if (i2c_index >= ARRAY_SIZE(i2c_bases))
-               return;
+               return -EINVAL;
+
+       name1 = malloc(9);
+       name2 = malloc(9);
+       if (!name1 || !name2)
+               return -ENOMEM;
+
+       sprintf(name1, "i2c_sda%d", i2c_index);
+       sprintf(name2, "i2c_scl%d", i2c_index);
+       ret = gpio_request(p->sda.gp, name1);
+       if (ret)
+               goto err_req1;
+
+       ret = gpio_request(p->scl.gp, name2);
+       if (ret)
+               goto err_req2;
+
        /* Enable i2c clock */
-       enable_i2c_clk(1, i2c_index);
+       ret = enable_i2c_clk(1, i2c_index);
+       if (ret)
+               goto err_clk;
+
        /* Make sure bus is idle */
-       force_idle_bus(p);
+       ret = force_idle_bus(p);
+       if (ret)
+               goto err_idle;
+
        bus_i2c_init(i2c_bases[i2c_index], speed, slave_addr,
                        force_idle_bus, p);
+
+       return 0;
+
+err_idle:
+err_clk:
+       gpio_free(p->scl.gp);
+err_req2:
+       gpio_free(p->sda.gp);
+err_req1:
+       free(name1);
+       free(name2);
+
+       return ret;
 }
index dbecf4e4348e776d4f62ee77b4dc581d7629b656..12256a38eb97a5803071ff526f4fd2ad3b81fb9b 100644 (file)
@@ -5,6 +5,7 @@
  */
 
 #include <common.h>
+#include <asm/arch/sys_proto.h>
 #include <asm/errno.h>
 #include <asm/io.h>
 #include <asm/imx-common/regs-common.h>
index 32494372639e89cb66675c1afb63694b4391eb90..d8bf87258b5d2ec07227ddd1b815dfced2ccad5f 100644 (file)
@@ -36,7 +36,7 @@ struct module_pin_mux {
 
 /* Pad control register offset */
 #define PAD_CTRL_BASE  0x800
-#define OFFSET(x)      (unsigned int) (&((struct pad_signals *) \
+#define OFFSET(x)      (unsigned int) (&((struct pad_signals *)\
                                (PAD_CTRL_BASE))->x)
 
 /*
diff --git a/arch/arm/include/asm/arch-armada-xp/config.h b/arch/arm/include/asm/arch-armada-xp/config.h
new file mode 100644 (file)
index 0000000..00ee775
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * (C) Copyright 2011
+ * Marvell Semiconductor <www.marvell.com>
+ * Written-by: Lei Wen <leiwen@marvell.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+/*
+ * This file should be included in board config header file.
+ *
+ * It supports common definitions for Armada XP platforms
+ */
+
+#ifndef _ARMADA_XP_CONFIG_H
+#define _ARMADA_XP_CONFIG_H
+
+#include <asm/arch/soc.h>
+
+#define MV88F78X60 /* for the DDR training bin_hdr code */
+
+#define CONFIG_SYS_CACHELINE_SIZE      32
+
+/*
+ * By default kwbimage.cfg from board specific folder is used
+ * If for some board, different configuration file need to be used,
+ * CONFIG_SYS_KWD_CONFIG should be defined in board specific header file
+ */
+#ifndef CONFIG_SYS_KWD_CONFIG
+#define        CONFIG_SYS_KWD_CONFIG   $(CONFIG_BOARDDIR)/kwbimage.cfg
+#endif /* CONFIG_SYS_KWD_CONFIG */
+
+/* Add target to build it automatically upon "make" */
+#define CONFIG_BUILD_TARGET    "u-boot.kwb"
+
+/* end of 16M scrubbed by training in bootrom */
+#define CONFIG_SYS_INIT_SP_ADDR                0x00FF0000
+#define CONFIG_NR_DRAM_BANKS_MAX       2
+
+#define MV_UART_CONSOLE_BASE           MVEBU_UART0_BASE
+
+/*
+ * SPI Flash configuration
+ */
+#ifdef CONFIG_CMD_SF
+#define CONFIG_HARD_SPI                        1
+#define CONFIG_KIRKWOOD_SPI            1
+#ifndef CONFIG_ENV_SPI_BUS
+# define CONFIG_ENV_SPI_BUS            0
+#endif
+#ifndef CONFIG_ENV_SPI_CS
+# define CONFIG_ENV_SPI_CS             0
+#endif
+#ifndef CONFIG_ENV_SPI_MAX_HZ
+# define CONFIG_ENV_SPI_MAX_HZ         50000000
+#endif
+#endif
+
+/*
+ * Ethernet Driver configuration
+ */
+#ifdef CONFIG_CMD_NET
+#define CONFIG_CMD_MII
+#define CONFIG_MII             /* expose smi ove miiphy interface */
+#define CONFIG_MVNETA          /* Enable Marvell Gbe Controller Driver */
+#define CONFIG_PHYLIB
+#define CONFIG_ENV_OVERWRITE   /* ethaddr can be reprogrammed */
+#define CONFIG_PHY_GIGE                /* GbE speed/duplex detect */
+#endif /* CONFIG_CMD_NET */
+
+/*
+ * I2C related stuff
+ */
+#ifdef CONFIG_CMD_I2C
+#ifndef CONFIG_SYS_I2C_SOFT
+#define CONFIG_I2C_MVTWSI
+#endif
+#define CONFIG_SYS_I2C_SLAVE           0x0
+#define CONFIG_SYS_I2C_SPEED           100000
+#endif
+
+#endif /* _ARMADA_XP_CONFIG_H */
diff --git a/arch/arm/include/asm/arch-armada-xp/cpu.h b/arch/arm/include/asm/arch-armada-xp/cpu.h
new file mode 100644 (file)
index 0000000..6b60c21
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * (C) Copyright 2009
+ * Marvell Semiconductor <www.marvell.com>
+ * Written-by: Prafulla Wadaskar <prafulla@marvell.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#ifndef _ARMADA_XP_CPU_H
+#define _ARMADA_XP_CPU_H
+
+#include <asm/system.h>
+
+#ifndef __ASSEMBLY__
+
+#define MVEBU_REG_PCIE_DEVID           (MVEBU_REG_PCIE_BASE + 0x00)
+#define MVEBU_REG_PCIE_REVID           (MVEBU_REG_PCIE_BASE + 0x08)
+
+enum memory_bank {
+       BANK0,
+       BANK1,
+       BANK2,
+       BANK3
+};
+
+enum cpu_winen {
+       CPU_WIN_DISABLE,
+       CPU_WIN_ENABLE
+};
+
+enum cpu_target {
+       CPU_TARGET_DRAM = 0x0,
+       CPU_TARGET_DEVICEBUS_BOOTROM_SPI = 0x1,
+       CPU_TARGET_ETH23 = 0x3,
+       CPU_TARGET_PCIE02 = 0x4,
+       CPU_TARGET_ETH01 = 0x7,
+       CPU_TARGET_PCIE13 = 0x8,
+       CPU_TARGET_SASRAM = 0x9,
+       CPU_TARGET_NAND = 0xd,
+};
+
+enum cpu_attrib {
+       CPU_ATTR_SASRAM = 0x01,
+       CPU_ATTR_DRAM_CS0 = 0x0e,
+       CPU_ATTR_DRAM_CS1 = 0x0d,
+       CPU_ATTR_DRAM_CS2 = 0x0b,
+       CPU_ATTR_DRAM_CS3 = 0x07,
+       CPU_ATTR_NANDFLASH = 0x2f,
+       CPU_ATTR_SPIFLASH = 0x1e,
+       CPU_ATTR_BOOTROM = 0x1d,
+       CPU_ATTR_PCIE_IO = 0xe0,
+       CPU_ATTR_PCIE_MEM = 0xe8,
+       CPU_ATTR_DEV_CS0 = 0x3e,
+       CPU_ATTR_DEV_CS1 = 0x3d,
+       CPU_ATTR_DEV_CS2 = 0x3b,
+       CPU_ATTR_DEV_CS3 = 0x37,
+};
+
+/*
+ * Default Device Address MAP BAR values
+ */
+#define DEFADR_PCI_MEM         0x90000000
+#define DEFADR_PCI_IO          0xC0000000
+#define DEFADR_SPIF            0xF4000000
+#define DEFADR_BOOTROM         0xF8000000
+
+struct mbus_win {
+       u32 base;
+       u32 size;
+       u8 target;
+       u8 attr;
+};
+
+/*
+ * System registers
+ * Ref: Datasheet sec:A.28
+ */
+struct mvebu_system_registers {
+       u8 pad1[0x60];
+       u32 rstoutn_mask; /* 0x60 */
+       u32 sys_soft_rst; /* 0x64 */
+};
+
+/*
+ * GPIO Registers
+ * Ref: Datasheet sec:A.19
+ */
+struct kwgpio_registers {
+       u32 dout;
+       u32 oe;
+       u32 blink_en;
+       u32 din_pol;
+       u32 din;
+       u32 irq_cause;
+       u32 irq_mask;
+       u32 irq_level;
+};
+
+/*
+ * functions
+ */
+unsigned int mvebu_sdram_bar(enum memory_bank bank);
+unsigned int mvebu_sdram_bs(enum memory_bank bank);
+void mvebu_sdram_size_adjust(enum memory_bank bank);
+int mvebu_mbus_probe(struct mbus_win windows[], int count);
+#endif /* __ASSEMBLY__ */
+#endif /* _ARMADA_XP_CPU_H */
diff --git a/arch/arm/include/asm/arch-armada-xp/soc.h b/arch/arm/include/asm/arch-armada-xp/soc.h
new file mode 100644 (file)
index 0000000..963e7ac
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * (C) Copyright 2009
+ * Marvell Semiconductor <www.marvell.com>
+ * Written-by: Prafulla Wadaskar <prafulla@marvell.com>
+ *
+ * Header file for the Marvell's Feroceon CPU core.
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#ifndef _ASM_ARCH_ARMADA_XP_H
+#define _ASM_ARCH_ARMADA_XP_H
+
+#define SOC_MV78460_ID         0x7846
+
+/* TCLK Core Clock definition */
+#ifndef CONFIG_SYS_TCLK
+#define CONFIG_SYS_TCLK                250000000       /* 250MHz */
+#endif
+
+/* SOC specific definations */
+#define INTREG_BASE            0xd0000000
+#define INTREG_BASE_ADDR_REG   (INTREG_BASE + 0x20080)
+#define SOC_REGS_PHY_BASE      0xf1000000
+#define MVEBU_REGISTER(x)      (SOC_REGS_PHY_BASE + x)
+
+#define MVEBU_SDRAM_SCRATCH    (MVEBU_REGISTER(0x01504))
+#define MVEBU_SPI_BASE         (MVEBU_REGISTER(0x10600))
+#define MVEBU_TWSI_BASE                (MVEBU_REGISTER(0x11000))
+#define MVEBU_UART0_BASE       (MVEBU_REGISTER(0x12000))
+#define MVEBU_UART1_BASE       (MVEBU_REGISTER(0x12100))
+#define MVEBU_MPP_BASE         (MVEBU_REGISTER(0x18000))
+#define MVEBU_GPIO0_BASE       (MVEBU_REGISTER(0x18100))
+#define MVEBU_GPIO1_BASE       (MVEBU_REGISTER(0x18140))
+#define MVEBU_GPIO2_BASE       (MVEBU_REGISTER(0x18180))
+#define MVEBU_SYSTEM_REG_BASE  (MVEBU_REGISTER(0x18200))
+#define MVEBU_CPU_WIN_BASE     (MVEBU_REGISTER(0x20000))
+#define MVEBU_SDRAM_BASE       (MVEBU_REGISTER(0x20180))
+#define MVEBU_TIMER_BASE       (MVEBU_REGISTER(0x20300))
+#define MVEBU_EGIGA2_BASE      (MVEBU_REGISTER(0x30000))
+#define MVEBU_EGIGA3_BASE      (MVEBU_REGISTER(0x34000))
+#define MVEBU_REG_PCIE_BASE    (MVEBU_REGISTER(0x40000))
+#define MVEBU_EGIGA0_BASE      (MVEBU_REGISTER(0x70000))
+#define MVEBU_EGIGA1_BASE      (MVEBU_REGISTER(0x74000))
+
+#define SDRAM_MAX_CS           4
+#define SDRAM_ADDR_MASK                0xFF000000
+
+/* Armada XP GbE controller has 4 ports */
+#define MAX_MVNETA_DEVS                4
+
+/* Kirkwood CPU memory windows */
+#define MVCPU_WIN_CTRL_DATA    CPU_WIN_CTRL_DATA
+#define MVCPU_WIN_ENABLE       CPU_WIN_ENABLE
+#define MVCPU_WIN_DISABLE      CPU_WIN_DISABLE
+
+#endif /* _ASM_ARCH_ARMADA_XP_H */
index 9a49b6e05efa5af346953a183f88d415d98fe46d..db42896201b321fb623af79c78a22addddf9de34 100644 (file)
@@ -52,4 +52,13 @@ struct bcm2835_gpio_regs {
        u32 gppudclk[2];
 };
 
+/**
+ * struct bcm2835_gpio_platdata - GPIO platform description
+ *
+ * @base: Base address of GPIO controller
+ */
+struct bcm2835_gpio_platdata {
+       unsigned long base;
+};
+
 #endif /* _BCM2835_GPIO_H_ */
index dded857c3ad50abbe650f12a1ebb435e6f8d7614..61f427d914cd939386806a2c45f263d397a11058 100644 (file)
@@ -119,6 +119,20 @@ struct bcm2835_mbox_tag_hdr {
  * };
  */
 
+#define BCM2835_MBOX_TAG_GET_MAC_ADDRESS       0x00010003
+
+struct bcm2835_mbox_tag_get_mac_address {
+       struct bcm2835_mbox_tag_hdr tag_hdr;
+       union {
+               struct {
+               } req;
+               struct {
+                       u8 mac[6];
+                       u8 pad[2];
+               } resp;
+       } body;
+};
+
 #define BCM2835_MBOX_TAG_GET_ARM_MEMORY                0x00010005
 
 struct bcm2835_mbox_tag_get_arm_mem {
index 8fb5c2321ecdd5c95c43230e7198260cf10ed8a5..ad2ece64f49b3568e7903541360f89bb1d2e5c63 100644 (file)
@@ -284,7 +284,7 @@ enum exynos4_gpio_pin {
        EXYNOS4_GPIO_Y65,
        EXYNOS4_GPIO_Y66,
        EXYNOS4_GPIO_Y67,
-       EXYNOS4_GPIO_X00 = 896,         /* 896 0x380 */
+       EXYNOS4_GPIO_X00,               /* 256 0x100 */
        EXYNOS4_GPIO_X01,
        EXYNOS4_GPIO_X02,
        EXYNOS4_GPIO_X03,
@@ -292,7 +292,7 @@ enum exynos4_gpio_pin {
        EXYNOS4_GPIO_X05,
        EXYNOS4_GPIO_X06,
        EXYNOS4_GPIO_X07,
-       EXYNOS4_GPIO_X10,               /* 904 0x388 */
+       EXYNOS4_GPIO_X10,               /* 264 0x108 */
        EXYNOS4_GPIO_X11,
        EXYNOS4_GPIO_X12,
        EXYNOS4_GPIO_X13,
@@ -300,7 +300,7 @@ enum exynos4_gpio_pin {
        EXYNOS4_GPIO_X15,
        EXYNOS4_GPIO_X16,
        EXYNOS4_GPIO_X17,
-       EXYNOS4_GPIO_X20,               /* 912 0x390 */
+       EXYNOS4_GPIO_X20,               /* 272 0x110 */
        EXYNOS4_GPIO_X21,
        EXYNOS4_GPIO_X22,
        EXYNOS4_GPIO_X23,
@@ -308,7 +308,7 @@ enum exynos4_gpio_pin {
        EXYNOS4_GPIO_X25,
        EXYNOS4_GPIO_X26,
        EXYNOS4_GPIO_X27,
-       EXYNOS4_GPIO_X30,               /* 920 0x398 */
+       EXYNOS4_GPIO_X30,               /* 280 0x118 */
        EXYNOS4_GPIO_X31,
        EXYNOS4_GPIO_X32,
        EXYNOS4_GPIO_X33,
@@ -318,7 +318,7 @@ enum exynos4_gpio_pin {
        EXYNOS4_GPIO_X37,
 
        /* GPIO_PART3_STARTS */
-       EXYNOS4_GPIO_MAX_PORT_PART_2,   /* 928 0x3A0 */
+       EXYNOS4_GPIO_MAX_PORT_PART_2,   /* 288 0x120 */
        EXYNOS4_GPIO_Z0 = EXYNOS4_GPIO_MAX_PORT_PART_2,
        EXYNOS4_GPIO_Z1,
        EXYNOS4_GPIO_Z2,
@@ -389,7 +389,7 @@ enum exynos4X12_gpio_pin {
        EXYNOS4X12_GPIO_D15,
        EXYNOS4X12_GPIO_D16,
        EXYNOS4X12_GPIO_D17,
-       EXYNOS4X12_GPIO_F00 = 96,       /* 96 0x60 */
+       EXYNOS4X12_GPIO_F00,            /* 56 0x38 */
        EXYNOS4X12_GPIO_F01,
        EXYNOS4X12_GPIO_F02,
        EXYNOS4X12_GPIO_F03,
@@ -397,7 +397,7 @@ enum exynos4X12_gpio_pin {
        EXYNOS4X12_GPIO_F05,
        EXYNOS4X12_GPIO_F06,
        EXYNOS4X12_GPIO_F07,
-       EXYNOS4X12_GPIO_F10,            /* 104 0x68 */
+       EXYNOS4X12_GPIO_F10,            /* 64 0x40 */
        EXYNOS4X12_GPIO_F11,
        EXYNOS4X12_GPIO_F12,
        EXYNOS4X12_GPIO_F13,
@@ -405,7 +405,7 @@ enum exynos4X12_gpio_pin {
        EXYNOS4X12_GPIO_F15,
        EXYNOS4X12_GPIO_F16,
        EXYNOS4X12_GPIO_F17,
-       EXYNOS4X12_GPIO_F20,            /* 112 0x70 */
+       EXYNOS4X12_GPIO_F20,            /* 72 0x48 */
        EXYNOS4X12_GPIO_F21,
        EXYNOS4X12_GPIO_F22,
        EXYNOS4X12_GPIO_F23,
@@ -413,7 +413,7 @@ enum exynos4X12_gpio_pin {
        EXYNOS4X12_GPIO_F25,
        EXYNOS4X12_GPIO_F26,
        EXYNOS4X12_GPIO_F27,
-       EXYNOS4X12_GPIO_F30,            /* 120 0x78 */
+       EXYNOS4X12_GPIO_F30,            /* 80 0x50 */
        EXYNOS4X12_GPIO_F31,
        EXYNOS4X12_GPIO_F32,
        EXYNOS4X12_GPIO_F33,
@@ -421,7 +421,7 @@ enum exynos4X12_gpio_pin {
        EXYNOS4X12_GPIO_F35,
        EXYNOS4X12_GPIO_F36,
        EXYNOS4X12_GPIO_F37,
-       EXYNOS4X12_GPIO_J00 = 144,      /* 144 0x90 */
+       EXYNOS4X12_GPIO_J00,            /* 88 0x58 */
        EXYNOS4X12_GPIO_J01,
        EXYNOS4X12_GPIO_J02,
        EXYNOS4X12_GPIO_J03,
@@ -429,7 +429,7 @@ enum exynos4X12_gpio_pin {
        EXYNOS4X12_GPIO_J05,
        EXYNOS4X12_GPIO_J06,
        EXYNOS4X12_GPIO_J07,
-       EXYNOS4X12_GPIO_J10,            /* 152 0x98 */
+       EXYNOS4X12_GPIO_J10,            /* 96 0x60 */
        EXYNOS4X12_GPIO_J11,
        EXYNOS4X12_GPIO_J12,
        EXYNOS4X12_GPIO_J13,
@@ -439,8 +439,8 @@ enum exynos4X12_gpio_pin {
        EXYNOS4X12_GPIO_J17,
 
        /* GPIO_PART2_STARTS */
-       EXYNOS4X12_GPIO_MAX_PORT_PART_1,/* 160 0xA0 */
-       EXYNOS4X12_GPIO_K00 = 176,      /* 176 0xB0 */
+       EXYNOS4X12_GPIO_MAX_PORT_PART_1,/* 104 0x66 */
+       EXYNOS4X12_GPIO_K00 = EXYNOS4X12_GPIO_MAX_PORT_PART_1,
        EXYNOS4X12_GPIO_K01,
        EXYNOS4X12_GPIO_K02,
        EXYNOS4X12_GPIO_K03,
@@ -448,7 +448,7 @@ enum exynos4X12_gpio_pin {
        EXYNOS4X12_GPIO_K05,
        EXYNOS4X12_GPIO_K06,
        EXYNOS4X12_GPIO_K07,
-       EXYNOS4X12_GPIO_K10,            /* 184 0xB8 */
+       EXYNOS4X12_GPIO_K10,            /* 112 0x70 */
        EXYNOS4X12_GPIO_K11,
        EXYNOS4X12_GPIO_K12,
        EXYNOS4X12_GPIO_K13,
@@ -456,7 +456,7 @@ enum exynos4X12_gpio_pin {
        EXYNOS4X12_GPIO_K15,
        EXYNOS4X12_GPIO_K16,
        EXYNOS4X12_GPIO_K17,
-       EXYNOS4X12_GPIO_K20,            /* 192 0xC0 */
+       EXYNOS4X12_GPIO_K20,            /* 120 0x78 */
        EXYNOS4X12_GPIO_K21,
        EXYNOS4X12_GPIO_K22,
        EXYNOS4X12_GPIO_K23,
@@ -464,7 +464,7 @@ enum exynos4X12_gpio_pin {
        EXYNOS4X12_GPIO_K25,
        EXYNOS4X12_GPIO_K26,
        EXYNOS4X12_GPIO_K27,
-       EXYNOS4X12_GPIO_K30,            /* 200 0xC8 */
+       EXYNOS4X12_GPIO_K30,            /* 128 0x80 */
        EXYNOS4X12_GPIO_K31,
        EXYNOS4X12_GPIO_K32,
        EXYNOS4X12_GPIO_K33,
@@ -472,7 +472,7 @@ enum exynos4X12_gpio_pin {
        EXYNOS4X12_GPIO_K35,
        EXYNOS4X12_GPIO_K36,
        EXYNOS4X12_GPIO_K37,
-       EXYNOS4X12_GPIO_L00,            /* 208 0xD0 */
+       EXYNOS4X12_GPIO_L00,            /* 136 0x88 */
        EXYNOS4X12_GPIO_L01,
        EXYNOS4X12_GPIO_L02,
        EXYNOS4X12_GPIO_L03,
@@ -480,7 +480,7 @@ enum exynos4X12_gpio_pin {
        EXYNOS4X12_GPIO_L05,
        EXYNOS4X12_GPIO_L06,
        EXYNOS4X12_GPIO_L07,
-       EXYNOS4X12_GPIO_L10,            /* 216 0xD8 */
+       EXYNOS4X12_GPIO_L10,            /* 144 0x90 */
        EXYNOS4X12_GPIO_L11,
        EXYNOS4X12_GPIO_L12,
        EXYNOS4X12_GPIO_L13,
@@ -488,7 +488,7 @@ enum exynos4X12_gpio_pin {
        EXYNOS4X12_GPIO_L15,
        EXYNOS4X12_GPIO_L16,
        EXYNOS4X12_GPIO_L17,
-       EXYNOS4X12_GPIO_L20,            /* 224 0xE0 */
+       EXYNOS4X12_GPIO_L20,            /* 152 0x98 */
        EXYNOS4X12_GPIO_L21,
        EXYNOS4X12_GPIO_L22,
        EXYNOS4X12_GPIO_L23,
@@ -496,7 +496,7 @@ enum exynos4X12_gpio_pin {
        EXYNOS4X12_GPIO_L25,
        EXYNOS4X12_GPIO_L26,
        EXYNOS4X12_GPIO_L27,
-       EXYNOS4X12_GPIO_Y00,            /* 232 0xE8 */
+       EXYNOS4X12_GPIO_Y00,            /* 160 0xa0 */
        EXYNOS4X12_GPIO_Y01,
        EXYNOS4X12_GPIO_Y02,
        EXYNOS4X12_GPIO_Y03,
@@ -504,7 +504,7 @@ enum exynos4X12_gpio_pin {
        EXYNOS4X12_GPIO_Y05,
        EXYNOS4X12_GPIO_Y06,
        EXYNOS4X12_GPIO_Y07,
-       EXYNOS4X12_GPIO_Y10,            /* 240 0xF0 */
+       EXYNOS4X12_GPIO_Y10,            /* 168 0xa8 */
        EXYNOS4X12_GPIO_Y11,
        EXYNOS4X12_GPIO_Y12,
        EXYNOS4X12_GPIO_Y13,
@@ -512,7 +512,7 @@ enum exynos4X12_gpio_pin {
        EXYNOS4X12_GPIO_Y15,
        EXYNOS4X12_GPIO_Y16,
        EXYNOS4X12_GPIO_Y17,
-       EXYNOS4X12_GPIO_Y20,            /* 248 0xF8 */
+       EXYNOS4X12_GPIO_Y20,            /* 176 0xb0 */
        EXYNOS4X12_GPIO_Y21,
        EXYNOS4X12_GPIO_Y22,
        EXYNOS4X12_GPIO_Y23,
@@ -520,7 +520,7 @@ enum exynos4X12_gpio_pin {
        EXYNOS4X12_GPIO_Y25,
        EXYNOS4X12_GPIO_Y26,
        EXYNOS4X12_GPIO_Y27,
-       EXYNOS4X12_GPIO_Y30,            /* 256 0x100 */
+       EXYNOS4X12_GPIO_Y30,            /* 184 0xb8 */
        EXYNOS4X12_GPIO_Y31,
        EXYNOS4X12_GPIO_Y32,
        EXYNOS4X12_GPIO_Y33,
@@ -528,7 +528,7 @@ enum exynos4X12_gpio_pin {
        EXYNOS4X12_GPIO_Y35,
        EXYNOS4X12_GPIO_Y36,
        EXYNOS4X12_GPIO_Y37,
-       EXYNOS4X12_GPIO_Y40,            /* 264 0x108 */
+       EXYNOS4X12_GPIO_Y40,            /* 192 0xc0 */
        EXYNOS4X12_GPIO_Y41,
        EXYNOS4X12_GPIO_Y42,
        EXYNOS4X12_GPIO_Y43,
@@ -536,7 +536,7 @@ enum exynos4X12_gpio_pin {
        EXYNOS4X12_GPIO_Y45,
        EXYNOS4X12_GPIO_Y46,
        EXYNOS4X12_GPIO_Y47,
-       EXYNOS4X12_GPIO_Y50,            /* 272 0x110 */
+       EXYNOS4X12_GPIO_Y50,            /* 200 0xc8 */
        EXYNOS4X12_GPIO_Y51,
        EXYNOS4X12_GPIO_Y52,
        EXYNOS4X12_GPIO_Y53,
@@ -544,7 +544,7 @@ enum exynos4X12_gpio_pin {
        EXYNOS4X12_GPIO_Y55,
        EXYNOS4X12_GPIO_Y56,
        EXYNOS4X12_GPIO_Y57,
-       EXYNOS4X12_GPIO_Y60,            /* 280 0x118 */
+       EXYNOS4X12_GPIO_Y60,            /* 208 0xd0 */
        EXYNOS4X12_GPIO_Y61,
        EXYNOS4X12_GPIO_Y62,
        EXYNOS4X12_GPIO_Y63,
@@ -552,7 +552,7 @@ enum exynos4X12_gpio_pin {
        EXYNOS4X12_GPIO_Y65,
        EXYNOS4X12_GPIO_Y66,
        EXYNOS4X12_GPIO_Y67,
-       EXYNOS4X12_GPIO_M00 = 312,      /* 312 0xF0 */
+       EXYNOS4X12_GPIO_M00,            /* 216 0xd8 */
        EXYNOS4X12_GPIO_M01,
        EXYNOS4X12_GPIO_M02,
        EXYNOS4X12_GPIO_M03,
@@ -560,7 +560,7 @@ enum exynos4X12_gpio_pin {
        EXYNOS4X12_GPIO_M05,
        EXYNOS4X12_GPIO_M06,
        EXYNOS4X12_GPIO_M07,
-       EXYNOS4X12_GPIO_M10,            /* 320 0xF8 */
+       EXYNOS4X12_GPIO_M10,            /* 224 0xe0 */
        EXYNOS4X12_GPIO_M11,
        EXYNOS4X12_GPIO_M12,
        EXYNOS4X12_GPIO_M13,
@@ -568,7 +568,7 @@ enum exynos4X12_gpio_pin {
        EXYNOS4X12_GPIO_M15,
        EXYNOS4X12_GPIO_M16,
        EXYNOS4X12_GPIO_M17,
-       EXYNOS4X12_GPIO_M20,            /* 328 0x100 */
+       EXYNOS4X12_GPIO_M20,            /* 232 0xe8 */
        EXYNOS4X12_GPIO_M21,
        EXYNOS4X12_GPIO_M22,
        EXYNOS4X12_GPIO_M23,
@@ -576,7 +576,7 @@ enum exynos4X12_gpio_pin {
        EXYNOS4X12_GPIO_M25,
        EXYNOS4X12_GPIO_M26,
        EXYNOS4X12_GPIO_M27,
-       EXYNOS4X12_GPIO_M30,            /* 336 0x108 */
+       EXYNOS4X12_GPIO_M30,            /* 240 0xf0 */
        EXYNOS4X12_GPIO_M31,
        EXYNOS4X12_GPIO_M32,
        EXYNOS4X12_GPIO_M33,
@@ -584,7 +584,7 @@ enum exynos4X12_gpio_pin {
        EXYNOS4X12_GPIO_M35,
        EXYNOS4X12_GPIO_M36,
        EXYNOS4X12_GPIO_M37,
-       EXYNOS4X12_GPIO_M40,            /* 344 0x110 */
+       EXYNOS4X12_GPIO_M40,            /* 248 0xf8 */
        EXYNOS4X12_GPIO_M41,
        EXYNOS4X12_GPIO_M42,
        EXYNOS4X12_GPIO_M43,
@@ -592,7 +592,7 @@ enum exynos4X12_gpio_pin {
        EXYNOS4X12_GPIO_M45,
        EXYNOS4X12_GPIO_M46,
        EXYNOS4X12_GPIO_M47,
-       EXYNOS4X12_GPIO_X00 = 928,      /* 928 0x3A0 */
+       EXYNOS4X12_GPIO_X00,            /* 256 0x100 */
        EXYNOS4X12_GPIO_X01,
        EXYNOS4X12_GPIO_X02,
        EXYNOS4X12_GPIO_X03,
@@ -600,7 +600,7 @@ enum exynos4X12_gpio_pin {
        EXYNOS4X12_GPIO_X05,
        EXYNOS4X12_GPIO_X06,
        EXYNOS4X12_GPIO_X07,
-       EXYNOS4X12_GPIO_X10,            /* 936 0x3A8 */
+       EXYNOS4X12_GPIO_X10,            /* 264 0x108 */
        EXYNOS4X12_GPIO_X11,
        EXYNOS4X12_GPIO_X12,
        EXYNOS4X12_GPIO_X13,
@@ -608,7 +608,7 @@ enum exynos4X12_gpio_pin {
        EXYNOS4X12_GPIO_X15,
        EXYNOS4X12_GPIO_X16,
        EXYNOS4X12_GPIO_X17,
-       EXYNOS4X12_GPIO_X20,            /* 944 0x3B0 */
+       EXYNOS4X12_GPIO_X20,            /* 272 0x110 */
        EXYNOS4X12_GPIO_X21,
        EXYNOS4X12_GPIO_X22,
        EXYNOS4X12_GPIO_X23,
@@ -616,7 +616,7 @@ enum exynos4X12_gpio_pin {
        EXYNOS4X12_GPIO_X25,
        EXYNOS4X12_GPIO_X26,
        EXYNOS4X12_GPIO_X27,
-       EXYNOS4X12_GPIO_X30,            /* 952 0x3B8 */
+       EXYNOS4X12_GPIO_X30,            /* 280 0x118 */
        EXYNOS4X12_GPIO_X31,
        EXYNOS4X12_GPIO_X32,
        EXYNOS4X12_GPIO_X33,
@@ -626,7 +626,7 @@ enum exynos4X12_gpio_pin {
        EXYNOS4X12_GPIO_X37,
 
        /* GPIO_PART3_STARTS */
-       EXYNOS4X12_GPIO_MAX_PORT_PART_2,/* 960 0x3C0 */
+       EXYNOS4X12_GPIO_MAX_PORT_PART_2,/* 288 0x120 */
        EXYNOS4X12_GPIO_Z0 = EXYNOS4X12_GPIO_MAX_PORT_PART_2,
        EXYNOS4X12_GPIO_Z1,
        EXYNOS4X12_GPIO_Z2,
@@ -637,7 +637,7 @@ enum exynos4X12_gpio_pin {
        EXYNOS4X12_GPIO_Z7,
 
        /* GPIO_PART4_STARTS */
-       EXYNOS4X12_GPIO_MAX_PORT_PART_3,/* 968 0x3C8 */
+       EXYNOS4X12_GPIO_MAX_PORT_PART_3,/* 296 0x128 */
        EXYNOS4X12_GPIO_V00 = EXYNOS4X12_GPIO_MAX_PORT_PART_3,
        EXYNOS4X12_GPIO_V01,
        EXYNOS4X12_GPIO_V02,
@@ -646,7 +646,7 @@ enum exynos4X12_gpio_pin {
        EXYNOS4X12_GPIO_V05,
        EXYNOS4X12_GPIO_V06,
        EXYNOS4X12_GPIO_V07,
-       EXYNOS4X12_GPIO_V10,            /* 976 0x3D0 */
+       EXYNOS4X12_GPIO_V10,            /* 304 0x130 */
        EXYNOS4X12_GPIO_V11,
        EXYNOS4X12_GPIO_V12,
        EXYNOS4X12_GPIO_V13,
@@ -654,7 +654,7 @@ enum exynos4X12_gpio_pin {
        EXYNOS4X12_GPIO_V15,
        EXYNOS4X12_GPIO_V16,
        EXYNOS4X12_GPIO_V17,
-       EXYNOS4X12_GPIO_V20 = 992,      /* 992 0x3E0 */
+       EXYNOS4X12_GPIO_V20,            /* 312 0x138 */
        EXYNOS4X12_GPIO_V21,
        EXYNOS4X12_GPIO_V22,
        EXYNOS4X12_GPIO_V23,
@@ -662,7 +662,7 @@ enum exynos4X12_gpio_pin {
        EXYNOS4X12_GPIO_V25,
        EXYNOS4X12_GPIO_V26,
        EXYNOS4X12_GPIO_V27,
-       EXYNOS4X12_GPIO_V30 = 1000,     /* 1000 0x3E8 */
+       EXYNOS4X12_GPIO_V30,            /* 320 0x140 */
        EXYNOS4X12_GPIO_V31,
        EXYNOS4X12_GPIO_V32,
        EXYNOS4X12_GPIO_V33,
@@ -670,7 +670,7 @@ enum exynos4X12_gpio_pin {
        EXYNOS4X12_GPIO_V35,
        EXYNOS4X12_GPIO_V36,
        EXYNOS4X12_GPIO_V37,
-       EXYNOS4X12_GPIO_V40 = 1016,     /* 1016 0x3F8 */
+       EXYNOS4X12_GPIO_V40,            /* 328 0x148 */
        EXYNOS4X12_GPIO_V41,
        EXYNOS4X12_GPIO_V42,
        EXYNOS4X12_GPIO_V43,
@@ -1504,12 +1504,7 @@ static const struct gpio_name_num_table exynos5420_gpio_table[] = {
 void gpio_cfg_pin(int gpio, int cfg);
 void gpio_set_pull(int gpio, int mode);
 void gpio_set_drv(int gpio, int mode);
-int gpio_direction_input(unsigned gpio);
-int gpio_direction_output(unsigned gpio, int value);
-int gpio_set_value(unsigned gpio, int value);
-int gpio_get_value(unsigned gpio);
 void gpio_set_rate(int gpio, int mode);
-struct s5p_gpio_bank *s5p_gpio_get_bank(unsigned gpio);
 int s5p_gpio_get_pin(unsigned gpio);
 #endif
 
index df33a78a103da33d59264f5312f8cfd482c77d5a..d013b830ed5c4243453ec3768a4497e90b660f28 100644 (file)
@@ -25,27 +25,28 @@ enum ext_clk_e {
 
 extern unsigned int external_clk[ext_clk_count];
 
-enum clk_e {
-       core_pll_clk,
-       pass_pll_clk,
-       ddr3_pll_clk,
-       sys_clk0_clk,
-       sys_clk0_1_clk,
-       sys_clk0_2_clk,
-       sys_clk0_3_clk,
-       sys_clk0_4_clk,
-       sys_clk0_6_clk,
-       sys_clk0_8_clk,
-       sys_clk0_12_clk,
-       sys_clk0_24_clk,
-       sys_clk1_clk,
-       sys_clk1_3_clk,
-       sys_clk1_4_clk,
-       sys_clk1_6_clk,
-       sys_clk1_12_clk,
-       sys_clk2_clk,
-       sys_clk3_clk
-};
+#define CLK_LIST(CLK)\
+       CLK(0, core_pll_clk)\
+       CLK(1, pass_pll_clk)\
+       CLK(2, ddr3_pll_clk)\
+       CLK(3, sys_clk0_clk)\
+       CLK(4, sys_clk0_1_clk)\
+       CLK(5, sys_clk0_2_clk)\
+       CLK(6, sys_clk0_3_clk)\
+       CLK(7, sys_clk0_4_clk)\
+       CLK(8, sys_clk0_6_clk)\
+       CLK(9, sys_clk0_8_clk)\
+       CLK(10, sys_clk0_12_clk)\
+       CLK(11, sys_clk0_24_clk)\
+       CLK(12, sys_clk1_clk)\
+       CLK(13, sys_clk1_3_clk)\
+       CLK(14, sys_clk1_4_clk)\
+       CLK(15, sys_clk1_6_clk)\
+       CLK(16, sys_clk1_12_clk)\
+       CLK(17, sys_clk2_clk)\
+       CLK(18, sys_clk3_clk)
+
+#define PLLSET_CMD_LIST        "<pa|ddr3>"
 
 #define KS2_CLK1_6     sys_clk0_6_clk
 
index bdb869bed41f2db8f9ad7d06f348525bc41ad6d6..f28d5f0c4e99b7eca524864e0c4b065847891e5d 100644 (file)
@@ -28,29 +28,30 @@ enum ext_clk_e {
 
 extern unsigned int external_clk[ext_clk_count];
 
-enum clk_e {
-       core_pll_clk,
-       pass_pll_clk,
-       tetris_pll_clk,
-       ddr3a_pll_clk,
-       ddr3b_pll_clk,
-       sys_clk0_clk,
-       sys_clk0_1_clk,
-       sys_clk0_2_clk,
-       sys_clk0_3_clk,
-       sys_clk0_4_clk,
-       sys_clk0_6_clk,
-       sys_clk0_8_clk,
-       sys_clk0_12_clk,
-       sys_clk0_24_clk,
-       sys_clk1_clk,
-       sys_clk1_3_clk,
-       sys_clk1_4_clk,
-       sys_clk1_6_clk,
-       sys_clk1_12_clk,
-       sys_clk2_clk,
-       sys_clk3_clk
-};
+#define CLK_LIST(CLK)\
+       CLK(0, core_pll_clk)\
+       CLK(1, pass_pll_clk)\
+       CLK(2, tetris_pll_clk)\
+       CLK(3, ddr3a_pll_clk)\
+       CLK(4, ddr3b_pll_clk)\
+       CLK(5, sys_clk0_clk)\
+       CLK(6, sys_clk0_1_clk)\
+       CLK(7, sys_clk0_2_clk)\
+       CLK(8, sys_clk0_3_clk)\
+       CLK(9, sys_clk0_4_clk)\
+       CLK(10, sys_clk0_6_clk)\
+       CLK(11, sys_clk0_8_clk)\
+       CLK(12, sys_clk0_12_clk)\
+       CLK(13, sys_clk0_24_clk)\
+       CLK(14, sys_clk1_clk)\
+       CLK(15, sys_clk1_3_clk)\
+       CLK(16, sys_clk1_4_clk)\
+       CLK(17, sys_clk1_6_clk)\
+       CLK(18, sys_clk1_12_clk)\
+       CLK(19, sys_clk2_clk)\
+       CLK(20, sys_clk3_clk)
+
+#define PLLSET_CMD_LIST                "<pa|arm|ddr3a|ddr3b>"
 
 #define KS2_CLK1_6 sys_clk0_6_clk
 
diff --git a/arch/arm/include/asm/arch-keystone/clock-k2l.h b/arch/arm/include/asm/arch-keystone/clock-k2l.h
new file mode 100644 (file)
index 0000000..bb9a5c4
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * K2L: Clock management APIs
+ *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#ifndef __ASM_ARCH_CLOCK_K2L_H
+#define __ASM_ARCH_CLOCK_K2L_H
+
+enum ext_clk_e {
+       sys_clk,
+       alt_core_clk,
+       pa_clk,
+       tetris_clk,
+       ddr3_clk,
+       pcie_clk,
+       sgmii_clk,
+       usb_clk,
+       rp1_clk,
+       ext_clk_count /* number of external clocks */
+};
+
+extern unsigned int external_clk[ext_clk_count];
+
+#define CLK_LIST(CLK)\
+       CLK(0, core_pll_clk)\
+       CLK(1, pass_pll_clk)\
+       CLK(2, tetris_pll_clk)\
+       CLK(3, ddr3_pll_clk)\
+       CLK(4, sys_clk0_clk)\
+       CLK(5, sys_clk0_1_clk)\
+       CLK(6, sys_clk0_2_clk)\
+       CLK(7, sys_clk0_3_clk)\
+       CLK(8, sys_clk0_4_clk)\
+       CLK(9, sys_clk0_6_clk)\
+       CLK(10, sys_clk0_8_clk)\
+       CLK(11, sys_clk0_12_clk)\
+       CLK(12, sys_clk0_24_clk)\
+       CLK(13, sys_clk1_clk)\
+       CLK(14, sys_clk1_3_clk)\
+       CLK(15, sys_clk1_4_clk)\
+       CLK(16, sys_clk1_6_clk)\
+       CLK(17, sys_clk1_12_clk)\
+       CLK(18, sys_clk2_clk)\
+       CLK(19, sys_clk3_clk)\
+
+#define PLLSET_CMD_LIST        "<pa|arm|ddr3>"
+
+#define KS2_CLK1_6     sys_clk0_6_clk
+
+/* PLL identifiers */
+enum pll_type_e {
+       CORE_PLL,
+       PASS_PLL,
+       TETRIS_PLL,
+       DDR3_PLL,
+};
+
+enum {
+       SPD800,
+       SPD1000,
+       SPD1200,
+       SPD1350,
+       SPD1400,
+       SPD_RSV
+};
+
+#define CORE_PLL_799   {CORE_PLL, 13, 1, 2}
+#define CORE_PLL_983   {CORE_PLL, 16, 1, 2}
+#define CORE_PLL_1000  {CORE_PLL, 114, 7, 2}
+#define CORE_PLL_1167  {CORE_PLL, 19, 1, 2}
+#define CORE_PLL_1198  {CORE_PLL, 39, 2, 2}
+#define CORE_PLL_1228  {CORE_PLL, 20, 1, 2}
+#define PASS_PLL_1228  {PASS_PLL, 20, 1, 2}
+#define PASS_PLL_983   {PASS_PLL, 16, 1, 2}
+#define PASS_PLL_1050  {PASS_PLL, 205, 12, 2}
+#define TETRIS_PLL_491 {TETRIS_PLL, 8, 1, 2}
+#define TETRIS_PLL_737 {TETRIS_PLL, 12, 1, 2}
+#define TETRIS_PLL_799 {TETRIS_PLL, 13, 1, 2}
+#define TETRIS_PLL_983 {TETRIS_PLL, 16, 1, 2}
+#define TETRIS_PLL_1000        {TETRIS_PLL, 114, 7, 2}
+#define TETRIS_PLL_1167        {TETRIS_PLL, 19, 1, 2}
+#define TETRIS_PLL_1198        {TETRIS_PLL, 39, 2, 2}
+#define TETRIS_PLL_1228        {TETRIS_PLL, 20, 1, 2}
+#define TETRIS_PLL_1352        {TETRIS_PLL, 22, 1, 2}
+#define TETRIS_PLL_1401        {TETRIS_PLL, 114, 5, 2}
+#define DDR3_PLL_200   {DDR3_PLL, 4, 1, 2}
+#define DDR3_PLL_400   {DDR3_PLL, 16, 1, 4}
+#define DDR3_PLL_800   {DDR3_PLL, 16, 1, 2}
+#define DDR3_PLL_333   {DDR3_PLL, 20, 1, 6}
+
+#endif
index dae000e43ae4166ad49037317d67392ec98a515f..9f6cfb265f4342f3b9e36b682cbb541462846397 100644 (file)
 #include <asm/arch/clock-k2e.h>
 #endif
 
+#ifdef CONFIG_SOC_K2L
+#include <asm/arch/clock-k2l.h>
+#endif
+
 #define MAIN_PLL CORE_PLL
 
 #include <asm/types.h>
 
+#define GENERATE_ENUM(NUM, ENUM) ENUM = NUM,
+#define GENERATE_INDX_STR(NUM, STRING) #NUM"\t- "#STRING"\n"
+#define CLOCK_INDEXES_LIST     CLK_LIST(GENERATE_INDX_STR)
+
+enum clk_e {
+       CLK_LIST(GENERATE_ENUM)
+};
+
 struct keystone_pll_regs {
        u32 reg0;
        u32 reg1;
@@ -46,6 +58,7 @@ void init_pll(const struct pll_init_data *data);
 unsigned long clk_get_rate(unsigned int clk);
 unsigned long clk_round_rate(unsigned int clk, unsigned long hz);
 int clk_set_rate(unsigned int clk, unsigned long hz);
+void pass_pll_pa_clk_enable(void);
 int get_max_dev_speed(void);
 int get_max_arm_speed(void);
 
index 6bf35d354366d1aba944d09960f2f571d7016f47..b044d6f18ff2473f44060aab7816f3329e46a097 100644 (file)
@@ -49,8 +49,14 @@ struct ddr3_emif_config {
 };
 
 void ddr3_init(void);
+int ddr3_get_size(void);
 void ddr3_reset_ddrphy(void);
+void ddr3_init_ecc(u32 base);
+void ddr3_disable_ecc(u32 base);
+void ddr3_check_ecc_int(u32 base);
+int ddr3_ecc_support_rmw(u32 base);
 void ddr3_err_reset_workaround(void);
+void ddr3_enable_ecc(u32 base, int test);
 void ddr3_init_ddrphy(u32 base, struct ddr3_phy_config *phy_cfg);
 void ddr3_init_ddremif(u32 base, struct ddr3_emif_config *emif_cfg);
 
diff --git a/arch/arm/include/asm/arch-keystone/emac_defs.h b/arch/arm/include/asm/arch-keystone/emac_defs.h
deleted file mode 100644 (file)
index 9cd8925..0000000
+++ /dev/null
@@ -1,237 +0,0 @@
-/*
- * emac definitions for keystone2 devices
- *
- * (C) Copyright 2012-2014
- *     Texas Instruments Incorporated, <www.ti.com>
- *
- * SPDX-License-Identifier:     GPL-2.0+
- */
-
-#ifndef _EMAC_DEFS_H_
-#define _EMAC_DEFS_H_
-
-#include <asm/arch/hardware.h>
-#include <asm/io.h>
-
-#define EMAC_EMACSL_BASE_ADDR           (KS2_PASS_BASE + 0x00090900)
-#define EMAC_MDIO_BASE_ADDR             (KS2_PASS_BASE + 0x00090300)
-#define EMAC_SGMII_BASE_ADDR            (KS2_PASS_BASE + 0x00090100)
-
-#define KEYSTONE2_EMAC_GIG_ENABLE
-
-#define MAC_ID_BASE_ADDR                (KS2_DEVICE_STATE_CTRL_BASE + 0x110)
-
-#ifdef CONFIG_SOC_K2HK
-/* MDIO module input frequency */
-#define EMAC_MDIO_BUS_FREQ              (clk_get_rate(pass_pll_clk))
-/* MDIO clock output frequency */
-#define EMAC_MDIO_CLOCK_FREQ            1000000                /* 1.0 MHz */
-#endif
-
-/* MII Status Register */
-#define MII_STATUS_REG                  1
-#define MII_STATUS_LINK_MASK            (0x4)
-
-/* Marvell 88E1111 PHY ID */
-#define PHY_MARVELL_88E1111             (0x01410cc0)
-
-#define MDIO_CONTROL_IDLE               (0x80000000)
-#define MDIO_CONTROL_ENABLE             (0x40000000)
-#define MDIO_CONTROL_FAULT_ENABLE       (0x40000)
-#define MDIO_CONTROL_FAULT              (0x80000)
-#define MDIO_USERACCESS0_GO             (0x80000000)
-#define MDIO_USERACCESS0_WRITE_READ     (0x0)
-#define MDIO_USERACCESS0_WRITE_WRITE    (0x40000000)
-#define MDIO_USERACCESS0_ACK            (0x20000000)
-
-#define EMAC_MACCONTROL_MIIEN_ENABLE       (0x20)
-#define EMAC_MACCONTROL_FULLDUPLEX_ENABLE  (0x1)
-#define EMAC_MACCONTROL_GIGABIT_ENABLE     (1 << 7)
-#define EMAC_MACCONTROL_GIGFORCE           (1 << 17)
-#define EMAC_MACCONTROL_RMIISPEED_100      (1 << 15)
-
-#define EMAC_MIN_ETHERNET_PKT_SIZE         60
-
-struct mac_sl_cfg {
-       u_int32_t max_rx_len;   /* Maximum receive packet length. */
-       u_int32_t ctl;          /* Control bitfield */
-};
-
-/*
- * Definition: Control bitfields used in the ctl field of hwGmacSlCfg_t
- */
-#define GMACSL_RX_ENABLE_RCV_CONTROL_FRAMES       (1 << 24)
-#define GMACSL_RX_ENABLE_RCV_SHORT_FRAMES         (1 << 23)
-#define GMACSL_RX_ENABLE_RCV_ERROR_FRAMES         (1 << 22)
-#define GMACSL_RX_ENABLE_EXT_CTL                  (1 << 18)
-#define GMACSL_RX_ENABLE_GIG_FORCE                (1 << 17)
-#define GMACSL_RX_ENABLE_IFCTL_B                  (1 << 16)
-#define GMACSL_RX_ENABLE_IFCTL_A                  (1 << 15)
-#define GMACSL_RX_ENABLE_CMD_IDLE                 (1 << 11)
-#define GMACSL_TX_ENABLE_SHORT_GAP                (1 << 10)
-#define GMACSL_ENABLE_GIG_MODE                    (1 <<  7)
-#define GMACSL_TX_ENABLE_PACE                     (1 <<  6)
-#define GMACSL_ENABLE                             (1 <<  5)
-#define GMACSL_TX_ENABLE_FLOW_CTL                 (1 <<  4)
-#define GMACSL_RX_ENABLE_FLOW_CTL                 (1 <<  3)
-#define GMACSL_ENABLE_LOOPBACK                    (1 <<  1)
-#define GMACSL_ENABLE_FULL_DUPLEX                 (1 <<  0)
-
-/*
- * DEFINTITION: function return values
- */
-#define GMACSL_RET_OK                        0
-#define GMACSL_RET_INVALID_PORT             -1
-#define GMACSL_RET_WARN_RESET_INCOMPLETE    -2
-#define GMACSL_RET_WARN_MAXLEN_TOO_BIG      -3
-#define GMACSL_RET_CONFIG_FAIL_RESET_ACTIVE -4
-
-/* Register offsets */
-#define CPGMACSL_REG_ID         0x00
-#define CPGMACSL_REG_CTL        0x04
-#define CPGMACSL_REG_STATUS     0x08
-#define CPGMACSL_REG_RESET      0x0c
-#define CPGMACSL_REG_MAXLEN     0x10
-#define CPGMACSL_REG_BOFF       0x14
-#define CPGMACSL_REG_RX_PAUSE   0x18
-#define CPGMACSL_REG_TX_PAURSE  0x1c
-#define CPGMACSL_REG_EM_CTL     0x20
-#define CPGMACSL_REG_PRI        0x24
-
-/* Soft reset register values */
-#define CPGMAC_REG_RESET_VAL_RESET_MASK      (1 << 0)
-#define CPGMAC_REG_RESET_VAL_RESET           (1 << 0)
-
-/* Maxlen register values */
-#define CPGMAC_REG_MAXLEN_LEN                0x3fff
-
-/* Control bitfields */
-#define CPSW_CTL_P2_PASS_PRI_TAGGED     (1 << 5)
-#define CPSW_CTL_P1_PASS_PRI_TAGGED     (1 << 4)
-#define CPSW_CTL_P0_PASS_PRI_TAGGED     (1 << 3)
-#define CPSW_CTL_P0_ENABLE              (1 << 2)
-#define CPSW_CTL_VLAN_AWARE             (1 << 1)
-#define CPSW_CTL_FIFO_LOOPBACK          (1 << 0)
-
-#define DEVICE_CPSW_NUM_PORTS       5                    /* 5 switch ports */
-#define DEVICE_CPSW_BASE            (0x02090800)
-#define target_get_switch_ctl()     CPSW_CTL_P0_ENABLE   /* Enable port 0 */
-#define SWITCH_MAX_PKT_SIZE         9000
-
-/* Register offsets */
-#define CPSW_REG_CTL                0x004
-#define CPSW_REG_STAT_PORT_EN       0x00c
-#define CPSW_REG_MAXLEN             0x040
-#define CPSW_REG_ALE_CONTROL        0x608
-#define CPSW_REG_ALE_PORTCTL(x)     (0x640 + (x)*4)
-
-/* Register values */
-#define CPSW_REG_VAL_STAT_ENABLE_ALL             0xf
-#define CPSW_REG_VAL_ALE_CTL_RESET_AND_ENABLE    ((u_int32_t)0xc0000000)
-#define CPSW_REG_VAL_ALE_CTL_BYPASS              ((u_int32_t)0x00000010)
-#define CPSW_REG_VAL_PORTCTL_FORWARD_MODE        0x3
-
-#define SGMII_REG_STATUS_LOCK           BIT(4)
-#define SGMII_REG_STATUS_LINK           BIT(0)
-#define SGMII_REG_STATUS_AUTONEG        BIT(2)
-#define SGMII_REG_CONTROL_AUTONEG       BIT(0)
-#define SGMII_REG_CONTROL_MASTER        BIT(5)
-#define        SGMII_REG_MR_ADV_ENABLE         BIT(0)
-#define        SGMII_REG_MR_ADV_LINK           BIT(15)
-#define        SGMII_REG_MR_ADV_FULL_DUPLEX    BIT(12)
-#define SGMII_REG_MR_ADV_GIG_MODE       BIT(11)
-
-#define SGMII_LINK_MAC_MAC_AUTONEG      0
-#define SGMII_LINK_MAC_PHY              1
-#define SGMII_LINK_MAC_MAC_FORCED       2
-#define SGMII_LINK_MAC_FIBER            3
-#define SGMII_LINK_MAC_PHY_FORCED       4
-
-#define TARGET_SGMII_BASE              KS2_PASS_BASE + 0x00090100
-#define TARGET_SGMII_BASE_ADDRESSES    {KS2_PASS_BASE + 0x00090100, \
-                                       KS2_PASS_BASE + 0x00090200, \
-                                       KS2_PASS_BASE + 0x00090400, \
-                                       KS2_PASS_BASE + 0x00090500}
-
-#define SGMII_OFFSET(x)        ((x <= 1) ? (x * 0x100) : ((x * 0x100) + 0x100))
-
-/*
- * SGMII registers
- */
-#define SGMII_IDVER_REG(x)    (TARGET_SGMII_BASE + SGMII_OFFSET(x) + 0x000)
-#define SGMII_SRESET_REG(x)   (TARGET_SGMII_BASE + SGMII_OFFSET(x) + 0x004)
-#define SGMII_CTL_REG(x)      (TARGET_SGMII_BASE + SGMII_OFFSET(x) + 0x010)
-#define SGMII_STATUS_REG(x)   (TARGET_SGMII_BASE + SGMII_OFFSET(x) + 0x014)
-#define SGMII_MRADV_REG(x)    (TARGET_SGMII_BASE + SGMII_OFFSET(x) + 0x018)
-#define SGMII_LPADV_REG(x)    (TARGET_SGMII_BASE + SGMII_OFFSET(x) + 0x020)
-#define SGMII_TXCFG_REG(x)    (TARGET_SGMII_BASE + SGMII_OFFSET(x) + 0x030)
-#define SGMII_RXCFG_REG(x)    (TARGET_SGMII_BASE + SGMII_OFFSET(x) + 0x034)
-#define SGMII_AUXCFG_REG(x)   (TARGET_SGMII_BASE + SGMII_OFFSET(x) + 0x038)
-
-#define DEVICE_EMACSL_BASE(x)      (KS2_PASS_BASE + 0x00090900 + (x) * 0x040)
-#define DEVICE_N_GMACSL_PORTS           4
-#define DEVICE_EMACSL_RESET_POLL_COUNT  100
-
-#define DEVICE_PSTREAM_CFG_REG_ADDR                 (KS2_PASS_BASE + 0x604)
-
-#ifdef CONFIG_SOC_K2HK
-#define DEVICE_PSTREAM_CFG_REG_VAL_ROUTE_CPPI      0x06060606
-#endif
-
-#define hw_config_streaming_switch() \
-       writel(DEVICE_PSTREAM_CFG_REG_VAL_ROUTE_CPPI,\
-              DEVICE_PSTREAM_CFG_REG_ADDR);
-
-/* EMAC MDIO Registers Structure */
-struct mdio_regs {
-       dv_reg          version;
-       dv_reg          control;
-       dv_reg          alive;
-       dv_reg          link;
-       dv_reg          linkintraw;
-       dv_reg          linkintmasked;
-       u_int8_t        rsvd0[8];
-       dv_reg          userintraw;
-       dv_reg          userintmasked;
-       dv_reg          userintmaskset;
-       dv_reg          userintmaskclear;
-       u_int8_t        rsvd1[80];
-       dv_reg          useraccess0;
-       dv_reg          userphysel0;
-       dv_reg          useraccess1;
-       dv_reg          userphysel1;
-};
-
-/* Ethernet MAC Registers Structure */
-struct emac_regs {
-       dv_reg          idver;
-       dv_reg          maccontrol;
-       dv_reg          macstatus;
-       dv_reg          soft_reset;
-       dv_reg          rx_maxlen;
-       u32             rsvd0;
-       dv_reg          rx_pause;
-       dv_reg          tx_pause;
-       dv_reg          emcontrol;
-       dv_reg          pri_map;
-       u32             rsvd1[6];
-};
-
-#define SGMII_ACCESS(port, reg) \
-       *((volatile unsigned int *)(sgmiis[port] + reg))
-
-struct eth_priv_t {
-       char    int_name[32];
-       int     rx_flow;
-       int     phy_addr;
-       int     slave_port;
-       int     sgmii_link_type;
-};
-
-extern struct eth_priv_t eth_priv_cfg[];
-
-int keystone2_emac_initialize(struct eth_priv_t *eth_priv);
-void sgmii_serdes_setup_156p25mhz(void);
-void sgmii_serdes_shutdown(void);
-
-#endif  /* _EMAC_DEFS_H_ */
index 62172a4b84d65c67b5c45e097c310bbfc0d3dd0a..9512756619b3eae14075a9d36b756ac46ae4bdaa 100644 (file)
 #define KS2_LPSC_PCIE_1                        27
 #define KS2_LPSC_XGE                   50
 
+/* MSMC */
+#define KS2_MSMC_SEGMENT_PCIE1         13
+
 /* Chip Interrupt Controller */
 #define KS2_CIC2_DDR3_ECC_IRQ_NUM      -1      /* not defined in K2E */
 #define KS2_CIC2_DDR3_ECC_CHAN_NUM     -1      /* not defined in K2E */
 
+/* SGMII SerDes */
+#define KS2_SGMII_SERDES2_BASE         0x02324000
+#define KS2_LANES_PER_SGMII_SERDES     4
+
 /* Number of DSP cores */
 #define KS2_NUM_DSPS                   1
 
+/* NETCP pktdma */
+#define KS2_NETCP_PDMA_CTRL_BASE       0x24186000
+#define KS2_NETCP_PDMA_TX_BASE         0x24187000
+#define KS2_NETCP_PDMA_TX_CH_NUM       21
+#define KS2_NETCP_PDMA_RX_BASE         0x24188000
+#define KS2_NETCP_PDMA_RX_CH_NUM       91
+#define KS2_NETCP_PDMA_SCHED_BASE      0x24186100
+#define KS2_NETCP_PDMA_RX_FLOW_BASE    0x24189000
+#define KS2_NETCP_PDMA_RX_FLOW_NUM     96
+#define KS2_NETCP_PDMA_RX_FREE_QUEUE   4001
+#define KS2_NETCP_PDMA_RX_RCV_QUEUE    4002
+#define KS2_NETCP_PDMA_TX_SND_QUEUE    896
+
+/* NETCP */
+#define KS2_NETCP_BASE                 0x24000000
+
 #endif
index eb132f73e605dd3d189be6d899b6e896ddaeb364..5a9ea4fbca56dd089af020ab55a9c91c2c3dd2d2 100644 (file)
@@ -10,8 +10,6 @@
 #ifndef __ASM_ARCH_HARDWARE_K2HK_H
 #define __ASM_ARCH_HARDWARE_K2HK_H
 
-#define KS2_MISC_CTRL                  (KS2_DEVICE_STATE_CTRL_BASE + 0xc7c)
-
 #define KS2_ARM_PLL_EN                 BIT(13)
 
 /* PA SS Registers */
 #define KS2_DDR3B_EMIF_DATA_BASE       0x60000000
 #define KS2_DDR3B_DDRPHYC              0x02328000
 
+#define KS2_CIC2_DDR3_ECC_IRQ_NUM      0x0D3 /* DDR3 ECC system irq number */
+#define KS2_CIC2_DDR3_ECC_CHAN_NUM     0x01D /* DDR3 ECC int mapped to CIC2
+                                                channel 29 */
+
+/* SGMII SerDes */
+#define KS2_LANES_PER_SGMII_SERDES     4
+
 /* Number of DSP cores */
 #define KS2_NUM_DSPS                   8
 
+/* NETCP pktdma */
+#define KS2_NETCP_PDMA_CTRL_BASE       0x02004000
+#define KS2_NETCP_PDMA_TX_BASE         0x02004400
+#define KS2_NETCP_PDMA_TX_CH_NUM       9
+#define KS2_NETCP_PDMA_RX_BASE         0x02004800
+#define KS2_NETCP_PDMA_RX_CH_NUM       26
+#define KS2_NETCP_PDMA_SCHED_BASE      0x02004c00
+#define KS2_NETCP_PDMA_RX_FLOW_BASE    0x02005000
+#define KS2_NETCP_PDMA_RX_FLOW_NUM     32
+#define KS2_NETCP_PDMA_RX_FREE_QUEUE   4001
+#define KS2_NETCP_PDMA_RX_RCV_QUEUE    4002
+#define KS2_NETCP_PDMA_TX_SND_QUEUE    648
+
+/* NETCP */
+#define KS2_NETCP_BASE                 0x02000000
+
 #endif /* __ASM_ARCH_HARDWARE_H */
diff --git a/arch/arm/include/asm/arch-keystone/hardware-k2l.h b/arch/arm/include/asm/arch-keystone/hardware-k2l.h
new file mode 100644 (file)
index 0000000..05532ad
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ * K2L: SoC definitions
+ *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#ifndef __ASM_ARCH_HARDWARE_K2L_H
+#define __ASM_ARCH_HARDWARE_K2L_H
+
+#define KS2_ARM_PLL_EN                 BIT(13)
+
+/* PA SS Registers */
+#define KS2_PASS_BASE                  0x26000000
+
+/* Power and Sleep Controller (PSC) Domains */
+#define KS2_LPSC_MOD                   0
+#define KS2_LPSC_DFE_IQN_SYS           1
+#define KS2_LPSC_USB                   2
+#define KS2_LPSC_EMIF25_SPI            3
+#define KS2_LPSC_TSIP                   4
+#define KS2_LPSC_DEBUGSS_TRC           5
+#define KS2_LPSC_TETB_TRC              6
+#define KS2_LPSC_PKTPROC               7
+#define KS2_LPSC_PA                    KS2_LPSC_PKTPROC
+#define KS2_LPSC_SGMII                 8
+#define KS2_LPSC_CPGMAC                        KS2_LPSC_SGMII
+#define KS2_LPSC_CRYPTO                        9
+#define KS2_LPSC_PCIE0                 10
+#define KS2_LPSC_PCIE1                 11
+#define KS2_LPSC_JESD_MISC             12
+#define KS2_LPSC_CHIP_SRSS             13
+#define KS2_LPSC_MSMC                  14
+#define KS2_LPSC_GEM_1                 16
+#define KS2_LPSC_GEM_2                 17
+#define KS2_LPSC_GEM_3                 18
+#define KS2_LPSC_EMIF4F_DDR3           23
+#define KS2_LPSC_TAC                   25
+#define KS2_LPSC_RAC                   26
+#define KS2_LPSC_DDUC4X_CFR2X_BB       27
+#define KS2_LPSC_FFTC_A                        28
+#define KS2_LPSC_OSR                   34
+#define KS2_LPSC_TCP3D_0               35
+#define KS2_LPSC_TCP3D_1               37
+#define KS2_LPSC_VCP2X4_A              39
+#define KS2_LPSC_VCP2X4_B              40
+#define KS2_LPSC_VCP2X4_C              41
+#define KS2_LPSC_VCP2X4_D              42
+#define KS2_LPSC_BCP                   47
+#define KS2_LPSC_DPD4X                 48
+#define KS2_LPSC_FFTC_B                        49
+#define KS2_LPSC_IQN_AIL               50
+
+/* MSMC */
+#define KS2_MSMC_SEGMENT_PCIE1         14
+
+/* Chip Interrupt Controller */
+#define KS2_CIC2_DDR3_ECC_IRQ_NUM      0x0D3
+#define KS2_CIC2_DDR3_ECC_CHAN_NUM     0x01D
+
+/* OSR */
+#define KS2_OSR_DATA_BASE              0x70000000      /* OSR data base */
+#define KS2_OSR_CFG_BASE               0x02348c00      /* OSR config base */
+#define KS2_OSR_ECC_VEC                        0x08            /* ECC Vector reg */
+#define KS2_OSR_ECC_CTRL               0x14            /* ECC control reg */
+
+/* OSR ECC Vector register */
+#define KS2_OSR_ECC_VEC_TRIG_RD                BIT(15)         /* trigger a read op */
+#define KS2_OSR_ECC_VEC_RD_DONE                BIT(24)         /* read complete */
+
+#define KS2_OSR_ECC_VEC_RAM_ID_SH      0               /* RAM ID shift */
+#define KS2_OSR_ECC_VEC_RD_ADDR_SH     16              /* read address shift */
+
+/* OSR ECC control register */
+#define KS2_OSR_ECC_CTRL_EN            BIT(0)          /* ECC enable bit */
+#define KS2_OSR_ECC_CTRL_CHK           BIT(1)          /* ECC check bit */
+#define KS2_OSR_ECC_CTRL_RMW           BIT(2)          /* ECC check bit */
+
+/* Number of OSR RAM banks */
+#define KS2_OSR_NUM_RAM_BANKS          4
+
+/* OSR memory size */
+#define KS2_OSR_SIZE                   0x100000
+
+/* Number of DSP cores */
+#define KS2_NUM_DSPS                   4
+
+/* NETCP pktdma */
+#define KS2_NETCP_PDMA_CTRL_BASE       0x26186000
+#define KS2_NETCP_PDMA_TX_BASE         0x26187000
+#define KS2_NETCP_PDMA_TX_CH_NUM       21
+#define KS2_NETCP_PDMA_RX_BASE         0x26188000
+#define KS2_NETCP_PDMA_RX_CH_NUM       91
+#define KS2_NETCP_PDMA_SCHED_BASE      0x26186100
+#define KS2_NETCP_PDMA_RX_FLOW_BASE    0x26189000
+#define KS2_NETCP_PDMA_RX_FLOW_NUM     96
+#define KS2_NETCP_PDMA_TX_SND_QUEUE    896
+
+#endif /* __ASM_ARCH_HARDWARE_K2L_H */
index 76e6441e579547e674a7b7da23e0789cdaf9e585..c6a54d8b91bac618df69390599f6af73d44d5fb5 100644 (file)
@@ -87,6 +87,52 @@ typedef volatile unsigned int   *dv_reg_p;
 
 #define KS2_DDR3_PLLCTRL_PHY_RESET     0x80000000
 
+/* DDR3 ECC */
+#define KS2_DDR3_ECC_INT_STATUS_OFFSET                 0x0AC
+#define KS2_DDR3_ECC_INT_ENABLE_SET_SYS_OFFSET         0x0B4
+#define KS2_DDR3_ECC_CTRL_OFFSET                       0x110
+#define KS2_DDR3_ECC_ADDR_RANGE1_OFFSET                        0x114
+#define KS2_DDR3_ONE_BIT_ECC_ERR_CNT_OFFSET            0x130
+#define KS2_DDR3_ONE_BIT_ECC_ERR_ADDR_LOG_OFFSET       0x13C
+
+/* DDR3 ECC Interrupt Status register */
+#define KS2_DDR3_1B_ECC_ERR_SYS                BIT(5)
+#define KS2_DDR3_2B_ECC_ERR_SYS                BIT(4)
+#define KS2_DDR3_WR_ECC_ERR_SYS                BIT(3)
+
+/* DDR3 ECC Control register */
+#define KS2_DDR3_ECC_EN                        BIT(31)
+#define KS2_DDR3_ECC_ADDR_RNG_PROT     BIT(30)
+#define KS2_DDR3_ECC_VERIFY_EN         BIT(29)
+#define KS2_DDR3_ECC_RMW_EN            BIT(28)
+#define KS2_DDR3_ECC_ADDR_RNG_1_EN     BIT(0)
+
+#define KS2_DDR3_ECC_ENABLE            (KS2_DDR3_ECC_EN | \
+                                       KS2_DDR3_ECC_ADDR_RNG_PROT | \
+                                       KS2_DDR3_ECC_VERIFY_EN)
+
+/* EDMA */
+#define KS2_EDMA0_BASE                 0x02700000
+
+/* EDMA3 register offsets */
+#define KS2_EDMA_QCHMAP0               0x0200
+#define KS2_EDMA_IPR                   0x1068
+#define KS2_EDMA_ICR                   0x1070
+#define KS2_EDMA_QEECR                 0x1088
+#define KS2_EDMA_QEESR                 0x108c
+#define KS2_EDMA_PARAM_1(x)            (0x4020 + (4 * x))
+
+/* Chip Interrupt Controller */
+#define KS2_CIC2_BASE                  0x02608000
+
+/* Chip Interrupt Controller register offsets */
+#define KS2_CIC_CTRL                   0x04
+#define KS2_CIC_HOST_CTRL              0x0C
+#define KS2_CIC_GLOBAL_ENABLE          0x10
+#define KS2_CIC_SYS_ENABLE_IDX_SET     0x28
+#define KS2_CIC_HOST_ENABLE_IDX_SET    0x34
+#define KS2_CIC_CHAN_MAP(n)            (0x0400 + (n << 2))
+
 #define KS2_UART0_BASE                 0x02530c00
 #define KS2_UART1_BASE                 0x02531000
 
@@ -140,19 +186,51 @@ typedef volatile unsigned int   *dv_reg_p;
 /* Flag from ks2_debug options to check if DSPs need to stay ON */
 #define DBG_LEAVE_DSPS_ON              0x1
 
+/* MSMC control */
+#define KS2_MSMC_CTRL_BASE             0x0bc00000
+#define KS2_MSMC_DATA_BASE             0x0c000000
+#define KS2_MSMC_SEGMENT_TETRIS                8
+#define KS2_MSMC_SEGMENT_NETCP         9
+#define KS2_MSMC_SEGMENT_QM_PDSP       10
+#define KS2_MSMC_SEGMENT_PCIE0         11
+
+/* MSMC segment size shift bits */
+#define KS2_MSMC_SEG_SIZE_SHIFT                12
+#define KS2_MSMC_MAP_SEG_NUM           (2 << (30 - KS2_MSMC_SEG_SIZE_SHIFT))
+#define KS2_MSMC_DST_SEG_BASE          (CONFIG_SYS_LPAE_SDRAM_BASE >> \
+                                       KS2_MSMC_SEG_SIZE_SHIFT)
+
 /* Device speed */
 #define KS2_REV1_DEVSPEED              (KS2_DEVICE_STATE_CTRL_BASE + 0xc98)
 #define KS2_EFUSE_BOOTROM              (KS2_DEVICE_STATE_CTRL_BASE + 0xc90)
+#define KS2_MISC_CTRL                  (KS2_DEVICE_STATE_CTRL_BASE + 0xc7c)
 
 /* Queue manager */
-#define KS2_QM_MANAGER_BASE            0x02a02000
+#define KS2_QM_BASE_ADDRESS            0x23a80000
+#define KS2_QM_CONF_BASE               0x02a02000
 #define KS2_QM_DESC_SETUP_BASE         0x02a03000
-#define KS2_QM_MANAGER_QUEUES_BASEi    0x02a80000
+#define KS2_QM_STATUS_RAM_BASE         0x02a06000
+#define KS2_QM_INTD_CONF_BASE          0x02a0c000
+#define KS2_QM_PDSP1_CMD_BASE          0x02a20000
+#define KS2_QM_PDSP1_CTRL_BASE         0x02a0f000
+#define KS2_QM_PDSP1_IRAM_BASE         0x02a10000
+#define KS2_QM_MANAGER_QUEUES_BASE     0x02a80000
 #define KS2_QM_MANAGER_Q_PROXY_BASE    0x02ac0000
 #define KS2_QM_QUEUE_STATUS_BASE       0x02a40000
+#define KS2_QM_LINK_RAM_BASE           0x00100000
+#define KS2_QM_REGION_NUM              64
+#define KS2_QM_QPOOL_NUM               4000
 
-/* MSMC control */
-#define KS2_MSMC_CTRL_BASE             0x0bc00000
+/* USB */
+#define KS2_USB_SS_BASE                        0x02680000
+#define KS2_USB_HOST_XHCI_BASE         (KS2_USB_SS_BASE + 0x10000)
+#define KS2_DEV_USB_PHY_BASE           0x02620738
+#define KS2_USB_PHY_CFG_BASE           0x02630000
+
+#define KS2_MAC_ID_BASE_ADDR           (KS2_DEVICE_STATE_CTRL_BASE + 0x110)
+
+/* SGMII SerDes */
+#define KS2_SGMII_SERDES_BASE          0x0232a000
 
 #ifdef CONFIG_SOC_K2HK
 #include <asm/arch/hardware-k2hk.h>
@@ -162,6 +240,10 @@ typedef volatile unsigned int   *dv_reg_p;
 #include <asm/arch/hardware-k2e.h>
 #endif
 
+#ifdef CONFIG_SOC_K2L
+#include <asm/arch/hardware-k2l.h>
+#endif
+
 #ifndef __ASSEMBLY__
 static inline int cpu_is_k2hk(void)
 {
@@ -179,6 +261,14 @@ static inline int cpu_is_k2e(void)
        return (part_no == 0xb9a6) ? 1 : 0;
 }
 
+static inline int cpu_is_k2l(void)
+{
+       unsigned int jtag_id    = __raw_readl(KS2_JTAG_ID_REG);
+       unsigned int part_no    = (jtag_id >> 12) & 0xffff;
+
+       return (part_no == 0xb9a7) ? 1 : 0;
+}
+
 static inline int cpu_revision(void)
 {
        unsigned int jtag_id    = __raw_readl(KS2_JTAG_ID_REG);
index c320db5b65c693cf264f3489951b517b9300dfb7..083f5ba0522ba9e760877acfa8a4d0c99ce9c06c 100644 (file)
 
 #include <asm/arch/hardware.h>
 
+enum mpax_seg_size {
+       MPAX_SEG_4K = 0x0b,
+       MPAX_SEG_8K,
+       MPAX_SEG_16K,
+       MPAX_SEG_32K,
+       MPAX_SEG_64K,
+       MPAX_SEG_128K,
+       MPAX_SEG_256K,
+       MPAX_SEG_512K,
+       MPAX_SEG_1M,
+       MPAX_SEG_2M,
+       MPAX_SEG_4M,
+       MPAX_SEG_8M,
+       MPAX_SEG_16M,
+       MPAX_SEG_32M,
+       MPAX_SEG_64M,
+       MPAX_SEG_128M,
+       MPAX_SEG_256M,
+       MPAX_SEG_512M,
+       MPAX_SEG_1G,
+       MPAX_SEG_2G,
+       MPAX_SEG_4G
+};
+
 void msmc_share_all_segments(int priv_id);
+void msmc_get_ses_mpax(int priv_id, int ses_pair, u32 *mpax);
+void msmc_set_ses_mpax(int priv_id, int ses_pair, u32 *mpax);
+void msmc_map_ses_segment(int priv_id, int ses_pair,
+                         u32 src_pfn, u32 dst_pfn, enum mpax_seg_size size);
 
 #endif
diff --git a/arch/arm/include/asm/arch-keystone/spl.h b/arch/arm/include/asm/arch-keystone/spl.h
deleted file mode 100644 (file)
index a7102d5..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-/*
- * (C) Copyright 2012-2014
- * Texas Instruments, <www.ti.com>
- *
- * SPDX-License-Identifier:    GPL-2.0+
- */
-#ifndef _ASM_ARCH_SPL_H_
-#define _ASM_ARCH_SPL_H_
-
-#define BOOT_DEVICE_SPI        2
-
-#endif
diff --git a/arch/arm/include/asm/arch-keystone/xhci-keystone.h b/arch/arm/include/asm/arch-keystone/xhci-keystone.h
new file mode 100644 (file)
index 0000000..3aab4e0
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * USB 3.0 DRD Controller
+ *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#define USB3_PHY_REF_SSP_EN            BIT(29)
+#define USB3_PHY_OTG_VBUSVLDECTSEL     BIT(16)
+
+/* KEYSTONE2 XHCI PHY register structure */
+struct keystone_xhci_phy {
+       unsigned int phy_utmi;          /* ctl0 */
+       unsigned int phy_pipe;          /* ctl1 */
+       unsigned int phy_param_ctrl_1;  /* ctl2 */
+       unsigned int phy_param_ctrl_2;  /* ctl3 */
+       unsigned int phy_clock;         /* ctl4 */
+       unsigned int phy_pll;           /* ctl5 */
+};
index f7bfa0e74d7f68864a8ee090f77d5e2f4d025574..ccc8e4e7d64b57bc9d1e94587b5e8d0e42d3d690 100644 (file)
@@ -23,7 +23,7 @@
 #error "SOC Name not defined"
 #endif /* CONFIG_KW88F6281 */
 
-#include <asm/arch/kirkwood.h>
+#include <asm/arch/soc.h>
 #define CONFIG_ARM926EJS       1       /* Basic Architecture */
 #define CONFIG_SYS_CACHELINE_SIZE      32
                                /* default Dcache Line length for kirkwood */
index 97daa403ce7f294400f90dde720de8a5720f24e0..926d347110f8265680171cd12f6bdc1302404b52 100644 (file)
@@ -140,11 +140,11 @@ struct kwgpio_registers {
  * functions
  */
 unsigned char get_random_hex(void);
-unsigned int kw_sdram_bar(enum memory_bank bank);
-unsigned int kw_sdram_bs(enum memory_bank bank);
-void kw_sdram_size_adjust(enum memory_bank bank);
+unsigned int mvebu_sdram_bar(enum memory_bank bank);
+unsigned int mvebu_sdram_bs(enum memory_bank bank);
+void mvebu_sdram_size_adjust(enum memory_bank bank);
 int kw_config_adr_windows(void);
-void kw_config_gpio(unsigned int gpp0_oe_val, unsigned int gpp1_oe_val,
+void mvebu_config_gpio(unsigned int gpp0_oe_val, unsigned int gpp1_oe_val,
                unsigned int gpp0_oe, unsigned int gpp1_oe);
 int kw_config_mpp(unsigned int mpp0_7, unsigned int mpp8_15,
                unsigned int mpp16_23, unsigned int mpp24_31,
index 5f4d78608559dd60f7babb5f70090429e3a56d43..aa8c5da36d35c4b3102083b1f8f9c916f0e0f622 100644 (file)
 
 #define GPIO_MAX               50
 #define GPIO_OFF(pin)          (((pin) >> 5) ? 0x0040 : 0x0000)
-#define GPIO_OUT(pin)          (KW_GPIO0_BASE + GPIO_OFF(pin) + 0x00)
-#define GPIO_IO_CONF(pin)      (KW_GPIO0_BASE + GPIO_OFF(pin) + 0x04)
-#define GPIO_BLINK_EN(pin)     (KW_GPIO0_BASE + GPIO_OFF(pin) + 0x08)
-#define GPIO_IN_POL(pin)       (KW_GPIO0_BASE + GPIO_OFF(pin) + 0x0c)
-#define GPIO_DATA_IN(pin)      (KW_GPIO0_BASE + GPIO_OFF(pin) + 0x10)
-#define GPIO_EDGE_CAUSE(pin)   (KW_GPIO0_BASE + GPIO_OFF(pin) + 0x14)
-#define GPIO_EDGE_MASK(pin)    (KW_GPIO0_BASE + GPIO_OFF(pin) + 0x18)
-#define GPIO_LEVEL_MASK(pin)   (KW_GPIO0_BASE + GPIO_OFF(pin) + 0x1c)
+#define GPIO_OUT(pin)          (MVEBU_GPIO0_BASE + GPIO_OFF(pin) + 0x00)
+#define GPIO_IO_CONF(pin)      (MVEBU_GPIO0_BASE + GPIO_OFF(pin) + 0x04)
+#define GPIO_BLINK_EN(pin)     (MVEBU_GPIO0_BASE + GPIO_OFF(pin) + 0x08)
+#define GPIO_IN_POL(pin)       (MVEBU_GPIO0_BASE + GPIO_OFF(pin) + 0x0c)
+#define GPIO_DATA_IN(pin)      (MVEBU_GPIO0_BASE + GPIO_OFF(pin) + 0x10)
+#define GPIO_EDGE_CAUSE(pin)   (MVEBU_GPIO0_BASE + GPIO_OFF(pin) + 0x14)
+#define GPIO_EDGE_MASK(pin)    (MVEBU_GPIO0_BASE + GPIO_OFF(pin) + 0x18)
+#define GPIO_LEVEL_MASK(pin)   (MVEBU_GPIO0_BASE + GPIO_OFF(pin) + 0x1c)
 
 /*
  * Kirkwood-specific GPIO API
similarity index 90%
rename from arch/arm/include/asm/arch-kirkwood/kirkwood.h
rename to arch/arm/include/asm/arch-kirkwood/soc.h
index 3ea51d7848c5f21bd93baef774b22e692f4eb2c0..58ed71b186413c4c014ca672a3af8ab29246928c 100644 (file)
 #define KW_REG_UNDOC_0x1470            (KW_REGISTER(0x1470))
 #define KW_REG_UNDOC_0x1478            (KW_REGISTER(0x1478))
 
+#define MVEBU_SDRAM_BASE               (KW_REGISTER(0x1500))
 #define KW_TWSI_BASE                   (KW_REGISTER(0x11000))
 #define KW_UART0_BASE                  (KW_REGISTER(0x12000))
 #define KW_UART1_BASE                  (KW_REGISTER(0x12100))
 #define KW_MPP_BASE                    (KW_REGISTER(0x10000))
-#define KW_GPIO0_BASE                  (KW_REGISTER(0x10100))
-#define KW_GPIO1_BASE                  (KW_REGISTER(0x10140))
+#define MVEBU_GPIO0_BASE                       (KW_REGISTER(0x10100))
+#define MVEBU_GPIO1_BASE                       (KW_REGISTER(0x10140))
 #define KW_RTC_BASE                    (KW_REGISTER(0x10300))
 #define KW_NANDF_BASE                  (KW_REGISTER(0x10418))
-#define KW_SPI_BASE                    (KW_REGISTER(0x10600))
+#define MVEBU_SPI_BASE                 (KW_REGISTER(0x10600))
 #define KW_CPU_WIN_BASE                        (KW_REGISTER(0x20000))
 #define KW_CPU_REG_BASE                        (KW_REGISTER(0x20100))
-#define KW_TIMER_BASE                  (KW_REGISTER(0x20300))
+#define MVEBU_TIMER_BASE                       (KW_REGISTER(0x20300))
 #define KW_REG_PCIE_BASE               (KW_REGISTER(0x40000))
 #define KW_USB20_BASE                  (KW_REGISTER(0x50000))
 #define KW_EGIGA0_BASE                 (KW_REGISTER(0x72000))
index a500b5bc3b6581b9e72a73998d8ee3ded1d55034..f2c9687df42cb9da9cc480cc0d35b5255a400c9e 100644 (file)
@@ -19,6 +19,8 @@
 #define CONFIG_SYS_IFC_ADDR                    (CONFIG_SYS_IMMR + 0x00530000)
 #define CONFIG_SYS_FSL_ESDHC_ADDR              (CONFIG_SYS_IMMR + 0x00560000)
 #define CONFIG_SYS_FSL_SCFG_ADDR               (CONFIG_SYS_IMMR + 0x00570000)
+#define CONFIG_SYS_FSL_SEC_ADDR                        (CONFIG_SYS_IMMR + 0x700000)
+#define CONFIG_SYS_FSL_JR0_ADDR                        (CONFIG_SYS_IMMR + 0x710000)
 #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)
@@ -66,6 +68,7 @@
 #define CONFIG_SYS_FSL_DSPI_BE
 #define CONFIG_SYS_FSL_QSPI_BE
 #define CONFIG_SYS_FSL_DCU_BE
+#define CONFIG_SYS_FSL_SEC_LE
 
 #define DCU_LAYER_MAX_NUM                      16
 
@@ -76,6 +79,7 @@
 #define CONFIG_SYS_FSL_IFC_BANK_COUNT          8
 #define CONFIG_NUM_DDR_CONTROLLERS             1
 #define CONFIG_SYS_FSL_DDR_VER                 FSL_DDR_VER_5_0
+#define CONFIG_SYS_FSL_SEC_COMPAT              5
 #else
 #error SoC not defined
 #endif
index 09dfc90a9b0391c7c092285886b1c3fe164daab6..062f3de1d05bfd4de1011762b55fbb6311c84fc9 100644 (file)
@@ -10,6 +10,8 @@
 #ifndef __SYS_PROTO_H__
 #define __SYS_PROTO_H__
 
+#include <asm/imx-common/regs-common.h>
+
 int mxs_reset_block(struct mxs_register_32 *reg);
 int mxs_wait_mask_set(struct mxs_register_32 *reg,
                       uint32_t mask,
index 2f8320629be86380876b7eada7a955dc7d403be7..eba4a5c7f0cf712a2ed822f22d7467f2b2396de0 100644 (file)
 #define CONTROL_PADCONF_SYS_OFF_MODE   0x0A18
 #define CONTROL_PADCONF_SYS_CLKOUT1    0x0A1A
 #define CONTROL_PADCONF_SYS_CLKOUT2    0x01E2
-#define CONTROL_PADCONF_JTAG_nTRST     0x0A1C
+#define CONTROL_PADCONF_JTAG_NTRST     0x0A1C
 #define CONTROL_PADCONF_JTAG_TCK       0x0A1E
 #define CONTROL_PADCONF_JTAG_TMS       0x0A20
 #define CONTROL_PADCONF_JTAG_TDI       0x0A22
 #define OMAP34XX_CTRL_WKUP_CTRL                (OMAP34XX_CTRL_BASE + 0x0A5C)
 #define OMAP34XX_CTRL_WKUP_CTRL_GPIO_IO_PWRDNZ (1<<6)
 
-#define MUX_VAL(OFFSET,VALUE)\
+#define MUX_VAL(OFFSET, VALUE)\
        writew((VALUE), OMAP34XX_CTRL_BASE + (OFFSET));
 
 #define        CP(x)   (CONTROL_PADCONF_##x)
index 5866bf23e8d2a003515cf0e1637c1c27e2e66a40..34bd8c509aac924b6886b4a34fe0fe36cba38427 100644 (file)
@@ -64,6 +64,7 @@ void try_unlock_memory(void);
 u32 get_boot_type(void);
 void invalidate_dcache(u32);
 u32 wait_on_value(u32, u32, void *, u32);
+void cancel_out(u32 *num, u32 *den, u32 den_limit);
 void sdelay(unsigned long);
 void make_cs1_contiguous(void);
 void omap_nand_switch_ecc(uint32_t, uint32_t);
index d5dbc22c18d0b1717ecba69fddd1df892fcb0aaf..2de205e74b635ba320b02a2fed8994e814b01d42 100644 (file)
@@ -682,8 +682,7 @@ enum s5pc110_gpio_pin {
        S5PC110_GPIO_MP285,
        S5PC110_GPIO_MP286,
        S5PC110_GPIO_MP287,
-       S5PC110_GPIO_RES,
-       S5PC110_GPIO_H00 = (S5PC110_GPIO_RES + (48 * 8)),
+       S5PC110_GPIO_H00,
        S5PC110_GPIO_H01,
        S5PC110_GPIO_H02,
        S5PC110_GPIO_H03,
@@ -815,11 +814,7 @@ static const struct gpio_name_num_table s5pc110_gpio_table[] = {
 void gpio_cfg_pin(int gpio, int cfg);
 void gpio_set_pull(int gpio, int mode);
 void gpio_set_drv(int gpio, int mode);
-int gpio_direction_output(unsigned gpio, int value);
-int gpio_set_value(unsigned gpio, int value);
-int gpio_get_value(unsigned gpio);
 void gpio_set_rate(int gpio, int mode);
-struct s5p_gpio_bank *s5p_gpio_get_bank(unsigned gpio);
 int s5p_gpio_get_pin(unsigned gpio);
 
 /* GPIO pins per bank  */
diff --git a/arch/arm/include/asm/arch-socfpga/spl.h b/arch/arm/include/asm/arch-socfpga/spl.h
deleted file mode 100644 (file)
index 7e310d5..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- *  Copyright (C) 2012 Pavel Machek <pavel@denx.de>
- *
- * SPDX-License-Identifier:    GPL-2.0+
- */
-
-#ifndef _SOCFPGA_SPL_H_
-#define _SOCFPGA_SPL_H_
-
-/* Symbols from linker script */
-extern char __malloc_start, __malloc_end, __stack_start;
-
-#define BOOT_DEVICE_RAM 1
-
-#endif
index 5669f392fab7a38e56558cc2f74ea5c903009b30..c562f621c22624ddf8589afb3e2cc3090eac8b1c 100644 (file)
 #define CLK_GATE_CLOSE                 0x0
 
 /* clock control module regs definition */
+#if defined(CONFIG_SUN6I) || defined(CONFIG_SUN8I)
+#include <asm/arch/clock_sun6i.h>
+#else
 #include <asm/arch/clock_sun4i.h>
+#endif
 
 #ifndef __ASSEMBLY__
 int clock_init(void);
 int clock_twi_onoff(int port, int state);
 void clock_set_pll1(unsigned int hz);
+unsigned int clock_get_pll5p(void);
 unsigned int clock_get_pll6(void);
 void clock_init_safe(void);
 void clock_init_uart(void);
index 1ba997adf9f8b4bf1f2b71c71bc5f1816e308794..90af8e250699b835bbf94c080e798d9eaa575121 100644 (file)
@@ -199,13 +199,16 @@ struct sunxi_ccm_reg {
 #define CCM_PLL5_CTRL_M1_MASK CCM_PLL5_CTRL_M1(0x3)
 #define CCM_PLL5_CTRL_M1_X(n) ((n) - 1)
 #define CCM_PLL5_CTRL_K(n) (((n) & 0x3) << 4)
+#define CCM_PLL5_CTRL_K_SHIFT 4
 #define CCM_PLL5_CTRL_K_MASK CCM_PLL5_CTRL_K(0x3)
 #define CCM_PLL5_CTRL_K_X(n) ((n) - 1)
 #define CCM_PLL5_CTRL_LDO (0x1 << 7)
 #define CCM_PLL5_CTRL_N(n) (((n) & 0x1f) << 8)
+#define CCM_PLL5_CTRL_N_SHIFT 8
 #define CCM_PLL5_CTRL_N_MASK CCM_PLL5_CTRL_N(0x1f)
 #define CCM_PLL5_CTRL_N_X(n) (n)
 #define CCM_PLL5_CTRL_P(n) (((n) & 0x3) << 16)
+#define CCM_PLL5_CTRL_P_SHIFT 16
 #define CCM_PLL5_CTRL_P_MASK CCM_PLL5_CTRL_P(0x3)
 #define CCM_PLL5_CTRL_P_X(n) ((n) - 1)
 #define CCM_PLL5_CTRL_BW (0x1 << 18)
diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h
new file mode 100644 (file)
index 0000000..1397b35
--- /dev/null
@@ -0,0 +1,205 @@
+/*
+ * sun6i clock register definitions
+ *
+ * (C) Copyright 2007-2011
+ * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
+ * Tom Cubie <tangliang@allwinnertech.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#ifndef _SUNXI_CLOCK_SUN6I_H
+#define _SUNXI_CLOCK_SUN6I_H
+
+struct sunxi_ccm_reg {
+       u32 pll1_cfg;           /* 0x00 pll1 control */
+       u32 reserved0;
+       u32 pll2_cfg;           /* 0x08 pll2 control */
+       u32 reserved1;
+       u32 pll3_cfg;           /* 0x10 pll3 control */
+       u32 reserved2;
+       u32 pll4_cfg;           /* 0x18 pll4 control */
+       u32 reserved3;
+       u32 pll5_cfg;           /* 0x20 pll5 control */
+       u32 reserved4;
+       u32 pll6_cfg;           /* 0x28 pll6 control */
+       u32 reserved5;
+       u32 pll7_cfg;           /* 0x30 pll7 control */
+       u32 reserved6;
+       u32 pll8_cfg;           /* 0x38 pll8 control */
+       u32 reserved7;
+       u32 mipi_pll_cfg;       /* 0x40 MIPI pll control */
+       u32 pll9_cfg;           /* 0x44 pll9 control */
+       u32 pll10_cfg;          /* 0x48 pll10 control */
+       u32 reserved8;
+       u32 cpu_axi_cfg;        /* 0x50 CPU/AXI divide ratio */
+       u32 ahb1_apb1_div;      /* 0x54 AHB1/APB1 divide ratio */
+       u32 apb2_div;           /* 0x58 APB2 divide ratio */
+       u32 axi_gate;           /* 0x5c axi module clock gating */
+       u32 ahb_gate0;          /* 0x60 ahb module clock gating 0 */
+       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 nand0_clk_cfg;      /* 0x80 nand0 clock control */
+       u32 nand1_clk_cfg;      /* 0x84 nand1 clock control */
+       u32 sd0_clk_cfg;        /* 0x88 sd0 clock control */
+       u32 sd1_clk_cfg;        /* 0x8c sd1 clock control */
+       u32 sd2_clk_cfg;        /* 0x90 sd2 clock control */
+       u32 sd3_clk_cfg;        /* 0x94 sd3 clock control */
+       u32 ts_clk_cfg;         /* 0x98 transport stream clock control */
+       u32 ss_clk_cfg;         /* 0x9c security system clock control */
+       u32 spi0_clk_cfg;       /* 0xa0 spi0 clock control */
+       u32 spi1_clk_cfg;       /* 0xa4 spi1 clock control */
+       u32 spi2_clk_cfg;       /* 0xa8 spi2 clock control */
+       u32 spi3_clk_cfg;       /* 0xac spi3 clock control */
+       u32 i2s0_clk_cfg;       /* 0xb0 I2S0 clock control*/
+       u32 i2s1_clk_cfg;       /* 0xb4 I2S1 clock control */
+       u32 reserved10[2];
+       u32 spdif_clk_cfg;      /* 0xc0 SPDIF clock control */
+       u32 reserved11[2];
+       u32 usb_clk_cfg;        /* 0xcc USB clock control */
+       u32 gmac_clk_cfg;       /* 0xd0 GMAC clock control */
+       u32 reserved12[7];
+       u32 mdfs_clk_cfg;       /* 0xf0 MDFS clock control */
+       u32 dram_clk_cfg;       /* 0xf4 DRAM configuration clock control */
+       u32 reserved13[2];
+       u32 dram_clk_gate;      /* 0x100 DRAM module gating */
+       u32 be0_clk_cfg;        /* 0x104 BE0 module clock */
+       u32 be1_clk_cfg;        /* 0x108 BE1 module clock */
+       u32 fe0_clk_cfg;        /* 0x10c FE0 module clock */
+       u32 fe1_clk_cfg;        /* 0x110 FE1 module clock */
+       u32 mp_clk_cfg;         /* 0x114 MP module clock */
+       u32 lcd0_ch0_clk_cfg;   /* 0x118 LCD0 CH0 module clock */
+       u32 lcd1_ch0_clk_cfg;   /* 0x11c LCD1 CH0 module clock */
+       u32 reserved14[3];
+       u32 lcd0_ch1_clk_cfg;   /* 0x12c LCD0 CH1 module clock */
+       u32 lcd1_ch1_clk_cfg;   /* 0x130 LCD1 CH1 module clock */
+       u32 csi0_clk_cfg;       /* 0x134 CSI0 module clock */
+       u32 csi1_clk_cfg;       /* 0x138 CSI1 module clock */
+       u32 ve_clk_cfg;         /* 0x13c VE module clock */
+       u32 adda_clk_cfg;       /* 0x140 ADDA module clock */
+       u32 avs_clk_cfg;        /* 0x144 AVS module clock */
+       u32 dmic_clk_cfg;       /* 0x148 Digital Mic module clock*/
+       u32 reserved15;
+       u32 hdmi_clk_cfg;       /* 0x150 HDMI module clock */
+       u32 ps_clk_cfg;         /* 0x154 PS module clock */
+       u32 mtc_clk_cfg;        /* 0x158 MTC module clock */
+       u32 mbus0_clk_cfg;      /* 0x15c MBUS0 module clock */
+       u32 mbus1_clk_cfg;      /* 0x160 MBUS1 module clock */
+       u32 reserved16;
+       u32 mipi_dsi_clk_cfg;   /* 0x168 MIPI DSI clock control */
+       u32 mipi_csi_clk_cfg;   /* 0x16c MIPI CSI clock control */
+       u32 reserved17[4];
+       u32 iep_drc0_clk_cfg;   /* 0x180 IEP DRC0 module clock */
+       u32 iep_drc1_clk_cfg;   /* 0x184 IEP DRC1 module clock */
+       u32 iep_deu0_clk_cfg;   /* 0x188 IEP DEU0 module clock */
+       u32 iep_deu1_clk_cfg;   /* 0x18c IEP DEU1 module clock */
+       u32 reserved18[4];
+       u32 gpu_core_clk_cfg;   /* 0x1a0 GPU core clock config */
+       u32 gpu_mem_clk_cfg;    /* 0x1a4 GPU memory clock config */
+       u32 gpu_hyd_clk_cfg;    /* 0x1a0 GPU HYD clock config */
+       u32 reserved19[21];
+       u32 pll_lock;           /* 0x200 PLL Lock Time */
+       u32 pll1_lock;          /* 0x204 PLL1 Lock Time */
+       u32 reserved20[6];
+       u32 pll1_bias_cfg;      /* 0x220 PLL1 Bias config */
+       u32 pll2_bias_cfg;      /* 0x224 PLL2 Bias config */
+       u32 pll3_bias_cfg;      /* 0x228 PLL3 Bias config */
+       u32 pll4_bias_cfg;      /* 0x22c PLL4 Bias config */
+       u32 pll5_bias_cfg;      /* 0x230 PLL5 Bias config */
+       u32 pll6_bias_cfg;      /* 0x234 PLL6 Bias config */
+       u32 pll7_bias_cfg;      /* 0x238 PLL7 Bias config */
+       u32 pll8_bias_cfg;      /* 0x23c PLL8 Bias config */
+       u32 mipi_bias_cfg;      /* 0x240 MIPI Bias config */
+       u32 pll9_bias_cfg;      /* 0x244 PLL9 Bias config */
+       u32 pll10_bias_cfg;     /* 0x248 PLL10 Bias config */
+       u32 reserved21[13];
+       u32 pll1_pattern_cfg;   /* 0x280 PLL1 Pattern config */
+       u32 pll2_pattern_cfg;   /* 0x284 PLL2 Pattern config */
+       u32 pll3_pattern_cfg;   /* 0x288 PLL3 Pattern config */
+       u32 pll4_pattern_cfg;   /* 0x28c PLL4 Pattern config */
+       u32 pll5_pattern_cfg;   /* 0x290 PLL5 Pattern config */
+       u32 pll6_pattern_cfg;   /* 0x294 PLL6 Pattern config */
+       u32 pll7_pattern_cfg;   /* 0x298 PLL7 Pattern config */
+       u32 pll8_pattern_cfg;   /* 0x29c PLL8 Pattern config */
+       u32 mipi_pattern_cfg;   /* 0x2a0 MIPI Pattern config */
+       u32 pll9_pattern_cfg;   /* 0x2a4 PLL9 Pattern config */
+       u32 pll10_pattern_cfg;  /* 0x2a8 PLL10 Pattern config */
+       u32 reserved22[5];
+       u32 ahb_reset0_cfg;     /* 0x2c0 AHB1 Reset 0 config */
+       u32 ahb_reset1_cfg;     /* 0x2c4 AHB1 Reset 1 config */
+       u32 ahb_reset2_cfg;     /* 0x2c8 AHB1 Reset 2 config */
+       u32 reserved23;
+       u32 apb1_reset_cfg;     /* 0x2d0 APB1 Reset config */
+       u32 reserved24;
+       u32 apb2_reset_cfg;     /* 0x2d8 APB2 Reset config */
+};
+
+/* apb2 bit field */
+#define APB2_CLK_SRC_LOSC              (0x0 << 24)
+#define APB2_CLK_SRC_OSC24M            (0x1 << 24)
+#define APB2_CLK_SRC_PLL6              (0x2 << 24)
+#define APB2_CLK_SRC_MASK              (0x3 << 24)
+#define APB2_CLK_RATE_N_1              (0x0 << 16)
+#define APB2_CLK_RATE_N_2              (0x1 << 16)
+#define APB2_CLK_RATE_N_4              (0x2 << 16)
+#define APB2_CLK_RATE_N_8              (0x3 << 16)
+#define APB2_CLK_RATE_N_MASK           (3 << 16)
+#define APB2_CLK_RATE_M(m)             (((m)-1) << 0)
+#define APB2_CLK_RATE_M_MASK            (0x1f << 0)
+
+/* apb2 gate field */
+#define APB2_GATE_UART_SHIFT   (16)
+#define APB2_GATE_UART_MASK            (0xff << APB2_GATE_UART_SHIFT)
+#define APB2_GATE_TWI_SHIFT    (0)
+#define APB2_GATE_TWI_MASK             (0xf << APB2_GATE_TWI_SHIFT)
+
+/* cpu_axi_cfg bits */
+#define AXI_DIV_SHIFT                  0
+#define ATB_DIV_SHIFT                  8
+#define CPU_CLK_SRC_SHIFT              16
+
+#define AXI_DIV_1                      0
+#define AXI_DIV_2                      1
+#define AXI_DIV_3                      2
+#define AXI_DIV_4                      3
+#define ATB_DIV_1                      0
+#define ATB_DIV_2                      1
+#define ATB_DIV_4                      2
+#define CPU_CLK_SRC_OSC24M             1
+#define CPU_CLK_SRC_PLL1               2
+
+#define PLL1_CFG_DEFAULT               0x90011b21
+
+#define PLL6_CFG_DEFAULT               0x90041811
+
+#define CCM_PLL6_CTRL_N_SHIFT          8
+#define CCM_PLL6_CTRL_N_MASK           (0x1f << CCM_PLL6_CTRL_N_SHIFT)
+#define CCM_PLL6_CTRL_K_SHIFT          4
+#define CCM_PLL6_CTRL_K_MASK           (0x3 << CCM_PLL6_CTRL_K_SHIFT)
+
+#define AHB_GATE_OFFSET_MMC3           11
+#define AHB_GATE_OFFSET_MMC2           10
+#define AHB_GATE_OFFSET_MMC1           9
+#define AHB_GATE_OFFSET_MMC0           8
+#define AHB_GATE_OFFSET_MMC(n)         (AHB_GATE_OFFSET_MMC0 + (n))
+
+#define CCM_MMC_CTRL_OSCM24 (0x0 << 24)
+#define CCM_MMC_CTRL_PLL6   (0x1 << 24)
+
+#define CCM_MMC_CTRL_ENABLE (0x1 << 31)
+
+#define AHB_RESET_OFFSET_MMC3          11
+#define AHB_RESET_OFFSET_MMC2          10
+#define AHB_RESET_OFFSET_MMC1          9
+#define AHB_RESET_OFFSET_MMC0          8
+#define AHB_RESET_OFFSET_MMC(n)                (AHB_RESET_OFFSET_MMC0 + (n))
+
+/* apb2 reset */
+#define APB2_RESET_UART_SHIFT          (16)
+#define APB2_RESET_UART_MASK           (0xff << APB2_RESET_UART_SHIFT)
+#define APB2_RESET_TWI_SHIFT           (0)
+#define APB2_RESET_TWI_MASK            (0xf << APB2_RESET_TWI_SHIFT)
+
+#endif /* _SUNXI_CLOCK_SUN6I_H */
index a987e51d576902d9ec94c6f4196a97e14e899e7f..0de79a0d50890b8463b59b83169ac0703748aec0 100644 (file)
 #define SUNXI_MALI400_BASE             0x01c40000
 #define SUNXI_GMAC_BASE                        0x01c50000
 
+#define SUNXI_DRAM_COM_BASE            0x01c62000
+#define SUNXI_DRAM_CTL_BASE            0x01c63000
+#define SUNXI_DRAM_PHY_CH1_BASE                0x01c65000
+#define SUNXI_DRAM_PHY_CH2_BASE                0x01c66000
+
 /* module sram */
 #define SUNXI_SRAM_C_BASE              0x01d00000
 
 #define SUNXI_MP_BASE                  0x01e80000
 #define SUNXI_AVG_BASE                 0x01ea0000
 
+#define SUNXI_PRCM_BASE                        0x01f01400
+#define SUNXI_R_UART_BASE              0x01f02800
+#define SUNXI_R_PIO_BASE               0x01f02c00
+#define SUNXI_P2WI_BASE                        0x01f03400
+
 /* CoreSight Debug Module */
 #define SUNXI_CSDM_BASE                        0x3f500000
 
index f7f3d8c41ad4c3cd0f8e5673513b9477f15541dc..7bb649950a982d19d9ea293352a35e82414e06ad 100644 (file)
@@ -10,6 +10,7 @@
 #define _SUNXI_GPIO_H
 
 #include <linux/types.h>
+#include <asm/arch/cpu.h>
 
 /*
  * sunxi has 9 banks of gpio, they are:
 #define SUNXI_GPIO_G   6
 #define SUNXI_GPIO_H   7
 #define SUNXI_GPIO_I   8
+
+/*
+ * This defines the number of GPIO banks for the _main_ GPIO controller.
+ * You should fix up the padding in struct sunxi_gpio_reg below if you
+ * change this.
+ */
 #define SUNXI_GPIO_BANKS 9
 
+/*
+ * sun6i/sun8i and later SoCs have an additional GPIO controller (R_PIO)
+ * at a different register offset.
+ *
+ * sun6i has 2 banks:
+ * PL0 - PL8  | PM0 - PM7
+ *
+ * sun8i has 1 bank:
+ * PL0 - PL11
+ */
+#define SUNXI_GPIO_L   11
+#define SUNXI_GPIO_M   12
+
 struct sunxi_gpio {
        u32 cfg[4];
        u32 dat;
@@ -50,8 +70,9 @@ struct sunxi_gpio_reg {
        struct sunxi_gpio_int gpio_int;
 };
 
-#define BANK_TO_GPIO(bank) \
-       &((struct sunxi_gpio_reg *)SUNXI_PIO_BASE)->gpio_bank[bank]
+#define BANK_TO_GPIO(bank)     (((bank) < SUNXI_GPIO_L) ? \
+       &((struct sunxi_gpio_reg *)SUNXI_PIO_BASE)->gpio_bank[bank] : \
+       &((struct sunxi_gpio_reg *)SUNXI_R_PIO_BASE)->gpio_bank[(bank) - SUNXI_GPIO_L])
 
 #define GPIO_BANK(pin)         ((pin) >> 5)
 #define GPIO_NUM(pin)          ((pin) & 0x1f)
@@ -75,6 +96,8 @@ struct sunxi_gpio_reg {
 #define SUNXI_GPIO_G_NR                32
 #define SUNXI_GPIO_H_NR                32
 #define SUNXI_GPIO_I_NR                32
+#define SUNXI_GPIO_L_NR                32
+#define SUNXI_GPIO_M_NR                32
 
 #define SUNXI_GPIO_NEXT(__gpio) \
        ((__gpio##_START) + (__gpio##_NR) + 0)
@@ -89,6 +112,8 @@ enum sunxi_gpio_number {
        SUNXI_GPIO_G_START = SUNXI_GPIO_NEXT(SUNXI_GPIO_F),
        SUNXI_GPIO_H_START = SUNXI_GPIO_NEXT(SUNXI_GPIO_G),
        SUNXI_GPIO_I_START = SUNXI_GPIO_NEXT(SUNXI_GPIO_H),
+       SUNXI_GPIO_L_START = 352,
+       SUNXI_GPIO_M_START = SUNXI_GPIO_NEXT(SUNXI_GPIO_L),
 };
 
 /* SUNXI GPIO number definitions */
@@ -101,6 +126,8 @@ enum sunxi_gpio_number {
 #define SUNXI_GPG(_nr) (SUNXI_GPIO_G_START + (_nr))
 #define SUNXI_GPH(_nr) (SUNXI_GPIO_H_START + (_nr))
 #define SUNXI_GPI(_nr) (SUNXI_GPIO_I_START + (_nr))
+#define SUNXI_GPL(_nr) (SUNXI_GPIO_L_START + (_nr))
+#define SUNXI_GPM(_nr) (SUNXI_GPIO_M_START + (_nr))
 
 /* GPIO pin function config */
 #define SUNXI_GPIO_INPUT       0
@@ -117,6 +144,8 @@ enum sunxi_gpio_number {
 #define SUN5I_GPB19_UART0_TX   2
 #define SUN5I_GPB20_UART0_RX   2
 
+#define SUN5I_GPG3_SDC1                2
+
 #define SUN5I_GPG3_UART1_TX    4
 #define SUN5I_GPG4_UART1_RX    4
 
@@ -125,15 +154,27 @@ enum sunxi_gpio_number {
 #define SUNXI_GPF0_SDC0                2
 
 #define SUNXI_GPF2_SDC0                2
+
+#ifdef CONFIG_SUN8I
+#define SUNXI_GPF2_UART0_TX    3
+#define SUNXI_GPF4_UART0_RX    3
+#else
 #define SUNXI_GPF2_UART0_TX    4
 #define SUNXI_GPF4_UART0_RX    4
+#endif
 
 #define SUN4I_GPG0_SDC1                4
 
 #define SUN4I_GPH22_SDC1       5
 
+#define SUN6I_GPH20_UART0_TX   2
+#define SUN6I_GPH21_UART0_RX   2
+
 #define SUN4I_GPI4_SDC3                2
 
+#define SUN8I_GPL2_R_UART_TX   2
+#define SUN8I_GPL3_R_UART_RX   2
+
 /* GPIO pin pull-up/down config */
 #define SUNXI_GPIO_PULL_DISABLE        0
 #define SUNXI_GPIO_PULL_UP     1
index 53196e3b024c68f3232a1596f29910f16f2131f0..8a216740a722e4471f4f39680634fe9db861b354 100644 (file)
@@ -43,7 +43,10 @@ struct sunxi_mmc {
        u32 chda;               /* 0x90 */
        u32 cbda;               /* 0x94 */
        u32 res1[26];
-       u32 fifo;               /* 0x100 FIFO access address */
+#if defined(CONFIG_SUN6I) || defined(CONFIG_SUN8I)
+       u32 res2[64];
+#endif
+       u32 fifo;               /* 0x100 (0x200 on sun6i) FIFO access address */
 };
 
 #define SUNXI_MMC_CLK_POWERSAVE                (0x1 << 17)
@@ -120,5 +123,5 @@ struct sunxi_mmc {
 #define SUNXI_MMC_IDIE_TXIRQ           (0x1 << 0)
 #define SUNXI_MMC_IDIE_RXIRQ           (0x1 << 1)
 
-int sunxi_mmc_init(int sdc_no);
+struct mmc *sunxi_mmc_init(int sdc_no);
 #endif /* _SUNXI_MMC_H */
diff --git a/arch/arm/include/asm/arch-sunxi/prcm.h b/arch/arm/include/asm/arch-sunxi/prcm.h
new file mode 100644 (file)
index 0000000..3d3bfa6
--- /dev/null
@@ -0,0 +1,238 @@
+/*
+ * Sunxi A31 Power Management Unit register definition.
+ *
+ * (C) Copyright 2013 Oliver Schinagl <oliver@schinagl.nl>
+ * http://linux-sunxi.org
+ * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
+ * Berg Xing <bergxing@allwinnertech.com>
+ * Tom Cubie <tangliang@allwinnertech.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#ifndef _SUNXI_PRCM_H
+#define _SUNXI_PRCM_H
+
+#define __PRCM_CPUS_CFG_PRE(n) (((n) & 0x3) << 4)
+#define PRCM_CPUS_CFG_PRE_MASK __PRCM_CPUS_CFG_PRE(0x3)
+#define __PRCM_CPUS_CFG_PRE_DIV(n) (((n) >> 1) - 1)
+#define PRCM_CPUS_CFG_PRE_DIV(n) \
+       __PRCM_CPUS_CFG_PRE(__PRCM_CPUS_CFG_CLK_PRE(n))
+#define __PRCM_CPUS_CFG_POST(n) (((n) & 0x1f) << 8)
+#define PRCM_CPUS_CFG_POST_MASK __PRCM_CPUS_CFG_POST(0x1f)
+#define __PRCM_CPUS_CFG_POST_DIV(n) ((n) - 1)
+#define PRCM_CPUS_CFG_POST_DIV(n) \
+       __PRCM_CPUS_CFG_POST_DIV(__PRCM_CPUS_CFG_POST_DIV(n))
+#define __PRCM_CPUS_CFG_CLK_SRC(n) (((n) & 0x3) << 16)
+#define PRCM_CPUS_CFG_CLK_SRC_MASK __PRCM_CPUS_CFG_CLK_SRC(0x3)
+#define __PRCM_CPUS_CFG_CLK_SRC_LOSC 0x0
+#define __PRCM_CPUS_CFG_CLK_SRC_HOSC 0x1
+#define __PRCM_CPUS_CFG_CLK_SRC_PLL6 0x2
+#define __PRCM_CPUS_CFG_CLK_SRC_PDIV 0x3
+#define PRCM_CPUS_CFG_CLK_SRC_LOSC \
+       __PRCM_CPUS_CFG_CLK_SRC(__PRCM_CPUS_CFG_CLK_SRC_LOSC)
+#define PRCM_CPUS_CFG_CLK_SRC_HOSC \
+       __PRCM_CPUS_CFG_CLK_SRC(__PRCM_CPUS_CFG_CLK_SRC_HOSC)
+#define PRCM_CPUS_CFG_CLK_SRC_PLL6 \
+       __PRCM_CPUS_CFG_CLK_SRC(__PRCM_CPUS_CFG_CLK_SRC_PLL6)
+#define PRCM_CPUS_CFG_CLK_SRC_PDIV \
+       __PRCM_CPUS_CFG_CLK_SRC(__PRCM_CPUS_CFG_CLK_SRC_PDIV)
+
+#define __PRCM_APB0_RATIO(n) (((n) & 0x3) << 0)
+#define PRCM_APB0_RATIO_DIV_MASK __PRCM_APB0_RATIO_DIV(0x3)
+#define __PRCM_APB0_RATIO_DIV(n) (((n) >> 1) - 1)
+#define PRCM_APB0_RATIO_DIV(n) \
+       __PRCM_APB0_RATIO(__PRCM_APB0_RATIO_DIV(n))
+
+#define PRCM_CPU_CFG_NEON_CLK_EN (0x1 << 0)
+#define PRCM_CPU_CFG_CPU_CLK_EN (0x1 << 1)
+
+#define PRCM_APB0_GATE_PIO (0x1 << 0)
+#define PRCM_APB0_GATE_IR (0x1 << 1)
+#define PRCM_APB0_GATE_TIMER01 (0x1 << 2)
+#define PRCM_APB0_GATE_P2WI (0x1 << 3)
+#define PRCM_APB0_GATE_UART (0x1 << 4)
+#define PRCM_APB0_GATE_1WIRE (0x1 << 5)
+#define PRCM_APB0_GATE_I2C (0x1 << 6)
+
+#define PRCM_APB0_RESET_PIO (0x1 << 0)
+#define PRCM_APB0_RESET_IR (0x1 << 1)
+#define PRCM_APB0_RESET_TIMER01 (0x1 << 2)
+#define PRCM_APB0_RESET_P2WI (0x1 << 3)
+#define PRCM_APB0_RESET_UART (0x1 << 4)
+#define PRCM_APB0_RESET_1WIRE (0x1 << 5)
+#define PRCM_APB0_RESET_I2C (0x1 << 6)
+
+#define PRCM_PLL_CTRL_PLL_BIAS (0x1 << 0)
+#define PRCM_PLL_CTRL_HOSC_GAIN_ENH (0x1 << 1)
+#define __PRCM_PLL_CTRL_USB_CLK_SRC(n) (((n) & 0x3) << 4)
+#define PRCM_PLL_CTRL_USB_CLK_SRC_MASK \
+       __PRCM_PLL_CTRL_USB_CLK_SRC(0x3)
+#define __PRCM_PLL_CTRL_USB_CLK_0 0x0
+#define __PRCM_PLL_CTRL_USB_CLK_1 0x1
+#define __PRCM_PLL_CTRL_USB_CLK_2 0x2
+#define __PRCM_PLL_CTRL_USB_CLK_3 0x3
+#define PRCM_PLL_CTRL_USB_CLK_0 \
+       __PRCM_PLL_CTRL_USB_CLK_SRC(__PRCM_PLL_CTRL_USB_CLK_0)
+#define PRCM_PLL_CTRL_USB_CLK_1 \
+       __PRCM_PLL_CTRL_USB_CLK_SRC(__PRCM_PLL_CTRL_USB_CLK_1)
+#define PRCM_PLL_CTRL_USB_CLK_2 \
+       __PRCM_PLL_CTRL_USB_CLK_SRC(__PRCM_PLL_CTRL_USB_CLK_2)
+#define PRCM_PLL_CTRL_USB_CLK_3 \
+       __PRCM_PLL_CTRL_USB_CLK_SRC(__PRCM_PLL_CTRL_USB_CLK_3)
+#define __PRCM_PLL_CTRL_INT_PLL_IN_SEL(n) (((n) & 0x3) << 12)
+#define PRCM_PLL_CTRL_INT_PLL_IN_SEL_MASK \
+       __PRCM_PLL_CTRL_INT_PLL_IN_SEL(0x3)
+#define PRCM_PLL_CTRL_INT_PLL_IN_SEL(n) \
+       __PRCM_PLL_CTRL_INT_PLL_IN_SEL(n)
+#define __PRCM_PLL_CTRL_HOSC_CLK_SEL(n) (((n) & 0x3) << 20)
+#define PRCM_PLL_CTRL_HOSC_CLK_SEL_MASK \
+       __PRCM_PLL_CTRL_HOSC_CLK_SEL(0x3)
+#define __PRCM_PLL_CTRL_HOSC_CLK_0 0x0
+#define __PRCM_PLL_CTRL_HOSC_CLK_1 0x1
+#define __PRCM_PLL_CTRL_HOSC_CLK_2 0x2
+#define __PRCM_PLL_CTRL_HOSC_CLK_3 0x3
+#define PRCM_PLL_CTRL_HOSC_CLK_0 \
+       __PRCM_PLL_CTRL_HOSC_CLK_SEL(__PRCM_PLL_CTRL_HOSC_CLK_0)
+#define PRCM_PLL_CTRL_HOSC_CLK_1 \
+       __PRCM_PLL_CTRL_HOSC_CLK_SEL(__PRCM_PLL_CTRL_HOSC_CLK_1)
+#define PRCM_PLL_CTRL_HOSC_CLK_2 \
+       __PRCM_PLL_CTRL_HOSC_CLK_SEL(__PRCM_PLL_CTRL_HOSC_CLK_2)
+#define PRCM_PLL_CTRL_HOSC_CLK_3 \
+       __PRCM_PLL_CTRL_HOSC_CLK_SEL(__PRCM_PLL_CTRL_HOSC_CLK_3)
+#define PRCM_PLL_CTRL_PLL_TST_SRC_EXT (0x1 << 24)
+#define PRCM_PLL_CTRL_LDO_DIGITAL_EN (0x1 << 0)
+#define PRCM_PLL_CTRL_LDO_ANALOG_EN (0x1 << 1)
+#define PRCM_PLL_CTRL_EXT_OSC_EN (0x1 << 2)
+#define PRCM_PLL_CTRL_CLK_TST_EN (0x1 << 3)
+#define PRCM_PLL_CTRL_IN_PWR_HIGH (0x1 << 15) /* 3.3 for hi 2.5 for lo */
+#define __PRCM_PLL_CTRL_VDD_LDO_OUT(n) (((n) & 0x7) << 16)
+#define PRCM_PLL_CTRL_LDO_OUT_MASK \
+       __PRCM_PLL_CTRL_LDO_OUT(0x7)
+/* When using the low voltage 20 mV steps, and high voltage 30 mV steps */
+#define PRCM_PLL_CTRL_LDO_OUT_L(n) \
+       __PRCM_PLL_CTRL_VDD_LDO_OUT((((n) - 1000) / 20) & 0x7)
+#define PRCM_PLL_CTRL_LDO_OUT_H(n) \
+       __PRCM_PLL_CTRL_VDD_LDO_OUT((((n) - 1160) / 30) & 0x7)
+#define PRCM_PLL_CTRL_LDO_OUT_LV(n) \
+       __PRCM_PLL_CTRL_VDD_LDO_OUT((((n) & 0x7) * 20) + 1000)
+#define PRCM_PLL_CTRL_LDO_OUT_HV(n) \
+       __PRCM_PLL_CTRL_VDD_LDO_OUT((((n) & 0x7) * 30) + 1160)
+#define PRCM_PLL_CTRL_LDO_KEY (0xa7 << 24)
+
+#define PRCM_CLK_1WIRE_GATE (0x1 << 31)
+
+#define __PRCM_CLK_MOD0_M(n) (((n) & 0xf) << 0)
+#define PRCM_CLK_MOD0_M_MASK __PRCM_CLK_MOD0_M(0xf)
+#define __PRCM_CLK_MOD0_M_X(n) (n - 1)
+#define PRCM_CLK_MOD0_M(n) __PRCM_CLK_MOD0_M(__PRCM_CLK_MOD0_M_X(n))
+#define PRCM_CLK_MOD0_OUT_PHASE(n) (((n) & 0x7) << 8)
+#define PRCM_CLK_MOD0_OUT_PHASE_MASK(n) PRCM_CLK_MOD0_OUT_PHASE(0x7)
+#define _PRCM_CLK_MOD0_N(n) (((n) & 0x3) << 16)
+#define PRCM_CLK_MOD0_N_MASK __PRCM_CLK_MOD_N(0x3)
+#define __PRCM_CLK_MOD0_N_X(n) (((n) >> 1) - 1)
+#define PRCM_CLK_MOD0_N(n) __PRCM_CLK_MOD0_N(__PRCM_CLK_MOD0_N_X(n))
+#define PRCM_CLK_MOD0_SMPL_PHASE(n) (((n) & 0x7) << 20)
+#define PRCM_CLK_MOD0_SMPL_PHASE_MASK PRCM_CLK_MOD0_SMPL_PHASE(0x7)
+#define PRCM_CLK_MOD0_SRC_SEL(n) (((n) & 0x7) << 24)
+#define PRCM_CLK_MOD0_SRC_SEL_MASK PRCM_CLK_MOD0_SRC_SEL(0x7)
+#define PRCM_CLK_MOD0_GATE_EN (0x1 << 31)
+
+#define PRCM_APB0_RESET_PIO (0x1 << 0)
+#define PRCM_APB0_RESET_IR (0x1 << 1)
+#define PRCM_APB0_RESET_TIMER01 (0x1 << 2)
+#define PRCM_APB0_RESET_P2WI (0x1 << 3)
+#define PRCM_APB0_RESET_UART (0x1 << 4)
+#define PRCM_APB0_RESET_1WIRE (0x1 << 5)
+#define PRCM_APB0_RESET_I2C (0x1 << 6)
+
+#define __PRCM_CLK_OUTD_M(n) (((n) & 0x7) << 8)
+#define PRCM_CLK_OUTD_M_MASK __PRCM_CLK_OUTD_M(0x7)
+#define __PRCM_CLK_OUTD_M_X() ((n) - 1)
+#define PRCM_CLK_OUTD_M(n) __PRCM_CLK_OUTD_M(__PRCM_CLK_OUTD_M_X(n))
+#define __PRCM_CLK_OUTD_N(n) (((n) & 0x7) << 20)
+#define PRCM_CLK_OUTD_N_MASK __PRCM_CLK_OUTD_N(0x7)
+#define __PRCM_CLK_OUTD_N_X(n) (((n) >> 1) - 1)
+#define PRCM_CLK_OUTD_N(n) __PRCM_CLK_OUTD_N(__PRCM_CLK_OUTD_N_X(n)
+#define __PRCM_CLK_OUTD_SRC_SEL(n) (((n) & 0x3) << 24)
+#define PRCM_CLK_OUTD_SRC_SEL_MASK __PRCM_CLK_OUTD_SRC_SEL(0x3)
+#define __PRCM_CLK_OUTD_SRC_LOSC2 0x0
+#define __PRCM_CLK_OUTD_SRC_LOSC 0x1
+#define __PRCM_CLK_OUTD_SRC_HOSC 0x2
+#define __PRCM_CLK_OUTD_SRC_ERR 0x3
+#define PRCM_CLK_OUTD_SRC_LOSC2 \
+#deifne __PRCM_CLK_OUTD_SRC_SEL(__PRCM_CLK_OUTD_SRC_LOSC2)
+#define PRCM_CLK_OUTD_SRC_LOSC \
+#deifne __PRCM_CLK_OUTD_SRC_SEL(__PRCM_CLK_OUTD_SRC_LOSC)
+#define PRCM_CLK_OUTD_SRC_HOSC \
+#deifne __PRCM_CLK_OUTD_SRC_SEL(__PRCM_CLK_OUTD_SRC_HOSC)
+#define PRCM_CLK_OUTD_SRC_ERR \
+#deifne __PRCM_CLK_OUTD_SRC_SEL(__PRCM_CLK_OUTD_SRC_ERR)
+#define PRCM_CLK_OUTD_EN (0x1 << 31)
+
+#define PRCM_CPU0_PWROFF (0x1 << 0)
+#define PRCM_CPU1_PWROFF (0x1 << 1)
+#define PRCM_CPU2_PWROFF (0x1 << 2)
+#define PRCM_CPU3_PWROFF (0x1 << 3)
+#define PRCM_CPU_ALL_PWROFF (0xf << 0)
+
+#define PRCM_VDD_SYS_DRAM_CH0_PAD_HOLD_PWROFF (0x1 << 0)
+#define PRCM_VDD_SYS_DRAM_CH1_PAD_HOLD_PWROFF (0x1 << 1)
+#define PRCM_VDD_SYS_AVCC_A_PWROFF (0x1 << 2)
+#define PRCM_VDD_SYS_CPU0_VDD_PWROFF (0x1 << 3)
+
+#define PRCM_VDD_GPU_PWROFF (0x1 << 0)
+
+#define PRCM_VDD_SYS_RESET (0x1 << 0)
+
+#define PRCM_CPU1_PWR_CLAMP(n) (((n) & 0xff) << 0)
+#define PRCM_CPU1_PWR_CLAMP_MASK PRCM_CPU1_PWR_CLAMP(0xff)
+
+#define PRCM_CPU2_PWR_CLAMP(n) (((n) & 0xff) << 0)
+#define PRCM_CPU2_PWR_CLAMP_MASK PRCM_CPU2_PWR_CLAMP(0xff)
+
+#define PRCM_CPU3_PWR_CLAMP(n) (((n) & 0xff) << 0)
+#define PRCM_CPU3_PWR_CLAMP_MASK PRCM_CPU3_PWR_CLAMP(0xff)
+
+#ifndef __ASSEMBLY__
+struct sunxi_prcm_reg {
+       u32 cpus_cfg;           /* 0x000 */
+       u8 res0[0x8];           /* 0x004 */
+       u32 apb0_ratio;         /* 0x00c */
+       u32 cpu0_cfg;           /* 0x010 */
+       u32 cpu1_cfg;           /* 0x014 */
+       u32 cpu2_cfg;           /* 0x018 */
+       u32 cpu3_cfg;           /* 0x01c */
+       u8 res1[0x8];           /* 0x020 */
+       u32 apb0_gate;          /* 0x028 */
+       u8 res2[0x14];          /* 0x02c */
+       u32 pll_ctrl0;          /* 0x040 */
+       u32 pll_ctrl1;          /* 0x044 */
+       u8 res3[0x8];           /* 0x048 */
+       u32 clk_1wire;          /* 0x050 */
+       u32 clk_ir;             /* 0x054 */
+       u8 res4[0x58];          /* 0x058 */
+       u32 apb0_reset;         /* 0x0b0 */
+       u8 res5[0x3c];          /* 0x0b4 */
+       u32 clk_outd;           /* 0x0f0 */
+       u8 res6[0xc];           /* 0x0f4 */
+       u32 cpu_pwroff;         /* 0x100 */
+       u8 res7[0xc];           /* 0x104 */
+       u32 vdd_sys_pwroff;     /* 0x110 */
+       u8 res8[0x4];           /* 0x114 */
+       u32 gpu_pwroff;         /* 0x118 */
+       u8 res9[0x4];           /* 0x11c */
+       u32 vdd_pwr_reset;      /* 0x120 */
+       u8 res10[0x20];         /* 0x124 */
+       u32 cpu1_pwr_clamp;     /* 0x144 */
+       u32 cpu2_pwr_clamp;     /* 0x148 */
+       u32 cpu3_pwr_clamp;     /* 0x14c */
+       u8 res11[0x30];         /* 0x150 */
+       u32 dram_pwr;           /* 0x180 */
+       u8 res12[0xc];          /* 0x184 */
+       u32 dram_tst;           /* 0x190 */
+};
+
+void prcm_apb0_enable(u32 flags);
+#endif /* __ASSEMBLY__ */
+#endif /* _PRCM_H */
index 58e14fd0f713033aeaa2e2b0976b40444a8e1399..03a0684c797a3c28179886a283ca2382d249b17b 100644 (file)
 #ifndef _SUNXI_TIMER_H_
 #define _SUNXI_TIMER_H_
 
-#define WDT_CTRL_RESTART       (0x1 << 0)
-#define WDT_CTRL_KEY           (0x0a57 << 1)
-#define WDT_MODE_EN            (0x1 << 0)
-#define WDT_MODE_RESET_EN      (0x1 << 1)
-
 #ifndef __ASSEMBLY__
 
 #include <linux/types.h>
+#include <asm/arch/watchdog.h>
 
 /* General purpose timer */
 struct sunxi_timer {
@@ -43,12 +39,6 @@ struct sunxi_64cnt {
        u32 hi;                 /* 0xa8 */
 };
 
-/* Watchdog */
-struct sunxi_wdog {
-       u32 ctl;                /* 0x90 */
-       u32 mode;               /* 0x94 */
-};
-
 /* Rtc */
 struct sunxi_rtc {
        u32 ctl;                /* 0x100 */
@@ -77,15 +67,20 @@ struct sunxi_timer_reg {
        struct sunxi_timer timer[6];    /* We have 6 timers */
        u8 res2[16];
        struct sunxi_avs avs;
-       struct sunxi_wdog wdog;
-       u8 res3[8];
-       struct sunxi_64cnt cnt64;
+#if defined(CONFIG_SUN4I) || defined(CONFIG_SUN5I) || defined(CONFIG_SUN7I)
+       struct sunxi_wdog wdog; /* 0x90 */
+       /* XXX the following is not accurate for sun5i/sun7i */
+       struct sunxi_64cnt cnt64;       /* 0xa0 */
        u8 res4[0x58];
        struct sunxi_rtc rtc;
        struct sunxi_alarm alarm;
        struct sunxi_tgp tgp[4];
        u8 res5[8];
        u32 cpu_cfg;
+#else /* CONFIG_SUN6I || CONFIG_SUN8I || ... */
+       u8 res3[16];
+       struct sunxi_wdog wdog[5];      /* We have 5 watchdogs */
+#endif
 };
 
 #endif /* __ASSEMBLY__ */
diff --git a/arch/arm/include/asm/arch-sunxi/watchdog.h b/arch/arm/include/asm/arch-sunxi/watchdog.h
new file mode 100644 (file)
index 0000000..ccc8fa3
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * (C) Copyright 2014
+ * Chen-Yu Tsai <wens@csie.org>
+ *
+ * Watchdog register definitions
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#ifndef _SUNXI_WATCHDOG_H_
+#define _SUNXI_WATCHDOG_H_
+
+#define WDT_CTRL_RESTART       (0x1 << 0)
+#define WDT_CTRL_KEY           (0x0a57 << 1)
+
+#if defined(CONFIG_SUN4I) || defined(CONFIG_SUN5I) || defined(CONFIG_SUN7I)
+
+#define WDT_MODE_EN            (0x1 << 0)
+#define WDT_MODE_RESET_EN      (0x1 << 1)
+
+struct sunxi_wdog {
+       u32 ctl;                /* 0x00 */
+       u32 mode;               /* 0x04 */
+       u32 res[2];
+};
+
+#else
+
+#define WDT_CFG_RESET          (0x1)
+#define WDT_MODE_EN            (0x1)
+
+struct sunxi_wdog {
+       u32 irq_en;             /* 0x00 */
+       u32 irq_sta;            /* 0x04 */
+       u32 res1[2];
+       u32 ctl;                /* 0x10 */
+       u32 cfg;                /* 0x14 */
+       u32 mode;               /* 0x18 */
+       u32 res2;
+};
+
+#endif
+
+#endif /* _SUNXI_WATCHDOG_H_ */
index ff773646cbec669607d5e03a624d1207b4c65b8b..783bb3c0fa12265901fdd3b99c9f2cc008486a83 100644 (file)
@@ -24,10 +24,11 @@ void gpio_early_init(void);  /* overrideable GPIO config        */
  * an empty stub function will be called.
  */
 
-void pinmux_init(void);      /* overrideable general pinmux setup */
-void pin_mux_usb(void);      /* overrideable USB pinmux setup     */
-void pin_mux_spi(void);      /* overrideable SPI pinmux setup     */
-void pin_mux_nand(void);     /* overrideable NAND pinmux setup    */
-void pin_mux_display(void);  /* overrideable DISPLAY pinmux setup */
+void pinmux_init(void);      /* overridable general pinmux setup */
+void pin_mux_usb(void);      /* overridable USB pinmux setup     */
+void pin_mux_spi(void);      /* overridable SPI pinmux setup     */
+void pin_mux_nand(void);     /* overridable NAND pinmux setup    */
+void pin_mux_mmc(void);      /* overridable mmc pinmux setup     */
+void pin_mux_display(void);  /* overridable DISPLAY pinmux setup */
 
 #endif
diff --git a/arch/arm/include/asm/arch-tegra114/mc.h b/arch/arm/include/asm/arch-tegra114/mc.h
new file mode 100644 (file)
index 0000000..044b1e0
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ *  (C) Copyright 2014
+ *  NVIDIA Corporation <www.nvidia.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#ifndef _TEGRA114_MC_H_
+#define _TEGRA114_MC_H_
+
+/**
+ * Defines the memory controller registers we need/care about
+ */
+struct mc_ctlr {
+       u32 reserved0[4];                       /* offset 0x00 - 0x0C */
+       u32 mc_smmu_config;                     /* offset 0x10 */
+       u32 mc_smmu_tlb_config;                 /* offset 0x14 */
+       u32 mc_smmu_ptc_config;                 /* offset 0x18 */
+       u32 mc_smmu_ptb_asid;                   /* offset 0x1C */
+       u32 mc_smmu_ptb_data;                   /* offset 0x20 */
+       u32 reserved1[3];                       /* offset 0x24 - 0x2C */
+       u32 mc_smmu_tlb_flush;                  /* offset 0x30 */
+       u32 mc_smmu_ptc_flush;                  /* offset 0x34 */
+       u32 reserved2[6];                       /* offset 0x38 - 0x4C */
+       u32 mc_emem_cfg;                        /* offset 0x50 */
+       u32 mc_emem_adr_cfg;                    /* offset 0x54 */
+       u32 mc_emem_adr_cfg_dev0;               /* offset 0x58 */
+       u32 mc_emem_adr_cfg_dev1;               /* offset 0x5C */
+       u32 reserved3[12];                      /* offset 0x60 - 0x8C */
+       u32 mc_emem_arb_reserved[28];           /* offset 0x90 - 0xFC */
+       u32 reserved4[338];                     /* offset 0x100 - 0x644 */
+       u32 mc_video_protect_bom;               /* offset 0x648 */
+       u32 mc_video_protect_size_mb;           /* offset 0x64c */
+       u32 mc_video_protect_reg_ctrl;          /* offset 0x650 */
+};
+
+#endif /* _TEGRA114_MC_H_ */
index 5d426b524a1e10776e73940e16c0be70596a6e2a..c3d061ec5867e389cd6b374d9e151428a8f3f5a8 100644 (file)
@@ -19,6 +19,7 @@
 
 #define NV_PA_SDRAM_BASE       0x80000000      /* 0x80000000 for real T114 */
 #define NV_PA_TSC_BASE         0x700F0000      /* System Counter TSC regs */
+#define NV_PA_MC_BASE          0x70019000
 
 #include <asm/arch-tegra/tegra.h>
 
diff --git a/arch/arm/include/asm/arch-tegra114/tegra114_spi.h b/arch/arm/include/asm/arch-tegra114/tegra114_spi.h
deleted file mode 100644 (file)
index 48197bc..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * NVIDIA Tegra SPI controller
- *
- * Copyright 2010-2013 NVIDIA Corporation
- *
- * This software may be used and distributed according to the
- * terms of the GNU Public License, Version 2, incorporated
- * herein by reference.
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-#ifndef _TEGRA114_SPI_H_
-#define _TEGRA114_SPI_H_
-
-#include <asm/types.h>
-
-int tegra114_spi_init(int *node_list, int count);
-int tegra114_spi_cs_is_valid(unsigned int bus, unsigned int cs);
-struct spi_slave *tegra114_spi_setup_slave(unsigned int bus, unsigned int cs,
-                                 unsigned int max_hz, unsigned int mode);
-void tegra114_spi_free_slave(struct spi_slave *slave);
-int tegra114_spi_claim_bus(struct spi_slave *slave);
-void tegra114_spi_cs_activate(struct spi_slave *slave);
-void tegra114_spi_cs_deactivate(struct spi_slave *slave);
-int tegra114_spi_xfer(struct spi_slave *slave, unsigned int bitlen,
-                    const void *data_out, void *data_in, unsigned long flags);
-
-#endif /* _TEGRA114_SPI_H_ */
diff --git a/arch/arm/include/asm/arch-tegra20/mc.h b/arch/arm/include/asm/arch-tegra20/mc.h
new file mode 100644 (file)
index 0000000..9c6e3ff
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ *  (C) Copyright 2014
+ *  NVIDIA Corporation <www.nvidia.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#ifndef _TEGRA20_MC_H_
+#define _TEGRA20_MC_H_
+
+/**
+ * Defines the memory controller registers we need/care about
+ */
+struct mc_ctlr {
+       u32 reserved0[3];                       /* offset 0x00 - 0x08 */
+       u32 mc_emem_cfg;                        /* offset 0x0C */
+       u32 mc_emem_adr_cfg;                    /* offset 0x10 */
+       u32 mc_emem_arb_cfg0;                   /* offset 0x14 */
+       u32 mc_emem_arb_cfg1;                   /* offset 0x18 */
+       u32 mc_emem_arb_cfg2;                   /* offset 0x1C */
+       u32 reserved1;                          /* offset 0x20 */
+       u32 mc_gart_cfg;                        /* offset 0x24 */
+       u32 mc_gart_entry_addr;                 /* offset 0x28 */
+       u32 mc_gart_entry_data;                 /* offset 0x2C */
+       u32 mc_gart_error_req;                  /* offset 0x30 */
+       u32 mc_gart_error_addr;                 /* offset 0x34 */
+       u32 reserved2;                          /* offset 0x38 */
+       u32 mc_timeout_ctrl;                    /* offset 0x3C */
+       u32 reserved3[6];                       /* offset 0x40 - 0x54 */
+       u32 mc_decerr_emem_others_status;       /* offset 0x58 */
+       u32 mc_decerr_emem_others_adr;          /* offset 0x5C */
+       u32 reserved4[40];                      /* offset 0x60 - 0xFC */
+       u32 reserved5[93];                      /* offset 0x100 - 0x270 */
+};
+
+#endif /* _TEGRA20_MC_H_ */
index 18856ac3727d085977a9b5b1b70f9963f33548f4..22774abb936df1f3c0687041f7482e0cfca96a18 100644 (file)
@@ -9,6 +9,7 @@
 #define _TEGRA20_H_
 
 #define NV_PA_SDRAM_BASE       0x00000000
+#define NV_PA_MC_BASE          0x7000F000
 
 #include <asm/arch-tegra/tegra.h>
 
diff --git a/arch/arm/include/asm/arch-tegra20/tegra20_sflash.h b/arch/arm/include/asm/arch-tegra20/tegra20_sflash.h
deleted file mode 100644 (file)
index e8cc68c..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * NVIDIA Tegra20 SPI-FLASH controller
- *
- * Copyright 2010-2012 NVIDIA Corporation
- *
- * This software may be used and distributed according to the
- * terms of the GNU Public License, Version 2, incorporated
- * herein by reference.
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-#ifndef _TEGRA20_SPI_H_
-#define _TEGRA20_SPI_H_
-
-#include <asm/types.h>
-
-int tegra20_spi_cs_is_valid(unsigned int bus, unsigned int cs);
-struct spi_slave *tegra20_spi_setup_slave(unsigned int bus, unsigned int cs,
-                                 unsigned int max_hz, unsigned int mode);
-void tegra20_spi_free_slave(struct spi_slave *slave);
-int tegra20_spi_init(int *node_list, int count);
-int tegra20_spi_claim_bus(struct spi_slave *slave);
-void tegra20_spi_cs_activate(struct spi_slave *slave);
-void tegra20_spi_cs_deactivate(struct spi_slave *slave);
-int tegra20_spi_xfer(struct spi_slave *slave, unsigned int bitlen,
-            const void *data_out, void *data_in, unsigned long flags);
-
-#endif /* _TEGRA20_SPI_H_ */
diff --git a/arch/arm/include/asm/arch-tegra20/tegra20_slink.h b/arch/arm/include/asm/arch-tegra20/tegra20_slink.h
deleted file mode 100644 (file)
index 5aa74dd..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * NVIDIA Tegra SPI-SLINK controller
- *
- * Copyright 2010-2013 NVIDIA Corporation
- *
- * This software may be used and distributed according to the
- * terms of the GNU Public License, Version 2, incorporated
- * herein by reference.
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-#ifndef _TEGRA30_SPI_H_
-#define _TEGRA30_SPI_H_
-
-#include <asm/types.h>
-
-int tegra30_spi_init(int *node_list, int count);
-int tegra30_spi_cs_is_valid(unsigned int bus, unsigned int cs);
-struct spi_slave *tegra30_spi_setup_slave(unsigned int bus, unsigned int cs,
-                                 unsigned int max_hz, unsigned int mode);
-void tegra30_spi_free_slave(struct spi_slave *slave);
-int tegra30_spi_claim_bus(struct spi_slave *slave);
-void tegra30_spi_cs_activate(struct spi_slave *slave);
-void tegra30_spi_cs_deactivate(struct spi_slave *slave);
-int tegra30_spi_xfer(struct spi_slave *slave, unsigned int bitlen,
-                    const void *data_out, void *data_in, unsigned long flags);
-
-#endif /* _TEGRA30_SPI_H_ */
diff --git a/arch/arm/include/asm/arch-tegra30/mc.h b/arch/arm/include/asm/arch-tegra30/mc.h
new file mode 100644 (file)
index 0000000..242a1fc
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ *  (C) Copyright 2014
+ *  NVIDIA Corporation <www.nvidia.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#ifndef _TEGRA30_MC_H_
+#define _TEGRA30_MC_H_
+
+/**
+ * Defines the memory controller registers we need/care about
+ */
+struct mc_ctlr {
+       u32 reserved0[4];                       /* offset 0x00 - 0x0C */
+       u32 mc_smmu_config;                     /* offset 0x10 */
+       u32 mc_smmu_tlb_config;                 /* offset 0x14 */
+       u32 mc_smmu_ptc_config;                 /* offset 0x18 */
+       u32 mc_smmu_ptb_asid;                   /* offset 0x1C */
+       u32 mc_smmu_ptb_data;                   /* offset 0x20 */
+       u32 reserved1[3];                       /* offset 0x24 - 0x2C */
+       u32 mc_smmu_tlb_flush;                  /* offset 0x30 */
+       u32 mc_smmu_ptc_flush;                  /* offset 0x34 */
+       u32 mc_smmu_asid_security;              /* offset 0x38 */
+       u32 reserved2[5];                       /* offset 0x3C - 0x4C */
+       u32 mc_emem_cfg;                        /* offset 0x50 */
+       u32 mc_emem_adr_cfg;                    /* offset 0x54 */
+       u32 mc_emem_adr_cfg_dev0;               /* offset 0x58 */
+       u32 mc_emem_adr_cfg_dev1;               /* offset 0x5C */
+       u32 reserved3[12];                      /* offset 0x60 - 0x8C */
+       u32 mc_emem_arb_reserved[28];           /* offset 0x90 - 0xFC */
+       u32 reserved4[338];                     /* offset 0x100 - 0x644 */
+       u32 mc_video_protect_bom;               /* offset 0x648 */
+       u32 mc_video_protect_size_mb;           /* offset 0x64c */
+       u32 mc_video_protect_reg_ctrl;          /* offset 0x650 */
+};
+
+#endif /* _TEGRA30_MC_H_ */
index c02c5d850037ffb7460b7df3b17f41cbf5c932ca..93671793a9f61d416824115d844ef3d939da17db 100644 (file)
@@ -17,6 +17,7 @@
 #ifndef _TEGRA30_H_
 #define _TEGRA30_H_
 
+#define NV_PA_MC_BASE          0x7000F000
 #define NV_PA_SDRAM_BASE       0x80000000      /* 0x80000000 for real T30 */
 
 #include <asm/arch-tegra/tegra.h>
diff --git a/arch/arm/include/asm/arch-uniphier/platdevice.h b/arch/arm/include/asm/arch-uniphier/platdevice.h
new file mode 100644 (file)
index 0000000..cdf7d13
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2014 Panasonic Corporation
+ *   Author: Masahiro Yamada <yamada.m@jp.panasonic.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#ifndef ARCH_PLATDEVICE_H
+#define ARCH_PLATDEVICE_H
+
+#include <dm/platdata.h>
+#include <dm/platform_data/serial-uniphier.h>
+
+#define SERIAL_DEVICE(n, ba, clk)                                      \
+static struct uniphier_serial_platform_data serial_device##n = {       \
+       .base = ba,                                                     \
+       .uartclk = clk                                                  \
+};                                                                     \
+U_BOOT_DEVICE(serial##n) = {                                           \
+       .name = DRIVER_NAME,                                            \
+       .platdata = &serial_device##n                                   \
+};
+
+#endif /* ARCH_PLATDEVICE_H */
index 182c2f397f1748d0f574a4ffaa9a31335475fba5..af861635350d00209405435084ef767bec5b77e6 100644 (file)
@@ -52,8 +52,8 @@ struct i2c_pads_info {
                                        &mx6q_##name : &mx6s_##name
 #endif
 
-void setup_i2c(unsigned i2c_index, int speed, int slave_addr,
-               struct i2c_pads_info *p);
+int setup_i2c(unsigned i2c_index, int speed, int slave_addr,
+             struct i2c_pads_info *p);
 void bus_i2c_init(void *base, int speed, int slave_addr,
                int (*idle_bus_fn)(void *p), void *p);
 int bus_i2c_read(void *base, uchar chip, uint addr, int alen, uchar *buf,
index 560924e83ffdc56ee498a25e9b415c108fe1b3a3..d4a447b2b8a96568307bb907fd012b5da9f99187 100644 (file)
@@ -1107,6 +1107,7 @@ extern unsigned int __machine_arch_type;
 #define MACH_TYPE_ARMADILLO_800EVA     3863
 #define MACH_TYPE_KZM9G                4140
 #define MACH_TYPE_COLIBRI_T30          4493
+#define MACH_TYPE_APALIS_T30           4513
 
 #ifdef CONFIG_ARCH_EBSA110
 # ifdef machine_arch_type
@@ -14248,6 +14249,18 @@ extern unsigned int __machine_arch_type;
 # define machine_is_colibri_t30()      (0)
 #endif
 
+#ifdef CONFIG_MACH_APALIS_T30
+# ifdef machine_arch_type
+#  undef machine_arch_type
+#  define machine_arch_type    __machine_arch_type
+# else
+#  define machine_arch_type    MACH_TYPE_APALIS_T30
+# endif
+# define machine_is_apalis_t30()       (machine_arch_type == MACH_TYPE_APALIS_T30)
+#else
+# define machine_is_apalis_t30()       (0)
+#endif
+
 /*
  * These have not yet been registered
  */
index 5d25d04c3bf68f45560aa120faf4182cefca8930..839af54d482e9fbc9e03c5a777eb9317566681ea 100644 (file)
 
 #include <asm/arch/cpu.h>
 
+enum gpio_method {
+       METHOD_GPIO_24XX        = 4,
+};
+
+#ifdef CONFIG_DM_GPIO
+
+/* Information about a GPIO bank */
+struct omap_gpio_platdata {
+       int bank_index;
+       ulong base;     /* address of registers in physical memory */
+       enum gpio_method method;
+};
+
+#else
+
 struct gpio_bank {
        void *base;
        int method;
@@ -30,8 +45,6 @@ struct gpio_bank {
 
 extern const struct gpio_bank *const omap_gpio_bank;
 
-#define METHOD_GPIO_24XX       4
-
 /**
  * Check if gpio is valid.
  *
@@ -39,4 +52,6 @@ extern const struct gpio_bank *const omap_gpio_bank;
  * @return 1 if ok, 0 on error
  */
 int gpio_is_valid(int gpio);
+#endif
+
 #endif /* _GPIO_H_ */
index e5daf89127125c4d4379ed5b08775c7e4d0cc5ec..8acd7cd1bd5ab539ccef5201607fcfe64aab08a7 100644 (file)
@@ -7,7 +7,7 @@
 #ifndef        _ASM_SPL_H_
 #define        _ASM_SPL_H_
 
-#if defined(CONFIG_OMAP) || defined(CONFIG_SOCFPGA) \
+#if defined(CONFIG_OMAP) \
        || defined(CONFIG_EXYNOS4) || defined(CONFIG_EXYNOS5) \
        || defined(CONFIG_EXYNOS4210)
 /* Platform-specific defines */
similarity index 91%
rename from arch/arm/include/asm/arch-keystone/keystone_nav.h
rename to arch/arm/include/asm/ti-common/keystone_nav.h
index ab81eaf1fda09fdd472ad07b77fe62acd1a62171..696d8c6fc09edac6c73546f6c804f7548bef8150 100644 (file)
 #include <asm/arch/hardware.h>
 #include <asm/io.h>
 
-enum soc_type_t {
-       k2hk
-};
-
 #define QM_OK                    0
 #define QM_ERR                  -1
 #define QM_DESC_TYPE_HOST        0
@@ -173,6 +169,8 @@ struct pktdma_cfg {
        u32                     rx_flow; /* flow that is used for RX */
 };
 
+extern struct pktdma_cfg netcp_pktdma;
+
 /*
  * packet dma user allocates memory for rx buffers
  * and describe it in the following structure
@@ -184,10 +182,10 @@ struct rx_buff_desc {
        u32     rx_flow;
 };
 
-int netcp_close(void);
-int netcp_init(struct rx_buff_desc *rx_buffers);
-int netcp_send(u32 *pkt, int num_bytes, u32 swinfo2);
-void *netcp_recv(u32 **pkt, int *num_bytes);
-void netcp_release_rxhd(void *hd);
+int ksnav_close(struct pktdma_cfg *pktdma);
+int ksnav_init(struct pktdma_cfg *pktdma, struct rx_buff_desc *rx_buffers);
+int ksnav_send(struct pktdma_cfg *pktdma, u32 *pkt, int num_bytes, u32 swinfo2);
+void *ksnav_recv(struct pktdma_cfg *pktdma, u32 **pkt, int *num_bytes);
+void ksnav_release_rxhd(struct pktdma_cfg *pktdma, void *hd);
 
 #endif  /* _KEYSTONE_NAV_H_ */
diff --git a/arch/arm/include/asm/ti-common/keystone_net.h b/arch/arm/include/asm/ti-common/keystone_net.h
new file mode 100644 (file)
index 0000000..011c03c
--- /dev/null
@@ -0,0 +1,249 @@
+/*
+ * emac definitions for keystone2 devices
+ *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#ifndef _KEYSTONE_NET_H_
+#define _KEYSTONE_NET_H_
+
+#include <asm/io.h>
+
+/* EMAC */
+#ifdef CONFIG_KSNET_NETCP_V1_0
+
+#define GBETH_BASE                     (CONFIG_KSNET_NETCP_BASE + 0x00090000)
+#define EMAC_EMACSL_BASE_ADDR          (GBETH_BASE + 0x900)
+#define EMAC_MDIO_BASE_ADDR            (GBETH_BASE + 0x300)
+#define EMAC_SGMII_BASE_ADDR           (GBETH_BASE + 0x100)
+#define DEVICE_EMACSL_BASE(x)          (EMAC_EMACSL_BASE_ADDR + (x) * 0x040)
+
+/* Register offsets */
+#define CPGMACSL_REG_CTL               0x04
+#define CPGMACSL_REG_STATUS            0x08
+#define CPGMACSL_REG_RESET             0x0c
+#define CPGMACSL_REG_MAXLEN            0x10
+
+#elif defined CONFIG_KSNET_NETCP_V1_5
+
+#define GBETH_BASE                     (CONFIG_KSNET_NETCP_BASE + 0x00200000)
+#define CPGMACSL_REG_RX_PRI_MAP                0x020
+#define EMAC_EMACSL_BASE_ADDR          (GBETH_BASE + 0x22000)
+#define EMAC_MDIO_BASE_ADDR            (GBETH_BASE + 0x00f00)
+#define EMAC_SGMII_BASE_ADDR           (GBETH_BASE + 0x00100)
+#define DEVICE_EMACSL_BASE(x)          (EMAC_EMACSL_BASE_ADDR + (x) * 0x1000)
+
+/* Register offsets */
+#define CPGMACSL_REG_CTL               0x330
+#define CPGMACSL_REG_STATUS            0x334
+#define CPGMACSL_REG_RESET             0x338
+#define CPGMACSL_REG_MAXLEN            0x024
+
+#endif
+
+#define KEYSTONE2_EMAC_GIG_ENABLE
+
+#define MAC_ID_BASE_ADDR               CONFIG_KSNET_MAC_ID_BASE
+
+/* MDIO module input frequency */
+#define EMAC_MDIO_BUS_FREQ             (clk_get_rate(pass_pll_clk))
+/* MDIO clock output frequency */
+#define EMAC_MDIO_CLOCK_FREQ           2500000 /* 2.5 MHz */
+
+/* MII Status Register */
+#define MII_STATUS_REG                 1
+#define MII_STATUS_LINK_MASK           0x4
+
+#define MDIO_CONTROL_IDLE              0x80000000
+#define MDIO_CONTROL_ENABLE            0x40000000
+#define MDIO_CONTROL_FAULT_ENABLE      0x40000
+#define MDIO_CONTROL_FAULT             0x80000
+#define MDIO_USERACCESS0_GO            0x80000000
+#define MDIO_USERACCESS0_WRITE_READ    0x0
+#define MDIO_USERACCESS0_WRITE_WRITE   0x40000000
+#define MDIO_USERACCESS0_ACK           0x20000000
+
+#define EMAC_MACCONTROL_MIIEN_ENABLE           0x20
+#define EMAC_MACCONTROL_FULLDUPLEX_ENABLE      0x1
+#define EMAC_MACCONTROL_GIGABIT_ENABLE         BIT(7)
+#define EMAC_MACCONTROL_GIGFORCE               BIT(17)
+#define EMAC_MACCONTROL_RMIISPEED_100          BIT(15)
+
+#define EMAC_MIN_ETHERNET_PKT_SIZE             60
+
+struct mac_sl_cfg {
+       u_int32_t max_rx_len;   /* Maximum receive packet length. */
+       u_int32_t ctl;          /* Control bitfield */
+};
+
+/**
+ * Definition: Control bitfields used in the ctl field of mac_sl_cfg
+ */
+#define GMACSL_RX_ENABLE_RCV_CONTROL_FRAMES    BIT(24)
+#define GMACSL_RX_ENABLE_RCV_SHORT_FRAMES      BIT(23)
+#define GMACSL_RX_ENABLE_RCV_ERROR_FRAMES      BIT(22)
+#define GMACSL_RX_ENABLE_EXT_CTL               BIT(18)
+#define GMACSL_RX_ENABLE_GIG_FORCE             BIT(17)
+#define GMACSL_RX_ENABLE_IFCTL_B               BIT(16)
+#define GMACSL_RX_ENABLE_IFCTL_A               BIT(15)
+#define GMACSL_RX_ENABLE_CMD_IDLE              BIT(11)
+#define GMACSL_TX_ENABLE_SHORT_GAP             BIT(10)
+#define GMACSL_ENABLE_GIG_MODE                 BIT(7)
+#define GMACSL_TX_ENABLE_PACE                  BIT(6)
+#define GMACSL_ENABLE                          BIT(5)
+#define GMACSL_TX_ENABLE_FLOW_CTL              BIT(4)
+#define GMACSL_RX_ENABLE_FLOW_CTL              BIT(3)
+#define GMACSL_ENABLE_LOOPBACK                 BIT(1)
+#define GMACSL_ENABLE_FULL_DUPLEX              BIT(0)
+
+/* EMAC SL function return values */
+#define GMACSL_RET_OK                          0
+#define GMACSL_RET_INVALID_PORT                        -1
+#define GMACSL_RET_WARN_RESET_INCOMPLETE       -2
+#define GMACSL_RET_WARN_MAXLEN_TOO_BIG         -3
+#define GMACSL_RET_CONFIG_FAIL_RESET_ACTIVE    -4
+
+/* EMAC SL register definitions */
+#define DEVICE_EMACSL_RESET_POLL_COUNT         100
+
+/* Soft reset register values */
+#define CPGMAC_REG_RESET_VAL_RESET_MASK                BIT(0)
+#define CPGMAC_REG_RESET_VAL_RESET             BIT(0)
+#define CPGMAC_REG_MAXLEN_LEN                  0x3fff
+
+/* CPSW */
+/* Control bitfields */
+#define CPSW_CTL_P2_PASS_PRI_TAGGED            BIT(5)
+#define CPSW_CTL_P1_PASS_PRI_TAGGED            BIT(4)
+#define CPSW_CTL_P0_PASS_PRI_TAGGED            BIT(3)
+#define CPSW_CTL_P0_ENABLE                     BIT(2)
+#define CPSW_CTL_VLAN_AWARE                    BIT(1)
+#define CPSW_CTL_FIFO_LOOPBACK                 BIT(0)
+
+#define DEVICE_CPSW_NUM_PORTS                  CONFIG_KSNET_CPSW_NUM_PORTS
+#define DEVICE_N_GMACSL_PORTS                  (DEVICE_CPSW_NUM_PORTS - 1)
+
+#ifdef CONFIG_KSNET_NETCP_V1_0
+
+#define DEVICE_CPSW_BASE                       (GBETH_BASE + 0x800)
+#define CPSW_REG_CTL                           0x004
+#define CPSW_REG_STAT_PORT_EN                  0x00c
+#define CPSW_REG_MAXLEN                                0x040
+#define CPSW_REG_ALE_CONTROL                   0x608
+#define CPSW_REG_ALE_PORTCTL(x)                        (0x640 + (x) * 4)
+#define CPSW_REG_VAL_STAT_ENABLE_ALL           0xf
+
+#elif defined CONFIG_KSNET_NETCP_V1_5
+
+#define DEVICE_CPSW_BASE                       (GBETH_BASE + 0x20000)
+#define CPSW_REG_CTL                           0x00004
+#define CPSW_REG_STAT_PORT_EN                  0x00014
+#define CPSW_REG_MAXLEN                                0x01024
+#define CPSW_REG_ALE_CONTROL                   0x1e008
+#define CPSW_REG_ALE_PORTCTL(x)                        (0x1e040 + (x) * 4)
+#define CPSW_REG_VAL_STAT_ENABLE_ALL           0x1ff
+
+#endif
+
+#define CPSW_REG_VAL_ALE_CTL_RESET_AND_ENABLE  ((u_int32_t)0xc0000000)
+#define CPSW_REG_VAL_ALE_CTL_BYPASS            ((u_int32_t)0x00000010)
+#define CPSW_REG_VAL_PORTCTL_FORWARD_MODE      0x3
+
+#define target_get_switch_ctl()                        CPSW_CTL_P0_ENABLE
+#define SWITCH_MAX_PKT_SIZE                    9000
+
+/* SGMII */
+#define SGMII_REG_STATUS_LOCK                  BIT(4)
+#define SGMII_REG_STATUS_LINK                  BIT(0)
+#define SGMII_REG_STATUS_AUTONEG               BIT(2)
+#define SGMII_REG_CONTROL_AUTONEG              BIT(0)
+#define SGMII_REG_CONTROL_MASTER               BIT(5)
+#define SGMII_REG_MR_ADV_ENABLE                        BIT(0)
+#define SGMII_REG_MR_ADV_LINK                  BIT(15)
+#define SGMII_REG_MR_ADV_FULL_DUPLEX           BIT(12)
+#define SGMII_REG_MR_ADV_GIG_MODE              BIT(11)
+
+#define SGMII_LINK_MAC_MAC_AUTONEG             0
+#define SGMII_LINK_MAC_PHY                     1
+#define SGMII_LINK_MAC_MAC_FORCED              2
+#define SGMII_LINK_MAC_FIBER                   3
+#define SGMII_LINK_MAC_PHY_FORCED              4
+
+#ifdef CONFIG_KSNET_NETCP_V1_0
+#define SGMII_OFFSET(x)                ((x <= 1) ? (x * 0x100) : ((x * 0x100) + 0x100))
+#elif defined CONFIG_KSNET_NETCP_V1_5
+#define SGMII_OFFSET(x)                ((x) * 0x100)
+#endif
+
+#define SGMII_IDVER_REG(x)     (EMAC_SGMII_BASE_ADDR + SGMII_OFFSET(x) + 0x000)
+#define SGMII_SRESET_REG(x)    (EMAC_SGMII_BASE_ADDR + SGMII_OFFSET(x) + 0x004)
+#define SGMII_CTL_REG(x)       (EMAC_SGMII_BASE_ADDR + SGMII_OFFSET(x) + 0x010)
+#define SGMII_STATUS_REG(x)    (EMAC_SGMII_BASE_ADDR + SGMII_OFFSET(x) + 0x014)
+#define SGMII_MRADV_REG(x)     (EMAC_SGMII_BASE_ADDR + SGMII_OFFSET(x) + 0x018)
+#define SGMII_LPADV_REG(x)     (EMAC_SGMII_BASE_ADDR + SGMII_OFFSET(x) + 0x020)
+#define SGMII_TXCFG_REG(x)     (EMAC_SGMII_BASE_ADDR + SGMII_OFFSET(x) + 0x030)
+#define SGMII_RXCFG_REG(x)     (EMAC_SGMII_BASE_ADDR + SGMII_OFFSET(x) + 0x034)
+#define SGMII_AUXCFG_REG(x)    (EMAC_SGMII_BASE_ADDR + SGMII_OFFSET(x) + 0x038)
+
+/* PSS */
+#ifdef CONFIG_KSNET_NETCP_V1_0
+
+#define DEVICE_PSTREAM_CFG_REG_ADDR    (CONFIG_KSNET_NETCP_BASE + 0x604)
+#define DEVICE_PSTREAM_CFG_VAL_ROUTE_CPPI      0x06060606
+#define hw_config_streaming_switch()\
+       writel(DEVICE_PSTREAM_CFG_VAL_ROUTE_CPPI, DEVICE_PSTREAM_CFG_REG_ADDR);
+
+#elif defined CONFIG_KSNET_NETCP_V1_5
+
+#define DEVICE_PSTREAM_CFG_REG_ADDR    (CONFIG_KSNET_NETCP_BASE + 0x500)
+#define DEVICE_PSTREAM_CFG_VAL_ROUTE_CPPI      0x0
+
+#define hw_config_streaming_switch()\
+       writel(DEVICE_PSTREAM_CFG_VAL_ROUTE_CPPI,\
+              DEVICE_PSTREAM_CFG_REG_ADDR);\
+       writel(DEVICE_PSTREAM_CFG_VAL_ROUTE_CPPI,\
+              DEVICE_PSTREAM_CFG_REG_ADDR+4);\
+       writel(DEVICE_PSTREAM_CFG_VAL_ROUTE_CPPI,\
+              DEVICE_PSTREAM_CFG_REG_ADDR+8);\
+       writel(DEVICE_PSTREAM_CFG_VAL_ROUTE_CPPI,\
+              DEVICE_PSTREAM_CFG_REG_ADDR+12);
+
+#endif
+
+/* EMAC MDIO Registers Structure */
+struct mdio_regs {
+       u32 version;
+       u32 control;
+       u32 alive;
+       u32 link;
+       u32 linkintraw;
+       u32 linkintmasked;
+       u32 rsvd0[2];
+       u32 userintraw;
+       u32 userintmasked;
+       u32 userintmaskset;
+       u32 userintmaskclear;
+       u32 rsvd1[20];
+       u32 useraccess0;
+       u32 userphysel0;
+       u32 useraccess1;
+       u32 userphysel1;
+};
+
+struct eth_priv_t {
+       char int_name[32];
+       int rx_flow;
+       int phy_addr;
+       int slave_port;
+       int sgmii_link_type;
+       struct phy_device *phy_dev;
+};
+
+int keystone2_emac_initialize(struct eth_priv_t *eth_priv);
+void sgmii_serdes_setup_156p25mhz(void);
+void sgmii_serdes_shutdown(void);
+
+#endif  /* _KEYSTONE_NET_H_ */
diff --git a/arch/arm/include/asm/ti-common/keystone_serdes.h b/arch/arm/include/asm/ti-common/keystone_serdes.h
new file mode 100644 (file)
index 0000000..2e92411
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Texas Instruments Keystone SerDes driver
+ *
+ * (C) Copyright 2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#ifndef __TI_KEYSTONE_SERDES_H__
+#define __TI_KEYSTONE_SERDES_H__
+
+/* SERDES Reference clock */
+enum ks2_serdes_clock {
+       SERDES_CLOCK_100M,              /* 100 MHz */
+       SERDES_CLOCK_122P88M,           /* 122.88 MHz */
+       SERDES_CLOCK_125M,              /* 125 MHz */
+       SERDES_CLOCK_156P25M,           /* 156.25 MHz */
+       SERDES_CLOCK_312P5M,            /* 312.5 MHz */
+};
+
+/* SERDES Lane Baud Rate */
+enum ks2_serdes_rate {
+       SERDES_RATE_4P9152G,            /* 4.9152 GBaud */
+       SERDES_RATE_5G,                 /* 5 GBaud */
+       SERDES_RATE_6P144G,             /* 6.144 GBaud */
+       SERDES_RATE_6P25G,              /* 6.25 GBaud */
+       SERDES_RATE_10p3125g,           /* 10.3215 GBaud */
+       SERDES_RATE_12p5g,              /* 12.5 GBaud */
+};
+
+/* SERDES Lane Rate Mode */
+enum ks2_serdes_rate_mode {
+       SERDES_FULL_RATE,
+       SERDES_HALF_RATE,
+       SERDES_QUARTER_RATE,
+};
+
+/* SERDES PHY TYPE */
+enum ks2_serdes_interface {
+       SERDES_PHY_SGMII,
+       SERDES_PHY_PCSR,                /* XGE SERDES */
+};
+
+struct ks2_serdes {
+       enum ks2_serdes_clock clk;
+       enum ks2_serdes_rate rate;
+       enum ks2_serdes_rate_mode rate_mode;
+       enum ks2_serdes_interface intf;
+       u32 loopback;
+};
+
+int ks2_serdes_init(u32 base, struct ks2_serdes *serdes, u32 num_lanes);
+
+#endif /* __TI_KEYSTONE_SERDES_H__ */
diff --git a/arch/arm/include/asm/ti-common/ti-edma3.h b/arch/arm/include/asm/ti-common/ti-edma3.h
new file mode 100644 (file)
index 0000000..5adc1da
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+ * Enhanced Direct Memory Access (EDMA3) Controller
+ *
+ * (C) Copyright 2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#ifndef _EDMA3_H_
+#define _EDMA3_H_
+
+#include <linux/stddef.h>
+
+#define EDMA3_PARSET_NULL_LINK                 0xffff
+
+/*
+ * All parameter RAM set options
+ * opt field in edma3_param_set_config structure
+ */
+#define EDMA3_SLOPT_PRIV_LEVEL                 BIT(31)
+#define EDMA3_SLOPT_PRIV_ID(id)                        ((0xf & (id)) << 24)
+#define EDMA3_SLOPT_INTERM_COMP_CHAIN_ENB      BIT(23)
+#define EDMA3_SLOPT_TRANS_COMP_CHAIN_ENB       BIT(22)
+#define EDMA3_SLOPT_INTERM_COMP_INT_ENB                BIT(21)
+#define EDMA3_SLOPT_TRANS_COMP_INT_ENB         BIT(20)
+#define EDMA3_SLOPT_COMP_CODE(code)            ((0x3f & (code)) << 12)
+#define EDMA3_SLOPT_FIFO_WIDTH_8               0
+#define EDMA3_SLOPT_FIFO_WIDTH_16              (1 << 8)
+#define EDMA3_SLOPT_FIFO_WIDTH_32              (2 << 8)
+#define EDMA3_SLOPT_FIFO_WIDTH_64              (3 << 8)
+#define EDMA3_SLOPT_FIFO_WIDTH_128             (4 << 8)
+#define EDMA3_SLOPT_FIFO_WIDTH_256             (5 << 8)
+#define EDMA3_SLOPT_FIFO_WIDTH_SET(w)          ((w & 0x7) << 8)
+#define EDMA3_SLOPT_STATIC                     BIT(3)
+#define EDMA3_SLOPT_AB_SYNC                    BIT(2)
+#define EDMA3_SLOPT_DST_ADDR_CONST_MODE                BIT(1)
+#define EDMA3_SLOPT_SRC_ADDR_CONST_MODE                BIT(0)
+
+enum edma3_address_mode {
+       INCR = 0,
+       FIFO = 1
+};
+
+enum edma3_fifo_width {
+       W8BIT = 0,
+       W16BIT = 1,
+       W32BIT = 2,
+       W64BIT = 3,
+       W128BIT = 4,
+       W256BIT = 5
+};
+
+enum edma3_sync_dimension {
+       ASYNC = 0,
+       ABSYNC = 1
+};
+
+/* PaRAM slots are laid out like this */
+struct edma3_slot_layout {
+       u32 opt;
+       u32 src;
+       u32 a_b_cnt;
+       u32 dst;
+       u32 src_dst_bidx;
+       u32 link_bcntrld;
+       u32 src_dst_cidx;
+       u32 ccnt;
+} __packed;
+
+/*
+ * Use this to assign trigger word number of edma3_slot_layout struct.
+ * trigger_word_name - is the exact name from edma3_slot_layout.
+ */
+#define EDMA3_TWORD(trigger_word_name)\
+               (offsetof(struct edma3_slot_layout, trigger_word_name) / 4)
+
+struct edma3_slot_config {
+       u32 opt;
+       u32 src;
+       u32 dst;
+       int bcnt;
+       int acnt;
+       int ccnt;
+       int src_bidx;
+       int dst_bidx;
+       int src_cidx;
+       int dst_cidx;
+       int bcntrld;
+       int link;
+};
+
+struct edma3_channel_config {
+       int slot;
+       int chnum;
+       int complete_code;      /* indicate pending complete interrupt */
+       int trigger_slot_word;  /* only used for qedma */
+};
+
+void qedma3_start(u32 base, struct edma3_channel_config *cfg);
+void qedma3_stop(u32 base, struct edma3_channel_config *cfg);
+void edma3_slot_configure(u32 base, int slot, struct edma3_slot_config *cfg);
+int edma3_check_for_transfer(u32 base, struct edma3_channel_config *cfg);
+void edma3_write_slot(u32 base, int slot, struct edma3_slot_layout *param);
+void edma3_read_slot(u32 base, int slot, struct edma3_slot_layout *param);
+
+void edma3_set_dest(u32 base, int slot, u32 dst, enum edma3_address_mode mode,
+                   enum edma3_fifo_width width);
+void edma3_set_dest_index(u32 base, unsigned slot, int bidx, int cidx);
+void edma3_set_dest_addr(u32 base, int slot, u32 dst);
+
+void edma3_set_src(u32 base, int slot, u32 src, enum edma3_address_mode mode,
+                  enum edma3_fifo_width width);
+void edma3_set_src_index(u32 base, unsigned slot, int bidx, int cidx);
+void edma3_set_src_addr(u32 base, int slot, u32 src);
+
+void edma3_set_transfer_params(u32 base, int slot, int acnt,
+                              int bcnt, int ccnt, u16 bcnt_rld,
+                              enum edma3_sync_dimension sync_mode);
+
+#endif
index b16694c72f8d6b6f06b2a6efd47cc612c4430ba6..f97f3dd1496aa54f7ca0667d0ebea299c95d50e7 100644 (file)
@@ -45,4 +45,19 @@ void reset_timer_masked      (void);
 ulong  get_timer_masked        (void);
 void   udelay_masked           (unsigned long usec);
 
+/* calls to c from vectors.S */
+void bad_mode(void);
+void do_undefined_instruction(struct pt_regs *pt_regs);
+void do_software_interrupt(struct pt_regs *pt_regs);
+void do_prefetch_abort(struct pt_regs *pt_regs);
+void do_data_abort(struct pt_regs *pt_regs);
+void do_not_used(struct pt_regs *pt_regs);
+#ifdef CONFIG_ARM64
+void do_fiq(struct pt_regs *pt_regs, unsigned int esr);
+void do_irq(struct pt_regs *pt_regs, unsigned int esr);
+#else
+void do_fiq(struct pt_regs *pt_regs);
+void do_irq(struct pt_regs *pt_regswq);
+#endif
+
 #endif /* _U_BOOT_ARM_H_ */
index 76adaf3aa4abf69916155cadd9f1e9e1a5effdb7..f6062557e6677fe0636520f9d7f76a9eedfc8d50 100644 (file)
@@ -34,6 +34,7 @@
 #include <onenand_uboot.h>
 #include <mmc.h>
 #include <scsi.h>
+#include <status_led.h>
 #include <libfdt.h>
 #include <fdtdec.h>
 #include <post.h>
@@ -63,25 +64,15 @@ extern void dataflash_print_info(void);
  ************************************************************************
  * May be supplied by boards if desired
  */
-inline void __coloured_LED_init(void) {}
-void coloured_LED_init(void)
-       __attribute__((weak, alias("__coloured_LED_init")));
-inline void __red_led_on(void) {}
-void red_led_on(void) __attribute__((weak, alias("__red_led_on")));
-inline void __red_led_off(void) {}
-void red_led_off(void) __attribute__((weak, alias("__red_led_off")));
-inline void __green_led_on(void) {}
-void green_led_on(void) __attribute__((weak, alias("__green_led_on")));
-inline void __green_led_off(void) {}
-void green_led_off(void) __attribute__((weak, alias("__green_led_off")));
-inline void __yellow_led_on(void) {}
-void yellow_led_on(void) __attribute__((weak, alias("__yellow_led_on")));
-inline void __yellow_led_off(void) {}
-void yellow_led_off(void) __attribute__((weak, alias("__yellow_led_off")));
-inline void __blue_led_on(void) {}
-void blue_led_on(void) __attribute__((weak, alias("__blue_led_on")));
-inline void __blue_led_off(void) {}
-void blue_led_off(void) __attribute__((weak, alias("__blue_led_off")));
+__weak void coloured_LED_init(void) {}
+__weak void red_led_on(void) {}
+__weak void red_led_off(void) {}
+__weak void green_led_on(void) {}
+__weak void green_led_off(void) {}
+__weak void yellow_led_on(void) {}
+__weak void yellow_led_off(void) {}
+__weak void blue_led_on(void) {}
+__weak void blue_led_off(void) {}
 
 /*
  ************************************************************************
@@ -198,27 +189,21 @@ static int arm_pci_init(void)
  */
 typedef int (init_fnc_t) (void);
 
-void __dram_init_banksize(void)
+__weak 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 dram_init_banksize(void)
-       __attribute__((weak, alias("__dram_init_banksize")));
 
-int __arch_cpu_init(void)
+__weak int arch_cpu_init(void)
 {
        return 0;
 }
-int arch_cpu_init(void)
-       __attribute__((weak, alias("__arch_cpu_init")));
 
-int __power_init_board(void)
+__weak int power_init_board(void)
 {
        return 0;
 }
-int power_init_board(void)
-       __attribute__((weak, alias("__power_init_board")));
 
        /* Record the board_init_f() bootstage (after arch_cpu_init()) */
 static int mark_bootstage(void)
index 4949d573af8c310f8348beae48caa5ea0f580bf9..cdb19751058815b19e274ba32c7293690c5ce99f 100644 (file)
@@ -15,6 +15,7 @@
 #include <common.h>
 #include <command.h>
 #include <image.h>
+#include <vxworks.h>
 #include <u-boot/zlib.h>
 #include <asm/byteorder.h>
 #include <libfdt.h>
index f6b7c03578b80e24a9a275bc7fe65f64ebe47666..9019736d2c74bec4da3fa4f97752954666a91ec1 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <common.h>
 #include <asm/proc-armv/ptrace.h>
+#include <asm/u-boot-arm.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
diff --git a/arch/arm/mvebu-common/Makefile b/arch/arm/mvebu-common/Makefile
new file mode 100644 (file)
index 0000000..9dcab69
--- /dev/null
@@ -0,0 +1,12 @@
+#
+# (C) Copyright 2009
+# Marvell Semiconductor <www.marvell.com>
+# Written-by: Prafulla Wadaskar <prafulla@marvell.com>
+#
+# SPDX-License-Identifier:     GPL-2.0+
+#
+
+obj-y  = dram.o
+obj-y  += gpio.o
+obj-$(CONFIG_ARMADA_XP) += mbus.o
+obj-y  += timer.o
similarity index 57%
rename from arch/arm/cpu/arm926ejs/kirkwood/dram.c
rename to arch/arm/mvebu-common/dram.c
index d73ae47c34162a4ed3ea46b9e1f95e6c84082cfc..db18791a8627e77f9baba41199a9ba5fba3af37c 100644 (file)
 #include <common.h>
 #include <asm/io.h>
 #include <asm/arch/cpu.h>
-#include <asm/arch/kirkwood.h>
+#include <asm/arch/soc.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
-struct kw_sdram_bank {
+struct sdram_bank {
        u32     win_bar;
        u32     win_sz;
 };
 
-struct kw_sdram_addr_dec {
-       struct kw_sdram_bank    sdram_bank[4];
+struct sdram_addr_dec {
+       struct sdram_bank sdram_bank[4];
 };
 
-#define KW_REG_CPUCS_WIN_ENABLE                (1 << 0)
-#define KW_REG_CPUCS_WIN_WR_PROTECT    (1 << 1)
-#define KW_REG_CPUCS_WIN_WIN0_CS(x)    (((x) & 0x3) << 2)
-#define KW_REG_CPUCS_WIN_SIZE(x)       (((x) & 0xff) << 24)
+#define REG_CPUCS_WIN_ENABLE           (1 << 0)
+#define REG_CPUCS_WIN_WR_PROTECT       (1 << 1)
+#define REG_CPUCS_WIN_WIN0_CS(x)       (((x) & 0x3) << 2)
+#define REG_CPUCS_WIN_SIZE(x)          (((x) & 0xff) << 24)
 
 /*
- * kw_sdram_bar - reads SDRAM Base Address Register
+ * mvebu_sdram_bar - reads SDRAM Base Address Register
  */
-u32 kw_sdram_bar(enum memory_bank bank)
+u32 mvebu_sdram_bar(enum memory_bank bank)
 {
-       struct kw_sdram_addr_dec *base =
-               (struct kw_sdram_addr_dec *)KW_REGISTER(0x1500);
+       struct sdram_addr_dec *base =
+               (struct sdram_addr_dec *)MVEBU_SDRAM_BASE;
        u32 result = 0;
        u32 enable = 0x01 & readl(&base->sdram_bank[bank].win_sz);
 
@@ -46,31 +46,31 @@ u32 kw_sdram_bar(enum memory_bank bank)
 }
 
 /*
- * kw_sdram_bs_set - writes SDRAM Bank size
+ * mvebu_sdram_bs_set - writes SDRAM Bank size
  */
-static void kw_sdram_bs_set(enum memory_bank bank, u32 size)
+static void mvebu_sdram_bs_set(enum memory_bank bank, u32 size)
 {
-       struct kw_sdram_addr_dec *base =
-               (struct kw_sdram_addr_dec *)KW_REGISTER(0x1500);
+       struct sdram_addr_dec *base =
+               (struct sdram_addr_dec *)MVEBU_SDRAM_BASE;
        /* Read current register value */
        u32 reg = readl(&base->sdram_bank[bank].win_sz);
 
        /* Clear window size */
-       reg &= ~KW_REG_CPUCS_WIN_SIZE(0xFF);
+       reg &= ~REG_CPUCS_WIN_SIZE(0xFF);
 
        /* Set new window size */
-       reg |= KW_REG_CPUCS_WIN_SIZE((size - 1) >> 24);
+       reg |= REG_CPUCS_WIN_SIZE((size - 1) >> 24);
 
        writel(reg, &base->sdram_bank[bank].win_sz);
 }
 
 /*
- * kw_sdram_bs - reads SDRAM Bank size
+ * mvebu_sdram_bs - reads SDRAM Bank size
  */
-u32 kw_sdram_bs(enum memory_bank bank)
+u32 mvebu_sdram_bs(enum memory_bank bank)
 {
-       struct kw_sdram_addr_dec *base =
-               (struct kw_sdram_addr_dec *)KW_REGISTER(0x1500);
+       struct sdram_addr_dec *base =
+               (struct sdram_addr_dec *)MVEBU_SDRAM_BASE;
        u32 result = 0;
        u32 enable = 0x01 & readl(&base->sdram_bank[bank].win_sz);
 
@@ -81,15 +81,16 @@ u32 kw_sdram_bs(enum memory_bank bank)
        return result;
 }
 
-void kw_sdram_size_adjust(enum memory_bank bank)
+void mvebu_sdram_size_adjust(enum memory_bank bank)
 {
        u32 size;
 
        /* probe currently equipped RAM size */
-       size = get_ram_size((void *)kw_sdram_bar(bank), kw_sdram_bs(bank));
+       size = get_ram_size((void *)mvebu_sdram_bar(bank),
+                           mvebu_sdram_bs(bank));
 
        /* adjust SDRAM window size accordingly */
-       kw_sdram_bs_set(bank, size);
+       mvebu_sdram_bs_set(bank, size);
 }
 
 #ifndef CONFIG_SYS_BOARD_DRAM_INIT
@@ -99,8 +100,8 @@ int dram_init(void)
 
        gd->ram_size = 0;
        for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
-               gd->bd->bi_dram[i].start = kw_sdram_bar(i);
-               gd->bd->bi_dram[i].size = kw_sdram_bs(i);
+               gd->bd->bi_dram[i].start = mvebu_sdram_bar(i);
+               gd->bd->bi_dram[i].size = mvebu_sdram_bs(i);
                /*
                 * It is assumed that all memory banks are consecutive
                 * and without gaps.
@@ -110,7 +111,13 @@ int dram_init(void)
                if (gd->bd->bi_dram[i].start != gd->ram_size)
                        break;
 
-               gd->ram_size += gd->bd->bi_dram[i].size;
+               /*
+                * Don't report more than 3GiB of SDRAM, otherwise there is no
+                * address space left for the internal registers etc.
+                */
+               if ((gd->ram_size + gd->bd->bi_dram[i].size != 0) &&
+                   (gd->ram_size + gd->bd->bi_dram[i].size <= (3 << 30)))
+                       gd->ram_size += gd->bd->bi_dram[i].size;
 
        }
 
diff --git a/arch/arm/mvebu-common/gpio.c b/arch/arm/mvebu-common/gpio.c
new file mode 100644 (file)
index 0000000..56e54e0
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * (C) Copyright 2009
+ * Marvell Semiconductor <www.marvell.com>
+ * Written-by: Prafulla Wadaskar <prafulla@marvell.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/soc.h>
+
+/*
+ * mvebu_config_gpio - GPIO configuration
+ */
+void mvebu_config_gpio(u32 gpp0_oe_val, u32 gpp1_oe_val,
+                      u32 gpp0_oe, u32 gpp1_oe)
+{
+       struct kwgpio_registers *gpio0reg =
+               (struct kwgpio_registers *)MVEBU_GPIO0_BASE;
+       struct kwgpio_registers *gpio1reg =
+               (struct kwgpio_registers *)MVEBU_GPIO1_BASE;
+
+       /* Init GPIOS to default values as per board requirement */
+       writel(gpp0_oe_val, &gpio0reg->dout);
+       writel(gpp1_oe_val, &gpio1reg->dout);
+       writel(gpp0_oe, &gpio0reg->oe);
+       writel(gpp1_oe, &gpio1reg->oe);
+}
diff --git a/arch/arm/mvebu-common/mbus.c b/arch/arm/mvebu-common/mbus.c
new file mode 100644 (file)
index 0000000..05c9ef2
--- /dev/null
@@ -0,0 +1,471 @@
+/*
+ * Address map functions for Marvell EBU SoCs (Kirkwood, Armada
+ * 370/XP, Dove, Orion5x and MV78xx0)
+ *
+ * Ported from the Barebox version to U-Boot by:
+ * Stefan Roese <sr@denx.de>
+ *
+ * The Barebox version is:
+ * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
+ *
+ * based on mbus driver from Linux
+ *   (C) Copyright 2008 Marvell Semiconductor
+ *
+ * SPDX-License-Identifier:    GPL-2.0
+ *
+ * The Marvell EBU SoCs have a configurable physical address space:
+ * the physical address at which certain devices (PCIe, NOR, NAND,
+ * etc.) sit can be configured. The configuration takes place through
+ * two sets of registers:
+ *
+ * - One to configure the access of the CPU to the devices. Depending
+ *   on the families, there are between 8 and 20 configurable windows,
+ *   each can be use to create a physical memory window that maps to a
+ *   specific device. Devices are identified by a tuple (target,
+ *   attribute).
+ *
+ * - One to configure the access to the CPU to the SDRAM. There are
+ *   either 2 (for Dove) or 4 (for other families) windows to map the
+ *   SDRAM into the physical address space.
+ *
+ * This driver:
+ *
+ * - Reads out the SDRAM address decoding windows at initialization
+ *   time, and fills the mbus_dram_info structure with these
+ *   informations. The exported function mv_mbus_dram_info() allow
+ *   device drivers to get those informations related to the SDRAM
+ *   address decoding windows. This is because devices also have their
+ *   own windows (configured through registers that are part of each
+ *   device register space), and therefore the drivers for Marvell
+ *   devices have to configure those device -> SDRAM windows to ensure
+ *   that DMA works properly.
+ *
+ * - Provides an API for platform code or device drivers to
+ *   dynamically add or remove address decoding windows for the CPU ->
+ *   device accesses. This API is mvebu_mbus_add_window_by_id(),
+ *   mvebu_mbus_add_window_remap_by_id() and
+ *   mvebu_mbus_del_window().
+ */
+
+#include <common.h>
+#include <asm/errno.h>
+#include <asm/io.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/soc.h>
+#include <linux/mbus.h>
+
+#define BIT(nr)                        (1UL << (nr))
+
+/* DDR target is the same on all platforms */
+#define TARGET_DDR             0
+
+/* CPU Address Decode Windows registers */
+#define WIN_CTRL_OFF           0x0000
+#define   WIN_CTRL_ENABLE       BIT(0)
+#define   WIN_CTRL_TGT_MASK     0xf0
+#define   WIN_CTRL_TGT_SHIFT    4
+#define   WIN_CTRL_ATTR_MASK    0xff00
+#define   WIN_CTRL_ATTR_SHIFT   8
+#define   WIN_CTRL_SIZE_MASK    0xffff0000
+#define   WIN_CTRL_SIZE_SHIFT   16
+#define WIN_BASE_OFF           0x0004
+#define   WIN_BASE_LOW          0xffff0000
+#define   WIN_BASE_HIGH         0xf
+#define WIN_REMAP_LO_OFF       0x0008
+#define   WIN_REMAP_LOW         0xffff0000
+#define WIN_REMAP_HI_OFF       0x000c
+
+#define ATTR_HW_COHERENCY      (0x1 << 4)
+
+#define DDR_BASE_CS_OFF(n)     (0x0000 + ((n) << 3))
+#define  DDR_BASE_CS_HIGH_MASK  0xf
+#define  DDR_BASE_CS_LOW_MASK   0xff000000
+#define DDR_SIZE_CS_OFF(n)     (0x0004 + ((n) << 3))
+#define  DDR_SIZE_ENABLED       BIT(0)
+#define  DDR_SIZE_CS_MASK       0x1c
+#define  DDR_SIZE_CS_SHIFT      2
+#define  DDR_SIZE_MASK          0xff000000
+
+#define DOVE_DDR_BASE_CS_OFF(n) ((n) << 4)
+
+struct mvebu_mbus_state;
+
+struct mvebu_mbus_soc_data {
+       unsigned int num_wins;
+       unsigned int num_remappable_wins;
+       unsigned int (*win_cfg_offset)(const int win);
+       void (*setup_cpu_target)(struct mvebu_mbus_state *s);
+};
+
+struct mvebu_mbus_state mbus_state
+       __attribute__ ((section(".data")));
+static struct mbus_dram_target_info mbus_dram_info
+       __attribute__ ((section(".data")));
+
+/*
+ * Functions to manipulate the address decoding windows
+ */
+
+static void mvebu_mbus_read_window(struct mvebu_mbus_state *mbus,
+                                  int win, int *enabled, u64 *base,
+                                  u32 *size, u8 *target, u8 *attr,
+                                  u64 *remap)
+{
+       void __iomem *addr = mbus->mbuswins_base +
+               mbus->soc->win_cfg_offset(win);
+       u32 basereg = readl(addr + WIN_BASE_OFF);
+       u32 ctrlreg = readl(addr + WIN_CTRL_OFF);
+
+       if (!(ctrlreg & WIN_CTRL_ENABLE)) {
+               *enabled = 0;
+               return;
+       }
+
+       *enabled = 1;
+       *base = ((u64)basereg & WIN_BASE_HIGH) << 32;
+       *base |= (basereg & WIN_BASE_LOW);
+       *size = (ctrlreg | ~WIN_CTRL_SIZE_MASK) + 1;
+
+       if (target)
+               *target = (ctrlreg & WIN_CTRL_TGT_MASK) >> WIN_CTRL_TGT_SHIFT;
+
+       if (attr)
+               *attr = (ctrlreg & WIN_CTRL_ATTR_MASK) >> WIN_CTRL_ATTR_SHIFT;
+
+       if (remap) {
+               if (win < mbus->soc->num_remappable_wins) {
+                       u32 remap_low = readl(addr + WIN_REMAP_LO_OFF);
+                       u32 remap_hi  = readl(addr + WIN_REMAP_HI_OFF);
+                       *remap = ((u64)remap_hi << 32) | remap_low;
+               } else {
+                       *remap = 0;
+               }
+       }
+}
+
+static void mvebu_mbus_disable_window(struct mvebu_mbus_state *mbus,
+                                     int win)
+{
+       void __iomem *addr;
+
+       addr = mbus->mbuswins_base + mbus->soc->win_cfg_offset(win);
+
+       writel(0, addr + WIN_BASE_OFF);
+       writel(0, addr + WIN_CTRL_OFF);
+       if (win < mbus->soc->num_remappable_wins) {
+               writel(0, addr + WIN_REMAP_LO_OFF);
+               writel(0, addr + WIN_REMAP_HI_OFF);
+       }
+}
+
+/* Checks whether the given window number is available */
+static int mvebu_mbus_window_is_free(struct mvebu_mbus_state *mbus,
+                                    const int win)
+{
+       void __iomem *addr = mbus->mbuswins_base +
+               mbus->soc->win_cfg_offset(win);
+       u32 ctrl = readl(addr + WIN_CTRL_OFF);
+       return !(ctrl & WIN_CTRL_ENABLE);
+}
+
+/*
+ * Checks whether the given (base, base+size) area doesn't overlap an
+ * existing region
+ */
+static int mvebu_mbus_window_conflicts(struct mvebu_mbus_state *mbus,
+                                      phys_addr_t base, size_t size,
+                                      u8 target, u8 attr)
+{
+       u64 end = (u64)base + size;
+       int win;
+
+       for (win = 0; win < mbus->soc->num_wins; win++) {
+               u64 wbase, wend;
+               u32 wsize;
+               u8 wtarget, wattr;
+               int enabled;
+
+               mvebu_mbus_read_window(mbus, win,
+                                      &enabled, &wbase, &wsize,
+                                      &wtarget, &wattr, NULL);
+
+               if (!enabled)
+                       continue;
+
+               wend = wbase + wsize;
+
+               /*
+                * Check if the current window overlaps with the
+                * proposed physical range
+                */
+               if ((u64)base < wend && end > wbase)
+                       return 0;
+
+               /*
+                * Check if target/attribute conflicts
+                */
+               if (target == wtarget && attr == wattr)
+                       return 0;
+       }
+
+       return 1;
+}
+
+static int mvebu_mbus_find_window(struct mvebu_mbus_state *mbus,
+                                 phys_addr_t base, size_t size)
+{
+       int win;
+
+       for (win = 0; win < mbus->soc->num_wins; win++) {
+               u64 wbase;
+               u32 wsize;
+               int enabled;
+
+               mvebu_mbus_read_window(mbus, win,
+                                      &enabled, &wbase, &wsize,
+                                      NULL, NULL, NULL);
+
+               if (!enabled)
+                       continue;
+
+               if (base == wbase && size == wsize)
+                       return win;
+       }
+
+       return -ENODEV;
+}
+
+static int mvebu_mbus_setup_window(struct mvebu_mbus_state *mbus,
+                                  int win, phys_addr_t base, size_t size,
+                                  phys_addr_t remap, u8 target,
+                                  u8 attr)
+{
+       void __iomem *addr = mbus->mbuswins_base +
+               mbus->soc->win_cfg_offset(win);
+       u32 ctrl, remap_addr;
+
+       ctrl = ((size - 1) & WIN_CTRL_SIZE_MASK) |
+               (attr << WIN_CTRL_ATTR_SHIFT)    |
+               (target << WIN_CTRL_TGT_SHIFT)   |
+               WIN_CTRL_ENABLE;
+
+       writel(base & WIN_BASE_LOW, addr + WIN_BASE_OFF);
+       writel(ctrl, addr + WIN_CTRL_OFF);
+       if (win < mbus->soc->num_remappable_wins) {
+               if (remap == MVEBU_MBUS_NO_REMAP)
+                       remap_addr = base;
+               else
+                       remap_addr = remap;
+               writel(remap_addr & WIN_REMAP_LOW, addr + WIN_REMAP_LO_OFF);
+               writel(0, addr + WIN_REMAP_HI_OFF);
+       }
+
+       return 0;
+}
+
+static int mvebu_mbus_alloc_window(struct mvebu_mbus_state *mbus,
+                                  phys_addr_t base, size_t size,
+                                  phys_addr_t remap, u8 target,
+                                  u8 attr)
+{
+       int win;
+
+       if (remap == MVEBU_MBUS_NO_REMAP) {
+               for (win = mbus->soc->num_remappable_wins;
+                    win < mbus->soc->num_wins; win++)
+                       if (mvebu_mbus_window_is_free(mbus, win))
+                               return mvebu_mbus_setup_window(mbus, win, base,
+                                                              size, remap,
+                                                              target, attr);
+       }
+
+
+       for (win = 0; win < mbus->soc->num_wins; win++)
+               if (mvebu_mbus_window_is_free(mbus, win))
+                       return mvebu_mbus_setup_window(mbus, win, base, size,
+                                                      remap, target, attr);
+
+       return -ENOMEM;
+}
+
+/*
+ * SoC-specific functions and definitions
+ */
+
+static unsigned int armada_370_xp_mbus_win_offset(int win)
+{
+       /* The register layout is a bit annoying and the below code
+        * tries to cope with it.
+        * - At offset 0x0, there are the registers for the first 8
+        *   windows, with 4 registers of 32 bits per window (ctrl,
+        *   base, remap low, remap high)
+        * - Then at offset 0x80, there is a hole of 0x10 bytes for
+        *   the internal registers base address and internal units
+        *   sync barrier register.
+        * - Then at offset 0x90, there the registers for 12
+        *   windows, with only 2 registers of 32 bits per window
+        *   (ctrl, base).
+        */
+       if (win < 8)
+               return win << 4;
+       else
+               return 0x90 + ((win - 8) << 3);
+}
+
+static unsigned int orion5x_mbus_win_offset(int win)
+{
+       return win << 4;
+}
+
+static void mvebu_mbus_default_setup_cpu_target(struct mvebu_mbus_state *mbus)
+{
+       int i;
+       int cs;
+
+       mbus_dram_info.mbus_dram_target_id = TARGET_DDR;
+
+       for (i = 0, cs = 0; i < 4; i++) {
+               u32 base = readl(mbus->sdramwins_base + DDR_BASE_CS_OFF(i));
+               u32 size = readl(mbus->sdramwins_base + DDR_SIZE_CS_OFF(i));
+
+               /*
+                * We only take care of entries for which the chip
+                * select is enabled, and that don't have high base
+                * address bits set (devices can only access the first
+                * 32 bits of the memory).
+                */
+               if ((size & DDR_SIZE_ENABLED) &&
+                   !(base & DDR_BASE_CS_HIGH_MASK)) {
+                       struct mbus_dram_window *w;
+
+                       w = &mbus_dram_info.cs[cs++];
+                       w->cs_index = i;
+                       w->mbus_attr = 0xf & ~(1 << i);
+#if defined(CONFIG_ARMADA_XP)
+                       w->mbus_attr |= ATTR_HW_COHERENCY;
+#endif
+                       w->base = base & DDR_BASE_CS_LOW_MASK;
+                       w->size = (size | ~DDR_SIZE_MASK) + 1;
+               }
+       }
+       mbus_dram_info.num_cs = cs;
+}
+
+static const struct mvebu_mbus_soc_data
+armada_370_xp_mbus_data __maybe_unused = {
+       .num_wins            = 20,
+       .num_remappable_wins = 8,
+       .win_cfg_offset      = armada_370_xp_mbus_win_offset,
+       .setup_cpu_target    = mvebu_mbus_default_setup_cpu_target,
+};
+
+static const struct mvebu_mbus_soc_data
+kirkwood_mbus_data __maybe_unused = {
+       .num_wins            = 8,
+       .num_remappable_wins = 4,
+       .win_cfg_offset      = orion5x_mbus_win_offset,
+       .setup_cpu_target    = mvebu_mbus_default_setup_cpu_target,
+};
+
+/*
+ * Public API of the driver
+ */
+const struct mbus_dram_target_info *mvebu_mbus_dram_info(void)
+{
+       return &mbus_dram_info;
+}
+
+int mvebu_mbus_add_window_remap_by_id(unsigned int target,
+                                     unsigned int attribute,
+                                     phys_addr_t base, size_t size,
+                                     phys_addr_t remap)
+{
+       struct mvebu_mbus_state *s = &mbus_state;
+
+       if (!mvebu_mbus_window_conflicts(s, base, size, target, attribute)) {
+               printf("Cannot add window '%x:%x', conflicts with another window\n",
+                      target, attribute);
+               return -EINVAL;
+       }
+
+       return mvebu_mbus_alloc_window(s, base, size, remap, target, attribute);
+}
+
+int mvebu_mbus_add_window_by_id(unsigned int target, unsigned int attribute,
+                               phys_addr_t base, size_t size)
+{
+       return mvebu_mbus_add_window_remap_by_id(target, attribute, base,
+                                                size, MVEBU_MBUS_NO_REMAP);
+}
+
+int mvebu_mbus_del_window(phys_addr_t base, size_t size)
+{
+       int win;
+
+       win = mvebu_mbus_find_window(&mbus_state, base, size);
+       if (win < 0)
+               return win;
+
+       mvebu_mbus_disable_window(&mbus_state, win);
+       return 0;
+}
+
+int mbus_dt_setup_win(struct mvebu_mbus_state *mbus,
+                     u32 base, u32 size, u8 target, u8 attr)
+{
+       if (!mvebu_mbus_window_conflicts(mbus, base, size, target, attr)) {
+               printf("Cannot add window '%04x:%04x', conflicts with another window\n",
+                      target, attr);
+               return -EBUSY;
+       }
+
+       /*
+        * In U-Boot we first try to add the mbus window to the remap windows.
+        * If this fails, lets try to add the windows to the non-remap windows.
+        */
+       if (mvebu_mbus_alloc_window(mbus, base, size, base, target, attr)) {
+               if (mvebu_mbus_alloc_window(mbus, base, size,
+                                           MVEBU_MBUS_NO_REMAP, target, attr))
+                       return -ENOMEM;
+       }
+
+       return 0;
+}
+
+int mvebu_mbus_probe(struct mbus_win windows[], int count)
+{
+       int win;
+       int ret;
+       int i;
+
+#if defined(CONFIG_KIRKWOOD)
+       mbus_state.soc = &kirkwood_mbus_data;
+#endif
+#if defined(CONFIG_ARMADA_XP)
+       mbus_state.soc = &armada_370_xp_mbus_data;
+#endif
+
+       mbus_state.mbuswins_base = (void __iomem *)MVEBU_CPU_WIN_BASE;
+       mbus_state.sdramwins_base = (void __iomem *)MVEBU_SDRAM_BASE;
+
+       for (win = 0; win < mbus_state.soc->num_wins; win++)
+               mvebu_mbus_disable_window(&mbus_state, win);
+
+       mbus_state.soc->setup_cpu_target(&mbus_state);
+
+       /* Setup statically declared windows in the DT */
+       for (i = 0; i < count; i++) {
+               u32 base, size;
+               u8 target, attr;
+
+               target = windows[i].target;
+               attr = windows[i].attr;
+               base = windows[i].base;
+               size = windows[i].size;
+               ret = mbus_dt_setup_win(&mbus_state, base, size, target, attr);
+               if (ret < 0)
+                       return ret;
+       }
+
+       return 0;
+}
similarity index 63%
rename from arch/arm/cpu/arm926ejs/kirkwood/timer.c
rename to arch/arm/mvebu-common/timer.c
index a08f4a1456cf714341dbc3752eb7f407456150bd..40c4bc2da1b233732f69821dec23ccd90495bba9 100644 (file)
@@ -7,75 +7,68 @@
 
 #include <common.h>
 #include <asm/io.h>
-#include <asm/arch/kirkwood.h>
+#include <asm/arch/soc.h>
 
-#define UBOOT_CNTR     0       /* counter to use for uboot timer */
-
-/* Timer reload and current value registers */
-struct kwtmr_val {
-       u32 reload;     /* Timer reload reg */
-       u32 val;        /* Timer value reg */
-};
-
-/* Timer registers */
-struct kwtmr_registers {
-       u32 ctrl;       /* Timer control reg */
-       u32 pad[3];
-       struct kwtmr_val tmr[2];
-       u32 wdt_reload;
-       u32 wdt_val;
-};
-
-struct kwtmr_registers *kwtmr_regs = (struct kwtmr_registers *)KW_TIMER_BASE;
+#define UBOOT_CNTR     0       /* counter to use for U-Boot timer */
 
 /*
  * ARM Timers Registers Map
  */
-#define CNTMR_CTRL_REG                 &kwtmr_regs->ctrl
-#define CNTMR_RELOAD_REG(tmrnum)       &kwtmr_regs->tmr[tmrnum].reload
-#define CNTMR_VAL_REG(tmrnum)          &kwtmr_regs->tmr[tmrnum].val
+#define CNTMR_CTRL_REG                 &tmr_regs->ctrl
+#define CNTMR_RELOAD_REG(tmrnum)       &tmr_regs->tmr[tmrnum].reload
+#define CNTMR_VAL_REG(tmrnum)          &tmr_regs->tmr[tmrnum].val
 
 /*
  * ARM Timers Control Register
  * CPU_TIMERS_CTRL_REG (CTCR)
  */
 #define CTCR_ARM_TIMER_EN_OFFS(cntr)   (cntr * 2)
-#define CTCR_ARM_TIMER_EN_MASK(cntr)   (1 << CTCR_ARM_TIMER_EN_OFFS)
 #define CTCR_ARM_TIMER_EN(cntr)                (1 << CTCR_ARM_TIMER_EN_OFFS(cntr))
-#define CTCR_ARM_TIMER_DIS(cntr)       (0 << CTCR_ARM_TIMER_EN_OFFS(cntr))
 
 #define CTCR_ARM_TIMER_AUTO_OFFS(cntr) ((cntr * 2) + 1)
-#define CTCR_ARM_TIMER_AUTO_MASK(cntr) (1 << 1)
 #define CTCR_ARM_TIMER_AUTO_EN(cntr)   (1 << CTCR_ARM_TIMER_AUTO_OFFS(cntr))
-#define CTCR_ARM_TIMER_AUTO_DIS(cntr)  (0 << CTCR_ARM_TIMER_AUTO_OFFS(cntr))
 
-/*
- * ARM Timer\Watchdog Reload Register
- * CNTMR_RELOAD_REG (TRR)
- */
-#define TRG_ARM_TIMER_REL_OFFS         0
-#define TRG_ARM_TIMER_REL_MASK         0xffffffff
+/* Only Armada XP have the 25MHz enable bit (Kirkwood doesn't) */
+#if defined(CONFIG_ARMADA_XP)
+#define CTCR_ARM_TIMER_25MHZ_OFFS(cntr)        (cntr + 11)
+#define CTCR_ARM_TIMER_25MHZ(cntr)     (1 << CTCR_ARM_TIMER_25MHZ_OFFS(cntr))
+#else
+#define CTCR_ARM_TIMER_25MHZ(cntr)     0
+#endif
 
-/*
- * ARM Timer\Watchdog Register
- * CNTMR_VAL_REG (TVRG)
- */
-#define TVR_ARM_TIMER_OFFS             0
-#define TVR_ARM_TIMER_MASK             0xffffffff
-#define TVR_ARM_TIMER_MAX              0xffffffff
 #define TIMER_LOAD_VAL                         0xffffffff
 
-#define READ_TIMER                     (readl(CNTMR_VAL_REG(UBOOT_CNTR)) /     \
-                                        (CONFIG_SYS_TCLK / 1000))
+#define timestamp                      gd->arch.tbl
+#define lastdec                                gd->arch.lastinc
+
+/* Timer reload and current value registers */
+struct kwtmr_val {
+       u32 reload;     /* Timer reload reg */
+       u32 val;        /* Timer value reg */
+};
+
+/* Timer registers */
+struct kwtmr_registers {
+       u32 ctrl;       /* Timer control reg */
+       u32 pad[3];
+       struct kwtmr_val tmr[4];
+       u32 wdt_reload;
+       u32 wdt_val;
+};
 
 DECLARE_GLOBAL_DATA_PTR;
 
-#define timestamp gd->arch.tbl
-#define lastdec gd->arch.lastinc
+static struct kwtmr_registers *tmr_regs =
+       (struct kwtmr_registers *)MVEBU_TIMER_BASE;
+
+static inline ulong read_timer(void)
+{
+       return readl(CNTMR_VAL_REG(UBOOT_CNTR)) / (CONFIG_SYS_TCLK / 1000);
+}
 
 ulong get_timer_masked(void)
 {
-       ulong now = READ_TIMER;
+       ulong now = read_timer();
 
        if (lastdec >= now) {
                /* normal mode */
@@ -119,20 +112,17 @@ void __udelay(unsigned long usec)
  */
 int timer_init(void)
 {
-       unsigned int cntmrctrl;
-
        /* load value into timer */
        writel(TIMER_LOAD_VAL, CNTMR_RELOAD_REG(UBOOT_CNTR));
        writel(TIMER_LOAD_VAL, CNTMR_VAL_REG(UBOOT_CNTR));
 
        /* enable timer in auto reload mode */
-       cntmrctrl = readl(CNTMR_CTRL_REG);
-       cntmrctrl |= CTCR_ARM_TIMER_EN(UBOOT_CNTR);
-       cntmrctrl |= CTCR_ARM_TIMER_AUTO_EN(UBOOT_CNTR);
-       writel(cntmrctrl, CNTMR_CTRL_REG);
+       clrsetbits_le32(CNTMR_CTRL_REG, CTCR_ARM_TIMER_25MHZ(UBOOT_CNTR),
+                       CTCR_ARM_TIMER_EN(UBOOT_CNTR) |
+                       CTCR_ARM_TIMER_AUTO_EN(UBOOT_CNTR));
 
        /* init the timestamp and lastdec value */
-       lastdec = READ_TIMER;
+       lastdec = read_timer();
        timestamp = 0;
 
        return 0;
index 7686b779bf7b20dd8bb2df58365314105d5f2b47..9b72bab56b64884543e1527a2186b388f7d460ca 100644 (file)
@@ -4,6 +4,9 @@ menu "MIPS architecture"
 config SYS_ARCH
        default "mips"
 
+config USE_PRIVATE_LIBGCC
+       default y
+
 choice
        prompt "Target select"
 
index 5bfab70b7edbac0d9ca15d124fab619db91c0192..85d32fc6128558ac8e169dc391b40b54c8d7b7e4 100644 (file)
@@ -27,6 +27,9 @@
 #include <hwconfig.h>
 #include <linux/compiler.h>
 #include "mp.h"
+#ifdef CONFIG_FSL_CAAM
+#include <fsl_sec.h>
+#endif
 #ifdef CONFIG_SYS_QE_FMAN_FW_IN_NAND
 #include <nand.h>
 #include <errno.h>
@@ -423,7 +426,8 @@ ulong cpu_init_f(void)
 {
        ulong flag = 0;
        extern void m8560_cpm_reset (void);
-#ifdef CONFIG_SYS_DCSRBAR_PHYS
+#if defined(CONFIG_SYS_DCSRBAR_PHYS) || \
+       (defined(CONFIG_SECURE_BOOT) && defined(CONFIG_FSL_CORENET))
        ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
 #endif
 #if defined(CONFIG_SECURE_BOOT)
@@ -455,6 +459,12 @@ ulong cpu_init_f(void)
 #if defined(CONFIG_SYS_CPC_REINIT_F)
        disable_cpc_sram();
 #endif
+
+#if defined(CONFIG_FSL_CORENET)
+       /* Put PAMU in bypass mode */
+       out_be32(&gur->pamubypenr, FSL_CORENET_PAMU_BYPASS);
+#endif
+
 #endif
 
 #ifdef CONFIG_CPM2
@@ -803,7 +813,7 @@ int cpu_init_r(void)
 #ifdef CONFIG_SYS_FSL_ERRATUM_SEC_A003571
 #define MCFGR_AXIPIPE 0x000000f0
        if (IS_SVR_REV(svr, 1, 0))
-               clrbits_be32(&sec->mcfgr, MCFGR_AXIPIPE);
+               sec_clrbits32(&sec->mcfgr, MCFGR_AXIPIPE);
 #endif
 
 #ifdef CONFIG_SYS_FSL_ERRATUM_A005871
@@ -938,6 +948,10 @@ int cpu_init_r(void)
        fman_enet_init();
 #endif
 
+#ifdef CONFIG_FSL_CAAM
+       sec_init();
+#endif
+
 #if defined(CONFIG_FSL_SATA_V2) && defined(CONFIG_FSL_SATA_ERRATUM_A001)
        /*
         * For P1022/1013 Rev1.0 silicon, after power on SATA host
index 3222e26a5aa3e2ab66fc348ceb8e3782918d92c3..d4c3d9df9b8fe314fe17d97ef51d6371aaf2d09b 100644 (file)
@@ -714,7 +714,7 @@ void ft_cpu_setup(void *blob, bd_t *bd)
                ccsr_sec_t __iomem *sec;
 
                sec = (void __iomem *)CONFIG_SYS_FSL_SEC_ADDR;
-               fdt_fixup_crypto_node(blob, in_be32(&sec->secvid_ms));
+               fdt_fixup_crypto_node(blob, sec_in32(&sec->secvid_ms));
        }
 #endif
 
index 19e130e87f1986f01e46c4609997def84da433b1..7a2d4be42cec34495b814b4fafcc8ea397151913 100644 (file)
@@ -66,12 +66,12 @@ static void setup_sec_liodn_base(void)
                return;
 
        /* QILCR[QSLOM] */
-       out_be32(&sec->qilcr_ms, 0x3ff<<16);
+       sec_out32(&sec->qilcr_ms, 0x3ff<<16);
 
        base = (liodn_bases[FSL_HW_PORTAL_SEC].id[0] << 16) |
                liodn_bases[FSL_HW_PORTAL_SEC].id[1];
 
-       out_be32(&sec->qilcr_ls, base);
+       sec_out32(&sec->qilcr_ls, base);
 }
 
 #ifdef CONFIG_SYS_DPAA_FMAN
index 4cec5e118ffc7d6666fde11e988cd3f7bbf02aa2..c6b4d955496e0c69d2d1179480036f885af909fd 100644 (file)
@@ -287,8 +287,8 @@ static u8 caam_get_era(void)
        };
 
        ccsr_sec_t __iomem *sec = (void __iomem *)CONFIG_SYS_FSL_SEC_ADDR;
-       u32 secvid_ms = in_be32(&sec->secvid_ms);
-       u32 ccbvid = in_be32(&sec->ccbvid);
+       u32 secvid_ms = sec_in32(&sec->secvid_ms);
+       u32 ccbvid = sec_in32(&sec->ccbvid);
        u16 ip_id = (secvid_ms & SEC_SECVID_MS_IPID_MASK) >>
                                SEC_SECVID_MS_IPID_SHIFT;
        u8 maj_rev = (secvid_ms & SEC_SECVID_MS_MAJ_REV_MASK) >>
index 712f2ef4b3020aab86eefd459b0d9e324e068924..4c1774f503c834ee26877d58cddbd92a026865e6 100644 (file)
@@ -24,6 +24,7 @@
 
 /* IP endianness */
 #define CONFIG_SYS_FSL_IFC_BE
+#define CONFIG_SYS_FSL_SEC_BE
 
 /* Number of TLB CAM entries we have on FSL Book-E chips */
 #if defined(CONFIG_E500MC)
index dfb370e051b295d64226f203b4be23ed297e9e53..0264523d6402779e094ed5fee993f9fddcc95be0 100644 (file)
@@ -16,6 +16,7 @@
 #include <asm/fsl_dma.h>
 #include <asm/fsl_i2c.h>
 #include <fsl_ifc.h>
+#include <fsl_sec.h>
 #include <asm/fsl_lbc.h>
 #include <asm/fsl_fman.h>
 #include <fsl_immap.h>
@@ -1911,6 +1912,7 @@ defined(CONFIG_PPC_T1020) || defined(CONFIG_PPC_T1022)
        u8      res24[64];
        u32     pblsr;          /* Preboot loader status */
        u32     pamubypenr;     /* PAMU bypass enable */
+#define FSL_CORENET_PAMU_BYPASS                0xffff0000
        u32     dmacr1;         /* DMA control */
        u8      res25[4];
        u32     gensr1;         /* General status */
@@ -2675,72 +2677,6 @@ enum {
        FSL_SRDS_B3_LANE_D = 23,
 };
 
-/* Security Engine Block (MS = Most Sig., LS = Least Sig.) */
-#if CONFIG_SYS_FSL_SEC_COMPAT >= 4
-typedef struct ccsr_sec {
-       u32     res0;
-       u32     mcfgr;          /* Master CFG Register */
-       u8      res1[0x8];
-       struct {
-               u32     ms;     /* Job Ring LIODN Register, MS */
-               u32     ls;     /* Job Ring LIODN Register, LS */
-       } jrliodnr[4];
-       u8      res2[0x30];
-       struct {
-               u32     ms;     /* RTIC LIODN Register, MS */
-               u32     ls;     /* RTIC LIODN Register, LS */
-       } rticliodnr[4];
-       u8      res3[0x1c];
-       u32     decorr;         /* DECO Request Register */
-       struct {
-               u32     ms;     /* DECO LIODN Register, MS */
-               u32     ls;     /* DECO LIODN Register, LS */
-       } decoliodnr[8];
-       u8      res4[0x40];
-       u32     dar;            /* DECO Avail Register */
-       u32     drr;            /* DECO Reset Register */
-       u8      res5[0xe78];
-       u32     crnr_ms;        /* CHA Revision Number Register, MS */
-       u32     crnr_ls;        /* CHA Revision Number Register, LS */
-       u32     ctpr_ms;        /* Compile Time Parameters Register, MS */
-       u32     ctpr_ls;        /* Compile Time Parameters Register, LS */
-       u8      res6[0x10];
-       u32     far_ms;         /* Fault Address Register, MS */
-       u32     far_ls;         /* Fault Address Register, LS */
-       u32     falr;           /* Fault Address LIODN Register */
-       u32     fadr;           /* Fault Address Detail Register */
-       u8      res7[0x4];
-       u32     csta;           /* CAAM Status Register */
-       u8      res8[0x8];
-       u32     rvid;           /* Run Time Integrity Checking Version ID Reg.*/
-       u32     ccbvid;         /* CHA Cluster Block Version ID Register */
-       u32     chavid_ms;      /* CHA Version ID Register, MS */
-       u32     chavid_ls;      /* CHA Version ID Register, LS */
-       u32     chanum_ms;      /* CHA Number Register, MS */
-       u32     chanum_ls;      /* CHA Number Register, LS */
-       u32     secvid_ms;      /* SEC Version ID Register, MS */
-       u32     secvid_ls;      /* SEC Version ID Register, LS */
-       u8      res9[0x6020];
-       u32     qilcr_ms;       /* Queue Interface LIODN CFG Register, MS */
-       u32     qilcr_ls;       /* Queue Interface LIODN CFG Register, LS */
-       u8      res10[0x8fd8];
-} ccsr_sec_t;
-
-#define SEC_CTPR_MS_AXI_LIODN          0x08000000
-#define SEC_CTPR_MS_QI                 0x02000000
-#define SEC_RVID_MA                    0x0f000000
-#define SEC_CHANUM_MS_JRNUM_MASK       0xf0000000
-#define SEC_CHANUM_MS_JRNUM_SHIFT      28
-#define SEC_CHANUM_MS_DECONUM_MASK     0x0f000000
-#define SEC_CHANUM_MS_DECONUM_SHIFT    24
-#define SEC_SECVID_MS_IPID_MASK        0xffff0000
-#define SEC_SECVID_MS_IPID_SHIFT       16
-#define SEC_SECVID_MS_MAJ_REV_MASK     0x0000ff00
-#define SEC_SECVID_MS_MAJ_REV_SHIFT    8
-#define SEC_CCBVID_ERA_MASK            0xff000000
-#define SEC_CCBVID_ERA_SHIFT           24
-#endif
-
 typedef struct ccsr_qman {
 #ifdef CONFIG_SYS_FSL_QMAN_V3
        u8      res0[0x200];
@@ -2940,6 +2876,7 @@ struct ccsr_sfp_regs {
 #define CONFIG_SYS_MPC85xx_SATA1_OFFSET                0x220000
 #define CONFIG_SYS_MPC85xx_SATA2_OFFSET                0x221000
 #define CONFIG_SYS_FSL_SEC_OFFSET              0x300000
+#define CONFIG_SYS_FSL_JR0_OFFSET              0x301000
 #define CONFIG_SYS_FSL_CORENET_PME_OFFSET      0x316000
 #define CONFIG_SYS_FSL_QMAN_OFFSET             0x318000
 #define CONFIG_SYS_FSL_BMAN_OFFSET             0x31a000
@@ -3000,8 +2937,10 @@ struct ccsr_sfp_regs {
 #define CONFIG_SYS_MPC85xx_ESDHC_OFFSET                0x2e000
 #if defined(CONFIG_PPC_C29X)
 #define CONFIG_SYS_FSL_SEC_OFFSET              0x80000
+#define CONFIG_SYS_FSL_JR0_OFFSET               0x81000
 #else
 #define CONFIG_SYS_FSL_SEC_OFFSET              0x30000
+#define CONFIG_SYS_FSL_JR0_OFFSET               0x31000
 #endif
 #define CONFIG_SYS_MPC85xx_SERDES2_OFFSET      0xE3100
 #define CONFIG_SYS_MPC85xx_SERDES1_OFFSET      0xE3000
@@ -3106,6 +3045,8 @@ struct ccsr_sfp_regs {
        (CONFIG_SYS_IMMR + CONFIG_SYS_MPC85xx_USB2_PHY_OFFSET)
 #define CONFIG_SYS_FSL_SEC_ADDR \
        (CONFIG_SYS_IMMR + CONFIG_SYS_FSL_SEC_OFFSET)
+#define CONFIG_SYS_FSL_JR0_ADDR \
+       (CONFIG_SYS_IMMR + CONFIG_SYS_FSL_JR0_OFFSET)
 #define CONFIG_SYS_FSL_FM1_ADDR \
        (CONFIG_SYS_IMMR + CONFIG_SYS_FSL_FM1_OFFSET)
 #define CONFIG_SYS_FSL_FM1_DTSEC1_ADDR \
index b27a6b753a06cb02f55d187badc8e2f915af761d..b29ce792f7231a0b3e25cb1ff3b172c9fa522553 100644 (file)
@@ -41,8 +41,12 @@ typedef unsigned long long u64;
 
 #define BITS_PER_LONG 32
 
+#ifdef CONFIG_PHYS_64BIT
+typedef unsigned long long dma_addr_t;
+#else
 /* DMA addresses are 32-bits wide */
 typedef u32 dma_addr_t;
+#endif
 
 #ifdef CONFIG_PHYS_64BIT
 typedef unsigned long long phys_addr_t;
index 797478a2c7f661294bb462d56d71048459652cd7..76147154c22366b7f70e5a95e83c8ea8ee3dfbe1 100644 (file)
@@ -1,6 +1,9 @@
 /dts-v1/;
 
 / {
+       #address-cells = <1>;
+       #size-cells = <0>;
+
        chosen {
                stdout-path = "/serial";
        };
                num-gpios = <20>;
        };
 
+       spi@0 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               reg = <0>;
+               compatible = "sandbox,spi";
+               cs-gpios = <0>, <&gpio_a 0>;
+               flash@0 {
+                       reg = <0>;
+                       compatible = "spansion,m25p16", "sandbox,spi-flash";
+                       spi-max-frequency = <40000000>;
+                       sandbox,filename = "spi.bin";
+               };
+       };
+
+       cros-ec@0 {
+               compatible = "google,cros-ec";
+               #address-cells = <1>;
+               #size-cells = <1>;
+               firmware_storage_spi: flash@0 {
+                       reg = <0 0x400000>;
+               };
+       };
+
 };
index 49b4a0f103a166ad02a0e5a316704aefb96ce8ca..9985e3c494922985d5f4f9538c9212dcb62e8bbf 100644 (file)
@@ -32,19 +32,6 @@ struct sandbox_spi_emu_ops {
        int (*xfer)(void *priv, const u8 *rx, u8 *tx, uint bytes);
 };
 
-/*
- * There are times when the data lines are allowed to tristate.  What
- * is actually sensed on the line depends on the hardware.  It could
- * always be 0xFF/0x00 (if there are pull ups/downs), or things could
- * float and so we'd get garbage back.  This func encapsulates that
- * scenario so we can worry about the details here.
- */
-static inline void sandbox_spi_tristate(u8 *buf, uint len)
-{
-       /* XXX: make this into a user config option ? */
-       memset(buf, 0xff, len);
-}
-
 /*
  * Extract the bus/cs from the spi spec and return the start of the spi
  * client spec.  If the bus/cs are invalid for the current config, then
index d17a82e90fcaab037057531ffef881e41b85525b..32d55ccc4c241deacdcf394daac81859d234657d 100644 (file)
@@ -42,7 +42,7 @@ enum state_terminal_raw {
 
 struct sandbox_spi_info {
        const char *spec;
-       const struct sandbox_spi_emu_ops *ops;
+       struct udevice *emul;
 };
 
 /* The complete state of the test system */
index ff9935acc4fcbe9522ce3b7bd282baf13880fa88..0dba8acbb2b320671541c939c739b98402f100b9 100644 (file)
@@ -4,6 +4,9 @@ menu "x86 architecture"
 config SYS_ARCH
        default "x86"
 
+config USE_PRIVATE_LIBGCC
+       default y
+
 choice
        prompt "Target select"
 
index 3106079c852c0ca54a4c3609805e3413909be2d4..3e7fedb913bed80965c0ca4e2765a35aaec98017 100644 (file)
@@ -28,6 +28,3 @@ PLATFORM_LDFLAGS += --emit-relocs -Bsymbolic -Bsymbolic-functions -m elf_i386
 LDFLAGS_FINAL += --gc-sections -pie
 LDFLAGS_FINAL += --wrap=__divdi3 --wrap=__udivdi3
 LDFLAGS_FINAL += --wrap=__moddi3 --wrap=__umoddi3
-
-export NORMAL_LIBGCC = $(shell $(CC) $(PLATFORM_CPPFLAGS) -print-libgcc-file-name)
-CONFIG_USE_PRIVATE_LIBGCC := arch/x86/lib
index 415bc2498935222afea91cbaee0e51011d69346f..e7bb3e33d5bdd999f246e56e02a2a06775553035 100644 (file)
@@ -9,5 +9,5 @@
 #
 
 extra-y        = start.o
-extra-$(CONFIG_X86_RESET_VECTOR) += resetvec.o start16.o
-obj-y  = interrupts.o cpu.o
+obj-$(CONFIG_X86_RESET_VECTOR) += resetvec.o start16.o
+obj-y  += interrupts.o cpu.o
index 329bb3ab35bdce43bc83692c16b60fac04529a8a..338bab19e471fdd3f4ab088aa999afeb2e10145e 100644 (file)
@@ -85,12 +85,25 @@ car_init_ret:
        /* Align global data to 16-byte boundary */
        andl    $0xfffffff0, %esp
 
+       /* Zero the global data since it won't happen later */
+       xorl    %eax, %eax
+       movl    $GENERATED_GBL_DATA_SIZE, %ecx
+       movl    %esp, %edi
+       rep     stosb
+
        /* Setup first parameter to setup_gdt */
        movl    %esp, %eax
 
        /* Reserve space for global descriptor table */
        subl    $X86_GDT_SIZE, %esp
 
+#if defined(CONFIG_SYS_MALLOC_F_LEN)
+       subl    $CONFIG_SYS_MALLOC_F_LEN, %esp
+       movl    %eax, %edx
+       addl    $GD_MALLOC_BASE, %edx
+       movl    %esp, (%edx)
+#endif
+
        /* Align temporary global descriptor table to 16-byte boundary */
        andl    $0xfffffff0, %esp
 
index 8b9b327cd48734fbd50b71dbe3d6a238151d7074..6968fda6494998d1d595c9862e64a10a8082a3e1 100644 (file)
@@ -70,7 +70,7 @@ idt_ptr:
  * GDT is setup in a safe location in RAM
  */
 gdt_ptr:
-       .word   0x20            /* limit (32 bytes = 4 GDT entries) */
+       .word   0x1f            /* limit (31 bytes = 4 GDT entries - 1) */
        .long   BOOT_SEG + gdt  /* base */
 
 /* Some CPUs are picky about GDT alignment... */
index 4862a59704e0deec573debe84c2c64363c357e95..c8dc4cec3c99aac8edf1cbd9186ca900223bc241 100644 (file)
@@ -1,13 +1,14 @@
 /include/ "skeleton.dtsi"
 
 / {
-       aliases {
-               console = "/serial";
+       chosen {
+               stdout-path = "/serial";
        };
 
        serial {
-               compatible = "ns16550";
-               reg-shift = <1>;
+               compatible = "coreboot-uart";
+               reg = <0x3f8 0x10>;
+               reg-shift = <0>;
                io-mapped = <1>;
                multiplier = <1>;
                baudrate = <115200>;
index 4a37dac4ea9adc470005da949b281f0e18923ef6..f2fcb3927cbbb323f30c69468c8aaf687b390f06 100644 (file)
               silent_console = <0>;
        };
 
-       gpio: gpio {};
+       gpioa {
+               compatible = "intel,ich6-gpio";
+               reg = <0 0x10>;
+               bank-name = "A";
+       };
+
+       gpiob {
+               compatible = "intel,ich6-gpio";
+               reg = <0x30 0x10>;
+               bank-name = "B";
+       };
+
+       gpioc {
+               compatible = "intel,ich6-gpio";
+               reg = <0x40 0x10>;
+               bank-name = "C";
+       };
 
        serial {
                reg = <0x3f8 8>;
                        memory-map = <0xff800000 0x00800000>;
                };
        };
+
+       lpc {
+               compatible = "intel,lpc";
+               #address-cells = <1>;
+               #size-cells = <1>;
+               cros-ec@200 {
+                       compatible = "google,cros-ec";
+                       reg = <0x204 1 0x200 1 0x880 0x80>;
+
+                       /* This describes the flash memory within the EC */
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       flash@8000000 {
+                               reg = <0x08000000 0x20000>;
+                               erase-value = <0xff>;
+                       };
+               };
+       };
 };
diff --git a/arch/x86/include/asm/arch-coreboot/gpio.h b/arch/x86/include/asm/arch-coreboot/gpio.h
new file mode 100644 (file)
index 0000000..3ec1816
--- /dev/null
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2014, Google Inc.
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#ifndef _X86_ARCH_GPIO_H_
+#define _X86_ARCH_GPIO_H_
+
+struct ich6_bank_platdata {
+       uint32_t base_addr;
+       const char *bank_name;
+};
+
+#endif /* _X86_ARCH_GPIO_H_ */
diff --git a/arch/x86/include/asm/bootm.h b/arch/x86/include/asm/bootm.h
new file mode 100644 (file)
index 0000000..033ab79
--- /dev/null
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2013, Google Inc.
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#ifndef ARM_BOOTM_H
+#define ARM_BOOTM_H
+
+void bootm_announce_and_cleanup(void);
+
+#endif
index f06a15cdfca06c76f87e2d2209077856286cea7d..ff15828a713de5d1258aada2dc5aa599734ca900 100644 (file)
@@ -8,4 +8,7 @@
 #define _ASM_CONFIG_H_
 
 #define CONFIG_SYS_GENERIC_BOARD
+#define CONFIG_LMB
+#define CONFIG_SYS_BOOT_RAMDISK_HIGH
+
 #endif
index fe09f31515455e12dc8ddcef786db2b76630ee81..8bda414dbd73bdef24c93a816b39a1eb8a6129e6 100644 (file)
@@ -6,6 +6,7 @@
 #ifndef _X86_GPIO_H_
 #define _X86_GPIO_H_
 
+#include <asm/arch/gpio.h>
 #include <asm-generic/gpio.h>
 
 #endif /* _X86_GPIO_H_ */
index 0f9665f5495160353e40f8a9d27af726f17ceb16..e6d183b4796bc8ac951d68d3a9f4a9fdfcccfec5 100644 (file)
 #define SYSCTLA         0x92
 #define SLAVE_PIC       0xa0
 
-#if 1
-#define UART0_BASE     0x3f8
-#define UART1_BASE     0x2f8
-#else
-/* FixMe: uarts swapped */
-#define UART0_BASE     0x2f8
-#define UART1_BASE     0x3f8
-#endif
-
-
 #endif
index f7303abccbd3380384b1fa5624cf305683ddfab8..25b672a0c13d831f0ddf1df0f4c17717dab8c863 100644 (file)
@@ -20,9 +20,9 @@ obj-$(CONFIG_SYS_X86_TSC_TIMER)       += tsc_timer.o
 obj-$(CONFIG_VIDEO_VGA)        += video.o
 obj-$(CONFIG_CMD_ZBOOT)        += zimage.o
 
-LIBGCC := $(notdir $(NORMAL_LIBGCC))
-extra-y := $(LIBGCC)
+extra-$(CONFIG_USE_PRIVATE_LIBGCC) := lib.a
 
+NORMAL_LIBGCC = $(shell $(CC) $(PLATFORM_CPPFLAGS) -print-libgcc-file-name)
 OBJCOPYFLAGS := --prefix-symbols=__normal_
-$(obj)/$(LIBGCC): $(NORMAL_LIBGCC) FORCE
+$(obj)/lib.a: $(NORMAL_LIBGCC) FORCE
        $(call if_changed,objcopy)
index ff158dd6a9d940c823bfc59059ce6151bc60d675..4c5c7f5aa796bc679cf2bb91f6f16f64de128098 100644 (file)
 
 #include <common.h>
 #include <command.h>
+#include <fdt_support.h>
 #include <image.h>
 #include <u-boot/zlib.h>
 #include <asm/bootparam.h>
 #include <asm/byteorder.h>
 #include <asm/zimage.h>
+#ifdef CONFIG_SYS_COREBOOT
+#include <asm/arch/timestamp.h>
+#endif
 
 #define COMMAND_LINE_OFFSET 0x9000
 
-/*cmd_boot.c*/
-int do_bootm_linux(int flag, int argc, char * const argv[],
-               bootm_headers_t *images)
+/*
+ * Implement a weak default function for boards that optionally
+ * need to clean up the system before jumping to the kernel.
+ */
+__weak void board_final_cleanup(void)
 {
-       struct boot_params *base_ptr = NULL;
-       ulong os_data, os_len;
-       image_header_t *hdr;
-       void *load_address;
+}
 
-#if defined(CONFIG_FIT)
-       const void      *data;
-       size_t          len;
+void bootm_announce_and_cleanup(void)
+{
+       printf("\nStarting kernel ...\n\n");
+
+#ifdef CONFIG_SYS_COREBOOT
+       timestamp_add_now(TS_U_BOOT_START_KERNEL);
+#endif
+       bootstage_mark_name(BOOTSTAGE_ID_BOOTM_HANDOFF, "start_kernel");
+#ifdef CONFIG_BOOTSTAGE_REPORT
+       bootstage_report();
 #endif
+       board_final_cleanup();
+}
 
-       if (flag & BOOTM_STATE_OS_PREP)
-               return 0;
-       if ((flag != 0) && (flag != BOOTM_STATE_OS_GO))
-               return 1;
+#if defined(CONFIG_OF_LIBFDT) && !defined(CONFIG_OF_NO_KERNEL)
+int arch_fixup_memory_node(void *blob)
+{
+       bd_t    *bd = gd->bd;
+       int bank;
+       u64 start[CONFIG_NR_DRAM_BANKS];
+       u64 size[CONFIG_NR_DRAM_BANKS];
+
+       for (bank = 0; bank < CONFIG_NR_DRAM_BANKS; bank++) {
+               start[bank] = bd->bi_dram[bank].start;
+               size[bank] = bd->bi_dram[bank].size;
+       }
+
+       return fdt_fixup_memory_banks(blob, start, size, CONFIG_NR_DRAM_BANKS);
+}
+#endif
 
+/* Subcommand: PREP */
+static int boot_prep_linux(bootm_headers_t *images)
+{
+       char *cmd_line_dest = NULL;
+       image_header_t *hdr;
+       int is_zimage = 0;
+       void *data = NULL;
+       size_t len;
+       int ret;
+
+#ifdef CONFIG_OF_LIBFDT
+       if (images->ft_len) {
+               debug("using: FDT\n");
+               if (image_setup_linux(images)) {
+                       puts("FDT creation failed! hanging...");
+                       hang();
+               }
+       }
+#endif
        if (images->legacy_hdr_valid) {
                hdr = images->legacy_hdr_os;
                if (image_check_type(hdr, IH_TYPE_MULTI)) {
+                       ulong os_data, os_len;
+
                        /* if multi-part image, we need to get first subimage */
                        image_multi_getimg(hdr, 0, &os_data, &os_len);
+                       data = (void *)os_data;
+                       len = os_len;
                } else {
                        /* otherwise get image data */
-                       os_data = image_get_data(hdr);
-                       os_len = image_get_data_size(hdr);
+                       data = (void *)image_get_data(hdr);
+                       len = image_get_data_size(hdr);
                }
+               is_zimage = 1;
 #if defined(CONFIG_FIT)
-       } else if (images->fit_uname_os) {
-               int ret;
-
+       } else if (images->fit_uname_os && is_zimage) {
                ret = fit_image_get_data(images->fit_hdr_os,
-                                       images->fit_noffset_os, &data, &len);
+                               images->fit_noffset_os,
+                               (const void **)&data, &len);
                if (ret) {
                        puts("Can't get image data/size!\n");
                        goto error;
                }
-               os_data = (ulong)data;
-               os_len = (ulong)len;
+               is_zimage = 1;
 #endif
-       } else {
-               puts("Could not find kernel image!\n");
-               goto error;
        }
 
-#ifdef CONFIG_CMD_ZBOOT
-       base_ptr = load_zimage((void *)os_data, os_len, &load_address);
-#endif
+       if (is_zimage) {
+               void *load_address;
+               char *base_ptr;
 
-       if (NULL == base_ptr) {
-               printf("## Kernel loading failed ...\n");
+               base_ptr = (char *)load_zimage(data, len, &load_address);
+               images->os.load = (ulong)load_address;
+               cmd_line_dest = base_ptr + COMMAND_LINE_OFFSET;
+               images->ep = (ulong)base_ptr;
+       } else if (images->ep) {
+               cmd_line_dest = (void *)images->ep + COMMAND_LINE_OFFSET;
+       } else {
+               printf("## Kernel loading failed (no setup) ...\n");
                goto error;
        }
 
-       if (setup_zimage(base_ptr, (char *)base_ptr + COMMAND_LINE_OFFSET,
+       printf("Setup at %#08lx\n", images->ep);
+       ret = setup_zimage((void *)images->ep, cmd_line_dest,
                        0, images->rd_start,
-                       images->rd_end - images->rd_start)) {
+                       images->rd_end - images->rd_start);
+
+       if (ret) {
                printf("## Setting up boot parameters failed ...\n");
-               goto error;
+               return 1;
        }
 
-       boot_zimage(base_ptr, load_address);
-       /* does not return */
+       return 0;
 
 error:
        return 1;
 }
+
+/* Subcommand: GO */
+static int boot_jump_linux(bootm_headers_t *images)
+{
+       debug("## Transferring control to Linux (at address %08lx, kernel %08lx) ...\n",
+             images->ep, images->os.load);
+
+       boot_zimage((struct boot_params *)images->ep, (void *)images->os.load);
+       /* does not return */
+
+       return 1;
+}
+
+int do_bootm_linux(int flag, int argc, char * const argv[],
+               bootm_headers_t *images)
+{
+       /* No need for those on x86 */
+       if (flag & BOOTM_STATE_OS_BD_T || flag & BOOTM_STATE_OS_CMDLINE)
+               return -1;
+
+       if (flag & BOOTM_STATE_OS_PREP)
+               return boot_prep_linux(images);
+
+       if (flag & BOOTM_STATE_OS_GO) {
+               boot_jump_linux(images);
+               return 0;
+       }
+
+       return boot_jump_linux(images);
+}
index 1dab3cc78878dcea322d1685f0df0ed388f7a70c..b1902834e8a9514e5bdcce56b2bccbb03fdc7f7c 100644 (file)
@@ -18,6 +18,7 @@
 #include <asm/ptrace.h>
 #include <asm/zimage.h>
 #include <asm/byteorder.h>
+#include <asm/bootm.h>
 #include <asm/bootparam.h>
 #ifdef CONFIG_SYS_COREBOOT
 #include <asm/arch/timestamp.h>
@@ -242,41 +243,27 @@ int setup_zimage(struct boot_params *setup_base, char *cmd_line, int auto_boot,
                hdr->loadflags |= HEAP_FLAG;
        }
 
-       if (bootproto >= 0x0202) {
-               hdr->cmd_line_ptr = (uintptr_t)cmd_line;
-       } else if (bootproto >= 0x0200) {
-               setup_base->screen_info.cl_magic = COMMAND_LINE_MAGIC;
-               setup_base->screen_info.cl_offset =
-                       (uintptr_t)cmd_line - (uintptr_t)setup_base;
+       if (cmd_line) {
+               if (bootproto >= 0x0202) {
+                       hdr->cmd_line_ptr = (uintptr_t)cmd_line;
+               } else if (bootproto >= 0x0200) {
+                       setup_base->screen_info.cl_magic = COMMAND_LINE_MAGIC;
+                       setup_base->screen_info.cl_offset =
+                               (uintptr_t)cmd_line - (uintptr_t)setup_base;
+
+                       hdr->setup_move_size = 0x9100;
+               }
 
-               hdr->setup_move_size = 0x9100;
+               /* build command line at COMMAND_LINE_OFFSET */
+               build_command_line(cmd_line, auto_boot);
        }
 
-       /* build command line at COMMAND_LINE_OFFSET */
-       build_command_line(cmd_line, auto_boot);
        return 0;
 }
 
-/*
- * Implement a weak default function for boards that optionally
- * need to clean up the system before jumping to the kernel.
- */
-__weak void board_final_cleanup(void)
-{
-}
-
 void boot_zimage(void *setup_base, void *load_address)
 {
-       debug("## Transferring control to Linux (at address %08x) ...\n",
-             (u32)setup_base);
-
-       bootstage_mark_name(BOOTSTAGE_ID_BOOTM_HANDOFF, "start_kernel");
-#ifdef CONFIG_BOOTSTAGE_REPORT
-       bootstage_report();
-#endif
-       board_final_cleanup();
-
-       printf("\nStarting kernel ...\n\n");
+       bootm_announce_and_cleanup();
 
 #ifdef CONFIG_SYS_COREBOOT
        timestamp_add_now(TS_U_BOOT_START_KERNEL);
@@ -295,7 +282,6 @@ void boot_zimage(void *setup_base, void *load_address)
        :: [kernel_entry]"a"(load_address),
           [boot_params] "S"(setup_base),
           "b"(0), "D"(0)
-       :  "%ebp"
        );
 }
 
index a79476485274046c2f377ef30ccfea336e024028..acf2b803079e9cf67398a21ff1709a65b9c311ed 100644 (file)
@@ -332,7 +332,7 @@ const omap3_sysinfo sysinfo = {
        MUX_VAL(CP(SYS_CLKOUT1),        (IEN  | PTD | DIS | M0)) \
        MUX_VAL(CP(SYS_CLKOUT2),        (IEN  | PTU | EN  | M0)) \
        /* JTAG */\
-       MUX_VAL(CP(JTAG_nTRST),         (IEN  | PTD | DIS | M0)) \
+       MUX_VAL(CP(JTAG_NTRST),         (IEN  | PTD | DIS | M0)) \
        MUX_VAL(CP(JTAG_TCK),           (IEN  | PTD | DIS | M0)) \
        MUX_VAL(CP(JTAG_TMS),           (IEN  | PTD | DIS | M0)) \
        MUX_VAL(CP(JTAG_TDI),           (IEN  | PTD | DIS | M0)) \
index 4c3a9ba785a3219a55c6800072691c2630fd8f23..263bb5426c0d1a7086b9ed28ea7085e7ee0a96ed 100644 (file)
@@ -13,7 +13,7 @@
 #include <command.h>
 #include <i2c.h>
 #include <asm/arch/cpu.h>
-#include <asm/arch/kirkwood.h>
+#include <asm/arch/soc.h>
 #include <asm/arch/mpp.h>
 #include <asm/arch/gpio.h>
 
@@ -26,8 +26,8 @@ DECLARE_GLOBAL_DATA_PTR;
 int board_early_init_f(void)
 {
        /* GPIO configuration */
-       kw_config_gpio(NET2BIG_V2_OE_VAL_LOW, NET2BIG_V2_OE_VAL_HIGH,
-                       NET2BIG_V2_OE_LOW, NET2BIG_V2_OE_HIGH);
+       mvebu_config_gpio(NET2BIG_V2_OE_VAL_LOW, NET2BIG_V2_OE_VAL_HIGH,
+                         NET2BIG_V2_OE_LOW, NET2BIG_V2_OE_HIGH);
 
        /* Multi-Purpose Pins Functionality configuration */
        static const u32 kwmpp_config[] = {
@@ -77,7 +77,7 @@ int board_init(void)
        gd->bd->bi_arch_number = MACH_TYPE_NET2BIG_V2;
 
        /* Boot parameters address */
-       gd->bd->bi_boot_params = kw_sdram_bar(0) + 0x100;
+       gd->bd->bi_boot_params = mvebu_sdram_bar(0) + 0x100;
 
        return 0;
 }
index 3773587cc6d1ea9ffb553009b8ff2de0354568ec..17e629622ff733487303611f58730835e1317246 100644 (file)
@@ -12,7 +12,7 @@
 #include <common.h>
 #include <command.h>
 #include <asm/arch/cpu.h>
-#include <asm/arch/kirkwood.h>
+#include <asm/arch/soc.h>
 #include <asm/arch/mpp.h>
 #include <asm/arch/gpio.h>
 
@@ -24,8 +24,8 @@ DECLARE_GLOBAL_DATA_PTR;
 int board_early_init_f(void)
 {
        /* Gpio configuration */
-       kw_config_gpio(NETSPACE_V2_OE_VAL_LOW, NETSPACE_V2_OE_VAL_HIGH,
-                       NETSPACE_V2_OE_LOW, NETSPACE_V2_OE_HIGH);
+       mvebu_config_gpio(NETSPACE_V2_OE_VAL_LOW, NETSPACE_V2_OE_VAL_HIGH,
+                         NETSPACE_V2_OE_LOW, NETSPACE_V2_OE_HIGH);
 
        /* Multi-Purpose Pins Functionality configuration */
        static const u32 kwmpp_config[] = {
@@ -73,7 +73,7 @@ int board_init(void)
        gd->bd->bi_arch_number = CONFIG_MACH_TYPE;
 
        /* Boot parameters address */
-       gd->bd->bi_boot_params = kw_sdram_bar(0) + 0x100;
+       gd->bd->bi_boot_params = mvebu_sdram_bar(0) + 0x100;
 
        return 0;
 }
index 2dc50185604248475eed34d766bf40396973bd9d..8620e4b5d135fa1022043a4cf53f40b2491dde20 100644 (file)
@@ -12,7 +12,7 @@
 #include <common.h>
 #include <command.h>
 #include <asm/arch/cpu.h>
-#include <asm/arch/kirkwood.h>
+#include <asm/arch/soc.h>
 #include <asm/arch/mpp.h>
 #include <asm/arch/gpio.h>
 
@@ -97,8 +97,8 @@ struct mv88e61xx_config swcfg = {
 int board_early_init_f(void)
 {
        /* Gpio configuration */
-       kw_config_gpio(WIRELESS_SPACE_OE_VAL_LOW, WIRELESS_SPACE_OE_VAL_HIGH,
-                       WIRELESS_SPACE_OE_LOW, WIRELESS_SPACE_OE_HIGH);
+       mvebu_config_gpio(WIRELESS_SPACE_OE_VAL_LOW, WIRELESS_SPACE_OE_VAL_HIGH,
+                         WIRELESS_SPACE_OE_LOW, WIRELESS_SPACE_OE_HIGH);
 
        /* Multi-Purpose Pins Functionality configuration */
        kirkwood_mpp_conf(kwmpp_config, NULL);
@@ -112,7 +112,7 @@ int board_init(void)
        gd->bd->bi_arch_number = CONFIG_MACH_TYPE;
 
        /* Boot parameters address */
-       gd->bd->bi_boot_params = kw_sdram_bar(0) + 0x100;
+       gd->bd->bi_boot_params = mvebu_sdram_bar(0) + 0x100;
 
        return 0;
 }
diff --git a/board/Marvell/db-mv784mp-gp/Kconfig b/board/Marvell/db-mv784mp-gp/Kconfig
new file mode 100644 (file)
index 0000000..f94a444
--- /dev/null
@@ -0,0 +1,23 @@
+if TARGET_DB_MV784MP_GP
+
+config SYS_CPU
+       string
+       default "armv7"
+
+config SYS_BOARD
+       string
+       default "db-mv784mp-gp"
+
+config SYS_VENDOR
+       string
+       default "Marvell"
+
+config SYS_SOC
+       string
+       default "armada-xp"
+
+config SYS_CONFIG_NAME
+       string
+       default "db-mv784mp-gp"
+
+endif
diff --git a/board/Marvell/db-mv784mp-gp/MAINTAINERS b/board/Marvell/db-mv784mp-gp/MAINTAINERS
new file mode 100644 (file)
index 0000000..a095f89
--- /dev/null
@@ -0,0 +1,6 @@
+DB_MV784MP_GP BOARD
+M:     Stefan Roese <sr@denx.de>
+S:     Maintained
+F:     board/Marvell/db-mv784mp-gp/
+F:     include/configs/db-mv784mp-gp.h
+F:     configs/db-mv784mp-gp_defconfig
diff --git a/board/Marvell/db-mv784mp-gp/Makefile b/board/Marvell/db-mv784mp-gp/Makefile
new file mode 100644 (file)
index 0000000..8f5a7fb
--- /dev/null
@@ -0,0 +1,7 @@
+#
+# Copyright (C) 2014 Stefan Roese <sr@denx.de>
+#
+# SPDX-License-Identifier:     GPL-2.0+
+#
+
+obj-y  := db-mv784mp-gp.o
diff --git a/board/Marvell/db-mv784mp-gp/db-mv784mp-gp.c b/board/Marvell/db-mv784mp-gp/db-mv784mp-gp.c
new file mode 100644 (file)
index 0000000..b3dae89
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2014 Stefan Roese <sr@denx.de>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <miiphy.h>
+#include <asm/io.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/soc.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define BIT(nr)                                (1UL << (nr))
+
+#define ETH_PHY_CTRL_REG               0
+#define ETH_PHY_CTRL_POWER_DOWN_BIT    11
+#define ETH_PHY_CTRL_POWER_DOWN_MASK   (1 << ETH_PHY_CTRL_POWER_DOWN_BIT)
+
+/*
+ * Those values and defines are taken from the Marvell U-Boot version
+ * "u-boot-2011.12-2014_T1.0" for the board rd78460gp aka
+ * "RD-AXP-GP rev 1.0".
+ *
+ * GPPs
+ * MPP#                NAME                    IN/OUT
+ * ----------------------------------------------
+ * 21          SW_Reset_               OUT
+ * 25          Phy_Int#                IN
+ * 28          SDI_WP                  IN
+ * 29          SDI_Status              IN
+ * 54-61       On GPP Connector        ?
+ * 62          Switch Interrupt        IN
+ * 63-65       Reserved from SW Board  ?
+ * 66          SW_BRD connected        IN
+ */
+#define RD_78460_GP_GPP_OUT_ENA_LOW    (~(BIT(21) | BIT(20)))
+#define RD_78460_GP_GPP_OUT_ENA_MID    (~(BIT(26) | BIT(27)))
+#define RD_78460_GP_GPP_OUT_ENA_HIGH   (~(0x0))
+
+#define RD_78460_GP_GPP_OUT_VAL_LOW    (BIT(21) | BIT(20))
+#define RD_78460_GP_GPP_OUT_VAL_MID    (BIT(26) | BIT(27))
+#define RD_78460_GP_GPP_OUT_VAL_HIGH   0x0
+
+int board_early_init_f(void)
+{
+       /* Configure MPP */
+       writel(0x00000000, MVEBU_MPP_BASE + 0x00);
+       writel(0x00000000, MVEBU_MPP_BASE + 0x04);
+       writel(0x33000000, MVEBU_MPP_BASE + 0x08);
+       writel(0x11000000, MVEBU_MPP_BASE + 0x0c);
+       writel(0x11111111, MVEBU_MPP_BASE + 0x10);
+       writel(0x00221100, MVEBU_MPP_BASE + 0x14);
+       writel(0x00000003, MVEBU_MPP_BASE + 0x18);
+       writel(0x00000000, MVEBU_MPP_BASE + 0x1c);
+       writel(0x00000000, MVEBU_MPP_BASE + 0x20);
+
+       /* Configure GPIO */
+       writel(RD_78460_GP_GPP_OUT_VAL_LOW, MVEBU_GPIO0_BASE + 0x00);
+       writel(RD_78460_GP_GPP_OUT_ENA_LOW, MVEBU_GPIO0_BASE + 0x04);
+       writel(RD_78460_GP_GPP_OUT_VAL_MID, MVEBU_GPIO1_BASE + 0x00);
+       writel(RD_78460_GP_GPP_OUT_ENA_MID, MVEBU_GPIO1_BASE + 0x04);
+       writel(RD_78460_GP_GPP_OUT_VAL_HIGH, MVEBU_GPIO2_BASE + 0x00);
+       writel(RD_78460_GP_GPP_OUT_ENA_HIGH, MVEBU_GPIO2_BASE + 0x04);
+
+       return 0;
+}
+
+int board_init(void)
+{
+       /* adress of boot parameters */
+       gd->bd->bi_boot_params = mvebu_sdram_bar(0) + 0x100;
+
+       return 0;
+}
+
+int checkboard(void)
+{
+       puts("Board: Marvell DB-MV784MP-GP\n");
+
+       return 0;
+}
+
+#ifdef CONFIG_RESET_PHY_R
+/* Configure and enable MV88E1545 PHY */
+void reset_phy(void)
+{
+       u16 devadr = CONFIG_PHY_BASE_ADDR;
+       char *name = "neta0";
+       u16 reg;
+
+       if (miiphy_set_current_dev(name))
+               return;
+
+       /* Enable QSGMII AN */
+       /* Set page to 4 */
+       miiphy_write(name, devadr, 0x16, 4);
+       /* Enable AN */
+       miiphy_write(name, devadr, 0x0, 0x1140);
+       /* Set page to 0 */
+       miiphy_write(name, devadr, 0x16, 0);
+
+       /* Phy C_ANEG */
+       miiphy_read(name, devadr, 0x4, &reg);
+       reg |= 0x1E0;
+       miiphy_write(name, devadr, 0x4, reg);
+
+       /* Soft-Reset */
+       miiphy_write(name, devadr, 22, 0x0000);
+       miiphy_write(name, devadr, 0, 0x9140);
+
+       /* Power up the phy */
+       miiphy_read(name, devadr, ETH_PHY_CTRL_REG, &reg);
+       reg &= ~(ETH_PHY_CTRL_POWER_DOWN_MASK);
+       miiphy_write(name, devadr, ETH_PHY_CTRL_REG, reg);
+
+       printf("88E1545 Initialized on %s\n", name);
+}
+#endif /* CONFIG_RESET_PHY_R */
diff --git a/board/Marvell/db-mv784mp-gp/kwbimage.cfg b/board/Marvell/db-mv784mp-gp/kwbimage.cfg
new file mode 100644 (file)
index 0000000..d7ef407
--- /dev/null
@@ -0,0 +1,12 @@
+#
+# Copyright (C) 2014 Stefan Roese <sr@denx.de>
+#
+
+# Armada XP uses version 1 image format
+VERSION                1
+
+# Boot Media configurations
+BOOT_FROM      spi
+
+# Binary Header (bin_hdr) with DDR3 training code
+BINARY board/Marvell/db-mv784mp-gp/binary.0 0000005b 00000068
index b53c81080d10985faeb02992fa62f9f35864d64f..0887d92c2995469cb115c0ef719846b7e2eb7e24 100644 (file)
@@ -12,7 +12,7 @@
 #include <common.h>
 #include <miiphy.h>
 #include <asm/arch/cpu.h>
-#include <asm/arch/kirkwood.h>
+#include <asm/arch/soc.h>
 #include <asm/arch/mpp.h>
 #include "dreamplug.h"
 
@@ -25,9 +25,9 @@ int board_early_init_f(void)
         * There are maximum 64 gpios controlled through 2 sets of registers
         * the  below configuration configures mainly initial LED status
         */
-       kw_config_gpio(DREAMPLUG_OE_VAL_LOW,
-                       DREAMPLUG_OE_VAL_HIGH,
-                       DREAMPLUG_OE_LOW, DREAMPLUG_OE_HIGH);
+       mvebu_config_gpio(DREAMPLUG_OE_VAL_LOW,
+                         DREAMPLUG_OE_VAL_HIGH,
+                         DREAMPLUG_OE_LOW, DREAMPLUG_OE_HIGH);
 
        /* Multi-Purpose Pins Functionality configuration */
        static const u32 kwmpp_config[] = {
@@ -90,7 +90,7 @@ int board_early_init_f(void)
 int board_init(void)
 {
        /* adress of boot parameters */
-       gd->bd->bi_boot_params = kw_sdram_bar(0) + 0x100;
+       gd->bd->bi_boot_params = mvebu_sdram_bar(0) + 0x100;
 
        return 0;
 }
index 72bccc821ce2cc2b7d9fe21e83382f0546a9663e..b0d5f1e10f4ddf46a4f21371a3f5edaaa22af10f 100644 (file)
@@ -9,7 +9,7 @@
 #include <common.h>
 #include <miiphy.h>
 #include <asm/arch/cpu.h>
-#include <asm/arch/kirkwood.h>
+#include <asm/arch/soc.h>
 #include <asm/arch/mpp.h>
 #include "guruplug.h"
 
@@ -22,9 +22,9 @@ int board_early_init_f(void)
         * There are maximum 64 gpios controlled through 2 sets of registers
         * the  below configuration configures mainly initial LED status
         */
-       kw_config_gpio(GURUPLUG_OE_VAL_LOW,
-                       GURUPLUG_OE_VAL_HIGH,
-                       GURUPLUG_OE_LOW, GURUPLUG_OE_HIGH);
+       mvebu_config_gpio(GURUPLUG_OE_VAL_LOW,
+                         GURUPLUG_OE_VAL_HIGH,
+                         GURUPLUG_OE_LOW, GURUPLUG_OE_HIGH);
 
        /* Multi-Purpose Pins Functionality configuration */
        static const u32 kwmpp_config[] = {
@@ -92,7 +92,7 @@ int board_init(void)
        gd->bd->bi_arch_number = MACH_TYPE_GURUPLUG;
 
        /* adress of boot parameters */
-       gd->bd->bi_boot_params = kw_sdram_bar(0) + 0x100;
+       gd->bd->bi_boot_params = mvebu_sdram_bar(0) + 0x100;
 
        return 0;
 }
index e1652c08317405ac922f087ec1e2f29b153d6da9..ef08ad8928d04dad71afbebfabd9f80f7943052d 100644 (file)
@@ -11,7 +11,7 @@
 #include <common.h>
 #include <netdev.h>
 #include <asm/arch/cpu.h>
-#include <asm/arch/kirkwood.h>
+#include <asm/arch/soc.h>
 #include <asm/arch/mpp.h>
 #include "mv88f6281gtw_ge.h"
 
@@ -24,9 +24,9 @@ int board_early_init_f(void)
         * There are maximum 64 gpios controlled through 2 sets of registers
         * the  below configuration configures mainly initial LED status
         */
-       kw_config_gpio(MV88F6281GTW_GE_OE_VAL_LOW,
-                       MV88F6281GTW_GE_OE_VAL_HIGH,
-                       MV88F6281GTW_GE_OE_LOW, MV88F6281GTW_GE_OE_HIGH);
+       mvebu_config_gpio(MV88F6281GTW_GE_OE_VAL_LOW,
+                         MV88F6281GTW_GE_OE_VAL_HIGH,
+                         MV88F6281GTW_GE_OE_LOW, MV88F6281GTW_GE_OE_HIGH);
 
        /* Multi-Purpose Pins Functionality configuration */
        static const u32 kwmpp_config[] = {
@@ -94,7 +94,7 @@ int board_init(void)
        gd->bd->bi_arch_number = MACH_TYPE_MV88F6281GTW_GE;
 
        /* adress of boot parameters */
-       gd->bd->bi_boot_params = kw_sdram_bar(0) + 0x100;
+       gd->bd->bi_boot_params = mvebu_sdram_bar(0) + 0x100;
 
        return 0;
 }
index a005a2f79dd07618e89267bc32906f9a946e6e11..55cf525cf8aa18e7aed9542c2761ddc30d41a959 100644 (file)
@@ -14,7 +14,7 @@
 #include <common.h>
 #include <miiphy.h>
 #include <asm/arch/cpu.h>
-#include <asm/arch/kirkwood.h>
+#include <asm/arch/soc.h>
 #include <asm/arch/mpp.h>
 #include "openrd.h"
 
@@ -27,9 +27,9 @@ int board_early_init_f(void)
         * There are maximum 64 gpios controlled through 2 sets of registers
         * the  below configuration configures mainly initial LED status
         */
-       kw_config_gpio(OPENRD_OE_VAL_LOW,
-                       OPENRD_OE_VAL_HIGH,
-                       OPENRD_OE_LOW, OPENRD_OE_HIGH);
+       mvebu_config_gpio(OPENRD_OE_VAL_LOW,
+                         OPENRD_OE_VAL_HIGH,
+                         OPENRD_OE_LOW, OPENRD_OE_HIGH);
 
        /* Multi-Purpose Pins Functionality configuration */
        static const u32 kwmpp_config[] = {
@@ -104,7 +104,7 @@ int board_init(void)
 #endif
 
        /* adress of boot parameters */
-       gd->bd->bi_boot_params = kw_sdram_bar(0) + 0x100;
+       gd->bd->bi_boot_params = mvebu_sdram_bar(0) + 0x100;
        return 0;
 }
 
index 33ef0c78e5bba9d18ecb15b57f1a1db567506c42..b0020c95a5bb067ebe2291eb4714981751603edf 100644 (file)
@@ -10,7 +10,7 @@
 #include <miiphy.h>
 #include <netdev.h>
 #include <asm/arch/cpu.h>
-#include <asm/arch/kirkwood.h>
+#include <asm/arch/soc.h>
 #include <asm/arch/mpp.h>
 #include "rd6281a.h"
 
@@ -23,9 +23,9 @@ int board_early_init_f(void)
         * There are maximum 64 gpios controlled through 2 sets of registers
         * the  below configuration configures mainly initial LED status
         */
-       kw_config_gpio(RD6281A_OE_VAL_LOW,
-                       RD6281A_OE_VAL_HIGH,
-                       RD6281A_OE_LOW, RD6281A_OE_HIGH);
+       mvebu_config_gpio(RD6281A_OE_VAL_LOW,
+                         RD6281A_OE_VAL_HIGH,
+                         RD6281A_OE_LOW, RD6281A_OE_HIGH);
 
        /* Multi-Purpose Pins Functionality configuration */
        static const u32 kwmpp_config[] = {
@@ -93,7 +93,7 @@ int board_init(void)
        gd->bd->bi_arch_number = MACH_TYPE_RD88F6281;
 
        /* adress of boot parameters */
-       gd->bd->bi_boot_params = kw_sdram_bar(0) + 0x100;
+       gd->bd->bi_boot_params = mvebu_sdram_bar(0) + 0x100;
 
        return 0;
 }
index 87e49f417bb7138199fd77d3252c46a200206236..8907fb58ff80f90f48c14545e7bbb04c93ae705f 100644 (file)
@@ -9,7 +9,7 @@
 #include <common.h>
 #include <miiphy.h>
 #include <asm/arch/cpu.h>
-#include <asm/arch/kirkwood.h>
+#include <asm/arch/soc.h>
 #include <asm/arch/mpp.h>
 #include "sheevaplug.h"
 
@@ -22,9 +22,9 @@ int board_early_init_f(void)
         * There are maximum 64 gpios controlled through 2 sets of registers
         * the  below configuration configures mainly initial LED status
         */
-       kw_config_gpio(SHEEVAPLUG_OE_VAL_LOW,
-                       SHEEVAPLUG_OE_VAL_HIGH,
-                       SHEEVAPLUG_OE_LOW, SHEEVAPLUG_OE_HIGH);
+       mvebu_config_gpio(SHEEVAPLUG_OE_VAL_LOW,
+                         SHEEVAPLUG_OE_VAL_HIGH,
+                         SHEEVAPLUG_OE_LOW, SHEEVAPLUG_OE_HIGH);
 
        /* Multi-Purpose Pins Functionality configuration */
        static const u32 kwmpp_config[] = {
@@ -92,7 +92,7 @@ int board_init(void)
        gd->bd->bi_arch_number = MACH_TYPE_SHEEVAPLUG;
 
        /* adress of boot parameters */
-       gd->bd->bi_boot_params = kw_sdram_bar(0) + 0x100;
+       gd->bd->bi_boot_params = mvebu_sdram_bar(0) + 0x100;
 
        return 0;
 }
index ff6a6a09ed7794f3d398f101cdb369a010da75d3..83ab1bc32d307dc16b3e5017dcb169d31b32b8d2 100644 (file)
@@ -11,7 +11,7 @@
 
 #include <common.h>
 #include <miiphy.h>
-#include <asm/arch/kirkwood.h>
+#include <asm/arch/soc.h>
 #include <asm/arch/mpp.h>
 #include <asm/arch/cpu.h>
 #include <asm/io.h>
@@ -26,9 +26,9 @@ int board_early_init_f(void)
         * There are maximum 64 gpios controlled through 2 sets of registers
         * the  below configuration configures mainly initial LED status
         */
-       kw_config_gpio(DOCKSTAR_OE_VAL_LOW,
-                       DOCKSTAR_OE_VAL_HIGH,
-                       DOCKSTAR_OE_LOW, DOCKSTAR_OE_HIGH);
+       mvebu_config_gpio(DOCKSTAR_OE_VAL_LOW,
+                         DOCKSTAR_OE_VAL_HIGH,
+                         DOCKSTAR_OE_LOW, DOCKSTAR_OE_HIGH);
 
        /* Multi-Purpose Pins Functionality configuration */
        static const u32 kwmpp_config[] = {
@@ -96,7 +96,7 @@ int board_init(void)
        gd->bd->bi_arch_number = MACH_TYPE_DOCKSTAR;
 
        /* address of boot parameters */
-       gd->bd->bi_boot_params = kw_sdram_bar(0) + 0x100;
+       gd->bd->bi_boot_params = mvebu_sdram_bar(0) + 0x100;
 
        return 0;
 }
@@ -143,7 +143,7 @@ void reset_phy(void)
 
 static void set_leds(u32 leds, u32 blinking)
 {
-       struct kwgpio_registers *r = (struct kwgpio_registers *)KW_GPIO1_BASE;
+       struct kwgpio_registers *r = (struct kwgpio_registers *)MVEBU_GPIO1_BASE;
        u32 oe = readl(&r->oe) | BOTH_LEDS;
        writel(oe & ~leds, &r->oe);     /* active low */
        u32 bl = readl(&r->blink_en) & ~BOTH_LEDS;
index a6598e9c81e607d29a2a568d7738ec07574f1f1d..1f4fb924942a4c65a9833fd660eb6847853b90a7 100644 (file)
@@ -14,7 +14,7 @@
 
 #include <common.h>
 #include <miiphy.h>
-#include <asm/arch/kirkwood.h>
+#include <asm/arch/soc.h>
 #include <asm/arch/mpp.h>
 #include <asm/arch/cpu.h>
 #include <asm/io.h>
@@ -83,9 +83,9 @@ int board_early_init_f(void)
         * There are maximum 64 gpios controlled through 2 sets of registers
         * the  below configuration configures mainly initial LED status
         */
-       kw_config_gpio(GOFLEXHOME_OE_VAL_LOW,
-                      GOFLEXHOME_OE_VAL_HIGH,
-                      GOFLEXHOME_OE_LOW, GOFLEXHOME_OE_HIGH);
+       mvebu_config_gpio(GOFLEXHOME_OE_VAL_LOW,
+                         GOFLEXHOME_OE_VAL_HIGH,
+                         GOFLEXHOME_OE_LOW, GOFLEXHOME_OE_HIGH);
        kirkwood_mpp_conf(kwmpp_config, NULL);
        return 0;
 }
@@ -98,7 +98,7 @@ int board_init(void)
        gd->bd->bi_arch_number = MACH_TYPE_GOFLEXHOME;
 
        /* address of boot parameters */
-       gd->bd->bi_boot_params = kw_sdram_bar(0) + 0x100;
+       gd->bd->bi_boot_params = mvebu_sdram_bar(0) + 0x100;
 
        return 0;
 }
@@ -149,7 +149,7 @@ static void set_leds(u32 leds, u32 blinking)
        u32 oe;
        u32 bl;
 
-       r = (struct kwgpio_registers *)KW_GPIO1_BASE;
+       r = (struct kwgpio_registers *)MVEBU_GPIO1_BASE;
        oe = readl(&r->oe) | BOTH_LEDS;
        writel(oe & ~leds, &r->oe);     /* active low */
        bl = readl(&r->blink_en) & ~BOTH_LEDS;
index 2298e3619c4ee0d4e2ff9b9aebc4ed7f785ecac5..6761b141fb82fd42a51f5e47896d1b9bfaed1b7d 100644 (file)
@@ -14,6 +14,7 @@
 #include <asm/arch/hardware.h>
 #include <asm/arch/at91_pmc.h>
 #include <asm/arch/at91_pio.h>
+#include <status_led.h>
 
 /* bit mask in PIO port B */
 #define        GREEN_LED       (1<<0)
index 56d811ca42566e8e3409c461c6dffd7ed3a568bb..fbe15afd281b34d59317d3c40d40f35299253df7 100644 (file)
@@ -9,6 +9,7 @@
 #include <common.h>
 #include <asm/io.h>
 #include <asm/arch/gpio.h>
+#include <status_led.h>
 
 void coloured_LED_init(void)
 {
index 659a124b22750fda1fb4b02df5d74defaf4012e6..b0d49c4ee6b8ac266588d63c81b8ef3094097346 100644 (file)
 #include <malloc.h>
 #include <netdev.h>
 #include <miiphy.h>
-#include <asm/arch/kirkwood.h>
+#include <spi.h>
+#include <spi_flash.h>
+#include <asm/arch/soc.h>
 #include <asm/arch/cpu.h>
 #include <asm/arch/mpp.h>
 #include <asm/arch/gpio.h>
-#include <spi_flash.h>
 
 #include "lsxl.h"
 
@@ -51,9 +52,9 @@ int board_early_init_f(void)
         * There are maximum 64 gpios controlled through 2 sets of registers
         * the below configuration configures mainly initial LED status
         */
-       kw_config_gpio(LSXL_OE_VAL_LOW,
-                       LSXL_OE_VAL_HIGH,
-                       LSXL_OE_LOW, LSXL_OE_HIGH);
+       mvebu_config_gpio(LSXL_OE_VAL_LOW,
+                         LSXL_OE_VAL_HIGH,
+                         LSXL_OE_LOW, LSXL_OE_HIGH);
 
        /*
         * Multi-Purpose Pins Functionality configuration
@@ -167,7 +168,7 @@ static void set_led(int state)
 int board_init(void)
 {
        /* address of boot parameters */
-       gd->bd->bi_boot_params = kw_sdram_bar(0) + 0x100;
+       gd->bd->bi_boot_params = mvebu_sdram_bar(0) + 0x100;
 
        set_led(LED_POWER_BLINKING);
 
index 4f2ac898ebcf3c52ebcb78aef0345612a5d94e0d..27ebe78eb139184cf3687832d13d467ece6ddb20 100644 (file)
@@ -12,4 +12,4 @@
 # SPDX-License-Identifier:     GPL-2.0+
 #
 
-obj-y  += coreboot_start.o
+obj-y  += coreboot_start.o coreboot.o
diff --git a/board/chromebook-x86/coreboot/coreboot.c b/board/chromebook-x86/coreboot/coreboot.c
new file mode 100644 (file)
index 0000000..0240c34
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ * Copyright (C) 2013 Google, Inc
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <cros_ec.h>
+
+int arch_early_init_r(void)
+{
+       if (cros_ec_board_init())
+               return -1;
+
+       return 0;
+}
index 0e632582d3dcae7c5a0d36e13fc7cfa15fe5079b..8309d06882e39db567488107608745fd8d694ff7 100644 (file)
@@ -13,7 +13,7 @@
 #include <common.h>
 #include <miiphy.h>
 #include <asm/arch/cpu.h>
-#include <asm/arch/kirkwood.h>
+#include <asm/arch/soc.h>
 #include <asm/arch/mpp.h>
 #include "pogo_e02.h"
 
@@ -26,9 +26,9 @@ int board_early_init_f(void)
         * There are maximum 64 gpios controlled through 2 sets of registers
         * the  below configuration configures mainly initial LED status
         */
-       kw_config_gpio(POGO_E02_OE_VAL_LOW,
-                       POGO_E02_OE_VAL_HIGH,
-                       POGO_E02_OE_LOW, POGO_E02_OE_HIGH);
+       mvebu_config_gpio(POGO_E02_OE_VAL_LOW,
+                         POGO_E02_OE_VAL_HIGH,
+                         POGO_E02_OE_LOW, POGO_E02_OE_HIGH);
 
        /* Multi-Purpose Pins Functionality configuration */
        static const u32 kwmpp_config[] = {
@@ -64,7 +64,7 @@ int board_early_init_f(void)
 int board_init(void)
 {
        /* Boot parameters address */
-       gd->bd->bi_boot_params = kw_sdram_bar(0) + 0x100;
+       gd->bd->bi_boot_params = mvebu_sdram_bar(0) + 0x100;
 
        return 0;
 }
index fdb8ebf9e75567c41965d4018b306f2266ffc5e8..82681b10eb8cef4d92f80a751ad99a2360271a37 100644 (file)
@@ -9,6 +9,7 @@
  */
 
 #include <common.h>
+#include <dm.h>
 #include <fsl_esdhc.h>
 #include <miiphy.h>
 #include <netdev.h>
@@ -21,6 +22,7 @@
 #include <asm/imx-common/sata.h>
 #include <asm/io.h>
 #include <asm/gpio.h>
+#include <dm/platform_data/serial_mxc.h>
 #include "common.h"
 #include "../common/eeprom.h"
 
@@ -69,16 +71,23 @@ static iomux_v3_cfg_t const sata_pads[] = {
        IOMUX_PADS(PAD_EIM_BCLK__GPIO6_IO31   | MUX_PAD_CTRL(NO_PAD_CTRL)),
 };
 
-static void cm_fx6_setup_issd(void)
+static int cm_fx6_setup_issd(void)
 {
+       int ret, i;
+
        SETUP_IOMUX_PADS(sata_pads);
-       /* Make sure this gpio has logical 0 value */
-       gpio_direction_output(CM_FX6_SATA_PWLOSS_INT, 0);
-       udelay(100);
 
-       cm_fx6_sata_power(0);
-       mdelay(250);
-       cm_fx6_sata_power(1);
+       for (i = 0; i < ARRAY_SIZE(cm_fx6_issd_gpios); i++) {
+               ret = gpio_request(cm_fx6_issd_gpios[i], "sata");
+               if (ret)
+                       return ret;
+       }
+
+       ret = gpio_request(CM_FX6_SATA_PWLOSS_INT, "sata_pwloss_int");
+       if (ret)
+               return ret;
+
+       return 0;
 }
 
 #define CM_FX6_SATA_INIT_RETRIES       10
@@ -86,7 +95,14 @@ int sata_initialize(void)
 {
        int err, i;
 
-       cm_fx6_setup_issd();
+       /* Make sure this gpio has logical 0 value */
+       gpio_direction_output(CM_FX6_SATA_PWLOSS_INT, 0);
+       udelay(100);
+
+       cm_fx6_sata_power(0);
+       mdelay(250);
+       cm_fx6_sata_power(1);
+
        for (i = 0; i < CM_FX6_SATA_INIT_RETRIES; i++) {
                err = setup_sata();
                if (err) {
@@ -109,6 +125,8 @@ int sata_initialize(void)
 
        return err;
 }
+#else
+static int cm_fx6_setup_issd(void) { return 0; }
 #endif
 
 #ifdef CONFIG_SYS_I2C_MXC
@@ -141,49 +159,68 @@ I2C_PADS(i2c2_pads,
         IMX_GPIO_NR(1, 6));
 
 
-static void cm_fx6_setup_i2c(void)
+static int cm_fx6_setup_one_i2c(int busnum, struct i2c_pads_info *pads)
+{
+       int ret;
+
+       ret = setup_i2c(busnum, CONFIG_SYS_I2C_SPEED, 0x7f, pads);
+       if (ret)
+               printf("Warning: I2C%d setup failed: %d\n", busnum, ret);
+
+       return ret;
+}
+
+static int cm_fx6_setup_i2c(void)
 {
-       setup_i2c(0, CONFIG_SYS_I2C_SPEED, 0x7f, I2C_PADS_INFO(i2c0_pads));
-       setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, I2C_PADS_INFO(i2c1_pads));
-       setup_i2c(2, CONFIG_SYS_I2C_SPEED, 0x7f, I2C_PADS_INFO(i2c2_pads));
+       int ret = 0, err;
+
+       /* i2c<x>_pads are wierd macro variables; we can't use an array */
+       err = cm_fx6_setup_one_i2c(0, I2C_PADS_INFO(i2c0_pads));
+       if (err)
+               ret = err;
+       err = cm_fx6_setup_one_i2c(1, I2C_PADS_INFO(i2c1_pads));
+       if (err)
+               ret = err;
+       err = cm_fx6_setup_one_i2c(2, I2C_PADS_INFO(i2c2_pads));
+       if (err)
+               ret = err;
+
+       return ret;
 }
 #else
-static void cm_fx6_setup_i2c(void) { }
+static int cm_fx6_setup_i2c(void) { return 0; }
 #endif
 
 #ifdef CONFIG_USB_EHCI_MX6
 #define WEAK_PULLDOWN  (PAD_CTL_PUS_100K_DOWN |                \
                        PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | \
                        PAD_CTL_HYS | PAD_CTL_SRE_SLOW)
+#define MX6_USBNC_BASEADDR     0x2184800
+#define USBNC_USB_H1_PWR_POL   (1 << 9)
 
-static int cm_fx6_usb_hub_reset(void)
+static int cm_fx6_setup_usb_host(void)
 {
        int err;
 
        err = gpio_request(CM_FX6_USB_HUB_RST, "usb hub rst");
-       if (err) {
-               printf("USB hub rst gpio request failed: %d\n", err);
-               return -1;
-       }
+       if (err)
+               return err;
 
+       SETUP_IOMUX_PAD(PAD_GPIO_0__USB_H1_PWR | MUX_PAD_CTRL(NO_PAD_CTRL));
        SETUP_IOMUX_PAD(PAD_SD3_RST__GPIO7_IO08 | MUX_PAD_CTRL(NO_PAD_CTRL));
-       gpio_direction_output(CM_FX6_USB_HUB_RST, 0);
-       udelay(10);
-       gpio_direction_output(CM_FX6_USB_HUB_RST, 1);
-       mdelay(1);
 
        return 0;
 }
 
-static int cm_fx6_init_usb_otg(void)
+static int cm_fx6_setup_usb_otg(void)
 {
-       int ret;
+       int err;
        struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
 
-       ret = gpio_request(SB_FX6_USB_OTG_PWR, "usb-pwr");
-       if (ret) {
-               printf("USB OTG pwr gpio request failed: %d\n", ret);
-               return ret;
+       err = gpio_request(SB_FX6_USB_OTG_PWR, "usb-pwr");
+       if (err) {
+               printf("USB OTG pwr gpio request failed: %d\n", err);
+               return err;
        }
 
        SETUP_IOMUX_PAD(PAD_EIM_D22__GPIO3_IO22 | MUX_PAD_CTRL(NO_PAD_CTRL));
@@ -194,25 +231,27 @@ static int cm_fx6_init_usb_otg(void)
        return gpio_direction_output(SB_FX6_USB_OTG_PWR, 0);
 }
 
-#define MX6_USBNC_BASEADDR     0x2184800
-#define USBNC_USB_H1_PWR_POL   (1 << 9)
 int board_ehci_hcd_init(int port)
 {
+       int ret;
        u32 *usbnc_usb_uh1_ctrl = (u32 *)(MX6_USBNC_BASEADDR + 4);
 
-       switch (port) {
-       case 0:
-               return cm_fx6_init_usb_otg();
-       case 1:
-               SETUP_IOMUX_PAD(PAD_GPIO_0__USB_H1_PWR |
-                               MUX_PAD_CTRL(NO_PAD_CTRL));
+       /* Only 1 host controller in use. port 0 is OTG & needs no attention */
+       if (port != 1)
+               return 0;
 
-               /* Set PWR polarity to match power switch's enable polarity */
-               setbits_le32(usbnc_usb_uh1_ctrl, USBNC_USB_H1_PWR_POL);
-               return cm_fx6_usb_hub_reset();
-       default:
-               break;
-       }
+       /* Set PWR polarity to match power switch's enable polarity */
+       setbits_le32(usbnc_usb_uh1_ctrl, USBNC_USB_H1_PWR_POL);
+       ret = gpio_direction_output(CM_FX6_USB_HUB_RST, 0);
+       if (ret)
+               return ret;
+
+       udelay(10);
+       ret = gpio_direction_output(CM_FX6_USB_HUB_RST, 1);
+       if (ret)
+               return ret;
+
+       mdelay(1);
 
        return 0;
 }
@@ -224,6 +263,9 @@ int board_ehci_power(int port, int on)
 
        return 0;
 }
+#else
+static int cm_fx6_setup_usb_otg(void) { return 0; }
+static int cm_fx6_setup_usb_host(void) { return 0; }
 #endif
 
 #ifdef CONFIG_FEC_MXC
@@ -318,12 +360,17 @@ static int handle_mac_address(void)
 
 int board_eth_init(bd_t *bis)
 {
-       int res = handle_mac_address();
-       if (res)
+       int err;
+
+       err = handle_mac_address();
+       if (err)
                puts("No MAC address found\n");
 
        SETUP_IOMUX_PADS(enet_pads);
        /* phy reset */
+       err = gpio_request(CM_FX6_ENET_NRST, "enet_nrst");
+       if (err)
+               printf("Etnernet NRST gpio request failed: %d\n", err);
        gpio_direction_output(CM_FX6_ENET_NRST, 0);
        udelay(500);
        gpio_set_value(CM_FX6_ENET_NRST, 1);
@@ -394,6 +441,16 @@ int board_mmc_init(bd_t *bis)
 }
 #endif
 
+#ifdef CONFIG_MXC_SPI
+int cm_fx6_setup_ecspi(void)
+{
+       cm_fx6_set_ecspi_iomux();
+       return gpio_request(CM_FX6_ECSPI_BUS0_CS0, "ecspi_bus0_cs0");
+}
+#else
+int cm_fx6_setup_ecspi(void) { return 0; }
+#endif
+
 #ifdef CONFIG_OF_BOARD_SETUP
 void ft_board_setup(void *blob, bd_t *bd)
 {
@@ -409,9 +466,37 @@ void ft_board_setup(void *blob, bd_t *bd)
 
 int board_init(void)
 {
+       int ret;
+
        gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100;
        cm_fx6_setup_gpmi_nand();
-       cm_fx6_setup_i2c();
+
+       ret = cm_fx6_setup_ecspi();
+       if (ret)
+               printf("Warning: ECSPI setup failed: %d\n", ret);
+
+       ret = cm_fx6_setup_usb_otg();
+       if (ret)
+               printf("Warning: USB OTG setup failed: %d\n", ret);
+
+       ret = cm_fx6_setup_usb_host();
+       if (ret)
+               printf("Warning: USB host setup failed: %d\n", ret);
+
+       /*
+        * cm-fx6 may have iSSD not assembled and in this case it has
+        * bypasses for a (m)SATA socket on the baseboard. The socketed
+        * device is not controlled by those GPIOs. So just print a warning
+        * if the setup fails.
+        */
+       ret = cm_fx6_setup_issd();
+       if (ret)
+               printf("Warning: iSSD setup failed: %d\n", ret);
+
+       /* Warn on failure but do not abort boot */
+       ret = cm_fx6_setup_i2c();
+       if (ret)
+               printf("Warning: I2C setup failed: %d\n", ret);
 
        return 0;
 }
@@ -481,3 +566,11 @@ u32 get_board_rev(void)
        return cl_eeprom_get_board_rev();
 }
 
+static struct mxc_serial_platdata cm_fx6_mxc_serial_plat = {
+       .reg = (struct mxc_uart *)UART4_BASE,
+};
+
+U_BOOT_DEVICE(cm_fx6_serial) = {
+       .name   = "serial_mxc",
+       .platdata = &cm_fx6_mxc_serial_plat,
+};
index 0944903ec8882005b096d8ca7c8750dd1d8a53d8..d0b0930f423ad633cce8aee1cd05a5ee032de64c 100644 (file)
@@ -53,16 +53,6 @@ static u32 gpmc_net_config[GPMC_MAX_REG] = {
        0
 };
 
-static u32 gpmc_nand_config[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,
-};
-
 #ifdef CONFIG_LCD
 #ifdef CONFIG_CMD_NAND
 static int splash_load_from_nand(u32 bmp_load_addr)
@@ -148,9 +138,6 @@ int board_init(void)
 {
        gpmc_init(); /* in SRAM or SDRAM, finish GPMC */
 
-       enable_gpmc_cs_config(gpmc_nand_config, &gpmc_cfg->cs[0],
-                             CONFIG_SYS_NAND_BASE, GPMC_SIZE_16M);
-
        /* board id for Linux */
        if (get_cpu_family() == CPU_OMAP34XX)
                gd->bd->bi_arch_number = MACH_TYPE_CM_T35;
@@ -381,7 +368,7 @@ static void cm_t3x_set_common_muxconf(void)
        MUX_VAL(CP(SYS_OFF_MODE),       (IEN  | PTD | DIS | M0)); /*OFF_MODE*/
        MUX_VAL(CP(SYS_CLKOUT1),        (IEN  | PTD | DIS | M0)); /*CLKOUT1*/
        MUX_VAL(CP(SYS_CLKOUT2),        (IDIS | PTU | DIS | M4)); /*green LED*/
-       MUX_VAL(CP(JTAG_nTRST),         (IEN  | PTD | DIS | M0)); /*JTAG_nTRST*/
+       MUX_VAL(CP(JTAG_NTRST),         (IEN  | PTD | DIS | M0)); /*JTAG_NTRST*/
        MUX_VAL(CP(JTAG_TCK),           (IEN  | PTD | DIS | M0)); /*JTAG_TCK*/
        MUX_VAL(CP(JTAG_TMS),           (IEN  | PTD | DIS | M0)); /*JTAG_TMS*/
        MUX_VAL(CP(JTAG_TDI),           (IEN  | PTD | DIS | M0)); /*JTAG_TDI*/
@@ -457,6 +444,8 @@ void set_muxconf_regs(void)
 }
 
 #if defined(CONFIG_GENERIC_MMC) && !defined(CONFIG_SPL_BUILD)
+#define SB_T35_WP_GPIO 59
+
 int board_mmc_getcd(struct mmc *mmc)
 {
        u8 val;
@@ -469,7 +458,7 @@ int board_mmc_getcd(struct mmc *mmc)
 
 int board_mmc_init(bd_t *bis)
 {
-       return omap_mmc_init(0, 0, 0, -1, 59);
+       return omap_mmc_init(0, 0, 0, -1, SB_T35_WP_GPIO);
 }
 #endif
 
index ff70e9415f0900b466c34ec7d76239334f91b3d8..a022daf71e419bc87b707aeaf35ea7813d6e13fe 100644 (file)
@@ -14,7 +14,7 @@
 #include <miiphy.h>
 #include <netdev.h>
 #include <asm/arch/cpu.h>
-#include <asm/arch/kirkwood.h>
+#include <asm/arch/soc.h>
 #include <asm/arch/mpp.h>
 #include <asm/arch/gpio.h>
 #include "dns325.h"
@@ -24,8 +24,8 @@ DECLARE_GLOBAL_DATA_PTR;
 int board_early_init_f(void)
 {
        /* Gpio configuration */
-       kw_config_gpio(DNS325_OE_VAL_LOW, DNS325_OE_VAL_HIGH,
-                       DNS325_OE_LOW, DNS325_OE_HIGH);
+       mvebu_config_gpio(DNS325_OE_VAL_LOW, DNS325_OE_VAL_HIGH,
+                         DNS325_OE_LOW, DNS325_OE_HIGH);
 
        /* Multi-Purpose Pins Functionality configuration */
        static const u32 kwmpp_config[] = {
@@ -92,7 +92,7 @@ int board_early_init_f(void)
 int board_init(void)
 {
        /* Boot parameters address */
-       gd->bd->bi_boot_params = kw_sdram_bar(0) + 0x100;
+       gd->bd->bi_boot_params = mvebu_sdram_bar(0) + 0x100;
 
        return 0;
 }
index ccf45131b8735da2a8081a6de39ddd1e393a7e54..e30e94471b1d2feb6f3447ed093e606db93ec866 100644 (file)
@@ -5,3 +5,4 @@ F:      board/freescale/ls1021aqds/
 F:     include/configs/ls1021aqds.h
 F:     configs/ls1021aqds_nor_defconfig
 F:     configs/ls1021aqds_ddr4_nor_defconfig
+F:     configs/ls1021aqds_nor_SECURE_BOOT_defconfig
index 12e83f764546e5ae5b372de84b569036c9373079..5fafc8567207d3d777f40567dfb90aec92670196 100644 (file)
@@ -13,6 +13,7 @@
 #include <mmc.h>
 #include <fsl_esdhc.h>
 #include <fsl_ifc.h>
+#include <fsl_sec.h>
 
 #include "../common/qixis.h"
 #include "ls1021aqds_qixis.h"
@@ -213,6 +214,15 @@ int config_serdes_mux(void)
        return 0;
 }
 
+#if defined(CONFIG_MISC_INIT_R)
+int misc_init_r(void)
+{
+#ifdef CONFIG_FSL_CAAM
+       return sec_init();
+#endif
+}
+#endif
+
 int board_init(void)
 {
        struct ccsr_cci400 *cci = (struct ccsr_cci400 *)CONFIG_SYS_CCI400_ADDR;
index 4e5bc15a0d6cb61fb43889f270f7f58261688256..8def0e5ac4b8ba0f6f538d40d5b6a2e0fb952d69 100644 (file)
@@ -4,3 +4,4 @@ S:      Maintained
 F:     board/freescale/ls1021atwr/
 F:     include/configs/ls1021atwr.h
 F:     configs/ls1021atwr_nor_defconfig
+F:     configs/ls1021atwr_nor_SECURE_BOOT_defconfig
index b522ff28e5eb8e7c87ffd6c10430beaa5798669b..50d564055b173ddd2ee46db63b2797168e7e2544 100644 (file)
@@ -16,6 +16,7 @@
 #include <netdev.h>
 #include <fsl_mdio.h>
 #include <tsec.h>
+#include <fsl_sec.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -280,6 +281,15 @@ int board_init(void)
        return 0;
 }
 
+#if defined(CONFIG_MISC_INIT_R)
+int misc_init_r(void)
+{
+#ifdef CONFIG_FSL_CAAM
+       return sec_init();
+#endif
+}
+#endif
+
 void ft_board_setup(void *blob, bd_t *bd)
 {
        ft_cpu_setup(blob, bd);
index 17c122cf5093f39578b781766e333bec84fa9b26..d6c5df203e63e09c430d0133641cf7038a230905 100644 (file)
@@ -339,7 +339,7 @@ const omap3_sysinfo sysinfo = {
        MUX_VAL(CP(SYS_CLKOUT1),        (IEN  | PTD | DIS | M4))\
        MUX_VAL(CP(SYS_CLKOUT2),        (IDIS | PTU | DIS | M4))\
        /* JTAG */\
-       MUX_VAL(CP(JTAG_nTRST),         (IEN | PTU | EN  | M4)) \
+       MUX_VAL(CP(JTAG_NTRST),         (IEN | PTU | EN  | M4)) \
        MUX_VAL(CP(JTAG_TCK),           (IEN | PTU | EN  | M4)) \
        MUX_VAL(CP(JTAG_TMS),           (IEN | PTU | EN  | M4)) \
        MUX_VAL(CP(JTAG_TDI),           (IEN | PTU | EN  | M4)) \
index c3443bdc88334f027907010ee63b59da2c97ab48..086a473e8875c98865d9d3dc64d970e93467444b 100644 (file)
@@ -9,7 +9,7 @@
 #include <common.h>
 #include <miiphy.h>
 #include <asm/arch/cpu.h>
-#include <asm/arch/kirkwood.h>
+#include <asm/arch/soc.h>
 #include <asm/arch/mpp.h>
 #include "iconnect.h"
 
@@ -22,9 +22,9 @@ int board_early_init_f(void)
         * There are maximum 64 gpios controlled through 2 sets of registers
         * the below configuration configures mainly initial LED status
         */
-       kw_config_gpio(ICONNECT_OE_VAL_LOW,
-                       ICONNECT_OE_VAL_HIGH,
-                       ICONNECT_OE_LOW, ICONNECT_OE_HIGH);
+       mvebu_config_gpio(ICONNECT_OE_VAL_LOW,
+                         ICONNECT_OE_VAL_HIGH,
+                         ICONNECT_OE_LOW, ICONNECT_OE_HIGH);
 
        /* Multi-Purpose Pins Functionality configuration */
        static const u32 kwmpp_config[] = {
@@ -87,7 +87,7 @@ int board_early_init_f(void)
 int board_init(void)
 {
        /* adress of boot parameters */
-       gd->bd->bi_boot_params = kw_sdram_bar(0) + 0x100;
+       gd->bd->bi_boot_params = mvebu_sdram_bar(0) + 0x100;
 
        return 0;
 }
index 3b2b1f15b8e9647fe0fc72efee1e8f78fa11b588..7b87cc27c41b4e517753342202f240e7ff5668b4 100644 (file)
@@ -5,6 +5,8 @@
  * SPDX-License-Identifier:    GPL-2.0+
  */
 #include <common.h>
+#include <dm.h>
+#include <ns16550.h>
 #include <twl4030.h>
 #include <netdev.h>
 #include <asm/gpio.h>
@@ -30,6 +32,17 @@ static const u32 gpmc_lan_config[] = {
 };
 #endif
 
+static const struct ns16550_platdata igep_serial = {
+       OMAP34XX_UART3,
+       2,
+       V_NS16550_CLK
+};
+
+U_BOOT_DEVICE(igep_uart) = {
+       "serial_omap",
+       &igep_serial
+};
+
 /*
  * Routine: board_init
  * Description: Early hardware init.
index ed0575cb05a26a6c4a77c6635bdc88ba04f91f9d..35546d24e87560454d3a4a047b76899cd1318413 100644 (file)
@@ -8,7 +8,7 @@
 #include <common.h>
 #include <miiphy.h>
 #include <asm/arch/cpu.h>
-#include <asm/arch/kirkwood.h>
+#include <asm/arch/soc.h>
 #include <asm/arch/mpp.h>
 #include <asm/io.h>
 
@@ -26,9 +26,9 @@ int board_early_init_f(void)
         * There are maximum 64 gpios controlled through 2 sets of registers
         * the  below configuration configures mainly initial LED status
         */
-       kw_config_gpio(TK71_OE_VAL_LOW,
-                       TK71_OE_VAL_HIGH,
-                       TK71_OE_LOW, TK71_OE_HIGH);
+       mvebu_config_gpio(TK71_OE_VAL_LOW,
+                         TK71_OE_VAL_HIGH,
+                         TK71_OE_LOW, TK71_OE_HIGH);
 
        /* Multi-Purpose Pins Functionality configuration */
        static const u32 kwmpp_config[] = {
@@ -97,7 +97,7 @@ int board_init(void)
        gd->bd->bi_arch_number = CONFIG_MACH_TYPE;
 
        /* adress of boot parameters */
-       gd->bd->bi_boot_params = kw_sdram_bar(0) + 0x100;
+       gd->bd->bi_boot_params = mvebu_sdram_bar(0) + 0x100;
 
        return 0;
 }
index 35402c800bd31df15c7162e03a7c327c50878bb7..1c7c108cb5acd7536e0081a7d2a7f40a7eb23a74 100644 (file)
@@ -20,7 +20,7 @@
 #include <spi.h>
 #include <asm/io.h>
 #include <asm/arch/cpu.h>
-#include <asm/arch/kirkwood.h>
+#include <asm/arch/soc.h>
 #include <asm/arch/mpp.h>
 
 #include "../common/common.h"
@@ -222,11 +222,11 @@ int board_early_init_f(void)
        u32 tmp;
 
        /* set the 2 bitbang i2c pins as output gpios */
-       tmp = readl(KW_GPIO0_BASE + 4);
-       writel(tmp & (~KM_KIRKWOOD_SOFT_I2C_GPIOS) , KW_GPIO0_BASE + 4);
+       tmp = readl(MVEBU_GPIO0_BASE + 4);
+       writel(tmp & (~KM_KIRKWOOD_SOFT_I2C_GPIOS) , MVEBU_GPIO0_BASE + 4);
 #endif
        /* adjust SDRAM size for bank 0 */
-       kw_sdram_size_adjust(0);
+       mvebu_sdram_size_adjust(0);
        kirkwood_mpp_conf(kwmpp_config, NULL);
        return 0;
 }
@@ -234,7 +234,7 @@ int board_early_init_f(void)
 int board_init(void)
 {
        /* address of boot parameters */
-       gd->bd->bi_boot_params = kw_sdram_bar(0) + 0x100;
+       gd->bd->bi_boot_params = mvebu_sdram_bar(0) + 0x100;
 
        /*
         * The KM_FLASH_GPIO_PIN switches between using a
index d407d66ae69b3e8f5ff98921cb7652255be78470..a6a55eef4918a165eb27d64a26a3839020e1ec94 100644 (file)
@@ -333,7 +333,7 @@ const omap3_sysinfo sysinfo = {
        MUX_VAL(CP(SYS_CLKOUT1),        (IEN  | PTD | DIS | M0)) \
        MUX_VAL(CP(SYS_CLKOUT2),        (IEN  | PTU | EN  | M0)) \
        /* JTAG */\
-       MUX_VAL(CP(JTAG_nTRST),         (IEN  | PTD | DIS | M0)) \
+       MUX_VAL(CP(JTAG_NTRST),         (IEN  | PTD | DIS | M0)) \
        MUX_VAL(CP(JTAG_TCK),           (IEN  | PTD | DIS | M0)) \
        MUX_VAL(CP(JTAG_TMS),           (IEN  | PTD | DIS | M0)) \
        MUX_VAL(CP(JTAG_TDI),           (IEN  | PTD | DIS | M0)) \
index 075fe949ae442f2437f2cb2c88d2778a4fec35c3..1fd9f2cf01cd612dbee9036e463998e24119fa54 100644 (file)
@@ -230,6 +230,6 @@ void set_muxconf_regs(void)
        MUX_VAL(CP(SYS_OFF_MODE),       (IEN  | PTD | DIS | M0));
        MUX_VAL(CP(SYS_CLKOUT1),        (IEN  | PTD | DIS | M0));
        MUX_VAL(CP(SYS_CLKOUT2),        (IEN  | PTU | EN  | M0));
-       MUX_VAL(CP(JTAG_nTRST),         (IEN  | PTD | DIS | M0));
+       MUX_VAL(CP(JTAG_NTRST),         (IEN  | PTD | DIS | M0));
        MUX_VAL(CP(SDRC_CKE0),          (IDIS | PTU | EN  | M0));
 }
index 461a852724eb6d7a76dd79d785599a26300a8fcb..9ef002637a665f7e405e5873bddee8f640da49af 100644 (file)
@@ -15,6 +15,8 @@
  * SPDX-License-Identifier:    GPL-2.0+
  */
 #include <common.h>
+#include <dm.h>
+#include <ns16550.h>
 #include <netdev.h>
 #include <twl4030.h>
 #include <asm/io.h>
@@ -41,6 +43,17 @@ static const u32 gpmc_lab_enet[] = {
        /*CONF7- computed as params */
 };
 
+static const struct ns16550_platdata zoom1_serial = {
+       OMAP34XX_UART3,
+       2,
+       V_NS16550_CLK
+};
+
+U_BOOT_DEVICE(zoom1_uart) = {
+       "serial_omap",
+       &zoom1_serial
+};
+
 /*
  * Routine: board_init
  * Description: Early hardware init.
diff --git a/board/maxbcm/Kconfig b/board/maxbcm/Kconfig
new file mode 100644 (file)
index 0000000..d34e2ab
--- /dev/null
@@ -0,0 +1,19 @@
+if TARGET_MAXBCM
+
+config SYS_CPU
+       string
+       default "armv7"
+
+config SYS_BOARD
+       string
+       default "maxbcm"
+
+config SYS_SOC
+       string
+       default "armada-xp"
+
+config SYS_CONFIG_NAME
+       string
+       default "maxbcm"
+
+endif
diff --git a/board/maxbcm/MAINTAINERS b/board/maxbcm/MAINTAINERS
new file mode 100644 (file)
index 0000000..3c8af21
--- /dev/null
@@ -0,0 +1,6 @@
+MAXBCM BOARD
+M:     Stefan Roese <sr@denx.de>
+S:     Maintained
+F:     board/maxbcm/
+F:     include/configs/maxbcm.h
+F:     configs/maxbcm_defconfig
diff --git a/board/maxbcm/Makefile b/board/maxbcm/Makefile
new file mode 100644 (file)
index 0000000..37c17d6
--- /dev/null
@@ -0,0 +1,7 @@
+#
+# Copyright (C) 2014 Stefan Roese <sr@denx.de>
+#
+# SPDX-License-Identifier:     GPL-2.0+
+#
+
+obj-y  := maxbcm.o
diff --git a/board/maxbcm/kwbimage.cfg b/board/maxbcm/kwbimage.cfg
new file mode 100644 (file)
index 0000000..5a3bc67
--- /dev/null
@@ -0,0 +1,12 @@
+#
+# Copyright (C) 2014 Stefan Roese <sr@denx.de>
+#
+
+# Armada XP uses version 1 image format
+VERSION                1
+
+# Boot Media configurations
+BOOT_FROM      spi
+
+# Binary Header (bin_hdr) with DDR3 training code
+BINARY board/maxbcm/binary.0 0000005b 00000068
diff --git a/board/maxbcm/maxbcm.c b/board/maxbcm/maxbcm.c
new file mode 100644 (file)
index 0000000..7fc83ee
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2014 Stefan Roese <sr@denx.de>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <miiphy.h>
+#include <asm/io.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/soc.h>
+#include <linux/mbus.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* Base addresses for the external device chip selects */
+#define DEV_CS0_BASE           0xe0000000
+#define DEV_CS1_BASE           0xe1000000
+#define DEV_CS2_BASE           0xe2000000
+#define DEV_CS3_BASE           0xe3000000
+
+/* Needed for dynamic (board-specific) mbus configuration */
+extern struct mvebu_mbus_state mbus_state;
+
+int board_early_init_f(void)
+{
+       /*
+        * Don't configure MPP (pin multiplexing) and GPIO here,
+        * its already done in bin_hdr
+        */
+
+       /*
+        * Setup some board specific mbus address windows
+        */
+       mbus_dt_setup_win(&mbus_state, DEV_CS0_BASE, 16 << 20,
+                         CPU_TARGET_DEVICEBUS_BOOTROM_SPI, CPU_ATTR_DEV_CS0);
+       mbus_dt_setup_win(&mbus_state, DEV_CS1_BASE, 16 << 20,
+                         CPU_TARGET_DEVICEBUS_BOOTROM_SPI, CPU_ATTR_DEV_CS1);
+       mbus_dt_setup_win(&mbus_state, DEV_CS2_BASE, 16 << 20,
+                         CPU_TARGET_DEVICEBUS_BOOTROM_SPI, CPU_ATTR_DEV_CS2);
+       mbus_dt_setup_win(&mbus_state, DEV_CS3_BASE, 16 << 20,
+                         CPU_TARGET_DEVICEBUS_BOOTROM_SPI, CPU_ATTR_DEV_CS3);
+
+       return 0;
+}
+
+int board_init(void)
+{
+       /* adress of boot parameters */
+       gd->bd->bi_boot_params = mvebu_sdram_bar(0) + 0x100;
+
+       return 0;
+}
+
+int checkboard(void)
+{
+       puts("Board: maxBCM\n");
+
+       return 0;
+}
+
+#ifdef CONFIG_RESET_PHY_R
+/* Configure and enable MV88E6185 switch */
+void reset_phy(void)
+{
+       u16 devadr = CONFIG_PHY_BASE_ADDR;
+       char *name = "neta0";
+       u16 reg;
+
+       if (miiphy_set_current_dev(name))
+               return;
+
+       /* todo: fill this with the real setup / config code */
+
+       printf("88E6185 Initialized on %s\n", name);
+}
+#endif /* CONFIG_RESET_PHY_R */
index d01abcee13c14121dfd8db0eeea8f21440b36363..51125df34f018b79a511b44dc49e73a817944a43 100644 (file)
@@ -47,46 +47,19 @@ const struct tegra_sysinfo sysinfo = {
        CONFIG_TEGRA_BOARD_STRING
 };
 
-void __pinmux_init(void)
-{
-}
-
-void pinmux_init(void) __attribute__((weak, alias("__pinmux_init")));
-
-void __pin_mux_usb(void)
-{
-}
-
-void pin_mux_usb(void) __attribute__((weak, alias("__pin_mux_usb")));
-
-void __pin_mux_spi(void)
-{
-}
-
-void pin_mux_spi(void) __attribute__((weak, alias("__pin_mux_spi")));
-
-void __gpio_early_init_uart(void)
-{
-}
-
-void gpio_early_init_uart(void)
-__attribute__((weak, alias("__gpio_early_init_uart")));
+__weak void pinmux_init(void) {}
+__weak void pin_mux_usb(void) {}
+__weak void pin_mux_spi(void) {}
+__weak void gpio_early_init_uart(void) {}
+__weak void pin_mux_display(void) {}
 
 #if defined(CONFIG_TEGRA_NAND)
-void __pin_mux_nand(void)
+__weak void pin_mux_nand(void)
 {
        funcmux_select(PERIPH_ID_NDFLASH, FUNCMUX_DEFAULT);
 }
-
-void pin_mux_nand(void) __attribute__((weak, alias("__pin_mux_nand")));
 #endif
 
-void __pin_mux_display(void)
-{
-}
-
-void pin_mux_display(void) __attribute__((weak, alias("__pin_mux_display")));
-
 /*
  * Routine: power_det_init
  * Description: turn off power detects
@@ -114,9 +87,8 @@ int board_init(void)
        clock_init();
        clock_verify();
 
-#ifdef CONFIG_FDT_SPI
+#ifdef CONFIG_TEGRA_SPI
        pin_mux_spi();
-       spi_init();
 #endif
 
 #ifdef CONFIG_PWM_TEGRA
@@ -205,12 +177,10 @@ int board_late_init(void)
 }
 
 #if defined(CONFIG_TEGRA_MMC)
-void __pin_mux_mmc(void)
+__weak void pin_mux_mmc(void)
 {
 }
 
-void pin_mux_mmc(void) __attribute__((weak, alias("__pin_mux_mmc")));
-
 /* this is a weak define that we are overriding */
 int board_mmc_init(bd_t *bd)
 {
index 8124f8aafde0671e48d0abe770cedcd6bf868c25..8c62f36a7b04a00b8d05f68405567f9d3e1fd687 100644 (file)
@@ -5,6 +5,7 @@
  */
 
 #include <common.h>
+#include "emc.h"
 #include <asm/io.h>
 #include <asm/arch/clock.h>
 #include <asm/arch/emc.h>
index d338818a64eb898697db9ac014fb392fea858674..de4eb355982cb2b1821849407f635caf65d3759b 100644 (file)
@@ -283,6 +283,11 @@ static const struct pmux_pingrp_config jetson_tk1_pingrps[] = {
        PINCFG(PCC2,                   DEFAULT,      DOWN,   NORMAL,   INPUT,   DEFAULT, DEFAULT),
        PINCFG(SDMMC4_CLK_PCC4,        SDMMC4,       NORMAL, NORMAL,   INPUT,   DEFAULT, DEFAULT),
        PINCFG(CLK2_REQ_PCC5,          DEFAULT,      NORMAL, NORMAL,   OUTPUT,  DEFAULT, DEFAULT),
+       PINCFG(PEX_L0_RST_N_PDD1,      PE0,          NORMAL, NORMAL,   OUTPUT,  DEFAULT, DEFAULT),
+       PINCFG(PEX_L0_CLKREQ_N_PDD2,   PE0,          UP,     NORMAL,   INPUT,   DEFAULT, DEFAULT),
+       PINCFG(PEX_WAKE_N_PDD3,        PE,           UP,     NORMAL,   INPUT,   DEFAULT, DEFAULT),
+       PINCFG(PEX_L1_RST_N_PDD5,      PE1,          NORMAL, NORMAL,   OUTPUT,  DEFAULT, DEFAULT),
+       PINCFG(PEX_L1_CLKREQ_N_PDD6,   PE1,          UP,     NORMAL,   INPUT,   DEFAULT, DEFAULT),
        PINCFG(CLK3_OUT_PEE0,          EXTPERIPH3,   NORMAL, NORMAL,   OUTPUT,  DEFAULT, DEFAULT),
        PINCFG(CLK3_REQ_PEE1,          DEFAULT,      NORMAL, NORMAL,   OUTPUT,  DEFAULT, DEFAULT),
        PINCFG(DAP_MCLK1_REQ_PEE2,     SATA,         NORMAL, NORMAL,   OUTPUT,  DEFAULT, DEFAULT),
index 6a243f0aea98cb42b5fd969b16ecd9a361f2aa54..11472ebaf20d1eb385457cf8745322460e7b94bc 100644 (file)
@@ -8,6 +8,7 @@
 #include <common.h>
 #include <asm/io.h>
 #include <asm/arch/tegra.h>
+#include <asm/arch-tegra/board.h>
 #include <asm/arch/clock.h>
 #include <asm/arch/funcmux.h>
 #include <asm/arch/gpio.h>
index 13220c56dd0634dc8a1cee9538fda0dafae2302c..dfb8602bafccb8d8c912c58c7d946c06effee2c0 100644 (file)
@@ -13,6 +13,8 @@
  * SPDX-License-Identifier:    GPL-2.0+
  */
 #include <common.h>
+#include <dm.h>
+#include <ns16550.h>
 #include <netdev.h>
 #include <twl4030.h>
 #include <linux/mtd/nand.h>
 #include <asm/mach-types.h>
 #include "overo.h"
 
+#ifdef CONFIG_USB_EHCI
+#include <usb.h>
+#include <asm/ehci-omap.h>
+#endif
+
 DECLARE_GLOBAL_DATA_PTR;
 
 #define TWL4030_I2C_BUS                        0
 #define EXPANSION_EEPROM_I2C_BUS       2
 #define EXPANSION_EEPROM_I2C_ADDRESS   0x51
 
+#define GUMSTIX_EMPTY_EEPROM           0x0
+
 #define GUMSTIX_SUMMIT                 0x01000200
 #define GUMSTIX_TOBI                   0x02000200
 #define GUMSTIX_TOBI_DUO               0x03000200
@@ -56,21 +65,17 @@ static struct {
        char fab_revision[8];
        char env_var[16];
        char env_setting[64];
-} expansion_config;
+} expansion_config = {0x0};
 
-#if defined(CONFIG_CMD_NET)
-static void setup_net_chip(void);
-#endif
+static const struct ns16550_platdata overo_serial = {
+       OMAP34XX_UART3,
+       2,
+       V_NS16550_CLK
+};
 
-/* GPMC definitions for LAN9221 chips on Tobi expansion boards */
-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,
-    /*CONFIG7- computed as params */
+U_BOOT_DEVICE(overo_uart) = {
+       "serial_omap",
+       &overo_serial
 };
 
 /*
@@ -213,6 +218,9 @@ int get_sdio2_config(void)
  */
 unsigned int get_expansion_id(void)
 {
+       if (expansion_config.device_vendor != 0x0)
+               return expansion_config.device_vendor;
+
        i2c_set_bus_num(EXPANSION_EEPROM_I2C_BUS);
 
        /* return GUMSTIX_NO_EEPROM if eeprom doesn't respond */
@@ -241,10 +249,6 @@ int misc_init_r(void)
        twl4030_power_init();
        twl4030_led_init(TWL4030_LED_LEDEN_LEDAON | TWL4030_LED_LEDEN_LEDBON);
 
-#if defined(CONFIG_CMD_NET)
-       setup_net_chip();
-#endif
-
        printf("Board revision: %d\n", get_board_revision());
 
        switch (get_sdio2_config()) {
@@ -266,6 +270,7 @@ int misc_init_r(void)
                printf("Recognized Summit expansion board (rev %d %s)\n",
                        expansion_config.revision,
                        expansion_config.fab_revision);
+               MUX_GUMSTIX();
                setenv("defaultdisplay", "dvi");
                setenv("expansionname", "summit");
                break;
@@ -273,6 +278,7 @@ int misc_init_r(void)
                printf("Recognized Tobi expansion board (rev %d %s)\n",
                        expansion_config.revision,
                        expansion_config.fab_revision);
+               MUX_GUMSTIX();
                setenv("defaultdisplay", "dvi");
                setenv("expansionname", "tobi");
                break;
@@ -280,20 +286,20 @@ int misc_init_r(void)
                printf("Recognized Tobi Duo expansion board (rev %d %s)\n",
                        expansion_config.revision,
                        expansion_config.fab_revision);
-               /* second lan chip */
-               enable_gpmc_cs_config(gpmc_lan_config, &gpmc_cfg->cs[4],
-                   0x2B000000, GPMC_SIZE_16M);
+               MUX_GUMSTIX();
                break;
        case GUMSTIX_PALO35:
                printf("Recognized Palo35 expansion board (rev %d %s)\n",
                        expansion_config.revision,
                        expansion_config.fab_revision);
+               MUX_GUMSTIX();
                setenv("defaultdisplay", "lcd35");
                break;
        case GUMSTIX_PALO43:
                printf("Recognized Palo43 expansion board (rev %d %s)\n",
                        expansion_config.revision,
                        expansion_config.fab_revision);
+               MUX_GUMSTIX();
                setenv("defaultdisplay", "lcd43");
                setenv("expansionname", "palo43");
                break;
@@ -301,6 +307,7 @@ int misc_init_r(void)
                printf("Recognized Chestnut43 expansion board (rev %d %s)\n",
                        expansion_config.revision,
                        expansion_config.fab_revision);
+               MUX_GUMSTIX();
                setenv("defaultdisplay", "lcd43");
                setenv("expansionname", "chestnut43");
                break;
@@ -308,11 +315,13 @@ int misc_init_r(void)
                printf("Recognized Pinto expansion board (rev %d %s)\n",
                        expansion_config.revision,
                        expansion_config.fab_revision);
+               MUX_GUMSTIX();
                break;
        case GUMSTIX_GALLOP43:
                printf("Recognized Gallop43 expansion board (rev %d %s)\n",
                        expansion_config.revision,
                        expansion_config.fab_revision);
+               MUX_GUMSTIX();
                setenv("defaultdisplay", "lcd43");
                setenv("expansionname", "gallop43");
                break;
@@ -320,6 +329,7 @@ int misc_init_r(void)
                printf("Recognized Alto35 expansion board (rev %d %s)\n",
                        expansion_config.revision,
                        expansion_config.fab_revision);
+               MUX_GUMSTIX();
                MUX_ALTO35();
                setenv("defaultdisplay", "lcd35");
                setenv("expansionname", "alto35");
@@ -328,21 +338,25 @@ int misc_init_r(void)
                printf("Recognized Stagecoach expansion board (rev %d %s)\n",
                        expansion_config.revision,
                        expansion_config.fab_revision);
+               MUX_GUMSTIX();
                break;
        case GUMSTIX_THUMBO:
                printf("Recognized Thumbo expansion board (rev %d %s)\n",
                        expansion_config.revision,
                        expansion_config.fab_revision);
+               MUX_GUMSTIX();
                break;
        case GUMSTIX_TURTLECORE:
                printf("Recognized Turtlecore expansion board (rev %d %s)\n",
                        expansion_config.revision,
                        expansion_config.fab_revision);
+               MUX_GUMSTIX();
                break;
        case GUMSTIX_ARBOR43C:
                printf("Recognized Arbor43C expansion board (rev %d %s)\n",
                        expansion_config.revision,
                        expansion_config.fab_revision);
+               MUX_GUMSTIX();
                MUX_ARBOR43C();
                setenv("defaultdisplay", "lcd43");
                break;
@@ -350,16 +364,17 @@ int misc_init_r(void)
                printf("Recognized Ettus Research USRP-E (rev %d %s)\n",
                        expansion_config.revision,
                        expansion_config.fab_revision);
+               MUX_GUMSTIX();
                MUX_USRP_E();
                setenv("defaultdisplay", "dvi");
                break;
        case GUMSTIX_NO_EEPROM:
-               puts("No EEPROM on expansion board\n");
+       case GUMSTIX_EMPTY_EEPROM:
+               puts("No or empty EEPROM on expansion board\n");
+               MUX_GUMSTIX();
                setenv("expansionname", "tobi");
                break;
        default:
-               if (expansion_id == 0x0)
-                       setenv("expansionname", "tobi");
                printf("Unrecognized expansion board 0x%08x\n", expansion_id);
                break;
        }
@@ -388,7 +403,18 @@ void set_muxconf_regs(void)
        MUX_OVERO();
 }
 
-#if defined(CONFIG_CMD_NET)
+#if defined(CONFIG_CMD_NET) && !defined(CONFIG_SPL_BUILD)
+/* GPMC definitions for LAN9221 chips on Tobi expansion boards */
+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,
+       /*CONFIG7- computed as params */
+};
+
 /*
  * Routine: setup_net_chip
  * Description: Setting up the configuration GPMC registers specific to the
@@ -398,10 +424,6 @@ static void setup_net_chip(void)
 {
        struct ctrl *ctrl_base = (struct ctrl *)OMAP34XX_CTRL_BASE;
 
-       /* first lan chip */
-       enable_gpmc_cs_config(gpmc_lan_config, &gpmc_cfg->cs[5], 0x2C000000,
-                       GPMC_SIZE_16M);
-
        /* Enable off mode for NWE in PADCONF_GPMC_NWE register */
        writew(readw(&ctrl_base ->gpmc_nwe) | 0x0E00, &ctrl_base->gpmc_nwe);
        /* Enable off mode for NOE in PADCONF_GPMC_NADV_ALE register */
@@ -409,7 +431,14 @@ static void setup_net_chip(void)
        /* Enable off mode for ALE in PADCONF_GPMC_NADV_ALE register */
        writew(readw(&ctrl_base->gpmc_nadv_ale) | 0x0E00,
                &ctrl_base->gpmc_nadv_ale);
+}
 
+/*
+ * Routine: reset_net_chip
+ * Description: Reset the Ethernet hardware.
+ */
+static void reset_net_chip(void)
+{
        /* Make GPIO 64 as output pin and send a magic pulse through it */
        if (!gpio_request(64, "")) {
                gpio_direction_output(64, 0);
@@ -420,16 +449,42 @@ static void setup_net_chip(void)
                gpio_set_value(64, 1);
        }
 }
-#endif
 
 int board_eth_init(bd_t *bis)
 {
+       unsigned int expansion_id;
        int rc = 0;
+
 #ifdef CONFIG_SMC911X
-       rc = smc911x_initialize(0, CONFIG_SMC911X_BASE);
+       expansion_id = get_expansion_id();
+       switch (expansion_id) {
+       case GUMSTIX_TOBI_DUO:
+               /* second lan chip */
+               enable_gpmc_cs_config(gpmc_lan_config, &gpmc_cfg->cs[4],
+                                     0x2B000000, GPMC_SIZE_16M);
+               /* no break */
+       case GUMSTIX_TOBI:
+       case GUMSTIX_CHESTNUT43:
+       case GUMSTIX_STAGECOACH:
+       case GUMSTIX_NO_EEPROM:
+       case GUMSTIX_EMPTY_EEPROM:
+               /* first lan chip */
+               enable_gpmc_cs_config(gpmc_lan_config, &gpmc_cfg->cs[5],
+                                     0x2C000000, GPMC_SIZE_16M);
+
+               setup_net_chip();
+               reset_net_chip();
+
+               rc = smc911x_initialize(0, CONFIG_SMC911X_BASE);
+               break;
+       default:
+               break;
+       }
 #endif
+
        return rc;
 }
+#endif
 
 #if defined(CONFIG_GENERIC_MMC) && !defined(CONFIG_SPL_BUILD)
 int board_mmc_init(bd_t *bis)
@@ -437,3 +492,32 @@ int board_mmc_init(bd_t *bis)
        return omap_mmc_init(0, 0, 0, -1, -1);
 }
 #endif
+
+#if defined(CONFIG_USB_EHCI) &&  !defined(CONFIG_SPL_BUILD)
+static struct omap_usbhs_board_data usbhs_bdata = {
+       .port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED,
+       .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
+       .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED
+};
+
+#define GUMSTIX_GPIO_USBH_CPEN         168
+int ehci_hcd_init(int index, enum usb_init_type init,
+                 struct ehci_hccr **hccr, struct ehci_hcor **hcor)
+{
+       /* Enable USB power */
+       if (!gpio_request(GUMSTIX_GPIO_USBH_CPEN, "usbh_cpen"))
+               gpio_direction_output(GUMSTIX_GPIO_USBH_CPEN, 1);
+
+       return omap_ehci_hcd_init(index, &usbhs_bdata, hccr, hcor);
+}
+
+int ehci_hcd_stop(void)
+{
+       /* Disable USB power */
+       gpio_set_value(GUMSTIX_GPIO_USBH_CPEN, 0);
+       gpio_free(GUMSTIX_GPIO_USBH_CPEN);
+
+       return omap_ehci_hcd_stop();
+}
+
+#endif /* CONFIG_USB_EHCI */
index 57725d867f2b3fd7a34226d55a67a94dd59cd45d..d0edf86365a68e0c3a71137f6f4ebc9819ca1f76 100644 (file)
@@ -101,13 +101,9 @@ const omap3_sysinfo sysinfo = {
        MUX_VAL(CP(GPMC_D14),           (IEN  | PTU | EN  | M0)) /*GPMC_D14*/\
        MUX_VAL(CP(GPMC_D15),           (IEN  | PTU | EN  | M0)) /*GPMC_D15*/\
        MUX_VAL(CP(GPMC_NCS0),          (IDIS | PTU | EN  | M0)) /*GPMC_nCS0*/\
-       MUX_VAL(CP(GPMC_NCS1),          (IDIS | PTU | EN  | M0)) /*GPMC_nCS1*/\
        MUX_VAL(CP(GPMC_NCS2),          (IDIS | PTU | EN  | M0)) /*GPMC_nCS2*/\
        MUX_VAL(CP(GPMC_NCS3),          (IEN  | PTU | EN  | M4)) /*GPIO_54*/\
                                                                 /* - MMC1_WP*/\
-       MUX_VAL(CP(GPMC_NCS4),          (IDIS | PTU | EN  | M0)) /*GPMC_nCS4*/\
-       MUX_VAL(CP(GPMC_NCS5),          (IDIS | PTU | EN  | M0)) /*GPMC_nCS5*/\
-       MUX_VAL(CP(GPMC_NCS6),          (IEN  | PTD | DIS | M0)) /*GPMC_nCS6*/\
        MUX_VAL(CP(GPMC_NCS7),          (IEN  | PTU | EN  | M0)) /*GPMC_nCS7*/\
        MUX_VAL(CP(GPMC_NBE1),          (IEN  | PTD | DIS | M0)) /*GPMC_nCS3*/\
        MUX_VAL(CP(GPMC_CLK),           (IEN  | PTU | EN  | M0)) /*GPMC_CLK*/\
@@ -117,45 +113,11 @@ const omap3_sysinfo sysinfo = {
        MUX_VAL(CP(GPMC_NBE0_CLE),      (IDIS | PTD | DIS | M0)) /*GPMC_nBE0_CLE*/\
        MUX_VAL(CP(GPMC_NWP),           (IEN  | PTD | DIS | M0)) /*GPMC_nWP*/\
        MUX_VAL(CP(GPMC_WAIT0),         (IEN  | PTU | EN  | M0)) /*GPMC_WAIT0*/\
-       MUX_VAL(CP(GPMC_WAIT1),         (IEN  | PTU | EN  | M0)) /*GPMC_WAIT1*/\
-       MUX_VAL(CP(GPMC_WAIT2),         (IEN  | PTU | EN  | M4)) /*GPIO_64*/\
-                                                                /* - SMSC911X_NRES*/\
-       MUX_VAL(CP(GPMC_WAIT3),         (IEN  | PTU | DIS | M4)) /*GPIO_65*/\
- /*DSS*/\
-       MUX_VAL(CP(DSS_PCLK),           (IDIS | PTD | DIS | M0)) /*DSS_PCLK*/\
-       MUX_VAL(CP(DSS_HSYNC),          (IDIS | PTD | DIS | M0)) /*DSS_HSYNC*/\
-       MUX_VAL(CP(DSS_VSYNC),          (IDIS | PTD | DIS | M0)) /*DSS_VSYNC*/\
-       MUX_VAL(CP(DSS_ACBIAS),         (IDIS | PTD | DIS | M0)) /*DSS_ACBIAS*/\
-       MUX_VAL(CP(DSS_DATA0),          (IDIS | PTD | DIS | M0)) /*DSS_DATA0*/\
-       MUX_VAL(CP(DSS_DATA1),          (IDIS | PTD | DIS | M0)) /*DSS_DATA1*/\
-       MUX_VAL(CP(DSS_DATA2),          (IDIS | PTD | DIS | M0)) /*DSS_DATA2*/\
-       MUX_VAL(CP(DSS_DATA3),          (IDIS | PTD | DIS | M0)) /*DSS_DATA3*/\
-       MUX_VAL(CP(DSS_DATA4),          (IDIS | PTD | DIS | M0)) /*DSS_DATA4*/\
-       MUX_VAL(CP(DSS_DATA5),          (IDIS | PTD | DIS | M0)) /*DSS_DATA5*/\
-       MUX_VAL(CP(DSS_DATA6),          (IDIS | PTD | DIS | M0)) /*DSS_DATA6*/\
-       MUX_VAL(CP(DSS_DATA7),          (IDIS | PTD | DIS | M0)) /*DSS_DATA7*/\
-       MUX_VAL(CP(DSS_DATA8),          (IDIS | PTD | DIS | M0)) /*DSS_DATA8*/\
-       MUX_VAL(CP(DSS_DATA9),          (IDIS | PTD | DIS | M0)) /*DSS_DATA9*/\
-       MUX_VAL(CP(DSS_DATA10),         (IDIS | PTD | DIS | M0)) /*DSS_DATA10*/\
-       MUX_VAL(CP(DSS_DATA11),         (IDIS | PTD | DIS | M0)) /*DSS_DATA11*/\
-       MUX_VAL(CP(DSS_DATA12),         (IDIS | PTD | DIS | M0)) /*DSS_DATA12*/\
-       MUX_VAL(CP(DSS_DATA13),         (IDIS | PTD | DIS | M0)) /*DSS_DATA13*/\
-       MUX_VAL(CP(DSS_DATA14),         (IDIS | PTD | DIS | M0)) /*DSS_DATA14*/\
-       MUX_VAL(CP(DSS_DATA15),         (IDIS | PTD | DIS | M0)) /*DSS_DATA15*/\
-       MUX_VAL(CP(DSS_DATA16),         (IDIS | PTD | DIS | M0)) /*DSS_DATA16*/\
-       MUX_VAL(CP(DSS_DATA17),         (IDIS | PTD | DIS | M0)) /*DSS_DATA17*/\
-       MUX_VAL(CP(DSS_DATA18),         (IDIS | PTD | DIS | M0)) /*DSS_DATA18*/\
-       MUX_VAL(CP(DSS_DATA19),         (IDIS | PTD | DIS | M0)) /*DSS_DATA19*/\
-       MUX_VAL(CP(DSS_DATA20),         (IDIS | PTD | DIS | M0)) /*DSS_DATA20*/\
-       MUX_VAL(CP(DSS_DATA21),         (IDIS | PTD | DIS | M0)) /*DSS_DATA21*/\
-       MUX_VAL(CP(DSS_DATA22),         (IDIS | PTD | DIS | M0)) /*DSS_DATA22*/\
-       MUX_VAL(CP(DSS_DATA23),         (IDIS | PTD | DIS | M0)) /*DSS_DATA23*/\
  /*CAMERA*/\
        MUX_VAL(CP(CAM_HS),             (IEN  | PTU | DIS | M0)) /*CAM_HS */\
        MUX_VAL(CP(CAM_VS),             (IEN  | PTU | DIS | M0)) /*CAM_VS */\
        MUX_VAL(CP(CAM_XCLKA),          (IDIS | PTD | DIS | M0)) /*CAM_XCLKA*/\
        MUX_VAL(CP(CAM_PCLK),           (IEN  | PTU | DIS | M0)) /*CAM_PCLK*/\
-       MUX_VAL(CP(CAM_FLD),            (IDIS | PTD | DIS | M4)) /*CAM_FLD*/\
        MUX_VAL(CP(CAM_D0),             (IEN  | PTD | DIS | M0)) /*CAM_D0*/\
        MUX_VAL(CP(CAM_D1),             (IEN  | PTD | DIS | M0)) /*CAM_D1*/\
        MUX_VAL(CP(CAM_D2),             (IEN  | PTD | DIS | M0)) /*CAM_D2*/\
@@ -168,13 +130,8 @@ const omap3_sysinfo sysinfo = {
        MUX_VAL(CP(CAM_D9),             (IEN  | PTD | DIS | M0)) /*CAM_D9*/\
        MUX_VAL(CP(CAM_D10),            (IEN  | PTD | DIS | M0)) /*CAM_D10*/\
        MUX_VAL(CP(CAM_D11),            (IEN  | PTD | DIS | M0)) /*CAM_D11*/\
-       MUX_VAL(CP(CAM_XCLKB),          (IDIS | PTD | DIS | M0)) /*CAM_XCLKB*/\
-       MUX_VAL(CP(CAM_WEN),            (IEN  | PTD | DIS | M0)) /*CAM_WEN*/\
-       MUX_VAL(CP(CAM_STROBE),         (IDIS | PTD | DIS | M0)) /*CAM_STROBE*/\
        MUX_VAL(CP(CSI2_DX0),           (IEN  | PTD | EN  | M4)) /*GPIO_112*/\
        MUX_VAL(CP(CSI2_DY0),           (IEN  | PTD | EN  | M4)) /*GPIO_113*/\
-       MUX_VAL(CP(CSI2_DX1),           (IEN  | PTD | EN  | M4)) /*GPIO_114*/\
-                                                                /* - PEN_DOWN*/\
        MUX_VAL(CP(CSI2_DY1),           (IEN  | PTD | EN  | M4)) /*GPIO_115*/\
  /*Audio Interface */\
        MUX_VAL(CP(MCBSP2_FSX),         (IEN  | PTD | DIS | M0)) /*McBSP2_FSX*/\
@@ -208,14 +165,7 @@ const omap3_sysinfo sysinfo = {
        MUX_VAL(CP(MCBSP3_DR),          (IDIS | PTD | DIS | M1)) /*UART2_RTS*/\
        MUX_VAL(CP(MCBSP3_CLKX),        (IDIS | PTD | DIS | M1)) /*UART2_TX*/\
        MUX_VAL(CP(MCBSP3_FSX),         (IEN  | PTD | DIS | M1)) /*UART2_RX*/\
-       MUX_VAL(CP(UART2_CTS),          (IEN  | PTD | DIS | M4)) /*GPIO_144 - LCD_EN*/\
-       MUX_VAL(CP(UART2_RTS),          (IEN  | PTD | DIS | M4)) /*GPIO_145*/\
-       MUX_VAL(CP(UART2_TX),           (IEN  | PTD | DIS | M4)) /*GPIO_146*/\
-       MUX_VAL(CP(UART2_RX),           (IEN  | PTD | DIS | M4)) /*GPIO_147*/\
-       MUX_VAL(CP(UART1_TX),           (IDIS | PTD | DIS | M0)) /*UART1_TX*/\
        MUX_VAL(CP(UART1_RTS),          (IEN  | PTU | DIS | M4)) /*GPIO_149*/ \
-       MUX_VAL(CP(UART1_CTS),          (IEN  | PTU | DIS | M4)) /*GPIO_150-MMC3_WP*/\
-       MUX_VAL(CP(UART1_RX),           (IEN  | PTD | DIS | M0)) /*UART1_RX*/\
        MUX_VAL(CP(MCBSP4_CLKX),        (IEN  | PTD | DIS | M0)) /*McBSP4_CLKX*/\
        MUX_VAL(CP(MCBSP4_DR),          (IEN  | PTD | DIS | M0)) /*McBSP4_DR*/\
        MUX_VAL(CP(MCBSP4_DX),          (IEN  | PTD | DIS | M0)) /*McBSP4_DX*/\
@@ -228,7 +178,6 @@ const omap3_sysinfo sysinfo = {
        MUX_VAL(CP(MCBSP1_FSX),         (IEN  | PTD | DIS | M0)) /*McBSP1_FSX*/\
        MUX_VAL(CP(MCBSP1_CLKX),        (IEN  | PTD | DIS | M0)) /*McBSP1_CLKX*/\
  /*Serial Interface*/\
-       MUX_VAL(CP(UART3_CTS_RCTX),     (IEN  | PTD | EN  | M0)) /*UART3_CTS_RCTX*/\
        MUX_VAL(CP(UART3_RTS_SD),       (IEN  | PTU | EN  | M4)) /*GPIO_164 W2W_*/\
                                                                 /* BT_NRESET*/\
        MUX_VAL(CP(UART3_RX_IRRX),      (IEN  | PTU | EN  | M0)) /*UART3_RX_IRRX*/\
@@ -255,14 +204,6 @@ const omap3_sysinfo sysinfo = {
        MUX_VAL(CP(I2C3_SDA),           (IEN  | PTU | EN  | M0)) /*I2C3_SDA*/\
        MUX_VAL(CP(I2C4_SCL),           (IEN  | PTU | EN  | M0)) /*I2C4_SCL*/\
        MUX_VAL(CP(I2C4_SDA),           (IEN  | PTU | EN  | M0)) /*I2C4_SDA*/\
-       MUX_VAL(CP(HDQ_SIO),            (IDIS | PTU | EN  | M4)) /*HDQ_SIO*/\
-       MUX_VAL(CP(MCSPI1_CLK),         (IEN  | PTD | DIS | M0)) /*McSPI1_CLK*/\
-       MUX_VAL(CP(MCSPI1_SIMO),        (IEN  | PTD | DIS | M0)) /*McSPI1_SIMO */\
-       MUX_VAL(CP(MCSPI1_SOMI),        (IEN  | PTD | DIS | M0)) /*McSPI1_SOMI */\
-       MUX_VAL(CP(MCSPI1_CS0),         (IEN  | PTD | EN  | M0)) /*McSPI1_CS0*/\
-       MUX_VAL(CP(MCSPI1_CS1),         (IDIS | PTD | EN  | M0)) /*McSPI1_CS1*/\
-       MUX_VAL(CP(MCSPI1_CS2),         (IEN  | PTU | DIS | M4)) /*GPIO_176 */\
-                                                                /* - LAN_INTR */\
        MUX_VAL(CP(MCSPI1_CS3),         (IEN  | PTD | DIS | M3)) /*HSUSB2_DATA2*/\
        MUX_VAL(CP(MCSPI2_CLK),         (IEN  | PTD | DIS | M3)) /*HSUSB2_DATA7*/\
        MUX_VAL(CP(MCSPI2_SIMO),        (IEN  | PTD | DIS | M3)) /*HSUSB2_DATA4*/\
@@ -281,21 +222,9 @@ const omap3_sysinfo sysinfo = {
        MUX_VAL(CP(SYS_BOOT5),          (IEN  | PTD | DIS | M4)) /*GPIO_7*/\
        MUX_VAL(CP(SYS_BOOT6),          (IDIS | PTD | DIS | M4)) /*GPIO_8*/\
        MUX_VAL(CP(SYS_OFF_MODE),       (IEN  | PTD | DIS | M0)) /*SYS_OFF_MODE*/\
-       MUX_VAL(CP(SYS_CLKOUT1),        (IEN  | PTU | EN  | M4)) /*GPIO_10*/\
-       MUX_VAL(CP(SYS_CLKOUT2),        (IEN  | PTU | EN  | M4)) /*GPIO_186*/\
-       MUX_VAL(CP(ETK_CLK_ES2),        (IEN  | PTU | EN  | M2)) /*MMC3_CLK*/\
-       MUX_VAL(CP(ETK_CTL_ES2),        (IEN  | PTU | EN  | M2)) /*MMC3_CMD*/\
-       MUX_VAL(CP(ETK_D0_ES2),         (IEN  | PTU | EN  | M4)) /*GPIO_14*/\
        MUX_VAL(CP(ETK_D1_ES2),         (IEN  | PTD | EN  | M4)) /*GPIO_15 - X_GATE*/\
        MUX_VAL(CP(ETK_D2_ES2),         (IEN  | PTU | EN  | M4)) /*GPIO_16*/\
                                                                 /* - W2W_NRESET*/\
-       MUX_VAL(CP(ETK_D3_ES2),         (IEN  | PTU | EN  | M2)) /*MMC3_DAT3*/\
-       MUX_VAL(CP(ETK_D4_ES2),         (IEN  | PTU | EN  | M2)) /*MMC3_DAT0*/\
-       MUX_VAL(CP(ETK_D5_ES2),         (IEN  | PTU | EN  | M2)) /*MMC3_DAT1*/\
-       MUX_VAL(CP(ETK_D6_ES2),         (IEN  | PTU | EN  | M2)) /*MMC3_DAT2*/\
-       MUX_VAL(CP(ETK_D7_ES2),         (IEN  | PTU | EN  | M4)) /*GPIO_21*/\
-       MUX_VAL(CP(ETK_D8_ES2),         (IEN  | PTU | EN  | M4)) /*GPIO_22*/\
-       MUX_VAL(CP(ETK_D9_ES2),         (IEN  | PTU | EN  | M4)) /*GPIO_23*/\
        MUX_VAL(CP(ETK_D10_ES2),        (IDIS | PTD | DIS | M3)) /*HSUSB2_CLK*/\
        MUX_VAL(CP(ETK_D11_ES2),        (IDIS | PTD | DIS | M3)) /*HSUSB2_STP*/\
        MUX_VAL(CP(ETK_D12_ES2),        (IEN  | PTD | DIS | M3)) /*HSUSB2_DIR*/\
@@ -369,6 +298,85 @@ const omap3_sysinfo sysinfo = {
        MUX_VAL(CP(SDRC_CKE0),          (IDIS | PTU | EN  | M0)) /*sdrc_cke0*/\
        MUX_VAL(CP(SDRC_CKE1),          (IDIS | PTU | EN  | M0)) /*sdrc_cke1*/
 
+#define MUX_GUMSTIX() \
+  /*GPMC*/\
+       MUX_VAL(CP(GPMC_NCS1),          (IDIS | PTU | EN  | M0)) /*GPMC_nCS1*/\
+       MUX_VAL(CP(GPMC_NCS4),          (IDIS | PTU | EN  | M0)) /*GPMC_nCS4*/\
+       MUX_VAL(CP(GPMC_NCS5),          (IDIS | PTU | EN  | M0)) /*GPMC_nCS5*/\
+       MUX_VAL(CP(GPMC_NCS6),          (IEN  | PTD | DIS | M0)) /*GPMC_nCS6*/\
+       MUX_VAL(CP(GPMC_WAIT1),         (IEN  | PTU | EN  | M4)) /*GPIO_63*/\
+                                                                /* - CAM_IRQ*/\
+       MUX_VAL(CP(GPMC_WAIT2),         (IEN  | PTU | EN  | M4)) /*GPIO_64*/\
+                                                                /* - SMSC911X_NRES*/\
+       MUX_VAL(CP(GPMC_WAIT3),         (IEN  | PTU | DIS | M4)) /*GPIO_65*/\
+ /*DSS*/\
+       MUX_VAL(CP(DSS_PCLK),           (IDIS | PTD | DIS | M0)) /*DSS_PCLK*/\
+       MUX_VAL(CP(DSS_HSYNC),          (IDIS | PTD | DIS | M0)) /*DSS_HSYNC*/\
+       MUX_VAL(CP(DSS_VSYNC),          (IDIS | PTD | DIS | M0)) /*DSS_VSYNC*/\
+       MUX_VAL(CP(DSS_ACBIAS),         (IDIS | PTD | DIS | M0)) /*DSS_ACBIAS*/\
+       MUX_VAL(CP(DSS_DATA0),          (IDIS | PTD | DIS | M0)) /*DSS_DATA0*/\
+       MUX_VAL(CP(DSS_DATA1),          (IDIS | PTD | DIS | M0)) /*DSS_DATA1*/\
+       MUX_VAL(CP(DSS_DATA2),          (IDIS | PTD | DIS | M0)) /*DSS_DATA2*/\
+       MUX_VAL(CP(DSS_DATA3),          (IDIS | PTD | DIS | M0)) /*DSS_DATA3*/\
+       MUX_VAL(CP(DSS_DATA4),          (IDIS | PTD | DIS | M0)) /*DSS_DATA4*/\
+       MUX_VAL(CP(DSS_DATA5),          (IDIS | PTD | DIS | M0)) /*DSS_DATA5*/\
+       MUX_VAL(CP(DSS_DATA6),          (IDIS | PTD | DIS | M0)) /*DSS_DATA6*/\
+       MUX_VAL(CP(DSS_DATA7),          (IDIS | PTD | DIS | M0)) /*DSS_DATA7*/\
+       MUX_VAL(CP(DSS_DATA8),          (IDIS | PTD | DIS | M0)) /*DSS_DATA8*/\
+       MUX_VAL(CP(DSS_DATA9),          (IDIS | PTD | DIS | M0)) /*DSS_DATA9*/\
+       MUX_VAL(CP(DSS_DATA10),         (IDIS | PTD | DIS | M0)) /*DSS_DATA10*/\
+       MUX_VAL(CP(DSS_DATA11),         (IDIS | PTD | DIS | M0)) /*DSS_DATA11*/\
+       MUX_VAL(CP(DSS_DATA12),         (IDIS | PTD | DIS | M0)) /*DSS_DATA12*/\
+       MUX_VAL(CP(DSS_DATA13),         (IDIS | PTD | DIS | M0)) /*DSS_DATA13*/\
+       MUX_VAL(CP(DSS_DATA14),         (IDIS | PTD | DIS | M0)) /*DSS_DATA14*/\
+       MUX_VAL(CP(DSS_DATA15),         (IDIS | PTD | DIS | M0)) /*DSS_DATA15*/\
+       MUX_VAL(CP(DSS_DATA16),         (IDIS | PTD | DIS | M0)) /*DSS_DATA16*/\
+       MUX_VAL(CP(DSS_DATA17),         (IDIS | PTD | DIS | M0)) /*DSS_DATA17*/\
+       MUX_VAL(CP(DSS_DATA18),         (IDIS | PTD | DIS | M0)) /*DSS_DATA18*/\
+       MUX_VAL(CP(DSS_DATA19),         (IDIS | PTD | DIS | M0)) /*DSS_DATA19*/\
+       MUX_VAL(CP(DSS_DATA20),         (IDIS | PTD | DIS | M0)) /*DSS_DATA20*/\
+       MUX_VAL(CP(DSS_DATA21),         (IDIS | PTD | DIS | M0)) /*DSS_DATA21*/\
+       MUX_VAL(CP(DSS_DATA22),         (IDIS | PTD | DIS | M0)) /*DSS_DATA22*/\
+       MUX_VAL(CP(DSS_DATA23),         (IDIS | PTD | DIS | M0)) /*DSS_DATA23*/\
+ /*CAMERA*/\
+       MUX_VAL(CP(CAM_FLD),            (IDIS | PTD | DIS | M4)) /*CAM_FLD*/\
+       MUX_VAL(CP(CAM_XCLKB),          (IDIS | PTD | DIS | M0)) /*CAM_XCLKB*/\
+       MUX_VAL(CP(CAM_WEN),            (IEN  | PTD | DIS | M0)) /*CAM_WEN*/\
+       MUX_VAL(CP(CAM_STROBE),         (IDIS | PTD | DIS | M0)) /*CAM_STROBE*/\
+       MUX_VAL(CP(CSI2_DX1),           (IEN  | PTD | EN  | M4)) /*GPIO_114*/\
+                                                                /* - PEN_DOWN*/\
+ /*Bluetooth*/\
+       MUX_VAL(CP(UART2_CTS),          (IEN  | PTD | DIS | M4)) /*GPIO_144 - LCD_EN*/\
+       MUX_VAL(CP(UART2_RTS),          (IEN  | PTD | DIS | M4)) /*GPIO_145*/\
+       MUX_VAL(CP(UART2_TX),           (IEN  | PTD | DIS | M4)) /*GPIO_146*/\
+       MUX_VAL(CP(UART2_RX),           (IEN  | PTD | DIS | M4)) /*GPIO_147*/\
+       MUX_VAL(CP(UART1_TX),           (IDIS | PTD | DIS | M0)) /*UART1_TX*/\
+       MUX_VAL(CP(UART1_CTS),          (IEN  | PTU | DIS | M4)) /*GPIO_150-MMC3_WP*/\
+       MUX_VAL(CP(UART1_RX),           (IEN  | PTD | DIS | M0)) /*UART1_RX*/\
+ /*Serial Interface*/\
+       MUX_VAL(CP(UART3_CTS_RCTX),     (IEN  | PTD | EN  | M0)) /*UART3_CTS_RCTX*/\
+       MUX_VAL(CP(HDQ_SIO),            (IDIS | PTU | EN  | M4)) /*HDQ_SIO*/\
+       MUX_VAL(CP(MCSPI1_CLK),         (IEN  | PTD | DIS | M0)) /*McSPI1_CLK*/\
+       MUX_VAL(CP(MCSPI1_SIMO),        (IEN  | PTD | DIS | M0)) /*McSPI1_SIMO */\
+       MUX_VAL(CP(MCSPI1_SOMI),        (IEN  | PTD | DIS | M0)) /*McSPI1_SOMI */\
+       MUX_VAL(CP(MCSPI1_CS0),         (IEN  | PTD | EN  | M0)) /*McSPI1_CS0*/\
+       MUX_VAL(CP(MCSPI1_CS1),         (IDIS | PTD | EN  | M0)) /*McSPI1_CS1*/\
+       MUX_VAL(CP(MCSPI1_CS2),         (IEN  | PTU | DIS | M4)) /*GPIO_176 */\
+                                                                /* - LAN_INTR */\
+ /*Control and debug */\
+       MUX_VAL(CP(SYS_CLKOUT1),        (IEN  | PTU | EN  | M4)) /*GPIO_10*/\
+       MUX_VAL(CP(SYS_CLKOUT2),        (IEN  | PTU | EN  | M4)) /*GPIO_186*/\
+       MUX_VAL(CP(ETK_CLK_ES2),        (IEN  | PTU | EN  | M2)) /*MMC3_CLK*/\
+       MUX_VAL(CP(ETK_CTL_ES2),        (IEN  | PTU | EN  | M2)) /*MMC3_CMD*/\
+       MUX_VAL(CP(ETK_D0_ES2),         (IEN  | PTU | EN  | M4)) /*GPIO_14*/\
+       MUX_VAL(CP(ETK_D3_ES2),         (IEN  | PTU | EN  | M2)) /*MMC3_DAT3*/\
+       MUX_VAL(CP(ETK_D4_ES2),         (IEN  | PTU | EN  | M2)) /*MMC3_DAT0*/\
+       MUX_VAL(CP(ETK_D5_ES2),         (IEN  | PTU | EN  | M2)) /*MMC3_DAT1*/\
+       MUX_VAL(CP(ETK_D6_ES2),         (IEN  | PTU | EN  | M2)) /*MMC3_DAT2*/\
+       MUX_VAL(CP(ETK_D7_ES2),         (IEN  | PTU | EN  | M4)) /*GPIO_21*/\
+       MUX_VAL(CP(ETK_D8_ES2),         (IEN  | PTU | EN  | M4)) /*GPIO_22*/\
+       MUX_VAL(CP(ETK_D9_ES2),         (IEN  | PTU | EN  | M4)) /*GPIO_23*/\
+
 #define MUX_OVERO_SDIO2_DIRECT() \
        MUX_VAL(CP(MMC2_CLK),           (IEN  | PTU | EN  | M0)) /*MMC2_CLK*/\
        MUX_VAL(CP(MMC2_CMD),           (IEN  | PTU | EN  | M0)) /*MMC2_CMD*/\
index cbf4186f71e912f0e8cb9fdfa1db2aebc6301383..268b92998f66ccbec0cea9ef8a9e39a922f0c4b9 100644 (file)
@@ -310,7 +310,7 @@ const omap3_sysinfo sysinfo = {
        MUX_VAL(CP(SYS_BOOT6),          (IEN  | PTD | DIS | M4)) /*GPIO_8*/\
        MUX_VAL(CP(SYS_OFF_MODE),       (IEN  | PTD | DIS | M0)) /*SYS_OFF_MODE*/\
  /*JTAG*/\
-       MUX_VAL(CP(JTAG_nTRST),         (IEN  | PTD | DIS | M0)) /*JTAG_nTRST*/\
+       MUX_VAL(CP(JTAG_NTRST),         (IEN  | PTD | DIS | M0)) /*JTAG_NTRST*/\
        MUX_VAL(CP(JTAG_TCK),           (IEN  | PTD | DIS | M0)) /*JTAG_TCK*/\
        MUX_VAL(CP(JTAG_TMS),           (IEN  | PTD | DIS | M0)) /*JTAG_TMS*/\
        MUX_VAL(CP(JTAG_TDI),           (IEN  | PTD | DIS | M0)) /*JTAG_TDI*/\
index 976ba4ce94226c8f464944ca6c456a29d6c52269..f01fb1c6e7624bbe66d9714fc3fbfe0d98db0619 100644 (file)
@@ -11,7 +11,7 @@
 #include <miiphy.h>
 #include <asm/io.h>
 #include <asm/arch/cpu.h>
-#include <asm/arch/kirkwood.h>
+#include <asm/arch/soc.h>
 #include <asm/arch/mpp.h>
 #include "ib62x0.h"
 
@@ -24,9 +24,9 @@ int board_early_init_f(void)
         * There are maximum 64 gpios controlled through 2 sets of registers
         * the below configuration configures mainly initial LED status
         */
-       kw_config_gpio(IB62x0_OE_VAL_LOW,
-                       IB62x0_OE_VAL_HIGH,
-                       IB62x0_OE_LOW, IB62x0_OE_HIGH);
+       mvebu_config_gpio(IB62x0_OE_VAL_LOW,
+                         IB62x0_OE_VAL_HIGH,
+                         IB62x0_OE_LOW, IB62x0_OE_HIGH);
 
        /* Set SATA activity LEDs to default off */
        writel(MVSATAHC_LED_POLARITY_CTRL, MVSATAHC_LED_CONF_REG);
@@ -62,7 +62,7 @@ int board_early_init_f(void)
 int board_init(void)
 {
        /* adress of boot parameters */
-       gd->bd->bi_boot_params = kw_sdram_bar(0) + 0x100;
+       gd->bd->bi_boot_params = mvebu_sdram_bar(0) + 0x100;
 
        return 0;
 }
index 220bb90dc1ae025ddf37e8fe9636201843c00650..7445f5318ad2ed44525ea8bf8a11cc5ae95cbc42 100644 (file)
 
 #include <common.h>
 #include <config.h>
+#include <dm.h>
 #include <fdt_support.h>
 #include <lcd.h>
 #include <mmc.h>
+#include <asm/gpio.h>
 #include <asm/arch/mbox.h>
 #include <asm/arch/sdhci.h>
 #include <asm/global_data.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
+static const struct bcm2835_gpio_platdata gpio_platdata = {
+       .base = BCM2835_GPIO_BASE,
+};
+
+U_BOOT_DEVICE(bcm2835_gpios) = {
+       .name = "gpio_bcm2835",
+       .platdata = &gpio_platdata,
+};
+
 struct msg_get_arm_mem {
        struct bcm2835_mbox_hdr hdr;
        struct bcm2835_mbox_tag_get_arm_mem get_arm_mem;
        u32 end_tag;
 };
 
+struct msg_get_mac_address {
+       struct bcm2835_mbox_hdr hdr;
+       struct bcm2835_mbox_tag_get_mac_address get_mac_address;
+       u32 end_tag;
+};
+
 struct msg_set_power_state {
        struct bcm2835_mbox_hdr hdr;
        struct bcm2835_mbox_tag_set_power_state set_power_state;
@@ -62,6 +79,29 @@ int dram_init(void)
        return 0;
 }
 
+int misc_init_r(void)
+{
+       ALLOC_ALIGN_BUFFER(struct msg_get_mac_address, msg, 1, 16);
+       int ret;
+
+       if (getenv("usbethaddr"))
+               return 0;
+
+       BCM2835_MBOX_INIT_HDR(msg);
+       BCM2835_MBOX_INIT_TAG(&msg->get_mac_address, GET_MAC_ADDRESS);
+
+       ret = bcm2835_mbox_call_prop(BCM2835_MBOX_PROP_CHAN, &msg->hdr);
+       if (ret) {
+               printf("bcm2835: Could not query MAC address\n");
+               /* Ignore error; not critical */
+               return 0;
+       }
+
+       eth_setenv_enetaddr("usbethaddr", msg->get_mac_address.body.resp.mac);
+
+       return 0;
+}
+
 static int power_on_module(u32 module)
 {
        ALLOC_ALIGN_BUFFER(struct msg_set_power_state, msg_pwr, 1, 16);
index 5eedbf8ce66c5deadd36f268d181f998123fa45e..3aad532367b361cfe0c5bba0ed72f2f0e5c69c90 100644 (file)
@@ -9,6 +9,7 @@
 #include <asm/processor.h>
 #include <asm/io.h>
 #include <asm/mmc.h>
+#include <spi.h>
 #include <spi_flash.h>
 
 int checkboard(void)
index 42b920fb33395013fdda8ec2af0af823a9efa464..9f6494561c6a43378f899fda6d4702344b6cf63a 100644 (file)
@@ -9,6 +9,7 @@
 #include <asm/processor.h>
 #include <asm/io.h>
 #include <asm/mmc.h>
+#include <spi.h>
 #include <spi_flash.h>
 
 int checkboard(void)
index 1464f48b43ae00f2ad290c292433f07fcbe7386d..ddcf275f6e7854ca6d23cc7ab1d24162cf3c626f 100644 (file)
@@ -9,6 +9,7 @@
 #include <asm/processor.h>
 #include <asm/io.h>
 #include <asm/mmc.h>
+#include <spi.h>
 #include <spi_flash.h>
 
 int checkboard(void)
index 83fd3bd754bdf1549a7a9fe65a8929649feb2f2a..881d080522563912da43a96e90a7a66a6fa4866a 100644 (file)
@@ -6,9 +6,9 @@
 
 #include <common.h>
 #include <usb.h>
+#include <asm/gpio.h>
 #include <asm/arch/pinmux.h>
 #include <asm/arch/dwmmc.h>
-#include <asm/arch/gpio.h>
 #include <asm/arch/power.h>
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -19,6 +19,8 @@ int board_usb_init(int index, enum usb_init_type init)
        /* Configure gpios for usb 3503 hub:
         * disconnect, toggle reset and connect
         */
+       gpio_request(EXYNOS5_GPIO_D17, "usb_connect");
+       gpio_request(EXYNOS5_GPIO_X35, "usb_reset");
        gpio_direction_output(EXYNOS5_GPIO_D17, 0);
        gpio_direction_output(EXYNOS5_GPIO_X35, 0);
 
index 5c3c5bb9254b0bc427ab493033844f5fb1083086..8b4c8e9a9db90f882a1349e1b5c6e1258fc77ce3 100644 (file)
 #include <tmu.h>
 #include <netdev.h>
 #include <asm/io.h>
+#include <asm/gpio.h>
 #include <asm/arch/board.h>
 #include <asm/arch/cpu.h>
 #include <asm/arch/dwmmc.h>
-#include <asm/arch/gpio.h>
 #include <asm/arch/mmc.h>
 #include <asm/arch/pinmux.h>
 #include <asm/arch/power.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
-int __exynos_early_init_f(void)
+__weak int exynos_early_init_f(void)
 {
        return 0;
 }
-int exynos_early_init_f(void)
-       __attribute__((weak, alias("__exynos_early_init_f")));
 
-int __exynos_power_init(void)
+__weak int exynos_power_init(void)
 {
        return 0;
 }
-int exynos_power_init(void)
-       __attribute__((weak, alias("__exynos_power_init")));
 
 #if defined CONFIG_EXYNOS_TMU
 /* Boot Time Thermal Analysis for SoC temperature threshold breach */
@@ -87,9 +83,6 @@ int board_init(void)
        boot_temp_check();
 #endif
 
-#ifdef CONFIG_EXYNOS_SPI
-       spi_init();
-#endif
        return exynos_init();
 }
 
index 8766f0ca0684948877b28bcec64177c6b51530b0..4538ac7f2a2fc2d2a91f840944d13ec542e35e11 100644 (file)
@@ -14,7 +14,6 @@
 #include <malloc.h>
 #include <linux/sizes.h>
 #include <asm/arch/cpu.h>
-#include <asm/arch/gpio.h>
 #include <asm/gpio.h>
 #include <linux/input.h>
 #include <power/pmic.h>
@@ -412,6 +411,8 @@ void check_boot_mode(void)
 void keys_init(void)
 {
        /* Set direction to input */
+       gpio_request(KEY_VOL_UP_GPIO, "volume-up");
+       gpio_request(KEY_VOL_DOWN_GPIO, "volume-down");
        gpio_direction_input(KEY_VOL_UP_GPIO);
        gpio_direction_input(KEY_VOL_DOWN_GPIO);
 }
index eb0f9bffae0e4a3b925b570af2ab4f1337aa2f60..58cf96eaa84f49bcd9ce47a3f2476504deb783be 100644 (file)
@@ -7,7 +7,7 @@
  */
 
 #include <common.h>
-#include <asm/arch/gpio.h>
+#include <asm/gpio.h>
 #include <asm/arch/mmc.h>
 #include <power/pmic.h>
 #include <usb/s3c_udc.h>
@@ -33,6 +33,16 @@ int board_init(void)
        return 0;
 }
 
+#ifdef CONFIG_SYS_I2C_INIT_BOARD
+void i2c_init_board(void)
+{
+       gpio_request(S5PC110_GPIO_J43, "i2c_clk");
+       gpio_request(S5PC110_GPIO_J40, "i2c_data");
+       gpio_direction_output(S5PC110_GPIO_J43, 1);
+       gpio_direction_output(S5PC110_GPIO_J40, 1);
+}
+#endif
+
 int power_init_board(void)
 {
        int ret;
@@ -80,6 +90,7 @@ int board_mmc_init(bd_t *bis)
        int i, ret, ret_sd = 0;
 
        /* MASSMEMORY_EN: XMSMDATA7: GPJ2[7] output high */
+       gpio_request(S5PC110_GPIO_J27, "massmemory_en");
        gpio_direction_output(S5PC110_GPIO_J27, 1);
 
        /*
@@ -108,6 +119,7 @@ int board_mmc_init(bd_t *bis)
         * SD card (T_FLASH) detect and init
         * T_FLASH_DETECT: EINT28: GPH3[4] input mode
         */
+       gpio_request(S5PC110_GPIO_H34, "t_flash_detect");
        gpio_cfg_pin(S5PC110_GPIO_H34, S5P_GPIO_INPUT);
        gpio_set_pull(S5PC110_GPIO_H34, S5P_GPIO_PULL_UP);
 
index a539267a1ca43339ddfe246ecc37aa85b0f73b9f..99a2facd1ee71f00945c01d5774d7d00e955c832 100644 (file)
@@ -6,8 +6,8 @@
 
 #include <common.h>
 #include <asm/io.h>
+#include <asm/gpio.h>
 #include <asm/arch/cpu.h>
-#include <asm/arch/gpio.h>
 #include <asm/arch/mmc.h>
 #include <asm/arch/periph.h>
 #include <asm/arch/pinmux.h>
index d6ce1337b94ba6f06172ea6459c7162396dbc5ea..53ff7061d730c293260acd1f77367ec1d5bb4f16 100644 (file)
@@ -29,6 +29,7 @@ DECLARE_GLOBAL_DATA_PTR;
 static void board_enable_audio_codec(void)
 {
        /* Enable MAX98095 Codec */
+       gpio_request(EXYNOS5_GPIO_X17, "max98095_enable");
        gpio_direction_output(EXYNOS5_GPIO_X17, 1);
        gpio_set_pull(EXYNOS5_GPIO_X17, S5P_GPIO_PULL_NONE);
 }
@@ -199,16 +200,19 @@ static int board_dp_bridge_setup(void)
        /* Setup the GPIOs */
 
        /* PD is ACTIVE_LOW, and initially de-asserted */
+       gpio_request(EXYNOS5_GPIO_Y25, "dp_bridge_pd");
        gpio_set_pull(EXYNOS5_GPIO_Y25, S5P_GPIO_PULL_NONE);
        gpio_direction_output(EXYNOS5_GPIO_Y25, 1);
 
        /* Reset is ACTIVE_LOW */
+       gpio_request(EXYNOS5_GPIO_X15, "dp_bridge_reset");
        gpio_set_pull(EXYNOS5_GPIO_X15, S5P_GPIO_PULL_NONE);
        gpio_direction_output(EXYNOS5_GPIO_X15, 0);
 
        udelay(10);
        gpio_set_value(EXYNOS5_GPIO_X15, 1);
 
+       gpio_request(EXYNOS5_GPIO_X07, "dp_bridge_hpd");
        gpio_direction_input(EXYNOS5_GPIO_X07);
 
        /*
@@ -236,10 +240,12 @@ static int board_dp_bridge_setup(void)
 void exynos_cfg_lcd_gpio(void)
 {
        /* For Backlight */
+       gpio_request(EXYNOS5_GPIO_B20, "lcd_backlight");
        gpio_cfg_pin(EXYNOS5_GPIO_B20, S5P_GPIO_OUTPUT);
        gpio_set_value(EXYNOS5_GPIO_B20, 1);
 
        /* LCD power on */
+       gpio_request(EXYNOS5_GPIO_X15, "lcd_power");
        gpio_cfg_pin(EXYNOS5_GPIO_X15, S5P_GPIO_OUTPUT);
        gpio_set_value(EXYNOS5_GPIO_X15, 1);
 
@@ -276,6 +282,7 @@ void exynos_backlight_on(unsigned int on)
        mdelay(10);
 
        /* board_dp_backlight_en */
+       gpio_request(EXYNOS5_GPIO_X30, "board_dp_backlight_en");
        gpio_direction_output(EXYNOS5_GPIO_X30, 1);
 #endif
 }
index 270ee834e65695210c88668f2beab5e06ac4a304..a691222b8b143dd61e784ae8e3122dc95b8e3953 100644 (file)
@@ -11,9 +11,9 @@
 #include <lcd.h>
 #include <spi.h>
 #include <errno.h>
+#include <asm/gpio.h>
 #include <asm/arch/board.h>
 #include <asm/arch/cpu.h>
-#include <asm/arch/gpio.h>
 #include <asm/arch/pinmux.h>
 #include <asm/arch/system.h>
 #include <asm/arch/dp_info.h>
@@ -74,9 +74,12 @@ void exynos_lcd_power_on(void)
        mdelay(5);
 
        /* TODO(ajaykumar.rs@samsung.com): Use device tree */
+       gpio_request(EXYNOS5420_GPIO_X35, "edp_slp#");
        gpio_direction_output(EXYNOS5420_GPIO_X35, 1);  /* EDP_SLP# */
        mdelay(10);
+       gpio_request(EXYNOS5420_GPIO_Y77, "edp_rst#");
        gpio_direction_output(EXYNOS5420_GPIO_Y77, 1);  /* EDP_RST# */
+       gpio_request(EXYNOS5420_GPIO_X26, "edp_hpd");
        gpio_direction_input(EXYNOS5420_GPIO_X26);      /* EDP_HPD */
        gpio_set_pull(EXYNOS5420_GPIO_X26, S5P_GPIO_PULL_NONE);
 
@@ -88,6 +91,7 @@ void exynos_lcd_power_on(void)
 void exynos_backlight_on(unsigned int onoff)
 {
        /* For PWM */
+       gpio_request(EXYNOS5420_GPIO_B20, "backlight_on");
        gpio_cfg_pin(EXYNOS5420_GPIO_B20, S5P_GPIO_FUNC(0x1));
        gpio_set_value(EXYNOS5420_GPIO_B20, 1);
 
index e009564a5988ce8a79a9bd7e83634ee9e8ca7ac4..66b6a9801f734ec1894b213a822b37ca86139419 100644 (file)
@@ -7,9 +7,9 @@
  */
 
 #include <common.h>
+#include <asm/gpio.h>
 #include <asm/io.h>
 #include <asm/arch/sromc.h>
-#include <asm/arch/gpio.h>
 #include <netdev.h>
 
 DECLARE_GLOBAL_DATA_PTR;
index 8eca358981f10351a639c7775a58e19504072106..cb7f9b0ac88babc95253a5cf43e9e8d2ca580da6 100644 (file)
@@ -5,10 +5,10 @@
  */
 
 #include <common.h>
+#include <asm/gpio.h>
 #include <asm/io.h>
 #include <netdev.h>
 #include <asm/arch/cpu.h>
-#include <asm/arch/gpio.h>
 #include <asm/arch/mmc.h>
 #include <asm/arch/periph.h>
 #include <asm/arch/pinmux.h>
index 3dd340b7d8da7e3b6a80d770e8442d0ba1a477b8..e163e45a587df150324e60ee57114a5735269a76 100644 (file)
@@ -10,8 +10,8 @@
 #include <common.h>
 #include <lcd.h>
 #include <asm/io.h>
+#include <asm/gpio.h>
 #include <asm/arch/cpu.h>
-#include <asm/arch/gpio.h>
 #include <asm/arch/pinmux.h>
 #include <asm/arch/clock.h>
 #include <asm/arch/mipi_dsim.h>
@@ -63,6 +63,8 @@ void i2c_init_board(void)
        }
 
        /* I2C_8 -> FG */
+       gpio_request(EXYNOS4_GPIO_Y40, "i2c_clk");
+       gpio_request(EXYNOS4_GPIO_Y41, "i2c_data");
        gpio_direction_output(EXYNOS4_GPIO_Y40, 1);
        gpio_direction_output(EXYNOS4_GPIO_Y41, 1);
 }
@@ -346,12 +348,17 @@ int exynos_power_init(void)
 static unsigned int get_hw_revision(void)
 {
        int hwrev = 0;
+       char str[10];
        int i;
 
        /* hw_rev[3:0] == GPE1[3:0] */
-       for (i = EXYNOS4_GPIO_E10; i < EXYNOS4_GPIO_E14; i++) {
-               gpio_cfg_pin(i, S5P_GPIO_INPUT);
-               gpio_set_pull(i, S5P_GPIO_PULL_NONE);
+       for (i = 0; i < 4; i++) {
+               int pin = i + EXYNOS4_GPIO_E10;
+
+               sprintf(str, "hw_rev%d", i);
+               gpio_request(pin, str);
+               gpio_cfg_pin(pin, S5P_GPIO_INPUT);
+               gpio_set_pull(pin, S5P_GPIO_PULL_NONE);
        }
 
        udelay(1);
@@ -517,6 +524,7 @@ static void board_power_init(void)
 static void exynos_uart_init(void)
 {
        /* UART_SEL GPY4[7] (part2) at EXYNOS4 */
+       gpio_request(EXYNOS4_GPIO_Y47, "uart_sel");
        gpio_set_pull(EXYNOS4_GPIO_Y47, S5P_GPIO_PULL_UP);
        gpio_direction_output(EXYNOS4_GPIO_Y47, 1);
 }
@@ -534,6 +542,7 @@ int exynos_early_init_f(void)
 
 void exynos_reset_lcd(void)
 {
+       gpio_request(EXYNOS4_GPIO_Y45, "lcd_reset");
        gpio_direction_output(EXYNOS4_GPIO_Y45, 1);
        udelay(10000);
        gpio_direction_output(EXYNOS4_GPIO_Y45, 0);
index fa26e61244fc97e2a16b903dc89b971dadf26010..a7377497e5d2d4002f7b847ae051abfe5e8bb2b9 100644 (file)
@@ -8,6 +8,7 @@
 
 #include <common.h>
 #include <lcd.h>
+#include <asm/gpio.h>
 #include <asm/arch/pinmux.h>
 #include <asm/arch/power.h>
 #include <asm/arch/mipi_dsim.h>
@@ -32,6 +33,7 @@ static inline u32 get_model_rev(void);
 static void check_hw_revision(void)
 {
        int modelrev = 0;
+       char str[12];
        int i;
 
        /*
@@ -40,13 +42,22 @@ static void check_hw_revision(void)
         * TRM say that it may cause unexcepted state and leakage current.
         * and pull-none is only for output function.
         */
-       for (i = EXYNOS4X12_GPIO_M10; i < EXYNOS4X12_GPIO_M12; i++)
-               gpio_cfg_pin(i, S5P_GPIO_INPUT);
+       for (i = 0; i < 2; i++) {
+               int pin = i + EXYNOS4X12_GPIO_M10;
+
+               sprintf(str, "model_rev%d", i);
+               gpio_request(pin, str);
+               gpio_cfg_pin(pin, S5P_GPIO_INPUT);
+       }
 
        /* GPM1[5:2]: HW_REV[3:0] */
-       for (i = EXYNOS4X12_GPIO_M12; i < EXYNOS4X12_GPIO_M16; i++) {
-               gpio_cfg_pin(i, S5P_GPIO_INPUT);
-               gpio_set_pull(i, S5P_GPIO_PULL_NONE);
+       for (i = 0; i < 4; i++) {
+               int pin = i + EXYNOS4X12_GPIO_M12;
+
+               sprintf(str, "hw_rev%d", i);
+               gpio_request(pin, str);
+               gpio_cfg_pin(pin, S5P_GPIO_INPUT);
+               gpio_set_pull(pin, S5P_GPIO_PULL_NONE);
        }
 
        /* GPM1[1:0]: MODEL_REV[1:0] */
@@ -102,10 +113,14 @@ static void board_init_i2c(void)
        }
 
        /* I2C_8 */
+       gpio_request(EXYNOS4X12_GPIO_F14, "i2c8_clk");
+       gpio_request(EXYNOS4X12_GPIO_F15, "i2c8_data");
        gpio_direction_output(EXYNOS4X12_GPIO_F14, 1);
        gpio_direction_output(EXYNOS4X12_GPIO_F15, 1);
 
        /* I2C_9 */
+       gpio_request(EXYNOS4X12_GPIO_M21, "i2c9_clk");
+       gpio_request(EXYNOS4X12_GPIO_M20, "i2c9_data");
        gpio_direction_output(EXYNOS4X12_GPIO_M21, 1);
        gpio_direction_output(EXYNOS4X12_GPIO_M20, 1);
 }
@@ -387,6 +402,7 @@ void exynos_lcd_power_on(void)
        struct pmic *p = pmic_get("MAX77686_PMIC");
 
        /* LCD_2.2V_EN: GPC0[1] */
+       gpio_request(EXYNOS4X12_GPIO_C01, "lcd_2v2_en");
        gpio_set_pull(EXYNOS4X12_GPIO_C01, S5P_GPIO_PULL_UP);
        gpio_direction_output(EXYNOS4X12_GPIO_C01, 1);
 
@@ -399,6 +415,7 @@ void exynos_lcd_power_on(void)
 void exynos_reset_lcd(void)
 {
        /* reset lcd */
+       gpio_request(EXYNOS4X12_GPIO_F21, "lcd_reset");
        gpio_direction_output(EXYNOS4X12_GPIO_F21, 0);
        udelay(10);
        gpio_set_value(EXYNOS4X12_GPIO_F21, 1);
index 47e7f538d65b7cd35943328d91ecb44385096961..22b08497cb57c1091b1eb82aeed7b58b73c18857 100644 (file)
@@ -12,7 +12,6 @@
 #include <asm/io.h>
 #include <asm/gpio.h>
 #include <asm/arch/adc.h>
-#include <asm/arch/gpio.h>
 #include <asm/arch/pinmux.h>
 #include <asm/arch/watchdog.h>
 #include <ld9040.h>
@@ -202,53 +201,6 @@ int exynos_early_init_f(void)
        return 0;
 }
 
-#ifdef CONFIG_SOFT_SPI
-static void soft_spi_init(void)
-{
-       gpio_direction_output(CONFIG_SOFT_SPI_GPIO_SCLK,
-               CONFIG_SOFT_SPI_MODE & SPI_CPOL);
-       gpio_direction_output(CONFIG_SOFT_SPI_GPIO_MOSI, 1);
-       gpio_direction_input(CONFIG_SOFT_SPI_GPIO_MISO);
-       gpio_direction_output(CONFIG_SOFT_SPI_GPIO_CS,
-               !(CONFIG_SOFT_SPI_MODE & SPI_CS_HIGH));
-}
-
-void spi_cs_activate(struct spi_slave *slave)
-{
-       gpio_set_value(CONFIG_SOFT_SPI_GPIO_CS,
-               !(CONFIG_SOFT_SPI_MODE & SPI_CS_HIGH));
-       SPI_SCL(1);
-       gpio_set_value(CONFIG_SOFT_SPI_GPIO_CS,
-               CONFIG_SOFT_SPI_MODE & SPI_CS_HIGH);
-}
-
-void spi_cs_deactivate(struct spi_slave *slave)
-{
-       gpio_set_value(CONFIG_SOFT_SPI_GPIO_CS,
-               !(CONFIG_SOFT_SPI_MODE & SPI_CS_HIGH));
-}
-
-int  spi_cs_is_valid(unsigned int bus, unsigned int cs)
-{
-       return bus == 0 && cs == 0;
-}
-
-void universal_spi_scl(int bit)
-{
-       gpio_set_value(CONFIG_SOFT_SPI_GPIO_SCLK, bit);
-}
-
-void universal_spi_sda(int bit)
-{
-       gpio_set_value(CONFIG_SOFT_SPI_GPIO_MOSI, bit);
-}
-
-int universal_spi_read(void)
-{
-       return gpio_get_value(CONFIG_SOFT_SPI_GPIO_MISO);
-}
-#endif
-
 static void init_pmic_lcd(void)
 {
        unsigned char val;
@@ -331,9 +283,8 @@ void exynos_cfg_lcd_gpio(void)
        }
 
        /* gpio pad configuration for LCD reset. */
+       gpio_request(EXYNOS4_GPIO_Y45, "lcd_reset");
        gpio_cfg_pin(EXYNOS4_GPIO_Y45, S5P_GPIO_OUTPUT);
-
-       spi_init();
 }
 
 int mipi_power(void)
@@ -387,6 +338,7 @@ int exynos_init(void)
                 * you should set it HIGH since it removes the inverter
                 */
                /* MASSMEMORY_EN: XMDMDATA_6: GPE3[6] */
+               gpio_request(EXYNOS4_GPIO_E36, "ldo_en");
                gpio_direction_output(EXYNOS4_GPIO_E36, 0);
                break;
        default:
@@ -395,13 +347,11 @@ int exynos_init(void)
                 * But set it as HIGH to ensure
                 */
                /* MASSMEMORY_EN: XMDMADDR_3: GPE1[3] */
+               gpio_request(EXYNOS4_GPIO_E13, "massmemory_en");
                gpio_direction_output(EXYNOS4_GPIO_E13, 1);
                break;
        }
 
-#ifdef CONFIG_SOFT_SPI
-       soft_spi_init();
-#endif
        check_hw_revision();
        printf("HW Revision:\t0x%x\n", board_rev);
 
index bcd0a55a1e584410e13689b691f9d2d3614cdf67..31a15037d07cf950059f9a23d80e7b8fe6259c6f 100644 (file)
@@ -1,25 +1,12 @@
-if TARGET_SUN4I
+if TARGET_SUN4I || TARGET_SUN5I || TARGET_SUN6I || TARGET_SUN7I || TARGET_SUN8I
 
 config SYS_CONFIG_NAME
-       default "sun4i"
-
-endif
-
-if TARGET_SUN5I
-
-config SYS_CONFIG_NAME
-       default "sun5i"
-
-endif
-
-if TARGET_SUN7I
-
-config SYS_CONFIG_NAME
-       default "sun7i"
-
-endif
-
-if TARGET_SUN4I || TARGET_SUN5I || TARGET_SUN7I
+       string
+       default "sun4i" if TARGET_SUN4I
+       default "sun5i" if TARGET_SUN5I
+       default "sun6i" if TARGET_SUN6I
+       default "sun7i" if TARGET_SUN7I
+       default "sun8i" if TARGET_SUN8I
 
 config SYS_CPU
        default "armv7"
@@ -33,4 +20,45 @@ config SYS_SOC
 config FDTFILE
        string "Default fdtfile env setting for this board"
 
+config OLD_SUNXI_KERNEL_COMPAT
+       boolean "Enable workarounds for booting old kernels"
+       default n
+       ---help---
+       Set this to enable various workarounds for old kernels, this results in
+       sub-optimal settings for newer kernels, only enable if needed.
+
+config MMC0_CD_PIN
+       string "Card detect pin for mmc0"
+       default ""
+       ---help---
+       Set the card detect pin for mmc0, leave empty to not use cd. This
+       takes a string in the format understood by sunxi_name_to_gpio, e.g.
+       PH1 for pin 1 of port H.
+
+config MMC1_CD_PIN
+       string "Card detect pin for mmc1"
+       default ""
+       ---help---
+       See MMC0_CD_PIN help text.
+
+config MMC2_CD_PIN
+       string "Card detect pin for mmc2"
+       default ""
+       ---help---
+       See MMC0_CD_PIN help text.
+
+config MMC3_CD_PIN
+       string "Card detect pin for mmc3"
+       default ""
+       ---help---
+       See MMC0_CD_PIN help text.
+
+config MMC_SUNXI_SLOT_EXTRA
+       int "mmc extra slot number"
+       default -1
+       ---help---
+       sunxi builds always enable mmc0, some boards also have a second sdcard
+       slot or emmc on mmc1 - mmc3. Setting this to 1, 2 or 3 will enable
+       support for this.
+
 endif
index 4f32195dcd92372858a2ff0170f45059531d8adf..febd126cb83bb15518515422ac35e25cba071dfa 100644 (file)
@@ -8,6 +8,7 @@ F:      configs/ba10_tv_box_defconfig
 F:     configs/Cubieboard_defconfig
 F:     configs/Mele_A1000_defconfig
 F:     configs/Mele_A1000G_defconfig
+F:     configs/Mele_M3_defconfig
 F:     configs/Mini-X_defconfig
 F:     configs/Mini-X-1Gb_defconfig
 F:     include/configs/sun5i.h
@@ -38,3 +39,19 @@ M:   FUKAUMI Naoki <naobsd@gmail.com>
 S:     Maintained
 F:     board/sunxi/dram_a20_olinuxino_l.c
 F:     configs/A20-OLinuXino-Lime_defconfig
+
+A20-OLINUXINO-LIME2 BOARD
+M:     Iain Paton <ipaton0@gmail.com>
+S:     Maintained
+F:     board/sunxi/dram_a20_olinuxino_l2.c
+F:     configs/A20-OLinuXino-Lime2_defconfig
+
+COLOMBUS BOARD
+M:     Maxime Ripard <maxime.ripard@free-electrons.com>
+S:     Maintained
+F:     configs/Colombus_defconfig
+
+IPPO-Q8H-V5 BOARD
+M:     CHen-Yu Tsai <wens@csie.org>
+S:     Maintained
+F:     configs/Ippo_q8h_v5_defconfig
index 56073a024d1a4c58940671b325e7c0ad71d75427..6a2e4c9d5b5553d52a6325277109a201d10a1ca3 100644 (file)
@@ -16,6 +16,7 @@ obj-$(CONFIG_A10S_OLINUXINO_M)        += dram_a10s_olinuxino_m.o
 obj-$(CONFIG_A13_OLINUXINO)    += dram_a13_olinuxino.o
 obj-$(CONFIG_A13_OLINUXINOM)   += dram_a13_oli_micro.o
 obj-$(CONFIG_A20_OLINUXINO_L)  += dram_a20_olinuxino_l.o
+obj-$(CONFIG_A20_OLINUXINO_L2) += dram_a20_olinuxino_l2.o
 obj-$(CONFIG_A20_OLINUXINO_M)  += dram_sun7i_384_1024_iow16.o
 # This is not a typo, uses the same mem settings as the a10s-olinuxino-m
 obj-$(CONFIG_AUXTEK_T004)      += dram_a10s_olinuxino_m.o
@@ -27,6 +28,7 @@ obj-$(CONFIG_CUBIETRUCK)      += dram_cubietruck.o
 obj-$(CONFIG_I12_TVBOX)                += dram_sun7i_384_1024_iow16.o
 obj-$(CONFIG_MELE_A1000)       += dram_sun4i_360_512.o
 obj-$(CONFIG_MELE_A1000G)      += dram_sun4i_360_1024_iow8.o
+obj-$(CONFIG_MELE_M3)          += dram_sun7i_384_1024_iow16.o
 obj-$(CONFIG_MINI_X)           += dram_sun4i_360_512.o
 obj-$(CONFIG_MINI_X_1GB)       += dram_sun4i_360_1024_iow16.o
 obj-$(CONFIG_PCDUINO3)         += dram_linksprite_pcduino3.o
index 2179e234e21d67b0fec064de792fca175db90ca5..03890c8c9ceb62c40279c4fb910a56441858ec8a 100644 (file)
@@ -12,6 +12,7 @@
  */
 
 #include <common.h>
+#include <mmc.h>
 #ifdef CONFIG_AXP152_POWER
 #include <axp152.h>
 #endif
@@ -70,9 +71,9 @@ static void mmc_pinmux_setup(int sdc)
                break;
 
        case 1:
-               /* CMD-PH22, CLK-PH23, D0~D3-PH24~27 : 5 */
-               for (pin = SUNXI_GPH(22); pin <= SUNXI_GPH(27); pin++) {
-                       sunxi_gpio_set_cfgpin(pin, SUN4I_GPH22_SDC1);
+               /* CMD-PG3, CLK-PG4, D0~D3-PG5-8 */
+               for (pin = SUNXI_GPG(3); pin <= SUNXI_GPG(8); pin++) {
+                       sunxi_gpio_set_cfgpin(pin, SUN5I_GPG3_SDC1);
                        sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
                        sunxi_gpio_set_drv(pin, 2);
                }
@@ -104,11 +105,36 @@ static void mmc_pinmux_setup(int sdc)
 
 int board_mmc_init(bd_t *bis)
 {
+       __maybe_unused struct mmc *mmc0, *mmc1;
+       __maybe_unused char buf[512];
+
        mmc_pinmux_setup(CONFIG_MMC_SUNXI_SLOT);
-       sunxi_mmc_init(CONFIG_MMC_SUNXI_SLOT);
-#if !defined (CONFIG_SPL_BUILD) && defined (CONFIG_MMC_SUNXI_SLOT_EXTRA)
+       mmc0 = sunxi_mmc_init(CONFIG_MMC_SUNXI_SLOT);
+       if (!mmc0)
+               return -1;
+
+#if CONFIG_MMC_SUNXI_SLOT_EXTRA != -1
        mmc_pinmux_setup(CONFIG_MMC_SUNXI_SLOT_EXTRA);
-       sunxi_mmc_init(CONFIG_MMC_SUNXI_SLOT_EXTRA);
+       mmc1 = sunxi_mmc_init(CONFIG_MMC_SUNXI_SLOT_EXTRA);
+       if (!mmc1)
+               return -1;
+#endif
+
+#if CONFIG_MMC_SUNXI_SLOT == 0 && CONFIG_MMC_SUNXI_SLOT_EXTRA == 2
+       /*
+        * Both mmc0 and mmc2 are bootable, figure out where we're booting
+        * from. Try mmc0 first, just like the brom does.
+        */
+       if (mmc_getcd(mmc0) && mmc_init(mmc0) == 0 &&
+           mmc0->block_dev.block_read(0, 16, 1, buf) == 1) {
+               buf[12] = 0;
+               if (strcmp(&buf[4], "eGON.BT0") == 0)
+                       return 0;
+       }
+
+       /* no bootable card in mmc0, so we must be booting from mmc2, swap */
+       mmc0->block_dev.dev = 1;
+       mmc1->block_dev.dev = 0;
 #endif
 
        return 0;
diff --git a/board/sunxi/dram_a20_olinuxino_l2.c b/board/sunxi/dram_a20_olinuxino_l2.c
new file mode 100644 (file)
index 0000000..2115d37
--- /dev/null
@@ -0,0 +1,31 @@
+/* this file is generated, don't edit it yourself */
+
+#include <common.h>
+#include <asm/arch/dram.h>
+
+static struct dram_para dram_para = {
+       .clock = 480,
+       .type = 3,
+       .rank_num = 1,
+       .density = 4096,
+       .io_width = 16,
+       .bus_width = 32,
+       .cas = 9,
+       .zq = 0x7f,
+       .odt_en = 0,
+       .size = 1024,
+       .tpr0 = 0x42d899b7,
+       .tpr1 = 0xa090,
+       .tpr2 = 0x22a00,
+       .tpr3 = 0,
+       .tpr4 = 0,
+       .tpr5 = 0,
+       .emr1 = 0x4,
+       .emr2 = 0x10,
+       .emr3 = 0,
+};
+
+unsigned long sunxi_dram_init(void)
+{
+       return dramc_init(&dram_para);
+}
index daff1094802fd2bb406a99702b8d3737c57541e8..4a94399fc98232f118c9c847b35bfabe65fa80d4 100644 (file)
@@ -275,7 +275,7 @@ const omap3_sysinfo sysinfo = {
        MUX_VAL(CP(SYS_OFF_MODE), (IEN  | PTD | DIS | M0)) \
        MUX_VAL(CP(SYS_CLKOUT1), (IEN  | PTD | DIS | M0)) \
        MUX_VAL(CP(SYS_CLKOUT2), (IEN  | PTU | EN  | M0)) \
-       MUX_VAL(CP(JTAG_nTRST), (IEN  | PTD | DIS | M0)) \
+       MUX_VAL(CP(JTAG_NTRST), (IEN  | PTD | DIS | M0)) \
        MUX_VAL(CP(JTAG_TCK),   (IEN  | PTD | DIS | M0)) \
        MUX_VAL(CP(JTAG_TMS),   (IEN  | PTD | DIS | M0)) \
        MUX_VAL(CP(JTAG_TDI),   (IEN  | PTD | DIS | M0)) \
index 054e7ccdedf9bf4f222b22ecaab0fa2805b4d68f..a4aed3ba8baf2d3ce742f7c6967f273e61cc5afb 100644 (file)
@@ -16,6 +16,8 @@
 #include <asm/omap_gpio.h>
 #include <asm/arch/mmc_host_def.h>
 #include <i2c.h>
+#include <spl.h>
+#include <mmc.h>
 #include <asm/gpio.h>
 #ifdef CONFIG_USB_EHCI
 #include <usb.h>
index 62fbfdfed64332a1a8da4e643d16cd9fd1a739da..e286bd4522f0b0ba4b270ba8b47b1bec642091be 100644 (file)
@@ -337,7 +337,7 @@ const omap3_sysinfo sysinfo = {
        MUX_VAL(CP(SYS_CLKOUT1),        (IEN  | PTD | DIS | M0)) \
        MUX_VAL(CP(SYS_CLKOUT2),        (IEN  | PTU | EN  | M0)) \
        /* JTAG */\
-       MUX_VAL(CP(JTAG_nTRST),         (IEN  | PTD | DIS | M0)) \
+       MUX_VAL(CP(JTAG_NTRST),         (IEN  | PTD | DIS | M0)) \
        MUX_VAL(CP(JTAG_TCK),           (IEN  | PTD | DIS | M0)) \
        MUX_VAL(CP(JTAG_TMS),           (IEN  | PTD | DIS | M0)) \
        MUX_VAL(CP(JTAG_TDI),           (IEN  | PTD | DIS | M0)) \
index aba71a84bf9d8af9ce5ee24b3468b169bfebad6c..bc85ad4350a914de7f044c3f3473dce250ea5dff 100644 (file)
@@ -339,7 +339,7 @@ const omap3_sysinfo sysinfo = {
                        /* gpio_10 */\
        MUX_VAL(CP(SYS_CLKOUT2),        (IEN  | PTU | EN  | M0)) \
        /* JTAG */\
-       MUX_VAL(CP(JTAG_nTRST),         (IEN  | PTD | DIS | M0)) \
+       MUX_VAL(CP(JTAG_NTRST),         (IEN  | PTD | DIS | M0)) \
        MUX_VAL(CP(JTAG_TCK),           (IEN  | PTD | DIS | M0)) \
        MUX_VAL(CP(JTAG_TMS),           (IEN  | PTD | DIS | M0)) \
        MUX_VAL(CP(JTAG_TDI),           (IEN  | PTD | DIS | M0)) \
index f4bb9f890b5bf4bdb7cca8ecd67dcfadb0cd650a..680f6560f25780897fa01792464066bc320ab5c8 100644 (file)
@@ -359,9 +359,9 @@ void enable_board_pin_mux(struct am335x_baseboard_id *header)
                configure_module_pin_mux(i2c1_pin_mux);
                configure_module_pin_mux(mii1_pin_mux);
                configure_module_pin_mux(mmc0_pin_mux);
-#if defined(CONFIG_NAND)
+#if defined(CONFIG_NAND) && defined(CONFIG_EMMC_BOOT)
                configure_module_pin_mux(nand_pin_mux);
-#elif defined(CONFIG_NOR)
+#elif defined(CONFIG_NOR) && defined(CONFIG_EMMC_BOOT)
                configure_module_pin_mux(bone_norcape_pin_mux);
 #else
                configure_module_pin_mux(mmc1_pin_mux);
index e131c8fb99fb58ab293c752f71bb9b0af52a0214..6289ca787c1fc33026d6dd426b31b52076b273e7 100644 (file)
@@ -284,7 +284,7 @@ const omap3_sysinfo sysinfo = {
        MUX_VAL(CP(SYS_CLKOUT1),    (IEN  | PTD | DIS | M4))/*GPIO_10 TP*/\
        MUX_VAL(CP(SYS_CLKOUT2),        (IEN  | PTU | EN  | M0))\
        /*JTAG*/\
-       MUX_VAL(CP(JTAG_nTRST), (IEN  | PTD | DIS | M0))\
+       MUX_VAL(CP(JTAG_NTRST), (IEN  | PTD | DIS | M0))\
        MUX_VAL(CP(JTAG_TCK),   (IEN  | PTD | DIS | M0))\
        MUX_VAL(CP(JTAG_TMS),   (IEN  | PTD | DIS | M0))\
        MUX_VAL(CP(JTAG_TDI),   (IEN  | PTD | DIS | M0))\
index 94b99bf53762660406c1dd1d87d1b9694d5a5625..4c5e38136fd55c542c52379285d0e42237e2cda2 100644 (file)
@@ -14,6 +14,8 @@
  * SPDX-License-Identifier:    GPL-2.0+
  */
 #include <common.h>
+#include <dm.h>
+#include <ns16550.h>
 #ifdef CONFIG_STATUS_LED
 #include <status_led.h>
 #endif
@@ -70,6 +72,17 @@ static struct {
        char env_setting[64];
 } expansion_config;
 
+static const struct ns16550_platdata beagle_serial = {
+       OMAP34XX_UART3,
+       2,
+       V_NS16550_CLK
+};
+
+U_BOOT_DEVICE(beagle_uart) = {
+       "serial_omap",
+       &beagle_serial
+};
+
 /*
  * Routine: board_init
  * Description: Early hardware init.
@@ -103,22 +116,22 @@ int board_init(void)
  */
 static int get_board_revision(void)
 {
-       int revision;
-
-       if (!gpio_request(171, "") &&
-           !gpio_request(172, "") &&
-           !gpio_request(173, "")) {
-
-               gpio_direction_input(171);
-               gpio_direction_input(172);
-               gpio_direction_input(173);
-
-               revision = gpio_get_value(173) << 2 |
-                          gpio_get_value(172) << 1 |
-                          gpio_get_value(171);
-       } else {
-               printf("Error: unable to acquire board revision GPIOs\n");
-               revision = -1;
+       static int revision = -1;
+
+       if (revision == -1) {
+               if (!gpio_request(171, "rev0") &&
+                   !gpio_request(172, "rev1") &&
+                   !gpio_request(173, "rev2")) {
+                       gpio_direction_input(171);
+                       gpio_direction_input(172);
+                       gpio_direction_input(173);
+
+                       revision = gpio_get_value(173) << 2 |
+                               gpio_get_value(172) << 1 |
+                               gpio_get_value(171);
+               } else {
+                       printf("Error: unable to acquire board revision GPIOs\n");
+               }
        }
 
        return revision;
@@ -258,7 +271,7 @@ static void beagle_dvi_pup(void)
        case REVISION_AXBX:
        case REVISION_CX:
        case REVISION_C4:
-               gpio_request(170, "");
+               gpio_request(170, "dvi");
                gpio_direction_output(170, 0);
                gpio_set_value(170, 1);
                break;
index 89b8dd3c3c1ee015be657b27372bc5c2176cc634..a913a4c84aa624453138ce0ad6fa8180db61fc1b 100644 (file)
@@ -27,47 +27,46 @@ void green_led_on(void)
 }
 #endif
 
+static int get_led_gpio(led_id_t mask)
+{
+#ifdef STATUS_LED_BIT
+       if (STATUS_LED_BIT & mask)
+               return BEAGLE_LED_USR0;
+#endif
+#ifdef STATUS_LED_BIT1
+       if (STATUS_LED_BIT1 & mask)
+               return BEAGLE_LED_USR1;
+#endif
+
+       return 0;
+}
+
 void __led_init (led_id_t mask, int state)
 {
-       __led_set (mask, state);
+       int toggle_gpio;
+
+       toggle_gpio = get_led_gpio(mask);
+
+       if (toggle_gpio && !gpio_request(toggle_gpio, "led"))
+               __led_set(mask, state);
 }
 
 void __led_toggle (led_id_t mask)
 {
-       int state, toggle_gpio = 0;
-#ifdef STATUS_LED_BIT
-       if (!toggle_gpio && STATUS_LED_BIT & mask)
-               toggle_gpio = BEAGLE_LED_USR0;
-#endif
-#ifdef STATUS_LED_BIT1
-       if (!toggle_gpio && STATUS_LED_BIT1 & mask)
-               toggle_gpio = BEAGLE_LED_USR1;
-#endif
+       int state, toggle_gpio;
+
+       toggle_gpio = get_led_gpio(mask);
        if (toggle_gpio) {
-               if (!gpio_request(toggle_gpio, "")) {
-                       gpio_direction_output(toggle_gpio, 0);
-                       state = gpio_get_value(toggle_gpio);
-                       gpio_set_value(toggle_gpio, !state);
-               }
+               state = gpio_get_value(toggle_gpio);
+               gpio_direction_output(toggle_gpio, !state);
        }
 }
 
 void __led_set (led_id_t mask, int state)
 {
-#ifdef STATUS_LED_BIT
-       if (STATUS_LED_BIT & mask) {
-               if (!gpio_request(BEAGLE_LED_USR0, "")) {
-                       gpio_direction_output(BEAGLE_LED_USR0, 0);
-                       gpio_set_value(BEAGLE_LED_USR0, state);
-               }
-       }
-#endif
-#ifdef STATUS_LED_BIT1
-       if (STATUS_LED_BIT1 & mask) {
-               if (!gpio_request(BEAGLE_LED_USR1, "")) {
-                       gpio_direction_output(BEAGLE_LED_USR1, 0);
-                       gpio_set_value(BEAGLE_LED_USR1, state);
-               }
-       }
-#endif
+       int toggle_gpio;
+
+       toggle_gpio = get_led_gpio(mask);
+       if (toggle_gpio)
+               gpio_direction_output(toggle_gpio, state);
 }
index f50193d99af5d5f7e6d184abc175309688223504..91e9b88c548c3b19f7ff72727579656ec1a21365 100644 (file)
@@ -300,7 +300,7 @@ static void reset_net_chip(void);
        MUX_VAL(CP(SYS_OFF_MODE),       (IEN  | PTD | DIS | M0)) /*SYS_OFF_MODE*/\
        MUX_VAL(CP(SYS_CLKOUT1),        (IEN  | PTD | DIS | M0)) /*SYS_CLKOUT1*/\
        MUX_VAL(CP(SYS_CLKOUT2),        (IEN  | PTU | EN  | M0)) /*SYS_CLKOUT2*/\
-       MUX_VAL(CP(JTAG_nTRST),         (IEN  | PTD | DIS | M0)) /*JTAG_nTRST*/\
+       MUX_VAL(CP(JTAG_NTRST),         (IEN  | PTD | DIS | M0)) /*JTAG_NTRST*/\
        MUX_VAL(CP(JTAG_TCK),           (IEN  | PTD | DIS | M0)) /*JTAG_TCK*/\
        MUX_VAL(CP(JTAG_TMS),           (IEN  | PTD | DIS | M0)) /*JTAG_TMS*/\
        MUX_VAL(CP(JTAG_TDI),           (IEN  | PTD | DIS | M0)) /*JTAG_TDI*/\
index 9c1e103a20fcda9ca9e8c7110e56e90b5c0e5531..96c5f22eadeb544f47b7459356210cb8bea7c6d9 100644 (file)
@@ -23,3 +23,19 @@ config SYS_CONFIG_NAME
        default "k2hk_evm"
 
 endif
+
+if TARGET_K2L_EVM
+
+config SYS_BOARD
+       string
+       default "ks2_evm"
+
+config SYS_VENDOR
+       string
+       default "ti"
+
+config SYS_CONFIG_NAME
+       string
+       default "k2l_evm"
+
+endif
index 595a80a8bc6fbd201f5737701dca41a9cf7072e1..87c36c9d14a2a8ad6546e735b58dcf5228ac17b7 100644 (file)
@@ -6,3 +6,5 @@ F:      include/configs/k2hk_evm.h
 F:     configs/k2hk_evm_defconfig
 F:     include/configs/k2e_evm.h
 F:     configs/k2e_evm_defconfig
+F:     include/configs/k2l_evm.h
+F:     configs/k2l_evm_defconfig
index 00f1164833c29f9483c714047167c9c7d6e7b330..071dbee180ad466221f16a88e745ac30f6b36bf7 100644 (file)
@@ -11,3 +11,5 @@ obj-$(CONFIG_K2HK_EVM) += board_k2hk.o
 obj-$(CONFIG_K2HK_EVM) += ddr3_k2hk.o
 obj-$(CONFIG_K2E_EVM) += board_k2e.o
 obj-$(CONFIG_K2E_EVM) += ddr3_k2e.o
+obj-$(CONFIG_K2L_EVM) += board_k2l.o
+obj-$(CONFIG_K2L_EVM) += ddr3_k2l.o
index dfe7be60e71befcd1c314b8f4a2cb05feca5a929..40294934525c9b0518d2a53118c45c6da22fdc13 100644 (file)
@@ -9,11 +9,13 @@
 
 #include "board.h"
 #include <common.h>
+#include <spl.h>
 #include <exports.h>
 #include <fdt_support.h>
 #include <asm/arch/ddr3.h>
-#include <asm/arch/emac_defs.h>
+#include <asm/arch/psc_defs.h>
 #include <asm/ti-common/ti-aemif.h>
+#include <asm/ti-common/keystone_net.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -38,6 +40,7 @@ int dram_init(void)
        gd->ram_size = get_ram_size((long *)CONFIG_SYS_SDRAM_BASE,
                                    CONFIG_MAX_RAM_BANK_SIZE);
        aemif_init(ARRAY_SIZE(aemif_configs), aemif_configs);
+       ddr3_init_ecc(KS2_DDR3A_EMIF_CTRL_BASE);
        return 0;
 }
 
@@ -68,6 +71,15 @@ int board_eth_init(bd_t *bis)
        int port_num;
        char link_type_name[32];
 
+       /* By default, select PA PLL clock as PA clock source */
+       if (psc_enable_module(KS2_LPSC_PA))
+               return -1;
+       if (psc_enable_module(KS2_LPSC_CPGMAC))
+               return -1;
+       if (psc_enable_module(KS2_LPSC_CRYPTO))
+               return -1;
+       pass_pll_pa_clk_enable();
+
        port_num = get_num_eth_ports();
 
        for (j = 0; j < port_num; j++) {
@@ -83,6 +95,24 @@ int board_eth_init(bd_t *bis)
 }
 #endif
 
+#ifdef CONFIG_SPL_BUILD
+void spl_board_init(void)
+{
+       spl_init_keystone_plls();
+       preloader_console_init();
+}
+
+u32 spl_boot_device(void)
+{
+#if defined(CONFIG_SPL_SPI_LOAD)
+       return BOOT_DEVICE_SPI;
+#else
+       puts("Unknown boot device\n");
+       hang();
+#endif
+}
+#endif
+
 #if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP)
 void ft_board_setup(void *blob, bd_t *bd)
 {
@@ -225,5 +255,7 @@ void ft_board_setup_ex(void *blob, bd_t *bd)
                        reserve_start += 2;
                }
        }
+
+       ddr3_check_ecc_int(KS2_DDR3A_EMIF_CTRL_BASE);
 }
 #endif
index d91ef736129fa3c2309d143f215322f108566d8b..2bbd79245baa438983439872db0bb9ca275f1770 100644 (file)
 #ifndef _KS2_BOARD
 #define _KS2_BOARD
 
-#include <asm/arch/emac_defs.h>
+#include <asm/ti-common/keystone_net.h>
 
 extern struct eth_priv_t eth_priv_cfg[];
 
 int get_num_eth_ports(void);
+void spl_init_keystone_plls(void);
 
 #endif
index 5472a43c43f105c4ca3ec3bbc5e268a2f6cc5c76..43dfc48a53da2085f699450c698dd34af2d71163 100644 (file)
@@ -10,6 +10,7 @@
 #include <common.h>
 #include <asm/arch/ddr3.h>
 #include <asm/arch/hardware.h>
+#include <asm/ti-common/keystone_net.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -35,10 +36,75 @@ static struct pll_init_data core_pll_config[] = {
        CORE_PLL_1500,
 };
 
-
 static struct pll_init_data pa_pll_config =
        PASS_PLL_1000;
 
+#ifdef CONFIG_DRIVER_TI_KEYSTONE_NET
+struct eth_priv_t eth_priv_cfg[] = {
+       {
+               .int_name        = "K2E_EMAC0",
+               .rx_flow         = 0,
+               .phy_addr        = 0,
+               .slave_port      = 1,
+               .sgmii_link_type = SGMII_LINK_MAC_PHY,
+       },
+       {
+               .int_name        = "K2E_EMAC1",
+               .rx_flow         = 8,
+               .phy_addr        = 1,
+               .slave_port      = 2,
+               .sgmii_link_type = SGMII_LINK_MAC_PHY,
+       },
+       {
+               .int_name        = "K2E_EMAC2",
+               .rx_flow         = 16,
+               .phy_addr        = 2,
+               .slave_port      = 3,
+               .sgmii_link_type = SGMII_LINK_MAC_MAC_FORCED,
+       },
+       {
+               .int_name        = "K2E_EMAC3",
+               .rx_flow         = 24,
+               .phy_addr        = 3,
+               .slave_port      = 4,
+               .sgmii_link_type = SGMII_LINK_MAC_MAC_FORCED,
+       },
+       {
+               .int_name        = "K2E_EMAC4",
+               .rx_flow         = 32,
+               .phy_addr        = 4,
+               .slave_port      = 5,
+               .sgmii_link_type = SGMII_LINK_MAC_MAC_FORCED,
+       },
+       {
+               .int_name        = "K2E_EMAC5",
+               .rx_flow         = 40,
+               .phy_addr        = 5,
+               .slave_port      = 6,
+               .sgmii_link_type = SGMII_LINK_MAC_MAC_FORCED,
+       },
+       {
+               .int_name        = "K2E_EMAC6",
+               .rx_flow         = 48,
+               .phy_addr        = 6,
+               .slave_port      = 7,
+               .sgmii_link_type = SGMII_LINK_MAC_MAC_FORCED,
+       },
+       {
+               .int_name        = "K2E_EMAC7",
+               .rx_flow         = 56,
+               .phy_addr        = 7,
+               .slave_port      = 8,
+               .sgmii_link_type = SGMII_LINK_MAC_MAC_FORCED,
+       },
+};
+
+int get_num_eth_ports(void)
+{
+       return sizeof(eth_priv_cfg) / sizeof(struct eth_priv_t);
+}
+#endif
+
 #if defined(CONFIG_BOARD_EARLY_INIT_F)
 int board_early_init_f(void)
 {
@@ -52,3 +118,14 @@ int board_early_init_f(void)
        return 0;
 }
 #endif
+
+#ifdef CONFIG_SPL_BUILD
+static struct pll_init_data spl_pll_config[] = {
+       CORE_PLL_800,
+};
+
+void spl_init_keystone_plls(void)
+{
+       init_plls(ARRAY_SIZE(spl_pll_config), spl_pll_config);
+}
+#endif
index 6fb3d2123df0a5183ec921f608735ab714f4e9e7..ed181f44b8974a229b23b8fd838e02c304ebe94c 100644 (file)
@@ -10,7 +10,7 @@
 #include <common.h>
 #include <asm/arch/clock.h>
 #include <asm/arch/hardware.h>
-#include <asm/arch/emac_defs.h>
+#include <asm/ti-common/keystone_net.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -100,3 +100,15 @@ int board_early_init_f(void)
        return 0;
 }
 #endif
+
+#ifdef CONFIG_SPL_BUILD
+static struct pll_init_data spl_pll_config[] = {
+       CORE_PLL_799,
+       TETRIS_PLL_500,
+};
+
+void spl_init_keystone_plls(void)
+{
+       init_plls(ARRAY_SIZE(spl_pll_config), spl_pll_config);
+}
+#endif
diff --git a/board/ti/ks2_evm/board_k2l.c b/board/ti/ks2_evm/board_k2l.c
new file mode 100644 (file)
index 0000000..559d20c
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * K2L EVM : Board initialization
+ *
+ * (C) Copyright 2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/arch/ddr3.h>
+#include <asm/arch/hardware.h>
+#include <asm/ti-common/ti-aemif.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+unsigned int external_clk[ext_clk_count] = {
+       [sys_clk]       = 122880000,
+       [alt_core_clk]  = 100000000,
+       [pa_clk]        = 122880000,
+       [tetris_clk]    = 122880000,
+       [ddr3_clk]      = 100000000,
+       [pcie_clk]      = 100000000,
+       [sgmii_clk]     = 156250000,
+       [usb_clk]       = 100000000,
+};
+
+static struct pll_init_data core_pll_config[] = {
+       CORE_PLL_799,
+       CORE_PLL_1000,
+       CORE_PLL_1198,
+};
+
+static struct pll_init_data tetris_pll_config[] = {
+       TETRIS_PLL_799,
+       TETRIS_PLL_1000,
+       TETRIS_PLL_1198,
+       TETRIS_PLL_1352,
+       TETRIS_PLL_1401,
+};
+
+static struct pll_init_data pa_pll_config =
+       PASS_PLL_983;
+
+#ifdef CONFIG_BOARD_EARLY_INIT_F
+int board_early_init_f(void)
+{
+       int speed;
+
+       speed = get_max_dev_speed();
+       init_pll(&core_pll_config[speed]);
+
+       init_pll(&pa_pll_config);
+
+       speed = get_max_arm_speed();
+       init_pll(&tetris_pll_config[speed]);
+
+       return 0;
+}
+#endif
+
+#ifdef CONFIG_SPL_BUILD
+static struct pll_init_data spl_pll_config[] = {
+       CORE_PLL_799,
+       TETRIS_PLL_491,
+};
+
+void spl_init_keystone_plls(void)
+{
+       init_plls(ARRAY_SIZE(spl_pll_config), spl_pll_config);
+}
+#endif
index f7da9f2bcbaab775f3a80e1ecad375286f4c141a..ab44676793c0b4617ec70ca7cc89117ed51890b8 100644 (file)
@@ -133,6 +133,42 @@ struct ddr3_emif_config ddr3_1600_4g = {
 };
 #endif
 
+struct ddr3_phy_config ddr3phy_1600_2g = {
+       .pllcr          = 0x0001C000ul,
+       .pgcr1_mask     = (IODDRM_MASK | ZCKSEL_MASK),
+       .pgcr1_val      = ((1 << 2) | (1 << 7) | (1 << 23)),
+       .ptr0           = 0x42C21590ul,
+       .ptr1           = 0xD05612C0ul,
+       .ptr2           = 0, /* not set in gel */
+       .ptr3           = 0x0D861A80ul,
+       .ptr4           = 0x0C827100ul,
+       .dcr_mask       = (PDQ_MASK | MPRDQ_MASK | BYTEMASK_MASK),
+       .dcr_val        = ((1 << 10)),
+       .dtpr0          = 0x9D5CBB66ul,
+       .dtpr1          = 0x12868300ul,
+       .dtpr2          = 0x5002D200ul,
+       .mr0            = 0x00001C70ul,
+       .mr1            = 0x00000006ul,
+       .mr2            = 0x00000018ul,
+       .dtcr           = 0x710035C7ul,
+       .pgcr2          = 0x00F07A12ul,
+       .zq0cr1         = 0x0001005Dul,
+       .zq1cr1         = 0x0001005Bul,
+       .zq2cr1         = 0x0001005Bul,
+       .pir_v1         = 0x00000033ul,
+       .pir_v2         = 0x0000FF81ul,
+};
+
+struct ddr3_emif_config ddr3_1600_2g = {
+       .sdcfg          = 0x6200CE62ul,
+       .sdtim1         = 0x166C9855ul,
+       .sdtim2         = 0x00001D4Aul,
+       .sdtim3         = 0x435DFF53ul,
+       .sdtim4         = 0x543F0CFFul,
+       .zqcfg          = 0x70073200ul,
+       .sdrfc          = 0x00001869ul,
+};
+
 int ddr3_get_dimm_params(char *dimm_name)
 {
        int ret;
index 15fcf52ef1980aec5303467f58f3b628c4739368..5bd786cff8e9f6e4ab918229b402c4ad782e71e6 100644 (file)
@@ -19,6 +19,9 @@ extern struct ddr3_emif_config ddr3_1333_2g;
 extern struct ddr3_phy_config ddr3phy_1600_4g;
 extern struct ddr3_emif_config ddr3_1600_4g;
 
+extern struct ddr3_phy_config ddr3phy_1600_2g;
+extern struct ddr3_emif_config ddr3_1600_2g;
+
 int ddr3_get_dimm_params(char *dimm_name);
 
 #endif /* __DDR3_CFG_H */
index 6070a9977029ad1fc8d222bd9f4381b0f823264e..a1c3d05f8e50e2f7d4f2a62097f8e46379f0aaaa 100644 (file)
@@ -12,6 +12,8 @@
 #include <asm/arch/ddr3.h>
 #include <asm/arch/hardware.h>
 
+static int ddr3_size;
+
 struct pll_init_data ddr3a_333 = DDR3_PLL_333(A);
 struct pll_init_data ddr3a_400 = DDR3_PLL_400(A);
 
@@ -44,12 +46,14 @@ void ddr3_init(void)
                        ddr3_init_ddremif(KS2_DDR3A_EMIF_CTRL_BASE,
                                          &ddr3_1600_8g);
                        printf("DRAM:  Capacity 8 GiB (includes reported below)\n");
+                       ddr3_size = 8;
                } else {
                        ddr3_init_ddrphy(KS2_DDR3A_DDRPHYC, &ddr3phy_1600_8g);
                        ddr3_1600_8g.sdcfg |= 0x1000;
                        ddr3_init_ddremif(KS2_DDR3A_EMIF_CTRL_BASE,
                                          &ddr3_1600_8g);
                        printf("DRAM:  Capacity 4 GiB (includes reported below)\n");
+                       ddr3_size = 4;
                }
        } else if (!strcmp(dimm_name, "SQR-SD3T-2G1333SED")) {
                init_pll(&ddr3a_333);
@@ -70,11 +74,15 @@ void ddr3_init(void)
                        }
                        ddr3_init_ddremif(KS2_DDR3A_EMIF_CTRL_BASE,
                                          &ddr3_1333_2g);
+                       ddr3_size = 2;
+                       printf("DRAM:  2 GiB");
                } else {
                        ddr3_init_ddrphy(KS2_DDR3A_DDRPHYC, &ddr3phy_1333_2g);
                        ddr3_1333_2g.sdcfg |= 0x1000;
                        ddr3_init_ddremif(KS2_DDR3A_EMIF_CTRL_BASE,
                                          &ddr3_1333_2g);
+                       ddr3_size = 1;
+                       printf("DRAM:  1 GiB");
                }
        } else {
                printf("Unknown SO-DIMM. Cannot configure DDR3\n");
@@ -86,3 +94,11 @@ void ddr3_init(void)
        if (cpu_revision() <= 1)
                ddr3_err_reset_workaround();
 }
+
+/**
+ * ddr3_get_size - return ddr3 size in GiB
+ */
+int ddr3_get_size(void)
+{
+       return ddr3_size;
+}
diff --git a/board/ti/ks2_evm/ddr3_k2l.c b/board/ti/ks2_evm/ddr3_k2l.c
new file mode 100644 (file)
index 0000000..15a14f2
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Keystone2: DDR3 initialization
+ *
+ * (C) Copyright 2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include "ddr3_cfg.h"
+#include <asm/arch/ddr3.h>
+
+static int ddr3_size;
+static struct pll_init_data ddr3_400 = DDR3_PLL_400;
+
+void ddr3_init(void)
+{
+       init_pll(&ddr3_400);
+
+       /* No SO-DIMM, 2GB discreet DDR */
+       printf("DRAM: 2 GiB\n");
+       ddr3_size = 2;
+
+       /* Reset DDR3 PHY after PLL enabled */
+       ddr3_reset_ddrphy();
+
+       ddr3_init_ddrphy(KS2_DDR3A_DDRPHYC, &ddr3phy_1600_2g);
+       ddr3_init_ddremif(KS2_DDR3A_EMIF_CTRL_BASE, &ddr3_1600_2g);
+}
+
+/**
+ * ddr3_get_size - return ddr3 size in GiB
+ */
+int ddr3_get_size(void)
+{
+       return ddr3_size;
+}
index 2acb302591ee1025d1a073bd1d478bc64d5d159d..0e631897e38e24f38e0ddecf01057408489a0836 100644 (file)
        MUX_VAL(CP(SYS_OFF_MODE), (IEN | PTD | DIS | M0))\
        MUX_VAL(CP(SYS_CLKOUT1), (IEN | PTD | DIS | M0))\
        MUX_VAL(CP(SYS_CLKOUT2), (OFF_IN_PD | IEN | PTU | EN | M4))/*GPIO_186*/\
-       MUX_VAL(CP(JTAG_nTRST), (IEN | PTD | DIS | M0))\
+       MUX_VAL(CP(JTAG_NTRST), (IEN | PTD | DIS | M0))\
        MUX_VAL(CP(JTAG_TCK), (IEN | PTD | DIS | M0))\
        MUX_VAL(CP(JTAG_TMS), (IEN | PTD | DIS | M0))\
        MUX_VAL(CP(JTAG_TDI), (IEN | PTD | DIS | M0))\
diff --git a/board/toradex/apalis_t30/Kconfig b/board/toradex/apalis_t30/Kconfig
new file mode 100644 (file)
index 0000000..f1dcda5
--- /dev/null
@@ -0,0 +1,12 @@
+if TARGET_APALIS_T30
+
+config SYS_BOARD
+       default "apalis_t30"
+
+config SYS_VENDOR
+       default "toradex"
+
+config SYS_CONFIG_NAME
+       default "apalis_t30"
+
+endif
diff --git a/board/toradex/apalis_t30/MAINTAINERS b/board/toradex/apalis_t30/MAINTAINERS
new file mode 100644 (file)
index 0000000..01bc73e
--- /dev/null
@@ -0,0 +1,7 @@
+Apalis T30
+M:     Marcel Ziswiler <marcel.ziswiler@toradex.com>
+S:     Maintained
+F:     board/toradex/apalis_t30/
+F:     include/configs/apalis_t30.h
+F:     configs/apalis_t30_defconfig
+F:     arch/arm/dts/tegra30-apalis.dtb
diff --git a/board/toradex/apalis_t30/Makefile b/board/toradex/apalis_t30/Makefile
new file mode 100644 (file)
index 0000000..a968e6b
--- /dev/null
@@ -0,0 +1,6 @@
+# Copyright (c) 2014 Marcel Ziswiler
+# SPDX-License-Identifier:      GPL-2.0+
+
+include $(srctree)/board/nvidia/common/common.mk
+
+obj-y  += apalis_t30.o
diff --git a/board/toradex/apalis_t30/apalis_t30.c b/board/toradex/apalis_t30/apalis_t30.c
new file mode 100644 (file)
index 0000000..b9d694a
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ *  (C) Copyright 2014
+ *  Marcel Ziswiler <marcel@ziswiler.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+
+#include <asm/arch/gp_padctrl.h>
+#include <asm/arch/pinmux.h>
+#include <asm/gpio.h>
+#include <i2c.h>
+#include <netdev.h>
+
+#include "pinmux-config-apalis_t30.h"
+
+#define PMU_I2C_ADDRESS                0x2D
+#define MAX_I2C_RETRY          3
+
+/*
+ * Routine: pinmux_init
+ * Description: Do individual peripheral pinmux configs
+ */
+void pinmux_init(void)
+{
+       pinmux_config_pingrp_table(tegra3_pinmux_common,
+                                  ARRAY_SIZE(tegra3_pinmux_common));
+
+       pinmux_config_pingrp_table(unused_pins_lowpower,
+                                  ARRAY_SIZE(unused_pins_lowpower));
+
+       /* Initialize any non-default pad configs (APB_MISC_GP regs) */
+       pinmux_config_drvgrp_table(apalis_t30_padctrl,
+                                  ARRAY_SIZE(apalis_t30_padctrl));
+}
+
+#ifdef CONFIG_PCI_TEGRA
+int tegra_pcie_board_init(void)
+{
+       unsigned int old_bus;
+       u8 addr, data[1];
+       int err;
+
+       old_bus = i2c_get_bus_num();
+
+       err = i2c_set_bus_num(0);
+       if (err) {
+               debug("failed to set I2C bus\n");
+               return err;
+       }
+
+       /* TPS659110: VDD2_OP_REG = 1.05V */
+       data[0] = 0x27;
+       addr = 0x25;
+
+       err = i2c_write(PMU_I2C_ADDRESS, addr, 1, data, 1);
+       if (err) {
+               debug("failed to set VDD supply\n");
+               return err;
+       }
+
+       /* TPS659110: VDD2_REG 7.5 mV/us, ACTIVE */
+       data[0] = 0x0D;
+       addr = 0x24;
+
+       err = i2c_write(PMU_I2C_ADDRESS, addr, 1, data, 1);
+       if (err) {
+               debug("failed to enable VDD supply\n");
+               return err;
+       }
+
+       /* TPS659110: LDO6_REG = 1.1V, ACTIVE */
+       data[0] = 0x0D;
+       addr = 0x35;
+
+       err = i2c_write(PMU_I2C_ADDRESS, addr, 1, data, 1);
+       if (err) {
+               debug("failed to set AVDD supply\n");
+               return err;
+       }
+
+       i2c_set_bus_num(old_bus);
+
+       return 0;
+}
+
+int board_eth_init(bd_t *bis)
+{
+       return pci_eth_init(bis);
+}
+#endif /* CONFIG_PCI_TEGRA */
diff --git a/board/toradex/apalis_t30/pinmux-config-apalis_t30.h b/board/toradex/apalis_t30/pinmux-config-apalis_t30.h
new file mode 100644 (file)
index 0000000..c988d39
--- /dev/null
@@ -0,0 +1,347 @@
+/*
+ * Copyright (c) 2014, Marcel Ziswiler
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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/>.
+ */
+
+#ifndef _PINMUX_CONFIG_APALIS_T30_H_
+#define _PINMUX_CONFIG_APALIS_T30_H_
+
+#define DEFAULT_PINMUX(_pingrp, _mux, _pull, _tri, _io)                \
+       {                                                       \
+               .pingrp         = PMUX_PINGRP_##_pingrp,        \
+               .func           = PMUX_FUNC_##_mux,             \
+               .pull           = PMUX_PULL_##_pull,            \
+               .tristate       = PMUX_TRI_##_tri,              \
+               .io             = PMUX_PIN_##_io,               \
+               .lock           = PMUX_PIN_LOCK_DEFAULT,        \
+               .od             = PMUX_PIN_OD_DEFAULT,          \
+               .ioreset        = PMUX_PIN_IO_RESET_DEFAULT,    \
+       }
+
+#define I2C_PINMUX(_pingrp, _mux, _pull, _tri, _io, _lock, _od)        \
+       {                                                       \
+               .pingrp         = PMUX_PINGRP_##_pingrp,        \
+               .func           = PMUX_FUNC_##_mux,             \
+               .pull           = PMUX_PULL_##_pull,            \
+               .tristate       = PMUX_TRI_##_tri,              \
+               .io             = PMUX_PIN_##_io,               \
+               .lock           = PMUX_PIN_LOCK_##_lock,        \
+               .od             = PMUX_PIN_OD_##_od,            \
+               .ioreset        = PMUX_PIN_IO_RESET_DEFAULT,    \
+       }
+
+#define LV_PINMUX(_pingrp, _mux, _pull, _tri, _io, _lock, _ioreset) \
+       {                                                       \
+               .pingrp         = PMUX_PINGRP_##_pingrp,        \
+               .func           = PMUX_FUNC_##_mux,             \
+               .pull           = PMUX_PULL_##_pull,            \
+               .tristate       = PMUX_TRI_##_tri,              \
+               .io             = PMUX_PIN_##_io,               \
+               .lock           = PMUX_PIN_LOCK_##_lock,        \
+               .od             = PMUX_PIN_OD_DEFAULT,          \
+               .ioreset        = PMUX_PIN_IO_RESET_##_ioreset  \
+       }
+
+#define DEFAULT_PADCFG(_drvgrp, _slwf, _slwr, _drvup, _drvdn, _lpmd, _schmt, _hsm) \
+       {                                                       \
+               .drvgrp         = PMUX_DRVGRP_##_drvgrp,        \
+               .slwf           = _slwf,                        \
+               .slwr           = _slwr,                        \
+               .drvup          = _drvup,                       \
+               .drvdn          = _drvdn,                       \
+               .lpmd           = PMUX_LPMD_##_lpmd,            \
+               .schmt          = PMUX_SCHMT_##_schmt,          \
+               .hsm            = PMUX_HSM_##_hsm,              \
+       }
+
+static struct pmux_pingrp_config tegra3_pinmux_common[] = {
+       /* SDMMC1 pinmux */
+       DEFAULT_PINMUX(SDMMC1_CLK_PZ0, SDMMC1, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(SDMMC1_CMD_PZ1, SDMMC1, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(SDMMC1_DAT3_PY4, SDMMC1, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(SDMMC1_DAT2_PY5, SDMMC1, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(SDMMC1_DAT1_PY6, SDMMC1, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(SDMMC1_DAT0_PY7, SDMMC1, NORMAL, NORMAL, INPUT),
+
+       /* SDMMC3 pinmux */
+       DEFAULT_PINMUX(SDMMC3_CLK_PA6, SDMMC3, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(SDMMC3_CMD_PA7, SDMMC3, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(SDMMC3_DAT0_PB7, SDMMC3, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(SDMMC3_DAT1_PB6, SDMMC3, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(SDMMC3_DAT2_PB5, SDMMC3, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(SDMMC3_DAT3_PB4, SDMMC3, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(SDMMC3_DAT4_PD1, SDMMC3, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(SDMMC3_DAT5_PD0, SDMMC3, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(SDMMC3_DAT6_PD3, SDMMC3, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(SDMMC3_DAT7_PD4, SDMMC3, NORMAL, NORMAL, INPUT),
+
+       /* SDMMC4 pinmux (eMMC) */
+       LV_PINMUX(SDMMC4_CLK_PCC4, SDMMC4, NORMAL, NORMAL, INPUT, DISABLE, DISABLE),
+       LV_PINMUX(SDMMC4_CMD_PT7, SDMMC4, UP, NORMAL, INPUT, DISABLE, DISABLE),
+       LV_PINMUX(SDMMC4_DAT0_PAA0, SDMMC4, UP, NORMAL, INPUT, DISABLE, DISABLE),
+       LV_PINMUX(SDMMC4_DAT1_PAA1, SDMMC4, UP, NORMAL, INPUT, DISABLE, DISABLE),
+       LV_PINMUX(SDMMC4_DAT2_PAA2, SDMMC4, UP, NORMAL, INPUT, DISABLE, DISABLE),
+       LV_PINMUX(SDMMC4_DAT3_PAA3, SDMMC4, UP, NORMAL, INPUT, DISABLE, DISABLE),
+       LV_PINMUX(SDMMC4_DAT4_PAA4, SDMMC4, UP, NORMAL, INPUT, DISABLE, DISABLE),
+       LV_PINMUX(SDMMC4_DAT5_PAA5, SDMMC4, UP, NORMAL, INPUT, DISABLE, DISABLE),
+       LV_PINMUX(SDMMC4_DAT6_PAA6, SDMMC4, UP, NORMAL, INPUT, DISABLE, DISABLE),
+       LV_PINMUX(SDMMC4_DAT7_PAA7, SDMMC4, UP, NORMAL, INPUT, DISABLE, DISABLE),
+       LV_PINMUX(SDMMC4_RST_N_PCC3, RSVD1, DOWN, NORMAL, INPUT, DISABLE, DISABLE),
+
+       /* I2C1 pinmux */
+       I2C_PINMUX(GEN1_I2C_SCL_PC4, I2C1, NORMAL, NORMAL, INPUT, DISABLE, ENABLE),
+       I2C_PINMUX(GEN1_I2C_SDA_PC5, I2C1, NORMAL, NORMAL, INPUT, DISABLE, ENABLE),
+
+       /* I2C2 pinmux */
+       I2C_PINMUX(GEN2_I2C_SCL_PT5, I2C2, NORMAL, NORMAL, INPUT, DISABLE, ENABLE),
+       I2C_PINMUX(GEN2_I2C_SDA_PT6, I2C2, NORMAL, NORMAL, INPUT, DISABLE, ENABLE),
+
+       /* I2C3 pinmux */
+       I2C_PINMUX(CAM_I2C_SCL_PBB1, I2C3, NORMAL, TRISTATE, INPUT, DISABLE, ENABLE),
+       I2C_PINMUX(CAM_I2C_SDA_PBB2, I2C3, NORMAL, TRISTATE, INPUT, DISABLE, ENABLE),
+
+       /* I2C4 pinmux */
+       I2C_PINMUX(DDC_SCL_PV4, I2C4, NORMAL, NORMAL, INPUT, DISABLE, ENABLE),
+       I2C_PINMUX(DDC_SDA_PV5, I2C4, NORMAL, NORMAL, INPUT, DISABLE, ENABLE),
+
+       /* Power I2C pinmux */
+       I2C_PINMUX(PWR_I2C_SCL_PZ6, I2CPWR, NORMAL, NORMAL, INPUT, DISABLE, ENABLE),
+       I2C_PINMUX(PWR_I2C_SDA_PZ7, I2CPWR, NORMAL, NORMAL, INPUT, DISABLE, ENABLE),
+
+       DEFAULT_PINMUX(ULPI_DATA0_PO1, UARTA, NORMAL, NORMAL, OUTPUT),
+       /* UARTA RX, make sure we don't get input form a floating Pin */
+       DEFAULT_PINMUX(ULPI_DATA1_PO2, UARTA, UP, NORMAL, INPUT),
+       DEFAULT_PINMUX(ULPI_DATA2_PO3, UARTA, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(ULPI_DATA3_PO4, RSVD1, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(ULPI_DATA4_PO5, UARTA, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(ULPI_DATA5_PO6, UARTA, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(ULPI_DATA6_PO7, UARTA, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(ULPI_DATA7_PO0, UARTA, NORMAL, NORMAL, OUTPUT),
+       DEFAULT_PINMUX(ULPI_CLK_PY0, UARTD, NORMAL, NORMAL, OUTPUT),
+       DEFAULT_PINMUX(ULPI_DIR_PY1, UARTD, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(ULPI_NXT_PY2, UARTD, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(ULPI_STP_PY3, UARTD, NORMAL, NORMAL, OUTPUT),
+       DEFAULT_PINMUX(DAP3_FS_PP0, I2S2, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(DAP3_DIN_PP1, I2S2, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(DAP3_DOUT_PP2, I2S2, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(DAP3_SCLK_PP3, I2S2, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(PV2, OWR, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(PV3, RSVD1, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(CLK2_OUT_PW5, EXTPERIPH2, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(CLK2_REQ_PCC5, DAP, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(LCD_PWR1_PC1, DISPLAYA, DOWN, TRISTATE, OUTPUT), /* NC */
+       DEFAULT_PINMUX(LCD_PWR2_PC6, DISPLAYA, DOWN, TRISTATE, OUTPUT), /* NC */
+       DEFAULT_PINMUX(LCD_SDIN_PZ2, SPI5, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(LCD_SDOUT_PN5, SPI5, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(LCD_WR_N_PZ3, DISPLAYA, DOWN, TRISTATE, OUTPUT), /* NC */
+       DEFAULT_PINMUX(LCD_CS0_N_PN4, SPI5, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(LCD_DC0_PN6, DISPLAYA, DOWN, TRISTATE, OUTPUT), /* NC */
+       DEFAULT_PINMUX(LCD_SCK_PZ4, SPI5, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(LCD_PWR0_PB2, DISPLAYA, DOWN, TRISTATE, OUTPUT), /* NC */
+       DEFAULT_PINMUX(LCD_PCLK_PB3, DISPLAYA, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(LCD_DE_PJ1, DISPLAYA, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(LCD_HSYNC_PJ3, DISPLAYA, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(LCD_VSYNC_PJ4, DISPLAYA, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(LCD_D0_PE0, DISPLAYA, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(LCD_D1_PE1, DISPLAYA, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(LCD_D2_PE2, DISPLAYA, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(LCD_D3_PE3, DISPLAYA, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(LCD_D4_PE4, DISPLAYA, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(LCD_D5_PE5, DISPLAYA, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(LCD_D6_PE6, DISPLAYA, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(LCD_D7_PE7, DISPLAYA, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(LCD_D8_PF0, DISPLAYA, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(LCD_D9_PF1, DISPLAYA, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(LCD_D10_PF2, DISPLAYA, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(LCD_D11_PF3, DISPLAYA, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(LCD_D12_PF4, DISPLAYA, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(LCD_D13_PF5, DISPLAYA, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(LCD_D14_PF6, DISPLAYA, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(LCD_D15_PF7, DISPLAYA, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(LCD_D16_PM0, DISPLAYA, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(LCD_D17_PM1, DISPLAYA, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(LCD_D18_PM2, DISPLAYA, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(LCD_D19_PM3, DISPLAYA, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(LCD_D20_PM4, DISPLAYA, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(LCD_D21_PM5, DISPLAYA, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(LCD_D22_PM6, DISPLAYA, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(LCD_D23_PM7, DISPLAYA, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(LCD_CS1_N_PW0, DISPLAYA, DOWN, TRISTATE, OUTPUT), /* NC */
+       DEFAULT_PINMUX(LCD_M1_PW1, DISPLAYA, DOWN, TRISTATE, OUTPUT), /* NC */
+       DEFAULT_PINMUX(LCD_DC1_PD2, DISPLAYA, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(CRT_HSYNC_PV6, CRT, NORMAL, NORMAL, OUTPUT),
+       DEFAULT_PINMUX(CRT_VSYNC_PV7, CRT, NORMAL, NORMAL, OUTPUT),
+       LV_PINMUX(VI_D0_PT4, VI, NORMAL, NORMAL, INPUT, DISABLE, DISABLE),
+       LV_PINMUX(VI_D1_PD5, VI, NORMAL, NORMAL, INPUT, DISABLE, DISABLE),
+       LV_PINMUX(VI_D2_PL0, VI, NORMAL, NORMAL, INPUT, DISABLE, DISABLE),
+       LV_PINMUX(VI_D3_PL1, VI, NORMAL, NORMAL, INPUT, DISABLE, DISABLE),
+       LV_PINMUX(VI_D4_PL2, VI, NORMAL, NORMAL, INPUT, DISABLE, DISABLE),
+       LV_PINMUX(VI_D5_PL3, VI, NORMAL, NORMAL, INPUT, DISABLE, DISABLE),
+       LV_PINMUX(VI_D6_PL4, VI, NORMAL, NORMAL, INPUT, DISABLE, DISABLE),
+       LV_PINMUX(VI_D7_PL5, VI, NORMAL, NORMAL, INPUT, DISABLE, DISABLE),
+       LV_PINMUX(VI_D8_PL6, VI, NORMAL, NORMAL, INPUT, DISABLE, DISABLE),
+       LV_PINMUX(VI_D9_PL7, VI, NORMAL, NORMAL, INPUT, DISABLE, DISABLE),
+       LV_PINMUX(VI_D10_PT2, VI, NORMAL, NORMAL, INPUT, DISABLE, DISABLE),
+       LV_PINMUX(VI_D11_PT3, VI, NORMAL, NORMAL, INPUT, DISABLE, DISABLE),
+       LV_PINMUX(VI_HSYNC_PD7, VI, NORMAL, NORMAL, INPUT, DISABLE, DISABLE),
+       LV_PINMUX(VI_MCLK_PT1, VI, NORMAL, NORMAL, OUTPUT, DISABLE, DISABLE),
+       LV_PINMUX(VI_PCLK_PT0, VI, NORMAL, NORMAL, INPUT, DISABLE, DISABLE),
+       LV_PINMUX(VI_VSYNC_PD6, VI, NORMAL, NORMAL, INPUT, DISABLE, DISABLE),
+       DEFAULT_PINMUX(UART2_RXD_PC3, UARTB, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(UART2_TXD_PC2, UARTB, NORMAL, NORMAL, OUTPUT),
+       DEFAULT_PINMUX(UART2_RTS_N_PJ6, UARTB, DOWN, TRISTATE, OUTPUT), /* NC */
+       DEFAULT_PINMUX(UART2_CTS_N_PJ5, UARTB, DOWN, TRISTATE, OUTPUT), /* NC */
+       DEFAULT_PINMUX(UART3_TXD_PW6, UARTC, NORMAL, NORMAL, OUTPUT),
+       DEFAULT_PINMUX(UART3_RXD_PW7, UARTC, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(UART3_CTS_N_PA1, UARTC, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(UART3_RTS_N_PC0, PWM0, NORMAL, NORMAL, OUTPUT),
+       DEFAULT_PINMUX(PU0, RSVD1, DOWN, TRISTATE, OUTPUT),
+       DEFAULT_PINMUX(PU1, RSVD1, DOWN, TRISTATE, OUTPUT),
+       DEFAULT_PINMUX(PU2, RSVD1, DOWN, TRISTATE, OUTPUT),
+       DEFAULT_PINMUX(PU3, PWM0, NORMAL, NORMAL, OUTPUT),
+       DEFAULT_PINMUX(PU4, PWM1, NORMAL, NORMAL, OUTPUT),
+       DEFAULT_PINMUX(PU5, PWM2, NORMAL, NORMAL, OUTPUT),
+       DEFAULT_PINMUX(PU6, PWM3, NORMAL, NORMAL, OUTPUT),
+       DEFAULT_PINMUX(DAP4_FS_PP4, I2S3, DOWN, TRISTATE, OUTPUT), /* NC */
+       DEFAULT_PINMUX(DAP4_DIN_PP5, I2S3, DOWN, TRISTATE, OUTPUT), /* NC */
+       DEFAULT_PINMUX(DAP4_DOUT_PP6, I2S3, DOWN, TRISTATE, OUTPUT), /* NC */
+       DEFAULT_PINMUX(DAP4_SCLK_PP7, I2S3, DOWN, TRISTATE, OUTPUT), /* NC */
+       DEFAULT_PINMUX(CLK3_OUT_PEE0, EXTPERIPH3, DOWN, TRISTATE, OUTPUT), /* NC */
+       DEFAULT_PINMUX(CLK3_REQ_PEE1, DEV3, DOWN, TRISTATE, OUTPUT), /* NC */
+       DEFAULT_PINMUX(GMI_WP_N_PC7, GMI, DOWN, TRISTATE, OUTPUT), /* NC */
+       DEFAULT_PINMUX(GMI_CS2_N_PK3, RSVD1, DOWN, TRISTATE, OUTPUT), /* NC */
+       DEFAULT_PINMUX(GMI_AD8_PH0, PWM0, DOWN, TRISTATE, OUTPUT), /* NC */
+       DEFAULT_PINMUX(GMI_AD10_PH2, NAND, DOWN, TRISTATE, OUTPUT), /* NC */
+       DEFAULT_PINMUX(GMI_A16_PJ7, UARTD, DOWN, TRISTATE, OUTPUT), /* NC */
+       DEFAULT_PINMUX(GMI_A17_PB0, UARTD, DOWN, TRISTATE, OUTPUT), /* NC */
+       DEFAULT_PINMUX(GMI_A18_PB1, UARTD, DOWN, TRISTATE, OUTPUT), /* NC */
+       DEFAULT_PINMUX(GMI_A19_PK7, UARTD, DOWN, TRISTATE, OUTPUT), /* NC */
+
+       DEFAULT_PINMUX(CAM_MCLK_PCC0, VI_ALT2, NORMAL, NORMAL, OUTPUT),
+       DEFAULT_PINMUX(PBB0, RSVD1, NORMAL, NORMAL, OUTPUT),
+       DEFAULT_PINMUX(PBB3, VGP3, NORMAL, NORMAL, OUTPUT),
+       DEFAULT_PINMUX(PBB4, VGP4, NORMAL, NORMAL, OUTPUT),
+       DEFAULT_PINMUX(PBB5, VGP5, NORMAL, NORMAL, OUTPUT),
+       DEFAULT_PINMUX(PBB6, VGP6, NORMAL, NORMAL, OUTPUT),
+       DEFAULT_PINMUX(PBB7, I2S4, NORMAL, NORMAL, OUTPUT),
+       DEFAULT_PINMUX(PCC1, RSVD1, NORMAL, NORMAL, OUTPUT),
+       DEFAULT_PINMUX(PCC2, I2S4, NORMAL, NORMAL, OUTPUT),
+
+       DEFAULT_PINMUX(JTAG_RTCK_PU7, RTCK, NORMAL, NORMAL, OUTPUT),
+
+       /* multiplexed VI_D2, VI_D3, VI_D4, VI_D5, VI_D6, VI_D7, VI_D8 and VI_D9
+        */
+       DEFAULT_PINMUX(KB_ROW0_PR0, RSVD2, NORMAL, TRISTATE, INPUT),
+       DEFAULT_PINMUX(KB_ROW1_PR1, RSVD2, NORMAL, TRISTATE, INPUT),
+       DEFAULT_PINMUX(KB_ROW2_PR2, RSVD2, NORMAL, TRISTATE, INPUT),
+       DEFAULT_PINMUX(KB_ROW3_PR3, RSVD2, NORMAL, TRISTATE, INPUT),
+       DEFAULT_PINMUX(KB_ROW4_PR4, RSVD3, NORMAL, TRISTATE, INPUT),
+       DEFAULT_PINMUX(KB_ROW5_PR5, KBC, NORMAL, TRISTATE, INPUT),
+       DEFAULT_PINMUX(KB_ROW6_PR6, KBC, NORMAL, TRISTATE, INPUT),
+       DEFAULT_PINMUX(KB_ROW7_PR7, KBC, NORMAL, TRISTATE, INPUT),
+       DEFAULT_PINMUX(KB_ROW8_PS0, KBC, NORMAL, TRISTATE, INPUT),
+       DEFAULT_PINMUX(KB_ROW9_PS1, KBC, NORMAL, TRISTATE, INPUT),
+
+       /* GPIOs */
+       DEFAULT_PINMUX(KB_ROW10_PS2, SDMMC2, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(KB_ROW11_PS3, SDMMC2, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(KB_ROW12_PS4, SDMMC2, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(KB_ROW13_PS5, SDMMC2, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(KB_ROW14_PS6, SDMMC2, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(KB_ROW15_PS7, SDMMC2, NORMAL, NORMAL, INPUT),
+
+       DEFAULT_PINMUX(KB_COL0_PQ0, KBC, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(KB_COL1_PQ1, KBC, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(KB_COL2_PQ2, KBC, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(KB_COL3_PQ3, KBC, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(KB_COL4_PQ4, KBC, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(KB_COL5_PQ5, KBC, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(KB_COL6_PQ6, KBC, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(KB_COL7_PQ7, KBC, NORMAL, NORMAL, INPUT),
+
+       DEFAULT_PINMUX(PV0, RSVD1, NORMAL, NORMAL, INPUT),
+
+       DEFAULT_PINMUX(CLK_32K_OUT_PA0, BLINK, DOWN, TRISTATE, OUTPUT), /* NC */
+       DEFAULT_PINMUX(SYS_CLK_REQ_PZ5, SYSCLK, NORMAL, NORMAL, INPUT),
+       /* multiplexed KB_COL0 */
+       DEFAULT_PINMUX(OWR, OWR, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(DAP1_FS_PN0, I2S0, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(DAP1_DIN_PN1, I2S0, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(DAP1_DOUT_PN2, I2S0, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(DAP1_SCLK_PN3, I2S0, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(CLK1_REQ_PEE2, DAP, NORMAL, NORMAL, OUTPUT),
+       DEFAULT_PINMUX(CLK1_OUT_PW4, EXTPERIPH1, NORMAL, NORMAL, OUTPUT),
+       DEFAULT_PINMUX(SPDIF_IN_PK6, SPDIF, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(SPDIF_OUT_PK5, SPDIF, NORMAL, NORMAL, OUTPUT),
+       DEFAULT_PINMUX(DAP2_FS_PA2, I2S1, NORMAL, TRISTATE, OUTPUT),
+       DEFAULT_PINMUX(DAP2_DIN_PA4, I2S1, NORMAL, TRISTATE, OUTPUT),
+       DEFAULT_PINMUX(DAP2_DOUT_PA5, I2S1, NORMAL, TRISTATE, OUTPUT),
+       DEFAULT_PINMUX(DAP2_SCLK_PA3, I2S1, NORMAL, TRISTATE, OUTPUT),
+
+       DEFAULT_PINMUX(SPI2_CS1_N_PW2, SPI2, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(SPI1_MOSI_PX4, SPI1, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(SPI1_SCK_PX5, SPI1, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(SPI1_CS0_N_PX6, SPI1, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(SPI1_MISO_PX7, SPI1, NORMAL, NORMAL, INPUT),
+
+       DEFAULT_PINMUX(PEX_L0_PRSNT_N_PDD0, PCIE, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(PEX_L0_RST_N_PDD1, PCIE, NORMAL, NORMAL, OUTPUT),
+       DEFAULT_PINMUX(PEX_L0_CLKREQ_N_PDD2, PCIE, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(PEX_WAKE_N_PDD3, PCIE, NORMAL, NORMAL, INPUT),
+
+       DEFAULT_PINMUX(PEX_L1_PRSNT_N_PDD4, PCIE, DOWN, TRISTATE, OUTPUT), /* NC */
+       DEFAULT_PINMUX(PEX_L1_RST_N_PDD5, PCIE, DOWN, TRISTATE, OUTPUT), /* NC */
+       DEFAULT_PINMUX(PEX_L1_CLKREQ_N_PDD6, PCIE, DOWN, TRISTATE, OUTPUT), /* NC */
+       DEFAULT_PINMUX(PEX_L2_PRSNT_N_PDD7, PCIE, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(PEX_L2_RST_N_PCC6, PCIE, NORMAL, NORMAL, OUTPUT),
+       DEFAULT_PINMUX(PEX_L2_CLKREQ_N_PCC7, PCIE, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(HDMI_CEC_PEE3, CEC, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(HDMI_INT_PN7, RSVD1, NORMAL, NORMAL, INPUT),
+
+       DEFAULT_PINMUX(GMI_IORDY_PI5, RSVD1, DOWN, TRISTATE, OUTPUT), /* NC */
+       DEFAULT_PINMUX(GMI_AD12_PH4, NAND, DOWN, TRISTATE, OUTPUT), /* NC */
+       DEFAULT_PINMUX(GMI_AD14_PH6, NAND, DOWN, TRISTATE, OUTPUT), /* NC */
+
+       DEFAULT_PINMUX(SPI2_SCK_PX2, GMI, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(KB_ROW8_PS0, KBC, NORMAL, NORMAL, INPUT),
+};
+
+static struct pmux_pingrp_config unused_pins_lowpower[] = {
+       DEFAULT_PINMUX(GMI_WAIT_PI7, NAND, DOWN, TRISTATE, OUTPUT),
+       DEFAULT_PINMUX(GMI_ADV_N_PK0, NAND, DOWN, TRISTATE, OUTPUT),
+       DEFAULT_PINMUX(GMI_CLK_PK1, NAND, DOWN, TRISTATE, OUTPUT),
+       DEFAULT_PINMUX(GMI_CS3_N_PK4, NAND, DOWN, TRISTATE, OUTPUT),
+       DEFAULT_PINMUX(GMI_CS7_N_PI6, NAND, DOWN, TRISTATE, OUTPUT),
+       DEFAULT_PINMUX(GMI_AD0_PG0, NAND, DOWN, TRISTATE, OUTPUT),
+       DEFAULT_PINMUX(GMI_AD1_PG1, NAND, DOWN, TRISTATE, OUTPUT),
+       DEFAULT_PINMUX(GMI_AD2_PG2, NAND, DOWN, TRISTATE, OUTPUT),
+       DEFAULT_PINMUX(GMI_AD3_PG3, NAND, DOWN, TRISTATE, OUTPUT),
+       DEFAULT_PINMUX(GMI_AD4_PG4, NAND, DOWN, TRISTATE, OUTPUT),
+       DEFAULT_PINMUX(GMI_AD5_PG5, NAND, DOWN, TRISTATE, OUTPUT),
+       DEFAULT_PINMUX(GMI_AD6_PG6, NAND, DOWN, TRISTATE, OUTPUT),
+       DEFAULT_PINMUX(GMI_AD7_PG7, NAND, DOWN, TRISTATE, OUTPUT),
+       DEFAULT_PINMUX(GMI_AD9_PH1, PWM1, DOWN, TRISTATE, OUTPUT),
+       DEFAULT_PINMUX(GMI_AD11_PH3, NAND, DOWN, TRISTATE, OUTPUT),
+       DEFAULT_PINMUX(GMI_AD13_PH5, NAND, DOWN, TRISTATE, OUTPUT),
+       DEFAULT_PINMUX(GMI_WR_N_PI0, NAND, DOWN, TRISTATE, OUTPUT),
+       DEFAULT_PINMUX(GMI_OE_N_PI1, NAND, NORMAL, NORMAL, INPUT),
+       DEFAULT_PINMUX(GMI_DQS_PI2, NAND, DOWN, TRISTATE, OUTPUT),
+};
+
+static struct pmux_drvgrp_config apalis_t30_padctrl[] = {
+       /* (_drvgrp, _slwf, _slwr, _drvup, _drvdn, _lpmd, _schmt, _hsm) */
+       DEFAULT_PADCFG(SDIO1, SDIOCFG_DRVUP_SLWF, SDIOCFG_DRVDN_SLWR, \
+               SDIOCFG_DRVUP, SDIOCFG_DRVDN, NONE, DISABLE, DISABLE),
+};
+#endif /* _PINMUX_CONFIG_APALIS_T30_H_ */
index ed043f49b37d70e2739b1c60ac061862cb70ccbf..f4bc7d8728eeda63a0df9b133c3f9fa5757180ee 100644 (file)
@@ -35,7 +35,7 @@ void pinmux_init(void)
 void pin_mux_usb(void)
 {
        /* Reset ASIX using LAN_RESET */
-       gpio_request(GPIO_PDD0, NULL);
+       gpio_request(GPIO_PDD0, "LAN_RESET");
        gpio_direction_output(GPIO_PDD0, 0);
        udelay(5);
        gpio_set_value(GPIO_PDD0, 1);
index 25fbb55c8e6c126c0ebc0f433f584ccf934aa40b..8f4fe310d7d2b23bef6dd5da1bd2e50c50615d6f 100644 (file)
@@ -8,12 +8,11 @@
 #include <common.h>
 #include <config.h>
 #include <command.h>
+#include <elf.h>
 
 /*
  * FIXME: Add code to test image and it's header.
  */
-extern int valid_elf_image (unsigned long addr);
-
 static int
 image_check(ulong addr)
 {
index b19d3793b467b0e8d88ffb6ae287a1ebf1b9a833..6cc4de8a73f6ab24a20760ded2d64e395b65a94f 100644 (file)
@@ -233,6 +233,7 @@ obj-$(CONFIG_SPL_ENV_SUPPORT) += env_flags.o
 obj-$(CONFIG_SPL_ENV_SUPPORT) += env_callback.o
 obj-$(CONFIG_ENV_IS_NOWHERE) += env_nowhere.o
 obj-$(CONFIG_ENV_IS_IN_MMC) += env_mmc.o
+obj-$(CONFIG_ENV_IS_IN_FAT) += env_fat.o
 obj-$(CONFIG_ENV_IS_IN_NAND) += env_nand.o
 obj-$(CONFIG_ENV_IS_IN_SPI_FLASH) += env_sf.o
 obj-$(CONFIG_ENV_IS_IN_FLASH) += env_flash.o
@@ -265,4 +266,6 @@ obj-y += aboot.o
 obj-y += fb_mmc.o
 endif
 
+obj-$(CONFIG_CMD_BLOB) += cmd_blob.o
+
 CFLAGS_env_embedded.o := -Wa,--no-warn -DENV_CRC=$(shell tools/envcrc 2>/dev/null)
index e6aa298d5a4e8bc5255f7bcacf2022bc7dbf0f8f..b5bebc9dc862727b7aa2386f64691ace23475cc0 100644 (file)
@@ -128,14 +128,11 @@ int init_func_watchdog_reset(void)
 }
 #endif /* CONFIG_WATCHDOG */
 
-void __board_add_ram_info(int use_default)
+__weak void board_add_ram_info(int use_default)
 {
        /* please define platform specific board_add_ram_info() */
 }
 
-void board_add_ram_info(int)
-       __attribute__ ((weak, alias("__board_add_ram_info")));
-
 static int init_baud_rate(void)
 {
        gd->baudrate = getenv_ulong("baudrate", 10, CONFIG_BAUDRATE);
@@ -221,7 +218,7 @@ static int show_dram_config(void)
        return 0;
 }
 
-void __dram_init_banksize(void)
+__weak void dram_init_banksize(void)
 {
 #if defined(CONFIG_NR_DRAM_BANKS) && defined(CONFIG_SYS_SDRAM_BASE)
        gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE;
@@ -229,9 +226,6 @@ void __dram_init_banksize(void)
 #endif
 }
 
-void dram_init_banksize(void)
-       __attribute__((weak, alias("__dram_init_banksize")));
-
 #if defined(CONFIG_HARD_I2C) || defined(CONFIG_SYS_I2C)
 static int init_func_i2c(void)
 {
index 7e1a76d97f73be5d2eb3d347dffbb82d301b7522..7c339008ed2a46b91677d4c4c9e5e97fd58f4a1f 100644 (file)
@@ -60,7 +60,7 @@ DECLARE_GLOBAL_DATA_PTR;
 
 ulong monitor_flash_len;
 
-int __board_flash_wp_on(void)
+__weak int board_flash_wp_on(void)
 {
        /*
         * Most flashes can't be detected when write protection is enabled,
@@ -70,16 +70,10 @@ int __board_flash_wp_on(void)
        return 0;
 }
 
-int board_flash_wp_on(void)
-       __attribute__ ((weak, alias("__board_flash_wp_on")));
-
-void __cpu_secondary_init_r(void)
+__weak void cpu_secondary_init_r(void)
 {
 }
 
-void cpu_secondary_init_r(void)
-       __attribute__ ((weak, alias("__cpu_secondary_init_r")));
-
 static int initr_secondary_cpu(void)
 {
        /*
@@ -354,7 +348,7 @@ static int initr_flash(void)
 }
 #endif
 
-#ifdef CONFIG_PPC
+#if defined(CONFIG_PPC) && !defined(CONFIG_DM_SPI)
 static int initr_spi(void)
 {
        /* PPC does this here */
@@ -370,7 +364,7 @@ static int initr_spi(void)
 
 #ifdef CONFIG_CMD_NAND
 /* go init the NAND */
-int initr_nand(void)
+static int initr_nand(void)
 {
        puts("NAND:  ");
        nand_init();
@@ -380,7 +374,7 @@ int initr_nand(void)
 
 #if defined(CONFIG_CMD_ONENAND)
 /* go init the NAND */
-int initr_onenand(void)
+static int initr_onenand(void)
 {
        puts("NAND:  ");
        onenand_init();
@@ -389,7 +383,7 @@ int initr_onenand(void)
 #endif
 
 #ifdef CONFIG_GENERIC_MMC
-int initr_mmc(void)
+static int initr_mmc(void)
 {
        puts("MMC:   ");
        mmc_initialize(gd->bd);
@@ -398,7 +392,7 @@ int initr_mmc(void)
 #endif
 
 #ifdef CONFIG_HAS_DATAFLASH
-int initr_dataflash(void)
+static int initr_dataflash(void)
 {
        AT91F_DataflashInit();
        dataflash_print_info();
index ff81a271a559232c07e3f7c1cbebc4bf327731c3..17ed3897f99391cbc0eb8f962d46ae138a4d1d17 100644 (file)
@@ -9,6 +9,7 @@
 #include <common.h>
 #include <bootstage.h>
 #include <bzlib.h>
+#include <errno.h>
 #include <fdt_support.h>
 #include <lmb.h>
 #include <malloc.h>
@@ -83,6 +84,7 @@ static int bootm_find_os(cmd_tbl_t *cmdtp, int flag, int argc,
 {
        const void *os_hdr;
        bool ep_found = false;
+       int ret;
 
        /* get kernel image header, start address and length */
        os_hdr = boot_get_kernel(cmdtp, flag, argc, argv,
@@ -102,6 +104,7 @@ static int bootm_find_os(cmd_tbl_t *cmdtp, int flag, int argc,
 
                images.os.end = image_get_image_end(os_hdr);
                images.os.load = image_get_load(os_hdr);
+               images.os.arch = image_get_arch(os_hdr);
                break;
 #endif
 #if defined(CONFIG_FIT)
@@ -129,6 +132,13 @@ static int bootm_find_os(cmd_tbl_t *cmdtp, int flag, int argc,
                        return 1;
                }
 
+               if (fit_image_get_arch(images.fit_hdr_os,
+                                      images.fit_noffset_os,
+                                      &images.os.arch)) {
+                       puts("Can't get image ARCH!\n");
+                       return 1;
+               }
+
                images.os.end = fit_get_end(images.fit_hdr_os);
 
                if (fit_image_get_load(images.fit_hdr_os, images.fit_noffset_os,
@@ -156,8 +166,17 @@ static int bootm_find_os(cmd_tbl_t *cmdtp, int flag, int argc,
                return 1;
        }
 
-       /* find kernel entry point */
-       if (images.legacy_hdr_valid) {
+       /* If we have a valid setup.bin, we will use that for entry (x86) */
+       if (images.os.arch == IH_ARCH_I386) {
+               ulong len;
+
+               ret = boot_get_setup(&images, IH_ARCH_I386, &images.ep, &len);
+               if (ret < 0 && ret != -ENOENT) {
+                       puts("Could not find a valid setup.bin for x86\n");
+                       return 1;
+               }
+               /* Kernel entry point is the setup.bin */
+       } else if (images.legacy_hdr_valid) {
                images.ep = image_get_ep(&images.legacy_hdr_os_copy);
 #if defined(CONFIG_FIT)
        } else if (images.fit_uname_os) {
diff --git a/common/cmd_blob.c b/common/cmd_blob.c
new file mode 100644 (file)
index 0000000..82ecaf0
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ *
+ * Command for encapsulating/decapsulating blob of memory.
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <command.h>
+#include <environment.h>
+#include <malloc.h>
+#include <asm/byteorder.h>
+#include <linux/compiler.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/**
+ * blob_decap() - Decapsulate the data as a blob
+ * @key_mod:   - Pointer to key modifier/key
+ * @src:       - Address of data to be decapsulated
+ * @dst:       - Address of data to be decapsulated
+ * @len:       - Size of data to be decapsulated
+ *
+ * Returns zero on success,and negative on error.
+ */
+__weak int blob_decap(u8 *key_mod, u8 *src, u8 *dst, u32 len)
+{
+       return 0;
+}
+
+/**
+ * blob_encap() - Encapsulate the data as a blob
+ * @key_mod:   - Pointer to key modifier/key
+ * @src:       - Address of data to be encapsulated
+ * @dst:       - Address of data to be encapsulated
+ * @len:       - Size of data to be encapsulated
+ *
+ * Returns zero on success,and negative on error.
+ */
+__weak int blob_encap(u8 *key_mod, u8 *src, u8 *dst, u32 len)
+{
+       return 0;
+}
+
+/**
+ * do_blob() - Handle the "blob" command-line command
+ * @cmdtp:     Command data struct pointer
+ * @flag:      Command flag
+ * @argc:      Command-line argument count
+ * @argv:      Array of command-line arguments
+ *
+ * Returns zero on success, CMD_RET_USAGE in case of misuse and negative
+ * on error.
+ */
+static int do_blob(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+{
+       uint32_t key_addr, src_addr, dst_addr, len;
+       uint8_t *km_ptr, *src_ptr, *dst_ptr;
+       int enc, ret = 0;
+
+       if (argc != 6)
+               return CMD_RET_USAGE;
+
+       if (!strncmp(argv[1], "enc", 3))
+               enc = 1;
+       else if (!strncmp(argv[1], "dec", 3))
+               enc = 0;
+       else
+               return CMD_RET_USAGE;
+
+       src_addr = simple_strtoul(argv[2], NULL, 16);
+       dst_addr = simple_strtoul(argv[3], NULL, 16);
+       len = simple_strtoul(argv[4], NULL, 16);
+       key_addr = simple_strtoul(argv[5], NULL, 16);
+
+       km_ptr = (uint8_t *)key_addr;
+       src_ptr = (uint8_t *)src_addr;
+       dst_ptr = (uint8_t *)dst_addr;
+
+       if (enc)
+               ret = blob_encap(km_ptr, src_ptr, dst_ptr, len);
+       else
+               ret = blob_decap(km_ptr, src_ptr, dst_ptr, len);
+
+       return ret;
+}
+
+/***************************************************/
+static char blob_help_text[] =
+       "enc src dst len km - Encapsulate and create blob of data\n"
+       "                          $len bytes long at address $src and\n"
+       "                          store the result at address $dst.\n"
+       "                          $km is the 16 byte key modifier\n"
+       "                          is also required for generation/use as\n"
+       "                          key for cryptographic operation. Key\n"
+       "                          modifier should be 16 byte long.\n"
+       "blob dec src dst len km - Decapsulate the  blob of data at address\n"
+       "                          $src and store result of $len byte at\n"
+       "                          addr $dst.\n"
+       "                          $km is the 16 byte key modifier\n"
+       "                          is also required for generation/use as\n"
+       "                          key for cryptographic operation. Key\n"
+       "                          modifier should be 16 byte long.\n";
+
+U_BOOT_CMD(
+       blob, 6, 1, do_blob,
+       "Blob encapsulation/decryption",
+       blob_help_text
+);
index 843ec6e0c2696380d176740bbb5864b05e46624b..67233600b157244409c2710afa606337d2ebaf80 100644 (file)
@@ -12,6 +12,7 @@
 #include <bootm.h>
 #include <command.h>
 #include <environment.h>
+#include <errno.h>
 #include <image.h>
 #include <lmb.h>
 #include <malloc.h>
index ab9c7e332d97b200109e09e464b0fb786ac967c6..42a52965c2722282c36e6ebeaa0049c8c21b4c9f 100644 (file)
@@ -14,6 +14,7 @@
  */
 
 #include <common.h>
+#include <bootm.h>
 #include <command.h>
 #include <linux/ctype.h>
 #include <net.h>
@@ -28,8 +29,7 @@ static unsigned long load_elf_image_phdr(unsigned long addr);
 static unsigned long load_elf_image_shdr(unsigned long addr);
 
 /* Allow ports to override the default behavior */
-__attribute__((weak))
-unsigned long do_bootelf_exec(ulong (*entry)(int, char * const[]),
+static unsigned long do_bootelf_exec(ulong (*entry)(int, char * const[]),
                               int argc, char * const argv[])
 {
        unsigned long ret;
index 11f4e4031daddca8570892c53c47e16a198cee8a..65d6df451c6d4f4c5dc9c26a94a02a536b42386e 100644 (file)
@@ -12,7 +12,7 @@
 #include <dm.h>
 #include <asm/gpio.h>
 
-int __weak name_to_gpio(const char *name)
+__weak int name_to_gpio(const char *name)
 {
        return simple_strtoul(name, NULL, 10);
 }
@@ -25,13 +25,6 @@ enum gpio_cmd {
 };
 
 #if defined(CONFIG_DM_GPIO) && !defined(gpio_status)
-static const char * const gpio_function[GPIOF_COUNT] = {
-       "input",
-       "output",
-       "unused",
-       "unknown",
-       "func",
-};
 
 /* A few flags used by show_gpio() */
 enum {
@@ -40,22 +33,16 @@ enum {
        FLAG_SHOW_NEWLINE       = 1 << 2,
 };
 
-static void show_gpio(struct udevice *dev, const char *bank_name, int offset,
-                     int *flagsp)
+static void gpio_get_description(struct udevice *dev, const char *bank_name,
+                                int offset, int *flagsp)
 {
-       struct dm_gpio_ops *ops = gpio_get_ops(dev);
-       int func = GPIOF_UNKNOWN;
        char buf[80];
        int ret;
 
-       BUILD_BUG_ON(GPIOF_COUNT != ARRAY_SIZE(gpio_function));
-
-       if (ops->get_function) {
-               ret = ops->get_function(dev, offset);
-               if (ret >= 0 && ret < ARRAY_SIZE(gpio_function))
-                       func = ret;
-       }
-       if (!(*flagsp & FLAG_SHOW_ALL) && func == GPIOF_UNUSED)
+       ret = gpio_get_function(dev, offset, NULL);
+       if (ret < 0)
+               goto err;
+       if (!(*flagsp & FLAG_SHOW_ALL) && ret == GPIOF_UNUSED)
                return;
        if ((*flagsp & FLAG_SHOW_BANK) && bank_name) {
                if (*flagsp & FLAG_SHOW_NEWLINE) {
@@ -65,20 +52,15 @@ static void show_gpio(struct udevice *dev, const char *bank_name, int offset,
                printf("Bank %s:\n", bank_name);
                *flagsp &= ~FLAG_SHOW_BANK;
        }
-       *buf = '\0';
-       if (ops->get_state) {
-               ret = ops->get_state(dev, offset, buf, sizeof(buf));
-               if (ret) {
-                       puts("<unknown>");
-                       return;
-               }
-       } else {
-               sprintf(buf, "%s%u: %8s %d", bank_name, offset,
-                       gpio_function[func], ops->get_value(dev, offset));
-       }
 
-       puts(buf);
-       puts("\n");
+       ret = gpio_get_status(dev, offset, buf, sizeof(buf));
+       if (ret)
+               goto err;
+
+       printf("%s\n", buf);
+       return;
+err:
+       printf("Error %d\n", ret);
 }
 
 static int do_gpio_status(bool all, const char *gpio_name)
@@ -101,8 +83,10 @@ static int do_gpio_status(bool all, const char *gpio_name)
                if (all)
                        flags |= FLAG_SHOW_ALL;
                bank_name = gpio_get_bank_info(dev, &num_bits);
-               if (!num_bits)
+               if (!num_bits) {
+                       debug("GPIO device %s has no bits\n", dev->name);
                        continue;
+               }
                banklen = bank_name ? strlen(bank_name) : 0;
 
                if (!gpio_name || !bank_name ||
@@ -113,11 +97,12 @@ static int do_gpio_status(bool all, const char *gpio_name)
                        p = gpio_name + banklen;
                        if (gpio_name && *p) {
                                offset = simple_strtoul(p, NULL, 10);
-                               show_gpio(dev, bank_name, offset, &flags);
+                               gpio_get_description(dev, bank_name, offset,
+                                                    &flags);
                        } else {
                                for (offset = 0; offset < num_bits; offset++) {
-                                       show_gpio(dev, bank_name, offset,
-                                                 &flags);
+                                       gpio_get_description(dev, bank_name,
+                                                            offset, &flags);
                                }
                        }
                }
index c60e8d10df6e1ad244a154a795bff79a4d51c8df..95a6f89a845da57b5e5430b339dbda12f4d5d354 100644 (file)
@@ -8,10 +8,13 @@
 
 #include <common.h>
 #include <div64.h>
+#include <dm.h>
 #include <malloc.h>
+#include <spi.h>
 #include <spi_flash.h>
 
 #include <asm/io.h>
+#include <dm/device-internal.h>
 
 static struct spi_flash *flash;
 
@@ -80,7 +83,12 @@ static int do_spi_flash_probe(int argc, char * const argv[])
        unsigned int speed = CONFIG_SF_DEFAULT_SPEED;
        unsigned int mode = CONFIG_SF_DEFAULT_MODE;
        char *endp;
+#ifdef CONFIG_DM_SPI_FLASH
+       struct udevice *new, *bus_dev;
+       int ret;
+#else
        struct spi_flash *new;
+#endif
 
        if (argc >= 2) {
                cs = simple_strtoul(argv[1], &endp, 0);
@@ -108,6 +116,23 @@ static int do_spi_flash_probe(int argc, char * const argv[])
                        return -1;
        }
 
+#ifdef CONFIG_DM_SPI_FLASH
+       /* Remove the old device, otherwise probe will just be a nop */
+       ret = spi_find_bus_and_cs(bus, cs, &bus_dev, &new);
+       if (!ret) {
+               device_remove(new);
+               device_unbind(new);
+       }
+       flash = NULL;
+       ret = spi_flash_probe_bus_cs(bus, cs, speed, mode, &new);
+       if (ret) {
+               printf("Failed to initialize SPI flash at %u:%u (error %d)\n",
+                      bus, cs, ret);
+               return 1;
+       }
+
+       flash = new->uclass_priv;
+#else
        new = spi_flash_probe(bus, cs, speed, mode);
        if (!new) {
                printf("Failed to initialize SPI flash at %u:%u\n", bus, cs);
@@ -117,6 +142,7 @@ static int do_spi_flash_probe(int argc, char * const argv[])
        if (flash)
                spi_flash_free(flash);
        flash = new;
+#endif
 
        return 0;
 }
index be5709c6173d09562a3f274fd6c1a0e4756c67af..64c3ffcf423b35fc1b0a65daccb99d490a053c5f 100644 (file)
@@ -11,6 +11,7 @@
 
 #include <common.h>
 #include <command.h>
+#include <dm.h>
 #include <errno.h>
 #include <spi.h>
 
@@ -42,19 +43,38 @@ static uchar                din[MAX_SPI_BYTES];
 static int do_spi_xfer(int bus, int cs)
 {
        struct spi_slave *slave;
-       int rcode = 0;
-
+       int ret = 0;
+
+#ifdef CONFIG_DM_SPI
+       char name[30], *str;
+       struct udevice *dev;
+
+       snprintf(name, sizeof(name), "generic_%d:%d", bus, cs);
+       str = strdup(name);
+       ret = spi_get_bus_and_cs(bus, cs, 1000000, mode, "spi_generic_drv",
+                                str, &dev, &slave);
+       if (ret)
+               return ret;
+#else
        slave = spi_setup_slave(bus, cs, 1000000, mode);
        if (!slave) {
                printf("Invalid device %d:%d\n", bus, cs);
                return -EINVAL;
        }
+#endif
 
-       spi_claim_bus(slave);
-       if (spi_xfer(slave, bitlen, dout, din,
-                    SPI_XFER_BEGIN | SPI_XFER_END) != 0) {
-               printf("Error during SPI transaction\n");
-               rcode = -EIO;
+       ret = spi_claim_bus(slave);
+       if (ret)
+               goto done;
+       ret = spi_xfer(slave, bitlen, dout, din,
+                      SPI_XFER_BEGIN | SPI_XFER_END);
+#ifndef CONFIG_DM_SPI
+       /* We don't get an error code in this case */
+       if (ret)
+               ret = -EIO;
+#endif
+       if (ret) {
+               printf("Error %d during SPI transaction\n", ret);
        } else {
                int j;
 
@@ -62,10 +82,13 @@ static int do_spi_xfer(int bus, int cs)
                        printf("%02X", din[j]);
                printf("\n");
        }
+done:
        spi_release_bus(slave);
+#ifndef CONFIG_DM_SPI
        spi_free_slave(slave);
+#endif
 
-       return rcode;
+       return ret;
 }
 
 /*
index 5a2f411600280acd5ba435762083f8394da61377..4695386a332ab867c12df32e938d4976ce7f0115 100644 (file)
@@ -7,6 +7,7 @@
 
 #include <common.h>
 #include <stdarg.h>
+#include <iomux.h>
 #include <malloc.h>
 #include <os.h>
 #include <serial.h>
@@ -621,7 +622,7 @@ inline void dbg(const char *fmt, ...)
 
 }
 #else
-inline void dbg(const char *fmt, ...)
+static inline void dbg(const char *fmt, ...)
 {
 }
 #endif
index b8ce1b581aab463f65330e4dcc769f3fc00b1f19..bb299bccfff7073791ad9b1cedf5c1d3c171d190 100644 (file)
 
 #include <common.h>
 #include <cros_ec.h>
+#include <dm.h>
+#include <errno.h>
+
 DECLARE_GLOBAL_DATA_PTR;
 
+#ifndef CONFIG_DM_CROS_EC
 struct local_info {
        struct cros_ec_dev *cros_ec_dev;        /* Pointer to cros_ec device */
        int cros_ec_err;                        /* Error for cros_ec, 0 if ok */
 };
 
 static struct local_info local;
+#endif
 
 struct cros_ec_dev *board_get_cros_ec_dev(void)
 {
+#ifdef CONFIG_DM_CROS_EC
+       struct udevice *dev;
+       int ret;
+
+       ret = uclass_get_device(UCLASS_CROS_EC, 0, &dev);
+       if (ret) {
+               debug("%s: Error %d\n", __func__, ret);
+               return NULL;
+       }
+       return dev->uclass_priv;
+#else
        return local.cros_ec_dev;
+#endif
 }
 
 static int board_init_cros_ec_devices(const void *blob)
 {
+#ifndef CONFIG_DM_CROS_EC
        local.cros_ec_err = cros_ec_init(blob, &local.cros_ec_dev);
        if (local.cros_ec_err)
                return -1;  /* Will report in board_late_init() */
+#endif
 
        return 0;
 }
@@ -40,5 +59,16 @@ int cros_ec_board_init(void)
 
 int cros_ec_get_error(void)
 {
+#ifdef CONFIG_DM_CROS_EC
+       struct udevice *dev;
+       int ret;
+
+       ret = uclass_get_device(UCLASS_CROS_EC, 0, &dev);
+       if (ret && ret != -ENODEV)
+               return ret;
+
+       return 0;
+#else
        return local.cros_ec_err;
+#endif
 }
index 5a734a9321a9400a73ee8024f29bcdb17d546ee6..749605fe3fa89ab798a0ebde92f1f90e4a40fb2b 100644 (file)
@@ -124,7 +124,7 @@ int env_init(void)
  * The legacy NAND code saved the environment in the first NAND device i.e.,
  * nand_dev_desc + 0. This is also the behaviour using the new NAND code.
  */
-int writeenv(size_t offset, u_char *buf)
+static int writeenv(size_t offset, u_char *buf)
 {
        size_t end = offset + CONFIG_ENV_RANGE;
        size_t amount_saved = 0;
@@ -233,7 +233,7 @@ int saveenv(void)
 }
 #endif /* CMD_SAVEENV */
 
-int readenv(size_t offset, u_char *buf)
+static int readenv(size_t offset, u_char *buf)
 {
        size_t end = offset + CONFIG_ENV_RANGE;
        size_t amount_loaded = 0;
index 37ab13ae17842309339fa9a70a42e49b8669207e..5e3729c2c2d62dfb201e2329081318f1657fa422 100644 (file)
@@ -12,6 +12,7 @@
 #include <common.h>
 #include <environment.h>
 #include <malloc.h>
+#include <spi.h>
 #include <spi_flash.h>
 #include <search.h>
 #include <errno.h>
index b97ca48307dcba1493d9426bde8e6f706d8fa1ed..88fcfc8cb6fc652e8fb5242869ebdb4c0813f5dd 100644 (file)
@@ -27,10 +27,12 @@ unsigned long get_version(void)
 # define i2c_write         dummy
 # define i2c_read          dummy
 #endif
-#ifndef CONFIG_CMD_SPI
+#if !defined(CONFIG_CMD_SPI) || defined(CONFIG_DM_SPI)
 # define spi_init          dummy
 # define spi_setup_slave   dummy
 # define spi_free_slave    dummy
+#endif
+#ifndef CONFIG_CMD_SPI
 # define spi_claim_bus     dummy
 # define spi_release_bus   dummy
 # define spi_xfer          dummy
index 255c4cac9cafa328d33cd382e524207c1728c7cc..a272ea2e83456d9a50018ffb1752b0e2016ddcf7 100644 (file)
@@ -1434,7 +1434,7 @@ void fit_conf_print(const void *fit, int noffset, const char *p)
                printf("%s  FDT:          %s\n", p, uname);
 }
 
-int fit_image_select(const void *fit, int rd_noffset, int verify)
+static int fit_image_select(const void *fit, int rd_noffset, int verify)
 {
        fit_image_print(fit, rd_noffset, "   ");
 
@@ -1497,6 +1497,8 @@ static const char *fit_get_image_type_property(int type)
                return FIT_KERNEL_PROP;
        case IH_TYPE_RAMDISK:
                return FIT_RAMDISK_PROP;
+       case IH_TYPE_X86_SETUP:
+               return FIT_SETUP_PROP;
        }
 
        return "unknown";
@@ -1591,7 +1593,7 @@ int fit_image_load(bootm_headers_t *images, ulong addr,
        }
 
        bootstage_mark(bootstage_id + BOOTSTAGE_SUB_CHECK_ARCH);
-#ifndef USE_HOSTCC
+#if !defined(USE_HOSTCC) && !defined(CONFIG_SANDBOX)
        if (!fit_image_check_target_arch(fit, noffset)) {
                puts("Unsupported Architecture\n");
                bootstage_error(bootstage_id + BOOTSTAGE_SUB_CHECK_ARCH);
@@ -1693,3 +1695,23 @@ int fit_image_load(bootm_headers_t *images, ulong addr,
 
        return noffset;
 }
+
+int boot_get_setup_fit(bootm_headers_t *images, uint8_t arch,
+                       ulong *setup_start, ulong *setup_len)
+{
+       int noffset;
+       ulong addr;
+       ulong len;
+       int ret;
+
+       addr = map_to_sysmem(images->fit_hdr_os);
+       noffset = fit_get_node_from_config(images, FIT_SETUP_PROP, addr);
+       if (noffset < 0)
+               return noffset;
+
+       ret = fit_image_load(images, addr, NULL, NULL, arch,
+                            IH_TYPE_X86_SETUP, BOOTSTAGE_ID_FIT_SETUP_START,
+                            FIT_LOAD_REQUIRED, setup_start, &len);
+
+       return ret;
+}
index 085771c7639b6a4aaed005dcef5f305dc3fe7e4e..640e83b7bdf8013d02416615faf796c483a12d0f 100644 (file)
@@ -143,6 +143,7 @@ static const table_entry_t uimage_type[] = {
        {       IH_TYPE_UBLIMAGE,   "ublimage",   "Davinci UBL image",},
        {       IH_TYPE_MXSIMAGE,   "mxsimage",   "Freescale MXS Boot Image",},
        {       IH_TYPE_ATMELIMAGE, "atmelimage", "ATMEL ROM-Boot Image",},
+       {       IH_TYPE_X86_SETUP,  "x86_setup",  "x86 setup.bin",    },
        {       -1,                 "",           "",                   },
 };
 
@@ -1136,6 +1137,16 @@ error:
 }
 #endif /* CONFIG_SYS_BOOT_RAMDISK_HIGH */
 
+int boot_get_setup(bootm_headers_t *images, uint8_t arch,
+                  ulong *setup_start, ulong *setup_len)
+{
+#if defined(CONFIG_FIT)
+       return boot_get_setup_fit(images, arch, setup_start, setup_len);
+#else
+       return -ENOENT;
+#endif
+}
+
 #ifdef CONFIG_SYS_BOOT_GET_CMDLINE
 /**
  * boot_get_cmdline - allocate and initialize kernel cmdline
index 217ec9dbd2e9ec3cefdaea4a63e5be2725b445dc..689d30eb25c9ad898237c92bd7401bfea0a7976b 100644 (file)
@@ -1023,7 +1023,7 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y)
 
        switch (bmp_bpix) {
        case 1: /* pass through */
-       case 8:
+       case 8: {
 #ifdef CONFIG_LCD_BMP_RLE8
                u32 compression = get_unaligned_le32(&bmp->header.compression);
                if (compression == BMP_BI_RLE8) {
@@ -1056,7 +1056,7 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y)
                        fb -= byte_width + lcd_line_length;
                }
                break;
-
+       }
 #if defined(CONFIG_BMP_16BPP)
        case 16:
                for (i = 0; i < height; ++i) {
index 94afeb290098dc4b1356496ade659d1985fcd143..e81c074f36c60a92e8223eed055e5b022c697ad8 100644 (file)
@@ -105,12 +105,9 @@ static inline void *menu_item_destroy(struct menu *m,
        return NULL;
 }
 
-void __menu_display_statusline(struct menu *m)
+__weak void menu_display_statusline(struct menu *m)
 {
-       return;
 }
-void menu_display_statusline(struct menu *m)
-       __attribute__ ((weak, alias("__menu_display_statusline")));
 
 /*
  * Display a menu so the user can make a choice of an item. First display its
index be54b1011018192327fdc0bcfd368d7285e0fd44..96b10648d869620ddb3e15a819528de0d29ab2e0 100644 (file)
@@ -19,7 +19,7 @@ static inline void mdm_readline(char *buf, int bufsiz)
        for(;;) {
                c = serial_getc();
 
-               /*              dbg("(%c)", c); */
+               debug("(%c)", c);
 
                switch(c) {
                case '\r':
@@ -40,7 +40,6 @@ static inline void mdm_readline(char *buf, int bufsiz)
        }
 }
 
-extern void  dbg(const char *fmt, ...);
 int mdm_init (void)
 {
        char env_str[16];
@@ -66,15 +65,15 @@ int mdm_init (void)
                        serial_puts("\n");
                        for(;;) {
                                mdm_readline(console_buffer, CONFIG_SYS_CBSIZE);
-                               dbg("ini%d: [%s]", i, console_buffer);
+                               debug("ini%d: [%s]", i, console_buffer);
 
                                if ((strcmp(console_buffer, "OK") == 0) ||
                                        (strcmp(console_buffer, "ERROR") == 0)) {
-                                       dbg("ini%d: cmd done", i);
+                                       debug("ini%d: cmd done", i);
                                        break;
                                } else /* in case we are originating call ... */
                                        if (strncmp(console_buffer, "CONNECT", 7) == 0) {
-                                               dbg("ini%d: connect", i);
+                                               debug("ini%d: connect", i);
                                                return 0;
                                        }
                        }
@@ -90,9 +89,9 @@ int mdm_init (void)
        for(;i > 1;) { /* if 'i' > 1 - wait for connection
                                  message from modem */
                mdm_readline(console_buffer, CONFIG_SYS_CBSIZE);
-               dbg("ini_f: [%s]", console_buffer);
+               debug("ini_f: [%s]", console_buffer);
                if (strncmp(console_buffer, "CONNECT", 7) == 0) {
-                       dbg("ini_f: connected");
+                       debug("ini_f: connected");
                        return 0;
                }
        }
index 82328150cba17ceb382c1ee111595c41b8fbde00..68c595d2d79c292e3ac9b93ae55b0b22bf0e27f0 100644 (file)
@@ -39,39 +39,39 @@ char *stdio_names[MAX_FILES] = { "stdin", "stdout", "stderr" };
 #endif
 
 #ifdef CONFIG_SYS_DEVICE_NULLDEV
-void nulldev_putc(struct stdio_dev *dev, const char c)
+static void nulldev_putc(struct stdio_dev *dev, const char c)
 {
        /* nulldev is empty! */
 }
 
-void nulldev_puts(struct stdio_dev *dev, const char *s)
+static void nulldev_puts(struct stdio_dev *dev, const char *s)
 {
        /* nulldev is empty! */
 }
 
-int nulldev_input(struct stdio_dev *dev)
+static int nulldev_input(struct stdio_dev *dev)
 {
        /* nulldev is empty! */
        return 0;
 }
 #endif
 
-void stdio_serial_putc(struct stdio_dev *dev, const char c)
+static void stdio_serial_putc(struct stdio_dev *dev, const char c)
 {
        serial_putc(c);
 }
 
-void stdio_serial_puts(struct stdio_dev *dev, const char *s)
+static void stdio_serial_puts(struct stdio_dev *dev, const char *s)
 {
        serial_puts(s);
 }
 
-int stdio_serial_getc(struct stdio_dev *dev)
+static int stdio_serial_getc(struct stdio_dev *dev)
 {
        return serial_getc();
 }
 
-int stdio_serial_tstc(struct stdio_dev *dev)
+static int stdio_serial_tstc(struct stdio_dev *dev)
 {
        return serial_tstc();
 }
index 2157537c823056729fef0aae65cffabfe1588b15..00805bdc5b3d9689b069c86c3bf5e67916e6d35a 100644 (file)
--- a/config.mk
+++ b/config.mk
@@ -18,6 +18,8 @@ PLATFORM_LDFLAGS :=
 LDFLAGS :=
 LDFLAGS_FINAL :=
 OBJCOPYFLAGS :=
+# clear VENDOR for tcsh
+VENDOR :=
 #########################################################################
 
 ARCH := $(CONFIG_SYS_ARCH:"%"=%)
index a578c067d4d0dd5dcb39854a1197abdeb24cb86c..2aad834fa840c5b1390c3621442e9ab444240349 100644 (file)
@@ -1,5 +1,8 @@
 CONFIG_SPL=y
 CONFIG_SYS_EXTRA_OPTIONS="A10S_OLINUXINO_M,AXP152_POWER,SUNXI_EMAC,USB_EHCI,SUNXI_USB_VBUS0_GPIO=SUNXI_GPB(10)"
 CONFIG_FDTFILE="sun5i-a10s-olinuxino-micro.dtb"
+CONFIG_MMC_SUNXI_SLOT_EXTRA=1
++S:CONFIG_MMC0_CD_PIN="PG1"
++S:CONFIG_MMC1_CD_PIN="PG13"
 +S:CONFIG_ARM=y
 +S:CONFIG_TARGET_SUN5I=y
diff --git a/configs/A20-OLinuXino-Lime2_defconfig b/configs/A20-OLinuXino-Lime2_defconfig
new file mode 100644 (file)
index 0000000..75ef872
--- /dev/null
@@ -0,0 +1,5 @@
+CONFIG_SPL=y
+CONFIG_SYS_EXTRA_OPTIONS="A20_OLINUXINO_L2,AXP209_POWER,SUNXI_GMAC,RGMII,AHCI,SATAPWR=SUNXI_GPC(3),USB_EHCI"
+CONFIG_FDTFILE="sun7i-a20-olinuxino-lime2.dtb"
++S:CONFIG_ARM=y
++S:CONFIG_TARGET_SUN7I=y
index 20a947ca723adc5e110437dd47914399930ddc0c..0e0a7def2de600f0fc06aaf6898f3644fdd4243e 100644 (file)
@@ -1,5 +1,8 @@
 CONFIG_SPL=y
 CONFIG_SYS_EXTRA_OPTIONS="A20_OLINUXINO_M,AXP209_POWER,SUNXI_GMAC,AHCI,SATAPWR=SUNXI_GPB(8),USB_EHCI"
 CONFIG_FDTFILE="sun7i-a20-olinuxino-micro.dtb"
+CONFIG_MMC_SUNXI_SLOT_EXTRA=3
++S:CONFIG_MMC0_CD_PIN="PH1"
++S:CONFIG_MMC3_CD_PIN="PH11"
 +S:CONFIG_ARM=y
 +S:CONFIG_TARGET_SUN7I=y
diff --git a/configs/Colombus_defconfig b/configs/Colombus_defconfig
new file mode 100644 (file)
index 0000000..16800de
--- /dev/null
@@ -0,0 +1,4 @@
+CONFIG_SYS_EXTRA_OPTIONS="COLOMBUS"
+CONFIG_ARM=y
+CONFIG_TARGET_SUN6I=y
+CONFIG_FDTFILE="sun6i-a31-colombus.dtb"
diff --git a/configs/Ippo_q8h_defconfig b/configs/Ippo_q8h_defconfig
new file mode 100644 (file)
index 0000000..781f137
--- /dev/null
@@ -0,0 +1,4 @@
+CONFIG_SYS_EXTRA_OPTIONS="IPPO_Q8H_V5,CONS_INDEX=5"
+CONFIG_ARM=y
+CONFIG_TARGET_SUN8I=y
+CONFIG_DEFAULT_DEVICE_TREE="sun8i-a23-ippo-q8h-v5.dtb"
diff --git a/configs/Mele_M3_defconfig b/configs/Mele_M3_defconfig
new file mode 100644 (file)
index 0000000..a043ad2
--- /dev/null
@@ -0,0 +1,7 @@
+CONFIG_SPL=y
+CONFIG_SYS_EXTRA_OPTIONS="MELE_M3,AXP209_POWER,SUNXI_GMAC,USB_EHCI"
+CONFIG_FDTFILE="sun7i-a20-m3.dtb"
++S:CONFIG_MMC_SUNXI_SLOT_EXTRA=2
++S:CONFIG_MMC0_CD_PIN="PH1"
++S:CONFIG_ARM=y
++S:CONFIG_TARGET_SUN7I=y
index 38450c0d615c6bb36cf95d1c31d16a29d61e80f4..b631c410dc73414eb83f99349236a2cd5ac6d89b 100644 (file)
@@ -1,4 +1,4 @@
 CONFIG_SPL=y
-CONFIG_SYS_EXTRA_OPTIONS="SERIAL1,CONS_INDEX=1,EMMC_BOOT"
+CONFIG_SYS_EXTRA_OPTIONS="EMMC_BOOT"
 +S:CONFIG_ARM=y
 +S:CONFIG_TARGET_AM335X_EVM=y
index e25714366be5a5b2a7186a97ef640a05e047c0f8..5837a0a4da75bfb9750fcf416194a58977a5ee90 100644 (file)
@@ -1,5 +1,5 @@
 CONFIG_SPL=y
-CONFIG_SYS_EXTRA_OPTIONS="SERIAL1,CONS_INDEX=1,EMMC_BOOT,ENABLE_VBOOT"
+CONFIG_SYS_EXTRA_OPTIONS="EMMC_BOOT,ENABLE_VBOOT"
 +S:CONFIG_ARM=y
 +S:CONFIG_TARGET_AM335X_EVM=y
 CONFIG_OF_CONTROL=y
diff --git a/configs/apalis_t30_defconfig b/configs/apalis_t30_defconfig
new file mode 100644 (file)
index 0000000..fc5e1e4
--- /dev/null
@@ -0,0 +1,5 @@
++S:CONFIG_ARM=y
++S:CONFIG_TEGRA=y
++S:CONFIG_TEGRA30=y
++S:CONFIG_TARGET_APALIS_T30=y
+CONFIG_DEFAULT_DEVICE_TREE="tegra30-apalis"
diff --git a/configs/db-mv784mp-gp_defconfig b/configs/db-mv784mp-gp_defconfig
new file mode 100644 (file)
index 0000000..7aa216c
--- /dev/null
@@ -0,0 +1,2 @@
+CONFIG_ARM=y
+CONFIG_TARGET_DB_MV784MP_GP=y
diff --git a/configs/k2l_evm_defconfig b/configs/k2l_evm_defconfig
new file mode 100644 (file)
index 0000000..45399ce
--- /dev/null
@@ -0,0 +1,4 @@
+CONFIG_SPL=y
++S:CONFIG_ARM=y
++S:CONFIG_ARCH_KEYSTONE=y
++S:CONFIG_TARGET_K2L_EVM=y
diff --git a/configs/ls1021aqds_nor_SECURE_BOOT_defconfig b/configs/ls1021aqds_nor_SECURE_BOOT_defconfig
new file mode 100644 (file)
index 0000000..2b47995
--- /dev/null
@@ -0,0 +1,3 @@
+CONFIG_SYS_EXTRA_OPTIONS="SECURE_BOOT"
+CONFIG_ARM=y
+CONFIG_TARGET_LS1021AQDS=y
diff --git a/configs/ls1021atwr_nor_SECURE_BOOT_defconfig b/configs/ls1021atwr_nor_SECURE_BOOT_defconfig
new file mode 100644 (file)
index 0000000..eeeb0d5
--- /dev/null
@@ -0,0 +1,3 @@
+CONFIG_SYS_EXTRA_OPTIONS="SECURE_BOOT"
+CONFIG_ARM=y
+CONFIG_TARGET_LS1021ATWR=y
diff --git a/configs/maxbcm_defconfig b/configs/maxbcm_defconfig
new file mode 100644 (file)
index 0000000..4bcffd8
--- /dev/null
@@ -0,0 +1,2 @@
+CONFIG_ARM=y
+CONFIG_TARGET_MAXBCM=y
index 53f3126e71e43e453d00815e4222de3204e38016..e6aba422f811940b81784c591201b5e743240d4f 100644 (file)
@@ -2,7 +2,10 @@ CONFIG_SPL=y
 +S:CONFIG_ARM=y
 +S:CONFIG_ARCH_UNIPHIER=y
 +S:CONFIG_MACH_PH1_LD4=y
+CONFIG_DM=y
 CONFIG_NAND_DENALI=y
 CONFIG_SYS_NAND_DENALI_64BIT=y
 CONFIG_NAND_DENALI_SPARE_AREA_SKIP_BYTES=8
+CONFIG_DM_SERIAL=y
+CONFIG_UNIPHIER_SERIAL=y
 S:CONFIG_SPL_NAND_DENALI=y
index 209466ebcb334c900e54692ac75993e7e5dbb00d..334ec4bbdff8ff9af4724770dc19d9a66524a711 100644 (file)
@@ -2,7 +2,10 @@ CONFIG_SPL=y
 +S:CONFIG_ARM=y
 +S:CONFIG_ARCH_UNIPHIER=y
 +S:CONFIG_MACH_PH1_PRO4=y
+CONFIG_DM=y
 CONFIG_NAND_DENALI=y
 CONFIG_SYS_NAND_DENALI_64BIT=y
 CONFIG_NAND_DENALI_SPARE_AREA_SKIP_BYTES=8
+CONFIG_DM_SERIAL=y
+CONFIG_UNIPHIER_SERIAL=y
 S:CONFIG_SPL_NAND_DENALI=y
index 658977bcf6293f8b58e358c1c2bc8d75d0050342..4e8f354c9b596a30fe5eba2429477e1ef0d9b17a 100644 (file)
@@ -2,7 +2,10 @@ CONFIG_SPL=y
 +S:CONFIG_ARM=y
 +S:CONFIG_ARCH_UNIPHIER=y
 +S:CONFIG_MACH_PH1_SLD8=y
+CONFIG_DM=y
 CONFIG_NAND_DENALI=y
 CONFIG_SYS_NAND_DENALI_64BIT=y
 CONFIG_NAND_DENALI_SPARE_AREA_SKIP_BYTES=8
+CONFIG_DM_SERIAL=y
+CONFIG_UNIPHIER_SERIAL=y
 S:CONFIG_SPL_NAND_DENALI=y
index cfd77b0ff567cbacd4f5a3e6223e2edeb28fbd69..43485c9148b0f404e91cb0f45f9a3c76b2267578 100644 (file)
@@ -57,7 +57,7 @@ static const struct block_drvr block_drvr[] = {
 DECLARE_GLOBAL_DATA_PTR;
 
 #ifdef HAVE_BLOCK_DEVICE
-block_dev_desc_t *get_dev_hwpart(const char *ifname, int dev, int hwpart)
+static block_dev_desc_t *get_dev_hwpart(const char *ifname, int dev, int hwpart)
 {
        const struct block_drvr *drvr = block_drvr;
        block_dev_desc_t* (*reloc_get_dev)(int dev);
diff --git a/doc/device-tree-bindings/mtd/spi/spi-flash.txt b/doc/device-tree-bindings/mtd/spi/spi-flash.txt
new file mode 100644 (file)
index 0000000..85522d8
--- /dev/null
@@ -0,0 +1,25 @@
+* MTD SPI driver for serial flash chips
+
+Required properties:
+- #address-cells, #size-cells : Must be present if the device has sub-nodes
+  representing partitions.
+- compatible : Should be the manufacturer and the name of the chip. Bear in
+               mind that the DT binding is not U-Boot-only, but in case of
+               U-Boot, see spi_flash_params_table table in
+               drivers/mtd/spi/sf_params.c for the list of supported chips.
+- reg : Chip-Select number
+- spi-max-frequency : Maximum frequency of the SPI bus the chip can operate at
+
+Optional properties:
+ - memory-map : Address and size of the flash, if memory mapped. This may
+                apply to Intel chipsets, which tend to memory-map flash.
+
+Example:
+
+       flash: m25p80@0 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "spansion,m25p80";
+               reg = <0>;
+               spi-max-frequency = <40000000>;
+       };
diff --git a/doc/device-tree-bindings/spi/soft-spi.txt b/doc/device-tree-bindings/spi/soft-spi.txt
new file mode 100644 (file)
index 0000000..d09c1a5
--- /dev/null
@@ -0,0 +1,34 @@
+Soft SPI
+
+The soft SPI bus implementation allows the use of GPIO pins to simulate a
+SPI bus. No SPI host is required for this to work. The down-side is that the
+performance will typically be much lower than a real SPI bus.
+
+The soft SPI node requires the following properties:
+
+compatible: "u-boot,soft-spi"
+soft_spi_cs: GPIO number to use for SPI chip select (output)
+soft_spi_sclk: GPIO number to use for SPI clock (output)
+soft_spi_mosi: GPIO number to use for SPI MOSI line (output)
+soft_spi_miso GPIO number to use for SPI MISO line (input)
+spi-delay-us: Number of microseconds of delay between each CS transition
+
+The GPIOs should be specified as required by the GPIO controller referenced.
+The first cell holds the phandle of the controller and the second cell
+typically holds the GPIO number.
+
+
+Example:
+
+       soft-spi {
+               compatible = "u-boot,soft-spi";
+               cs-gpio = <&gpio 235 0>;        /* Y43 */
+               sclk-gpio = <&gpio 225 0>;      /* Y31 */
+               mosi-gpio = <&gpio 227 0>;      /* Y33 */
+               miso-gpio = <&gpio 224 0>;      /* Y30 */
+               spi-delay-us = <1>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               cs@0 {
+               };
+       };
index f9b68beb6f6d663bba7d0da97fdea32024b337fa..0278dda4d77045a7dbcc8400b1d5593252b4f514 100644 (file)
@@ -95,7 +95,7 @@ are provided in test/dm. To run them, try:
 You should see something like this:
 
     <...U-Boot banner...>
-    Running 21 driver model tests
+    Running 29 driver model tests
     Test: dm_test_autobind
     Test: dm_test_autoprobe
     Test: dm_test_bus_children
@@ -103,6 +103,7 @@ You should see something like this:
     Device 'c-test@0': seq 0 is in use by 'a-test'
     Device 'c-test@1': seq 1 is in use by 'd-test'
     Test: dm_test_bus_children_funcs
+    Test: dm_test_bus_children_iterators
     Test: dm_test_bus_parent_data
     Test: dm_test_bus_parent_ops
     Test: dm_test_children
@@ -114,7 +115,12 @@ You should see something like this:
     Device 'd-test': seq 3 is in use by 'b-test'
     Device 'a-test': seq 0 is in use by 'd-test'
     Test: dm_test_gpio
-    sandbox_gpio: sb_gpio_get_value: error: offset 4 not reserved
+    extra-gpios: get_value: error: gpio b5 not reserved
+    Test: dm_test_gpio_anon
+    Test: dm_test_gpio_copy
+    Test: dm_test_gpio_leak
+    extra-gpios: get_value: error: gpio b5 not reserved
+    Test: dm_test_gpio_requestf
     Test: dm_test_leak
     Test: dm_test_lifecycle
     Test: dm_test_operations
@@ -122,6 +128,26 @@ You should see something like this:
     Test: dm_test_platdata
     Test: dm_test_pre_reloc
     Test: dm_test_remove
+    Test: dm_test_spi_find
+    Invalid chip select 0:0 (err=-19)
+    SF: Failed to get idcodes
+    Device 'name-emul': seq 0 is in use by 'name-emul'
+    SF: Detected M25P16 with page size 256 Bytes, erase size 64 KiB, total 2 MiB
+    Test: dm_test_spi_flash
+    2097152 bytes written in 0 ms
+    SF: Detected M25P16 with page size 256 Bytes, erase size 64 KiB, total 2 MiB
+    SPI flash test:
+    0 erase: 0 ticks, 65536000 KiB/s 524288.000 Mbps
+    1 check: 0 ticks, 65536000 KiB/s 524288.000 Mbps
+    2 write: 0 ticks, 65536000 KiB/s 524288.000 Mbps
+    3 read: 0 ticks, 65536000 KiB/s 524288.000 Mbps
+    Test passed
+    0 erase: 0 ticks, 65536000 KiB/s 524288.000 Mbps
+    1 check: 0 ticks, 65536000 KiB/s 524288.000 Mbps
+    2 write: 0 ticks, 65536000 KiB/s 524288.000 Mbps
+    3 read: 0 ticks, 65536000 KiB/s 524288.000 Mbps
+    Test: dm_test_spi_xfer
+    SF: Detected M25P16 with page size 256 Bytes, erase size 64 KiB, total 2 MiB
     Test: dm_test_uclass
     Test: dm_test_uclass_before_ready
     Failures: 0
@@ -358,7 +384,9 @@ Device Sequence Numbers
 U-Boot numbers devices from 0 in many situations, such as in the command
 line for I2C and SPI buses, and the device names for serial ports (serial0,
 serial1, ...). Driver model supports this numbering and permits devices
-to be locating by their 'sequence'.
+to be locating by their 'sequence'. This numbering unique identifies a
+device in its uclass, so no two devices within a particular uclass can have
+the same sequence number.
 
 Sequence numbers start from 0 but gaps are permitted. For example, a board
 may have I2C buses 0, 1, 4, 5 but no 2 or 3. The choice of how devices are
diff --git a/doc/driver-model/spi-howto.txt b/doc/driver-model/spi-howto.txt
new file mode 100644 (file)
index 0000000..719dbd5
--- /dev/null
@@ -0,0 +1,594 @@
+How to port a SPI driver to driver model
+========================================
+
+Here is a rough step-by-step guide. It is based around converting the
+exynos SPI driver to driver model (DM) and the example code is based
+around U-Boot v2014.10-rc2 (commit be9f643).
+
+It is quite long since it includes actual code examples.
+
+Before driver model, SPI drivers have their own private structure which
+contains 'struct spi_slave'. With driver model, 'struct spi_slave' still
+exists, but now it is 'per-child data' for the SPI bus. Each child of the
+SPI bus is a SPI slave. The information that was stored in the
+driver-specific slave structure can now be port in private data for the
+SPI bus.
+
+For example, struct tegra_spi_slave looks like this:
+
+struct tegra_spi_slave {
+       struct spi_slave slave;
+       struct tegra_spi_ctrl *ctrl;
+};
+
+In this case 'slave' will be in per-child data, and 'ctrl' will be in the
+SPI's buses private data.
+
+
+0. How long does this take?
+
+You should be able to complete this within 2 hours, including testing but
+excluding preparing the patches. The API is basically the same as before
+with only minor changes:
+
+- methods to set speed and mode are separated out
+- cs_info is used to get information on a chip select
+
+
+1. Enable driver mode for SPI and SPI flash
+
+Add these to your board config:
+
+#define CONFIG_DM_SPI
+#define CONFIG_DM_SPI_FLASH
+
+
+2. Add the skeleton
+
+Put this code at the bottom of your existing driver file:
+
+struct spi_slave *spi_setup_slave(unsigned int busnum, unsigned int cs,
+                       unsigned int max_hz, unsigned int mode)
+{
+       return NULL;
+}
+
+struct spi_slave *spi_setup_slave_fdt(const void *blob, int slave_node,
+                                     int spi_node)
+{
+       return NULL;
+}
+
+static int exynos_spi_ofdata_to_platdata(struct udevice *dev)
+{
+       return -ENODEV;
+}
+
+static int exynos_spi_probe(struct udevice *dev)
+{
+       return -ENODEV;
+}
+
+static int exynos_spi_remove(struct udevice *dev)
+{
+       return -ENODEV;
+}
+
+static int exynos_spi_claim_bus(struct udevice *dev)
+{
+
+       return -ENODEV;
+}
+
+static int exynos_spi_release_bus(struct udevice *dev)
+{
+
+       return -ENODEV;
+}
+
+static int exynos_spi_xfer(struct udevice *dev, unsigned int bitlen,
+                           const void *dout, void *din, unsigned long flags)
+{
+
+       return -ENODEV;
+}
+
+static int exynos_spi_set_speed(struct udevice *dev, uint speed)
+{
+       return -ENODEV;
+}
+
+static int exynos_spi_set_mode(struct udevice *dev, uint mode)
+{
+       return -ENODEV;
+}
+
+static int exynos_cs_info(struct udevice *bus, uint cs,
+                         struct spi_cs_info *info)
+{
+       return -ENODEV;
+}
+
+static const struct dm_spi_ops exynos_spi_ops = {
+       .claim_bus      = exynos_spi_claim_bus,
+       .release_bus    = exynos_spi_release_bus,
+       .xfer           = exynos_spi_xfer,
+       .set_speed      = exynos_spi_set_speed,
+       .set_mode       = exynos_spi_set_mode,
+       .cs_info        = exynos_cs_info,
+};
+
+static const struct udevice_id exynos_spi_ids[] = {
+       { .compatible = "samsung,exynos-spi" },
+       { }
+};
+
+U_BOOT_DRIVER(exynos_spi) = {
+       .name   = "exynos_spi",
+       .id     = UCLASS_SPI,
+       .of_match = exynos_spi_ids,
+       .ops    = &exynos_spi_ops,
+       .ofdata_to_platdata = exynos_spi_ofdata_to_platdata,
+       .probe  = exynos_spi_probe,
+       .remove = exynos_spi_remove,
+};
+
+
+3. Replace 'exynos' in the above code with your driver name
+
+
+4. #ifdef out all of the code in your driver except for the above
+
+This will allow you to get it building, which means you can work
+incrementally. Since all the methods return an error initially, there is
+less chance that you will accidentally leave something in.
+
+Also, even though your conversion is basically a rewrite, it might help
+reviewers if you leave functions in the same place in the file,
+particularly for large drivers.
+
+
+5. Add some includes
+
+Add these includes to your driver:
+
+#include <dm.h>
+#include <errno.h>
+
+
+6. Build
+
+At this point you should be able to build U-Boot for your board with the
+empty SPI driver. You still have empty methods in your driver, but we will
+write these one by one.
+
+If you have spi_init() functions or the like that are called from your
+board then the build will fail. Remove these calls and make a note of the
+init that needs to be done.
+
+
+7. Set up your platform data structure
+
+This will hold the information your driver to operate, like its hardware
+address or maximum frequency.
+
+You may already have a struct like this, or you may need to create one
+from some of the #defines or global variables in the driver.
+
+Note that this information is not the run-time information. It should not
+include state that changes. It should be fixed throughout the live of
+U-Boot. Run-time information comes later.
+
+Here is what was in the exynos spi driver:
+
+struct spi_bus {
+       enum periph_id periph_id;
+       s32 frequency;          /* Default clock frequency, -1 for none */
+       struct exynos_spi *regs;
+       int inited;             /* 1 if this bus is ready for use */
+       int node;
+       uint deactivate_delay_us;       /* Delay to wait after deactivate */
+};
+
+Of these, inited is handled by DM and node is the device tree node, which
+DM tells you. The name is not quite right. So in this case we would use:
+
+struct exynos_spi_platdata {
+       enum periph_id periph_id;
+       s32 frequency;          /* Default clock frequency, -1 for none */
+       struct exynos_spi *regs;
+       uint deactivate_delay_us;       /* Delay to wait after deactivate */
+};
+
+
+8a. Write ofdata_to_platdata()   [for device tree only]
+
+This method will convert information in the device tree node into a C
+structure in your driver (called platform data). If you are not using
+device tree, go to 8b.
+
+DM will automatically allocate the struct for us when we are using device
+tree, but we need to tell it the size:
+
+U_BOOT_DRIVER(spi_exynos) = {
+...
+       .platdata_auto_alloc_size = sizeof(struct exynos_spi_platdata),
+
+
+Here is a sample function. It gets a pointer to the platform data and
+fills in the fields from device tree.
+
+static int exynos_spi_ofdata_to_platdata(struct udevice *bus)
+{
+       struct exynos_spi_platdata *plat = bus->platdata;
+       const void *blob = gd->fdt_blob;
+       int node = bus->of_offset;
+
+       plat->regs = (struct exynos_spi *)fdtdec_get_addr(blob, node, "reg");
+       plat->periph_id = pinmux_decode_periph_id(blob, node);
+
+       if (plat->periph_id == PERIPH_ID_NONE) {
+               debug("%s: Invalid peripheral ID %d\n", __func__,
+                       plat->periph_id);
+               return -FDT_ERR_NOTFOUND;
+       }
+
+       /* Use 500KHz as a suitable default */
+       plat->frequency = fdtdec_get_int(blob, node, "spi-max-frequency",
+                                       500000);
+       plat->deactivate_delay_us = fdtdec_get_int(blob, node,
+                                       "spi-deactivate-delay", 0);
+       debug("%s: regs=%p, periph_id=%d, max-frequency=%d, deactivate_delay=%d\n",
+             __func__, plat->regs, plat->periph_id, plat->frequency,
+              plat->deactivate_delay_us);
+
+       return 0;
+}
+
+
+8b. Add the platform data  [non-device-tree only]
+
+Specify this data in a U_BOOT_DEVICE() declaration in your board file:
+
+struct exynos_spi_platdata platdata_spi0 = {
+       .periph_id = ...
+       .frequency = ...
+       .regs = ...
+       .deactivate_delay_us = ...
+};
+
+U_BOOT_DEVICE(board_spi0) = {
+       .name = "exynos_spi",
+       .platdata = &platdata_spi0,
+};
+
+You will unfortunately need to put the struct into a header file in this
+case so that your board file can use it.
+
+
+9. Add the device private data
+
+Most devices have some private data which they use to keep track of things
+while active. This is the run-time information and needs to be stored in
+a structure. There is probably a structure in the driver that includes a
+'struct spi_slave', so you can use that.
+
+struct exynos_spi_slave {
+       struct spi_slave slave;
+       struct exynos_spi *regs;
+       unsigned int freq;              /* Default frequency */
+       unsigned int mode;
+       enum periph_id periph_id;       /* Peripheral ID for this device */
+       unsigned int fifo_size;
+       int skip_preamble;
+       struct spi_bus *bus;            /* Pointer to our SPI bus info */
+       ulong last_transaction_us;      /* Time of last transaction end */
+};
+
+
+We should rename this to make its purpose more obvious, and get rid of
+the slave structure, so we have:
+
+struct exynos_spi_priv {
+       struct exynos_spi *regs;
+       unsigned int freq;              /* Default frequency */
+       unsigned int mode;
+       enum periph_id periph_id;       /* Peripheral ID for this device */
+       unsigned int fifo_size;
+       int skip_preamble;
+       ulong last_transaction_us;      /* Time of last transaction end */
+};
+
+
+DM can auto-allocate this also:
+
+U_BOOT_DRIVER(spi_exynos) = {
+...
+       .priv_auto_alloc_size = sizeof(struct exynos_spi_priv),
+
+
+Note that this is created before the probe method is called, and destroyed
+after the remove method is called. It will be zeroed when the probe
+method is called.
+
+
+10. Add the probe() and remove() methods
+
+Note: It's a good idea to build repeatedly as you are working, to avoid a
+huge amount of work getting things compiling at the end.
+
+The probe method is supposed to set up the hardware. U-Boot used to use
+spi_setup_slave() to do this. So take a look at this function and see
+what you can copy out to set things up.
+
+
+static int exynos_spi_probe(struct udevice *bus)
+{
+       struct exynos_spi_platdata *plat = dev_get_platdata(bus);
+       struct exynos_spi_priv *priv = dev_get_priv(bus);
+
+       priv->regs = plat->regs;
+       if (plat->periph_id == PERIPH_ID_SPI1 ||
+           plat->periph_id == PERIPH_ID_SPI2)
+               priv->fifo_size = 64;
+       else
+               priv->fifo_size = 256;
+
+       priv->skip_preamble = 0;
+       priv->last_transaction_us = timer_get_us();
+       priv->freq = plat->frequency;
+       priv->periph_id = plat->periph_id;
+
+       return 0;
+}
+
+This implementation doesn't actually touch the hardware, which is somewhat
+unusual for a driver. In this case we will do that when the device is
+claimed by something that wants to use the SPI bus.
+
+For remove we could shut down the clocks, but in this case there is
+nothing to do. DM frees any memory that it allocated, so we can just
+remove exynos_spi_remove() and its reference in U_BOOT_DRIVER.
+
+
+11. Implement set_speed()
+
+This should set up clocks so that the SPI bus is running at the right
+speed. With the old API spi_claim_bus() would normally do this and several
+of the following functions, so let's look at that function:
+
+int spi_claim_bus(struct spi_slave *slave)
+{
+       struct exynos_spi_slave *spi_slave = to_exynos_spi(slave);
+       struct exynos_spi *regs = spi_slave->regs;
+       u32 reg = 0;
+       int ret;
+
+       ret = set_spi_clk(spi_slave->periph_id,
+                                       spi_slave->freq);
+       if (ret < 0) {
+               debug("%s: Failed to setup spi clock\n", __func__);
+               return ret;
+       }
+
+       exynos_pinmux_config(spi_slave->periph_id, PINMUX_FLAG_NONE);
+
+       spi_flush_fifo(slave);
+
+       reg = readl(&regs->ch_cfg);
+       reg &= ~(SPI_CH_CPHA_B | SPI_CH_CPOL_L);
+
+       if (spi_slave->mode & SPI_CPHA)
+               reg |= SPI_CH_CPHA_B;
+
+       if (spi_slave->mode & SPI_CPOL)
+               reg |= SPI_CH_CPOL_L;
+
+       writel(reg, &regs->ch_cfg);
+       writel(SPI_FB_DELAY_180, &regs->fb_clk);
+
+       return 0;
+}
+
+
+It sets up the speed, mode, pinmux, feedback delay and clears the FIFOs.
+With DM these will happen in separate methods.
+
+
+Here is an example for the speed part:
+
+static int exynos_spi_set_speed(struct udevice *bus, uint speed)
+{
+       struct exynos_spi_platdata *plat = bus->platdata;
+       struct exynos_spi_priv *priv = dev_get_priv(bus);
+       int ret;
+
+       if (speed > plat->frequency)
+               speed = plat->frequency;
+       ret = set_spi_clk(priv->periph_id, speed);
+       if (ret)
+               return ret;
+       priv->freq = speed;
+       debug("%s: regs=%p, speed=%d\n", __func__, priv->regs, priv->freq);
+
+       return 0;
+}
+
+
+12. Implement set_mode()
+
+This should adjust the SPI mode (polarity, etc.). Again this code probably
+comes from the old spi_claim_bus(). Here is an example:
+
+
+static int exynos_spi_set_mode(struct udevice *bus, uint mode)
+{
+       struct exynos_spi_priv *priv = dev_get_priv(bus);
+       uint32_t reg;
+
+       reg = readl(&priv->regs->ch_cfg);
+       reg &= ~(SPI_CH_CPHA_B | SPI_CH_CPOL_L);
+
+       if (mode & SPI_CPHA)
+               reg |= SPI_CH_CPHA_B;
+
+       if (mode & SPI_CPOL)
+               reg |= SPI_CH_CPOL_L;
+
+       writel(reg, &priv->regs->ch_cfg);
+       priv->mode = mode;
+       debug("%s: regs=%p, mode=%d\n", __func__, priv->regs, priv->mode);
+
+       return 0;
+}
+
+
+13. Implement claim_bus()
+
+This is where a client wants to make use of the bus, so claims it first.
+At this point we need to make sure everything is set up ready for data
+transfer. Note that this function is wholly internal to the driver - at
+present the SPI uclass never calls it.
+
+Here again we look at the old claim function and see some code that is
+needed. It is anything unrelated to speed and mode:
+
+static int exynos_spi_claim_bus(struct udevice *bus)
+{
+       struct exynos_spi_priv *priv = dev_get_priv(bus);
+
+       exynos_pinmux_config(priv->periph_id, PINMUX_FLAG_NONE);
+       spi_flush_fifo(priv->regs);
+
+       writel(SPI_FB_DELAY_180, &priv->regs->fb_clk);
+
+       return 0;
+}
+
+The spi_flush_fifo() function is in the removed part of the code, so we
+need to expose it again (perhaps with an #endif before it and '#if 0'
+after it). It only needs access to priv->regs which is why we have
+passed that in:
+
+/**
+ * Flush spi tx, rx fifos and reset the SPI controller
+ *
+ * @param regs Pointer to SPI registers
+ */
+static void spi_flush_fifo(struct exynos_spi *regs)
+{
+       clrsetbits_le32(&regs->ch_cfg, SPI_CH_HS_EN, SPI_CH_RST);
+       clrbits_le32(&regs->ch_cfg, SPI_CH_RST);
+       setbits_le32(&regs->ch_cfg, SPI_TX_CH_ON | SPI_RX_CH_ON);
+}
+
+
+14. Implement release_bus()
+
+This releases the bus - in our example the old code in spi_release_bus()
+is a call to spi_flush_fifo, so we add:
+
+static int exynos_spi_release_bus(struct udevice *bus)
+{
+       struct exynos_spi_priv *priv = dev_get_priv(bus);
+
+       spi_flush_fifo(priv->regs);
+
+       return 0;
+}
+
+
+15. Implement xfer()
+
+This is the final method that we need to create, and it is where all the
+work happens. The method parameters are the same as the old spi_xfer() with
+the addition of a 'struct udevice' so conversion is pretty easy. Start
+by copying the contents of spi_xfer() to your new xfer() method and proceed
+from there.
+
+If (flags & SPI_XFER_BEGIN) is non-zero then xfer() normally calls an
+activate function, something like this:
+
+void spi_cs_activate(struct spi_slave *slave)
+{
+       struct exynos_spi_slave *spi_slave = to_exynos_spi(slave);
+
+       /* If it's too soon to do another transaction, wait */
+       if (spi_slave->bus->deactivate_delay_us &&
+           spi_slave->last_transaction_us) {
+               ulong delay_us;         /* The delay completed so far */
+               delay_us = timer_get_us() - spi_slave->last_transaction_us;
+               if (delay_us < spi_slave->bus->deactivate_delay_us)
+                       udelay(spi_slave->bus->deactivate_delay_us - delay_us);
+       }
+
+       clrbits_le32(&spi_slave->regs->cs_reg, SPI_SLAVE_SIG_INACT);
+       debug("Activate CS, bus %d\n", spi_slave->slave.bus);
+       spi_slave->skip_preamble = spi_slave->mode & SPI_PREAMBLE;
+}
+
+The new version looks like this:
+
+static void spi_cs_activate(struct udevice *dev)
+{
+       struct udevice *bus = dev->parent;
+       struct exynos_spi_platdata *pdata = dev_get_platdata(bus);
+       struct exynos_spi_priv *priv = dev_get_priv(bus);
+
+       /* If it's too soon to do another transaction, wait */
+       if (pdata->deactivate_delay_us &&
+           priv->last_transaction_us) {
+               ulong delay_us;         /* The delay completed so far */
+               delay_us = timer_get_us() - priv->last_transaction_us;
+               if (delay_us < pdata->deactivate_delay_us)
+                       udelay(pdata->deactivate_delay_us - delay_us);
+       }
+
+       clrbits_le32(&priv->regs->cs_reg, SPI_SLAVE_SIG_INACT);
+       debug("Activate CS, bus '%s'\n", bus->name);
+       priv->skip_preamble = priv->mode & SPI_PREAMBLE;
+}
+
+All we have really done here is change the pointers and print the device name
+instead of the bus number. Other local static functions can be treated in
+the same way.
+
+
+16. Set up the per-child data and child pre-probe function
+
+To minimise the pain and complexity of the SPI subsystem while the driver
+model change-over is in place, struct spi_slave is used to reference a
+SPI bus slave, even though that slave is actually a struct udevice. In fact
+struct spi_slave is the device's child data. We need to make sure this space
+is available. It is possible to allocate more space that struct spi_slave
+needs, but this is the minimum.
+
+U_BOOT_DRIVER(exynos_spi) = {
+...
+       .per_child_auto_alloc_size      = sizeof(struct spi_slave),
+}
+
+
+17. Optional: Set up cs_info() if you want it
+
+Sometimes it is useful to know whether a SPI chip select is valid, but this
+is not obvious from outside the driver. In this case you can provide a
+method for cs_info() to deal with this. If you don't provide it, then the
+device tree will be used to determine what chip selects are valid.
+
+Return -ENODEV if the supplied chip select is invalid, or 0 if it is valid.
+If you don't provide the cs_info() method, -ENODEV is assumed for all
+chip selects that do not appear in the device tree.
+
+
+18. Test it
+
+Now that you have the code written and it compiles, try testing it using
+the 'sf test' command. You may need to enable CONFIG_CMD_SF_TEST for your
+board.
+
+
+19. Prepare patches and send them to the mailing lists
+
+You can use 'tools/patman/patman' to prepare, check and send patches for
+your work. See the README for details.
index ef3ab8f726a1326e0e878bd75ae3254e08dd6b26..539cdbfafec0d8f63d3cd298323525f2f3e04cb7 100644 (file)
                };
        };
 };
+
+
+
+For x86 a setup node is also required: see x86-fit-boot.txt.
+
+/dts-v1/;
+
+/ {
+       description = "Simple image with single Linux kernel on x86";
+       #address-cells = <1>;
+
+       images {
+               kernel@1 {
+                       description = "Vanilla Linux kernel";
+                       data = /incbin/("./image.bin.lzo");
+                       type = "kernel";
+                       arch = "x86";
+                       os = "linux";
+                       compression = "lzo";
+                       load = <0x01000000>;
+                       entry = <0x00000000>;
+                       hash@2 {
+                               algo = "sha1";
+                       };
+               };
+
+               setup@1 {
+                       description = "Linux setup.bin";
+                       data = /incbin/("./setup.bin");
+                       type = "x86_setup";
+                       arch = "x86";
+                       os = "linux";
+                       compression = "none";
+                       load = <0x00090000>;
+                       entry = <0x00090000>;
+                       hash@2 {
+                               algo = "sha1";
+                       };
+               };
+       };
+
+       configurations {
+               default = "config@1";
+               config@1 {
+                       description = "Boot Linux kernel";
+                       kernel = "kernel@1";
+                       setup = "setup@1";
+               };
+       };
+};
index 9ed6f65e599383f837cc611e43d2c05a659b956c..b47ce73b8323a4034bbd58c77ce50d49f5492b38 100644 (file)
@@ -55,7 +55,7 @@ FIT is formally a flattened device tree (in the libfdt meaning), which
 conforms to bindings defined in this document.
 
 .its   - image tree source
-.itb   - image tree blob
+.fit   - flattened image tree blob
 
 c) Image building procedure
 
@@ -101,15 +101,15 @@ Root node of the uImage Tree should have the following layout:
     |
     o images
     | |
-    | o img@1 {...}
-    | o img@2 {...}
+    | o image@1 {...}
+    | o image@2 {...}
     | ...
     |
     o configurations
-      |- default = "cfg@1"
+      |- default = "conf@1"
       |
-      o cfg@1 {...}
-      o cfg@2 {...}
+      o conf@1 {...}
+      o conf@2 {...}
       ...
 
 
@@ -159,7 +159,7 @@ the '/images' node should have the following layout:
   - description : Textual description of the component sub-image
   - type : Name of component sub-image type, supported types are:
     "standalone", "kernel", "ramdisk", "firmware", "script", "filesystem",
-    "flat_dt".
+    "flat_dt" and others (see uimage_type in common/images.c).
   - data : Path to the external file which contains this node's binary data.
   - compression : Compression used by included data. Supported compressions
     are "gzip" and "bzip2". If no compression is used compression property
@@ -173,7 +173,8 @@ the '/images' node should have the following layout:
   - arch : Architecture name, mandatory for types: "standalone", "kernel",
     "firmware", "ramdisk" and "fdt". Valid architecture names are: "alpha",
     "arm", "i386", "ia64", "mips", "mips64", "ppc", "s390", "sh", "sparc",
-    "sparc64", "m68k", "microblaze", "nios2", "blackfin", "avr32", "st200".
+    "sparc64", "m68k", "microblaze", "nios2", "blackfin", "avr32", "st200",
+    "sandbox".
   - entry : entry point address, address size is determined by
     '#address-cells' property of the root node. Mandatory for for types:
     "standalone" and "kernel".
@@ -246,6 +247,8 @@ o config@1
     node of a "ramdisk" type).
   - fdt : Unit name of the corresponding fdt blob (component image node of a
     "fdt type").
+  - setup : Unit name of the corresponding setup binary (used for booting
+    an x86 kernel). This contains the setup.bin file built by the kernel.
 
 The FDT blob is required to properly boot FDT based kernel, so the minimal
 configuration for 2.6 FDT kernel is (kernel, fdt) pair.
diff --git a/doc/uImage.FIT/x86-fit-boot.txt b/doc/uImage.FIT/x86-fit-boot.txt
new file mode 100644 (file)
index 0000000..61c10ff
--- /dev/null
@@ -0,0 +1,276 @@
+Booting Linux on x86 with FIT
+=============================
+
+Background
+----------
+
+(corrections to the text below are welcome)
+
+Generally Linux x86 uses its own very complex booting method. There is a setup
+binary which contains all sorts of parameters and a compressed self-extracting
+binary for the kernel itself, often with a small built-in serial driver to
+display decompression progress.
+
+The x86 CPU has various processor modes. I am no expert on these, but my
+understanding is that an x86 CPU (even a really new one) starts up in a 16-bit
+'real' mode where only 1MB of memory is visible, moves to 32-bit 'protected'
+mode where 4GB is visible (or more with special memory access techniques) and
+then to 64-bit 'long' mode if 64-bit execution is required.
+
+Partly the self-extracting nature of Linux was introduced to cope with boot
+loaders that were barely capable of loading anything. Even changing to 32-bit
+mode was something of a challenge, so putting this logic in the kernel seemed
+to make sense.
+
+Bit by bit more and more logic has been added to this post-boot pre-Linux
+wrapper:
+
+- Changing to 32-bit mode
+- Decompression
+- Serial output (with drivers for various chips)
+- Load address randomisation
+- Elf loader complete with relocation (for the above)
+- Random number generator via 3 methods (again for the above)
+- Some sort of EFI mini-loader (1000+ glorious lines of code)
+- Locating and tacking on a device tree and ramdisk
+
+To my mind, if you sit back and look at things from first principles, this
+doesn't make a huge amount of sense. Any boot loader worth its salts already
+has most of the above features and more besides. The boot loader already knows
+the layout of memory, has a serial driver, can decompress things, includes an
+ELF loader and supports device tree and ramdisks. The decision to duplicate
+all these features in a Linux wrapper caters for the lowest common
+denominator: a boot loader which consists of a BIOS call to load something off
+disk, followed by a jmp instruction.
+
+(Aside: On ARM systems, we worry that the boot loader won't know where to load
+the kernel. It might be easier to just provide that information in the image,
+or in the boot loader rather than adding a self-relocator to put it in the
+right place. Or just use ELF?
+
+As a result, the x86 kernel boot process is needlessly complex. The file
+format is also complex, and obfuscates the contents to a degree that it is
+quite a challenge to extract anything from it. This bzImage format has become
+so prevalent that is actually isn't possible to produce the 'raw' kernel build
+outputs with the standard Makefile (as it is on ARM for example, at least at
+the time of writing).
+
+This document describes an alternative boot process which uses simple raw
+images which are loaded into the right place by the boot loader and then
+executed.
+
+
+Build the kernel
+----------------
+
+Note: these instructions assume a 32-bit kernel. U-Boot does not currently
+support booting a 64-bit kernel as it has no way of going into 64-bit mode on
+x86.
+
+You can build the kernel as normal with 'make'. This will create a file called
+'vmlinux'. This is a standard ELF file and you can look at it if you like:
+
+$ objdump -h vmlinux
+
+vmlinux:     file format elf32-i386
+
+Sections:
+Idx Name          Size      VMA       LMA       File off  Algn
+  0 .text         00416850  81000000  01000000  00001000  2**5
+                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
+  1 .notes        00000024  81416850  01416850  00417850  2**2
+                  CONTENTS, ALLOC, LOAD, READONLY, CODE
+  2 __ex_table    00000c50  81416880  01416880  00417880  2**3
+                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA
+  3 .rodata       00154b9e  81418000  01418000  00419000  2**5
+                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA
+  4 __bug_table   0000597c  8156cba0  0156cba0  0056dba0  2**0
+                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA
+  5 .pci_fixup    00001b80  8157251c  0157251c  0057351c  2**2
+                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA
+  6 .tracedata    00000024  8157409c  0157409c  0057509c  2**0
+                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA
+  7 __ksymtab     00007ec0  815740c0  015740c0  005750c0  2**2
+                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA
+  8 __ksymtab_gpl 00004a28  8157bf80  0157bf80  0057cf80  2**2
+                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA
+  9 __ksymtab_strings 0001d6fc  815809a8  015809a8  005819a8  2**0
+                  CONTENTS, ALLOC, LOAD, READONLY, DATA
+ 10 __init_rodata 00001c3c  8159e0a4  0159e0a4  0059f0a4  2**2
+                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA
+ 11 __param       00000ff0  8159fce0  0159fce0  005a0ce0  2**2
+                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA
+ 12 __modver      00000330  815a0cd0  015a0cd0  005a1cd0  2**2
+                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA
+ 13 .data         00063000  815a1000  015a1000  005a2000  2**12
+                  CONTENTS, ALLOC, LOAD, RELOC, DATA
+ 14 .init.text    0002f104  81604000  01604000  00605000  2**2
+                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
+ 15 .init.data    00040cdc  81634000  01634000  00635000  2**12
+                  CONTENTS, ALLOC, LOAD, RELOC, DATA
+ 16 .x86_cpu_dev.init 0000001c  81674cdc  01674cdc  00675cdc  2**2
+                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA
+ 17 .altinstructions 0000267c  81674cf8  01674cf8  00675cf8  2**0
+                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA
+ 18 .altinstr_replacement 00000942  81677374  01677374  00678374  2**0
+                  CONTENTS, ALLOC, LOAD, READONLY, CODE
+ 19 .iommu_table  00000014  81677cb8  01677cb8  00678cb8  2**2
+                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA
+ 20 .apicdrivers  00000004  81677cd0  01677cd0  00678cd0  2**2
+                  CONTENTS, ALLOC, LOAD, RELOC, DATA
+ 21 .exit.text    00001a80  81677cd8  01677cd8  00678cd8  2**0
+                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
+ 22 .data..percpu 00007880  8167a000  0167a000  0067b000  2**12
+                  CONTENTS, ALLOC, LOAD, RELOC, DATA
+ 23 .smp_locks    00003000  81682000  01682000  00683000  2**2
+                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA
+ 24 .bss          000a1000  81685000  01685000  00686000  2**12
+                  ALLOC
+ 25 .brk          00424000  81726000  01726000  00686000  2**0
+                  ALLOC
+ 26 .comment      00000049  00000000  00000000  00686000  2**0
+                  CONTENTS, READONLY
+ 27 .GCC.command.line 0003e055  00000000  00000000  00686049  2**0
+                  CONTENTS, READONLY
+ 28 .debug_aranges 0000f4c8  00000000  00000000  006c40a0  2**3
+                  CONTENTS, RELOC, READONLY, DEBUGGING
+ 29 .debug_info   0440b0df  00000000  00000000  006d3568  2**0
+                  CONTENTS, RELOC, READONLY, DEBUGGING
+ 30 .debug_abbrev 0022a83b  00000000  00000000  04ade647  2**0
+                  CONTENTS, READONLY, DEBUGGING
+ 31 .debug_line   004ead0d  00000000  00000000  04d08e82  2**0
+                  CONTENTS, RELOC, READONLY, DEBUGGING
+ 32 .debug_frame  0010a960  00000000  00000000  051f3b90  2**2
+                  CONTENTS, RELOC, READONLY, DEBUGGING
+ 33 .debug_str    001b442d  00000000  00000000  052fe4f0  2**0
+                  CONTENTS, READONLY, DEBUGGING
+ 34 .debug_loc    007c7fa9  00000000  00000000  054b291d  2**0
+                  CONTENTS, RELOC, READONLY, DEBUGGING
+ 35 .debug_ranges 00098828  00000000  00000000  05c7a8c8  2**3
+                  CONTENTS, RELOC, READONLY, DEBUGGING
+
+There is also the setup binary mentioned earlier. This is at
+arch/x86/boot/setup.bin and is about 12KB in size. It includes the command
+line and various settings need by the kernel. Arguably the boot loader should
+provide all of this also, but setting it up is some complex that the kernel
+helps by providing a head start.
+
+As you can see the code loads to address 0x01000000 and everything else
+follows after that. We could load this image using the 'bootelf' command but
+we would still need to provide the setup binary. This is not supported by
+U-Boot although I suppose you could mostly script it. This would permit the
+use of a relocatable kernel.
+
+All we need to boot is the vmlinux file and the setup.bin file.
+
+
+Create a FIT
+------------
+
+To create a FIT you will need a source file describing what should go in the
+FIT. See kernel.its for an example for x86. Put this into a file called
+image.its.
+
+Note that setup is loaded to the special address of 0x90000 (a special address
+you just have to know) and the kernel is loaded to 0x01000000 (the address you
+saw above). This means that you will need to load your FIT to a different
+address so that U-Boot doesn't overwrite it when decompressing. Something like
+0x02000000 will do so you can set CONFIG_SYS_LOAD_ADDR to that.
+
+In that example the kernel is compressed with lzo. Also we need to provide a
+flat binary, not an ELF. So the steps needed to set things are are:
+
+   # Create a flat binary
+   objcopy -O binary vmlinux vmlinux.bin
+
+   # Compress it into LZO format
+   lzop vmlinux.bin
+
+   # Build a FIT image
+   mkimage -f image.its image.fit
+
+(be careful to run the mkimage from your U-Boot tools directory since it
+will have x86_setup support.)
+
+You can take a look at the resulting fit file if you like:
+
+$ dumpimage -l image.fit
+FIT description: Simple image with single Linux kernel on x86
+Created:         Tue Oct  7 10:57:24 2014
+ Image 0 (kernel@1)
+  Description:  Vanilla Linux kernel
+  Created:      Tue Oct  7 10:57:24 2014
+  Type:         Kernel Image
+  Compression:  lzo compressed
+  Data Size:    4591767 Bytes = 4484.15 kB = 4.38 MB
+  Architecture: Intel x86
+  OS:           Linux
+  Load Address: 0x01000000
+  Entry Point:  0x00000000
+  Hash algo:    sha1
+  Hash value:   446b5163ebfe0fb6ee20cbb7a8501b263cd92392
+ Image 1 (setup@1)
+  Description:  Linux setup.bin
+  Created:      Tue Oct  7 10:57:24 2014
+  Type:         x86 setup.bin
+  Compression:  uncompressed
+  Data Size:    12912 Bytes = 12.61 kB = 0.01 MB
+  Hash algo:    sha1
+  Hash value:   a1f2099cf47ff9816236cd534c77af86e713faad
+ Default Configuration: 'config@1'
+ Configuration 0 (config@1)
+  Description:  Boot Linux kernel
+  Kernel:       kernel@1
+
+
+Booting the FIT
+---------------
+
+To make it boot you need to load it and then use 'bootm' to boot it. A
+suitable script to do this from a network server is:
+
+   bootp
+   tftp image.fit
+   bootm
+
+This will load the image from the network and boot it. The command line (from
+the 'bootargs' environment variable) will be passed to the kernel.
+
+If you want a ramdisk you can add it as normal with FIT. If you want a device
+tree then x86 doesn't normally use those - it has ACPI instead.
+
+
+Why Bother?
+-----------
+
+1. It demystifies the process of booting an x86 kernel
+2. It allows use of the standard U-Boot boot file format
+3. It allows U-Boot to perform decompression - problems will provide an error
+message and you are still in the boot loader. It is possible to investigate.
+4. It avoids all the pre-loader code in the kernel which is quite complex to
+follow
+5. You can use verified/secure boot and other features which haven't yet been
+added to the pre-Linux
+6. It makes x86 more like other architectures in the way it boots a kernel.
+You can potentially use the same file format for the kernel, and the same
+procedure for building and packaging it.
+
+
+References
+----------
+
+In the Linux kernel, Documentation/x86/boot.txt defines the boot protocol for
+the kernel including the setup.bin format. This is handled in U-Boot in
+arch/x86/lib/zimage.c and arch/x86/lib/bootm.c.
+
+The procedure for entering 64-bit mode on x86 seems to be described here:
+
+   http://wiki.osdev.org/64-bit_Higher_Half_Kernel_with_GRUB_2
+
+Various files in the same directory as this file describe the FIT format.
+
+
+--
+Simon Glass
+sjg@chromium.org
+7-Oct-2014
index d8361d95fd15ea8dab26b6e408cb8d4fb17d0eeb..33227c8bd6de003d170962e7f7778ed1b091c460 100644 (file)
@@ -19,3 +19,5 @@ obj-$(CONFIG_QE) += qe/
 obj-y += memory/
 obj-y += pwm/
 obj-y += input/
+# SOC specific infrastructure drivers.
+obj-y += soc/
index 574bc40b10e138a09200b8e3187d5295696b485f..e54d564bf764d0a6015bf84fc1c6cfd3999eeacd 100644 (file)
@@ -12,7 +12,7 @@
 #if defined(CONFIG_ORION5X)
 #include <asm/arch/orion5x.h>
 #elif defined(CONFIG_KIRKWOOD)
-#include <asm/arch/kirkwood.h>
+#include <asm/arch/soc.h>
 #endif
 
 /* SATA port registers */
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..d2799dc861ff5a661ff6717c985285f263ebd1e9 100644 (file)
@@ -0,0 +1,6 @@
+config DM
+       bool "Enable Driver Model"
+       depends on !SPL_BUILD
+       help
+         This config option enables Driver Model.
+         To use legacy drivers, say N.
index c7905b14409fcf4fe56653655960de8407c5348b..151c2398a4d47fce304d43a6ae775befd379baa2 100644 (file)
@@ -5,3 +5,4 @@
 #
 
 obj-y := device.o lists.o root.o uclass.o util.o
+obj-$(CONFIG_OF_CONTROL) += simple-bus.o
index 32e80e82b59c99f9ac5734c8f3dadc7c3b0c5f28..49faa29dc1a0eecaa84e76371b8301c2eef14d7b 100644 (file)
@@ -232,7 +232,7 @@ static void device_free(struct udevice *dev)
        }
 }
 
-int device_probe(struct udevice *dev)
+int device_probe_child(struct udevice *dev, void *parent_priv)
 {
        struct driver *drv;
        int size = 0;
@@ -282,6 +282,8 @@ int device_probe(struct udevice *dev)
                                ret = -ENOMEM;
                                goto fail;
                        }
+                       if (parent_priv)
+                               memcpy(dev->parent_priv, parent_priv, size);
                }
 
                ret = device_probe(dev->parent);
@@ -335,6 +337,11 @@ fail:
        return ret;
 }
 
+int device_probe(struct udevice *dev)
+{
+       return device_probe_child(dev, NULL);
+}
+
 int device_remove(struct udevice *dev)
 {
        struct driver *drv;
@@ -514,3 +521,30 @@ int device_get_child_by_of_offset(struct udevice *parent, int seq,
        ret = device_find_child_by_of_offset(parent, seq, &dev);
        return device_get_device_tail(dev, ret, devp);
 }
+
+int device_find_first_child(struct udevice *parent, struct udevice **devp)
+{
+       if (list_empty(&parent->child_head)) {
+               *devp = NULL;
+       } else {
+               *devp = list_first_entry(&parent->child_head, struct udevice,
+                                        sibling_node);
+       }
+
+       return 0;
+}
+
+int device_find_next_child(struct udevice **devp)
+{
+       struct udevice *dev = *devp;
+       struct udevice *parent = dev->parent;
+
+       if (list_is_last(&dev->sibling_node, &parent->child_head)) {
+               *devp = NULL;
+       } else {
+               *devp = list_entry(dev->sibling_node.next, struct udevice,
+                                  sibling_node);
+       }
+
+       return 0;
+}
index 699f94b435f213a0e78e91e4d2e854ae45473e7b..3a1ea8565449699a39ba5684dbecfbf71e30780b 100644 (file)
@@ -24,19 +24,12 @@ struct driver *lists_driver_lookup_name(const char *name)
                ll_entry_start(struct driver, driver);
        const int n_ents = ll_entry_count(struct driver, driver);
        struct driver *entry;
-       int len;
 
        if (!drv || !n_ents)
                return NULL;
 
-       len = strlen(name);
-
        for (entry = drv; entry != drv + n_ents; entry++) {
-               if (strncmp(name, entry->name, len))
-                       continue;
-
-               /* Full match */
-               if (len == strlen(entry->name))
+               if (!strcmp(name, entry->name))
                        return entry;
        }
 
diff --git a/drivers/core/simple-bus.c b/drivers/core/simple-bus.c
new file mode 100644 (file)
index 0000000..3ea4d82
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2014 Google, Inc
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <dm/root.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static int simple_bus_post_bind(struct udevice *dev)
+{
+       return dm_scan_fdt_node(dev, gd->fdt_blob, dev->of_offset, false);
+}
+
+UCLASS_DRIVER(simple_bus) = {
+       .id             = UCLASS_SIMPLE_BUS,
+       .name           = "simple_bus",
+       .post_bind      = simple_bus_post_bind,
+};
+
+static const struct udevice_id generic_simple_bus_ids[] = {
+       { .compatible = "simple-bus" },
+       { }
+};
+
+U_BOOT_DRIVER(simple_bus_drv) = {
+       .name   = "generic_simple_bus",
+       .id     = UCLASS_SIMPLE_BUS,
+       .of_match = generic_simple_bus_ids,
+};
index 61ca17e564a25dff143da7c26b8d886dab90de04..901b06ed2baaf5f4b0cbdb71d3ca40170de33991 100644 (file)
@@ -60,10 +60,6 @@ static int uclass_add(enum uclass_id id, struct uclass **ucp)
                        id);
                return -ENOENT;
        }
-       if (uc_drv->ops) {
-               dm_warn("No ops for uclass id %d\n", id);
-               return -EINVAL;
-       }
        uc = calloc(1, sizeof(*uc));
        if (!uc)
                return -ENOMEM;
index b8077953c5617ed8c8b232570efabfa9c10e9fa2..7b792371811eb37e7dadcf39310e65f955237678 100644 (file)
@@ -6,3 +6,4 @@
 #
 
 obj-$(CONFIG_EXYNOS_ACE_SHA)   += ace_sha.o
+obj-y += fsl/
diff --git a/drivers/crypto/fsl/Makefile b/drivers/crypto/fsl/Makefile
new file mode 100644 (file)
index 0000000..cb13d2e
--- /dev/null
@@ -0,0 +1,10 @@
+#
+# Copyright 2014 Freescale Semiconductor, Inc.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# Version 2 as published by the Free Software Foundation.
+#
+
+obj-$(CONFIG_FSL_CAAM) += jr.o fsl_hash.o jobdesc.o error.o
+obj-$(CONFIG_CMD_BLOB) += fsl_blob.o
diff --git a/drivers/crypto/fsl/desc.h b/drivers/crypto/fsl/desc.h
new file mode 100644 (file)
index 0000000..504f2b0
--- /dev/null
@@ -0,0 +1,651 @@
+/*
+ * CAAM descriptor composition header
+ * Definitions to support CAAM descriptor instruction generation
+ *
+ * Copyright 2008-2014 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ *
+ * Based on desc.h file in linux drivers/crypto/caam
+ */
+
+#ifndef DESC_H
+#define DESC_H
+
+/* Max size of any CAAM descriptor in 32-bit words, inclusive of header */
+#define MAX_CAAM_DESCSIZE      64
+
+/* Block size of any entity covered/uncovered with a KEK/TKEK */
+#define KEK_BLOCKSIZE          16
+/*
+ * Supported descriptor command types as they show up
+ * inside a descriptor command word.
+ */
+#define CMD_SHIFT              27
+#define CMD_MASK               0xf8000000
+
+#define CMD_KEY                        (0x00 << CMD_SHIFT)
+#define CMD_SEQ_KEY            (0x01 << CMD_SHIFT)
+#define CMD_LOAD               (0x02 << CMD_SHIFT)
+#define CMD_SEQ_LOAD           (0x03 << CMD_SHIFT)
+#define CMD_FIFO_LOAD          (0x04 << CMD_SHIFT)
+#define CMD_SEQ_FIFO_LOAD      (0x05 << CMD_SHIFT)
+#define CMD_STORE              (0x0a << CMD_SHIFT)
+#define CMD_SEQ_STORE          (0x0b << CMD_SHIFT)
+#define CMD_FIFO_STORE         (0x0c << CMD_SHIFT)
+#define CMD_SEQ_FIFO_STORE     (0x0d << CMD_SHIFT)
+#define CMD_MOVE_LEN           (0x0e << CMD_SHIFT)
+#define CMD_MOVE               (0x0f << CMD_SHIFT)
+#define CMD_OPERATION          (0x10 << CMD_SHIFT)
+#define CMD_SIGNATURE          (0x12 << CMD_SHIFT)
+#define CMD_JUMP               (0x14 << CMD_SHIFT)
+#define CMD_MATH               (0x15 << CMD_SHIFT)
+#define CMD_DESC_HDR           (0x16 << CMD_SHIFT)
+#define CMD_SHARED_DESC_HDR    (0x17 << CMD_SHIFT)
+#define CMD_SEQ_IN_PTR         (0x1e << CMD_SHIFT)
+#define CMD_SEQ_OUT_PTR                (0x1f << CMD_SHIFT)
+
+/* General-purpose class selector for all commands */
+#define CLASS_SHIFT            25
+#define CLASS_MASK             (0x03 << CLASS_SHIFT)
+
+#define CLASS_NONE             (0x00 << CLASS_SHIFT)
+#define CLASS_1                        (0x01 << CLASS_SHIFT)
+#define CLASS_2                        (0x02 << CLASS_SHIFT)
+#define CLASS_BOTH             (0x03 << CLASS_SHIFT)
+
+/*
+ * Descriptor header command constructs
+ * Covers shared, job, and trusted descriptor headers
+ */
+
+/*
+ * Do Not Run - marks a descriptor inexecutable if there was
+ * a preceding error somewhere
+ */
+#define HDR_DNR                        0x01000000
+
+/*
+ * ONE - should always be set. Combination of ONE (always
+ * set) and ZRO (always clear) forms an endianness sanity check
+ */
+#define HDR_ONE                        0x00800000
+#define HDR_ZRO                        0x00008000
+
+/* Start Index or SharedDesc Length */
+#define HDR_START_IDX_MASK     0x3f
+#define HDR_START_IDX_SHIFT    16
+
+/* If shared descriptor header, 6-bit length */
+#define HDR_DESCLEN_SHR_MASK   0x3f
+
+/* If non-shared header, 7-bit length */
+#define HDR_DESCLEN_MASK       0x7f
+
+/* This is a TrustedDesc (if not SharedDesc) */
+#define HDR_TRUSTED            0x00004000
+
+/* Make into TrustedDesc (if not SharedDesc) */
+#define HDR_MAKE_TRUSTED       0x00002000
+
+/* Save context if self-shared (if SharedDesc) */
+#define HDR_SAVECTX            0x00001000
+
+/* Next item points to SharedDesc */
+#define HDR_SHARED             0x00001000
+
+/*
+ * Reverse Execution Order - execute JobDesc first, then
+ * execute SharedDesc (normally SharedDesc goes first).
+ */
+#define HDR_REVERSE            0x00000800
+
+/* Propogate DNR property to SharedDesc */
+#define HDR_PROP_DNR           0x00000800
+
+/* JobDesc/SharedDesc share property */
+#define HDR_SD_SHARE_MASK      0x03
+#define HDR_SD_SHARE_SHIFT     8
+#define HDR_JD_SHARE_MASK      0x07
+#define HDR_JD_SHARE_SHIFT     8
+
+#define HDR_SHARE_NEVER                (0x00 << HDR_SD_SHARE_SHIFT)
+#define HDR_SHARE_WAIT         (0x01 << HDR_SD_SHARE_SHIFT)
+#define HDR_SHARE_SERIAL       (0x02 << HDR_SD_SHARE_SHIFT)
+#define HDR_SHARE_ALWAYS       (0x03 << HDR_SD_SHARE_SHIFT)
+#define HDR_SHARE_DEFER                (0x04 << HDR_SD_SHARE_SHIFT)
+
+/* JobDesc/SharedDesc descriptor length */
+#define HDR_JD_LENGTH_MASK     0x7f
+#define HDR_SD_LENGTH_MASK     0x3f
+
+/*
+ * KEY/SEQ_KEY Command Constructs
+ */
+
+/* Key Destination Class: 01 = Class 1, 02 - Class 2 */
+#define KEY_DEST_CLASS_SHIFT   25      /* use CLASS_1 or CLASS_2 */
+#define KEY_DEST_CLASS_MASK    (0x03 << KEY_DEST_CLASS_SHIFT)
+
+/* Scatter-Gather Table/Variable Length Field */
+#define KEY_SGF                        0x01000000
+#define KEY_VLF                        0x01000000
+
+/* Immediate - Key follows command in the descriptor */
+#define KEY_IMM                        0x00800000
+
+/*
+ * Encrypted - Key is encrypted either with the KEK, or
+ * with the TDKEK if TK is set
+ */
+#define KEY_ENC                        0x00400000
+
+/*
+ * No Write Back - Do not allow key to be FIFO STOREd
+ */
+#define KEY_NWB                        0x00200000
+
+/*
+ * Enhanced Encryption of Key
+ */
+#define KEY_EKT                        0x00100000
+
+/*
+ * Encrypted with Trusted Key
+ */
+#define KEY_TK                 0x00008000
+
+/*
+ * KDEST - Key Destination: 0 - class key register,
+ * 1 - PKHA 'e', 2 - AFHA Sbox, 3 - MDHA split-key
+ */
+#define KEY_DEST_SHIFT         16
+#define KEY_DEST_MASK          (0x03 << KEY_DEST_SHIFT)
+
+#define KEY_DEST_CLASS_REG     (0x00 << KEY_DEST_SHIFT)
+#define KEY_DEST_PKHA_E                (0x01 << KEY_DEST_SHIFT)
+#define KEY_DEST_AFHA_SBOX     (0x02 << KEY_DEST_SHIFT)
+#define KEY_DEST_MDHA_SPLIT    (0x03 << KEY_DEST_SHIFT)
+
+/* Length in bytes */
+#define KEY_LENGTH_MASK                0x000003ff
+
+/*
+ * LOAD/SEQ_LOAD/STORE/SEQ_STORE Command Constructs
+ */
+
+/*
+ * Load/Store Destination: 0 = class independent CCB,
+ * 1 = class 1 CCB, 2 = class 2 CCB, 3 = DECO
+ */
+#define LDST_CLASS_SHIFT       25
+#define LDST_CLASS_MASK                (0x03 << LDST_CLASS_SHIFT)
+#define LDST_CLASS_IND_CCB     (0x00 << LDST_CLASS_SHIFT)
+#define LDST_CLASS_1_CCB       (0x01 << LDST_CLASS_SHIFT)
+#define LDST_CLASS_2_CCB       (0x02 << LDST_CLASS_SHIFT)
+#define LDST_CLASS_DECO                (0x03 << LDST_CLASS_SHIFT)
+
+/* Scatter-Gather Table/Variable Length Field */
+#define LDST_SGF               0x01000000
+#define LDST_VLF               LDST_SGF
+
+/* Immediate - Key follows this command in descriptor */
+#define LDST_IMM_MASK          1
+#define LDST_IMM_SHIFT         23
+#define LDST_IMM               (LDST_IMM_MASK << LDST_IMM_SHIFT)
+
+/* SRC/DST - Destination for LOAD, Source for STORE */
+#define LDST_SRCDST_SHIFT      16
+#define LDST_SRCDST_MASK       (0x7f << LDST_SRCDST_SHIFT)
+
+#define LDST_SRCDST_BYTE_CONTEXT       (0x20 << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_BYTE_KEY           (0x40 << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_BYTE_INFIFO                (0x7c << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_BYTE_OUTFIFO       (0x7e << LDST_SRCDST_SHIFT)
+
+#define LDST_SRCDST_WORD_MODE_REG      (0x00 << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_KEYSZ_REG     (0x01 << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_DATASZ_REG    (0x02 << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_ICVSZ_REG     (0x03 << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_CHACTRL       (0x06 << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_DECOCTRL      (0x06 << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_IRQCTRL       (0x07 << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_DECO_PCLOVRD  (0x07 << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_CLRW          (0x08 << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_DECO_MATH0    (0x08 << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_STAT          (0x09 << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_DECO_MATH1    (0x09 << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_DECO_MATH2    (0x0a << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_DECO_AAD_SZ   (0x0b << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_DECO_MATH3    (0x0b << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_CLASS1_ICV_SZ (0x0c << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_ALTDS_CLASS1  (0x0f << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_PKHA_A_SZ     (0x10 << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_PKHA_B_SZ     (0x11 << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_PKHA_N_SZ     (0x12 << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_PKHA_E_SZ     (0x13 << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_CLASS_CTX     (0x20 << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_DESCBUF       (0x40 << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_DESCBUF_JOB   (0x41 << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_DESCBUF_SHARED        (0x42 << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_DESCBUF_JOB_WE        (0x45 << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_DESCBUF_SHARED_WE (0x46 << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_INFO_FIFO     (0x7a << LDST_SRCDST_SHIFT)
+
+/* Offset in source/destination */
+#define LDST_OFFSET_SHIFT      8
+#define LDST_OFFSET_MASK       (0xff << LDST_OFFSET_SHIFT)
+
+/* LDOFF definitions used when DST = LDST_SRCDST_WORD_DECOCTRL */
+/* These could also be shifted by LDST_OFFSET_SHIFT - this reads better */
+#define LDOFF_CHG_SHARE_SHIFT          0
+#define LDOFF_CHG_SHARE_MASK           (0x3 << LDOFF_CHG_SHARE_SHIFT)
+#define LDOFF_CHG_SHARE_NEVER          (0x1 << LDOFF_CHG_SHARE_SHIFT)
+#define LDOFF_CHG_SHARE_OK_PROP                (0x2 << LDOFF_CHG_SHARE_SHIFT)
+#define LDOFF_CHG_SHARE_OK_NO_PROP     (0x3 << LDOFF_CHG_SHARE_SHIFT)
+
+#define LDOFF_ENABLE_AUTO_NFIFO                (1 << 2)
+#define LDOFF_DISABLE_AUTO_NFIFO       (1 << 3)
+
+#define LDOFF_CHG_NONSEQLIODN_SHIFT    4
+#define LDOFF_CHG_NONSEQLIODN_MASK     (0x3 << LDOFF_CHG_NONSEQLIODN_SHIFT)
+#define LDOFF_CHG_NONSEQLIODN_SEQ      (0x1 << LDOFF_CHG_NONSEQLIODN_SHIFT)
+#define LDOFF_CHG_NONSEQLIODN_NON_SEQ  (0x2 << LDOFF_CHG_NONSEQLIODN_SHIFT)
+#define LDOFF_CHG_NONSEQLIODN_TRUSTED  (0x3 << LDOFF_CHG_NONSEQLIODN_SHIFT)
+
+#define LDOFF_CHG_SEQLIODN_SHIFT       6
+#define LDOFF_CHG_SEQLIODN_MASK                (0x3 << LDOFF_CHG_SEQLIODN_SHIFT)
+#define LDOFF_CHG_SEQLIODN_SEQ         (0x1 << LDOFF_CHG_SEQLIODN_SHIFT)
+#define LDOFF_CHG_SEQLIODN_NON_SEQ     (0x2 << LDOFF_CHG_SEQLIODN_SHIFT)
+#define LDOFF_CHG_SEQLIODN_TRUSTED     (0x3 << LDOFF_CHG_SEQLIODN_SHIFT)
+
+/* Data length in bytes        */
+#define LDST_LEN_SHIFT         0
+#define LDST_LEN_MASK          (0xff << LDST_LEN_SHIFT)
+
+/* Special Length definitions when dst=deco-ctrl */
+#define LDLEN_ENABLE_OSL_COUNT         (1 << 7)
+#define LDLEN_RST_CHA_OFIFO_PTR                (1 << 6)
+#define LDLEN_RST_OFIFO                        (1 << 5)
+#define LDLEN_SET_OFIFO_OFF_VALID      (1 << 4)
+#define LDLEN_SET_OFIFO_OFF_RSVD       (1 << 3)
+#define LDLEN_SET_OFIFO_OFFSET_SHIFT   0
+#define LDLEN_SET_OFIFO_OFFSET_MASK    (3 << LDLEN_SET_OFIFO_OFFSET_SHIFT)
+
+/*
+ * FIFO_LOAD/FIFO_STORE/SEQ_FIFO_LOAD/SEQ_FIFO_STORE
+ * Command Constructs
+ */
+
+/*
+ * Load Destination: 0 = skip (SEQ_FIFO_LOAD only),
+ * 1 = Load for Class1, 2 = Load for Class2, 3 = Load both
+ * Store Source: 0 = normal, 1 = Class1key, 2 = Class2key
+ */
+#define FIFOLD_CLASS_SHIFT     25
+#define FIFOLD_CLASS_MASK      (0x03 << FIFOLD_CLASS_SHIFT)
+#define FIFOLD_CLASS_SKIP      (0x00 << FIFOLD_CLASS_SHIFT)
+#define FIFOLD_CLASS_CLASS1    (0x01 << FIFOLD_CLASS_SHIFT)
+#define FIFOLD_CLASS_CLASS2    (0x02 << FIFOLD_CLASS_SHIFT)
+#define FIFOLD_CLASS_BOTH      (0x03 << FIFOLD_CLASS_SHIFT)
+
+#define FIFOST_CLASS_SHIFT     25
+#define FIFOST_CLASS_MASK      (0x03 << FIFOST_CLASS_SHIFT)
+#define FIFOST_CLASS_NORMAL    (0x00 << FIFOST_CLASS_SHIFT)
+#define FIFOST_CLASS_CLASS1KEY (0x01 << FIFOST_CLASS_SHIFT)
+#define FIFOST_CLASS_CLASS2KEY (0x02 << FIFOST_CLASS_SHIFT)
+
+/*
+ * Scatter-Gather Table/Variable Length Field
+ * If set for FIFO_LOAD, refers to a SG table. Within
+ * SEQ_FIFO_LOAD, is variable input sequence
+ */
+#define FIFOLDST_SGF_SHIFT     24
+#define FIFOLDST_SGF_MASK      (1 << FIFOLDST_SGF_SHIFT)
+#define FIFOLDST_VLF_MASK      (1 << FIFOLDST_SGF_SHIFT)
+#define FIFOLDST_SGF           (1 << FIFOLDST_SGF_SHIFT)
+#define FIFOLDST_VLF           (1 << FIFOLDST_SGF_SHIFT)
+
+/* Immediate - Data follows command in descriptor */
+#define FIFOLD_IMM_SHIFT       23
+#define FIFOLD_IMM_MASK                (1 << FIFOLD_IMM_SHIFT)
+#define FIFOLD_IMM             (1 << FIFOLD_IMM_SHIFT)
+
+/* Continue - Not the last FIFO store to come */
+#define FIFOST_CONT_SHIFT      23
+#define FIFOST_CONT_MASK       (1 << FIFOST_CONT_SHIFT)
+
+/*
+ * Extended Length - use 32-bit extended length that
+ * follows the pointer field. Illegal with IMM set
+ */
+#define FIFOLDST_EXT_SHIFT     22
+#define FIFOLDST_EXT_MASK      (1 << FIFOLDST_EXT_SHIFT)
+#define FIFOLDST_EXT           (1 << FIFOLDST_EXT_SHIFT)
+
+/* Input data type.*/
+#define FIFOLD_TYPE_SHIFT      16
+#define FIFOLD_CONT_TYPE_SHIFT 19 /* shift past last-flush bits */
+#define FIFOLD_TYPE_MASK       (0x3f << FIFOLD_TYPE_SHIFT)
+
+/* PK types */
+#define FIFOLD_TYPE_PK         (0x00 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_PK_MASK    (0x30 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_PK_TYPEMASK (0x0f << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_PK_A0      (0x00 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_PK_A1      (0x01 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_PK_A2      (0x02 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_PK_A3      (0x03 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_PK_B0      (0x04 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_PK_B1      (0x05 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_PK_B2      (0x06 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_PK_B3      (0x07 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_PK_N       (0x08 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_PK_A       (0x0c << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_PK_B       (0x0d << FIFOLD_TYPE_SHIFT)
+
+/* Other types. Need to OR in last/flush bits as desired */
+#define FIFOLD_TYPE_MSG_MASK   (0x38 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_MSG                (0x10 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_MSG1OUT2   (0x18 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_IV         (0x20 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_BITDATA    (0x28 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_AAD                (0x30 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_ICV                (0x38 << FIFOLD_TYPE_SHIFT)
+
+/* Last/Flush bits for use with "other" types above */
+#define FIFOLD_TYPE_ACT_MASK   (0x07 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_NOACTION   (0x00 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_FLUSH1     (0x01 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_LAST1      (0x02 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_LAST2FLUSH (0x03 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_LAST2      (0x04 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_LAST2FLUSH1 (0x05 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_LASTBOTH   (0x06 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_LASTBOTHFL (0x07 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_NOINFOFIFO (0x0F << FIFOLD_TYPE_SHIFT)
+
+#define FIFOLDST_LEN_MASK      0xffff
+#define FIFOLDST_EXT_LEN_MASK  0xffffffff
+
+/* Output data types */
+#define FIFOST_TYPE_SHIFT      16
+#define FIFOST_TYPE_MASK       (0x3f << FIFOST_TYPE_SHIFT)
+
+#define FIFOST_TYPE_PKHA_A0     (0x00 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_PKHA_A1     (0x01 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_PKHA_A2     (0x02 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_PKHA_A3     (0x03 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_PKHA_B0     (0x04 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_PKHA_B1     (0x05 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_PKHA_B2     (0x06 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_PKHA_B3     (0x07 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_PKHA_N      (0x08 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_PKHA_A      (0x0c << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_PKHA_B      (0x0d << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_AF_SBOX_JKEK (0x10 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_AF_SBOX_TKEK (0x21 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_PKHA_E_JKEK         (0x22 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_PKHA_E_TKEK         (0x23 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_KEY_KEK     (0x24 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_KEY_TKEK    (0x25 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_SPLIT_KEK   (0x26 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_SPLIT_TKEK  (0x27 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_OUTFIFO_KEK         (0x28 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_OUTFIFO_TKEK (0x29 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_MESSAGE_DATA (0x30 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_RNGSTORE    (0x34 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_RNGFIFO     (0x35 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_SKIP        (0x3f << FIFOST_TYPE_SHIFT)
+
+/*
+ * OPERATION Command Constructs
+ */
+
+/* Operation type selectors - OP TYPE */
+#define OP_TYPE_SHIFT          24
+#define OP_TYPE_MASK           (0x07 << OP_TYPE_SHIFT)
+
+#define OP_TYPE_UNI_PROTOCOL   (0x00 << OP_TYPE_SHIFT)
+#define OP_TYPE_PK             (0x01 << OP_TYPE_SHIFT)
+#define OP_TYPE_CLASS1_ALG     (0x02 << OP_TYPE_SHIFT)
+#define OP_TYPE_CLASS2_ALG     (0x04 << OP_TYPE_SHIFT)
+#define OP_TYPE_DECAP_PROTOCOL (0x06 << OP_TYPE_SHIFT)
+#define OP_TYPE_ENCAP_PROTOCOL (0x07 << OP_TYPE_SHIFT)
+
+/* ProtocolID selectors - PROTID */
+#define OP_PCLID_SHIFT         16
+#define OP_PCLID_MASK          (0xff << 16)
+
+/* Assuming OP_TYPE = OP_TYPE_UNI_PROTOCOL */
+#define OP_PCLID_BLOB          (0x0d << OP_PCLID_SHIFT)
+#define OP_PCLID_SECRETKEY     (0x11 << OP_PCLID_SHIFT)
+#define OP_PCLID_PUBLICKEYPAIR (0x14 << OP_PCLID_SHIFT)
+
+/* For non-protocol/alg-only op commands */
+#define OP_ALG_TYPE_SHIFT      24
+#define OP_ALG_TYPE_MASK       (0x7 << OP_ALG_TYPE_SHIFT)
+#define OP_ALG_TYPE_CLASS1     2
+#define OP_ALG_TYPE_CLASS2     4
+
+#define OP_ALG_ALGSEL_SHIFT    16
+#define OP_ALG_ALGSEL_MASK     (0xff << OP_ALG_ALGSEL_SHIFT)
+#define OP_ALG_ALGSEL_SUBMASK  (0x0f << OP_ALG_ALGSEL_SHIFT)
+#define OP_ALG_ALGSEL_AES      (0x10 << OP_ALG_ALGSEL_SHIFT)
+#define OP_ALG_ALGSEL_DES      (0x20 << OP_ALG_ALGSEL_SHIFT)
+#define OP_ALG_ALGSEL_3DES     (0x21 << OP_ALG_ALGSEL_SHIFT)
+#define OP_ALG_ALGSEL_ARC4     (0x30 << OP_ALG_ALGSEL_SHIFT)
+#define OP_ALG_ALGSEL_MD5      (0x40 << OP_ALG_ALGSEL_SHIFT)
+#define OP_ALG_ALGSEL_SHA1     (0x41 << OP_ALG_ALGSEL_SHIFT)
+#define OP_ALG_ALGSEL_SHA224   (0x42 << OP_ALG_ALGSEL_SHIFT)
+#define OP_ALG_ALGSEL_SHA256   (0x43 << OP_ALG_ALGSEL_SHIFT)
+#define OP_ALG_ALGSEL_SHA384   (0x44 << OP_ALG_ALGSEL_SHIFT)
+#define OP_ALG_ALGSEL_SHA512   (0x45 << OP_ALG_ALGSEL_SHIFT)
+#define OP_ALG_ALGSEL_RNG      (0x50 << OP_ALG_ALGSEL_SHIFT)
+#define OP_ALG_ALGSEL_SNOW     (0x60 << OP_ALG_ALGSEL_SHIFT)
+#define OP_ALG_ALGSEL_SNOW_F8  (0x60 << OP_ALG_ALGSEL_SHIFT)
+#define OP_ALG_ALGSEL_KASUMI   (0x70 << OP_ALG_ALGSEL_SHIFT)
+#define OP_ALG_ALGSEL_CRC      (0x90 << OP_ALG_ALGSEL_SHIFT)
+#define OP_ALG_ALGSEL_SNOW_F9  (0xA0 << OP_ALG_ALGSEL_SHIFT)
+
+#define OP_ALG_AAI_SHIFT       4
+#define OP_ALG_AAI_MASK                (0x1ff << OP_ALG_AAI_SHIFT)
+
+/* randomizer AAI set */
+#define OP_ALG_AAI_RNG         (0x00 << OP_ALG_AAI_SHIFT)
+#define OP_ALG_AAI_RNG_NZB     (0x10 << OP_ALG_AAI_SHIFT)
+#define OP_ALG_AAI_RNG_OBP     (0x20 << OP_ALG_AAI_SHIFT)
+
+/* RNG4 AAI set */
+#define OP_ALG_AAI_RNG4_SH_0   (0x00 << OP_ALG_AAI_SHIFT)
+#define OP_ALG_AAI_RNG4_SH_1   (0x01 << OP_ALG_AAI_SHIFT)
+#define OP_ALG_AAI_RNG4_PS     (0x40 << OP_ALG_AAI_SHIFT)
+#define OP_ALG_AAI_RNG4_AI     (0x80 << OP_ALG_AAI_SHIFT)
+#define OP_ALG_AAI_RNG4_SK     (0x100 << OP_ALG_AAI_SHIFT)
+
+/* hmac/smac AAI set */
+#define OP_ALG_AAI_HASH                (0x00 << OP_ALG_AAI_SHIFT)
+#define OP_ALG_AAI_HMAC                (0x01 << OP_ALG_AAI_SHIFT)
+#define OP_ALG_AAI_SMAC                (0x02 << OP_ALG_AAI_SHIFT)
+#define OP_ALG_AAI_HMAC_PRECOMP        (0x04 << OP_ALG_AAI_SHIFT)
+
+#define OP_ALG_AS_SHIFT                2
+#define OP_ALG_AS_MASK         (0x3 << OP_ALG_AS_SHIFT)
+#define OP_ALG_AS_UPDATE       (0 << OP_ALG_AS_SHIFT)
+#define OP_ALG_AS_INIT         (1 << OP_ALG_AS_SHIFT)
+#define OP_ALG_AS_FINALIZE     (2 << OP_ALG_AS_SHIFT)
+#define OP_ALG_AS_INITFINAL    (3 << OP_ALG_AS_SHIFT)
+
+#define OP_ALG_ICV_SHIFT       1
+#define OP_ALG_ICV_MASK                (1 << OP_ALG_ICV_SHIFT)
+#define OP_ALG_ICV_OFF         (0 << OP_ALG_ICV_SHIFT)
+#define OP_ALG_ICV_ON          (1 << OP_ALG_ICV_SHIFT)
+
+#define OP_ALG_DIR_SHIFT       0
+#define OP_ALG_DIR_MASK                1
+#define OP_ALG_DECRYPT         0
+#define OP_ALG_ENCRYPT         1
+
+/* PKHA algorithm type set */
+#define OP_ALG_PK              0x00800000
+#define OP_ALG_PK_FUN_MASK     0x3f /* clrmem, modmath, or cpymem */
+
+/* PKHA mode modular-arithmetic functions */
+#define OP_ALG_PKMODE_MOD_EXPO         0x006
+
+/*
+ * SEQ_IN_PTR Command Constructs
+ */
+
+/* Release Buffers */
+#define SQIN_RBS       0x04000000
+
+/* Sequence pointer is really a descriptor */
+#define SQIN_INL       0x02000000
+
+/* Sequence pointer is a scatter-gather table */
+#define SQIN_SGF       0x01000000
+
+/* Appends to a previous pointer */
+#define SQIN_PRE       0x00800000
+
+/* Use extended length following pointer */
+#define SQIN_EXT       0x00400000
+
+/* Restore sequence with pointer/length */
+#define SQIN_RTO       0x00200000
+
+/* Replace job descriptor */
+#define SQIN_RJD       0x00100000
+
+#define SQIN_LEN_SHIFT          0
+#define SQIN_LEN_MASK          (0xffff << SQIN_LEN_SHIFT)
+
+/*
+ * SEQ_OUT_PTR Command Constructs
+ */
+
+/* Sequence pointer is a scatter-gather table */
+#define SQOUT_SGF      0x01000000
+
+/* Appends to a previous pointer */
+#define SQOUT_PRE      SQIN_PRE
+
+/* Restore sequence with pointer/length */
+#define SQOUT_RTO       SQIN_RTO
+
+/* Use extended length following pointer */
+#define SQOUT_EXT      0x00400000
+
+#define SQOUT_LEN_SHIFT                0
+#define SQOUT_LEN_MASK         (0xffff << SQOUT_LEN_SHIFT)
+
+/*
+ * MOVE Command Constructs
+ */
+
+#define MOVE_AUX_SHIFT         25
+#define MOVE_AUX_MASK          (3 << MOVE_AUX_SHIFT)
+#define MOVE_AUX_MS            (2 << MOVE_AUX_SHIFT)
+#define MOVE_AUX_LS            (1 << MOVE_AUX_SHIFT)
+
+#define MOVE_WAITCOMP_SHIFT    24
+#define MOVE_WAITCOMP_MASK     (1 << MOVE_WAITCOMP_SHIFT)
+#define MOVE_WAITCOMP          (1 << MOVE_WAITCOMP_SHIFT)
+
+#define MOVE_SRC_SHIFT         20
+#define MOVE_SRC_MASK          (0x0f << MOVE_SRC_SHIFT)
+#define MOVE_SRC_CLASS1CTX     (0x00 << MOVE_SRC_SHIFT)
+#define MOVE_SRC_CLASS2CTX     (0x01 << MOVE_SRC_SHIFT)
+#define MOVE_SRC_OUTFIFO       (0x02 << MOVE_SRC_SHIFT)
+#define MOVE_SRC_DESCBUF       (0x03 << MOVE_SRC_SHIFT)
+#define MOVE_SRC_MATH0         (0x04 << MOVE_SRC_SHIFT)
+#define MOVE_SRC_MATH1         (0x05 << MOVE_SRC_SHIFT)
+#define MOVE_SRC_MATH2         (0x06 << MOVE_SRC_SHIFT)
+#define MOVE_SRC_MATH3         (0x07 << MOVE_SRC_SHIFT)
+#define MOVE_SRC_INFIFO                (0x08 << MOVE_SRC_SHIFT)
+#define MOVE_SRC_INFIFO_CL     (0x09 << MOVE_SRC_SHIFT)
+
+#define MOVE_DEST_SHIFT                16
+#define MOVE_DEST_MASK         (0x0f << MOVE_DEST_SHIFT)
+#define MOVE_DEST_CLASS1CTX    (0x00 << MOVE_DEST_SHIFT)
+#define MOVE_DEST_CLASS2CTX    (0x01 << MOVE_DEST_SHIFT)
+#define MOVE_DEST_OUTFIFO      (0x02 << MOVE_DEST_SHIFT)
+#define MOVE_DEST_DESCBUF      (0x03 << MOVE_DEST_SHIFT)
+#define MOVE_DEST_MATH0                (0x04 << MOVE_DEST_SHIFT)
+#define MOVE_DEST_MATH1                (0x05 << MOVE_DEST_SHIFT)
+#define MOVE_DEST_MATH2                (0x06 << MOVE_DEST_SHIFT)
+#define MOVE_DEST_MATH3                (0x07 << MOVE_DEST_SHIFT)
+#define MOVE_DEST_CLASS1INFIFO (0x08 << MOVE_DEST_SHIFT)
+#define MOVE_DEST_CLASS2INFIFO (0x09 << MOVE_DEST_SHIFT)
+#define MOVE_DEST_INFIFO_NOINFO (0x0a << MOVE_DEST_SHIFT)
+#define MOVE_DEST_PK_A         (0x0c << MOVE_DEST_SHIFT)
+#define MOVE_DEST_CLASS1KEY    (0x0d << MOVE_DEST_SHIFT)
+#define MOVE_DEST_CLASS2KEY    (0x0e << MOVE_DEST_SHIFT)
+
+#define MOVE_OFFSET_SHIFT      8
+#define MOVE_OFFSET_MASK       (0xff << MOVE_OFFSET_SHIFT)
+
+#define MOVE_LEN_SHIFT         0
+#define MOVE_LEN_MASK          (0xff << MOVE_LEN_SHIFT)
+
+#define MOVELEN_MRSEL_SHIFT    0
+#define MOVELEN_MRSEL_MASK     (0x3 << MOVE_LEN_SHIFT)
+
+/*
+ * JUMP Command Constructs
+ */
+
+#define JUMP_CLASS_SHIFT       25
+#define JUMP_CLASS_MASK                (3 << JUMP_CLASS_SHIFT)
+#define JUMP_CLASS_NONE                0
+#define JUMP_CLASS_CLASS1      (1 << JUMP_CLASS_SHIFT)
+#define JUMP_CLASS_CLASS2      (2 << JUMP_CLASS_SHIFT)
+#define JUMP_CLASS_BOTH                (3 << JUMP_CLASS_SHIFT)
+
+#define JUMP_JSL_SHIFT         24
+#define JUMP_JSL_MASK          (1 << JUMP_JSL_SHIFT)
+#define JUMP_JSL               (1 << JUMP_JSL_SHIFT)
+
+#define JUMP_TYPE_SHIFT                22
+#define JUMP_TYPE_MASK         (0x03 << JUMP_TYPE_SHIFT)
+#define JUMP_TYPE_LOCAL                (0x00 << JUMP_TYPE_SHIFT)
+#define JUMP_TYPE_NONLOCAL     (0x01 << JUMP_TYPE_SHIFT)
+#define JUMP_TYPE_HALT         (0x02 << JUMP_TYPE_SHIFT)
+#define JUMP_TYPE_HALT_USER    (0x03 << JUMP_TYPE_SHIFT)
+
+#define JUMP_TEST_SHIFT                16
+#define JUMP_TEST_MASK         (0x03 << JUMP_TEST_SHIFT)
+#define JUMP_TEST_ALL          (0x00 << JUMP_TEST_SHIFT)
+#define JUMP_TEST_INVALL       (0x01 << JUMP_TEST_SHIFT)
+#define JUMP_TEST_ANY          (0x02 << JUMP_TEST_SHIFT)
+#define JUMP_TEST_INVANY       (0x03 << JUMP_TEST_SHIFT)
+
+/* Condition codes. JSL bit is factored in */
+#define JUMP_COND_SHIFT                8
+#define JUMP_COND_MASK         (0x100ff << JUMP_COND_SHIFT)
+#define JUMP_COND_PK_0         (0x80 << JUMP_COND_SHIFT)
+#define JUMP_COND_PK_GCD_1     (0x40 << JUMP_COND_SHIFT)
+#define JUMP_COND_PK_PRIME     (0x20 << JUMP_COND_SHIFT)
+#define JUMP_COND_MATH_N       (0x08 << JUMP_COND_SHIFT)
+#define JUMP_COND_MATH_Z       (0x04 << JUMP_COND_SHIFT)
+#define JUMP_COND_MATH_C       (0x02 << JUMP_COND_SHIFT)
+#define JUMP_COND_MATH_NV      (0x01 << JUMP_COND_SHIFT)
+
+#define JUMP_COND_JRP          ((0x80 << JUMP_COND_SHIFT) | JUMP_JSL)
+#define JUMP_COND_SHRD         ((0x40 << JUMP_COND_SHIFT) | JUMP_JSL)
+#define JUMP_COND_SELF         ((0x20 << JUMP_COND_SHIFT) | JUMP_JSL)
+#define JUMP_COND_CALM         ((0x10 << JUMP_COND_SHIFT) | JUMP_JSL)
+#define JUMP_COND_NIP          ((0x08 << JUMP_COND_SHIFT) | JUMP_JSL)
+#define JUMP_COND_NIFP         ((0x04 << JUMP_COND_SHIFT) | JUMP_JSL)
+#define JUMP_COND_NOP          ((0x02 << JUMP_COND_SHIFT) | JUMP_JSL)
+#define JUMP_COND_NCP          ((0x01 << JUMP_COND_SHIFT) | JUMP_JSL)
+
+#define JUMP_OFFSET_SHIFT      0
+#define JUMP_OFFSET_MASK       (0xff << JUMP_OFFSET_SHIFT)
+
+#define OP_ALG_RNG4_SHIFT      4
+#define OP_ALG_RNG4_MAS                (0x1f3 << OP_ALG_RNG4_SHIFT)
+#define OP_ALG_RNG4_SK         (0x100 << OP_ALG_RNG4_SHIFT)
+
+#endif /* DESC_H */
diff --git a/drivers/crypto/fsl/desc_constr.h b/drivers/crypto/fsl/desc_constr.h
new file mode 100644 (file)
index 0000000..f9cae91
--- /dev/null
@@ -0,0 +1,280 @@
+/*
+ * caam descriptor construction helper functions
+ *
+ * Copyright 2008-2014 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ *
+ * Based on desc_constr.h file in linux drivers/crypto/caam
+ */
+
+#include <linux/compat.h>
+#include "desc.h"
+
+#define IMMEDIATE (1 << 23)
+#define CAAM_CMD_SZ sizeof(u32)
+#define CAAM_PTR_SZ sizeof(dma_addr_t)
+#define CAAM_DESC_BYTES_MAX (CAAM_CMD_SZ * MAX_CAAM_DESCSIZE)
+#define DESC_JOB_IO_LEN (CAAM_CMD_SZ * 5 + CAAM_PTR_SZ * 3)
+
+#ifdef DEBUG
+#define PRINT_POS do { printf("%02d: %s\n", desc_len(desc),\
+                             &__func__[sizeof("append")]); \
+                    } while (0)
+#else
+#define PRINT_POS
+#endif
+
+#define SET_OK_NO_PROP_ERRORS (IMMEDIATE | LDST_CLASS_DECO | \
+                              LDST_SRCDST_WORD_DECOCTRL | \
+                              (LDOFF_CHG_SHARE_OK_NO_PROP << \
+                               LDST_OFFSET_SHIFT))
+#define DISABLE_AUTO_INFO_FIFO (IMMEDIATE | LDST_CLASS_DECO | \
+                               LDST_SRCDST_WORD_DECOCTRL | \
+                               (LDOFF_DISABLE_AUTO_NFIFO << LDST_OFFSET_SHIFT))
+#define ENABLE_AUTO_INFO_FIFO (IMMEDIATE | LDST_CLASS_DECO | \
+                              LDST_SRCDST_WORD_DECOCTRL | \
+                              (LDOFF_ENABLE_AUTO_NFIFO << LDST_OFFSET_SHIFT))
+
+static inline int desc_len(u32 *desc)
+{
+       return *desc & HDR_DESCLEN_MASK;
+}
+
+static inline int desc_bytes(void *desc)
+{
+       return desc_len(desc) * CAAM_CMD_SZ;
+}
+
+static inline u32 *desc_end(u32 *desc)
+{
+       return desc + desc_len(desc);
+}
+
+static inline void init_desc(u32 *desc, u32 options)
+{
+       *desc = (options | HDR_ONE) + 1;
+}
+
+static inline void init_job_desc(u32 *desc, u32 options)
+{
+       init_desc(desc, CMD_DESC_HDR | options);
+}
+
+static inline void append_ptr(u32 *desc, dma_addr_t ptr)
+{
+       dma_addr_t *offset = (dma_addr_t *)desc_end(desc);
+
+       *offset = ptr;
+
+       (*desc) += CAAM_PTR_SZ / CAAM_CMD_SZ;
+}
+
+static inline void append_data(u32 *desc, void *data, int len)
+{
+       u32 *offset = desc_end(desc);
+
+       if (len) /* avoid sparse warning: memcpy with byte count of 0 */
+               memcpy(offset, data, len);
+
+       (*desc) += (len + CAAM_CMD_SZ - 1) / CAAM_CMD_SZ;
+}
+
+static inline void append_cmd(u32 *desc, u32 command)
+{
+       u32 *cmd = desc_end(desc);
+
+       *cmd = command;
+
+       (*desc)++;
+}
+
+#define append_u32 append_cmd
+
+static inline void append_u64(u32 *desc, u64 data)
+{
+       u32 *offset = desc_end(desc);
+
+       *offset = upper_32_bits(data);
+       *(++offset) = lower_32_bits(data);
+
+       (*desc) += 2;
+}
+
+/* Write command without affecting header, and return pointer to next word */
+static inline u32 *write_cmd(u32 *desc, u32 command)
+{
+       *desc = command;
+
+       return desc + 1;
+}
+
+static inline void append_cmd_ptr(u32 *desc, dma_addr_t ptr, int len,
+                                 u32 command)
+{
+       append_cmd(desc, command | len);
+       append_ptr(desc, ptr);
+}
+
+/* Write length after pointer, rather than inside command */
+static inline void append_cmd_ptr_extlen(u32 *desc, dma_addr_t ptr,
+                                        unsigned int len, u32 command)
+{
+       append_cmd(desc, command);
+       if (!(command & (SQIN_RTO | SQIN_PRE)))
+               append_ptr(desc, ptr);
+       append_cmd(desc, len);
+}
+
+static inline void append_cmd_data(u32 *desc, void *data, int len,
+                                  u32 command)
+{
+       append_cmd(desc, command | IMMEDIATE | len);
+       append_data(desc, data, len);
+}
+
+#define APPEND_CMD_RET(cmd, op) \
+static inline u32 *append_##cmd(u32 *desc, u32 options) \
+{ \
+       u32 *cmd = desc_end(desc); \
+       PRINT_POS; \
+       append_cmd(desc, CMD_##op | options); \
+       return cmd; \
+}
+APPEND_CMD_RET(jump, JUMP)
+APPEND_CMD_RET(move, MOVE)
+
+static inline void set_jump_tgt_here(u32 *desc, u32 *jump_cmd)
+{
+       *jump_cmd = *jump_cmd | (desc_len(desc) - (jump_cmd - desc));
+}
+
+static inline void set_move_tgt_here(u32 *desc, u32 *move_cmd)
+{
+       *move_cmd &= ~MOVE_OFFSET_MASK;
+       *move_cmd = *move_cmd | ((desc_len(desc) << (MOVE_OFFSET_SHIFT + 2)) &
+                                MOVE_OFFSET_MASK);
+}
+
+#define APPEND_CMD(cmd, op) \
+static inline void append_##cmd(u32 *desc, u32 options) \
+{ \
+       PRINT_POS; \
+       append_cmd(desc, CMD_##op | options); \
+}
+APPEND_CMD(operation, OPERATION)
+
+#define APPEND_CMD_LEN(cmd, op) \
+static inline void append_##cmd(u32 *desc, unsigned int len, u32 options) \
+{ \
+       PRINT_POS; \
+       append_cmd(desc, CMD_##op | len | options); \
+}
+APPEND_CMD_LEN(seq_store, SEQ_STORE)
+APPEND_CMD_LEN(seq_fifo_load, SEQ_FIFO_LOAD)
+APPEND_CMD_LEN(seq_fifo_store, SEQ_FIFO_STORE)
+
+#define APPEND_CMD_PTR(cmd, op) \
+static inline void append_##cmd(u32 *desc, dma_addr_t ptr, unsigned int len, \
+                               u32 options) \
+{ \
+       PRINT_POS; \
+       append_cmd_ptr(desc, ptr, len, CMD_##op | options); \
+}
+APPEND_CMD_PTR(key, KEY)
+APPEND_CMD_PTR(load, LOAD)
+APPEND_CMD_PTR(fifo_load, FIFO_LOAD)
+APPEND_CMD_PTR(fifo_store, FIFO_STORE)
+
+static inline void append_store(u32 *desc, dma_addr_t ptr, unsigned int len,
+                               u32 options)
+{
+       u32 cmd_src;
+
+       cmd_src = options & LDST_SRCDST_MASK;
+
+       append_cmd(desc, CMD_STORE | options | len);
+
+       /* The following options do not require pointer */
+       if (!(cmd_src == LDST_SRCDST_WORD_DESCBUF_SHARED ||
+             cmd_src == LDST_SRCDST_WORD_DESCBUF_JOB    ||
+             cmd_src == LDST_SRCDST_WORD_DESCBUF_JOB_WE ||
+             cmd_src == LDST_SRCDST_WORD_DESCBUF_SHARED_WE))
+               append_ptr(desc, ptr);
+}
+
+#define APPEND_SEQ_PTR_INTLEN(cmd, op) \
+static inline void append_seq_##cmd##_ptr_intlen(u32 *desc, dma_addr_t ptr, \
+                                                unsigned int len, \
+                                                u32 options) \
+{ \
+       PRINT_POS; \
+       if (options & (SQIN_RTO | SQIN_PRE)) \
+               append_cmd(desc, CMD_SEQ_##op##_PTR | len | options); \
+       else \
+               append_cmd_ptr(desc, ptr, len, CMD_SEQ_##op##_PTR | options); \
+}
+APPEND_SEQ_PTR_INTLEN(in, IN)
+APPEND_SEQ_PTR_INTLEN(out, OUT)
+
+#define APPEND_CMD_PTR_TO_IMM(cmd, op) \
+static inline void append_##cmd##_as_imm(u32 *desc, void *data, \
+                                        unsigned int len, u32 options) \
+{ \
+       PRINT_POS; \
+       append_cmd_data(desc, data, len, CMD_##op | options); \
+}
+APPEND_CMD_PTR_TO_IMM(load, LOAD);
+APPEND_CMD_PTR_TO_IMM(fifo_load, FIFO_LOAD);
+
+#define APPEND_CMD_PTR_EXTLEN(cmd, op) \
+static inline void append_##cmd##_extlen(u32 *desc, dma_addr_t ptr, \
+                                        unsigned int len, u32 options) \
+{ \
+       PRINT_POS; \
+       append_cmd_ptr_extlen(desc, ptr, len, CMD_##op | SQIN_EXT | options); \
+}
+APPEND_CMD_PTR_EXTLEN(seq_in_ptr, SEQ_IN_PTR)
+APPEND_CMD_PTR_EXTLEN(seq_out_ptr, SEQ_OUT_PTR)
+
+/*
+ * Determine whether to store length internally or externally depending on
+ * the size of its type
+ */
+#define APPEND_CMD_PTR_LEN(cmd, op, type) \
+static inline void append_##cmd(u32 *desc, dma_addr_t ptr, \
+                               type len, u32 options) \
+{ \
+       PRINT_POS; \
+       if (sizeof(type) > sizeof(u16)) \
+               append_##cmd##_extlen(desc, ptr, len, options); \
+       else \
+               append_##cmd##_intlen(desc, ptr, len, options); \
+}
+APPEND_CMD_PTR_LEN(seq_in_ptr, SEQ_IN_PTR, u32)
+APPEND_CMD_PTR_LEN(seq_out_ptr, SEQ_OUT_PTR, u32)
+
+/*
+ * 2nd variant for commands whose specified immediate length differs
+ * from length of immediate data provided, e.g., split keys
+ */
+#define APPEND_CMD_PTR_TO_IMM2(cmd, op) \
+static inline void append_##cmd##_as_imm(u32 *desc, void *data, \
+                                        unsigned int data_len, \
+                                        unsigned int len, u32 options) \
+{ \
+       PRINT_POS; \
+       append_cmd(desc, CMD_##op | IMMEDIATE | len | options); \
+       append_data(desc, data, data_len); \
+}
+APPEND_CMD_PTR_TO_IMM2(key, KEY);
+
+#define APPEND_CMD_RAW_IMM(cmd, op, type) \
+static inline void append_##cmd##_imm_##type(u32 *desc, type immediate, \
+                                            u32 options) \
+{ \
+       PRINT_POS; \
+       append_cmd(desc, CMD_##op | IMMEDIATE | options | sizeof(type)); \
+       append_cmd(desc, immediate); \
+}
+APPEND_CMD_RAW_IMM(load, LOAD, u32);
diff --git a/drivers/crypto/fsl/error.c b/drivers/crypto/fsl/error.c
new file mode 100644 (file)
index 0000000..28cdcdd
--- /dev/null
@@ -0,0 +1,258 @@
+/*
+ * CAAM Error Reporting
+ *
+ * Copyright 2009-2014 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ *
+ * Derived from error.c file in linux drivers/crypto/caam
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include "desc.h"
+#include "jr.h"
+
+#define CAAM_ERROR_STR_MAX 302
+
+#define JRSTA_SSRC_SHIFT            28
+#define JRSTA_CCBERR_CHAID_MASK     0x00f0
+#define JRSTA_CCBERR_CHAID_SHIFT    4
+#define JRSTA_CCBERR_ERRID_MASK     0x000
+#define JRSTA_CCBERR_CHAID_RNG      (0x05 << JRSTA_CCBERR_CHAID_SHIFT)
+
+#define JRSTA_DECOERR_JUMP          0x08000000
+#define JRSTA_DECOERR_INDEX_SHIFT   8
+#define JRSTA_DECOERR_INDEX_MASK    0xff00
+#define JRSTA_DECOERR_ERROR_MASK    0x00ff
+
+
+static const struct {
+       u8 value;
+       const char *error_text;
+} desc_error_list[] = {
+       { 0x00, "No error." },
+       { 0x01, "SGT Length Error. The descriptor is trying to read" \
+               " more data than is contained in the SGT table." },
+       { 0x02, "SGT Null Entry Error." },
+       { 0x03, "Job Ring Control Error. Bad value in Job Ring Control reg." },
+       { 0x04, "Invalid Descriptor Command." },
+       { 0x05, "Reserved." },
+       { 0x06, "Invalid KEY Command" },
+       { 0x07, "Invalid LOAD Command" },
+       { 0x08, "Invalid STORE Command" },
+       { 0x09, "Invalid OPERATION Command" },
+       { 0x0A, "Invalid FIFO LOAD Command" },
+       { 0x0B, "Invalid FIFO STORE Command" },
+       { 0x0C, "Invalid MOVE/MOVE_LEN Command" },
+       { 0x0D, "Invalid JUMP Command" },
+       { 0x0E, "Invalid MATH Command" },
+       { 0x0F, "Invalid SIGNATURE Command" },
+       { 0x10, "Invalid Sequence Command" },
+       { 0x11, "Skip data type invalid. The type must be 0xE or 0xF."},
+       { 0x12, "Shared Descriptor Header Error" },
+       { 0x13, "Header Error. Invalid length or parity, or other problems." },
+       { 0x14, "Burster Error. Burster has gotten to an illegal state" },
+       { 0x15, "Context Register Length Error" },
+       { 0x16, "DMA Error" },
+       { 0x17, "Reserved." },
+       { 0x1A, "Job failed due to JR reset" },
+       { 0x1B, "Job failed due to Fail Mode" },
+       { 0x1C, "DECO Watchdog timer timeout error" },
+       { 0x1D, "DECO tried to copy a key from another DECO but" \
+               " the other DECO's Key Registers were locked" },
+       { 0x1E, "DECO attempted to copy data from a DECO" \
+               "that had an unmasked Descriptor error" },
+       { 0x1F, "LIODN error" },
+       { 0x20, "DECO has completed a reset initiated via the DRR register" },
+       { 0x21, "Nonce error" },
+       { 0x22, "Meta data is too large (> 511 bytes) for TLS decap" },
+       { 0x23, "Read Input Frame error" },
+       { 0x24, "JDKEK, TDKEK or TDSK not loaded error" },
+       { 0x80, "DNR (do not run) error" },
+       { 0x81, "undefined protocol command" },
+       { 0x82, "invalid setting in PDB" },
+       { 0x83, "Anti-replay LATE error" },
+       { 0x84, "Anti-replay REPLAY error" },
+       { 0x85, "Sequence number overflow" },
+       { 0x86, "Sigver invalid signature" },
+       { 0x87, "DSA Sign Illegal test descriptor" },
+       { 0x88, "Protocol Format Error" },
+       { 0x89, "Protocol Size Error" },
+       { 0xC1, "Blob Command error: Undefined mode" },
+       { 0xC2, "Blob Command error: Secure Memory Blob mode error" },
+       { 0xC4, "Blob Command error: Black Blob key or input size error" },
+       { 0xC5, "Blob Command error: Invalid key destination" },
+       { 0xC8, "Blob Command error: Trusted/Secure mode error" },
+       { 0xF0, "IPsec TTL or hop limit field is 0, or was decremented to 0" },
+       { 0xF1, "3GPP HFN matches or exceeds the Threshold" },
+};
+
+static const char * const cha_id_list[] = {
+       "",
+       "AES",
+       "DES",
+       "ARC4",
+       "MDHA",
+       "RNG",
+       "SNOW f8",
+       "Kasumi f8/9",
+       "PKHA",
+       "CRCA",
+       "SNOW f9",
+       "ZUCE",
+       "ZUCA",
+};
+
+static const char * const err_id_list[] = {
+       "No error.",
+       "Mode error.",
+       "Data size error.",
+       "Key size error.",
+       "PKHA A memory size error.",
+       "PKHA B memory size error.",
+       "Data arrived out of sequence error.",
+       "PKHA divide-by-zero error.",
+       "PKHA modulus even error.",
+       "DES key parity error.",
+       "ICV check failed.",
+       "Hardware error.",
+       "Unsupported CCM AAD size.",
+       "Class 1 CHA is not reset",
+       "Invalid CHA combination was selected",
+       "Invalid CHA selected.",
+};
+
+static const char * const rng_err_id_list[] = {
+       "",
+       "",
+       "",
+       "Instantiate",
+       "Not instantiated",
+       "Test instantiate",
+       "Prediction resistance",
+       "Prediction resistance and test request",
+       "Uninstantiate",
+       "Secure key generation",
+};
+
+static void report_ccb_status(const u32 status,
+                             const char *error)
+{
+       u8 cha_id = (status & JRSTA_CCBERR_CHAID_MASK) >>
+                   JRSTA_CCBERR_CHAID_SHIFT;
+       u8 err_id = status & JRSTA_CCBERR_ERRID_MASK;
+       u8 idx = (status & JRSTA_DECOERR_INDEX_MASK) >>
+                 JRSTA_DECOERR_INDEX_SHIFT;
+       char *idx_str;
+       const char *cha_str = "unidentified cha_id value 0x";
+       char cha_err_code[3] = { 0 };
+       const char *err_str = "unidentified err_id value 0x";
+       char err_err_code[3] = { 0 };
+
+       if (status & JRSTA_DECOERR_JUMP)
+               idx_str = "jump tgt desc idx";
+       else
+               idx_str = "desc idx";
+
+       if (cha_id < ARRAY_SIZE(cha_id_list))
+               cha_str = cha_id_list[cha_id];
+       else
+               snprintf(cha_err_code, sizeof(cha_err_code), "%02x", cha_id);
+
+       if ((cha_id << JRSTA_CCBERR_CHAID_SHIFT) == JRSTA_CCBERR_CHAID_RNG &&
+           err_id < ARRAY_SIZE(rng_err_id_list) &&
+           strlen(rng_err_id_list[err_id])) {
+               /* RNG-only error */
+               err_str = rng_err_id_list[err_id];
+       } else if (err_id < ARRAY_SIZE(err_id_list)) {
+               err_str = err_id_list[err_id];
+       } else {
+               snprintf(err_err_code, sizeof(err_err_code), "%02x", err_id);
+       }
+
+       debug("%08x: %s: %s %d: %s%s: %s%s\n",
+              status, error, idx_str, idx,
+               cha_str, cha_err_code,
+               err_str, err_err_code);
+}
+
+static void report_jump_status(const u32 status,
+                              const char *error)
+{
+       debug("%08x: %s: %s() not implemented\n",
+              status, error, __func__);
+}
+
+static void report_deco_status(const u32 status,
+                              const char *error)
+{
+       u8 err_id = status & JRSTA_DECOERR_ERROR_MASK;
+       u8 idx = (status & JRSTA_DECOERR_INDEX_MASK) >>
+                 JRSTA_DECOERR_INDEX_SHIFT;
+       char *idx_str;
+       const char *err_str = "unidentified error value 0x";
+       char err_err_code[3] = { 0 };
+       int i;
+
+       if (status & JRSTA_DECOERR_JUMP)
+               idx_str = "jump tgt desc idx";
+       else
+               idx_str = "desc idx";
+
+       for (i = 0; i < ARRAY_SIZE(desc_error_list); i++)
+               if (desc_error_list[i].value == err_id)
+                       break;
+
+       if (i != ARRAY_SIZE(desc_error_list) && desc_error_list[i].error_text)
+               err_str = desc_error_list[i].error_text;
+       else
+               snprintf(err_err_code, sizeof(err_err_code), "%02x", err_id);
+
+       debug("%08x: %s: %s %d: %s%s\n",
+              status, error, idx_str, idx, err_str, err_err_code);
+}
+
+static void report_jr_status(const u32 status,
+                            const char *error)
+{
+       debug("%08x: %s: %s() not implemented\n",
+              status, error, __func__);
+}
+
+static void report_cond_code_status(const u32 status,
+                                   const char *error)
+{
+       debug("%08x: %s: %s() not implemented\n",
+              status, error, __func__);
+}
+
+void caam_jr_strstatus(u32 status)
+{
+       static const struct stat_src {
+               void (*report_ssed)(const u32 status,
+                                   const char *error);
+               const char *error;
+       } status_src[] = {
+               { NULL, "No error" },
+               { NULL, NULL },
+               { report_ccb_status, "CCB" },
+               { report_jump_status, "Jump" },
+               { report_deco_status, "DECO" },
+               { NULL, NULL },
+               { report_jr_status, "Job Ring" },
+               { report_cond_code_status, "Condition Code" },
+       };
+       u32 ssrc = status >> JRSTA_SSRC_SHIFT;
+       const char *error = status_src[ssrc].error;
+
+       /*
+        * If there is no further error handling function, just
+        * print the error code, error string and exit. Otherwise
+        * call the handler function.
+        */
+       if (!status_src[ssrc].report_ssed)
+               debug("%08x: %s:\n", status, status_src[ssrc].error);
+       else
+               status_src[ssrc].report_ssed(status, error);
+}
diff --git a/drivers/crypto/fsl/fsl_blob.c b/drivers/crypto/fsl/fsl_blob.c
new file mode 100644 (file)
index 0000000..bc01075
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2014 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ *
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include "jobdesc.h"
+#include "desc.h"
+#include "jr.h"
+
+int blob_decrypt(u8 *key_mod, u8 *src, u8 *dst, u8 len)
+{
+       int ret, i = 0;
+       u32 *desc;
+
+       printf("\nDecapsulating data to form blob\n");
+       desc = malloc(sizeof(int) * MAX_CAAM_DESCSIZE);
+       if (!desc) {
+               debug("Not enough memory for descriptor allocation\n");
+               return -1;
+       }
+
+       inline_cnstr_jobdesc_blob_decap(desc, key_mod, src, dst, len);
+
+       for (i = 0; i < 14; i++)
+               printf("%x\n", *(desc + i));
+       ret = run_descriptor_jr(desc);
+
+       if (ret)
+               printf("Error in Decapsulation %d\n", ret);
+
+       free(desc);
+       return ret;
+}
+
+int blob_encrypt(u8 *key_mod, u8 *src, u8 *dst, u8 len)
+{
+       int ret, i = 0;
+       u32 *desc;
+
+       printf("\nEncapsulating data to form blob\n");
+       desc = malloc(sizeof(int) * MAX_CAAM_DESCSIZE);
+       if (!desc) {
+               debug("Not enough memory for descriptor allocation\n");
+               return -1;
+       }
+
+       inline_cnstr_jobdesc_blob_encap(desc, key_mod, src, dst, len);
+       for (i = 0; i < 14; i++)
+               printf("%x\n", *(desc + i));
+       ret = run_descriptor_jr(desc);
+
+       if (ret)
+               printf("Error in Encapsulation %d\n", ret);
+
+       free(desc);
+       return ret;
+}
diff --git a/drivers/crypto/fsl/fsl_hash.c b/drivers/crypto/fsl/fsl_hash.c
new file mode 100644 (file)
index 0000000..d77f257
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2014 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ *
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include "jobdesc.h"
+#include "desc.h"
+#include "jr.h"
+
+#define CRYPTO_MAX_ALG_NAME    80
+#define SHA1_DIGEST_SIZE        20
+#define SHA256_DIGEST_SIZE      32
+
+struct caam_hash_template {
+       char name[CRYPTO_MAX_ALG_NAME];
+       unsigned int digestsize;
+       u32 alg_type;
+};
+
+enum caam_hash_algos {
+       SHA1 = 0,
+       SHA256
+};
+
+static struct caam_hash_template driver_hash[] = {
+       {
+               .name = "sha1",
+               .digestsize = SHA1_DIGEST_SIZE,
+               .alg_type = OP_ALG_ALGSEL_SHA1,
+       },
+       {
+               .name = "sha256",
+               .digestsize = SHA256_DIGEST_SIZE,
+               .alg_type = OP_ALG_ALGSEL_SHA256,
+       },
+};
+
+int caam_hash(const unsigned char *pbuf, unsigned int buf_len,
+             unsigned char *pout, enum caam_hash_algos algo)
+{
+       int ret = 0;
+       uint32_t *desc;
+
+       desc = malloc(sizeof(int) * MAX_CAAM_DESCSIZE);
+       if (!desc) {
+               debug("Not enough memory for descriptor allocation\n");
+               return -1;
+       }
+
+       inline_cnstr_jobdesc_hash(desc, pbuf, buf_len, pout,
+                                 driver_hash[algo].alg_type,
+                                 driver_hash[algo].digestsize,
+                                 0);
+
+       ret = run_descriptor_jr(desc);
+
+       free(desc);
+       return ret;
+}
+
+void hw_sha256(const unsigned char *pbuf, unsigned int buf_len,
+                       unsigned char *pout, unsigned int chunk_size)
+{
+       if (caam_hash(pbuf, buf_len, pout, SHA256))
+               printf("CAAM was not setup properly or it is faulty\n");
+}
+
+void hw_sha1(const unsigned char *pbuf, unsigned int buf_len,
+                       unsigned char *pout, unsigned int chunk_size)
+{
+       if (caam_hash(pbuf, buf_len, pout, SHA1))
+               printf("CAAM was not setup properly or it is faulty\n");
+}
diff --git a/drivers/crypto/fsl/jobdesc.c b/drivers/crypto/fsl/jobdesc.c
new file mode 100644 (file)
index 0000000..1386bae
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+ * SEC Descriptor Construction Library
+ * Basic job descriptor construction
+ *
+ * Copyright 2014 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ *
+ */
+
+#include <common.h>
+#include "desc_constr.h"
+#include "jobdesc.h"
+
+#define KEY_BLOB_SIZE                  32
+#define MAC_SIZE                       16
+
+void inline_cnstr_jobdesc_hash(uint32_t *desc,
+                         const uint8_t *msg, uint32_t msgsz, uint8_t *digest,
+                         u32 alg_type, uint32_t alg_size, int sg_tbl)
+{
+       /* SHA 256 , output is of length 32 words */
+       uint32_t storelen = alg_size;
+       u32 options;
+       dma_addr_t dma_addr_in, dma_addr_out;
+
+       dma_addr_in = virt_to_phys((void *)msg);
+       dma_addr_out = virt_to_phys((void *)digest);
+
+       init_job_desc(desc, 0);
+       append_operation(desc, OP_TYPE_CLASS2_ALG |
+                        OP_ALG_AAI_HASH | OP_ALG_AS_INITFINAL |
+                        OP_ALG_ENCRYPT | OP_ALG_ICV_OFF | alg_type);
+
+       options = LDST_CLASS_2_CCB | FIFOLD_TYPE_MSG | FIFOLD_TYPE_LAST2;
+       if (sg_tbl)
+               options |= FIFOLDST_SGF;
+       if (msgsz > 0xffff) {
+               options |= FIFOLDST_EXT;
+               append_fifo_load(desc, dma_addr_in, 0, options);
+               append_cmd(desc, msgsz);
+       } else {
+               append_fifo_load(desc, dma_addr_in, msgsz, options);
+       }
+
+       append_store(desc, dma_addr_out, storelen,
+                    LDST_CLASS_2_CCB | LDST_SRCDST_BYTE_CONTEXT);
+}
+
+void inline_cnstr_jobdesc_blob_encap(uint32_t *desc, uint8_t *key_idnfr,
+                                    uint8_t *plain_txt, uint8_t *enc_blob,
+                                    uint32_t in_sz)
+{
+       dma_addr_t dma_addr_key_idnfr, dma_addr_in, dma_addr_out;
+       uint32_t key_sz = KEY_IDNFR_SZ_BYTES;
+       /* output blob will have 32 bytes key blob in beginning and
+        * 16 byte HMAC identifier at end of data blob */
+       uint32_t out_sz = in_sz + KEY_BLOB_SIZE + MAC_SIZE;
+
+       dma_addr_key_idnfr = virt_to_phys((void *)key_idnfr);
+       dma_addr_in     = virt_to_phys((void *)plain_txt);
+       dma_addr_out    = virt_to_phys((void *)enc_blob);
+
+       init_job_desc(desc, 0);
+
+       append_key(desc, dma_addr_key_idnfr, key_sz, CLASS_2);
+
+       append_seq_in_ptr(desc, dma_addr_in, in_sz, 0);
+
+       append_seq_out_ptr(desc, dma_addr_out, out_sz, 0);
+
+       append_operation(desc, OP_TYPE_ENCAP_PROTOCOL | OP_PCLID_BLOB);
+}
+
+void inline_cnstr_jobdesc_blob_decap(uint32_t *desc, uint8_t *key_idnfr,
+                                    uint8_t *enc_blob, uint8_t *plain_txt,
+                                    uint32_t out_sz)
+{
+       dma_addr_t dma_addr_key_idnfr, dma_addr_in, dma_addr_out;
+       uint32_t key_sz = KEY_IDNFR_SZ_BYTES;
+       uint32_t in_sz = out_sz + KEY_BLOB_SIZE + MAC_SIZE;
+
+       dma_addr_key_idnfr = virt_to_phys((void *)key_idnfr);
+       dma_addr_in     = virt_to_phys((void *)enc_blob);
+       dma_addr_out    = virt_to_phys((void *)plain_txt);
+
+       init_job_desc(desc, 0);
+
+       append_key(desc, dma_addr_key_idnfr, key_sz, CLASS_2);
+
+       append_seq_in_ptr(desc, dma_addr_in, in_sz, 0);
+
+       append_seq_out_ptr(desc, dma_addr_out, out_sz, 0);
+
+       append_operation(desc, OP_TYPE_DECAP_PROTOCOL | OP_PCLID_BLOB);
+}
+
+/*
+ * Descriptor to instantiate RNG State Handle 0 in normal mode and
+ * load the JDKEK, TDKEK and TDSK registers
+ */
+void inline_cnstr_jobdesc_rng_instantiation(uint32_t *desc)
+{
+       u32 *jump_cmd;
+
+       init_job_desc(desc, 0);
+
+       /* INIT RNG in non-test mode */
+       append_operation(desc, OP_TYPE_CLASS1_ALG | OP_ALG_ALGSEL_RNG |
+                        OP_ALG_AS_INIT);
+
+       /* wait for done */
+       jump_cmd = append_jump(desc, JUMP_CLASS_CLASS1);
+       set_jump_tgt_here(desc, jump_cmd);
+
+       /*
+        * load 1 to clear written reg:
+        * resets the done interrrupt and returns the RNG to idle.
+        */
+       append_load_imm_u32(desc, 1, LDST_SRCDST_WORD_CLRW);
+
+       /* generate secure keys (non-test) */
+       append_operation(desc, OP_TYPE_CLASS1_ALG | OP_ALG_ALGSEL_RNG |
+                        OP_ALG_RNG4_SK);
+}
diff --git a/drivers/crypto/fsl/jobdesc.h b/drivers/crypto/fsl/jobdesc.h
new file mode 100644 (file)
index 0000000..3cf7226
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2014 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ *
+ */
+
+#ifndef __JOBDESC_H
+#define __JOBDESC_H
+
+#include <common.h>
+#include <asm/io.h>
+
+#define KEY_IDNFR_SZ_BYTES             16
+
+void inline_cnstr_jobdesc_hash(uint32_t *desc,
+                         const uint8_t *msg, uint32_t msgsz, uint8_t *digest,
+                         u32 alg_type, uint32_t alg_size, int sg_tbl);
+
+void inline_cnstr_jobdesc_blob_encap(uint32_t *desc, uint8_t *key_idnfr,
+                                    uint8_t *plain_txt, uint8_t *enc_blob,
+                                    uint32_t in_sz);
+
+void inline_cnstr_jobdesc_blob_decap(uint32_t *desc, uint8_t *key_idnfr,
+                                    uint8_t *enc_blob, uint8_t *plain_txt,
+                                    uint32_t out_sz);
+
+void inline_cnstr_jobdesc_rng_instantiation(uint32_t *desc);
+#endif
diff --git a/drivers/crypto/fsl/jr.c b/drivers/crypto/fsl/jr.c
new file mode 100644 (file)
index 0000000..29681e1
--- /dev/null
@@ -0,0 +1,462 @@
+/*
+ * Copyright 2008-2014 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ *
+ * Based on CAAM driver in drivers/crypto/caam in Linux
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include "fsl_sec.h"
+#include "jr.h"
+#include "jobdesc.h"
+
+#define CIRC_CNT(head, tail, size)     (((head) - (tail)) & (size - 1))
+#define CIRC_SPACE(head, tail, size)   CIRC_CNT((tail), (head) + 1, (size))
+
+struct jobring jr;
+
+static inline void start_jr0(void)
+{
+       ccsr_sec_t *sec = (void *)CONFIG_SYS_FSL_SEC_ADDR;
+       u32 ctpr_ms = sec_in32(&sec->ctpr_ms);
+       u32 scfgr = sec_in32(&sec->scfgr);
+
+       if (ctpr_ms & SEC_CTPR_MS_VIRT_EN_INCL) {
+               /* VIRT_EN_INCL = 1 & VIRT_EN_POR = 1 or
+                * VIRT_EN_INCL = 1 & VIRT_EN_POR = 0 & SEC_SCFGR_VIRT_EN = 1
+                */
+               if ((ctpr_ms & SEC_CTPR_MS_VIRT_EN_POR) ||
+                   (!(ctpr_ms & SEC_CTPR_MS_VIRT_EN_POR) &&
+                                       (scfgr & SEC_SCFGR_VIRT_EN)))
+                       sec_out32(&sec->jrstartr, CONFIG_JRSTARTR_JR0);
+       } else {
+               /* VIRT_EN_INCL = 0 && VIRT_EN_POR_VALUE = 1 */
+               if (ctpr_ms & SEC_CTPR_MS_VIRT_EN_POR)
+                       sec_out32(&sec->jrstartr, CONFIG_JRSTARTR_JR0);
+       }
+}
+
+static inline void jr_reset_liodn(void)
+{
+       ccsr_sec_t *sec = (void *)CONFIG_SYS_FSL_SEC_ADDR;
+       sec_out32(&sec->jrliodnr[0].ls, 0);
+}
+
+static inline void jr_disable_irq(void)
+{
+       struct jr_regs *regs = (struct jr_regs *)CONFIG_SYS_FSL_JR0_ADDR;
+       uint32_t jrcfg = sec_in32(&regs->jrcfg1);
+
+       jrcfg = jrcfg | JR_INTMASK;
+
+       sec_out32(&regs->jrcfg1, jrcfg);
+}
+
+static void jr_initregs(void)
+{
+       struct jr_regs *regs = (struct jr_regs *)CONFIG_SYS_FSL_JR0_ADDR;
+       phys_addr_t ip_base = virt_to_phys((void *)jr.input_ring);
+       phys_addr_t op_base = virt_to_phys((void *)jr.output_ring);
+
+#ifdef CONFIG_PHYS_64BIT
+       sec_out32(&regs->irba_h, ip_base >> 32);
+#else
+       sec_out32(&regs->irba_h, 0x0);
+#endif
+       sec_out32(&regs->irba_l, (uint32_t)ip_base);
+#ifdef CONFIG_PHYS_64BIT
+       sec_out32(&regs->orba_h, op_base >> 32);
+#else
+       sec_out32(&regs->orba_h, 0x0);
+#endif
+       sec_out32(&regs->orba_l, (uint32_t)op_base);
+       sec_out32(&regs->ors, JR_SIZE);
+       sec_out32(&regs->irs, JR_SIZE);
+
+       if (!jr.irq)
+               jr_disable_irq();
+}
+
+static int jr_init(void)
+{
+       memset(&jr, 0, sizeof(struct jobring));
+
+       jr.jq_id = DEFAULT_JR_ID;
+       jr.irq = DEFAULT_IRQ;
+
+#ifdef CONFIG_FSL_CORENET
+       jr.liodn = DEFAULT_JR_LIODN;
+#endif
+       jr.size = JR_SIZE;
+       jr.input_ring = (dma_addr_t *)malloc(JR_SIZE * sizeof(dma_addr_t));
+       if (!jr.input_ring)
+               return -1;
+       jr.output_ring =
+           (struct op_ring *)malloc(JR_SIZE * sizeof(struct op_ring));
+       if (!jr.output_ring)
+               return -1;
+
+       memset(jr.input_ring, 0, JR_SIZE * sizeof(dma_addr_t));
+       memset(jr.output_ring, 0, JR_SIZE * sizeof(struct op_ring));
+
+       start_jr0();
+
+       jr_initregs();
+
+       return 0;
+}
+
+static int jr_sw_cleanup(void)
+{
+       jr.head = 0;
+       jr.tail = 0;
+       jr.read_idx = 0;
+       jr.write_idx = 0;
+       memset(jr.info, 0, sizeof(jr.info));
+       memset(jr.input_ring, 0, jr.size * sizeof(dma_addr_t));
+       memset(jr.output_ring, 0, jr.size * sizeof(struct op_ring));
+
+       return 0;
+}
+
+static int jr_hw_reset(void)
+{
+       struct jr_regs *regs = (struct jr_regs *)CONFIG_SYS_FSL_JR0_ADDR;
+       uint32_t timeout = 100000;
+       uint32_t jrint, jrcr;
+
+       sec_out32(&regs->jrcr, JRCR_RESET);
+       do {
+               jrint = sec_in32(&regs->jrint);
+       } while (((jrint & JRINT_ERR_HALT_MASK) ==
+                 JRINT_ERR_HALT_INPROGRESS) && --timeout);
+
+       jrint = sec_in32(&regs->jrint);
+       if (((jrint & JRINT_ERR_HALT_MASK) !=
+            JRINT_ERR_HALT_INPROGRESS) && timeout == 0)
+               return -1;
+
+       timeout = 100000;
+       sec_out32(&regs->jrcr, JRCR_RESET);
+       do {
+               jrcr = sec_in32(&regs->jrcr);
+       } while ((jrcr & JRCR_RESET) && --timeout);
+
+       if (timeout == 0)
+               return -1;
+
+       return 0;
+}
+
+/* -1 --- error, can't enqueue -- no space available */
+static int jr_enqueue(uint32_t *desc_addr,
+              void (*callback)(uint32_t desc, uint32_t status, void *arg),
+              void *arg)
+{
+       struct jr_regs *regs = (struct jr_regs *)CONFIG_SYS_FSL_JR0_ADDR;
+       int head = jr.head;
+       dma_addr_t desc_phys_addr = virt_to_phys(desc_addr);
+
+       if (sec_in32(&regs->irsa) == 0 ||
+           CIRC_SPACE(jr.head, jr.tail, jr.size) <= 0)
+               return -1;
+
+       jr.input_ring[head] = desc_phys_addr;
+       jr.info[head].desc_phys_addr = desc_phys_addr;
+       jr.info[head].desc_addr = (uint32_t)desc_addr;
+       jr.info[head].callback = (void *)callback;
+       jr.info[head].arg = arg;
+       jr.info[head].op_done = 0;
+
+       jr.head = (head + 1) & (jr.size - 1);
+
+       sec_out32(&regs->irja, 1);
+
+       return 0;
+}
+
+static int jr_dequeue(void)
+{
+       struct jr_regs *regs = (struct jr_regs *)CONFIG_SYS_FSL_JR0_ADDR;
+       int head = jr.head;
+       int tail = jr.tail;
+       int idx, i, found;
+       void (*callback)(uint32_t desc, uint32_t status, void *arg);
+       void *arg = NULL;
+
+       while (sec_in32(&regs->orsf) && CIRC_CNT(jr.head, jr.tail, jr.size)) {
+               found = 0;
+
+               dma_addr_t op_desc = jr.output_ring[jr.tail].desc;
+               uint32_t status = jr.output_ring[jr.tail].status;
+               uint32_t desc_virt;
+
+               for (i = 0; CIRC_CNT(head, tail + i, jr.size) >= 1; i++) {
+                       idx = (tail + i) & (jr.size - 1);
+                       if (op_desc == jr.info[idx].desc_phys_addr) {
+                               desc_virt = jr.info[idx].desc_addr;
+                               found = 1;
+                               break;
+                       }
+               }
+
+               /* Error condition if match not found */
+               if (!found)
+                       return -1;
+
+               jr.info[idx].op_done = 1;
+               callback = (void *)jr.info[idx].callback;
+               arg = jr.info[idx].arg;
+
+               /* When the job on tail idx gets done, increment
+                * tail till the point where job completed out of oredr has
+                * been taken into account
+                */
+               if (idx == tail)
+                       do {
+                               tail = (tail + 1) & (jr.size - 1);
+                       } while (jr.info[tail].op_done);
+
+               jr.tail = tail;
+               jr.read_idx = (jr.read_idx + 1) & (jr.size - 1);
+
+               sec_out32(&regs->orjr, 1);
+               jr.info[idx].op_done = 0;
+
+               callback(desc_virt, status, arg);
+       }
+
+       return 0;
+}
+
+static void desc_done(uint32_t desc, uint32_t status, void *arg)
+{
+       struct result *x = arg;
+       x->status = status;
+       caam_jr_strstatus(status);
+       x->done = 1;
+}
+
+int run_descriptor_jr(uint32_t *desc)
+{
+       unsigned long long timeval = get_ticks();
+       unsigned long long timeout = usec2ticks(CONFIG_SEC_DEQ_TIMEOUT);
+       struct result op;
+       int ret = 0;
+
+       memset(&op, sizeof(op), 0);
+
+       ret = jr_enqueue(desc, desc_done, &op);
+       if (ret) {
+               debug("Error in SEC enq\n");
+               ret = JQ_ENQ_ERR;
+               goto out;
+       }
+
+       timeval = get_ticks();
+       timeout = usec2ticks(CONFIG_SEC_DEQ_TIMEOUT);
+       while (op.done != 1) {
+               ret = jr_dequeue();
+               if (ret) {
+                       debug("Error in SEC deq\n");
+                       ret = JQ_DEQ_ERR;
+                       goto out;
+               }
+
+               if ((get_ticks() - timeval) > timeout) {
+                       debug("SEC Dequeue timed out\n");
+                       ret = JQ_DEQ_TO_ERR;
+                       goto out;
+               }
+       }
+
+       if (!op.status) {
+               debug("Error %x\n", op.status);
+               ret = op.status;
+       }
+out:
+       return ret;
+}
+
+int jr_reset(void)
+{
+       if (jr_hw_reset() < 0)
+               return -1;
+
+       /* Clean up the jobring structure maintained by software */
+       jr_sw_cleanup();
+
+       return 0;
+}
+
+int sec_reset(void)
+{
+       ccsr_sec_t *sec = (void *)CONFIG_SYS_FSL_SEC_ADDR;
+       uint32_t mcfgr = sec_in32(&sec->mcfgr);
+       uint32_t timeout = 100000;
+
+       mcfgr |= MCFGR_SWRST;
+       sec_out32(&sec->mcfgr, mcfgr);
+
+       mcfgr |= MCFGR_DMA_RST;
+       sec_out32(&sec->mcfgr, mcfgr);
+       do {
+               mcfgr = sec_in32(&sec->mcfgr);
+       } while ((mcfgr & MCFGR_DMA_RST) == MCFGR_DMA_RST && --timeout);
+
+       if (timeout == 0)
+               return -1;
+
+       timeout = 100000;
+       do {
+               mcfgr = sec_in32(&sec->mcfgr);
+       } while ((mcfgr & MCFGR_SWRST) == MCFGR_SWRST && --timeout);
+
+       if (timeout == 0)
+               return -1;
+
+       return 0;
+}
+
+static int instantiate_rng(void)
+{
+       struct result op;
+       u32 *desc;
+       u32 rdsta_val;
+       int ret = 0;
+       ccsr_sec_t __iomem *sec =
+                       (ccsr_sec_t __iomem *)CONFIG_SYS_FSL_SEC_ADDR;
+       struct rng4tst __iomem *rng =
+                       (struct rng4tst __iomem *)&sec->rng;
+
+       memset(&op, 0, sizeof(struct result));
+
+       desc = malloc(sizeof(int) * 6);
+       if (!desc) {
+               printf("cannot allocate RNG init descriptor memory\n");
+               return -1;
+       }
+
+       inline_cnstr_jobdesc_rng_instantiation(desc);
+       ret = run_descriptor_jr(desc);
+
+       if (ret)
+               printf("RNG: Instantiation failed with error %x\n", ret);
+
+       rdsta_val = sec_in32(&rng->rdsta);
+       if (op.status || !(rdsta_val & RNG_STATE0_HANDLE_INSTANTIATED))
+               return -1;
+
+       return ret;
+}
+
+static u8 get_rng_vid(void)
+{
+       ccsr_sec_t *sec = (void *)CONFIG_SYS_FSL_SEC_ADDR;
+       u32 cha_vid = sec_in32(&sec->chavid_ls);
+
+       return (cha_vid & SEC_CHAVID_RNG_LS_MASK) >> SEC_CHAVID_LS_RNG_SHIFT;
+}
+
+/*
+ * By default, the TRNG runs for 200 clocks per sample;
+ * 1200 clocks per sample generates better entropy.
+ */
+static void kick_trng(int ent_delay)
+{
+       ccsr_sec_t __iomem *sec =
+                       (ccsr_sec_t __iomem *)CONFIG_SYS_FSL_SEC_ADDR;
+       struct rng4tst __iomem *rng =
+                       (struct rng4tst __iomem *)&sec->rng;
+       u32 val;
+
+       /* put RNG4 into program mode */
+       sec_setbits32(&rng->rtmctl, RTMCTL_PRGM);
+       /* rtsdctl bits 0-15 contain "Entropy Delay, which defines the
+        * length (in system clocks) of each Entropy sample taken
+        * */
+       val = sec_in32(&rng->rtsdctl);
+       val = (val & ~RTSDCTL_ENT_DLY_MASK) |
+             (ent_delay << RTSDCTL_ENT_DLY_SHIFT);
+       sec_out32(&rng->rtsdctl, val);
+       /* min. freq. count, equal to 1/4 of the entropy sample length */
+       sec_out32(&rng->rtfreqmin, ent_delay >> 2);
+       /* max. freq. count, equal to 8 times the entropy sample length */
+       sec_out32(&rng->rtfreqmax, ent_delay << 3);
+       /* put RNG4 into run mode */
+       sec_clrbits32(&rng->rtmctl, RTMCTL_PRGM);
+}
+
+static int rng_init(void)
+{
+       int ret, ent_delay = RTSDCTL_ENT_DLY_MIN;
+       ccsr_sec_t __iomem *sec =
+                       (ccsr_sec_t __iomem *)CONFIG_SYS_FSL_SEC_ADDR;
+       struct rng4tst __iomem *rng =
+                       (struct rng4tst __iomem *)&sec->rng;
+
+       u32 rdsta = sec_in32(&rng->rdsta);
+
+       /* Check if RNG state 0 handler is already instantiated */
+       if (rdsta & RNG_STATE0_HANDLE_INSTANTIATED)
+               return 0;
+
+       do {
+               /*
+                * If either of the SH's were instantiated by somebody else
+                * then it is assumed that the entropy
+                * parameters are properly set and thus the function
+                * setting these (kick_trng(...)) is skipped.
+                * Also, if a handle was instantiated, do not change
+                * the TRNG parameters.
+                */
+               kick_trng(ent_delay);
+               ent_delay += 400;
+               /*
+                * if instantiate_rng(...) fails, the loop will rerun
+                * and the kick_trng(...) function will modfiy the
+                * upper and lower limits of the entropy sampling
+                * interval, leading to a sucessful initialization of
+                * the RNG.
+                */
+               ret = instantiate_rng();
+       } while ((ret == -1) && (ent_delay < RTSDCTL_ENT_DLY_MAX));
+       if (ret) {
+               printf("RNG: Failed to instantiate RNG\n");
+               return ret;
+       }
+
+        /* Enable RDB bit so that RNG works faster */
+       sec_setbits32(&sec->scfgr, SEC_SCFGR_RDBENABLE);
+
+       return ret;
+}
+
+int sec_init(void)
+{
+       int ret = 0;
+
+#ifdef CONFIG_PHYS_64BIT
+       ccsr_sec_t *sec = (void *)CONFIG_SYS_FSL_SEC_ADDR;
+       uint32_t mcr = sec_in32(&sec->mcfgr);
+
+       sec_out32(&sec->mcfgr, mcr | 1 << MCFGR_PS_SHIFT);
+#endif
+       ret = jr_init();
+       if (ret < 0) {
+               printf("SEC initialization failed\n");
+               return -1;
+       }
+
+       if (get_rng_vid() >= 4) {
+               if (rng_init() < 0) {
+                       printf("RNG instantiation failed\n");
+                       return -1;
+               }
+               printf("SEC: RNG instantiated\n");
+       }
+
+       return ret;
+}
diff --git a/drivers/crypto/fsl/jr.h b/drivers/crypto/fsl/jr.h
new file mode 100644 (file)
index 0000000..cce2c58
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2008-2014 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ *
+ */
+
+#ifndef __JR_H
+#define __JR_H
+
+#include <linux/compiler.h>
+
+#define JR_SIZE 4
+/* Timeout currently defined as 90 sec */
+#define CONFIG_SEC_DEQ_TIMEOUT 90000000U
+
+#define DEFAULT_JR_ID          0
+#define DEFAULT_JR_LIODN       0
+#define DEFAULT_IRQ            0       /* Interrupts not to be configured */
+
+#define MCFGR_SWRST       ((uint32_t)(1)<<31) /* Software Reset */
+#define MCFGR_DMA_RST     ((uint32_t)(1)<<28) /* DMA Reset */
+#define MCFGR_PS_SHIFT          16
+#define JR_INTMASK       0x00000001
+#define JRCR_RESET                  0x01
+#define JRINT_ERR_HALT_INPROGRESS   0x4
+#define JRINT_ERR_HALT_MASK         0xc
+#define JRNSLIODN_SHIFT                16
+#define JRNSLIODN_MASK         0x0fff0000
+#define JRSLIODN_SHIFT         0
+#define JRSLIODN_MASK          0x00000fff
+
+#define JQ_DEQ_ERR             -1
+#define JQ_DEQ_TO_ERR          -2
+#define JQ_ENQ_ERR             -3
+
+struct op_ring {
+       dma_addr_t desc;
+       uint32_t status;
+} __packed;
+
+struct jr_info {
+       void (*callback)(dma_addr_t desc, uint32_t status, void *arg);
+       dma_addr_t desc_phys_addr;
+       uint32_t desc_addr;
+       uint32_t desc_len;
+       uint32_t op_done;
+       void *arg;
+};
+
+struct jobring {
+       int jq_id;
+       int irq;
+       int liodn;
+       /* Head is the index where software would enq the descriptor in
+        * the i/p ring
+        */
+       int head;
+       /* Tail index would be used by s/w ehile enqueuing to determine if
+        * there is any space left in the s/w maintained i/p rings
+        */
+       /* Also in case of deq tail will be incremented only in case of
+        * in-order job completion
+        */
+       int tail;
+       /* Read index of the output ring. It may not match with tail in case
+        * of out of order completetion
+        */
+       int read_idx;
+       /* Write index to input ring. Would be always equal to head */
+       int write_idx;
+       /* Size of the rings. */
+       int size;
+       /* The ip and output rings have to be accessed by SEC. So the
+        * pointers will ahve to point to the housekeeping region provided
+        * by SEC
+        */
+       /*Circular  Ring of i/p descriptors */
+       dma_addr_t *input_ring;
+       /* Circular Ring of o/p descriptors */
+       /* Circula Ring containing info regarding descriptors in i/p
+        * and o/p ring
+        */
+       /* This ring can be on the stack */
+       struct jr_info info[JR_SIZE];
+       struct op_ring *output_ring;
+};
+
+struct result {
+       int done;
+       uint32_t status;
+};
+
+void caam_jr_strstatus(u32 status);
+int run_descriptor_jr(uint32_t *desc);
+
+#endif
index 91f6df220b1dd7f11aabdaddb28fa7e3db32b44e..c3d3c3bcd85355b77dc8cb1d4c945a589f550781 100644 (file)
@@ -9,6 +9,7 @@
 #include <errno.h>
 #include <div64.h>
 #include <dfu.h>
+#include <spi.h>
 #include <spi_flash.h>
 
 static long dfu_get_medium_size_sf(struct dfu_entity *dfu)
index a79c3919ddc7d452a41ca8bc8676b2c97c88ad54..4c8fcc257568042d7168deb0ea267aeb74e11c7b 100644 (file)
@@ -8,3 +8,5 @@
 obj-$(CONFIG_FSLDMAFEC) += MCD_tasksInit.o MCD_dmaApi.o MCD_tasks.o
 obj-$(CONFIG_APBH_DMA) += apbh_dma.o
 obj-$(CONFIG_FSL_DMA) += fsl_dma.o
+obj-$(CONFIG_TI_KSNAV) += keystone_nav.o keystone_nav_cfg.o
+obj-$(CONFIG_TI_EDMA3) += ti-edma3.o
similarity index 53%
rename from arch/arm/cpu/armv7/keystone/keystone_nav.c
rename to drivers/dma/keystone_nav.c
index 39d6f995f7bd9c7cd700504bb32b102758c8e80c..77707c21098f45ca1c33d42470416717f8851f62 100644 (file)
@@ -8,28 +8,23 @@
  */
 #include <common.h>
 #include <asm/io.h>
-#include <asm/arch/keystone_nav.h>
-
-static int soc_type =
-#ifdef CONFIG_SOC_K2HK
-       k2hk;
-#endif
-
-struct qm_config k2hk_qm_memmap = {
-       .stat_cfg       = 0x02a40000,
-       .queue          = (struct qm_reg_queue *)0x02a80000,
-       .mngr_vbusm     = 0x23a80000,
-       .i_lram         = 0x00100000,
-       .proxy          = (struct qm_reg_queue *)0x02ac0000,
-       .status_ram     = 0x02a06000,
-       .mngr_cfg       = (struct qm_cfg_reg *)0x02a02000,
-       .intd_cfg       = 0x02a0c000,
-       .desc_mem       = (struct descr_mem_setup_reg *)0x02a03000,
-       .region_num     = 64,
-       .pdsp_cmd       = 0x02a20000,
-       .pdsp_ctl       = 0x02a0f000,
-       .pdsp_iram      = 0x02a10000,
-       .qpool_num      = 4000,
+#include <asm/ti-common/keystone_nav.h>
+
+struct qm_config qm_memmap = {
+       .stat_cfg       = CONFIG_KSNAV_QM_QUEUE_STATUS_BASE,
+       .queue          = (void *)CONFIG_KSNAV_QM_MANAGER_QUEUES_BASE,
+       .mngr_vbusm     = CONFIG_KSNAV_QM_BASE_ADDRESS,
+       .i_lram         = CONFIG_KSNAV_QM_LINK_RAM_BASE,
+       .proxy          = (void *)CONFIG_KSNAV_QM_MANAGER_Q_PROXY_BASE,
+       .status_ram     = CONFIG_KSNAV_QM_STATUS_RAM_BASE,
+       .mngr_cfg       = (void *)CONFIG_KSNAV_QM_CONF_BASE,
+       .intd_cfg       = CONFIG_KSNAV_QM_INTD_CONF_BASE,
+       .desc_mem       = (void *)CONFIG_KSNAV_QM_DESC_SETUP_BASE,
+       .region_num     = CONFIG_KSNAV_QM_REGION_NUM,
+       .pdsp_cmd       = CONFIG_KSNAV_QM_PDSP1_CMD_BASE,
+       .pdsp_ctl       = CONFIG_KSNAV_QM_PDSP1_CTRL_BASE,
+       .pdsp_iram      = CONFIG_KSNAV_QM_PDSP1_IRAM_BASE,
+       .qpool_num      = CONFIG_KSNAV_QM_QPOOL_NUM,
 };
 
 /*
@@ -52,12 +47,9 @@ inline int num_of_desc_to_reg(int num_descr)
        return 15;
 }
 
-static int _qm_init(struct qm_config *cfg)
+int _qm_init(struct qm_config *cfg)
 {
-       u32     j;
-
-       if (cfg == NULL)
-               return QM_ERR;
+       u32 j;
 
        qm_cfg = cfg;
 
@@ -82,12 +74,7 @@ static int _qm_init(struct qm_config *cfg)
 
 int qm_init(void)
 {
-       switch (soc_type) {
-       case k2hk:
-               return _qm_init(&k2hk_qm_memmap);
-       }
-
-       return QM_ERR;
+       return _qm_init(&qm_memmap);
 }
 
 void qm_close(void)
@@ -166,39 +153,23 @@ void queue_close(u32 qnum)
                ;
 }
 
-/*
+/**
  * DMA API
  */
 
-struct pktdma_cfg k2hk_netcp_pktdma = {
-       .global         = (struct global_ctl_regs *)0x02004000,
-       .tx_ch          = (struct tx_chan_regs *)0x02004400,
-       .tx_ch_num      = 9,
-       .rx_ch          = (struct rx_chan_regs *)0x02004800,
-       .rx_ch_num      = 26,
-       .tx_sched       = (u32 *)0x02004c00,
-       .rx_flows       = (struct rx_flow_regs *)0x02005000,
-       .rx_flow_num    = 32,
-       .rx_free_q      = 4001,
-       .rx_rcv_q       = 4002,
-       .tx_snd_q       = 648,
-};
-
-struct pktdma_cfg *netcp;
-
-static int netcp_rx_disable(void)
+static int ksnav_rx_disable(struct pktdma_cfg *pktdma)
 {
        u32 j, v, k;
 
-       for (j = 0; j < netcp->rx_ch_num; j++) {
-               v = readl(&netcp->rx_ch[j].cfg_a);
+       for (j = 0; j < pktdma->rx_ch_num; j++) {
+               v = readl(&pktdma->rx_ch[j].cfg_a);
                if (!(v & CPDMA_CHAN_A_ENABLE))
                        continue;
 
-               writel(v | CPDMA_CHAN_A_TDOWN, &netcp->rx_ch[j].cfg_a);
+               writel(v | CPDMA_CHAN_A_TDOWN, &pktdma->rx_ch[j].cfg_a);
                for (k = 0; k < TDOWN_TIMEOUT_COUNT; k++) {
                        udelay(100);
-                       v = readl(&netcp->rx_ch[j].cfg_a);
+                       v = readl(&pktdma->rx_ch[j].cfg_a);
                        if (!(v & CPDMA_CHAN_A_ENABLE))
                                continue;
                }
@@ -206,33 +177,33 @@ static int netcp_rx_disable(void)
        }
 
        /* Clear all of the flow registers */
-       for (j = 0; j < netcp->rx_flow_num; j++) {
-               writel(0, &netcp->rx_flows[j].control);
-               writel(0, &netcp->rx_flows[j].tags);
-               writel(0, &netcp->rx_flows[j].tag_sel);
-               writel(0, &netcp->rx_flows[j].fdq_sel[0]);
-               writel(0, &netcp->rx_flows[j].fdq_sel[1]);
-               writel(0, &netcp->rx_flows[j].thresh[0]);
-               writel(0, &netcp->rx_flows[j].thresh[1]);
-               writel(0, &netcp->rx_flows[j].thresh[2]);
+       for (j = 0; j < pktdma->rx_flow_num; j++) {
+               writel(0, &pktdma->rx_flows[j].control);
+               writel(0, &pktdma->rx_flows[j].tags);
+               writel(0, &pktdma->rx_flows[j].tag_sel);
+               writel(0, &pktdma->rx_flows[j].fdq_sel[0]);
+               writel(0, &pktdma->rx_flows[j].fdq_sel[1]);
+               writel(0, &pktdma->rx_flows[j].thresh[0]);
+               writel(0, &pktdma->rx_flows[j].thresh[1]);
+               writel(0, &pktdma->rx_flows[j].thresh[2]);
        }
 
        return QM_OK;
 }
 
-static int netcp_tx_disable(void)
+static int ksnav_tx_disable(struct pktdma_cfg *pktdma)
 {
        u32 j, v, k;
 
-       for (j = 0; j < netcp->tx_ch_num; j++) {
-               v = readl(&netcp->tx_ch[j].cfg_a);
+       for (j = 0; j < pktdma->tx_ch_num; j++) {
+               v = readl(&pktdma->tx_ch[j].cfg_a);
                if (!(v & CPDMA_CHAN_A_ENABLE))
                        continue;
 
-               writel(v | CPDMA_CHAN_A_TDOWN, &netcp->tx_ch[j].cfg_a);
+               writel(v | CPDMA_CHAN_A_TDOWN, &pktdma->tx_ch[j].cfg_a);
                for (k = 0; k < TDOWN_TIMEOUT_COUNT; k++) {
                        udelay(100);
-                       v = readl(&netcp->tx_ch[j].cfg_a);
+                       v = readl(&pktdma->tx_ch[j].cfg_a);
                        if (!(v & CPDMA_CHAN_A_ENABLE))
                                continue;
                }
@@ -242,19 +213,17 @@ static int netcp_tx_disable(void)
        return QM_OK;
 }
 
-static int _netcp_init(struct pktdma_cfg *netcp_cfg,
-                      struct rx_buff_desc *rx_buffers)
+int ksnav_init(struct pktdma_cfg *pktdma, struct rx_buff_desc *rx_buffers)
 {
        u32 j, v;
        struct qm_host_desc *hd;
        u8 *rx_ptr;
 
-       if (netcp_cfg == NULL || rx_buffers == NULL ||
+       if (pktdma == NULL || rx_buffers == NULL ||
            rx_buffers->buff_ptr == NULL || qm_cfg == NULL)
                return QM_ERR;
 
-       netcp = netcp_cfg;
-       netcp->rx_flow = rx_buffers->rx_flow;
+       pktdma->rx_flow = rx_buffers->rx_flow;
 
        /* init rx queue */
        rx_ptr = rx_buffers->buff_ptr;
@@ -264,77 +233,64 @@ static int _netcp_init(struct pktdma_cfg *netcp_cfg,
                if (hd == NULL)
                        return QM_ERR;
 
-               qm_buff_push(hd, netcp->rx_free_q,
+               qm_buff_push(hd, pktdma->rx_free_q,
                             rx_ptr, rx_buffers->buff_len);
 
                rx_ptr += rx_buffers->buff_len;
        }
 
-       netcp_rx_disable();
+       ksnav_rx_disable(pktdma);
 
        /* configure rx channels */
-       v = CPDMA_REG_VAL_MAKE_RX_FLOW_A(1, 1, 0, 0, 0, 0, 0, netcp->rx_rcv_q);
-       writel(v, &netcp->rx_flows[netcp->rx_flow].control);
-       writel(0, &netcp->rx_flows[netcp->rx_flow].tags);
-       writel(0, &netcp->rx_flows[netcp->rx_flow].tag_sel);
+       v = CPDMA_REG_VAL_MAKE_RX_FLOW_A(1, 1, 0, 0, 0, 0, 0, pktdma->rx_rcv_q);
+       writel(v, &pktdma->rx_flows[pktdma->rx_flow].control);
+       writel(0, &pktdma->rx_flows[pktdma->rx_flow].tags);
+       writel(0, &pktdma->rx_flows[pktdma->rx_flow].tag_sel);
 
-       v = CPDMA_REG_VAL_MAKE_RX_FLOW_D(0, netcp->rx_free_q, 0,
-                                        netcp->rx_free_q);
+       v = CPDMA_REG_VAL_MAKE_RX_FLOW_D(0, pktdma->rx_free_q, 0,
+                                        pktdma->rx_free_q);
 
-       writel(v, &netcp->rx_flows[netcp->rx_flow].fdq_sel[0]);
-       writel(v, &netcp->rx_flows[netcp->rx_flow].fdq_sel[1]);
-       writel(0, &netcp->rx_flows[netcp->rx_flow].thresh[0]);
-       writel(0, &netcp->rx_flows[netcp->rx_flow].thresh[1]);
-       writel(0, &netcp->rx_flows[netcp->rx_flow].thresh[2]);
+       writel(v, &pktdma->rx_flows[pktdma->rx_flow].fdq_sel[0]);
+       writel(v, &pktdma->rx_flows[pktdma->rx_flow].fdq_sel[1]);
+       writel(0, &pktdma->rx_flows[pktdma->rx_flow].thresh[0]);
+       writel(0, &pktdma->rx_flows[pktdma->rx_flow].thresh[1]);
+       writel(0, &pktdma->rx_flows[pktdma->rx_flow].thresh[2]);
 
-       for (j = 0; j < netcp->rx_ch_num; j++)
-               writel(CPDMA_CHAN_A_ENABLE, &netcp->rx_ch[j].cfg_a);
+       for (j = 0; j < pktdma->rx_ch_num; j++)
+               writel(CPDMA_CHAN_A_ENABLE, &pktdma->rx_ch[j].cfg_a);
 
        /* configure tx channels */
        /* Disable loopback in the tx direction */
-       writel(0, &netcp->global->emulation_control);
+       writel(0, &pktdma->global->emulation_control);
 
-/* TODO: make it dependend on a soc type variable */
-#ifdef CONFIG_SOC_K2HK
        /* Set QM base address, only for K2x devices */
-       writel(0x23a80000, &netcp->global->qm_base_addr[0]);
-#endif
+       writel(CONFIG_KSNAV_QM_BASE_ADDRESS, &pktdma->global->qm_base_addr[0]);
 
        /* Enable all channels. The current state isn't important */
-       for (j = 0; j < netcp->tx_ch_num; j++)  {
-               writel(0, &netcp->tx_ch[j].cfg_b);
-               writel(CPDMA_CHAN_A_ENABLE, &netcp->tx_ch[j].cfg_a);
+       for (j = 0; j < pktdma->tx_ch_num; j++)  {
+               writel(0, &pktdma->tx_ch[j].cfg_b);
+               writel(CPDMA_CHAN_A_ENABLE, &pktdma->tx_ch[j].cfg_a);
        }
 
        return QM_OK;
 }
 
-int netcp_init(struct rx_buff_desc *rx_buffers)
-{
-       switch (soc_type) {
-       case k2hk:
-               _netcp_init(&k2hk_netcp_pktdma, rx_buffers);
-               return QM_OK;
-       }
-       return QM_ERR;
-}
-
-int netcp_close(void)
+int ksnav_close(struct pktdma_cfg *pktdma)
 {
-       if (!netcp)
+       if (!pktdma)
                return QM_ERR;
 
-       netcp_tx_disable();
-       netcp_rx_disable();
+       ksnav_tx_disable(pktdma);
+       ksnav_rx_disable(pktdma);
 
-       queue_close(netcp->rx_free_q);
-       queue_close(netcp->rx_rcv_q);
-       queue_close(netcp->tx_snd_q);
+       queue_close(pktdma->rx_free_q);
+       queue_close(pktdma->rx_rcv_q);
+       queue_close(pktdma->tx_snd_q);
 
        return QM_OK;
 }
 
-int netcp_send(u32 *pkt, int num_bytes, u32 swinfo2)
+int ksnav_send(struct pktdma_cfg *pktdma, u32 *pkt, int num_bytes, u32 swinfo2)
 {
        struct qm_host_desc *hd;
 
@@ -346,16 +302,16 @@ int netcp_send(u32 *pkt, int num_bytes, u32 swinfo2)
        hd->swinfo[2]   = swinfo2;
        hd->packet_info = qm_cfg->qpool_num;
 
-       qm_buff_push(hd, netcp->tx_snd_q, pkt, num_bytes);
+       qm_buff_push(hd, pktdma->tx_snd_q, pkt, num_bytes);
 
        return QM_OK;
 }
 
-void *netcp_recv(u32 **pkt, int *num_bytes)
+void *ksnav_recv(struct pktdma_cfg *pktdma, u32 **pkt, int *num_bytes)
 {
        struct qm_host_desc *hd;
 
-       hd = qm_pop(netcp->rx_rcv_q);
+       hd = qm_pop(pktdma->rx_rcv_q);
        if (!hd)
                return NULL;
 
@@ -365,12 +321,12 @@ void *netcp_recv(u32 **pkt, int *num_bytes)
        return hd;
 }
 
-void netcp_release_rxhd(void *hd)
+void ksnav_release_rxhd(struct pktdma_cfg *pktdma, void *hd)
 {
        struct qm_host_desc *_hd = (struct qm_host_desc *)hd;
 
        _hd->buff_len = _hd->orig_buff_len;
        _hd->buff_ptr = _hd->orig_buff_ptr;
 
-       qm_push(_hd, netcp->rx_free_q);
+       qm_push(_hd, pktdma->rx_free_q);
 }
diff --git a/drivers/dma/keystone_nav_cfg.c b/drivers/dma/keystone_nav_cfg.c
new file mode 100644 (file)
index 0000000..bdd30a0
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Multicore Navigator driver for TI Keystone 2 devices.
+ *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <asm/ti-common/keystone_nav.h>
+
+#ifdef CONFIG_KSNAV_PKTDMA_NETCP
+/* NETCP Pktdma */
+struct pktdma_cfg netcp_pktdma = {
+       .global         = (void *)CONFIG_KSNAV_NETCP_PDMA_CTRL_BASE,
+       .tx_ch          = (void *)CONFIG_KSNAV_NETCP_PDMA_TX_BASE,
+       .tx_ch_num      = CONFIG_KSNAV_NETCP_PDMA_TX_CH_NUM,
+       .rx_ch          = (void *)CONFIG_KSNAV_NETCP_PDMA_RX_BASE,
+       .rx_ch_num      = CONFIG_KSNAV_NETCP_PDMA_RX_CH_NUM,
+       .tx_sched       = (u32 *)CONFIG_KSNAV_NETCP_PDMA_SCHED_BASE,
+       .rx_flows       = (void *)CONFIG_KSNAV_NETCP_PDMA_RX_FLOW_BASE,
+       .rx_flow_num    = CONFIG_KSNAV_NETCP_PDMA_RX_FLOW_NUM,
+       .rx_free_q      = CONFIG_KSNAV_NETCP_PDMA_RX_FREE_QUEUE,
+       .rx_rcv_q       = CONFIG_KSNAV_NETCP_PDMA_RX_RCV_QUEUE,
+       .tx_snd_q       = CONFIG_KSNAV_NETCP_PDMA_TX_SND_QUEUE,
+};
+#endif
diff --git a/drivers/dma/ti-edma3.c b/drivers/dma/ti-edma3.c
new file mode 100644 (file)
index 0000000..8184ded
--- /dev/null
@@ -0,0 +1,384 @@
+/*
+ * Enhanced Direct Memory Access (EDMA3) Controller
+ *
+ * (C) Copyright 2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * Author: Ivan Khoronzhuk <ivan.khoronzhuk@ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <asm/io.h>
+#include <common.h>
+#include <asm/ti-common/ti-edma3.h>
+
+#define EDMA3_SL_BASE(slot)                    (0x4000 + ((slot) << 5))
+#define EDMA3_SL_MAX_NUM                       512
+#define EDMA3_SLOPT_FIFO_WIDTH_MASK            (0x7 << 8)
+
+#define EDMA3_QCHMAP(ch)                       0x0200 + ((ch) << 2)
+#define EDMA3_CHMAP_PARSET_MASK                        0x1ff
+#define EDMA3_CHMAP_PARSET_SHIFT               0x5
+#define EDMA3_CHMAP_TRIGWORD_SHIFT             0x2
+
+#define EDMA3_QEMCR                            0x314
+#define EDMA3_IPR                              0x1068
+#define EDMA3_IPRH                             0x106c
+#define EDMA3_ICR                              0x1070
+#define EDMA3_ICRH                             0x1074
+#define EDMA3_QEECR                            0x1088
+#define EDMA3_QEESR                            0x108c
+#define EDMA3_QSECR                            0x1094
+
+/**
+ * qedma3_start - start qdma on a channel
+ * @base: base address of edma
+ * @cfg: pinter to struct edma3_channel_config where you can set
+ * the slot number to associate with, the chnum, which corresponds
+ * your quick channel number 0-7, complete code - transfer complete code
+ * and trigger slot word - which has to correspond to the word number in
+ * edma3_slot_layout struct for generating event.
+ *
+ */
+void qedma3_start(u32 base, struct edma3_channel_config *cfg)
+{
+       u32 qchmap;
+
+       /* Clear the pending int bit */
+       if (cfg->complete_code < 32)
+               __raw_writel(1 << cfg->complete_code, base + EDMA3_ICR);
+       else
+               __raw_writel(1 << cfg->complete_code, base + EDMA3_ICRH);
+
+       /* Map parameter set and trigger word 7 to quick channel */
+       qchmap = ((EDMA3_CHMAP_PARSET_MASK & cfg->slot)
+                 << EDMA3_CHMAP_PARSET_SHIFT) |
+                 (cfg->trigger_slot_word << EDMA3_CHMAP_TRIGWORD_SHIFT);
+
+       __raw_writel(qchmap, base + EDMA3_QCHMAP(cfg->chnum));
+
+       /* Clear missed event if set*/
+       __raw_writel(1 << cfg->chnum, base + EDMA3_QSECR);
+       __raw_writel(1 << cfg->chnum, base + EDMA3_QEMCR);
+
+       /* Enable qdma channel event */
+       __raw_writel(1 << cfg->chnum, base + EDMA3_QEESR);
+}
+
+/**
+ * edma3_set_dest - set initial DMA destination address in parameter RAM slot
+ * @base: base address of edma
+ * @slot: parameter RAM slot being configured
+ * @dst: physical address of destination (memory, controller FIFO, etc)
+ * @addressMode: INCR, except in very rare cases
+ * @width: ignored unless @addressMode is FIFO, else specifies the
+ *     width to use when addressing the fifo (e.g. W8BIT, W32BIT)
+ *
+ * Note that the destination address is modified during the DMA transfer
+ * according to edma3_set_dest_index().
+ */
+void edma3_set_dest(u32 base, int slot, u32 dst, enum edma3_address_mode mode,
+                   enum edma3_fifo_width width)
+{
+       u32 opt;
+       struct edma3_slot_layout *rg;
+
+       rg = (struct edma3_slot_layout *)(base + EDMA3_SL_BASE(slot));
+
+       opt = __raw_readl(&rg->opt);
+       if (mode == FIFO)
+               opt = (opt & EDMA3_SLOPT_FIFO_WIDTH_MASK) |
+                      (EDMA3_SLOPT_DST_ADDR_CONST_MODE |
+                       EDMA3_SLOPT_FIFO_WIDTH_SET(width));
+       else
+               opt &= ~EDMA3_SLOPT_DST_ADDR_CONST_MODE;
+
+       __raw_writel(opt, &rg->opt);
+       __raw_writel(dst, &rg->dst);
+}
+
+/**
+ * edma3_set_dest_index - configure DMA destination address indexing
+ * @base: base address of edma
+ * @slot: parameter RAM slot being configured
+ * @bidx: byte offset between destination arrays in a frame
+ * @cidx: byte offset between destination frames in a block
+ *
+ * Offsets are specified to support either contiguous or discontiguous
+ * memory transfers, or repeated access to a hardware register, as needed.
+ * When accessing hardware registers, both offsets are normally zero.
+ */
+void edma3_set_dest_index(u32 base, unsigned slot, int bidx, int cidx)
+{
+       u32 src_dst_bidx;
+       u32 src_dst_cidx;
+       struct edma3_slot_layout *rg;
+
+       rg = (struct edma3_slot_layout *)(base + EDMA3_SL_BASE(slot));
+
+       src_dst_bidx = __raw_readl(&rg->src_dst_bidx);
+       src_dst_cidx = __raw_readl(&rg->src_dst_cidx);
+
+       __raw_writel((src_dst_bidx & 0x0000ffff) | (bidx << 16),
+                    &rg->src_dst_bidx);
+       __raw_writel((src_dst_cidx & 0x0000ffff) | (cidx << 16),
+                    &rg->src_dst_cidx);
+}
+
+/**
+ * edma3_set_dest_addr - set destination address for slot only
+ */
+void edma3_set_dest_addr(u32 base, int slot, u32 dst)
+{
+       struct edma3_slot_layout *rg;
+
+       rg = (struct edma3_slot_layout *)(base + EDMA3_SL_BASE(slot));
+       __raw_writel(dst, &rg->dst);
+}
+
+/**
+ * edma3_set_src - set initial DMA source address in parameter RAM slot
+ * @base: base address of edma
+ * @slot: parameter RAM slot being configured
+ * @src_port: physical address of source (memory, controller FIFO, etc)
+ * @mode: INCR, except in very rare cases
+ * @width: ignored unless @addressMode is FIFO, else specifies the
+ *     width to use when addressing the fifo (e.g. W8BIT, W32BIT)
+ *
+ * Note that the source address is modified during the DMA transfer
+ * according to edma3_set_src_index().
+ */
+void edma3_set_src(u32 base, int slot, u32 src, enum edma3_address_mode mode,
+                  enum edma3_fifo_width width)
+{
+       u32 opt;
+       struct edma3_slot_layout *rg;
+
+       rg = (struct edma3_slot_layout *)(base + EDMA3_SL_BASE(slot));
+
+       opt = __raw_readl(&rg->opt);
+       if (mode == FIFO)
+               opt = (opt & EDMA3_SLOPT_FIFO_WIDTH_MASK) |
+                      (EDMA3_SLOPT_DST_ADDR_CONST_MODE |
+                       EDMA3_SLOPT_FIFO_WIDTH_SET(width));
+       else
+               opt &= ~EDMA3_SLOPT_DST_ADDR_CONST_MODE;
+
+       __raw_writel(opt, &rg->opt);
+       __raw_writel(src, &rg->src);
+}
+
+/**
+ * edma3_set_src_index - configure DMA source address indexing
+ * @base: base address of edma
+ * @slot: parameter RAM slot being configured
+ * @bidx: byte offset between source arrays in a frame
+ * @cidx: byte offset between source frames in a block
+ *
+ * Offsets are specified to support either contiguous or discontiguous
+ * memory transfers, or repeated access to a hardware register, as needed.
+ * When accessing hardware registers, both offsets are normally zero.
+ */
+void edma3_set_src_index(u32 base, unsigned slot, int bidx, int cidx)
+{
+       u32 src_dst_bidx;
+       u32 src_dst_cidx;
+       struct edma3_slot_layout *rg;
+
+       rg = (struct edma3_slot_layout *)(base + EDMA3_SL_BASE(slot));
+
+       src_dst_bidx = __raw_readl(&rg->src_dst_bidx);
+       src_dst_cidx = __raw_readl(&rg->src_dst_cidx);
+
+       __raw_writel((src_dst_bidx & 0xffff0000) | bidx,
+                    &rg->src_dst_bidx);
+       __raw_writel((src_dst_cidx & 0xffff0000) | cidx,
+                    &rg->src_dst_cidx);
+}
+
+/**
+ * edma3_set_src_addr - set source address for slot only
+ */
+void edma3_set_src_addr(u32 base, int slot, u32 src)
+{
+       struct edma3_slot_layout *rg;
+
+       rg = (struct edma3_slot_layout *)(base + EDMA3_SL_BASE(slot));
+       __raw_writel(src, &rg->src);
+}
+
+/**
+ * edma3_set_transfer_params - configure DMA transfer parameters
+ * @base: base address of edma
+ * @slot: parameter RAM slot being configured
+ * @acnt: how many bytes per array (at least one)
+ * @bcnt: how many arrays per frame (at least one)
+ * @ccnt: how many frames per block (at least one)
+ * @bcnt_rld: used only for A-Synchronized transfers; this specifies
+ *     the value to reload into bcnt when it decrements to zero
+ * @sync_mode: ASYNC or ABSYNC
+ *
+ * See the EDMA3 documentation to understand how to configure and link
+ * transfers using the fields in PaRAM slots.  If you are not doing it
+ * all at once with edma3_write_slot(), you will use this routine
+ * plus two calls each for source and destination, setting the initial
+ * address and saying how to index that address.
+ *
+ * An example of an A-Synchronized transfer is a serial link using a
+ * single word shift register.  In that case, @acnt would be equal to
+ * that word size; the serial controller issues a DMA synchronization
+ * event to transfer each word, and memory access by the DMA transfer
+ * controller will be word-at-a-time.
+ *
+ * An example of an AB-Synchronized transfer is a device using a FIFO.
+ * In that case, @acnt equals the FIFO width and @bcnt equals its depth.
+ * The controller with the FIFO issues DMA synchronization events when
+ * the FIFO threshold is reached, and the DMA transfer controller will
+ * transfer one frame to (or from) the FIFO.  It will probably use
+ * efficient burst modes to access memory.
+ */
+void edma3_set_transfer_params(u32 base, int slot, int acnt,
+                              int bcnt, int ccnt, u16 bcnt_rld,
+                              enum edma3_sync_dimension sync_mode)
+{
+       u32 opt;
+       u32 link_bcntrld;
+       struct edma3_slot_layout *rg;
+
+       rg = (struct edma3_slot_layout *)(base + EDMA3_SL_BASE(slot));
+
+       link_bcntrld = __raw_readl(&rg->link_bcntrld);
+
+       __raw_writel((bcnt_rld << 16) | (0x0000ffff & link_bcntrld),
+                    &rg->link_bcntrld);
+
+       opt = __raw_readl(&rg->opt);
+       if (sync_mode == ASYNC)
+               __raw_writel(opt & ~EDMA3_SLOPT_AB_SYNC, &rg->opt);
+       else
+               __raw_writel(opt | EDMA3_SLOPT_AB_SYNC, &rg->opt);
+
+       /* Set the acount, bcount, ccount registers */
+       __raw_writel((bcnt << 16) | (acnt & 0xffff), &rg->a_b_cnt);
+       __raw_writel(0xffff & ccnt, &rg->ccnt);
+}
+
+/**
+ * edma3_write_slot - write parameter RAM data for slot
+ * @base: base address of edma
+ * @slot: number of parameter RAM slot being modified
+ * @param: data to be written into parameter RAM slot
+ *
+ * Use this to assign all parameters of a transfer at once.  This
+ * allows more efficient setup of transfers than issuing multiple
+ * calls to set up those parameters in small pieces, and provides
+ * complete control over all transfer options.
+ */
+void edma3_write_slot(u32 base, int slot, struct edma3_slot_layout *param)
+{
+       int i;
+       u32 *p = (u32 *)param;
+       u32 *addr = (u32 *)(base + EDMA3_SL_BASE(slot));
+
+       for (i = 0; i < sizeof(struct edma3_slot_layout)/4; i += 4)
+               __raw_writel(*p++, addr++);
+}
+
+/**
+ * edma3_read_slot - read parameter RAM data from slot
+ * @base: base address of edma
+ * @slot: number of parameter RAM slot being copied
+ * @param: where to store copy of parameter RAM data
+ *
+ * Use this to read data from a parameter RAM slot, perhaps to
+ * save them as a template for later reuse.
+ */
+void edma3_read_slot(u32 base, int slot, struct edma3_slot_layout *param)
+{
+       int i;
+       u32 *p = (u32 *)param;
+       u32 *addr = (u32 *)(base + EDMA3_SL_BASE(slot));
+
+       for (i = 0; i < sizeof(struct edma3_slot_layout)/4; i += 4)
+               *p++ = __raw_readl(addr++);
+}
+
+void edma3_slot_configure(u32 base, int slot, struct edma3_slot_config *cfg)
+{
+       struct edma3_slot_layout *rg;
+
+       rg = (struct edma3_slot_layout *)(base + EDMA3_SL_BASE(slot));
+
+       __raw_writel(cfg->opt, &rg->opt);
+       __raw_writel(cfg->src, &rg->src);
+       __raw_writel((cfg->bcnt << 16) | (cfg->acnt & 0xffff), &rg->a_b_cnt);
+       __raw_writel(cfg->dst, &rg->dst);
+       __raw_writel((cfg->dst_bidx << 16) |
+                    (cfg->src_bidx & 0xffff), &rg->src_dst_bidx);
+       __raw_writel((cfg->bcntrld << 16) |
+                    (cfg->link & 0xffff), &rg->link_bcntrld);
+       __raw_writel((cfg->dst_cidx << 16) |
+                    (cfg->src_cidx & 0xffff), &rg->src_dst_cidx);
+       __raw_writel(0xffff & cfg->ccnt, &rg->ccnt);
+}
+
+/**
+ * edma3_check_for_transfer - check if transfer coplete by checking
+ * interrupt pending bit. Clear interrupt pending bit if complete.
+ * @base: base address of edma
+ * @cfg: pinter to struct edma3_channel_config which was passed
+ * to qedma3_start when you started qdma channel
+ *
+ * Return 0 if complete, 1 if not.
+ */
+int edma3_check_for_transfer(u32 base, struct edma3_channel_config *cfg)
+{
+       u32 inum;
+       u32 ipr_base;
+       u32 icr_base;
+
+       if (cfg->complete_code < 32) {
+               ipr_base = base + EDMA3_IPR;
+               icr_base = base + EDMA3_ICR;
+               inum = 1 << cfg->complete_code;
+       } else {
+               ipr_base = base + EDMA3_IPRH;
+               icr_base = base + EDMA3_ICRH;
+               inum = 1 << (cfg->complete_code - 32);
+       }
+
+       /* check complete interrupt */
+       if (!(__raw_readl(ipr_base) & inum))
+               return 1;
+
+       /* clean up the pending int bit */
+       __raw_writel(inum, icr_base);
+
+       return 0;
+}
+
+/**
+ * qedma3_stop - stops dma on the channel passed
+ * @base: base address of edma
+ * @cfg: pinter to struct edma3_channel_config which was passed
+ * to qedma3_start when you started qdma channel
+ */
+void qedma3_stop(u32 base, struct edma3_channel_config *cfg)
+{
+       /* Disable qdma channel event */
+       __raw_writel(1 << cfg->chnum, base + EDMA3_QEECR);
+
+       /* clean up the interrupt indication */
+       if (cfg->complete_code < 32)
+               __raw_writel(1 << cfg->complete_code, base + EDMA3_ICR);
+       else
+               __raw_writel(1 << cfg->complete_code, base + EDMA3_ICRH);
+
+       /* Clear missed event if set*/
+       __raw_writel(1 << cfg->chnum, base + EDMA3_QSECR);
+       __raw_writel(1 << cfg->chnum, base + EDMA3_QEMCR);
+
+       /* Clear the channel map */
+       __raw_writel(0, base + EDMA3_QCHMAP(cfg->chnum));
+}
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..d21302f8da95316cdf7891556a73bb0de576b8e1 100644 (file)
@@ -0,0 +1,6 @@
+config DM_GPIO
+       bool "Enable Driver Model for GPIO drivers"
+       depends on DM
+       help
+         If you want to use driver model for GPIO drivers, say Y.
+         To use legacy GPIO drivers, say N.
index 97b51371145e81de9f268a33f001c72d6f63ff98..0244c01882863903596f76f153a11cbbaf98dc3e 100644 (file)
  */
 
 #include <common.h>
+#include <dm.h>
+#include <errno.h>
 #include <asm/gpio.h>
 #include <asm/io.h>
 
-inline int gpio_is_valid(unsigned gpio)
-{
-       return (gpio < BCM2835_GPIO_COUNT);
-}
-
-int gpio_request(unsigned gpio, const char *label)
-{
-       return !gpio_is_valid(gpio);
-}
+struct bcm2835_gpios {
+       struct bcm2835_gpio_regs *reg;
+};
 
-int gpio_free(unsigned gpio)
+static int bcm2835_gpio_direction_input(struct udevice *dev, unsigned gpio)
 {
-       return 0;
-}
-
-int gpio_direction_input(unsigned gpio)
-{
-       struct bcm2835_gpio_regs *reg =
-               (struct bcm2835_gpio_regs *)BCM2835_GPIO_BASE;
+       struct bcm2835_gpios *gpios = dev_get_priv(dev);
        unsigned val;
 
-       val = readl(&reg->gpfsel[BCM2835_GPIO_FSEL_BANK(gpio)]);
+       val = readl(&gpios->reg->gpfsel[BCM2835_GPIO_FSEL_BANK(gpio)]);
        val &= ~(BCM2835_GPIO_FSEL_MASK << BCM2835_GPIO_FSEL_SHIFT(gpio));
        val |= (BCM2835_GPIO_INPUT << BCM2835_GPIO_FSEL_SHIFT(gpio));
-       writel(val, &reg->gpfsel[BCM2835_GPIO_FSEL_BANK(gpio)]);
+       writel(val, &gpios->reg->gpfsel[BCM2835_GPIO_FSEL_BANK(gpio)]);
 
        return 0;
 }
 
-int gpio_direction_output(unsigned gpio, int value)
+static int bcm2835_gpio_direction_output(struct udevice *dev, unsigned gpio,
+                                        int value)
 {
-       struct bcm2835_gpio_regs *reg =
-               (struct bcm2835_gpio_regs *)BCM2835_GPIO_BASE;
+       struct bcm2835_gpios *gpios = dev_get_priv(dev);
        unsigned val;
 
        gpio_set_value(gpio, value);
 
-       val = readl(&reg->gpfsel[BCM2835_GPIO_FSEL_BANK(gpio)]);
+       val = readl(&gpios->reg->gpfsel[BCM2835_GPIO_FSEL_BANK(gpio)]);
        val &= ~(BCM2835_GPIO_FSEL_MASK << BCM2835_GPIO_FSEL_SHIFT(gpio));
        val |= (BCM2835_GPIO_OUTPUT << BCM2835_GPIO_FSEL_SHIFT(gpio));
-       writel(val, &reg->gpfsel[BCM2835_GPIO_FSEL_BANK(gpio)]);
+       writel(val, &gpios->reg->gpfsel[BCM2835_GPIO_FSEL_BANK(gpio)]);
 
        return 0;
 }
 
-int gpio_get_value(unsigned gpio)
+static bool bcm2835_gpio_is_output(const struct bcm2835_gpios *gpios, int gpio)
+{
+       u32 val;
+
+       val = readl(&gpios->reg->gpfsel[BCM2835_GPIO_FSEL_BANK(gpio)]);
+       val &= BCM2835_GPIO_FSEL_MASK << BCM2835_GPIO_FSEL_SHIFT(gpio);
+       return val ? true : false;
+}
+
+static int bcm2835_get_value(const struct bcm2835_gpios *gpios, unsigned gpio)
 {
-       struct bcm2835_gpio_regs *reg =
-               (struct bcm2835_gpio_regs *)BCM2835_GPIO_BASE;
        unsigned val;
 
-       val = readl(&reg->gplev[BCM2835_GPIO_COMMON_BANK(gpio)]);
+       val = readl(&gpios->reg->gplev[BCM2835_GPIO_COMMON_BANK(gpio)]);
 
        return (val >> BCM2835_GPIO_COMMON_SHIFT(gpio)) & 0x1;
 }
 
-int gpio_set_value(unsigned gpio, int value)
+static int bcm2835_gpio_get_value(struct udevice *dev, unsigned gpio)
+{
+       const struct bcm2835_gpios *gpios = dev_get_priv(dev);
+
+       return bcm2835_get_value(gpios, gpio);
+}
+
+static int bcm2835_gpio_set_value(struct udevice *dev, unsigned gpio,
+                                 int value)
 {
-       struct bcm2835_gpio_regs *reg =
-               (struct bcm2835_gpio_regs *)BCM2835_GPIO_BASE;
-       u32 *output_reg = value ? reg->gpset : reg->gpclr;
+       struct bcm2835_gpios *gpios = dev_get_priv(dev);
+       u32 *output_reg = value ? gpios->reg->gpset : gpios->reg->gpclr;
 
        writel(1 << BCM2835_GPIO_COMMON_SHIFT(gpio),
                                &output_reg[BCM2835_GPIO_COMMON_BANK(gpio)]);
 
        return 0;
 }
+
+static int bcm2835_gpio_get_function(struct udevice *dev, unsigned offset)
+{
+       struct bcm2835_gpios *gpios = dev_get_priv(dev);
+
+       /* GPIOF_FUNC is not implemented yet */
+       if (bcm2835_gpio_is_output(gpios, offset))
+               return GPIOF_OUTPUT;
+       else
+               return GPIOF_INPUT;
+}
+
+
+static const struct dm_gpio_ops gpio_bcm2835_ops = {
+       .direction_input        = bcm2835_gpio_direction_input,
+       .direction_output       = bcm2835_gpio_direction_output,
+       .get_value              = bcm2835_gpio_get_value,
+       .set_value              = bcm2835_gpio_set_value,
+       .get_function           = bcm2835_gpio_get_function,
+};
+
+static int bcm2835_gpio_probe(struct udevice *dev)
+{
+       struct bcm2835_gpios *gpios = dev_get_priv(dev);
+       struct bcm2835_gpio_platdata *plat = dev_get_platdata(dev);
+       struct gpio_dev_priv *uc_priv = dev->uclass_priv;
+
+       uc_priv->bank_name = "GPIO";
+       uc_priv->gpio_count = BCM2835_GPIO_COUNT;
+       gpios->reg = (struct bcm2835_gpio_regs *)plat->base;
+
+       return 0;
+}
+
+U_BOOT_DRIVER(gpio_bcm2835) = {
+       .name   = "gpio_bcm2835",
+       .id     = UCLASS_GPIO,
+       .ops    = &gpio_bcm2835_ops,
+       .probe  = bcm2835_gpio_probe,
+       .priv_auto_alloc_size = sizeof(struct bcm2835_gpios),
+};
index f1bbc587961709dec3922c52c76585227acecd9b..45e9a5ad2278378814b7351c5d70dd5c53fbf287 100644 (file)
@@ -7,7 +7,9 @@
 #include <common.h>
 #include <dm.h>
 #include <errno.h>
+#include <malloc.h>
 #include <asm/gpio.h>
+#include <linux/ctype.h>
 
 /**
  * gpio_to_device() - Convert global GPIO number to device, number
@@ -43,35 +45,47 @@ static int gpio_to_device(unsigned int gpio, struct udevice **devp,
 int gpio_lookup_name(const char *name, struct udevice **devp,
                     unsigned int *offsetp, unsigned int *gpiop)
 {
-       struct gpio_dev_priv *uc_priv;
+       struct gpio_dev_priv *uc_priv = NULL;
        struct udevice *dev;
+       ulong offset;
+       int numeric;
        int ret;
 
        if (devp)
                *devp = NULL;
+       numeric = isdigit(*name) ? simple_strtoul(name, NULL, 10) : -1;
        for (ret = uclass_first_device(UCLASS_GPIO, &dev);
             dev;
             ret = uclass_next_device(&dev)) {
-               ulong offset;
                int len;
 
                uc_priv = dev->uclass_priv;
+               if (numeric != -1) {
+                       offset = numeric - uc_priv->gpio_base;
+                       /* Allow GPIOs to be numbered from 0 */
+                       if (offset >= 0 && offset < uc_priv->gpio_count)
+                               break;
+               }
+
                len = uc_priv->bank_name ? strlen(uc_priv->bank_name) : 0;
 
                if (!strncasecmp(name, uc_priv->bank_name, len)) {
-                       if (strict_strtoul(name + len, 10, &offset))
-                               continue;
-                       if (devp)
-                               *devp = dev;
-                       if (offsetp)
-                               *offsetp = offset;
-                       if (gpiop)
-                               *gpiop = uc_priv->gpio_base + offset;
-                       return 0;
+                       if (!strict_strtoul(name + len, 10, &offset))
+                               break;
                }
        }
 
-       return ret ? ret : -EINVAL;
+       if (!dev)
+               return ret ? ret : -EINVAL;
+
+       if (devp)
+               *devp = dev;
+       if (offsetp)
+               *offsetp = offset;
+       if (gpiop)
+               *gpiop = uc_priv->gpio_base + offset;
+
+       return 0;
 }
 
 /**
@@ -79,24 +93,62 @@ int gpio_lookup_name(const char *name, struct udevice **devp,
  * gpio:       GPIO number
  * label:      Name for the requested GPIO
  *
+ * The label is copied and allocated so the caller does not need to keep
+ * the pointer around.
+ *
  * This function implements the API that's compatible with current
  * GPIO API used in U-Boot. The request is forwarded to particular
  * GPIO driver. Returns 0 on success, negative value on error.
  */
 int gpio_request(unsigned gpio, const char *label)
 {
+       struct gpio_dev_priv *uc_priv;
        unsigned int offset;
        struct udevice *dev;
+       char *str;
        int ret;
 
        ret = gpio_to_device(gpio, &dev, &offset);
        if (ret)
                return ret;
 
-       if (!gpio_get_ops(dev)->request)
-               return 0;
+       uc_priv = dev->uclass_priv;
+       if (uc_priv->name[offset])
+               return -EBUSY;
+       str = strdup(label);
+       if (!str)
+               return -ENOMEM;
+       if (gpio_get_ops(dev)->request) {
+               ret = gpio_get_ops(dev)->request(dev, offset, label);
+               if (ret) {
+                       free(str);
+                       return ret;
+               }
+       }
+       uc_priv->name[offset] = str;
+
+       return 0;
+}
+
+/**
+ * gpio_requestf() - [COMPAT] Request GPIO
+ * @gpio:      GPIO number
+ * @fmt:       Format string for the requested GPIO
+ * @...:       Arguments for the printf() format string
+ *
+ * This function implements the API that's compatible with current
+ * GPIO API used in U-Boot. The request is forwarded to particular
+ * GPIO driver. Returns 0 on success, negative value on error.
+ */
+int gpio_requestf(unsigned gpio, const char *fmt, ...)
+{
+       va_list args;
+       char buf[40];
 
-       return gpio_get_ops(dev)->request(dev, offset, label);
+       va_start(args, fmt);
+       vscnprintf(buf, sizeof(buf), fmt, args);
+       va_end(args);
+       return gpio_request(gpio, buf);
 }
 
 /**
@@ -109,6 +161,7 @@ int gpio_request(unsigned gpio, const char *label)
  */
 int gpio_free(unsigned gpio)
 {
+       struct gpio_dev_priv *uc_priv;
        unsigned int offset;
        struct udevice *dev;
        int ret;
@@ -117,9 +170,34 @@ int gpio_free(unsigned gpio)
        if (ret)
                return ret;
 
-       if (!gpio_get_ops(dev)->free)
-               return 0;
-       return gpio_get_ops(dev)->free(dev, offset);
+       uc_priv = dev->uclass_priv;
+       if (!uc_priv->name[offset])
+               return -ENXIO;
+       if (gpio_get_ops(dev)->free) {
+               ret = gpio_get_ops(dev)->free(dev, offset);
+               if (ret)
+                       return ret;
+       }
+
+       free(uc_priv->name[offset]);
+       uc_priv->name[offset] = NULL;
+
+       return 0;
+}
+
+static int check_reserved(struct udevice *dev, unsigned offset,
+                         const char *func)
+{
+       struct gpio_dev_priv *uc_priv = dev->uclass_priv;
+
+       if (!uc_priv->name[offset]) {
+               printf("%s: %s: error: gpio %s%d not reserved\n",
+                      dev->name, func,
+                      uc_priv->bank_name ? uc_priv->bank_name : "", offset);
+               return -EBUSY;
+       }
+
+       return 0;
 }
 
 /**
@@ -139,8 +217,9 @@ int gpio_direction_input(unsigned gpio)
        ret = gpio_to_device(gpio, &dev, &offset);
        if (ret)
                return ret;
+       ret = check_reserved(dev, offset, "dir_input");
 
-       return gpio_get_ops(dev)->direction_input(dev, offset);
+       return ret ? ret : gpio_get_ops(dev)->direction_input(dev, offset);
 }
 
 /**
@@ -161,8 +240,10 @@ int gpio_direction_output(unsigned gpio, int value)
        ret = gpio_to_device(gpio, &dev, &offset);
        if (ret)
                return ret;
+       ret = check_reserved(dev, offset, "dir_output");
 
-       return gpio_get_ops(dev)->direction_output(dev, offset, value);
+       return ret ? ret :
+               gpio_get_ops(dev)->direction_output(dev, offset, value);
 }
 
 /**
@@ -183,8 +264,9 @@ int gpio_get_value(unsigned gpio)
        ret = gpio_to_device(gpio, &dev, &offset);
        if (ret)
                return ret;
+       ret = check_reserved(dev, offset, "get_value");
 
-       return gpio_get_ops(dev)->get_value(dev, offset);
+       return ret ? ret : gpio_get_ops(dev)->get_value(dev, offset);
 }
 
 /**
@@ -205,8 +287,9 @@ int gpio_set_value(unsigned gpio, int value)
        ret = gpio_to_device(gpio, &dev, &offset);
        if (ret)
                return ret;
+       ret = check_reserved(dev, offset, "set_value");
 
-       return gpio_get_ops(dev)->set_value(dev, offset, value);
+       return ret ? ret : gpio_get_ops(dev)->set_value(dev, offset, value);
 }
 
 const char *gpio_get_bank_info(struct udevice *dev, int *bit_count)
@@ -221,8 +304,94 @@ const char *gpio_get_bank_info(struct udevice *dev, int *bit_count)
        return priv->bank_name;
 }
 
+static const char * const gpio_function[GPIOF_COUNT] = {
+       "input",
+       "output",
+       "unused",
+       "unknown",
+       "func",
+};
+
+int get_function(struct udevice *dev, int offset, bool skip_unused,
+                const char **namep)
+{
+       struct gpio_dev_priv *uc_priv = dev->uclass_priv;
+       struct dm_gpio_ops *ops = gpio_get_ops(dev);
+
+       BUILD_BUG_ON(GPIOF_COUNT != ARRAY_SIZE(gpio_function));
+       if (!device_active(dev))
+               return -ENODEV;
+       if (offset < 0 || offset >= uc_priv->gpio_count)
+               return -EINVAL;
+       if (namep)
+               *namep = uc_priv->name[offset];
+       if (skip_unused && !uc_priv->name[offset])
+               return GPIOF_UNUSED;
+       if (ops->get_function) {
+               int ret;
+
+               ret = ops->get_function(dev, offset);
+               if (ret < 0)
+                       return ret;
+               if (ret >= ARRAY_SIZE(gpio_function))
+                       return -ENODATA;
+               return ret;
+       }
+
+       return GPIOF_UNKNOWN;
+}
+
+int gpio_get_function(struct udevice *dev, int offset, const char **namep)
+{
+       return get_function(dev, offset, true, namep);
+}
+
+int gpio_get_raw_function(struct udevice *dev, int offset, const char **namep)
+{
+       return get_function(dev, offset, false, namep);
+}
+
+int gpio_get_status(struct udevice *dev, int offset, char *buf, int buffsize)
+{
+       struct dm_gpio_ops *ops = gpio_get_ops(dev);
+       struct gpio_dev_priv *priv;
+       char *str = buf;
+       int func;
+       int ret;
+       int len;
+
+       BUILD_BUG_ON(GPIOF_COUNT != ARRAY_SIZE(gpio_function));
+
+       *buf = 0;
+       priv = dev->uclass_priv;
+       ret = gpio_get_raw_function(dev, offset, NULL);
+       if (ret < 0)
+               return ret;
+       func = ret;
+       len = snprintf(str, buffsize, "%s%d: %s",
+                      priv->bank_name ? priv->bank_name : "",
+                      offset, gpio_function[func]);
+       if (func == GPIOF_INPUT || func == GPIOF_OUTPUT ||
+           func == GPIOF_UNUSED) {
+               const char *label;
+               bool used;
+
+               ret = ops->get_value(dev, offset);
+               if (ret < 0)
+                       return ret;
+               used = gpio_get_function(dev, offset, &label) != GPIOF_UNUSED;
+               snprintf(str + len, buffsize - len, ": %d [%c]%s%s",
+                        ret,
+                        used ? 'x' : ' ',
+                        used ? " " : "",
+                        label ? label : "");
+       }
+
+       return 0;
+}
+
 /* We need to renumber the GPIOs when any driver is probed/removed */
-static int gpio_renumber(void)
+static int gpio_renumber(struct udevice *removed_dev)
 {
        struct gpio_dev_priv *uc_priv;
        struct udevice *dev;
@@ -237,7 +406,7 @@ static int gpio_renumber(void)
        /* Ensure that we have a base for each bank */
        base = 0;
        uclass_foreach_dev(dev, uc) {
-               if (device_active(dev)) {
+               if (device_active(dev) && dev != removed_dev) {
                        uc_priv = dev->uclass_priv;
                        uc_priv->gpio_base = base;
                        base += uc_priv->gpio_count;
@@ -249,12 +418,27 @@ static int gpio_renumber(void)
 
 static int gpio_post_probe(struct udevice *dev)
 {
-       return gpio_renumber();
+       struct gpio_dev_priv *uc_priv = dev->uclass_priv;
+
+       uc_priv->name = calloc(uc_priv->gpio_count, sizeof(char *));
+       if (!uc_priv->name)
+               return -ENOMEM;
+
+       return gpio_renumber(NULL);
 }
 
 static int gpio_pre_remove(struct udevice *dev)
 {
-       return gpio_renumber();
+       struct gpio_dev_priv *uc_priv = dev->uclass_priv;
+       int i;
+
+       for (i = 0; i < uc_priv->gpio_count; i++) {
+               if (uc_priv->name[i])
+                       free(uc_priv->name[i]);
+       }
+       free(uc_priv->name);
+
+       return gpio_renumber(dev);
 }
 
 UCLASS_DRIVER(gpio) = {
index 7d9fac72337fc329ac12d2c80ad21f03b9e8fe7e..d3381b0369c1a4122f30c0e80aecd154d4e4e896 100644 (file)
  */
 
 #include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <fdtdec.h>
 #include <pci.h>
 #include <asm/gpio.h>
 #include <asm/io.h>
 
+#define GPIO_PER_BANK  32
+
 /* Where in config space is the register that points to the GPIO registers? */
 #define PCI_CFG_GPIOBASE 0x48
 
-#define NUM_BANKS 3
-
-/* Within the I/O space, where are the registers to control the GPIOs? */
-static struct {
-       u8 use_sel;
-       u8 io_sel;
-       u8 lvl;
-} gpio_bank[NUM_BANKS] = {
-       { 0x00, 0x04, 0x0c },           /* Bank 0 */
-       { 0x30, 0x34, 0x38 },           /* Bank 1 */
-       { 0x40, 0x44, 0x48 }            /* Bank 2 */
+struct ich6_bank_priv {
+       /* These are I/O addresses */
+       uint32_t use_sel;
+       uint32_t io_sel;
+       uint32_t lvl;
 };
 
-static pci_dev_t dev;                  /* handle for 0:1f:0 */
-static u32 gpiobase;                   /* offset into I/O space */
-static int found_it_once;              /* valid GPIO device? */
-static u32 lock[NUM_BANKS];            /* "lock" for access to pins */
-
-static int bad_arg(int num, int *bank, int *bitnum)
-{
-       int i = num / 32;
-       int j = num % 32;
-
-       if (num < 0 || i > NUM_BANKS) {
-               debug("%s: bogus gpio num: %d\n", __func__, num);
-               return -1;
-       }
-       *bank = i;
-       *bitnum = j;
-       return 0;
-}
-
-static int mark_gpio(int bank, int bitnum)
-{
-       if (lock[bank] & (1UL << bitnum)) {
-               debug("%s: %d.%d already marked\n", __func__, bank, bitnum);
-               return -1;
-       }
-       lock[bank] |= (1 << bitnum);
-       return 0;
-}
-
-static void clear_gpio(int bank, int bitnum)
-{
-       lock[bank] &= ~(1 << bitnum);
-}
-
-static int notmine(int num, int *bank, int *bitnum)
-{
-       if (bad_arg(num, bank, bitnum))
-               return -1;
-       return !(lock[*bank] & (1UL << *bitnum));
-}
-
-static int gpio_init(void)
+static int gpio_ich6_ofdata_to_platdata(struct udevice *dev)
 {
+       struct ich6_bank_platdata *plat = dev_get_platdata(dev);
+       pci_dev_t pci_dev;                      /* handle for 0:1f:0 */
        u8 tmpbyte;
        u16 tmpword;
        u32 tmplong;
-
-       /* Have we already done this? */
-       if (found_it_once)
-               return 0;
+       u32 gpiobase;
+       int offset;
 
        /* Where should it be? */
-       dev = PCI_BDF(0, 0x1f, 0);
+       pci_dev = PCI_BDF(0, 0x1f, 0);
 
        /* Is the device present? */
-       pci_read_config_word(dev, PCI_VENDOR_ID, &tmpword);
+       pci_read_config_word(pci_dev, PCI_VENDOR_ID, &tmpword);
        if (tmpword != PCI_VENDOR_ID_INTEL) {
                debug("%s: wrong VendorID\n", __func__);
-               return -1;
+               return -ENODEV;
        }
 
-       pci_read_config_word(dev, PCI_DEVICE_ID, &tmpword);
+       pci_read_config_word(pci_dev, PCI_DEVICE_ID, &tmpword);
        debug("Found %04x:%04x\n", PCI_VENDOR_ID_INTEL, tmpword);
        /*
         * We'd like to validate the Device ID too, but pretty much any
@@ -118,37 +76,37 @@ static int gpio_init(void)
         */
 
        /* I/O should already be enabled (it's a RO bit). */
-       pci_read_config_word(dev, PCI_COMMAND, &tmpword);
+       pci_read_config_word(pci_dev, PCI_COMMAND, &tmpword);
        if (!(tmpword & PCI_COMMAND_IO)) {
                debug("%s: device IO not enabled\n", __func__);
-               return -1;
+               return -ENODEV;
        }
 
        /* Header Type must be normal (bits 6-0 only; see spec.) */
-       pci_read_config_byte(dev, PCI_HEADER_TYPE, &tmpbyte);
+       pci_read_config_byte(pci_dev, PCI_HEADER_TYPE, &tmpbyte);
        if ((tmpbyte & 0x7f) != PCI_HEADER_TYPE_NORMAL) {
                debug("%s: invalid Header type\n", __func__);
-               return -1;
+               return -ENODEV;
        }
 
        /* Base Class must be a bridge device */
-       pci_read_config_byte(dev, PCI_CLASS_CODE, &tmpbyte);
+       pci_read_config_byte(pci_dev, PCI_CLASS_CODE, &tmpbyte);
        if (tmpbyte != PCI_CLASS_CODE_BRIDGE) {
                debug("%s: invalid class\n", __func__);
-               return -1;
+               return -ENODEV;
        }
        /* Sub Class must be ISA */
-       pci_read_config_byte(dev, PCI_CLASS_SUB_CODE, &tmpbyte);
+       pci_read_config_byte(pci_dev, PCI_CLASS_SUB_CODE, &tmpbyte);
        if (tmpbyte != PCI_CLASS_SUB_CODE_BRIDGE_ISA) {
                debug("%s: invalid subclass\n", __func__);
-               return -1;
+               return -ENODEV;
        }
 
        /* Programming Interface must be 0x00 (no others exist) */
-       pci_read_config_byte(dev, PCI_CLASS_PROG, &tmpbyte);
+       pci_read_config_byte(pci_dev, PCI_CLASS_PROG, &tmpbyte);
        if (tmpbyte != 0x00) {
                debug("%s: invalid interface type\n", __func__);
-               return -1;
+               return -ENODEV;
        }
 
        /*
@@ -156,11 +114,11 @@ static int gpio_init(void)
         * that it was unused (or undocumented). Check that it looks
         * okay: not all ones or zeros, and mapped to I/O space (bit 0).
         */
-       pci_read_config_dword(dev, PCI_CFG_GPIOBASE, &tmplong);
+       pci_read_config_dword(pci_dev, PCI_CFG_GPIOBASE, &tmplong);
        if (tmplong == 0x00000000 || tmplong == 0xffffffff ||
            !(tmplong & 0x00000001)) {
                debug("%s: unexpected GPIOBASE value\n", __func__);
-               return -1;
+               return -ENODEV;
        }
 
        /*
@@ -170,105 +128,137 @@ static int gpio_init(void)
         * an I/O address, not a memory address, so mask that off.
         */
        gpiobase = tmplong & 0xfffffffe;
+       offset = fdtdec_get_int(gd->fdt_blob, dev->of_offset, "reg", -1);
+       if (offset == -1) {
+               debug("%s: Invalid register offset %d\n", __func__, offset);
+               return -EINVAL;
+       }
+       plat->base_addr = gpiobase + offset;
+       plat->bank_name = fdt_getprop(gd->fdt_blob, dev->of_offset,
+                                     "bank-name", NULL);
 
-       /* Finally. These are the droids we're looking for. */
-       found_it_once = 1;
        return 0;
 }
 
-int gpio_request(unsigned num, const char *label /* UNUSED */)
+int ich6_gpio_probe(struct udevice *dev)
 {
-       u32 tmplong;
-       int i = 0, j = 0;
+       struct ich6_bank_platdata *plat = dev_get_platdata(dev);
+       struct gpio_dev_priv *uc_priv = dev->uclass_priv;
+       struct ich6_bank_priv *bank = dev_get_priv(dev);
+
+       uc_priv->gpio_count = GPIO_PER_BANK;
+       uc_priv->bank_name = plat->bank_name;
+       bank->use_sel = plat->base_addr;
+       bank->io_sel = plat->base_addr + 4;
+       bank->lvl = plat->base_addr + 8;
 
-       /* Is the hardware ready? */
-       if (gpio_init())
-               return -1;
+       return 0;
+}
 
-       if (bad_arg(num, &i, &j))
-               return -1;
+int ich6_gpio_request(struct udevice *dev, unsigned offset, const char *label)
+{
+       struct ich6_bank_priv *bank = dev_get_priv(dev);
+       u32 tmplong;
 
        /*
         * Make sure that the GPIO pin we want isn't already in use for some
         * built-in hardware function. We have to check this for every
         * requested pin.
         */
-       tmplong = inl(gpiobase + gpio_bank[i].use_sel);
-       if (!(tmplong & (1UL << j))) {
+       tmplong = inl(bank->use_sel);
+       if (!(tmplong & (1UL << offset))) {
                debug("%s: gpio %d is reserved for internal use\n", __func__,
-                     num);
-               return -1;
+                     offset);
+               return -EPERM;
        }
 
-       return mark_gpio(i, j);
-}
-
-int gpio_free(unsigned num)
-{
-       int i = 0, j = 0;
-
-       if (notmine(num, &i, &j))
-               return -1;
-
-       clear_gpio(i, j);
        return 0;
 }
 
-int gpio_direction_input(unsigned num)
+static int ich6_gpio_direction_input(struct udevice *dev, unsigned offset)
 {
+       struct ich6_bank_priv *bank = dev_get_priv(dev);
        u32 tmplong;
-       int i = 0, j = 0;
-
-       if (notmine(num, &i, &j))
-               return -1;
 
-       tmplong = inl(gpiobase + gpio_bank[i].io_sel);
-       tmplong |= (1UL << j);
-       outl(gpiobase + gpio_bank[i].io_sel, tmplong);
+       tmplong = inl(bank->io_sel);
+       tmplong |= (1UL << offset);
+       outl(bank->io_sel, tmplong);
        return 0;
 }
 
-int gpio_direction_output(unsigned num, int value)
+static int ich6_gpio_direction_output(struct udevice *dev, unsigned offset,
+                                      int value)
 {
+       struct ich6_bank_priv *bank = dev_get_priv(dev);
        u32 tmplong;
-       int i = 0, j = 0;
 
-       if (notmine(num, &i, &j))
-               return -1;
-
-       tmplong = inl(gpiobase + gpio_bank[i].io_sel);
-       tmplong &= ~(1UL << j);
-       outl(gpiobase + gpio_bank[i].io_sel, tmplong);
+       tmplong = inl(bank->io_sel);
+       tmplong &= ~(1UL << offset);
+       outl(bank->io_sel, tmplong);
        return 0;
 }
 
-int gpio_get_value(unsigned num)
+static int ich6_gpio_get_value(struct udevice *dev, unsigned offset)
+
 {
+       struct ich6_bank_priv *bank = dev_get_priv(dev);
        u32 tmplong;
-       int i = 0, j = 0;
        int r;
 
-       if (notmine(num, &i, &j))
-               return -1;
-
-       tmplong = inl(gpiobase + gpio_bank[i].lvl);
-       r = (tmplong & (1UL << j)) ? 1 : 0;
+       tmplong = inl(bank->lvl);
+       r = (tmplong & (1UL << offset)) ? 1 : 0;
        return r;
 }
 
-int gpio_set_value(unsigned num, int value)
+static int ich6_gpio_set_value(struct udevice *dev, unsigned offset,
+                              int value)
 {
+       struct ich6_bank_priv *bank = dev_get_priv(dev);
        u32 tmplong;
-       int i = 0, j = 0;
 
-       if (notmine(num, &i, &j))
-               return -1;
-
-       tmplong = inl(gpiobase + gpio_bank[i].lvl);
+       tmplong = inl(bank->lvl);
        if (value)
-               tmplong |= (1UL << j);
+               tmplong |= (1UL << offset);
        else
-               tmplong &= ~(1UL << j);
-       outl(gpiobase + gpio_bank[i].lvl, tmplong);
+               tmplong &= ~(1UL << offset);
+       outl(bank->lvl, tmplong);
        return 0;
 }
+
+static int ich6_gpio_get_function(struct udevice *dev, unsigned offset)
+{
+       struct ich6_bank_priv *bank = dev_get_priv(dev);
+       u32 mask = 1UL << offset;
+
+       if (!(inl(bank->use_sel) & mask))
+               return GPIOF_FUNC;
+       if (inl(bank->io_sel) & mask)
+               return GPIOF_INPUT;
+       else
+               return GPIOF_OUTPUT;
+}
+
+static const struct dm_gpio_ops gpio_ich6_ops = {
+       .request                = ich6_gpio_request,
+       .direction_input        = ich6_gpio_direction_input,
+       .direction_output       = ich6_gpio_direction_output,
+       .get_value              = ich6_gpio_get_value,
+       .set_value              = ich6_gpio_set_value,
+       .get_function           = ich6_gpio_get_function,
+};
+
+static const struct udevice_id intel_ich6_gpio_ids[] = {
+       { .compatible = "intel,ich6-gpio" },
+       { }
+};
+
+U_BOOT_DRIVER(gpio_ich6) = {
+       .name   = "gpio_ich6",
+       .id     = UCLASS_GPIO,
+       .of_match = intel_ich6_gpio_ids,
+       .ops    = &gpio_ich6_ops,
+       .ofdata_to_platdata     = gpio_ich6_ofdata_to_platdata,
+       .probe  = ich6_gpio_probe,
+       .priv_auto_alloc_size = sizeof(struct ich6_bank_priv),
+       .platdata_auto_alloc_size = sizeof(struct ich6_bank_platdata),
+};
index 0af75a84ea7ab6ea5251549d43d40bbed96e40f2..43b27e3fea1bc86f5fbef46f969a7f8ff0322286 100644 (file)
@@ -16,7 +16,7 @@
 #include <common.h>
 #include <asm/bitops.h>
 #include <asm/io.h>
-#include <asm/arch/kirkwood.h>
+#include <asm/arch/soc.h>
 #include <asm/arch/gpio.h>
 
 static unsigned long gpio_valid_input[BITS_TO_LONGS(GPIO_MAX)];
@@ -36,7 +36,7 @@ void __set_direction(unsigned pin, int input)
        u = readl(GPIO_IO_CONF(pin));
 }
 
-void __set_level(unsigned pin, int high)
+static void __set_level(unsigned pin, int high)
 {
        u32 u;
 
@@ -48,7 +48,7 @@ void __set_level(unsigned pin, int high)
        writel(u, GPIO_OUT(pin));
 }
 
-void __set_blinking(unsigned pin, int blink)
+static void __set_blinking(unsigned pin, int blink)
 {
        u32 u;
 
index 6a572d5454b39e4905da9094edd01f47cf451035..8bb9e39b7231e522f87eaf9612ad5abf383931e7 100644 (file)
@@ -8,16 +8,29 @@
  * SPDX-License-Identifier:    GPL-2.0+
  */
 #include <common.h>
+#include <errno.h>
+#include <dm.h>
+#include <malloc.h>
 #include <asm/arch/imx-regs.h>
 #include <asm/gpio.h>
 #include <asm/io.h>
-#include <errno.h>
 
 enum mxc_gpio_direction {
        MXC_GPIO_DIRECTION_IN,
        MXC_GPIO_DIRECTION_OUT,
 };
 
+#define GPIO_PER_BANK                  32
+
+struct mxc_gpio_plat {
+       struct gpio_regs *regs;
+};
+
+struct mxc_bank_info {
+       struct gpio_regs *regs;
+};
+
+#ifndef CONFIG_DM_GPIO
 #define GPIO_TO_PORT(n)                (n / 32)
 
 /* GPIO port description */
@@ -134,3 +147,176 @@ int gpio_direction_output(unsigned gpio, int value)
 
        return mxc_gpio_direction(gpio, MXC_GPIO_DIRECTION_OUT);
 }
+#endif
+
+#ifdef CONFIG_DM_GPIO
+static int mxc_gpio_is_output(struct gpio_regs *regs, int offset)
+{
+       u32 val;
+
+       val = readl(&regs->gpio_dir);
+
+       return val & (1 << offset) ? 1 : 0;
+}
+
+static void mxc_gpio_bank_direction(struct gpio_regs *regs, int offset,
+                                   enum mxc_gpio_direction direction)
+{
+       u32 l;
+
+       l = readl(&regs->gpio_dir);
+
+       switch (direction) {
+       case MXC_GPIO_DIRECTION_OUT:
+               l |= 1 << offset;
+               break;
+       case MXC_GPIO_DIRECTION_IN:
+               l &= ~(1 << offset);
+       }
+       writel(l, &regs->gpio_dir);
+}
+
+static void mxc_gpio_bank_set_value(struct gpio_regs *regs, int offset,
+                                   int value)
+{
+       u32 l;
+
+       l = readl(&regs->gpio_dr);
+       if (value)
+               l |= 1 << offset;
+       else
+               l &= ~(1 << offset);
+       writel(l, &regs->gpio_dr);
+}
+
+static int mxc_gpio_bank_get_value(struct gpio_regs *regs, int offset)
+{
+       return (readl(&regs->gpio_psr) >> offset) & 0x01;
+}
+
+/* set GPIO pin 'gpio' as an input */
+static int mxc_gpio_direction_input(struct udevice *dev, unsigned offset)
+{
+       struct mxc_bank_info *bank = dev_get_priv(dev);
+
+       /* Configure GPIO direction as input. */
+       mxc_gpio_bank_direction(bank->regs, offset, MXC_GPIO_DIRECTION_IN);
+
+       return 0;
+}
+
+/* set GPIO pin 'gpio' as an output, with polarity 'value' */
+static int mxc_gpio_direction_output(struct udevice *dev, unsigned offset,
+                                      int value)
+{
+       struct mxc_bank_info *bank = dev_get_priv(dev);
+
+       /* Configure GPIO output value. */
+       mxc_gpio_bank_set_value(bank->regs, offset, value);
+
+       /* Configure GPIO direction as output. */
+       mxc_gpio_bank_direction(bank->regs, offset, MXC_GPIO_DIRECTION_OUT);
+
+       return 0;
+}
+
+/* read GPIO IN value of pin 'gpio' */
+static int mxc_gpio_get_value(struct udevice *dev, unsigned offset)
+{
+       struct mxc_bank_info *bank = dev_get_priv(dev);
+
+       return mxc_gpio_bank_get_value(bank->regs, offset);
+}
+
+/* write GPIO OUT value to pin 'gpio' */
+static int mxc_gpio_set_value(struct udevice *dev, unsigned offset,
+                                int value)
+{
+       struct mxc_bank_info *bank = dev_get_priv(dev);
+
+       mxc_gpio_bank_set_value(bank->regs, offset, value);
+
+       return 0;
+}
+
+static int mxc_gpio_get_function(struct udevice *dev, unsigned offset)
+{
+       struct mxc_bank_info *bank = dev_get_priv(dev);
+
+       /* GPIOF_FUNC is not implemented yet */
+       if (mxc_gpio_is_output(bank->regs, offset))
+               return GPIOF_OUTPUT;
+       else
+               return GPIOF_INPUT;
+}
+
+static const struct dm_gpio_ops gpio_mxc_ops = {
+       .direction_input        = mxc_gpio_direction_input,
+       .direction_output       = mxc_gpio_direction_output,
+       .get_value              = mxc_gpio_get_value,
+       .set_value              = mxc_gpio_set_value,
+       .get_function           = mxc_gpio_get_function,
+};
+
+static const struct mxc_gpio_plat mxc_plat[] = {
+       { (struct gpio_regs *)GPIO1_BASE_ADDR },
+       { (struct gpio_regs *)GPIO2_BASE_ADDR },
+       { (struct gpio_regs *)GPIO3_BASE_ADDR },
+#if defined(CONFIG_MX25) || defined(CONFIG_MX27) || defined(CONFIG_MX51) || \
+               defined(CONFIG_MX53) || defined(CONFIG_MX6)
+       { (struct gpio_regs *)GPIO4_BASE_ADDR },
+#endif
+#if defined(CONFIG_MX27) || defined(CONFIG_MX53) || defined(CONFIG_MX6)
+       { (struct gpio_regs *)GPIO5_BASE_ADDR },
+       { (struct gpio_regs *)GPIO6_BASE_ADDR },
+#endif
+#if defined(CONFIG_MX53) || defined(CONFIG_MX6)
+       { (struct gpio_regs *)GPIO7_BASE_ADDR },
+#endif
+};
+
+static int mxc_gpio_probe(struct udevice *dev)
+{
+       struct mxc_bank_info *bank = dev_get_priv(dev);
+       struct mxc_gpio_plat *plat = dev_get_platdata(dev);
+       struct gpio_dev_priv *uc_priv = dev->uclass_priv;
+       int banknum;
+       char name[18], *str;
+
+       banknum = plat - mxc_plat;
+       sprintf(name, "GPIO%d_", banknum + 1);
+       str = strdup(name);
+       if (!str)
+               return -ENOMEM;
+       uc_priv->bank_name = str;
+       uc_priv->gpio_count = GPIO_PER_BANK;
+       bank->regs = plat->regs;
+
+       return 0;
+}
+
+U_BOOT_DRIVER(gpio_mxc) = {
+       .name   = "gpio_mxc",
+       .id     = UCLASS_GPIO,
+       .ops    = &gpio_mxc_ops,
+       .probe  = mxc_gpio_probe,
+       .priv_auto_alloc_size = sizeof(struct mxc_bank_info),
+};
+
+U_BOOT_DEVICES(mxc_gpios) = {
+       { "gpio_mxc", &mxc_plat[0] },
+       { "gpio_mxc", &mxc_plat[1] },
+       { "gpio_mxc", &mxc_plat[2] },
+#if defined(CONFIG_MX25) || defined(CONFIG_MX27) || defined(CONFIG_MX51) || \
+               defined(CONFIG_MX53) || defined(CONFIG_MX6)
+       { "gpio_mxc", &mxc_plat[3] },
+#endif
+#if defined(CONFIG_MX27) || defined(CONFIG_MX53) || defined(CONFIG_MX6)
+       { "gpio_mxc", &mxc_plat[4] },
+       { "gpio_mxc", &mxc_plat[5] },
+#endif
+#if defined(CONFIG_MX53) || defined(CONFIG_MX6)
+       { "gpio_mxc", &mxc_plat[6] },
+#endif
+};
+#endif
index 13dcf798730f4313e6767dc8078b05a454e6adb2..f3a7ccb51e98f28ee1b9dd72906dac4b93e0c407 100644 (file)
@@ -19,6 +19,7 @@
  * Written by Juha Yrjölä <juha.yrjola@nokia.com>
  */
 #include <common.h>
+#include <dm.h>
 #include <asm/gpio.h>
 #include <asm/io.h>
 #include <asm/errno.h>
 #define OMAP_GPIO_DIR_OUT      0
 #define OMAP_GPIO_DIR_IN       1
 
-static inline const struct gpio_bank *get_gpio_bank(int gpio)
-{
-       return &omap_gpio_bank[gpio >> 5];
-}
+#ifdef CONFIG_DM_GPIO
+
+#define GPIO_PER_BANK                  32
+
+struct gpio_bank {
+       /* TODO(sjg@chromium.org): Can we use a struct here? */
+       void *base;     /* address of registers in physical memory */
+       enum gpio_method method;
+};
+
+#endif
 
 static inline int get_gpio_index(int gpio)
 {
@@ -41,15 +49,6 @@ int gpio_is_valid(int gpio)
        return (gpio >= 0) && (gpio < OMAP_MAX_GPIO);
 }
 
-static int check_gpio(int gpio)
-{
-       if (!gpio_is_valid(gpio)) {
-               printf("ERROR : check_gpio: invalid GPIO %d\n", gpio);
-               return -1;
-       }
-       return 0;
-}
-
 static void _set_gpio_direction(const struct gpio_bank *bank, int gpio,
                                int is_input)
 {
@@ -118,6 +117,48 @@ static void _set_gpio_dataout(const struct gpio_bank *bank, int gpio,
        __raw_writel(l, reg);
 }
 
+static int _get_gpio_value(const struct gpio_bank *bank, int gpio)
+{
+       void *reg = bank->base;
+       int input;
+
+       switch (bank->method) {
+       case METHOD_GPIO_24XX:
+               input = _get_gpio_direction(bank, gpio);
+               switch (input) {
+               case OMAP_GPIO_DIR_IN:
+                       reg += OMAP_GPIO_DATAIN;
+                       break;
+               case OMAP_GPIO_DIR_OUT:
+                       reg += OMAP_GPIO_DATAOUT;
+                       break;
+               default:
+                       return -1;
+               }
+               break;
+       default:
+               return -1;
+       }
+
+       return (__raw_readl(reg) & (1 << gpio)) != 0;
+}
+
+#ifndef CONFIG_DM_GPIO
+
+static inline const struct gpio_bank *get_gpio_bank(int gpio)
+{
+       return &omap_gpio_bank[gpio >> 5];
+}
+
+static int check_gpio(int gpio)
+{
+       if (!gpio_is_valid(gpio)) {
+               printf("ERROR : check_gpio: invalid GPIO %d\n", gpio);
+               return -1;
+       }
+       return 0;
+}
+
 /**
  * Set value of the specified gpio
  */
@@ -139,32 +180,12 @@ int gpio_set_value(unsigned gpio, int value)
 int gpio_get_value(unsigned gpio)
 {
        const struct gpio_bank *bank;
-       void *reg;
-       int input;
 
        if (check_gpio(gpio) < 0)
                return -1;
        bank = get_gpio_bank(gpio);
-       reg = bank->base;
-       switch (bank->method) {
-       case METHOD_GPIO_24XX:
-               input = _get_gpio_direction(bank, get_gpio_index(gpio));
-               switch (input) {
-               case OMAP_GPIO_DIR_IN:
-                       reg += OMAP_GPIO_DATAIN;
-                       break;
-               case OMAP_GPIO_DIR_OUT:
-                       reg += OMAP_GPIO_DATAOUT;
-                       break;
-               default:
-                       return -1;
-               }
-               break;
-       default:
-               return -1;
-       }
-       return (__raw_readl(reg)
-                       & (1 << get_gpio_index(gpio))) != 0;
+
+       return _get_gpio_value(bank, get_gpio_index(gpio));
 }
 
 /**
@@ -220,3 +241,95 @@ int gpio_free(unsigned gpio)
 {
        return 0;
 }
+
+#else /* new driver model interface CONFIG_DM_GPIO */
+
+/* set GPIO pin 'gpio' as an input */
+static int omap_gpio_direction_input(struct udevice *dev, unsigned offset)
+{
+       struct gpio_bank *bank = dev_get_priv(dev);
+
+       /* Configure GPIO direction as input. */
+       _set_gpio_direction(bank, offset, 1);
+
+       return 0;
+}
+
+/* set GPIO pin 'gpio' as an output, with polarity 'value' */
+static int omap_gpio_direction_output(struct udevice *dev, unsigned offset,
+                                      int value)
+{
+       struct gpio_bank *bank = dev_get_priv(dev);
+
+       _set_gpio_dataout(bank, offset, value);
+       _set_gpio_direction(bank, offset, 0);
+
+       return 0;
+}
+
+/* read GPIO IN value of pin 'gpio' */
+static int omap_gpio_get_value(struct udevice *dev, unsigned offset)
+{
+       struct gpio_bank *bank = dev_get_priv(dev);
+
+       return _get_gpio_value(bank, offset);
+}
+
+/* write GPIO OUT value to pin 'gpio' */
+static int omap_gpio_set_value(struct udevice *dev, unsigned offset,
+                                int value)
+{
+       struct gpio_bank *bank = dev_get_priv(dev);
+
+       _set_gpio_dataout(bank, offset, value);
+
+       return 0;
+}
+
+static int omap_gpio_get_function(struct udevice *dev, unsigned offset)
+{
+       struct gpio_bank *bank = dev_get_priv(dev);
+
+       /* GPIOF_FUNC is not implemented yet */
+       if (_get_gpio_direction(bank->base, offset) == OMAP_GPIO_DIR_OUT)
+               return GPIOF_OUTPUT;
+       else
+               return GPIOF_INPUT;
+}
+
+static const struct dm_gpio_ops gpio_omap_ops = {
+       .direction_input        = omap_gpio_direction_input,
+       .direction_output       = omap_gpio_direction_output,
+       .get_value              = omap_gpio_get_value,
+       .set_value              = omap_gpio_set_value,
+       .get_function           = omap_gpio_get_function,
+};
+
+static int omap_gpio_probe(struct udevice *dev)
+{
+       struct gpio_bank *bank = dev_get_priv(dev);
+       struct omap_gpio_platdata *plat = dev_get_platdata(dev);
+       struct gpio_dev_priv *uc_priv = dev->uclass_priv;
+       char name[18], *str;
+
+       sprintf(name, "GPIO%d_", plat->bank_index);
+       str = strdup(name);
+       if (!str)
+               return -ENOMEM;
+       uc_priv->bank_name = str;
+       uc_priv->gpio_count = GPIO_PER_BANK;
+       bank->base = (void *)plat->base;
+       bank->method = plat->method;
+
+       return 0;
+}
+
+U_BOOT_DRIVER(gpio_omap) = {
+       .name   = "gpio_omap",
+       .id     = UCLASS_GPIO,
+       .ops    = &gpio_omap_ops,
+       .probe  = omap_gpio_probe,
+       .priv_auto_alloc_size = sizeof(struct gpio_bank),
+};
+
+#endif /* CONFIG_DM_GPIO */
index db7b67373101636b61034b3fc90d2b147a33219a..6c41a42c177351adcd0d6f96ff81ae2a0f1036ee 100644 (file)
  */
 
 #include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <fdtdec.h>
+#include <malloc.h>
 #include <asm/io.h>
 #include <asm/gpio.h>
-#include <asm/arch/gpio.h>
+#include <dm/device-internal.h>
+
+DECLARE_GLOBAL_DATA_PTR;
 
 #define S5P_GPIO_GET_PIN(x)    (x % GPIO_PER_BANK)
 
-#define CON_MASK(x)            (0xf << ((x) << 2))
-#define CON_SFR(x, v)          ((v) << ((x) << 2))
+#define CON_MASK(val)                  (0xf << ((val) << 2))
+#define CON_SFR(gpio, cfg)             ((cfg) << ((gpio) << 2))
+#define CON_SFR_UNSHIFT(val, gpio)     ((val) >> ((gpio) << 2))
+
+#define DAT_MASK(gpio)                 (0x1 << (gpio))
+#define DAT_SET(gpio)                  (0x1 << (gpio))
 
-#define DAT_MASK(x)            (0x1 << (x))
-#define DAT_SET(x)             (0x1 << (x))
+#define PULL_MASK(gpio)                (0x3 << ((gpio) << 1))
+#define PULL_MODE(gpio, pull)          ((pull) << ((gpio) << 1))
 
-#define PULL_MASK(x)           (0x3 << ((x) << 1))
-#define PULL_MODE(x, v)                ((v) << ((x) << 1))
+#define DRV_MASK(gpio)                 (0x3 << ((gpio) << 1))
+#define DRV_SET(gpio, mode)            ((mode) << ((gpio) << 1))
+#define RATE_MASK(gpio)                (0x1 << (gpio + 16))
+#define RATE_SET(gpio)                 (0x1 << (gpio + 16))
 
-#define DRV_MASK(x)            (0x3 << ((x) << 1))
-#define DRV_SET(x, m)          ((m) << ((x) << 1))
-#define RATE_MASK(x)           (0x1 << (x + 16))
-#define RATE_SET(x)            (0x1 << (x + 16))
+/* Platform data for each bank */
+struct exynos_gpio_platdata {
+       struct s5p_gpio_bank *bank;
+       const char *bank_name;  /* Name of port, e.g. 'gpa0" */
+};
 
-#define name_to_gpio(n) s5p_name_to_gpio(n)
-static inline int s5p_name_to_gpio(const char *name)
+/* Information about each bank at run-time */
+struct exynos_bank_info {
+       struct s5p_gpio_bank *bank;
+};
+
+static struct s5p_gpio_bank *s5p_gpio_get_bank(unsigned int gpio)
 {
-       unsigned num, irregular_set_number, irregular_bank_base;
-       const struct gpio_name_num_table *tabp;
-       char this_bank, bank_name, irregular_bank_name;
-       char *endp;
-
-       /*
-        * The gpio name starts with either 'g' or 'gp' followed by the bank
-        * name character. Skip one or two characters depending on the prefix.
-        */
-       if (name[0] == 'g' && name[1] == 'p')
-               name += 2;
-       else if (name[0] == 'g')
-               name++;
-       else
-               return -1; /* Name must start with 'g' */
-
-       bank_name = *name++;
-       if (!*name)
-               return -1; /* At least one digit is required/expected. */
-
-       /*
-        * On both exynos5 and exynos5420 architectures there is a bank of
-        * GPIOs which does not fall into the regular address pattern. Those
-        * banks are c4 on Exynos5 and y7 on Exynos5420. The rest of the below
-        * assignments help to handle these irregularities.
-        */
-#if defined(CONFIG_EXYNOS4) || defined(CONFIG_EXYNOS5)
-       if (cpu_is_exynos5()) {
-               if (proid_is_exynos5420()) {
-                       tabp = exynos5420_gpio_table;
-                       irregular_bank_name = 'y';
-                       irregular_set_number = '7';
-                       irregular_bank_base = EXYNOS5420_GPIO_Y70;
-               } else {
-                       tabp = exynos5_gpio_table;
-                       irregular_bank_name = 'c';
-                       irregular_set_number = '4';
-                       irregular_bank_base = EXYNOS5_GPIO_C40;
-               }
-       } else {
-               if (proid_is_exynos4412())
-                       tabp = exynos4x12_gpio_table;
-               else
-                       tabp = exynos4_gpio_table;
-               irregular_bank_name = 0;
-               irregular_set_number = 0;
-               irregular_bank_base = 0;
-       }
-#else
-       if (cpu_is_s5pc110())
-               tabp = s5pc110_gpio_table;
-       else
-               tabp = s5pc100_gpio_table;
-       irregular_bank_name = 0;
-       irregular_set_number = 0;
-       irregular_bank_base = 0;
-#endif
+       const struct gpio_info *data;
+       unsigned int upto;
+       int i, count;
+
+       data = get_gpio_data();
+       count = get_bank_num();
+       upto = 0;
 
-       this_bank = tabp->bank;
-       do {
-               if (bank_name == this_bank) {
-                       unsigned pin_index; /* pin number within the bank */
-                       if ((bank_name == irregular_bank_name) &&
-                           (name[0] == irregular_set_number)) {
-                               pin_index = name[1] - '0';
-                               /* Irregular sets have 8 pins. */
-                               if (pin_index >= GPIO_PER_BANK)
-                                       return -1;
-                               num = irregular_bank_base + pin_index;
-                       } else {
-                               pin_index = simple_strtoul(name, &endp, 8);
-                               pin_index -= tabp->bank_offset;
-                               /*
-                                * Sanity check: bunk 'z' has no set number,
-                                * for all other banks there must be exactly
-                                * two octal digits, and the resulting number
-                                * should not exceed the number of pins in the
-                                * bank.
-                                */
-                               if (((bank_name != 'z') && !name[1]) ||
-                                   *endp ||
-                                   (pin_index >= tabp->bank_size))
-                                       return -1;
-                               num = tabp->base + pin_index;
-                       }
-                       return num;
+       for (i = 0; i < count; i++) {
+               debug("i=%d, upto=%d\n", i, upto);
+               if (gpio < data->max_gpio) {
+                       struct s5p_gpio_bank *bank;
+                       bank = (struct s5p_gpio_bank *)data->reg_addr;
+                       bank += (gpio - upto) / GPIO_PER_BANK;
+                       debug("gpio=%d, bank=%p\n", gpio, bank);
+                       return bank;
                }
-               this_bank = (++tabp)->bank;
-       } while (this_bank);
 
-       return -1;
+               upto = data->max_gpio;
+               data++;
+       }
+
+       return NULL;
 }
 
 static void s5p_gpio_cfg_pin(struct s5p_gpio_bank *bank, int gpio, int cfg)
@@ -143,16 +92,23 @@ static void s5p_gpio_set_value(struct s5p_gpio_bank *bank, int gpio, int en)
        writel(value, &bank->dat);
 }
 
-static void s5p_gpio_direction_output(struct s5p_gpio_bank *bank,
-                                     int gpio, int en)
+#ifdef CONFIG_SPL_BUILD
+/* Common GPIO API - SPL does not support driver model yet */
+int gpio_set_value(unsigned gpio, int value)
 {
-       s5p_gpio_cfg_pin(bank, gpio, S5P_GPIO_OUTPUT);
-       s5p_gpio_set_value(bank, gpio, en);
-}
+       s5p_gpio_set_value(s5p_gpio_get_bank(gpio),
+                          s5p_gpio_get_pin(gpio), value);
 
-static void s5p_gpio_direction_input(struct s5p_gpio_bank *bank, int gpio)
+       return 0;
+}
+#else
+static int s5p_gpio_get_cfg_pin(struct s5p_gpio_bank *bank, int gpio)
 {
-       s5p_gpio_cfg_pin(bank, gpio, S5P_GPIO_INPUT);
+       unsigned int value;
+
+       value = readl(&bank->con);
+       value &= CON_MASK(gpio);
+       return CON_SFR_UNSHIFT(value, gpio);
 }
 
 static unsigned int s5p_gpio_get_value(struct s5p_gpio_bank *bank, int gpio)
@@ -162,6 +118,7 @@ static unsigned int s5p_gpio_get_value(struct s5p_gpio_bank *bank, int gpio)
        value = readl(&bank->dat);
        return !!(value & DAT_MASK(gpio));
 }
+#endif /* CONFIG_SPL_BUILD */
 
 static void s5p_gpio_set_pull(struct s5p_gpio_bank *bank, int gpio, int mode)
 {
@@ -222,78 +179,63 @@ static void s5p_gpio_set_rate(struct s5p_gpio_bank *bank, int gpio, int mode)
        writel(value, &bank->drv);
 }
 
-struct s5p_gpio_bank *s5p_gpio_get_bank(unsigned int gpio)
-{
-       const struct gpio_info *data;
-       unsigned int upto;
-       int i, count;
-
-       data = get_gpio_data();
-       count = get_bank_num();
-       upto = 0;
-
-       for (i = 0; i < count; i++) {
-               debug("i=%d, upto=%d\n", i, upto);
-               if (gpio < data->max_gpio) {
-                       struct s5p_gpio_bank *bank;
-                       bank = (struct s5p_gpio_bank *)data->reg_addr;
-                       bank += (gpio - upto) / GPIO_PER_BANK;
-                       debug("gpio=%d, bank=%p\n", gpio, bank);
-                       return bank;
-               }
-
-               upto = data->max_gpio;
-               data++;
-       }
-
-       return NULL;
-}
-
 int s5p_gpio_get_pin(unsigned gpio)
 {
        return S5P_GPIO_GET_PIN(gpio);
 }
 
-/* Common GPIO API */
-
-int gpio_request(unsigned gpio, const char *label)
+/* Driver model interface */
+#ifndef CONFIG_SPL_BUILD
+/* set GPIO pin 'gpio' as an input */
+static int exynos_gpio_direction_input(struct udevice *dev, unsigned offset)
 {
-       return 0;
-}
+       struct exynos_bank_info *state = dev_get_priv(dev);
 
-int gpio_free(unsigned gpio)
-{
-       return 0;
-}
+       /* Configure GPIO direction as input. */
+       s5p_gpio_cfg_pin(state->bank, offset, S5P_GPIO_INPUT);
 
-int gpio_direction_input(unsigned gpio)
-{
-       s5p_gpio_direction_input(s5p_gpio_get_bank(gpio),
-                               s5p_gpio_get_pin(gpio));
        return 0;
 }
 
-int gpio_direction_output(unsigned gpio, int value)
+/* set GPIO pin 'gpio' as an output, with polarity 'value' */
+static int exynos_gpio_direction_output(struct udevice *dev, unsigned offset,
+                                      int value)
 {
-       s5p_gpio_direction_output(s5p_gpio_get_bank(gpio),
-                                s5p_gpio_get_pin(gpio), value);
+       struct exynos_bank_info *state = dev_get_priv(dev);
+
+       /* Configure GPIO output value. */
+       s5p_gpio_set_value(state->bank, offset, value);
+
+       /* Configure GPIO direction as output. */
+       s5p_gpio_cfg_pin(state->bank, offset, S5P_GPIO_OUTPUT);
+
        return 0;
 }
 
-int gpio_get_value(unsigned gpio)
+/* read GPIO IN value of pin 'gpio' */
+static int exynos_gpio_get_value(struct udevice *dev, unsigned offset)
 {
-       return (int) s5p_gpio_get_value(s5p_gpio_get_bank(gpio),
-                                      s5p_gpio_get_pin(gpio));
+       struct exynos_bank_info *state = dev_get_priv(dev);
+
+       return s5p_gpio_get_value(state->bank, offset);
 }
 
-int gpio_set_value(unsigned gpio, int value)
+/* write GPIO OUT value to pin 'gpio' */
+static int exynos_gpio_set_value(struct udevice *dev, unsigned offset,
+                                int value)
 {
-       s5p_gpio_set_value(s5p_gpio_get_bank(gpio),
-                         s5p_gpio_get_pin(gpio), value);
+       struct exynos_bank_info *state = dev_get_priv(dev);
+
+       s5p_gpio_set_value(state->bank, offset, value);
 
        return 0;
 }
+#endif /* nCONFIG_SPL_BUILD */
 
+/*
+ * There is no common GPIO API for pull, drv, pin, rate (yet). These
+ * functions are kept here to preserve function ordering for review.
+ */
 void gpio_set_pull(int gpio, int mode)
 {
        s5p_gpio_set_pull(s5p_gpio_get_bank(gpio),
@@ -317,3 +259,112 @@ void gpio_set_rate(int gpio, int mode)
        s5p_gpio_set_rate(s5p_gpio_get_bank(gpio),
                          s5p_gpio_get_pin(gpio), mode);
 }
+
+#ifndef CONFIG_SPL_BUILD
+static int exynos_gpio_get_function(struct udevice *dev, unsigned offset)
+{
+       struct exynos_bank_info *state = dev_get_priv(dev);
+       int cfg;
+
+       cfg = s5p_gpio_get_cfg_pin(state->bank, offset);
+       if (cfg == S5P_GPIO_OUTPUT)
+               return GPIOF_OUTPUT;
+       else if (cfg == S5P_GPIO_INPUT)
+               return GPIOF_INPUT;
+       else
+               return GPIOF_FUNC;
+}
+
+static const struct dm_gpio_ops gpio_exynos_ops = {
+       .direction_input        = exynos_gpio_direction_input,
+       .direction_output       = exynos_gpio_direction_output,
+       .get_value              = exynos_gpio_get_value,
+       .set_value              = exynos_gpio_set_value,
+       .get_function           = exynos_gpio_get_function,
+};
+
+static int gpio_exynos_probe(struct udevice *dev)
+{
+       struct gpio_dev_priv *uc_priv = dev->uclass_priv;
+       struct exynos_bank_info *priv = dev->priv;
+       struct exynos_gpio_platdata *plat = dev->platdata;
+
+       /* Only child devices have ports */
+       if (!plat)
+               return 0;
+
+       priv->bank = plat->bank;
+
+       uc_priv->gpio_count = GPIO_PER_BANK;
+       uc_priv->bank_name = plat->bank_name;
+
+       return 0;
+}
+
+/**
+ * We have a top-level GPIO device with no actual GPIOs. It has a child
+ * device for each Exynos GPIO bank.
+ */
+static int gpio_exynos_bind(struct udevice *parent)
+{
+       struct exynos_gpio_platdata *plat = parent->platdata;
+       struct s5p_gpio_bank *bank, *base;
+       const void *blob = gd->fdt_blob;
+       int node;
+
+       /* If this is a child device, there is nothing to do here */
+       if (plat)
+               return 0;
+
+       base = (struct s5p_gpio_bank *)fdtdec_get_addr(gd->fdt_blob,
+                                                  parent->of_offset, "reg");
+       for (node = fdt_first_subnode(blob, parent->of_offset), bank = base;
+            node > 0;
+            node = fdt_next_subnode(blob, node), bank++) {
+               struct exynos_gpio_platdata *plat;
+               struct udevice *dev;
+               fdt_addr_t reg;
+               int ret;
+
+               if (!fdtdec_get_bool(blob, node, "gpio-controller"))
+                       continue;
+               plat = calloc(1, sizeof(*plat));
+               if (!plat)
+                       return -ENOMEM;
+               reg = fdtdec_get_addr(blob, node, "reg");
+               if (reg != FDT_ADDR_T_NONE)
+                       bank = (struct s5p_gpio_bank *)((ulong)base + reg);
+               plat->bank = bank;
+               plat->bank_name = fdt_get_name(blob, node, NULL);
+               debug("dev at %p: %s\n", bank, plat->bank_name);
+
+               ret = device_bind(parent, parent->driver,
+                                       plat->bank_name, plat, -1, &dev);
+               if (ret)
+                       return ret;
+               dev->of_offset = parent->of_offset;
+       }
+
+       return 0;
+}
+
+static const struct udevice_id exynos_gpio_ids[] = {
+       { .compatible = "samsung,s5pc100-pinctrl" },
+       { .compatible = "samsung,s5pc110-pinctrl" },
+       { .compatible = "samsung,exynos4210-pinctrl" },
+       { .compatible = "samsung,exynos4x12-pinctrl" },
+       { .compatible = "samsung,exynos5250-pinctrl" },
+       { .compatible = "samsung,exynos5420-pinctrl" },
+       { }
+};
+
+U_BOOT_DRIVER(gpio_exynos) = {
+       .name   = "gpio_exynos",
+       .id     = UCLASS_GPIO,
+       .of_match = exynos_gpio_ids,
+       .bind   = gpio_exynos_bind,
+       .probe = gpio_exynos_probe,
+       .priv_auto_alloc_size = sizeof(struct exynos_bank_info),
+       .ops    = &gpio_exynos_ops,
+};
+#endif
index 75ada5d3871a844935c22b1bb9557f2e3229c84f..53c80d5be65dd85c0dbe20d2e1823e0400a4937f 100644 (file)
@@ -14,7 +14,6 @@ DECLARE_GLOBAL_DATA_PTR;
 /* Flags for each GPIO */
 #define GPIOF_OUTPUT   (1 << 0)        /* Currently set as an output */
 #define GPIOF_HIGH     (1 << 1)        /* Currently set high */
-#define GPIOF_RESERVED (1 << 2)        /* Is in use / requested */
 
 struct gpio_state {
        const char *label;      /* label given by requester */
@@ -54,18 +53,6 @@ static int set_gpio_flag(struct udevice *dev, unsigned offset, int flag,
        return 0;
 }
 
-static int check_reserved(struct udevice *dev, unsigned offset,
-                         const char *func)
-{
-       if (!get_gpio_flag(dev, offset, GPIOF_RESERVED)) {
-               printf("sandbox_gpio: %s: error: offset %u not reserved\n",
-                      func, offset);
-               return -1;
-       }
-
-       return 0;
-}
-
 /*
  * Back-channel sandbox-internal-only access to GPIO state
  */
@@ -101,9 +88,6 @@ static int sb_gpio_direction_input(struct udevice *dev, unsigned offset)
 {
        debug("%s: offset:%u\n", __func__, offset);
 
-       if (check_reserved(dev, offset, __func__))
-               return -1;
-
        return sandbox_gpio_set_direction(dev, offset, 0);
 }
 
@@ -113,9 +97,6 @@ static int sb_gpio_direction_output(struct udevice *dev, unsigned offset,
 {
        debug("%s: offset:%u, value = %d\n", __func__, offset, value);
 
-       if (check_reserved(dev, offset, __func__))
-               return -1;
-
        return sandbox_gpio_set_direction(dev, offset, 1) |
                sandbox_gpio_set_value(dev, offset, value);
 }
@@ -125,9 +106,6 @@ static int sb_gpio_get_value(struct udevice *dev, unsigned offset)
 {
        debug("%s: offset:%u\n", __func__, offset);
 
-       if (check_reserved(dev, offset, __func__))
-               return -1;
-
        return sandbox_gpio_get_value(dev, offset);
 }
 
@@ -136,9 +114,6 @@ static int sb_gpio_set_value(struct udevice *dev, unsigned offset, int value)
 {
        debug("%s: offset:%u, value = %d\n", __func__, offset, value);
 
-       if (check_reserved(dev, offset, __func__))
-               return -1;
-
        if (!sandbox_gpio_get_direction(dev, offset)) {
                printf("sandbox_gpio: error: set_value on input gpio %u\n",
                       offset);
@@ -148,69 +123,19 @@ static int sb_gpio_set_value(struct udevice *dev, unsigned offset, int value)
        return sandbox_gpio_set_value(dev, offset, value);
 }
 
-static int sb_gpio_request(struct udevice *dev, unsigned offset,
-                          const char *label)
+static int sb_gpio_get_function(struct udevice *dev, unsigned offset)
 {
-       struct gpio_dev_priv *uc_priv = dev->uclass_priv;
-       struct gpio_state *state = dev_get_priv(dev);
-
-       debug("%s: offset:%u, label:%s\n", __func__, offset, label);
-
-       if (offset >= uc_priv->gpio_count) {
-               printf("sandbox_gpio: error: invalid gpio %u\n", offset);
-               return -1;
-       }
-
-       if (get_gpio_flag(dev, offset, GPIOF_RESERVED)) {
-               printf("sandbox_gpio: error: gpio %u already reserved\n",
-                      offset);
-               return -1;
-       }
-
-       state[offset].label = label;
-       return set_gpio_flag(dev, offset, GPIOF_RESERVED, 1);
-}
-
-static int sb_gpio_free(struct udevice *dev, unsigned offset)
-{
-       struct gpio_state *state = dev_get_priv(dev);
-
-       debug("%s: offset:%u\n", __func__, offset);
-
-       if (check_reserved(dev, offset, __func__))
-               return -1;
-
-       state[offset].label = NULL;
-       return set_gpio_flag(dev, offset, GPIOF_RESERVED, 0);
-}
-
-static int sb_gpio_get_state(struct udevice *dev, unsigned int offset,
-                            char *buf, int bufsize)
-{
-       struct gpio_dev_priv *uc_priv = dev->uclass_priv;
-       struct gpio_state *state = dev_get_priv(dev);
-       const char *label;
-
-       label = state[offset].label;
-       snprintf(buf, bufsize, "%s%d: %s: %d [%c]%s%s",
-                uc_priv->bank_name ? uc_priv->bank_name : "", offset,
-                sandbox_gpio_get_direction(dev, offset) ? "out" : " in",
-                sandbox_gpio_get_value(dev, offset),
-                get_gpio_flag(dev, offset, GPIOF_RESERVED) ? 'x' : ' ',
-                label ? " " : "",
-                label ? label : "");
-
-       return 0;
+       if (get_gpio_flag(dev, offset, GPIOF_OUTPUT))
+               return GPIOF_OUTPUT;
+       return GPIOF_INPUT;
 }
 
 static const struct dm_gpio_ops gpio_sandbox_ops = {
-       .request                = sb_gpio_request,
-       .free                   = sb_gpio_free,
        .direction_input        = sb_gpio_direction_input,
        .direction_output       = sb_gpio_direction_output,
        .get_value              = sb_gpio_get_value,
        .set_value              = sb_gpio_set_value,
-       .get_state              = sb_gpio_get_state,
+       .get_function           = sb_gpio_get_function,
 };
 
 static int sandbox_gpio_ofdata_to_platdata(struct udevice *dev)
@@ -239,6 +164,13 @@ static int gpio_sandbox_probe(struct udevice *dev)
        return 0;
 }
 
+static int gpio_sandbox_remove(struct udevice *dev)
+{
+       free(dev->priv);
+
+       return 0;
+}
+
 static const struct udevice_id sandbox_gpio_ids[] = {
        { .compatible = "sandbox,gpio" },
        { }
@@ -250,5 +182,6 @@ U_BOOT_DRIVER(gpio_sandbox) = {
        .of_match = sandbox_gpio_ids,
        .ofdata_to_platdata = sandbox_gpio_ofdata_to_platdata,
        .probe  = gpio_sandbox_probe,
+       .remove = gpio_sandbox_remove,
        .ops    = &gpio_sandbox_ops,
 };
index 1cc4abb8a938b16ccc1322a6adcc903bc064b299..88f7ef5bf04d9abce9605cd7e8e161a11b135a8d 100644 (file)
@@ -39,7 +39,6 @@ struct tegra_gpio_platdata {
 
 /* Information about each port at run-time */
 struct tegra_port_info {
-       char label[TEGRA_GPIOS_PER_PORT][GPIO_NAME_SIZE];
        struct gpio_ctlr_bank *bank;
        int base_gpio;          /* Port number for this port (0, 1,.., n-1) */
 };
@@ -132,21 +131,6 @@ static void set_level(unsigned gpio, int high)
        writel(u, &bank->gpio_out[GPIO_PORT(gpio)]);
 }
 
-static int check_reserved(struct udevice *dev, unsigned offset,
-                         const char *func)
-{
-       struct tegra_port_info *state = dev_get_priv(dev);
-       struct gpio_dev_priv *uc_priv = dev->uclass_priv;
-
-       if (!*state->label[offset]) {
-               printf("tegra_gpio: %s: error: gpio %s%d not reserved\n",
-                      func, uc_priv->bank_name, offset);
-               return -EBUSY;
-       }
-
-       return 0;
-}
-
 /* set GPIO pin 'gpio' as an output, with polarity 'value' */
 int tegra_spl_gpio_direction_output(int gpio, int value)
 {
@@ -171,56 +155,16 @@ static int tegra_gpio_request(struct udevice *dev, unsigned offset,
 {
        struct tegra_port_info *state = dev_get_priv(dev);
 
-       if (*state->label[offset])
-               return -EBUSY;
-
-       strncpy(state->label[offset], label, GPIO_NAME_SIZE);
-       state->label[offset][GPIO_NAME_SIZE - 1] = '\0';
-
        /* Configure as a GPIO */
        set_config(state->base_gpio + offset, 1);
 
        return 0;
 }
 
-static int tegra_gpio_free(struct udevice *dev, unsigned offset)
-{
-       struct tegra_port_info *state = dev_get_priv(dev);
-       int ret;
-
-       ret = check_reserved(dev, offset, __func__);
-       if (ret)
-               return ret;
-       state->label[offset][0] = '\0';
-
-       return 0;
-}
-
-/* read GPIO OUT value of pin 'gpio' */
-static int tegra_gpio_get_output_value(unsigned gpio)
-{
-       struct gpio_ctlr *ctlr = (struct gpio_ctlr *)NV_PA_GPIO_BASE;
-       struct gpio_ctlr_bank *bank = &ctlr->gpio_bank[GPIO_BANK(gpio)];
-       int val;
-
-       debug("gpio_get_output_value: pin = %d (port %d:bit %d)\n",
-               gpio, GPIO_FULLPORT(gpio), GPIO_BIT(gpio));
-
-       val = readl(&bank->gpio_out[GPIO_PORT(gpio)]);
-
-       return (val >> GPIO_BIT(gpio)) & 1;
-}
-
-
 /* set GPIO pin 'gpio' as an input */
 static int tegra_gpio_direction_input(struct udevice *dev, unsigned offset)
 {
        struct tegra_port_info *state = dev_get_priv(dev);
-       int ret;
-
-       ret = check_reserved(dev, offset, __func__);
-       if (ret)
-               return ret;
 
        /* Configure GPIO direction as input. */
        set_direction(state->base_gpio + offset, 0);
@@ -234,11 +178,6 @@ static int tegra_gpio_direction_output(struct udevice *dev, unsigned offset,
 {
        struct tegra_port_info *state = dev_get_priv(dev);
        int gpio = state->base_gpio + offset;
-       int ret;
-
-       ret = check_reserved(dev, offset, __func__);
-       if (ret)
-               return ret;
 
        /* Configure GPIO output value. */
        set_level(gpio, value);
@@ -254,13 +193,8 @@ static int tegra_gpio_get_value(struct udevice *dev, unsigned offset)
 {
        struct tegra_port_info *state = dev_get_priv(dev);
        int gpio = state->base_gpio + offset;
-       int ret;
        int val;
 
-       ret = check_reserved(dev, offset, __func__);
-       if (ret)
-               return ret;
-
        debug("%s: pin = %d (port %d:bit %d)\n", __func__,
              gpio, GPIO_FULLPORT(gpio), GPIO_BIT(gpio));
 
@@ -274,11 +208,6 @@ static int tegra_gpio_set_value(struct udevice *dev, unsigned offset, int value)
 {
        struct tegra_port_info *state = dev_get_priv(dev);
        int gpio = state->base_gpio + offset;
-       int ret;
-
-       ret = check_reserved(dev, offset, __func__);
-       if (ret)
-               return ret;
 
        debug("gpio_set_value: pin = %d (port %d:bit %d), value = %d\n",
              gpio, GPIO_FULLPORT(gpio), GPIO_BIT(gpio), value);
@@ -314,8 +243,6 @@ static int tegra_gpio_get_function(struct udevice *dev, unsigned offset)
        struct tegra_port_info *state = dev_get_priv(dev);
        int gpio = state->base_gpio + offset;
 
-       if (!*state->label[offset])
-               return GPIOF_UNUSED;
        if (!get_config(gpio))
                return GPIOF_FUNC;
        else if (get_direction(gpio))
@@ -324,50 +251,13 @@ static int tegra_gpio_get_function(struct udevice *dev, unsigned offset)
                return GPIOF_INPUT;
 }
 
-static int tegra_gpio_get_state(struct udevice *dev, unsigned int offset,
-                               char *buf, int bufsize)
-{
-       struct gpio_dev_priv *uc_priv = dev->uclass_priv;
-       struct tegra_port_info *state = dev_get_priv(dev);
-       int gpio = state->base_gpio + offset;
-       const char *label;
-       int is_output;
-       int is_gpio;
-       int size;
-
-       label = state->label[offset];
-       is_gpio = get_config(gpio); /* GPIO, not SFPIO */
-       size = snprintf(buf, bufsize, "%s%d: ",
-                       uc_priv->bank_name ? uc_priv->bank_name : "", offset);
-       buf += size;
-       bufsize -= size;
-       if (is_gpio) {
-               is_output = get_direction(gpio);
-
-               snprintf(buf, bufsize, "%s: %d [%c]%s%s",
-                        is_output ? "out" : " in",
-                        is_output ?
-                               tegra_gpio_get_output_value(gpio) :
-                               tegra_gpio_get_value(dev, offset),
-                        *label ? 'x' : ' ',
-                        *label ? " " : "",
-                        label);
-       } else {
-               snprintf(buf, bufsize, "sfpio");
-       }
-
-       return 0;
-}
-
 static const struct dm_gpio_ops gpio_tegra_ops = {
        .request                = tegra_gpio_request,
-       .free                   = tegra_gpio_free,
        .direction_input        = tegra_gpio_direction_input,
        .direction_output       = tegra_gpio_direction_output,
        .get_value              = tegra_gpio_get_value,
        .set_value              = tegra_gpio_set_value,
        .get_function           = tegra_gpio_get_function,
-       .get_state              = tegra_gpio_get_state,
 };
 
 /**
index c891ebd39e243ebc5540e7db6291ed88f7e84678..e085a7095eaf55ef62bc9c47283bcfe20636740a 100644 (file)
@@ -8,6 +8,7 @@
 #include <common.h>
 #include <asm/io.h>
 #include "designware_i2c.h"
+#include <i2c.h>
 
 #ifdef CONFIG_I2C_MULTI_BUS
 static unsigned int bus_initialized[CONFIG_SYS_I2C_BUS_MAX];
@@ -76,16 +77,20 @@ static void set_speed(int i2c_spd)
  *
  * Set the i2c speed.
  */
-int i2c_set_bus_speed(int speed)
+int i2c_set_bus_speed(unsigned int speed)
 {
+       int i2c_spd;
+
        if (speed >= I2C_MAX_SPEED)
-               set_speed(IC_SPEED_MODE_MAX);
+               i2c_spd = IC_SPEED_MODE_MAX;
        else if (speed >= I2C_FAST_SPEED)
-               set_speed(IC_SPEED_MODE_FAST);
+               i2c_spd = IC_SPEED_MODE_FAST;
        else
-               set_speed(IC_SPEED_MODE_STANDARD);
+               i2c_spd = IC_SPEED_MODE_STANDARD;
 
-       return 0;
+       set_speed(i2c_spd);
+
+       return i2c_spd;
 }
 
 /*
@@ -93,7 +98,7 @@ int i2c_set_bus_speed(int speed)
  *
  * Gets the i2c speed.
  */
-int i2c_get_bus_speed(void)
+unsigned int i2c_get_bus_speed(void)
 {
        u32 cntl;
 
@@ -429,7 +434,7 @@ int i2c_set_bus_num(unsigned int bus)
        return 0;
 }
 
-int i2c_get_bus_num(void)
+unsigned int i2c_get_bus_num(void)
 {
        return current_bus;
 }
index ab3ffa0fc1535b89101f40877b5e4355b69ea1f2..9b2ca1e81ba33a7f94e539a020336015b30592fa 100644 (file)
@@ -20,8 +20,8 @@
 
 #if defined(CONFIG_ORION5X)
 #include <asm/arch/orion5x.h>
-#elif defined(CONFIG_KIRKWOOD)
-#include <asm/arch/kirkwood.h>
+#elif (defined(CONFIG_KIRKWOOD) || defined(CONFIG_ARMADA_XP))
+#include <asm/arch/soc.h>
 #elif defined(CONFIG_SUNXI)
 #include <asm/arch/i2c.h>
 #else
index 257b72f0f7cdf71b40afc10a2d18a9d48fdf700d..562211e7deb6504b65a0a3a088ea7572e5cc93b0 100644 (file)
@@ -471,8 +471,8 @@ static void tegra_i2c_init(struct i2c_adapter *adap, int speed, int slaveaddr)
 }
 
 /* i2c write version without the register address */
-int i2c_write_data(struct i2c_bus *bus, uchar chip, uchar *buffer, int len,
-                  bool end_with_repeated_start)
+static int i2c_write_data(struct i2c_bus *bus, uchar chip, uchar *buffer,
+                         int len, bool end_with_repeated_start)
 {
        int rc;
 
@@ -493,7 +493,8 @@ int i2c_write_data(struct i2c_bus *bus, uchar chip, uchar *buffer, int len,
 }
 
 /* i2c read version without the register address */
-int i2c_read_data(struct i2c_bus *bus, uchar chip, uchar *buffer, int len)
+static int i2c_read_data(struct i2c_bus *bus, uchar chip, uchar *buffer,
+                               int len)
 {
        int rc;
 
index 7e36db0a71a0b74ffbf2ff4b3fedd1ac99718241..0ef94f7a00bb26c72bfb2d07b60f63dc9030d77b 100644 (file)
@@ -181,7 +181,7 @@ static void kbd_wait_for_fifo_init(struct keyb *config)
  * @param input                Input configuration
  * @return 1, to indicate that we have something to look at
  */
-int tegra_kbc_check(struct input_config *input)
+static int tegra_kbc_check(struct input_config *input)
 {
        kbd_wait_for_fifo_init(&config);
        check_for_keys(&config);
index 068373b94263a999098d6af4d6d7038b0a4c7995..521edfd5de5cf5698ff98c1627e30703c3649282 100644 (file)
@@ -16,6 +16,7 @@
 
 #include <common.h>
 #include <command.h>
+#include <dm.h>
 #include <i2c.h>
 #include <cros_ec.h>
 #include <fdtdec.h>
@@ -24,6 +25,8 @@
 #include <asm/errno.h>
 #include <asm/io.h>
 #include <asm-generic/gpio.h>
+#include <dm/device-internal.h>
+#include <dm/uclass-internal.h>
 
 #ifdef DEBUG_TRACE
 #define debug_trace(fmt, b...) debug(fmt, #b)
@@ -38,7 +41,9 @@ enum {
        CROS_EC_CMD_HASH_TIMEOUT_MS = 2000,
 };
 
+#ifndef CONFIG_DM_CROS_EC
 static struct cros_ec_dev static_dev, *last_dev;
+#endif
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -204,6 +209,9 @@ static int send_command_proto3(struct cros_ec_dev *dev,
                               const void *dout, int dout_len,
                               uint8_t **dinp, int din_len)
 {
+#ifdef CONFIG_DM_CROS_EC
+       struct dm_cros_ec_ops *ops;
+#endif
        int out_bytes, in_bytes;
        int rv;
 
@@ -218,6 +226,10 @@ static int send_command_proto3(struct cros_ec_dev *dev,
        if (in_bytes < 0)
                return in_bytes;
 
+#ifdef CONFIG_DM_CROS_EC
+       ops = dm_cros_ec_get_ops(dev->dev);
+       rv = ops->packet(dev->dev, out_bytes, in_bytes);
+#else
        switch (dev->interface) {
 #ifdef CONFIG_CROS_EC_SPI
        case CROS_EC_IF_SPI:
@@ -235,6 +247,7 @@ static int send_command_proto3(struct cros_ec_dev *dev,
                debug("%s: Unsupported interface\n", __func__);
                rv = -1;
        }
+#endif
        if (rv < 0)
                return rv;
 
@@ -246,6 +259,9 @@ static int send_command(struct cros_ec_dev *dev, uint8_t cmd, int cmd_version,
                        const void *dout, int dout_len,
                        uint8_t **dinp, int din_len)
 {
+#ifdef CONFIG_DM_CROS_EC
+       struct dm_cros_ec_ops *ops;
+#endif
        int ret = -1;
 
        /* Handle protocol version 3 support */
@@ -254,6 +270,11 @@ static int send_command(struct cros_ec_dev *dev, uint8_t cmd, int cmd_version,
                                           dout, dout_len, dinp, din_len);
        }
 
+#ifdef CONFIG_DM_CROS_EC
+       ops = dm_cros_ec_get_ops(dev->dev);
+       ret = ops->command(dev->dev, cmd, cmd_version,
+                          (const uint8_t *)dout, dout_len, dinp, din_len);
+#else
        switch (dev->interface) {
 #ifdef CONFIG_CROS_EC_SPI
        case CROS_EC_IF_SPI:
@@ -280,6 +301,7 @@ static int send_command(struct cros_ec_dev *dev, uint8_t cmd, int cmd_version,
        default:
                ret = -1;
        }
+#endif
 
        return ret;
 }
@@ -990,6 +1012,7 @@ int cros_ec_get_ldo(struct cros_ec_dev *dev, uint8_t index, uint8_t *state)
        return 0;
 }
 
+#ifndef CONFIG_DM_CROS_EC
 /**
  * Decode EC interface details from the device tree and allocate a suitable
  * device.
@@ -1055,11 +1078,61 @@ static int cros_ec_decode_fdt(const void *blob, int node,
 
        return 0;
 }
+#endif
 
-int cros_ec_init(const void *blob, struct cros_ec_dev **cros_ecp)
+#ifdef CONFIG_DM_CROS_EC
+int cros_ec_register(struct udevice *dev)
 {
+       struct cros_ec_dev *cdev = dev->uclass_priv;
+       const void *blob = gd->fdt_blob;
+       int node = dev->of_offset;
        char id[MSG_BYTES];
+
+       cdev->dev = dev;
+       fdtdec_decode_gpio(blob, node, "ec-interrupt", &cdev->ec_int);
+       cdev->optimise_flash_write = fdtdec_get_bool(blob, node,
+                                                    "optimise-flash-write");
+
+       /* we will poll the EC interrupt line */
+       fdtdec_setup_gpio(&cdev->ec_int);
+       if (fdt_gpio_isvalid(&cdev->ec_int)) {
+               gpio_request(cdev->ec_int.gpio, "cros-ec-irq");
+               gpio_direction_input(cdev->ec_int.gpio);
+       }
+
+       if (cros_ec_check_version(cdev)) {
+               debug("%s: Could not detect CROS-EC version\n", __func__);
+               return -CROS_EC_ERR_CHECK_VERSION;
+       }
+
+       if (cros_ec_read_id(cdev, id, sizeof(id))) {
+               debug("%s: Could not read KBC ID\n", __func__);
+               return -CROS_EC_ERR_READ_ID;
+       }
+
+       /* Remember this device for use by the cros_ec command */
+       debug("Google Chrome EC CROS-EC driver ready, id '%s'\n", id);
+
+       return 0;
+}
+#else
+int cros_ec_init(const void *blob, struct cros_ec_dev **cros_ecp)
+{
        struct cros_ec_dev *dev;
+       char id[MSG_BYTES];
+#ifdef CONFIG_DM_CROS_EC
+       struct udevice *udev;
+       int ret;
+
+       ret = uclass_find_device(UCLASS_CROS_EC, 0, &udev);
+       if (!ret)
+               device_remove(udev);
+       ret = uclass_get_device(UCLASS_CROS_EC, 0, &udev);
+       if (ret)
+               return ret;
+       dev = udev->uclass_priv;
+       return 0;
+#else
        int node = 0;
 
        *cros_ecp = NULL;
@@ -1108,11 +1181,14 @@ int cros_ec_init(const void *blob, struct cros_ec_dev **cros_ecp)
        default:
                return 0;
        }
+#endif
 
        /* we will poll the EC interrupt line */
        fdtdec_setup_gpio(&dev->ec_int);
-       if (fdt_gpio_isvalid(&dev->ec_int))
+       if (fdt_gpio_isvalid(&dev->ec_int)) {
+               gpio_request(dev->ec_int.gpio, "cros-ec-irq");
                gpio_direction_input(dev->ec_int.gpio);
+       }
 
        if (cros_ec_check_version(dev)) {
                debug("%s: Could not detect CROS-EC version\n", __func__);
@@ -1125,11 +1201,15 @@ int cros_ec_init(const void *blob, struct cros_ec_dev **cros_ecp)
        }
 
        /* Remember this device for use by the cros_ec command */
-       last_dev = *cros_ecp = dev;
+       *cros_ecp = dev;
+#ifndef CONFIG_DM_CROS_EC
+       last_dev = dev;
+#endif
        debug("Google Chrome EC CROS-EC driver ready, id '%s'\n", id);
 
        return 0;
 }
+#endif
 
 int cros_ec_decode_region(int argc, char * const argv[])
 {
@@ -1147,15 +1227,10 @@ int cros_ec_decode_region(int argc, char * const argv[])
        return -1;
 }
 
-int cros_ec_decode_ec_flash(const void *blob, struct fdt_cros_ec *config)
+int cros_ec_decode_ec_flash(const void *blob, int node,
+                           struct fdt_cros_ec *config)
 {
-       int flash_node, node;
-
-       node = fdtdec_next_compatible(blob, 0, COMPAT_GOOGLE_CROS_EC);
-       if (node < 0) {
-               debug("Failed to find chrome-ec node'\n");
-               return -1;
-       }
+       int flash_node;
 
        flash_node = fdt_subnode_offset(blob, node, "flash");
        if (flash_node < 0) {
@@ -1516,7 +1591,10 @@ static int cros_ec_i2c_passthrough(struct cros_ec_dev *dev, int flag,
 
 static int do_cros_ec(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
-       struct cros_ec_dev *dev = last_dev;
+       struct cros_ec_dev *dev;
+#ifdef CONFIG_DM_CROS_EC
+       struct udevice *udev;
+#endif
        const char *cmd;
        int ret = 0;
 
@@ -1525,19 +1603,31 @@ static int do_cros_ec(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 
        cmd = argv[1];
        if (0 == strcmp("init", cmd)) {
+#ifndef CONFIG_DM_CROS_EC
                ret = cros_ec_init(gd->fdt_blob, &dev);
                if (ret) {
                        printf("Could not init cros_ec device (err %d)\n", ret);
                        return 1;
                }
+#endif
                return 0;
        }
 
+#ifdef CONFIG_DM_CROS_EC
+       ret = uclass_get_device(UCLASS_CROS_EC, 0, &udev);
+       if (ret) {
+               printf("Cannot get cros-ec device (err=%d)\n", ret);
+               return 1;
+       }
+       dev = udev->uclass_priv;
+#else
        /* Just use the last allocated device; there should be only one */
        if (!last_dev) {
                printf("No CROS-EC device available\n");
                return 1;
        }
+       dev = last_dev;
+#endif
        if (0 == strcmp("id", cmd)) {
                char id[MSG_BYTES];
 
@@ -1794,3 +1884,11 @@ U_BOOT_CMD(
        "crosec i2c mw chip address[.0, .1, .2] value [count] - write to I2C passthru (fill)"
 );
 #endif
+
+#ifdef CONFIG_DM_CROS_EC
+UCLASS_DRIVER(cros_ec) = {
+       .id             = UCLASS_CROS_EC,
+       .name           = "cros_ec",
+       .per_device_auto_alloc_size = sizeof(struct cros_ec_dev),
+};
+#endif
index 0e02671c93d46652864d9e83bf4a7d3d9f658e2e..07624a136fa47def2c330ae229c25a1cd822a3dc 100644 (file)
@@ -54,7 +54,7 @@ int cros_ec_lpc_command(struct cros_ec_dev *dev, uint8_t cmd, int cmd_version,
        int csum;
        int i;
 
-       if (dout_len > EC_HOST_PARAM_SIZE) {
+       if (dout_len > EC_PROTO2_MAX_PARAM_SIZE) {
                debug("%s: Cannot send %d bytes\n", __func__, dout_len);
                return -1;
        }
@@ -159,7 +159,7 @@ int cros_ec_lpc_init(struct cros_ec_dev *dev, const void *blob)
        byte = 0xff;
        byte &= inb(EC_LPC_ADDR_HOST_CMD);
        byte &= inb(EC_LPC_ADDR_HOST_DATA);
-       for (i = 0; i < EC_HOST_PARAM_SIZE && (byte == 0xff); i++)
+       for (i = 0; i < EC_PROTO2_MAX_PARAM_SIZE && (byte == 0xff); i++)
                byte &= inb(EC_LPC_ADDR_HOST_PARAM + i);
        if (byte == 0xff) {
                debug("%s: CROS_EC device not found on LPC bus\n",
index 8a04af557d035e6211865e4f2e1662d105d4447d..99cc5297cfb866acddd6495c088b681171d2c8f1 100644 (file)
@@ -8,6 +8,7 @@
 
 #include <common.h>
 #include <cros_ec.h>
+#include <dm.h>
 #include <ec_commands.h>
 #include <errno.h>
 #include <hash.h>
@@ -85,7 +86,7 @@ struct ec_state {
        struct ec_keymatrix_entry *matrix;      /* the key matrix info */
        uint8_t keyscan[KEYBOARD_COLS];
        bool recovery_req;
-} s_state, *state;
+} s_state, *g_state;
 
 /**
  * cros_ec_read_state() - read the sandbox EC state from the state file
@@ -138,7 +139,7 @@ static int cros_ec_read_state(const void *blob, int node)
  */
 static int cros_ec_write_state(void *blob, int node)
 {
-       struct ec_state *ec = &s_state;
+       struct ec_state *ec = g_state;
 
        /* We are guaranteed enough space to write basic properties */
        fdt_setprop_u32(blob, node, "current-image", ec->current_image);
@@ -369,7 +370,7 @@ static int process_cmd(struct ec_state *ec,
                struct fmap_entry *entry;
                int ret, size;
 
-               entry = &state->ec_config.region[EC_FLASH_REGION_RW];
+               entry = &ec->ec_config.region[EC_FLASH_REGION_RW];
 
                switch (req->cmd) {
                case EC_VBOOT_HASH_RECALC:
@@ -426,7 +427,7 @@ static int process_cmd(struct ec_state *ec,
                case EC_FLASH_REGION_RO:
                case EC_FLASH_REGION_RW:
                case EC_FLASH_REGION_WP_RO:
-                       entry = &state->ec_config.region[req->region];
+                       entry = &ec->ec_config.region[req->region];
                        resp->offset = entry->offset;
                        resp->size = entry->length;
                        len = sizeof(*resp);
@@ -466,16 +467,24 @@ static int process_cmd(struct ec_state *ec,
        return len;
 }
 
+#ifdef CONFIG_DM_CROS_EC
+int cros_ec_sandbox_packet(struct udevice *udev, int out_bytes, int in_bytes)
+{
+       struct cros_ec_dev *dev = udev->uclass_priv;
+       struct ec_state *ec = dev_get_priv(dev->dev);
+#else
 int cros_ec_sandbox_packet(struct cros_ec_dev *dev, int out_bytes,
                           int in_bytes)
 {
+       struct ec_state *ec = &s_state;
+#endif
        struct ec_host_request *req_hdr = (struct ec_host_request *)dev->dout;
        const void *req_data = req_hdr + 1;
        struct ec_host_response *resp_hdr = (struct ec_host_response *)dev->din;
        void *resp_data = resp_hdr + 1;
        int len;
 
-       len = process_cmd(&s_state, req_hdr, req_data, resp_hdr, resp_data);
+       len = process_cmd(ec, req_hdr, req_data, resp_hdr, resp_data);
        if (len < 0)
                return len;
 
@@ -498,7 +507,11 @@ int cros_ec_sandbox_decode_fdt(struct cros_ec_dev *dev, const void *blob)
 
 void cros_ec_check_keyboard(struct cros_ec_dev *dev)
 {
+#ifdef CONFIG_DM_CROS_EC
+       struct ec_state *ec = dev_get_priv(dev->dev);
+#else
        struct ec_state *ec = &s_state;
+#endif
        ulong start;
 
        printf("Press keys for EC to detect on reset (ESC=recovery)...");
@@ -512,6 +525,52 @@ void cros_ec_check_keyboard(struct cros_ec_dev *dev)
        }
 }
 
+#ifdef CONFIG_DM_CROS_EC
+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;
+       int node;
+       int err;
+
+       memcpy(ec, &s_state, sizeof(*ec));
+       err = cros_ec_decode_ec_flash(blob, dev->of_offset, &ec->ec_config);
+       if (err)
+               return err;
+
+       node = fdtdec_next_compatible(blob, 0, COMPAT_GOOGLE_CROS_EC_KEYB);
+       if (node < 0) {
+               debug("%s: No cros_ec keyboard found\n", __func__);
+       } else if (keyscan_read_fdt_matrix(ec, blob, node)) {
+               debug("%s: Could not read key matrix\n", __func__);
+               return -1;
+       }
+
+       /* If we loaded EC data, check that the length matches */
+       if (ec->flash_data &&
+           ec->flash_data_len != ec->ec_config.flash.length) {
+               printf("EC data length is %x, expected %x, discarding data\n",
+                      ec->flash_data_len, ec->ec_config.flash.length);
+               os_free(ec->flash_data);
+               ec->flash_data = NULL;
+       }
+
+       /* Otherwise allocate the memory */
+       if (!ec->flash_data) {
+               ec->flash_data_len = ec->ec_config.flash.length;
+               ec->flash_data = os_malloc(ec->flash_data_len);
+               if (!ec->flash_data)
+                       return -ENOMEM;
+       }
+
+       cdev->dev = dev;
+       g_state = ec;
+       return cros_ec_register(dev);
+}
+
+#else
+
 /**
  * Initialize sandbox EC emulation.
  *
@@ -525,8 +584,13 @@ int cros_ec_sandbox_init(struct cros_ec_dev *dev, const void *blob)
        int node;
        int err;
 
-       state = &s_state;
-       err = cros_ec_decode_ec_flash(blob, &ec->ec_config);
+       node = fdtdec_next_compatible(blob, 0, COMPAT_GOOGLE_CROS_EC);
+       if (node < 0) {
+               debug("Failed to find chrome-ec node'\n");
+               return -1;
+       }
+
+       err = cros_ec_decode_ec_flash(blob, node, &ec->ec_config);
        if (err)
                return err;
 
@@ -557,3 +621,24 @@ int cros_ec_sandbox_init(struct cros_ec_dev *dev, const void *blob)
 
        return 0;
 }
+#endif
+
+#ifdef CONFIG_DM_CROS_EC
+struct dm_cros_ec_ops cros_ec_ops = {
+       .packet = cros_ec_sandbox_packet,
+};
+
+static const struct udevice_id cros_ec_ids[] = {
+       { .compatible = "google,cros-ec" },
+       { }
+};
+
+U_BOOT_DRIVER(cros_ec_sandbox) = {
+       .name           = "cros_ec",
+       .id             = UCLASS_CROS_EC,
+       .of_match       = cros_ec_ids,
+       .probe          = cros_ec_probe,
+       .priv_auto_alloc_size = sizeof(struct ec_state),
+       .ops            = &cros_ec_ops,
+};
+#endif
index 015333f139a209fd686a4ac173aba02baeeb1b33..e403664bb561755184c60e9020e028b84169d40f 100644 (file)
 
 #include <common.h>
 #include <cros_ec.h>
+#include <dm.h>
+#include <errno.h>
 #include <spi.h>
 
+DECLARE_GLOBAL_DATA_PTR;
+
+#ifdef CONFIG_DM_CROS_EC
+int cros_ec_spi_packet(struct udevice *udev, int out_bytes, int in_bytes)
+{
+       struct cros_ec_dev *dev = udev->uclass_priv;
+#else
 int cros_ec_spi_packet(struct cros_ec_dev *dev, int out_bytes, int in_bytes)
 {
+#endif
+       struct spi_slave *slave = dev_get_parentdata(dev->dev);
        int rv;
 
        /* Do the transfer */
-       if (spi_claim_bus(dev->spi)) {
+       if (spi_claim_bus(slave)) {
                debug("%s: Cannot claim SPI bus\n", __func__);
                return -1;
        }
 
-       rv = spi_xfer(dev->spi, max(out_bytes, in_bytes) * 8,
+       rv = spi_xfer(slave, max(out_bytes, in_bytes) * 8,
                      dev->dout, dev->din,
                      SPI_XFER_BEGIN | SPI_XFER_END);
 
-       spi_release_bus(dev->spi);
+       spi_release_bus(slave);
 
        if (rv) {
                debug("%s: Cannot complete SPI transfer\n", __func__);
@@ -56,10 +67,19 @@ int cros_ec_spi_packet(struct cros_ec_dev *dev, int out_bytes, int in_bytes)
  * @param din_len      Maximum size of response in bytes
  * @return number of bytes in response, or -1 on error
  */
+#ifdef CONFIG_DM_CROS_EC
+int cros_ec_spi_command(struct udevice *udev, uint8_t cmd, int cmd_version,
+                    const uint8_t *dout, int dout_len,
+                    uint8_t **dinp, int din_len)
+{
+       struct cros_ec_dev *dev = udev->uclass_priv;
+#else
 int cros_ec_spi_command(struct cros_ec_dev *dev, uint8_t cmd, int cmd_version,
                     const uint8_t *dout, int dout_len,
                     uint8_t **dinp, int din_len)
 {
+#endif
+       struct spi_slave *slave = dev_get_parentdata(dev->dev);
        int in_bytes = din_len + 4;     /* status, length, checksum, trailer */
        uint8_t *out;
        uint8_t *p;
@@ -92,7 +112,7 @@ int cros_ec_spi_command(struct cros_ec_dev *dev, uint8_t cmd, int cmd_version,
         */
        memset(dev->din, '\0', in_bytes);
 
-       if (spi_claim_bus(dev->spi)) {
+       if (spi_claim_bus(slave)) {
                debug("%s: Cannot claim SPI bus\n", __func__);
                return -1;
        }
@@ -113,10 +133,10 @@ int cros_ec_spi_command(struct cros_ec_dev *dev, uint8_t cmd, int cmd_version,
        p = dev->din + sizeof(int64_t) - 2;
        len = dout_len + 4;
        cros_ec_dump_data("out", cmd, out, len);
-       rv = spi_xfer(dev->spi, max(len, in_bytes) * 8, out, p,
+       rv = spi_xfer(slave, max(len, in_bytes) * 8, out, p,
                      SPI_XFER_BEGIN | SPI_XFER_END);
 
-       spi_release_bus(dev->spi);
+       spi_release_bus(slave);
 
        if (rv) {
                debug("%s: Cannot complete SPI transfer\n", __func__);
@@ -146,6 +166,7 @@ int cros_ec_spi_command(struct cros_ec_dev *dev, uint8_t cmd, int cmd_version,
        return len;
 }
 
+#ifndef CONFIG_DM_CROS_EC
 int cros_ec_spi_decode_fdt(struct cros_ec_dev *dev, const void *blob)
 {
        /* Decode interface-specific FDT params */
@@ -165,11 +186,59 @@ int cros_ec_spi_decode_fdt(struct cros_ec_dev *dev, const void *blob)
  */
 int cros_ec_spi_init(struct cros_ec_dev *dev, const void *blob)
 {
-       dev->spi = spi_setup_slave_fdt(blob, dev->node, dev->parent_node);
-       if (!dev->spi) {
+       int ret;
+
+       ret = spi_setup_slave_fdt(blob, dev->node, dev->parent_node,
+                                 &slave);
+       if (ret) {
                debug("%s: Could not setup SPI slave\n", __func__);
-               return -1;
+               return ret;
        }
 
        return 0;
 }
+#endif
+
+#ifdef CONFIG_DM_CROS_EC
+int cros_ec_probe(struct udevice *dev)
+{
+       struct spi_slave *slave = dev_get_parentdata(dev);
+       int ret;
+
+       /*
+        * TODO(sjg@chromium.org)
+        *
+        * This is really horrible at present. It is an artifact of removing
+        * the child_pre_probe() method for SPI. Everything here could go in
+        * an automatic function, except that spi_get_bus_and_cs() wants to
+        * set it up manually and call device_probe_child().
+        *
+        * The solution may be to re-enable the child_pre_probe() method for
+        * SPI and have it do nothing if the child is already passed in via
+        * device_probe_child().
+        */
+       slave->dev = dev;
+       ret = spi_ofdata_to_platdata(gd->fdt_blob, dev->of_offset, slave);
+       if (ret)
+               return ret;
+       return cros_ec_register(dev);
+}
+
+struct dm_cros_ec_ops cros_ec_ops = {
+       .packet = cros_ec_spi_packet,
+       .command = cros_ec_spi_command,
+};
+
+static const struct udevice_id cros_ec_ids[] = {
+       { .compatible = "google,cros-ec" },
+       { }
+};
+
+U_BOOT_DRIVER(cros_ec_spi) = {
+       .name           = "cros_ec",
+       .id             = UCLASS_CROS_EC,
+       .of_match       = cros_ec_ids,
+       .probe          = cros_ec_probe,
+       .ops            = &cros_ec_ops,
+};
+#endif
index 82079d67cd8fc07565e5b8c57cc7e7c8234793b7..92f7d8942f02d1420e397664afcb99b938a3dafc 100644 (file)
@@ -40,6 +40,7 @@
 #include <malloc.h>
 #include <sdhci.h>
 #include <asm/arch/timer.h>
+#include <asm/arch-bcm2835/sdhci.h>
 
 /* 400KHz is max freq for card ID etc. Use that as min */
 #define MIN_FREQ 400000
index d34e74357f0a4e74055f0280e969b6eda6add4c6..9f98c3f37c9790858a873b90fdcf27845fce15bc 100644 (file)
@@ -14,7 +14,7 @@
 #include <mmc.h>
 #include <asm/io.h>
 #include <asm/arch/cpu.h>
-#include <asm/arch/kirkwood.h>
+#include <asm/arch/soc.h>
 #include <mvebu_mmc.h>
 
 DECLARE_GLOBAL_DATA_PTR;
index 5b0c3020693c325a396b6726fd01d920776122f3..ef2cbf9e2fa574cd2846c280149cca2cf1dbc28b 100644 (file)
@@ -67,14 +67,19 @@ static int mmc_write_data(struct hsmmc *mmc_base, const char *buf,
 #ifdef OMAP_HSMMC_USE_GPIO
 static int omap_mmc_setup_gpio_in(int gpio, const char *label)
 {
-       if (!gpio_is_valid(gpio))
-               return -1;
+       int ret;
 
-       if (gpio_request(gpio, label) < 0)
+#ifndef CONFIG_DM_GPIO
+       if (!gpio_is_valid(gpio))
                return -1;
+#endif
+       ret = gpio_request(gpio, label);
+       if (ret)
+               return ret;
 
-       if (gpio_direction_input(gpio) < 0)
-               return -1;
+       ret = gpio_direction_input(gpio);
+       if (ret)
+               return ret;
 
        return gpio;
 }
index 637dd972a5b3612d74b0ec3b6924f9f8544aa344..0dea45d079f33e9c4f8b3b55288d7f508e4abc2d 100644 (file)
@@ -102,6 +102,7 @@ struct sdhci_host sdhci_host[SDHCI_MAX_HOSTS];
 
 static int do_sdhci_init(struct sdhci_host *host)
 {
+       char str[20];
        int dev_id, flag;
        int err = 0;
 
@@ -109,6 +110,8 @@ static int do_sdhci_init(struct sdhci_host *host)
        dev_id = host->index + PERIPH_ID_SDMMC0;
 
        if (fdt_gpio_isvalid(&host->pwr_gpio)) {
+               sprintf(str, "sdhci%d_power", host->index & 0xf);
+               gpio_request(host->pwr_gpio.gpio, str);
                gpio_direction_output(host->pwr_gpio.gpio, 1);
                err = exynos_pinmux_config(dev_id, flag);
                if (err) {
@@ -118,7 +121,9 @@ static int do_sdhci_init(struct sdhci_host *host)
        }
 
        if (fdt_gpio_isvalid(&host->cd_gpio)) {
-               gpio_direction_output(host->cd_gpio.gpio, 0xf);
+               sprintf(str, "sdhci%d_cd", host->index & 0xf);
+               gpio_request(host->cd_gpio.gpio, str);
+               gpio_direction_output(host->cd_gpio.gpio, 1);
                if (gpio_get_value(host->cd_gpio.gpio))
                        return -ENODEV;
 
index 3125d13ba3ce8e8e2552248e41c059bd31e5fb3c..de88e19609f37aaba48665e9bff60f6a7b63f31b 100644 (file)
@@ -124,7 +124,7 @@ static int sdhci_transfer_data(struct sdhci_host *host, struct mmc_data *data,
 #endif
 #define CONFIG_SDHCI_CMD_DEFAULT_TIMEOUT       100
 
-int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd,
+static int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd,
                       struct mmc_data *data)
 {
        struct sdhci_host *host = mmc->priv;
@@ -355,7 +355,7 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned short power)
        sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL);
 }
 
-void sdhci_set_ios(struct mmc *mmc)
+static void sdhci_set_ios(struct mmc *mmc)
 {
        u32 ctrl;
        struct sdhci_host *host = mmc->priv;
@@ -393,7 +393,7 @@ void sdhci_set_ios(struct mmc *mmc)
        sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
 }
 
-int sdhci_init(struct mmc *mmc)
+static int sdhci_init(struct mmc *mmc)
 {
        struct sdhci_host *host = mmc->priv;
 
index d4e574fe191b0e8edd587b733be4b9cf5ec6ee24..16592e3d7cf2454e00013181576dcb0ea437822e 100644 (file)
 #include <asm/io.h>
 #include <asm/arch/clock.h>
 #include <asm/arch/cpu.h>
+#include <asm/arch/gpio.h>
 #include <asm/arch/mmc.h>
+#include <asm-generic/gpio.h>
 
 struct sunxi_mmc_host {
        unsigned mmc_no;
        uint32_t *mclkreg;
-       unsigned database;
        unsigned fatal_err;
        unsigned mod_clk;
        struct sunxi_mmc *reg;
@@ -57,7 +58,6 @@ static int mmc_resource_init(int sdc_no)
                printf("Wrong mmc number %d\n", sdc_no);
                return -1;
        }
-       mmchost->database = (unsigned int)mmchost->reg + 0x100;
        mmchost->mmc_no = sdc_no;
 
        return 0;
@@ -75,6 +75,11 @@ static int mmc_clk_io_on(int sdc_no)
        /* config ahb clock */
        setbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_MMC(sdc_no));
 
+#if defined(CONFIG_SUN6I) || defined(CONFIG_SUN8I)
+       /* unassert reset */
+       setbits_le32(&ccm->ahb_reset0_cfg, 1 << AHB_RESET_OFFSET_MMC(sdc_no));
+#endif
+
        /* config mod clock */
        pll_clk = clock_get_pll6();
        /* should be close to 100 MHz but no more, so round up */
@@ -194,9 +199,9 @@ static int mmc_trans_data_by_cpu(struct mmc *mmc, struct mmc_data *data)
                }
 
                if (reading)
-                       buff[i] = readl(mmchost->database);
+                       buff[i] = readl(&mmchost->reg->fifo);
                else
-                       writel(buff[i], mmchost->database);
+                       writel(buff[i], &mmchost->reg->fifo);
        }
 
        return 0;
@@ -343,13 +348,32 @@ out:
        return error;
 }
 
+static int sunxi_mmc_getcd(struct mmc *mmc)
+{
+       struct sunxi_mmc_host *mmchost = mmc->priv;
+       int cd_pin = -1;
+
+       switch (mmchost->mmc_no) {
+       case 0: cd_pin = sunxi_name_to_gpio(CONFIG_MMC0_CD_PIN); break;
+       case 1: cd_pin = sunxi_name_to_gpio(CONFIG_MMC1_CD_PIN); break;
+       case 2: cd_pin = sunxi_name_to_gpio(CONFIG_MMC2_CD_PIN); break;
+       case 3: cd_pin = sunxi_name_to_gpio(CONFIG_MMC3_CD_PIN); break;
+       }
+
+       if (cd_pin == -1)
+               return 1;
+
+       return !gpio_direction_input(cd_pin);
+}
+
 static const struct mmc_ops sunxi_mmc_ops = {
        .send_cmd       = mmc_send_cmd,
        .set_ios        = mmc_set_ios,
        .init           = mmc_core_init,
+       .getcd          = sunxi_mmc_getcd,
 };
 
-int sunxi_mmc_init(int sdc_no)
+struct mmc *sunxi_mmc_init(int sdc_no)
 {
        struct mmc_config *cfg = &mmc_host[sdc_no].cfg;
 
@@ -361,6 +385,9 @@ int sunxi_mmc_init(int sdc_no)
        cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
        cfg->host_caps = MMC_MODE_4BIT;
        cfg->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
+#if defined(CONFIG_SUN6I) || defined(CONFIG_SUN7I) || defined(CONFIG_SUN8I)
+       cfg->host_caps |= MMC_MODE_HC;
+#endif
        cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
 
        cfg->f_min = 400000;
@@ -369,8 +396,5 @@ int sunxi_mmc_init(int sdc_no)
        mmc_resource_init(sdc_no);
        mmc_clk_io_on(sdc_no);
 
-       if (mmc_create(cfg, &mmc_host[sdc_no]) == NULL)
-               return -1;
-
-       return 0;
+       return mmc_create(cfg, &mmc_host[sdc_no]);
 }
index ca9c4aa15feea77686f8d5e87b7f24bdb8e1be89..2bd36b0ee704a86308bfa0d3c7faa68cc506249a 100644 (file)
@@ -13,6 +13,7 @@
 #include <asm/io.h>
 #include <asm/arch/clock.h>
 #include <asm/arch-tegra/clk_rst.h>
+#include <asm/arch-tegra/mmc.h>
 #include <asm/arch-tegra/tegra_mmc.h>
 #include <mmc.h>
 
@@ -292,7 +293,7 @@ static int mmc_send_cmd_bounced(struct mmc *mmc, struct mmc_cmd *cmd,
                                /* Transfer Complete */
                                debug("r/w is done\n");
                                break;
-                       } else if (get_timer(start) > 2000UL) {
+                       } else if (get_timer(start) > 8000UL) {
                                writel(mask, &host->reg->norintsts);
                                printf("%s: MMC Timeout\n"
                                       "    Interrupt status        0x%08x\n"
@@ -508,7 +509,7 @@ static int tegra_mmc_core_init(struct mmc *mmc)
        return 0;
 }
 
-int tegra_mmc_getcd(struct mmc *mmc)
+static int tegra_mmc_getcd(struct mmc *mmc)
 {
        struct mmc_host *host = mmc->priv;
 
index 9b3175d87fbdabff14d922ce4c64d620b9aa60f4..50983b837b2238b781477f13b559502047b1ad6e 100644 (file)
@@ -63,6 +63,12 @@ flash_info_t flash_info[CFI_MAX_FLASH_BANKS];        /* FLASH chips info */
 #define CONFIG_SYS_FLASH_CFI_WIDTH     FLASH_CFI_8BIT
 #endif
 
+#ifdef CONFIG_CFI_FLASH_USE_WEAK_ACCESSORS
+#define __maybe_weak __weak
+#else
+#define __maybe_weak static
+#endif
+
 /*
  * 0xffff is an undefined value for the configuration register. When
  * this value is returned, the configuration register shall not be
@@ -81,14 +87,12 @@ static u16 cfi_flash_config_reg(int i)
 int cfi_flash_num_flash_banks = CONFIG_SYS_MAX_FLASH_BANKS_DETECT;
 #endif
 
-static phys_addr_t __cfi_flash_bank_addr(int i)
+__weak phys_addr_t cfi_flash_bank_addr(int i)
 {
        return ((phys_addr_t [])CONFIG_SYS_FLASH_BANKS_LIST)[i];
 }
-phys_addr_t cfi_flash_bank_addr(int i)
-       __attribute__((weak, alias("__cfi_flash_bank_addr")));
 
-static unsigned long __cfi_flash_bank_size(int i)
+__weak unsigned long cfi_flash_bank_size(int i)
 {
 #ifdef CONFIG_SYS_FLASH_BANKS_SIZES
        return ((unsigned long [])CONFIG_SYS_FLASH_BANKS_SIZES)[i];
@@ -96,71 +100,49 @@ static unsigned long __cfi_flash_bank_size(int i)
        return 0;
 #endif
 }
-unsigned long cfi_flash_bank_size(int i)
-       __attribute__((weak, alias("__cfi_flash_bank_size")));
 
-static void __flash_write8(u8 value, void *addr)
+__maybe_weak void flash_write8(u8 value, void *addr)
 {
        __raw_writeb(value, addr);
 }
 
-static void __flash_write16(u16 value, void *addr)
+__maybe_weak void flash_write16(u16 value, void *addr)
 {
        __raw_writew(value, addr);
 }
 
-static void __flash_write32(u32 value, void *addr)
+__maybe_weak void flash_write32(u32 value, void *addr)
 {
        __raw_writel(value, addr);
 }
 
-static void __flash_write64(u64 value, void *addr)
+__maybe_weak void flash_write64(u64 value, void *addr)
 {
        /* No architectures currently implement __raw_writeq() */
        *(volatile u64 *)addr = value;
 }
 
-static u8 __flash_read8(void *addr)
+__maybe_weak u8 flash_read8(void *addr)
 {
        return __raw_readb(addr);
 }
 
-static u16 __flash_read16(void *addr)
+__maybe_weak u16 flash_read16(void *addr)
 {
        return __raw_readw(addr);
 }
 
-static u32 __flash_read32(void *addr)
+__maybe_weak u32 flash_read32(void *addr)
 {
        return __raw_readl(addr);
 }
 
-static u64 __flash_read64(void *addr)
+__maybe_weak u64 flash_read64(void *addr)
 {
        /* No architectures currently implement __raw_readq() */
        return *(volatile u64 *)addr;
 }
 
-#ifdef CONFIG_CFI_FLASH_USE_WEAK_ACCESSORS
-void flash_write8(u8 value, void *addr)__attribute__((weak, alias("__flash_write8")));
-void flash_write16(u16 value, void *addr)__attribute__((weak, alias("__flash_write16")));
-void flash_write32(u32 value, void *addr)__attribute__((weak, alias("__flash_write32")));
-void flash_write64(u64 value, void *addr)__attribute__((weak, alias("__flash_write64")));
-u8 flash_read8(void *addr)__attribute__((weak, alias("__flash_read8")));
-u16 flash_read16(void *addr)__attribute__((weak, alias("__flash_read16")));
-u32 flash_read32(void *addr)__attribute__((weak, alias("__flash_read32")));
-u64 flash_read64(void *addr)__attribute__((weak, alias("__flash_read64")));
-#else
-#define flash_write8   __flash_write8
-#define flash_write16  __flash_write16
-#define flash_write32  __flash_write32
-#define flash_write64  __flash_write64
-#define flash_read8    __flash_read8
-#define flash_read16   __flash_read16
-#define flash_read32   __flash_read32
-#define flash_read64   __flash_read64
-#endif
-
 /*-----------------------------------------------------------------------
  */
 #if defined(CONFIG_ENV_IS_IN_FLASH) || defined(CONFIG_ENV_ADDR_REDUND) || (CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE)
index 3e5fb0cd65a243d77fe2759556bab0f9209beec1..4fc34d6b9fca6d7b41ff44f52912da85532d1b9b 100644 (file)
@@ -8,7 +8,7 @@
 
 #include <common.h>
 #include <asm/io.h>
-#include <asm/arch/kirkwood.h>
+#include <asm/arch/soc.h>
 #include <nand.h>
 
 /* NAND Flash Soc registers */
index db1599e9a641402e811c9e6172e35909098a0769..40d670563c1e447c172f075eabda3d304433f693 100644 (file)
@@ -75,7 +75,7 @@ static void omap_nand_hwcontrol(struct mtd_info *mtd, int32_t cmd,
 
 #ifdef CONFIG_SPL_BUILD
 /* Check wait pin as dev ready indicator */
-int omap_spl_dev_ready(struct mtd_info *mtd)
+static int omap_spl_dev_ready(struct mtd_info *mtd)
 {
        return gpmc_cfg->status & (1 << 8);
 }
@@ -161,23 +161,6 @@ static int __maybe_unused omap_correct_data(struct mtd_info *mtd, uint8_t *dat,
        return 0;
 }
 
-/*
- * omap_reverse_list - re-orders list elements in reverse order [internal]
- * @list:      pointer to start of list
- * @length:    length of list
-*/
-void omap_reverse_list(u8 *list, unsigned int length)
-{
-       unsigned int i, j;
-       unsigned int half_length = length / 2;
-       u8 tmp;
-       for (i = 0, j = length - 1; i < half_length; i++, j--) {
-               tmp = list[i];
-               list[i] = list[j];
-               list[j] = tmp;
-       }
-}
-
 /*
  * omap_enable_hwecc - configures GPMC as per ECC scheme before read/write
  * @mtd:       MTD device structure
@@ -350,6 +333,23 @@ static int omap_calculate_ecc(struct mtd_info *mtd, const uint8_t *dat,
 }
 
 #ifdef CONFIG_NAND_OMAP_ELM
+/*
+ * omap_reverse_list - re-orders list elements in reverse order [internal]
+ * @list:      pointer to start of list
+ * @length:    length of list
+*/
+static void omap_reverse_list(u8 *list, unsigned int length)
+{
+       unsigned int i, j;
+       unsigned int half_length = length / 2;
+       u8 tmp;
+       for (i = 0, j = length - 1; i < half_length; i++, j--) {
+               tmp = list[i];
+               list[i] = list[j];
+               list[j] = tmp;
+       }
+}
+
 /*
  * omap_correct_data_bch - Compares the ecc read from nand spare area
  * with ECC registers values and corrects one bit error if it has occured
index 9e18fb41de624b4684e19e435c5513525c38de5e..15789a07d8f674786e201581784a7ffb9c37bfed 100644 (file)
@@ -5,13 +5,18 @@
 # SPDX-License-Identifier:     GPL-2.0+
 #
 
+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
 endif
 
+#ifndef CONFIG_DM_SPI
+obj-$(CONFIG_SPI_FLASH) += sf_probe.o
+#endif
 obj-$(CONFIG_CMD_SF) += sf.o
-obj-$(CONFIG_SPI_FLASH) += sf_params.o sf_probe.o sf_ops.o
+obj-$(CONFIG_SPI_FLASH) += sf_ops.o sf_params.o
 obj-$(CONFIG_SPI_FRAM_RAMTRON) += ramtron.o
 obj-$(CONFIG_SPI_FLASH_SANDBOX) += sandbox.o
 obj-$(CONFIG_SPI_M95XXX) += eeprom_m95xxx.o
index d50da37c89af4418b5a6ad52c297007f6bb3dfc3..a23032cca58df0fdc2f304ce8aabaef253bd54fd 100644 (file)
@@ -35,6 +35,7 @@
 
 #include <common.h>
 #include <malloc.h>
+#include <spi.h>
 #include <spi_flash.h>
 #include "sf_internal.h"
 
index 98e0a34d4e3b2fa74017fff981b80f47d0736271..1cf2f98310a17493a5a99cce29caa652cb9aabd1 100644 (file)
@@ -9,6 +9,7 @@
  */
 
 #include <common.h>
+#include <dm.h>
 #include <malloc.h>
 #include <spi.h>
 #include <os.h>
 #include <asm/getopt.h>
 #include <asm/spi.h>
 #include <asm/state.h>
+#include <dm/device-internal.h>
+#include <dm/lists.h>
+#include <dm/uclass-internal.h>
+
+DECLARE_GLOBAL_DATA_PTR;
 
 /*
  * The different states that our SPI flash transitions between.
@@ -34,12 +40,14 @@ enum sandbox_sf_state {
        SF_ERASE, /* erase the flash */
        SF_READ_STATUS, /* read the flash's status register */
        SF_READ_STATUS1, /* read the flash's status register upper 8 bits*/
+       SF_WRITE_STATUS, /* write the flash's status register */
 };
 
 static const char *sandbox_sf_state_name(enum sandbox_sf_state state)
 {
        static const char * const states[] = {
                "CMD", "ID", "ADDR", "READ", "WRITE", "ERASE", "READ_STATUS",
+               "READ_STATUS1", "WRITE_STATUS",
        };
        return states[state];
 }
@@ -58,6 +66,7 @@ static u8 sandbox_sf_0xff[0x1000];
 
 /* Internal state data for each SPI flash */
 struct sandbox_spi_flash {
+       unsigned int cs;        /* Chip select we are attached to */
        /*
         * As we receive data over the SPI bus, our flash transitions
         * between states.  For example, we start off in the SF_CMD
@@ -84,71 +93,124 @@ struct sandbox_spi_flash {
        int fd;
 };
 
-static int sandbox_sf_setup(void **priv, const char *spec)
+struct sandbox_spi_flash_plat_data {
+       const char *filename;
+       const char *device_name;
+       int bus;
+       int cs;
+};
+
+/**
+ * This is a very strange probe function. If it has platform data (which may
+ * have come from the device tree) then this function gets the filename and
+ * device type from there. Failing that it looks at the command line
+ * parameter.
+ */
+static int sandbox_sf_probe(struct udevice *dev)
 {
        /* spec = idcode:file */
-       struct sandbox_spi_flash *sbsf;
+       struct sandbox_spi_flash *sbsf = dev_get_priv(dev);
        const char *file;
        size_t len, idname_len;
        const struct spi_flash_params *data;
-
-       file = strchr(spec, ':');
-       if (!file) {
-               printf("sandbox_sf: unable to parse file\n");
-               goto error;
+       struct sandbox_spi_flash_plat_data *pdata = dev_get_platdata(dev);
+       struct sandbox_state *state = state_get_current();
+       struct udevice *bus = dev->parent;
+       const char *spec = NULL;
+       int ret = 0;
+       int cs = -1;
+       int i;
+
+       debug("%s: bus %d, looking for emul=%p: ", __func__, bus->seq, dev);
+       if (bus->seq >= 0 && bus->seq < CONFIG_SANDBOX_SPI_MAX_BUS) {
+               for (i = 0; i < CONFIG_SANDBOX_SPI_MAX_CS; i++) {
+                       if (state->spi[bus->seq][i].emul == dev)
+                               cs = i;
+               }
+       }
+       if (cs == -1) {
+               printf("Error: Unknown chip select for device '%s'",
+                      dev->name);
+               return -EINVAL;
+       }
+       debug("found at cs %d\n", cs);
+
+       if (!pdata->filename) {
+               struct sandbox_state *state = state_get_current();
+
+               assert(bus->seq != -1);
+               if (bus->seq < CONFIG_SANDBOX_SPI_MAX_BUS)
+                       spec = state->spi[bus->seq][cs].spec;
+               if (!spec)
+                       return -ENOENT;
+
+               file = strchr(spec, ':');
+               if (!file) {
+                       printf("sandbox_sf: unable to parse file\n");
+                       ret = -EINVAL;
+                       goto error;
+               }
+               idname_len = file - spec;
+               pdata->filename = file + 1;
+               pdata->device_name = spec;
+               ++file;
+       } else {
+               spec = strchr(pdata->device_name, ',');
+               if (spec)
+                       spec++;
+               else
+                       spec = pdata->device_name;
+               idname_len = strlen(spec);
        }
-       idname_len = file - spec;
-       ++file;
+       debug("%s: device='%s'\n", __func__, spec);
 
        for (data = spi_flash_params_table; data->name; data++) {
                len = strlen(data->name);
                if (idname_len != len)
                        continue;
-               if (!memcmp(spec, data->name, len))
+               if (!strncasecmp(spec, data->name, len))
                        break;
        }
        if (!data->name) {
                printf("sandbox_sf: unknown flash '%*s'\n", (int)idname_len,
                       spec);
+               ret = -EINVAL;
                goto error;
        }
 
        if (sandbox_sf_0xff[0] == 0x00)
                memset(sandbox_sf_0xff, 0xff, sizeof(sandbox_sf_0xff));
 
-       sbsf = calloc(sizeof(*sbsf), 1);
-       if (!sbsf) {
-               printf("sandbox_sf: out of memory\n");
-               goto error;
-       }
-
-       sbsf->fd = os_open(file, 02);
+       sbsf->fd = os_open(pdata->filename, 02);
        if (sbsf->fd == -1) {
                free(sbsf);
-               printf("sandbox_sf: unable to open file '%s'\n", file);
+               printf("sandbox_sf: unable to open file '%s'\n",
+                      pdata->filename);
+               ret = -EIO;
                goto error;
        }
 
        sbsf->data = data;
+       sbsf->cs = cs;
 
-       *priv = sbsf;
        return 0;
 
  error:
-       return 1;
+       return ret;
 }
 
-static void sandbox_sf_free(void *priv)
+static int sandbox_sf_remove(struct udevice *dev)
 {
-       struct sandbox_spi_flash *sbsf = priv;
+       struct sandbox_spi_flash *sbsf = dev_get_priv(dev);
 
        os_close(sbsf->fd);
-       free(sbsf);
+
+       return 0;
 }
 
-static void sandbox_sf_cs_activate(void *priv)
+static void sandbox_sf_cs_activate(struct udevice *dev)
 {
-       struct sandbox_spi_flash *sbsf = priv;
+       struct sandbox_spi_flash *sbsf = dev_get_priv(dev);
 
        debug("sandbox_sf: CS activated; state is fresh!\n");
 
@@ -160,11 +222,24 @@ static void sandbox_sf_cs_activate(void *priv)
        sbsf->cmd = SF_CMD;
 }
 
-static void sandbox_sf_cs_deactivate(void *priv)
+static void sandbox_sf_cs_deactivate(struct udevice *dev)
 {
        debug("sandbox_sf: CS deactivated; cmd done processing!\n");
 }
 
+/*
+ * There are times when the data lines are allowed to tristate.  What
+ * is actually sensed on the line depends on the hardware.  It could
+ * always be 0xFF/0x00 (if there are pull ups/downs), or things could
+ * float and so we'd get garbage back.  This func encapsulates that
+ * scenario so we can worry about the details here.
+ */
+static void sandbox_spi_tristate(u8 *buf, uint len)
+{
+       /* XXX: make this into a user config option ? */
+       memset(buf, 0xff, len);
+}
+
 /* Figure out what command this stream is telling us to do */
 static int sandbox_sf_process_cmd(struct sandbox_spi_flash *sbsf, const u8 *rx,
                                  u8 *tx)
@@ -172,7 +247,8 @@ static int sandbox_sf_process_cmd(struct sandbox_spi_flash *sbsf, const u8 *rx,
        enum sandbox_sf_state oldstate = sbsf->state;
 
        /* We need to output a byte for the cmd byte we just ate */
-       sandbox_spi_tristate(tx, 1);
+       if (tx)
+               sandbox_spi_tristate(tx, 1);
 
        sbsf->cmd = rx[0];
        switch (sbsf->cmd) {
@@ -200,6 +276,9 @@ static int sandbox_sf_process_cmd(struct sandbox_spi_flash *sbsf, const u8 *rx,
                debug(" write enabled\n");
                sbsf->status |= STAT_WEL;
                break;
+       case CMD_WRITE_STATUS:
+               sbsf->state = SF_WRITE_STATUS;
+               break;
        default: {
                int flags = sbsf->data->flags;
 
@@ -216,7 +295,7 @@ static int sandbox_sf_process_cmd(struct sandbox_spi_flash *sbsf, const u8 *rx,
                        sbsf->erase_size = 64 << 10;
                } else {
                        debug(" cmd unknown: %#x\n", sbsf->cmd);
-                       return 1;
+                       return -EIO;
                }
                sbsf->state = SF_ADDR;
                break;
@@ -246,20 +325,27 @@ int sandbox_erase_part(struct sandbox_spi_flash *sbsf, int size)
        return 0;
 }
 
-static int sandbox_sf_xfer(void *priv, const u8 *rx, u8 *tx,
-               uint bytes)
+static int sandbox_sf_xfer(struct udevice *dev, unsigned int bitlen,
+                          const void *rxp, void *txp, unsigned long flags)
 {
-       struct sandbox_spi_flash *sbsf = priv;
+       struct sandbox_spi_flash *sbsf = dev_get_priv(dev);
+       const uint8_t *rx = rxp;
+       uint8_t *tx = txp;
        uint cnt, pos = 0;
+       int bytes = bitlen / 8;
        int ret;
 
        debug("sandbox_sf: state:%x(%s) bytes:%u\n", sbsf->state,
              sandbox_sf_state_name(sbsf->state), bytes);
 
+       if ((flags & SPI_XFER_BEGIN))
+               sandbox_sf_cs_activate(dev);
+
        if (sbsf->state == SF_CMD) {
                /* Figure out the initial state */
-               if (sandbox_sf_process_cmd(sbsf, rx, tx))
-                       return 1;
+               ret = sandbox_sf_process_cmd(sbsf, rx, tx);
+               if (ret)
+                       return ret;
                ++pos;
        }
 
@@ -290,7 +376,9 @@ static int sandbox_sf_xfer(void *priv, const u8 *rx, u8 *tx,
                                sbsf->off = (sbsf->off << 8) | rx[pos];
                        debug("addr:%06x\n", sbsf->off);
 
-                       sandbox_spi_tristate(&tx[pos++], 1);
+                       if (tx)
+                               sandbox_spi_tristate(&tx[pos], 1);
+                       pos++;
 
                        /* See if we're done processing */
                        if (sbsf->addr_bytes <
@@ -300,7 +388,7 @@ static int sandbox_sf_xfer(void *priv, const u8 *rx, u8 *tx,
                        /* Next state! */
                        if (os_lseek(sbsf->fd, sbsf->off, OS_SEEK_SET) < 0) {
                                puts("sandbox_sf: os_lseek() failed");
-                               return 1;
+                               return -EIO;
                        }
                        switch (sbsf->cmd) {
                        case CMD_READ_ARRAY_FAST:
@@ -326,10 +414,11 @@ static int sandbox_sf_xfer(void *priv, const u8 *rx, u8 *tx,
 
                        cnt = bytes - pos;
                        debug(" tx: read(%u)\n", cnt);
+                       assert(tx);
                        ret = os_read(sbsf->fd, tx + pos, cnt);
                        if (ret < 0) {
-                               puts("sandbox_spi: os_read() failed\n");
-                               return 1;
+                               puts("sandbox_sf: os_read() failed\n");
+                               return -EIO;
                        }
                        pos += ret;
                        break;
@@ -345,6 +434,10 @@ static int sandbox_sf_xfer(void *priv, const u8 *rx, u8 *tx,
                        memset(tx + pos, sbsf->status >> 8, cnt);
                        pos += cnt;
                        break;
+               case SF_WRITE_STATUS:
+                       debug(" write status: %#x (ignored)\n", rx[pos]);
+                       pos = bytes;
+                       break;
                case SF_WRITE:
                        /*
                         * XXX: need to handle exotic behavior:
@@ -359,11 +452,12 @@ static int sandbox_sf_xfer(void *priv, const u8 *rx, u8 *tx,
 
                        cnt = bytes - pos;
                        debug(" rx: write(%u)\n", cnt);
-                       sandbox_spi_tristate(&tx[pos], cnt);
+                       if (tx)
+                               sandbox_spi_tristate(&tx[pos], cnt);
                        ret = os_write(sbsf->fd, rx + pos, cnt);
                        if (ret < 0) {
                                puts("sandbox_spi: os_write() failed\n");
-                               return 1;
+                               return -EIO;
                        }
                        pos += ret;
                        sbsf->status &= ~STAT_WEL;
@@ -388,7 +482,8 @@ static int sandbox_sf_xfer(void *priv, const u8 *rx, u8 *tx,
                              sbsf->erase_size);
 
                        cnt = bytes - pos;
-                       sandbox_spi_tristate(&tx[pos], cnt);
+                       if (tx)
+                               sandbox_spi_tristate(&tx[pos], cnt);
                        pos += cnt;
 
                        /*
@@ -410,17 +505,33 @@ static int sandbox_sf_xfer(void *priv, const u8 *rx, u8 *tx,
        }
 
  done:
-       return pos == bytes ? 0 : 1;
+       if (flags & SPI_XFER_END)
+               sandbox_sf_cs_deactivate(dev);
+       return pos == bytes ? 0 : -EIO;
+}
+
+int sandbox_sf_ofdata_to_platdata(struct udevice *dev)
+{
+       struct sandbox_spi_flash_plat_data *pdata = dev_get_platdata(dev);
+       const void *blob = gd->fdt_blob;
+       int node = dev->of_offset;
+
+       pdata->filename = fdt_getprop(blob, node, "sandbox,filename", NULL);
+       pdata->device_name = fdt_getprop(blob, node, "compatible", NULL);
+       if (!pdata->filename || !pdata->device_name) {
+               debug("%s: Missing properties, filename=%s, device_name=%s\n",
+                     __func__, pdata->filename, pdata->device_name);
+               return -EINVAL;
+       }
+
+       return 0;
 }
 
-static const struct sandbox_spi_emu_ops sandbox_sf_ops = {
-       .setup         = sandbox_sf_setup,
-       .free          = sandbox_sf_free,
-       .cs_activate   = sandbox_sf_cs_activate,
-       .cs_deactivate = sandbox_sf_cs_deactivate,
+static const struct dm_spi_emul_ops sandbox_sf_emul_ops = {
        .xfer          = sandbox_sf_xfer,
 };
 
+#ifdef CONFIG_SPI_FLASH
 static int sandbox_cmdline_cb_spi_sf(struct sandbox_state *state,
                                     const char *arg)
 {
@@ -438,8 +549,141 @@ static int sandbox_cmdline_cb_spi_sf(struct sandbox_state *state,
         * spec here, but the problem is that no U-Boot init has been done
         * yet. Perhaps we can figure something out.
         */
-       state->spi[bus][cs].ops = &sandbox_sf_ops;
        state->spi[bus][cs].spec = spec;
        return 0;
 }
 SANDBOX_CMDLINE_OPT(spi_sf, 1, "connect a SPI flash: <bus>:<cs>:<id>:<file>");
+
+int sandbox_sf_bind_emul(struct sandbox_state *state, int busnum, int cs,
+                        struct udevice *bus, int of_offset, const char *spec)
+{
+       struct udevice *emul;
+       char name[20], *str;
+       struct driver *drv;
+       int ret;
+
+       /* now the emulator */
+       strncpy(name, spec, sizeof(name) - 6);
+       name[sizeof(name) - 6] = '\0';
+       strcat(name, "-emul");
+       str = strdup(name);
+       if (!str)
+               return -ENOMEM;
+       drv = lists_driver_lookup_name("sandbox_sf_emul");
+       if (!drv) {
+               puts("Cannot find sandbox_sf_emul driver\n");
+               return -ENOENT;
+       }
+       ret = device_bind(bus, drv, str, NULL, of_offset, &emul);
+       if (ret) {
+               printf("Cannot create emul device for spec '%s' (err=%d)\n",
+                      spec, ret);
+               return ret;
+       }
+       state->spi[busnum][cs].emul = emul;
+
+       return 0;
+}
+
+void sandbox_sf_unbind_emul(struct sandbox_state *state, int busnum, int cs)
+{
+       state->spi[busnum][cs].emul = NULL;
+}
+
+static int sandbox_sf_bind_bus_cs(struct sandbox_state *state, int busnum,
+                                 int cs, const char *spec)
+{
+       struct udevice *bus, *slave;
+       int ret;
+
+       ret = uclass_find_device_by_seq(UCLASS_SPI, busnum, true, &bus);
+       if (ret) {
+               printf("Invalid bus %d for spec '%s' (err=%d)\n", busnum,
+                      spec, ret);
+               return ret;
+       }
+       ret = device_find_child_by_seq(bus, cs, true, &slave);
+       if (!ret) {
+               printf("Chip select %d already exists for spec '%s'\n", cs,
+                      spec);
+               return -EEXIST;
+       }
+
+       ret = spi_bind_device(bus, cs, "spi_flash_std", spec, &slave);
+       if (ret)
+               return ret;
+
+       return sandbox_sf_bind_emul(state, busnum, cs, bus, -1, spec);
+}
+
+int sandbox_spi_get_emul(struct sandbox_state *state,
+                        struct udevice *bus, struct udevice *slave,
+                        struct udevice **emulp)
+{
+       struct sandbox_spi_info *info;
+       int busnum = bus->seq;
+       int cs = spi_chip_select(slave);
+       int ret;
+
+       info = &state->spi[busnum][cs];
+       if (!info->emul) {
+               /* Use the same device tree node as the SPI flash device */
+               debug("%s: busnum=%u, cs=%u: binding SPI flash emulation: ",
+                     __func__, busnum, cs);
+               ret = sandbox_sf_bind_emul(state, busnum, cs, bus,
+                                          slave->of_offset, slave->name);
+               if (ret) {
+                       debug("failed (err=%d)\n", ret);
+                       return ret;
+               }
+               debug("OK\n");
+       }
+       *emulp = info->emul;
+
+       return 0;
+}
+
+int dm_scan_other(bool pre_reloc_only)
+{
+       struct sandbox_state *state = state_get_current();
+       int busnum, cs;
+
+       if (pre_reloc_only)
+               return 0;
+       for (busnum = 0; busnum < CONFIG_SANDBOX_SPI_MAX_BUS; busnum++) {
+               for (cs = 0; cs < CONFIG_SANDBOX_SPI_MAX_CS; cs++) {
+                       const char *spec = state->spi[busnum][cs].spec;
+                       int ret;
+
+                       if (spec) {
+                               ret = sandbox_sf_bind_bus_cs(state, busnum,
+                                                            cs, spec);
+                               if (ret) {
+                                       debug("%s: Bind failed for bus %d, cs %d\n",
+                                             __func__, busnum, cs);
+                                       return ret;
+                               }
+                       }
+               }
+       }
+
+       return 0;
+}
+#endif
+
+static const struct udevice_id sandbox_sf_ids[] = {
+       { .compatible = "sandbox,spi-flash" },
+       { }
+};
+
+U_BOOT_DRIVER(sandbox_sf_emul) = {
+       .name           = "sandbox_sf_emul",
+       .id             = UCLASS_SPI_EMUL,
+       .of_match       = sandbox_sf_ids,
+       .ofdata_to_platdata = sandbox_sf_ofdata_to_platdata,
+       .probe          = sandbox_sf_probe,
+       .remove         = sandbox_sf_remove,
+       .priv_auto_alloc_size = sizeof(struct sandbox_spi_flash),
+       .platdata_auto_alloc_size = sizeof(struct sandbox_spi_flash_plat_data),
+       .ops            = &sandbox_sf_emul_ops,
+};
diff --git a/drivers/mtd/spi/sf-uclass.c b/drivers/mtd/spi/sf-uclass.c
new file mode 100644 (file)
index 0000000..376d815
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2014 Google, Inc
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <spi.h>
+#include <spi_flash.h>
+#include <dm/device-internal.h>
+#include "sf_internal.h"
+
+/*
+ * TODO(sjg@chromium.org): This is an old-style function. We should remove
+ * it when all SPI flash drivers use dm
+ */
+struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs,
+                                 unsigned int max_hz, unsigned int spi_mode)
+{
+       struct udevice *dev;
+
+       if (spi_flash_probe_bus_cs(bus, cs, max_hz, spi_mode, &dev))
+               return NULL;
+
+       return dev->uclass_priv;
+}
+
+void spi_flash_free(struct spi_flash *flash)
+{
+       spi_flash_remove(flash->spi->dev);
+}
+
+int spi_flash_probe_bus_cs(unsigned int busnum, unsigned int cs,
+                          unsigned int max_hz, unsigned int spi_mode,
+                          struct udevice **devp)
+{
+       struct spi_slave *slave;
+       struct udevice *bus;
+       char name[20], *str;
+       int ret;
+
+       snprintf(name, sizeof(name), "%d:%d", busnum, cs);
+       str = strdup(name);
+       ret = spi_get_bus_and_cs(busnum, cs, max_hz, spi_mode,
+                                 "spi_flash_std", str, &bus, &slave);
+       if (ret)
+               return ret;
+
+       *devp = slave->dev;
+       return 0;
+}
+
+int spi_flash_remove(struct udevice *dev)
+{
+       return device_remove(dev);
+}
+
+UCLASS_DRIVER(spi_flash) = {
+       .id             = UCLASS_SPI_FLASH,
+       .name           = "spi_flash",
+       .per_device_auto_alloc_size = sizeof(struct spi_flash),
+};
index 19d49146ebd1520d9f6a481765acdbd884b384ee..5b7670c9aaf1219e841cd2dfc5096bb62e7e3390 100644 (file)
 #ifndef _SF_INTERNAL_H_
 #define _SF_INTERNAL_H_
 
+#include <linux/types.h>
+#include <linux/compiler.h>
+
+/* Dual SPI flash memories - see SPI_COMM_DUAL_... */
+enum spi_dual_flash {
+       SF_SINGLE_FLASH = 0,
+       SF_DUAL_STACKED_FLASH   = 1 << 0,
+       SF_DUAL_PARALLEL_FLASH  = 1 << 1,
+};
+
+/* Enum list - Full read commands */
+enum spi_read_cmds {
+       ARRAY_SLOW              = 1 << 0,
+       DUAL_OUTPUT_FAST        = 1 << 1,
+       DUAL_IO_FAST            = 1 << 2,
+       QUAD_OUTPUT_FAST        = 1 << 3,
+       QUAD_IO_FAST            = 1 << 4,
+};
+
+#define RD_EXTN        (ARRAY_SLOW | DUAL_OUTPUT_FAST | DUAL_IO_FAST)
+#define RD_FULL        (RD_EXTN | QUAD_OUTPUT_FAST | QUAD_IO_FAST)
+
+/* sf param flags */
+enum {
+       SECT_4K         = 1 << 0,
+       SECT_32K        = 1 << 1,
+       E_FSR           = 1 << 2,
+       WR_QPP          = 1 << 3,
+};
+
 #define SPI_FLASH_3B_ADDR_LEN          3
 #define SPI_FLASH_CMD_LEN              (1 + SPI_FLASH_3B_ADDR_LEN)
 #define SPI_FLASH_16MB_BOUN            0x1000000
 #define CMD_WRITE_STATUS               0x01
 #define CMD_PAGE_PROGRAM               0x02
 #define CMD_WRITE_DISABLE              0x04
-#define CMD_READ_STATUS                        0x05
+#define CMD_READ_STATUS                0x05
 #define CMD_QUAD_PAGE_PROGRAM          0x32
 #define CMD_READ_STATUS1               0x35
 #define CMD_WRITE_ENABLE               0x06
-#define CMD_READ_CONFIG                        0x35
-#define CMD_FLAG_STATUS                        0x70
+#define CMD_READ_CONFIG                0x35
+#define CMD_FLAG_STATUS                0x70
 
 /* Read commands */
 #define CMD_READ_ARRAY_SLOW            0x03
@@ -57,7 +87,7 @@
 /* Common status */
 #define STATUS_WIP                     (1 << 0)
 #define STATUS_QEB_WINSPAN             (1 << 1)
-#define STATUS_QEB_MXIC                        (1 << 6)
+#define STATUS_QEB_MXIC                (1 << 6)
 #define STATUS_PEC                     (1 << 7)
 
 #ifdef CONFIG_SYS_SPI_ST_ENABLE_WP_PIN
 
 /* Flash timeout values */
 #define SPI_FLASH_PROG_TIMEOUT         (2 * CONFIG_SYS_HZ)
-#define SPI_FLASH_PAGE_ERASE_TIMEOUT   (5 * CONFIG_SYS_HZ)
+#define SPI_FLASH_PAGE_ERASE_TIMEOUT           (5 * CONFIG_SYS_HZ)
 #define SPI_FLASH_SECTOR_ERASE_TIMEOUT (10 * CONFIG_SYS_HZ)
 
 /* SST specific */
 #ifdef CONFIG_SPI_FLASH_SST
-# define SST_WP                        0x01    /* Supports AAI word program */
+# define SST_WP                0x01    /* Supports AAI word program */
 # define CMD_SST_BP            0x02    /* Byte Program */
-# define CMD_SST_AAI_WP                0xAD    /* Auto Address Incr Word Program */
+# define CMD_SST_AAI_WP        0xAD    /* Auto Address Incr Word Program */
 
 int sst_write_wp(struct spi_flash *flash, u32 offset, size_t len,
                const void *buf);
 #endif
 
+/**
+ * struct spi_flash_params - SPI/QSPI flash device params structure
+ *
+ * @name:              Device name ([MANUFLETTER][DEVTYPE][DENSITY][EXTRAINFO])
+ * @jedec:             Device jedec ID (0x[1byte_manuf_id][2byte_dev_id])
+ * @ext_jedec:         Device ext_jedec ID
+ * @sector_size:       Sector size of this device
+ * @nr_sectors:        No.of sectors on this device
+ * @e_rd_cmd:          Enum list for read commands
+ * @flags:             Important param, for flash specific behaviour
+ */
+struct spi_flash_params {
+       const char *name;
+       u32 jedec;
+       u16 ext_jedec;
+       u32 sector_size;
+       u32 nr_sectors;
+       u8 e_rd_cmd;
+       u16 flags;
+};
+
+extern const struct spi_flash_params spi_flash_params_table[];
+
 /* Send a single-byte command to the device and read the response */
 int spi_flash_cmd(struct spi_slave *spi, u8 cmd, void *response, size_t len);
 
index 453edf0149518cd69c945adcf2b3a270ddaebb62..61545cacaabe8415bf7a1a1fa35d2e7e8294e2b9 100644 (file)
@@ -7,6 +7,7 @@
  */
 
 #include <common.h>
+#include <spi.h>
 #include <spi_flash.h>
 
 #include "sf_internal.h"
index 4d148d1ace3749744cbc1e9ef190f5fdcb84649a..26364269be1a5e823efc99bd498262bd1a9d3393 100644 (file)
@@ -9,6 +9,8 @@
  */
 
 #include <common.h>
+#include <dm.h>
+#include <errno.h>
 #include <fdtdec.h>
 #include <malloc.h>
 #include <spi.h>
@@ -95,15 +97,15 @@ static int spi_flash_set_qeb(struct spi_flash *flash, u8 idcode0)
        }
 }
 
-static struct spi_flash *spi_flash_validate_params(struct spi_slave *spi,
-               u8 *idcode)
+static int spi_flash_validate_params(struct spi_slave *spi, u8 *idcode,
+                                    struct spi_flash *flash)
 {
        const struct spi_flash_params *params;
-       struct spi_flash *flash;
        u8 cmd;
        u16 jedec = idcode[1] << 8 | idcode[2];
        u16 ext_jedec = idcode[3] << 8 | idcode[4];
 
+       /* Validate params from spi_flash_params table */
        params = spi_flash_params_table;
        for (; params->name != NULL; params++) {
                if ((params->jedec >> 16) == idcode[0]) {
@@ -120,13 +122,7 @@ static struct spi_flash *spi_flash_validate_params(struct spi_slave *spi,
                printf("SF: Unsupported flash IDs: ");
                printf("manuf %02x, jedec %04x, ext_jedec %04x\n",
                       idcode[0], jedec, ext_jedec);
-               return NULL;
-       }
-
-       flash = calloc(1, sizeof(*flash));
-       if (!flash) {
-               debug("SF: Failed to allocate spi_flash\n");
-               return NULL;
+               return -EPROTONOSUPPORT;
        }
 
        /* Assign spi data */
@@ -136,13 +132,15 @@ static struct spi_flash *spi_flash_validate_params(struct spi_slave *spi,
        flash->dual_flash = flash->spi->option;
 
        /* Assign spi_flash ops */
+#ifndef CONFIG_DM_SPI_FLASH
        flash->write = spi_flash_cmd_write_ops;
-#ifdef CONFIG_SPI_FLASH_SST
+#if defined(CONFIG_SPI_FLASH_SST)
        if (params->flags & SST_WP)
                flash->write = sst_write_wp;
 #endif
        flash->erase = spi_flash_cmd_erase_ops;
        flash->read = spi_flash_cmd_read_ops;
+#endif
 
        /* Compute the flash size */
        flash->shift = (flash->dual_flash & SF_DUAL_PARALLEL_FLASH) ? 1 : 0;
@@ -227,15 +225,18 @@ static struct spi_flash *spi_flash_validate_params(struct spi_slave *spi,
 #ifdef CONFIG_SPI_FLASH_BAR
        u8 curr_bank = 0;
        if (flash->size > SPI_FLASH_16MB_BOUN) {
+               int ret;
+
                flash->bank_read_cmd = (idcode[0] == 0x01) ?
                                        CMD_BANKADDR_BRRD : CMD_EXTNADDR_RDEAR;
                flash->bank_write_cmd = (idcode[0] == 0x01) ?
                                        CMD_BANKADDR_BRWR : CMD_EXTNADDR_WREAR;
 
-               if (spi_flash_read_common(flash, &flash->bank_read_cmd, 1,
-                                         &curr_bank, 1)) {
+               ret = spi_flash_read_common(flash, &flash->bank_read_cmd, 1,
+                                           &curr_bank, 1);
+               if (ret) {
                        debug("SF: fail to read bank addr register\n");
-                       return NULL;
+                       return ret;
                }
                flash->bank_curr = curr_bank;
        } else {
@@ -250,7 +251,7 @@ static struct spi_flash *spi_flash_validate_params(struct spi_slave *spi,
                spi_flash_cmd_write_status(flash, 0);
 #endif
 
-       return flash;
+       return 0;
 }
 
 #ifdef CONFIG_OF_CONTROL
@@ -309,23 +310,29 @@ static int spi_enable_wp_pin(struct spi_flash *flash)
 }
 #endif
 
-static struct spi_flash *spi_flash_probe_slave(struct spi_slave *spi)
+/**
+ * spi_flash_probe_slave() - Probe for a SPI flash device on a bus
+ *
+ * @spi: Bus to probe
+ * @flashp: Pointer to place to put flash info, which may be NULL if the
+ * space should be allocated
+ */
+int spi_flash_probe_slave(struct spi_slave *spi, struct spi_flash *flash)
 {
-       struct spi_flash *flash = NULL;
        u8 idcode[5];
        int ret;
 
        /* Setup spi_slave */
        if (!spi) {
                printf("SF: Failed to set up slave\n");
-               return NULL;
+               return -ENODEV;
        }
 
        /* Claim spi bus */
        ret = spi_claim_bus(spi);
        if (ret) {
                debug("SF: Failed to claim SPI bus: %d\n", ret);
-               goto err_claim_bus;
+               return ret;
        }
 
        /* Read the ID codes */
@@ -340,10 +347,10 @@ static struct spi_flash *spi_flash_probe_slave(struct spi_slave *spi)
        print_buffer(0, idcode, 1, sizeof(idcode), 0);
 #endif
 
-       /* Validate params from spi_flash_params table */
-       flash = spi_flash_validate_params(spi, idcode);
-       if (!flash)
+       if (spi_flash_validate_params(spi, idcode, flash)) {
+               ret = -EINVAL;
                goto err_read_id;
+       }
 
        /* Set the quad enable bit - only for quad commands */
        if ((flash->read_cmd == CMD_READ_QUAD_OUTPUT_FAST) ||
@@ -351,13 +358,15 @@ static struct spi_flash *spi_flash_probe_slave(struct spi_slave *spi)
            (flash->write_cmd == CMD_QUAD_PAGE_PROGRAM)) {
                if (spi_flash_set_qeb(flash, idcode[0])) {
                        debug("SF: Fail to set QEB for %02x\n", idcode[0]);
-                       return NULL;
+                       ret = -EINVAL;
+                       goto err_read_id;
                }
        }
 
 #ifdef CONFIG_OF_CONTROL
        if (spi_flash_decode_fdt(gd->fdt_blob, flash)) {
                debug("SF: FDT decode error\n");
+               ret = -EINVAL;
                goto err_read_id;
        }
 #endif
@@ -385,32 +394,51 @@ static struct spi_flash *spi_flash_probe_slave(struct spi_slave *spi)
        /* Release spi bus */
        spi_release_bus(spi);
 
-       return flash;
+       return 0;
 
 err_read_id:
        spi_release_bus(spi);
-err_claim_bus:
-       spi_free_slave(spi);
-       return NULL;
+       return ret;
 }
 
-struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs,
+#ifndef CONFIG_DM_SPI_FLASH
+struct spi_flash *spi_flash_probe_tail(struct spi_slave *bus)
+{
+       struct spi_flash *flash;
+
+       /* Allocate space if needed (not used by sf-uclass */
+       flash = calloc(1, sizeof(*flash));
+       if (!flash) {
+               debug("SF: Failed to allocate spi_flash\n");
+               return NULL;
+       }
+
+       if (spi_flash_probe_slave(bus, flash)) {
+               spi_free_slave(bus);
+               free(flash);
+               return NULL;
+       }
+
+       return flash;
+}
+
+struct spi_flash *spi_flash_probe(unsigned int busnum, unsigned int cs,
                unsigned int max_hz, unsigned int spi_mode)
 {
-       struct spi_slave *spi;
+       struct spi_slave *bus;
 
-       spi = spi_setup_slave(bus, cs, max_hz, spi_mode);
-       return spi_flash_probe_slave(spi);
+       bus = spi_setup_slave(busnum, cs, max_hz, spi_mode);
+       return spi_flash_probe_tail(bus);
 }
 
 #ifdef CONFIG_OF_SPI_FLASH
 struct spi_flash *spi_flash_probe_fdt(const void *blob, int slave_node,
                                      int spi_node)
 {
-       struct spi_slave *spi;
+       struct spi_slave *bus;
 
-       spi = spi_setup_slave_fdt(blob, slave_node, spi_node);
-       return spi_flash_probe_slave(spi);
+       bus = spi_setup_slave_fdt(blob, slave_node, spi_node);
+       return spi_flash_probe_tail(bus);
 }
 #endif
 
@@ -419,3 +447,61 @@ void spi_flash_free(struct spi_flash *flash)
        spi_free_slave(flash->spi);
        free(flash);
 }
+
+#else /* defined CONFIG_DM_SPI_FLASH */
+
+static int spi_flash_std_read(struct udevice *dev, u32 offset, size_t len,
+                             void *buf)
+{
+       struct spi_flash *flash = dev->uclass_priv;
+
+       return spi_flash_cmd_read_ops(flash, offset, len, buf);
+}
+
+int spi_flash_std_write(struct udevice *dev, u32 offset, size_t len,
+                       const void *buf)
+{
+       struct spi_flash *flash = dev->uclass_priv;
+
+       return spi_flash_cmd_write_ops(flash, offset, len, buf);
+}
+
+int spi_flash_std_erase(struct udevice *dev, u32 offset, size_t len)
+{
+       struct spi_flash *flash = dev->uclass_priv;
+
+       return spi_flash_cmd_erase_ops(flash, offset, len);
+}
+
+int spi_flash_std_probe(struct udevice *dev)
+{
+       struct spi_slave *slave = dev_get_parentdata(dev);
+       struct spi_flash *flash;
+
+       flash = dev->uclass_priv;
+       flash->dev = dev;
+       debug("%s: slave=%p, cs=%d\n", __func__, slave, slave->cs);
+       return spi_flash_probe_slave(slave, flash);
+}
+
+static const struct dm_spi_flash_ops spi_flash_std_ops = {
+       .read = spi_flash_std_read,
+       .write = spi_flash_std_write,
+       .erase = spi_flash_std_erase,
+};
+
+static const struct udevice_id spi_flash_std_ids[] = {
+       { .compatible = "spi-flash" },
+       { }
+};
+
+U_BOOT_DRIVER(spi_flash_std) = {
+       .name           = "spi_flash_std",
+       .id             = UCLASS_SPI_FLASH,
+       .of_match       = spi_flash_std_ids,
+       .probe          = spi_flash_std_probe,
+       .priv_auto_alloc_size = sizeof(struct spi_flash),
+       .ops            = &spi_flash_std_ops,
+};
+
+#endif /* CONFIG_DM_SPI_FLASH */
index 59cca0f4d998d1d6b87f9b7ca0a16180f8840bcd..2e0c871219bd05ac31c63a80ba793e1dc1255899 100644 (file)
@@ -10,6 +10,7 @@
  */
 
 #include <common.h>
+#include <spi.h>
 #include <spi_flash.h>
 #include <spl.h>
 
index 2c4dd7cb6ad8657a500f7e7247a658591c1dab4b..fb0cf8c1cf172dce03a8dcea02d7522de26793a9 100644 (file)
@@ -41,6 +41,7 @@ obj-$(CONFIG_MCFFEC) += mcffec.o mcfmii.o
 obj-$(CONFIG_MPC5xxx_FEC) += mpc5xxx_fec.o
 obj-$(CONFIG_MPC512x_FEC) += mpc512x_fec.o
 obj-$(CONFIG_MVGBE) += mvgbe.o
+obj-$(CONFIG_MVNETA) += mvneta.o
 obj-$(CONFIG_NATSEMI) += natsemi.o
 obj-$(CONFIG_DRIVER_NE2000) += ne2000.o ne2000_base.o
 obj-$(CONFIG_DRIVER_AX88796L) += ax88796.o ne2000_base.o
index 439f8ae99e364f2082ceaa2ad5f0630c21e0fe9f..08bc1afcf638be1dbde9e1c23662a829c2bfa298 100644 (file)
@@ -27,6 +27,7 @@
 #include <net.h>
 #include <miiphy.h>
 #include <malloc.h>
+#include <netdev.h>
 #include <linux/compiler.h>
 #include <asm/arch/emac_defs.h>
 #include <asm/io.h>
index 549d6486136204ed644a2c2ecba101d25db303ef..b57247032fa85aaa65ec47c9fcf7668a4cd567df 100644 (file)
@@ -11,6 +11,7 @@
 #include <common.h>
 #include <malloc.h>
 #include <net.h>
+#include <netdev.h>
 #include <miiphy.h>
 #include "fec_mxc.h"
 
@@ -179,13 +180,14 @@ static int fec_mdio_write(struct ethernet_regs *eth, uint8_t phyAddr,
        return 0;
 }
 
-int fec_phy_read(struct mii_dev *bus, int phyAddr, int dev_addr, int regAddr)
+static int fec_phy_read(struct mii_dev *bus, int phyAddr, int dev_addr,
+                       int regAddr)
 {
        return fec_mdio_read(bus->priv, phyAddr, regAddr);
 }
 
-int fec_phy_write(struct mii_dev *bus, int phyAddr, int dev_addr, int regAddr,
-               u16 data)
+static int fec_phy_write(struct mii_dev *bus, int phyAddr, int dev_addr,
+                        int regAddr, u16 data)
 {
        return fec_mdio_write(bus->priv, phyAddr, regAddr, data);
 }
index d22b722bc53de033f162171eee3da22b766a1db7..c8681d02234b3b7d692d57c416328d83ce72790e 100644 (file)
 #include <command.h>
 
 #include <net.h>
+#include <phy.h>
+#include <errno.h>
 #include <miiphy.h>
 #include <malloc.h>
-#include <asm/arch/emac_defs.h>
-#include <asm/arch/psc_defs.h>
-#include <asm/arch/keystone_nav.h>
-
-unsigned int emac_dbg;
+#include <asm/ti-common/keystone_nav.h>
+#include <asm/ti-common/keystone_net.h>
+#include <asm/ti-common/keystone_serdes.h>
 
 unsigned int emac_open;
+static struct mii_dev *mdio_bus;
 static unsigned int sys_has_mdio = 1;
 
 #ifdef KEYSTONE2_EMAC_GIG_ENABLE
@@ -30,6 +31,7 @@ static unsigned int sys_has_mdio = 1;
 #define RX_BUFF_NUMS   24
 #define RX_BUFF_LEN    1520
 #define MAX_SIZE_STREAM_BUFFER RX_BUFF_LEN
+#define SGMII_ANEG_TIMEOUT             4000
 
 static u8 rx_buffs[RX_BUFF_NUMS * RX_BUFF_LEN] __aligned(16);
 
@@ -40,15 +42,7 @@ struct rx_buff_desc net_rx_buffs = {
        .rx_flow        = 22,
 };
 
-static void keystone2_eth_mdio_enable(void);
-
-static int gen_get_link_speed(int phy_addr);
-
-/* EMAC Addresses */
-static volatile struct emac_regs       *adap_emac =
-       (struct emac_regs *)EMAC_EMACSL_BASE_ADDR;
-static volatile struct mdio_regs       *adap_mdio =
-       (struct mdio_regs *)EMAC_MDIO_BASE_ADDR;
+static void keystone2_net_serdes_setup(void);
 
 int keystone2_eth_read_mac_addr(struct eth_device *dev)
 {
@@ -74,64 +68,67 @@ int keystone2_eth_read_mac_addr(struct eth_device *dev)
        return 0;
 }
 
-static void keystone2_eth_mdio_enable(void)
+/* MDIO */
+
+static int keystone2_mdio_reset(struct mii_dev *bus)
 {
-       u_int32_t       clkdiv;
+       u_int32_t clkdiv;
+       struct mdio_regs *adap_mdio = bus->priv;
 
        clkdiv = (EMAC_MDIO_BUS_FREQ / EMAC_MDIO_CLOCK_FREQ) - 1;
 
-       writel((clkdiv & 0xffff) |
-              MDIO_CONTROL_ENABLE |
-              MDIO_CONTROL_FAULT |
-              MDIO_CONTROL_FAULT_ENABLE,
+       writel((clkdiv & 0xffff) | MDIO_CONTROL_ENABLE |
+              MDIO_CONTROL_FAULT | MDIO_CONTROL_FAULT_ENABLE,
               &adap_mdio->control);
 
        while (readl(&adap_mdio->control) & MDIO_CONTROL_IDLE)
                ;
+
+       return 0;
 }
 
-/* Read a PHY register via MDIO inteface. Returns 1 on success, 0 otherwise */
-int keystone2_eth_phy_read(u_int8_t phy_addr, u_int8_t reg_num, u_int16_t *data)
+/**
+ * keystone2_mdio_read - read a PHY register via MDIO interface.
+ * Blocks until operation is complete.
+ */
+static int keystone2_mdio_read(struct mii_dev *bus,
+                              int addr, int devad, int reg)
 {
-       int     tmp;
+       int tmp;
+       struct mdio_regs *adap_mdio = bus->priv;
 
        while (readl(&adap_mdio->useraccess0) & MDIO_USERACCESS0_GO)
                ;
 
-       writel(MDIO_USERACCESS0_GO |
-              MDIO_USERACCESS0_WRITE_READ |
-              ((reg_num & 0x1f) << 21) |
-              ((phy_addr & 0x1f) << 16),
+       writel(MDIO_USERACCESS0_GO | MDIO_USERACCESS0_WRITE_READ |
+              ((reg & 0x1f) << 21) | ((addr & 0x1f) << 16),
               &adap_mdio->useraccess0);
 
        /* Wait for command to complete */
        while ((tmp = readl(&adap_mdio->useraccess0)) & MDIO_USERACCESS0_GO)
                ;
 
-       if (tmp & MDIO_USERACCESS0_ACK) {
-               *data = tmp & 0xffff;
-               return 0;
-       }
+       if (tmp & MDIO_USERACCESS0_ACK)
+               return tmp & 0xffff;
 
-       *data = -1;
        return -1;
 }
 
-/*
- * Write to a PHY register via MDIO inteface.
+/**
+ * keystone2_mdio_write - write to a PHY register via MDIO interface.
  * Blocks until operation is complete.
  */
-int keystone2_eth_phy_write(u_int8_t phy_addr, u_int8_t reg_num, u_int16_t data)
+static int keystone2_mdio_write(struct mii_dev *bus,
+                               int addr, int devad, int reg, u16 val)
 {
+       struct mdio_regs *adap_mdio = bus->priv;
+
        while (readl(&adap_mdio->useraccess0) & MDIO_USERACCESS0_GO)
                ;
 
-       writel(MDIO_USERACCESS0_GO |
-              MDIO_USERACCESS0_WRITE_WRITE |
-              ((reg_num & 0x1f) << 21) |
-              ((phy_addr & 0x1f) << 16) |
-              (data & 0xffff),
-              &adap_mdio->useraccess0);
+       writel(MDIO_USERACCESS0_GO | MDIO_USERACCESS0_WRITE_WRITE |
+              ((reg & 0x1f) << 21) | ((addr & 0x1f) << 16) |
+              (val & 0xffff), &adap_mdio->useraccess0);
 
        /* Wait for command to complete */
        while (readl(&adap_mdio->useraccess0) & MDIO_USERACCESS0_GO)
@@ -140,19 +137,6 @@ int keystone2_eth_phy_write(u_int8_t phy_addr, u_int8_t reg_num, u_int16_t data)
        return 0;
 }
 
-/* PHY functions for a generic PHY */
-static int gen_get_link_speed(int phy_addr)
-{
-       u_int16_t       tmp;
-
-       if ((!keystone2_eth_phy_read(phy_addr, MII_STATUS_REG, &tmp)) &&
-           (tmp & 0x04)) {
-               return 0;
-       }
-
-       return -1;
-}
-
 static void  __attribute__((unused))
        keystone2_eth_gigabit_enable(struct eth_device *dev)
 {
@@ -160,8 +144,10 @@ static void  __attribute__((unused))
        struct eth_priv_t *eth_priv = (struct eth_priv_t *)dev->priv;
 
        if (sys_has_mdio) {
-               if (keystone2_eth_phy_read(eth_priv->phy_addr, 0, &data) ||
-                   !(data & (1 << 6))) /* speed selection MSB */
+               data = keystone2_mdio_read(mdio_bus, eth_priv->phy_addr,
+                                          MDIO_DEVAD_NONE, 0);
+               /* speed selection MSB */
+               if (!(data & (1 << 6)))
                        return;
        }
 
@@ -169,10 +155,10 @@ static void  __attribute__((unused))
         * Check if link detected is giga-bit
         * If Gigabit mode detected, enable gigbit in MAC
         */
-       writel(readl(&(adap_emac[eth_priv->slave_port - 1].maccontrol)) |
+       writel(readl(DEVICE_EMACSL_BASE(eth_priv->slave_port - 1) +
+                    CPGMACSL_REG_CTL) |
               EMAC_MACCONTROL_GIGFORCE | EMAC_MACCONTROL_GIGABIT_ENABLE,
-              &(adap_emac[eth_priv->slave_port - 1].maccontrol))
-               ;
+              DEVICE_EMACSL_BASE(eth_priv->slave_port - 1) + CPGMACSL_REG_CTL);
 }
 
 int keystone_sgmii_link_status(int port)
@@ -181,38 +167,11 @@ int keystone_sgmii_link_status(int port)
 
        status = __raw_readl(SGMII_STATUS_REG(port));
 
-       return status & SGMII_REG_STATUS_LINK;
+       return (status & SGMII_REG_STATUS_LOCK) &&
+              (status & SGMII_REG_STATUS_LINK);
 }
 
-
-int keystone_get_link_status(struct eth_device *dev)
-{
-       struct eth_priv_t *eth_priv = (struct eth_priv_t *)dev->priv;
-       int sgmii_link;
-       int link_state = 0;
-#if CONFIG_GET_LINK_STATUS_ATTEMPTS > 1
-       int j;
-
-       for (j = 0; (j < CONFIG_GET_LINK_STATUS_ATTEMPTS) && (link_state == 0);
-            j++) {
-#endif
-               sgmii_link =
-                       keystone_sgmii_link_status(eth_priv->slave_port - 1);
-
-               if (sgmii_link) {
-                       link_state = 1;
-
-                       if (eth_priv->sgmii_link_type == SGMII_LINK_MAC_PHY)
-                               if (gen_get_link_speed(eth_priv->phy_addr))
-                                       link_state = 0;
-               }
-#if CONFIG_GET_LINK_STATUS_ATTEMPTS > 1
-       }
-#endif
-       return link_state;
-}
-
-int keystone_sgmii_config(int port, int interface)
+int keystone_sgmii_config(struct phy_device *phy_dev, int port, int interface)
 {
        unsigned int i, status, mask;
        unsigned int mr_adv_ability, control;
@@ -273,11 +232,35 @@ int keystone_sgmii_config(int port, int interface)
        if (control & SGMII_REG_CONTROL_AUTONEG)
                mask |= SGMII_REG_STATUS_AUTONEG;
 
-       for (i = 0; i < 1000; i++) {
+       status = __raw_readl(SGMII_STATUS_REG(port));
+       if ((status & mask) == mask)
+               return 0;
+
+       printf("\n%s Waiting for SGMII auto negotiation to complete",
+              phy_dev->dev->name);
+       while ((status & mask) != mask) {
+               /*
+                * Timeout reached ?
+                */
+               if (i > SGMII_ANEG_TIMEOUT) {
+                       puts(" TIMEOUT !\n");
+                       phy_dev->link = 0;
+                       return 0;
+               }
+
+               if (ctrlc()) {
+                       puts("user interrupt!\n");
+                       phy_dev->link = 0;
+                       return -EINTR;
+               }
+
+               if ((i++ % 500) == 0)
+                       printf(".");
+
+               udelay(1000);   /* 1 ms */
                status = __raw_readl(SGMII_STATUS_REG(port));
-               if ((status & mask) == mask)
-                       break;
        }
+       puts(" done\n");
 
        return 0;
 }
@@ -332,6 +315,11 @@ int mac_sl_config(u_int16_t port, struct mac_sl_cfg *cfg)
        writel(cfg->max_rx_len, DEVICE_EMACSL_BASE(port) + CPGMACSL_REG_MAXLEN);
        writel(cfg->ctl, DEVICE_EMACSL_BASE(port) + CPGMACSL_REG_CTL);
 
+#ifdef CONFIG_K2E_EVM
+       /* Map RX packet flow priority to 0 */
+       writel(0, DEVICE_EMACSL_BASE(port) + CPGMACSL_REG_RX_PRI_MAP);
+#endif
+
        return ret;
 }
 
@@ -393,15 +381,15 @@ int32_t cpmac_drv_send(u32 *buffer, int num_bytes, int slave_port_num)
        if (num_bytes < EMAC_MIN_ETHERNET_PKT_SIZE)
                num_bytes = EMAC_MIN_ETHERNET_PKT_SIZE;
 
-       return netcp_send(buffer, num_bytes, (slave_port_num) << 16);
+       return ksnav_send(&netcp_pktdma, buffer,
+                         num_bytes, (slave_port_num) << 16);
 }
 
 /* Eth device open */
 static int keystone2_eth_open(struct eth_device *dev, bd_t *bis)
 {
-       u_int32_t clkdiv;
-       int link;
        struct eth_priv_t *eth_priv = (struct eth_priv_t *)dev->priv;
+       struct phy_device *phy_dev = eth_priv->phy_dev;
 
        debug("+ emac_open\n");
 
@@ -410,15 +398,9 @@ static int keystone2_eth_open(struct eth_device *dev, bd_t *bis)
        sys_has_mdio =
                (eth_priv->sgmii_link_type == SGMII_LINK_MAC_PHY) ? 1 : 0;
 
-       psc_enable_module(KS2_LPSC_PA);
-       psc_enable_module(KS2_LPSC_CPGMAC);
-
-       sgmii_serdes_setup_156p25mhz();
-
-       if (sys_has_mdio)
-               keystone2_eth_mdio_enable();
+       keystone2_net_serdes_setup();
 
-       keystone_sgmii_config(eth_priv->slave_port - 1,
+       keystone_sgmii_config(phy_dev, eth_priv->slave_port - 1,
                              eth_priv->sgmii_link_type);
 
        udelay(10000);
@@ -431,7 +413,7 @@ static int keystone2_eth_open(struct eth_device *dev, bd_t *bis)
                printf("ERROR: qm_init()\n");
                return -1;
        }
-       if (netcp_init(&net_rx_buffs)) {
+       if (ksnav_init(&netcp_pktdma, &net_rx_buffs)) {
                qm_close();
                printf("ERROR: netcp_init()\n");
                return -1;
@@ -445,18 +427,11 @@ static int keystone2_eth_open(struct eth_device *dev, bd_t *bis)
        hw_config_streaming_switch();
 
        if (sys_has_mdio) {
-               /* Init MDIO & get link state */
-               clkdiv = (EMAC_MDIO_BUS_FREQ / EMAC_MDIO_CLOCK_FREQ) - 1;
-               writel((clkdiv & 0xff) | MDIO_CONTROL_ENABLE |
-                      MDIO_CONTROL_FAULT, &adap_mdio->control)
-                       ;
-
-               /* We need to wait for MDIO to start */
-               udelay(1000);
-
-               link = keystone_get_link_status(dev);
-               if (link == 0) {
-                       netcp_close();
+               keystone2_mdio_reset(mdio_bus);
+
+               phy_startup(phy_dev);
+               if (phy_dev->link == 0) {
+                       ksnav_close(&netcp_pktdma);
                        qm_close();
                        return -1;
                }
@@ -476,6 +451,9 @@ static int keystone2_eth_open(struct eth_device *dev, bd_t *bis)
 /* Eth device close */
 void keystone2_eth_close(struct eth_device *dev)
 {
+       struct eth_priv_t *eth_priv = (struct eth_priv_t *)dev->priv;
+       struct phy_device *phy_dev = eth_priv->phy_dev;
+
        debug("+ emac_close\n");
 
        if (!emac_open)
@@ -483,16 +461,15 @@ void keystone2_eth_close(struct eth_device *dev)
 
        ethss_stop();
 
-       netcp_close();
+       ksnav_close(&netcp_pktdma);
        qm_close();
+       phy_shutdown(phy_dev);
 
        emac_open = 0;
 
        debug("- emac_close\n");
 }
 
-static int tx_send_loop;
-
 /*
  * This function sends a single packet on the network and returns
  * positive number (number of bytes transmitted) or negative for error
@@ -502,22 +479,15 @@ static int keystone2_eth_send_packet(struct eth_device *dev,
 {
        int ret_status = -1;
        struct eth_priv_t *eth_priv = (struct eth_priv_t *)dev->priv;
+       struct phy_device *phy_dev = eth_priv->phy_dev;
 
-       tx_send_loop = 0;
-
-       if (keystone_get_link_status(dev) == 0)
+       genphy_update_link(phy_dev);
+       if (phy_dev->link == 0)
                return -1;
 
-       emac_gigabit_enable(dev);
-
        if (cpmac_drv_send((u32 *)packet, length, eth_priv->slave_port) != 0)
                return ret_status;
 
-       if (keystone_get_link_status(dev) == 0)
-               return -1;
-
-       emac_gigabit_enable(dev);
-
        return length;
 }
 
@@ -530,13 +500,13 @@ static int keystone2_eth_rcv_packet(struct eth_device *dev)
        int  pkt_size;
        u32  *pkt;
 
-       hd = netcp_recv(&pkt, &pkt_size);
+       hd = ksnav_recv(&netcp_pktdma, &pkt, &pkt_size);
        if (hd == NULL)
                return 0;
 
        NetReceive((uchar *)pkt, pkt_size);
 
-       netcp_release_rxhd(hd);
+       ksnav_release_rxhd(&netcp_pktdma, hd);
 
        return pkt_size;
 }
@@ -546,7 +516,9 @@ static int keystone2_eth_rcv_packet(struct eth_device *dev)
  */
 int keystone2_emac_initialize(struct eth_priv_t *eth_priv)
 {
+       int res;
        struct eth_device *dev;
+       struct phy_device *phy_dev;
 
        dev = malloc(sizeof(struct eth_device));
        if (dev == NULL)
@@ -567,145 +539,55 @@ int keystone2_emac_initialize(struct eth_priv_t *eth_priv)
 
        eth_register(dev);
 
-       return 0;
-}
-
-void sgmii_serdes_setup_156p25mhz(void)
-{
-       unsigned int cnt;
-
-       /*
-        * configure Serializer/Deserializer (SerDes) hardware. SerDes IP
-        * hardware vendor published only register addresses and their values
-        * to be used for configuring SerDes. So had to use hardcoded values
-        * below.
-        */
-       clrsetbits_le32(0x0232a000, 0xffff0000, 0x00800000);
-       clrsetbits_le32(0x0232a014, 0x0000ffff, 0x00008282);
-       clrsetbits_le32(0x0232a060, 0x00ffffff, 0x00142438);
-       clrsetbits_le32(0x0232a064, 0x00ffff00, 0x00c3c700);
-       clrsetbits_le32(0x0232a078, 0x0000ff00, 0x0000c000);
-
-       clrsetbits_le32(0x0232a204, 0xff0000ff, 0x38000080);
-       clrsetbits_le32(0x0232a208, 0x000000ff, 0x00000000);
-       clrsetbits_le32(0x0232a20c, 0xff000000, 0x02000000);
-       clrsetbits_le32(0x0232a210, 0xff000000, 0x1b000000);
-       clrsetbits_le32(0x0232a214, 0x0000ffff, 0x00006fb8);
-       clrsetbits_le32(0x0232a218, 0xffff00ff, 0x758000e4);
-       clrsetbits_le32(0x0232a2ac, 0x0000ff00, 0x00004400);
-       clrsetbits_le32(0x0232a22c, 0x00ffff00, 0x00200800);
-       clrsetbits_le32(0x0232a280, 0x00ff00ff, 0x00820082);
-       clrsetbits_le32(0x0232a284, 0xffffffff, 0x1d0f0385);
-
-       clrsetbits_le32(0x0232a404, 0xff0000ff, 0x38000080);
-       clrsetbits_le32(0x0232a408, 0x000000ff, 0x00000000);
-       clrsetbits_le32(0x0232a40c, 0xff000000, 0x02000000);
-       clrsetbits_le32(0x0232a410, 0xff000000, 0x1b000000);
-       clrsetbits_le32(0x0232a414, 0x0000ffff, 0x00006fb8);
-       clrsetbits_le32(0x0232a418, 0xffff00ff, 0x758000e4);
-       clrsetbits_le32(0x0232a4ac, 0x0000ff00, 0x00004400);
-       clrsetbits_le32(0x0232a42c, 0x00ffff00, 0x00200800);
-       clrsetbits_le32(0x0232a480, 0x00ff00ff, 0x00820082);
-       clrsetbits_le32(0x0232a484, 0xffffffff, 0x1d0f0385);
-
-       clrsetbits_le32(0x0232a604, 0xff0000ff, 0x38000080);
-       clrsetbits_le32(0x0232a608, 0x000000ff, 0x00000000);
-       clrsetbits_le32(0x0232a60c, 0xff000000, 0x02000000);
-       clrsetbits_le32(0x0232a610, 0xff000000, 0x1b000000);
-       clrsetbits_le32(0x0232a614, 0x0000ffff, 0x00006fb8);
-       clrsetbits_le32(0x0232a618, 0xffff00ff, 0x758000e4);
-       clrsetbits_le32(0x0232a6ac, 0x0000ff00, 0x00004400);
-       clrsetbits_le32(0x0232a62c, 0x00ffff00, 0x00200800);
-       clrsetbits_le32(0x0232a680, 0x00ff00ff, 0x00820082);
-       clrsetbits_le32(0x0232a684, 0xffffffff, 0x1d0f0385);
-
-       clrsetbits_le32(0x0232a804, 0xff0000ff, 0x38000080);
-       clrsetbits_le32(0x0232a808, 0x000000ff, 0x00000000);
-       clrsetbits_le32(0x0232a80c, 0xff000000, 0x02000000);
-       clrsetbits_le32(0x0232a810, 0xff000000, 0x1b000000);
-       clrsetbits_le32(0x0232a814, 0x0000ffff, 0x00006fb8);
-       clrsetbits_le32(0x0232a818, 0xffff00ff, 0x758000e4);
-       clrsetbits_le32(0x0232a8ac, 0x0000ff00, 0x00004400);
-       clrsetbits_le32(0x0232a82c, 0x00ffff00, 0x00200800);
-       clrsetbits_le32(0x0232a880, 0x00ff00ff, 0x00820082);
-       clrsetbits_le32(0x0232a884, 0xffffffff, 0x1d0f0385);
-
-       clrsetbits_le32(0x0232aa00, 0x0000ff00, 0x00000800);
-       clrsetbits_le32(0x0232aa08, 0xffff0000, 0x38a20000);
-       clrsetbits_le32(0x0232aa30, 0x00ffff00, 0x008a8a00);
-       clrsetbits_le32(0x0232aa84, 0x0000ff00, 0x00000600);
-       clrsetbits_le32(0x0232aa94, 0xff000000, 0x10000000);
-       clrsetbits_le32(0x0232aaa0, 0xff000000, 0x81000000);
-       clrsetbits_le32(0x0232aabc, 0xff000000, 0xff000000);
-       clrsetbits_le32(0x0232aac0, 0x000000ff, 0x0000008b);
-       clrsetbits_le32(0x0232ab08, 0xffff0000, 0x583f0000);
-       clrsetbits_le32(0x0232ab0c, 0x000000ff, 0x0000004e);
-       clrsetbits_le32(0x0232a000, 0x000000ff, 0x00000003);
-       clrsetbits_le32(0x0232aa00, 0x000000ff, 0x0000005f);
-
-       clrsetbits_le32(0x0232aa48, 0x00ffff00, 0x00fd8c00);
-       clrsetbits_le32(0x0232aa54, 0x00ffffff, 0x002fec72);
-       clrsetbits_le32(0x0232aa58, 0xffffff00, 0x00f92100);
-       clrsetbits_le32(0x0232aa5c, 0xffffffff, 0x00040060);
-       clrsetbits_le32(0x0232aa60, 0xffffffff, 0x00008000);
-       clrsetbits_le32(0x0232aa64, 0xffffffff, 0x0c581220);
-       clrsetbits_le32(0x0232aa68, 0xffffffff, 0xe13b0602);
-       clrsetbits_le32(0x0232aa6c, 0xffffffff, 0xb8074cc1);
-       clrsetbits_le32(0x0232aa70, 0xffffffff, 0x3f02e989);
-       clrsetbits_le32(0x0232aa74, 0x000000ff, 0x00000001);
-       clrsetbits_le32(0x0232ab20, 0x00ff0000, 0x00370000);
-       clrsetbits_le32(0x0232ab1c, 0xff000000, 0x37000000);
-       clrsetbits_le32(0x0232ab20, 0x000000ff, 0x0000005d);
-
-       /*Bring SerDes out of Reset if SerDes is Shutdown & is in Reset Mode*/
-       clrbits_le32(0x0232a010, 1 << 28);
-
-       /* Enable TX and RX via the LANExCTL_STS 0x0000 + x*4 */
-       clrbits_le32(0x0232a228, 1 << 29);
-       writel(0xF800F8C0, 0x0232bfe0);
-       clrbits_le32(0x0232a428, 1 << 29);
-       writel(0xF800F8C0, 0x0232bfe4);
-       clrbits_le32(0x0232a628, 1 << 29);
-       writel(0xF800F8C0, 0x0232bfe8);
-       clrbits_le32(0x0232a828, 1 << 29);
-       writel(0xF800F8C0, 0x0232bfec);
-
-       /*Enable pll via the pll_ctrl 0x0014*/
-       writel(0xe0000000, 0x0232bff4)
-               ;
-
-       /*Waiting for SGMII Serdes PLL lock.*/
-       for (cnt = 10000; cnt > 0 && ((readl(0x02090114) & 0x10) == 0); cnt--)
-               ;
-
-       for (cnt = 10000; cnt > 0 && ((readl(0x02090214) & 0x10) == 0); cnt--)
-               ;
-
-       for (cnt = 10000; cnt > 0 && ((readl(0x02090414) & 0x10) == 0); cnt--)
-               ;
+       /* Register MDIO bus if it's not registered yet */
+       if (!mdio_bus) {
+               mdio_bus        = mdio_alloc();
+               mdio_bus->read  = keystone2_mdio_read;
+               mdio_bus->write = keystone2_mdio_write;
+               mdio_bus->reset = keystone2_mdio_reset;
+               mdio_bus->priv  = (void *)EMAC_MDIO_BASE_ADDR;
+               sprintf(mdio_bus->name, "ethernet-mdio");
+
+               res = mdio_register(mdio_bus);
+               if (res)
+                       return res;
+       }
 
-       for (cnt = 10000; cnt > 0 && ((readl(0x02090514) & 0x10) == 0); cnt--)
-               ;
+       /* Create phy device and bind it with driver */
+#ifdef CONFIG_KSNET_MDIO_PHY_CONFIG_ENABLE
+       phy_dev = phy_connect(mdio_bus, eth_priv->phy_addr,
+                             dev, PHY_INTERFACE_MODE_SGMII);
+       phy_config(phy_dev);
+#else
+       phy_dev = phy_find_by_mask(mdio_bus, 1 << eth_priv->phy_addr,
+                                  PHY_INTERFACE_MODE_SGMII);
+       phy_dev->dev = dev;
+#endif
+       eth_priv->phy_dev = phy_dev;
 
-       udelay(45000);
+       return 0;
 }
 
-void sgmii_serdes_shutdown(void)
+struct ks2_serdes ks2_serdes_sgmii_156p25mhz = {
+       .clk = SERDES_CLOCK_156P25M,
+       .rate = SERDES_RATE_5G,
+       .rate_mode = SERDES_QUARTER_RATE,
+       .intf = SERDES_PHY_SGMII,
+       .loopback = 0,
+};
+
+static void keystone2_net_serdes_setup(void)
 {
-       /*
-        * shutdown SerDes hardware. SerDes hardware vendor published only
-        * register addresses and their values. So had to use hardcoded
-        * values below.
-        */
-       clrbits_le32(0x0232bfe0, 3 << 29 | 3 << 13);
-       setbits_le32(0x02320228, 1 << 29);
-       clrbits_le32(0x0232bfe4, 3 << 29 | 3 << 13);
-       setbits_le32(0x02320428, 1 << 29);
-       clrbits_le32(0x0232bfe8, 3 << 29 | 3 << 13);
-       setbits_le32(0x02320628, 1 << 29);
-       clrbits_le32(0x0232bfec, 3 << 29 | 3 << 13);
-       setbits_le32(0x02320828, 1 << 29);
-
-       clrbits_le32(0x02320034, 3 << 29);
-       setbits_le32(0x02320010, 1 << 28);
+       ks2_serdes_init(CONFIG_KSNET_SERDES_SGMII_BASE,
+                       &ks2_serdes_sgmii_156p25mhz,
+                       CONFIG_KSNET_SERDES_LANES_PER_SGMII);
+
+#ifdef CONFIG_SOC_K2E
+       ks2_serdes_init(CONFIG_KSNET_SERDES_SGMII2_BASE,
+                       &ks2_serdes_sgmii_156p25mhz,
+                       CONFIG_KSNET_SERDES_LANES_PER_SGMII);
+#endif
+
+       /* wait till setup */
+       udelay(5000);
 }
index 0cd06b6a69df68aa8e9e1410724d89844b131010..6ef6cacb6b87940421bae8d78085eb0ebb5a6e0d 100644 (file)
@@ -24,7 +24,7 @@
 #include <asm/arch/cpu.h>
 
 #if defined(CONFIG_KIRKWOOD)
-#include <asm/arch/kirkwood.h>
+#include <asm/arch/soc.h>
 #elif defined(CONFIG_ORION5X)
 #include <asm/arch/orion5x.h>
 #elif defined(CONFIG_DOVE)
diff --git a/drivers/net/mvneta.c b/drivers/net/mvneta.c
new file mode 100644 (file)
index 0000000..a2a69b4
--- /dev/null
@@ -0,0 +1,1653 @@
+/*
+ * Driver for Marvell NETA network card for Armada XP and Armada 370 SoCs.
+ *
+ * U-Boot version:
+ * Copyright (C) 2014 Stefan Roese <sr@denx.de>
+ *
+ * Based on the Linux version which is:
+ * Copyright (C) 2012 Marvell
+ *
+ * Rami Rosen <rosenr@marvell.com>
+ * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0
+ */
+
+#include <common.h>
+#include <net.h>
+#include <netdev.h>
+#include <config.h>
+#include <malloc.h>
+#include <asm/io.h>
+#include <asm/errno.h>
+#include <phy.h>
+#include <miiphy.h>
+#include <watchdog.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/soc.h>
+#include <linux/compat.h>
+#include <linux/mbus.h>
+
+#if !defined(CONFIG_PHYLIB)
+# error Marvell mvneta requires PHYLIB
+#endif
+
+/* Some linux -> U-Boot compatibility stuff */
+#define netdev_err(dev, fmt, args...)          \
+       printf(fmt, ##args)
+#define netdev_warn(dev, fmt, args...)         \
+       printf(fmt, ##args)
+#define netdev_info(dev, fmt, args...)         \
+       printf(fmt, ##args)
+
+#define CONFIG_NR_CPUS         1
+#define BIT(nr)                        (1UL << (nr))
+#define ETH_HLEN               14      /* Total octets in header */
+
+/* 2(HW hdr) 14(MAC hdr) 4(CRC) 32(extra for cache prefetch) */
+#define WRAP                   (2 + ETH_HLEN + 4 + 32)
+#define MTU                    1500
+#define RX_BUFFER_SIZE         (ALIGN(MTU + WRAP, ARCH_DMA_MINALIGN))
+
+#define MVNETA_SMI_TIMEOUT                     10000
+
+/* Registers */
+#define MVNETA_RXQ_CONFIG_REG(q)                (0x1400 + ((q) << 2))
+#define             MVNETA_RXQ_HW_BUF_ALLOC            BIT(1)
+#define      MVNETA_RXQ_PKT_OFFSET_ALL_MASK     (0xf    << 8)
+#define      MVNETA_RXQ_PKT_OFFSET_MASK(offs)   ((offs) << 8)
+#define MVNETA_RXQ_THRESHOLD_REG(q)             (0x14c0 + ((q) << 2))
+#define      MVNETA_RXQ_NON_OCCUPIED(v)         ((v) << 16)
+#define MVNETA_RXQ_BASE_ADDR_REG(q)             (0x1480 + ((q) << 2))
+#define MVNETA_RXQ_SIZE_REG(q)                  (0x14a0 + ((q) << 2))
+#define      MVNETA_RXQ_BUF_SIZE_SHIFT          19
+#define      MVNETA_RXQ_BUF_SIZE_MASK           (0x1fff << 19)
+#define MVNETA_RXQ_STATUS_REG(q)                (0x14e0 + ((q) << 2))
+#define      MVNETA_RXQ_OCCUPIED_ALL_MASK       0x3fff
+#define MVNETA_RXQ_STATUS_UPDATE_REG(q)         (0x1500 + ((q) << 2))
+#define      MVNETA_RXQ_ADD_NON_OCCUPIED_SHIFT  16
+#define      MVNETA_RXQ_ADD_NON_OCCUPIED_MAX    255
+#define MVNETA_PORT_RX_RESET                    0x1cc0
+#define      MVNETA_PORT_RX_DMA_RESET           BIT(0)
+#define MVNETA_PHY_ADDR                         0x2000
+#define      MVNETA_PHY_ADDR_MASK               0x1f
+#define MVNETA_SMI                              0x2004
+#define      MVNETA_PHY_REG_MASK                0x1f
+/* SMI register fields */
+#define     MVNETA_SMI_DATA_OFFS               0       /* Data */
+#define     MVNETA_SMI_DATA_MASK               (0xffff << MVNETA_SMI_DATA_OFFS)
+#define     MVNETA_SMI_DEV_ADDR_OFFS           16      /* PHY device address */
+#define     MVNETA_SMI_REG_ADDR_OFFS           21      /* PHY device reg addr*/
+#define     MVNETA_SMI_OPCODE_OFFS             26      /* Write/Read opcode */
+#define     MVNETA_SMI_OPCODE_READ             (1 << MVNETA_SMI_OPCODE_OFFS)
+#define     MVNETA_SMI_READ_VALID              (1 << 27)       /* Read Valid */
+#define     MVNETA_SMI_BUSY                    (1 << 28)       /* Busy */
+#define MVNETA_MBUS_RETRY                       0x2010
+#define MVNETA_UNIT_INTR_CAUSE                  0x2080
+#define MVNETA_UNIT_CONTROL                     0x20B0
+#define      MVNETA_PHY_POLLING_ENABLE          BIT(1)
+#define MVNETA_WIN_BASE(w)                      (0x2200 + ((w) << 3))
+#define MVNETA_WIN_SIZE(w)                      (0x2204 + ((w) << 3))
+#define MVNETA_WIN_REMAP(w)                     (0x2280 + ((w) << 2))
+#define MVNETA_BASE_ADDR_ENABLE                 0x2290
+#define MVNETA_PORT_CONFIG                      0x2400
+#define      MVNETA_UNI_PROMISC_MODE            BIT(0)
+#define      MVNETA_DEF_RXQ(q)                  ((q) << 1)
+#define      MVNETA_DEF_RXQ_ARP(q)              ((q) << 4)
+#define      MVNETA_TX_UNSET_ERR_SUM            BIT(12)
+#define      MVNETA_DEF_RXQ_TCP(q)              ((q) << 16)
+#define      MVNETA_DEF_RXQ_UDP(q)              ((q) << 19)
+#define      MVNETA_DEF_RXQ_BPDU(q)             ((q) << 22)
+#define      MVNETA_RX_CSUM_WITH_PSEUDO_HDR     BIT(25)
+#define      MVNETA_PORT_CONFIG_DEFL_VALUE(q)   (MVNETA_DEF_RXQ(q)       | \
+                                                MVNETA_DEF_RXQ_ARP(q)   | \
+                                                MVNETA_DEF_RXQ_TCP(q)   | \
+                                                MVNETA_DEF_RXQ_UDP(q)   | \
+                                                MVNETA_DEF_RXQ_BPDU(q)  | \
+                                                MVNETA_TX_UNSET_ERR_SUM | \
+                                                MVNETA_RX_CSUM_WITH_PSEUDO_HDR)
+#define MVNETA_PORT_CONFIG_EXTEND                0x2404
+#define MVNETA_MAC_ADDR_LOW                      0x2414
+#define MVNETA_MAC_ADDR_HIGH                     0x2418
+#define MVNETA_SDMA_CONFIG                       0x241c
+#define      MVNETA_SDMA_BRST_SIZE_16            4
+#define      MVNETA_RX_BRST_SZ_MASK(burst)       ((burst) << 1)
+#define      MVNETA_RX_NO_DATA_SWAP              BIT(4)
+#define      MVNETA_TX_NO_DATA_SWAP              BIT(5)
+#define      MVNETA_DESC_SWAP                    BIT(6)
+#define      MVNETA_TX_BRST_SZ_MASK(burst)       ((burst) << 22)
+#define MVNETA_PORT_STATUS                       0x2444
+#define      MVNETA_TX_IN_PRGRS                  BIT(1)
+#define      MVNETA_TX_FIFO_EMPTY                BIT(8)
+#define MVNETA_RX_MIN_FRAME_SIZE                 0x247c
+#define MVNETA_SERDES_CFG                       0x24A0
+#define      MVNETA_SGMII_SERDES_PROTO          0x0cc7
+#define      MVNETA_QSGMII_SERDES_PROTO                 0x0667
+#define MVNETA_TYPE_PRIO                         0x24bc
+#define      MVNETA_FORCE_UNI                    BIT(21)
+#define MVNETA_TXQ_CMD_1                         0x24e4
+#define MVNETA_TXQ_CMD                           0x2448
+#define      MVNETA_TXQ_DISABLE_SHIFT            8
+#define      MVNETA_TXQ_ENABLE_MASK              0x000000ff
+#define MVNETA_ACC_MODE                          0x2500
+#define MVNETA_CPU_MAP(cpu)                      (0x2540 + ((cpu) << 2))
+#define      MVNETA_CPU_RXQ_ACCESS_ALL_MASK      0x000000ff
+#define      MVNETA_CPU_TXQ_ACCESS_ALL_MASK      0x0000ff00
+#define MVNETA_RXQ_TIME_COAL_REG(q)              (0x2580 + ((q) << 2))
+
+/* Exception Interrupt Port/Queue Cause register */
+
+#define MVNETA_INTR_NEW_CAUSE                    0x25a0
+#define MVNETA_INTR_NEW_MASK                     0x25a4
+
+/* bits  0..7  = TXQ SENT, one bit per queue.
+ * bits  8..15 = RXQ OCCUP, one bit per queue.
+ * bits 16..23 = RXQ FREE, one bit per queue.
+ * bit  29 = OLD_REG_SUM, see old reg ?
+ * bit  30 = TX_ERR_SUM, one bit for 4 ports
+ * bit  31 = MISC_SUM,   one bit for 4 ports
+ */
+#define      MVNETA_TX_INTR_MASK(nr_txqs)        (((1 << nr_txqs) - 1) << 0)
+#define      MVNETA_TX_INTR_MASK_ALL             (0xff << 0)
+#define      MVNETA_RX_INTR_MASK(nr_rxqs)        (((1 << nr_rxqs) - 1) << 8)
+#define      MVNETA_RX_INTR_MASK_ALL             (0xff << 8)
+
+#define MVNETA_INTR_OLD_CAUSE                    0x25a8
+#define MVNETA_INTR_OLD_MASK                     0x25ac
+
+/* Data Path Port/Queue Cause Register */
+#define MVNETA_INTR_MISC_CAUSE                   0x25b0
+#define MVNETA_INTR_MISC_MASK                    0x25b4
+#define MVNETA_INTR_ENABLE                       0x25b8
+
+#define MVNETA_RXQ_CMD                           0x2680
+#define      MVNETA_RXQ_DISABLE_SHIFT            8
+#define      MVNETA_RXQ_ENABLE_MASK              0x000000ff
+#define MVETH_TXQ_TOKEN_COUNT_REG(q)             (0x2700 + ((q) << 4))
+#define MVETH_TXQ_TOKEN_CFG_REG(q)               (0x2704 + ((q) << 4))
+#define MVNETA_GMAC_CTRL_0                       0x2c00
+#define      MVNETA_GMAC_MAX_RX_SIZE_SHIFT       2
+#define      MVNETA_GMAC_MAX_RX_SIZE_MASK        0x7ffc
+#define      MVNETA_GMAC0_PORT_ENABLE            BIT(0)
+#define MVNETA_GMAC_CTRL_2                       0x2c08
+#define      MVNETA_GMAC2_PCS_ENABLE             BIT(3)
+#define      MVNETA_GMAC2_PORT_RGMII             BIT(4)
+#define      MVNETA_GMAC2_PORT_RESET             BIT(6)
+#define MVNETA_GMAC_STATUS                       0x2c10
+#define      MVNETA_GMAC_LINK_UP                 BIT(0)
+#define      MVNETA_GMAC_SPEED_1000              BIT(1)
+#define      MVNETA_GMAC_SPEED_100               BIT(2)
+#define      MVNETA_GMAC_FULL_DUPLEX             BIT(3)
+#define      MVNETA_GMAC_RX_FLOW_CTRL_ENABLE     BIT(4)
+#define      MVNETA_GMAC_TX_FLOW_CTRL_ENABLE     BIT(5)
+#define      MVNETA_GMAC_RX_FLOW_CTRL_ACTIVE     BIT(6)
+#define      MVNETA_GMAC_TX_FLOW_CTRL_ACTIVE     BIT(7)
+#define MVNETA_GMAC_AUTONEG_CONFIG               0x2c0c
+#define      MVNETA_GMAC_FORCE_LINK_DOWN         BIT(0)
+#define      MVNETA_GMAC_FORCE_LINK_PASS         BIT(1)
+#define      MVNETA_GMAC_CONFIG_MII_SPEED        BIT(5)
+#define      MVNETA_GMAC_CONFIG_GMII_SPEED       BIT(6)
+#define      MVNETA_GMAC_AN_SPEED_EN             BIT(7)
+#define      MVNETA_GMAC_CONFIG_FULL_DUPLEX      BIT(12)
+#define      MVNETA_GMAC_AN_DUPLEX_EN            BIT(13)
+#define MVNETA_MIB_COUNTERS_BASE                 0x3080
+#define      MVNETA_MIB_LATE_COLLISION           0x7c
+#define MVNETA_DA_FILT_SPEC_MCAST                0x3400
+#define MVNETA_DA_FILT_OTH_MCAST                 0x3500
+#define MVNETA_DA_FILT_UCAST_BASE                0x3600
+#define MVNETA_TXQ_BASE_ADDR_REG(q)              (0x3c00 + ((q) << 2))
+#define MVNETA_TXQ_SIZE_REG(q)                   (0x3c20 + ((q) << 2))
+#define      MVNETA_TXQ_SENT_THRESH_ALL_MASK     0x3fff0000
+#define      MVNETA_TXQ_SENT_THRESH_MASK(coal)   ((coal) << 16)
+#define MVNETA_TXQ_UPDATE_REG(q)                 (0x3c60 + ((q) << 2))
+#define      MVNETA_TXQ_DEC_SENT_SHIFT           16
+#define MVNETA_TXQ_STATUS_REG(q)                 (0x3c40 + ((q) << 2))
+#define      MVNETA_TXQ_SENT_DESC_SHIFT          16
+#define      MVNETA_TXQ_SENT_DESC_MASK           0x3fff0000
+#define MVNETA_PORT_TX_RESET                     0x3cf0
+#define      MVNETA_PORT_TX_DMA_RESET            BIT(0)
+#define MVNETA_TX_MTU                            0x3e0c
+#define MVNETA_TX_TOKEN_SIZE                     0x3e14
+#define      MVNETA_TX_TOKEN_SIZE_MAX            0xffffffff
+#define MVNETA_TXQ_TOKEN_SIZE_REG(q)             (0x3e40 + ((q) << 2))
+#define      MVNETA_TXQ_TOKEN_SIZE_MAX           0x7fffffff
+
+/* Descriptor ring Macros */
+#define MVNETA_QUEUE_NEXT_DESC(q, index)       \
+       (((index) < (q)->last_desc) ? ((index) + 1) : 0)
+
+/* Various constants */
+
+/* Coalescing */
+#define MVNETA_TXDONE_COAL_PKTS                16
+#define MVNETA_RX_COAL_PKTS            32
+#define MVNETA_RX_COAL_USEC            100
+
+/* The two bytes Marvell header. Either contains a special value used
+ * by Marvell switches when a specific hardware mode is enabled (not
+ * supported by this driver) or is filled automatically by zeroes on
+ * the RX side. Those two bytes being at the front of the Ethernet
+ * header, they allow to have the IP header aligned on a 4 bytes
+ * boundary automatically: the hardware skips those two bytes on its
+ * own.
+ */
+#define MVNETA_MH_SIZE                 2
+
+#define MVNETA_VLAN_TAG_LEN             4
+
+#define MVNETA_CPU_D_CACHE_LINE_SIZE    32
+#define MVNETA_TX_CSUM_MAX_SIZE                9800
+#define MVNETA_ACC_MODE_EXT            1
+
+/* Timeout constants */
+#define MVNETA_TX_DISABLE_TIMEOUT_MSEC 1000
+#define MVNETA_RX_DISABLE_TIMEOUT_MSEC 1000
+#define MVNETA_TX_FIFO_EMPTY_TIMEOUT   10000
+
+#define MVNETA_TX_MTU_MAX              0x3ffff
+
+/* Max number of Rx descriptors */
+#define MVNETA_MAX_RXD 16
+
+/* Max number of Tx descriptors */
+#define MVNETA_MAX_TXD 16
+
+/* descriptor aligned size */
+#define MVNETA_DESC_ALIGNED_SIZE       32
+
+struct mvneta_port {
+       void __iomem *base;
+       struct mvneta_rx_queue *rxqs;
+       struct mvneta_tx_queue *txqs;
+
+       u8 mcast_count[256];
+       u16 tx_ring_size;
+       u16 rx_ring_size;
+
+       phy_interface_t phy_interface;
+       unsigned int link;
+       unsigned int duplex;
+       unsigned int speed;
+
+       int init;
+       int phyaddr;
+       struct phy_device *phydev;
+       struct mii_dev *bus;
+};
+
+/* The mvneta_tx_desc and mvneta_rx_desc structures describe the
+ * layout of the transmit and reception DMA descriptors, and their
+ * layout is therefore defined by the hardware design
+ */
+
+#define MVNETA_TX_L3_OFF_SHIFT 0
+#define MVNETA_TX_IP_HLEN_SHIFT        8
+#define MVNETA_TX_L4_UDP       BIT(16)
+#define MVNETA_TX_L3_IP6       BIT(17)
+#define MVNETA_TXD_IP_CSUM     BIT(18)
+#define MVNETA_TXD_Z_PAD       BIT(19)
+#define MVNETA_TXD_L_DESC      BIT(20)
+#define MVNETA_TXD_F_DESC      BIT(21)
+#define MVNETA_TXD_FLZ_DESC    (MVNETA_TXD_Z_PAD  | \
+                                MVNETA_TXD_L_DESC | \
+                                MVNETA_TXD_F_DESC)
+#define MVNETA_TX_L4_CSUM_FULL BIT(30)
+#define MVNETA_TX_L4_CSUM_NOT  BIT(31)
+
+#define MVNETA_RXD_ERR_CRC             0x0
+#define MVNETA_RXD_ERR_SUMMARY         BIT(16)
+#define MVNETA_RXD_ERR_OVERRUN         BIT(17)
+#define MVNETA_RXD_ERR_LEN             BIT(18)
+#define MVNETA_RXD_ERR_RESOURCE                (BIT(17) | BIT(18))
+#define MVNETA_RXD_ERR_CODE_MASK       (BIT(17) | BIT(18))
+#define MVNETA_RXD_L3_IP4              BIT(25)
+#define MVNETA_RXD_FIRST_LAST_DESC     (BIT(26) | BIT(27))
+#define MVNETA_RXD_L4_CSUM_OK          BIT(30)
+
+struct mvneta_tx_desc {
+       u32  command;           /* Options used by HW for packet transmitting.*/
+       u16  reserverd1;        /* csum_l4 (for future use)             */
+       u16  data_size;         /* Data size of transmitted packet in bytes */
+       u32  buf_phys_addr;     /* Physical addr of transmitted buffer  */
+       u32  reserved2;         /* hw_cmd - (for future use, PMT)       */
+       u32  reserved3[4];      /* Reserved - (for future use)          */
+};
+
+struct mvneta_rx_desc {
+       u32  status;            /* Info about received packet           */
+       u16  reserved1;         /* pnc_info - (for future use, PnC)     */
+       u16  data_size;         /* Size of received packet in bytes     */
+
+       u32  buf_phys_addr;     /* Physical address of the buffer       */
+       u32  reserved2;         /* pnc_flow_id  (for future use, PnC)   */
+
+       u32  buf_cookie;        /* cookie for access to RX buffer in rx path */
+       u16  reserved3;         /* prefetch_cmd, for future use         */
+       u16  reserved4;         /* csum_l4 - (for future use, PnC)      */
+
+       u32  reserved5;         /* pnc_extra PnC (for future use, PnC)  */
+       u32  reserved6;         /* hw_cmd (for future use, PnC and HWF) */
+};
+
+struct mvneta_tx_queue {
+       /* Number of this TX queue, in the range 0-7 */
+       u8 id;
+
+       /* Number of TX DMA descriptors in the descriptor ring */
+       int size;
+
+       /* Index of last TX DMA descriptor that was inserted */
+       int txq_put_index;
+
+       /* Index of the TX DMA descriptor to be cleaned up */
+       int txq_get_index;
+
+       /* Virtual address of the TX DMA descriptors array */
+       struct mvneta_tx_desc *descs;
+
+       /* DMA address of the TX DMA descriptors array */
+       dma_addr_t descs_phys;
+
+       /* Index of the last TX DMA descriptor */
+       int last_desc;
+
+       /* Index of the next TX DMA descriptor to process */
+       int next_desc_to_proc;
+};
+
+struct mvneta_rx_queue {
+       /* rx queue number, in the range 0-7 */
+       u8 id;
+
+       /* num of rx descriptors in the rx descriptor ring */
+       int size;
+
+       /* Virtual address of the RX DMA descriptors array */
+       struct mvneta_rx_desc *descs;
+
+       /* DMA address of the RX DMA descriptors array */
+       dma_addr_t descs_phys;
+
+       /* Index of the last RX DMA descriptor */
+       int last_desc;
+
+       /* Index of the next RX DMA descriptor to process */
+       int next_desc_to_proc;
+};
+
+/* U-Boot doesn't use the queues, so set the number to 1 */
+static int rxq_number = 1;
+static int txq_number = 1;
+static int rxq_def;
+
+struct buffer_location {
+       struct mvneta_tx_desc *tx_descs;
+       struct mvneta_rx_desc *rx_descs;
+       u32 rx_buffers;
+};
+
+/*
+ * All 4 interfaces use the same global buffer, since only one interface
+ * can be enabled at once
+ */
+static struct buffer_location buffer_loc;
+
+/*
+ * Page table entries are set to 1MB, or multiples of 1MB
+ * (not < 1MB). driver uses less bd's so use 1MB bdspace.
+ */
+#define BD_SPACE       (1 << 20)
+
+/* Utility/helper methods */
+
+/* Write helper method */
+static void mvreg_write(struct mvneta_port *pp, u32 offset, u32 data)
+{
+       writel(data, pp->base + offset);
+}
+
+/* Read helper method */
+static u32 mvreg_read(struct mvneta_port *pp, u32 offset)
+{
+       return readl(pp->base + offset);
+}
+
+/* Clear all MIB counters */
+static void mvneta_mib_counters_clear(struct mvneta_port *pp)
+{
+       int i;
+
+       /* Perform dummy reads from MIB counters */
+       for (i = 0; i < MVNETA_MIB_LATE_COLLISION; i += 4)
+               mvreg_read(pp, (MVNETA_MIB_COUNTERS_BASE + i));
+}
+
+/* Rx descriptors helper methods */
+
+/* Checks whether the RX descriptor having this status is both the first
+ * and the last descriptor for the RX packet. Each RX packet is currently
+ * received through a single RX descriptor, so not having each RX
+ * descriptor with its first and last bits set is an error
+ */
+static int mvneta_rxq_desc_is_first_last(u32 status)
+{
+       return (status & MVNETA_RXD_FIRST_LAST_DESC) ==
+               MVNETA_RXD_FIRST_LAST_DESC;
+}
+
+/* Add number of descriptors ready to receive new packets */
+static void mvneta_rxq_non_occup_desc_add(struct mvneta_port *pp,
+                                         struct mvneta_rx_queue *rxq,
+                                         int ndescs)
+{
+       /* Only MVNETA_RXQ_ADD_NON_OCCUPIED_MAX (255) descriptors can
+        * be added at once
+        */
+       while (ndescs > MVNETA_RXQ_ADD_NON_OCCUPIED_MAX) {
+               mvreg_write(pp, MVNETA_RXQ_STATUS_UPDATE_REG(rxq->id),
+                           (MVNETA_RXQ_ADD_NON_OCCUPIED_MAX <<
+                            MVNETA_RXQ_ADD_NON_OCCUPIED_SHIFT));
+               ndescs -= MVNETA_RXQ_ADD_NON_OCCUPIED_MAX;
+       }
+
+       mvreg_write(pp, MVNETA_RXQ_STATUS_UPDATE_REG(rxq->id),
+                   (ndescs << MVNETA_RXQ_ADD_NON_OCCUPIED_SHIFT));
+}
+
+/* Get number of RX descriptors occupied by received packets */
+static int mvneta_rxq_busy_desc_num_get(struct mvneta_port *pp,
+                                       struct mvneta_rx_queue *rxq)
+{
+       u32 val;
+
+       val = mvreg_read(pp, MVNETA_RXQ_STATUS_REG(rxq->id));
+       return val & MVNETA_RXQ_OCCUPIED_ALL_MASK;
+}
+
+/* Update num of rx desc called upon return from rx path or
+ * from mvneta_rxq_drop_pkts().
+ */
+static void mvneta_rxq_desc_num_update(struct mvneta_port *pp,
+                                      struct mvneta_rx_queue *rxq,
+                                      int rx_done, int rx_filled)
+{
+       u32 val;
+
+       if ((rx_done <= 0xff) && (rx_filled <= 0xff)) {
+               val = rx_done |
+                 (rx_filled << MVNETA_RXQ_ADD_NON_OCCUPIED_SHIFT);
+               mvreg_write(pp, MVNETA_RXQ_STATUS_UPDATE_REG(rxq->id), val);
+               return;
+       }
+
+       /* Only 255 descriptors can be added at once */
+       while ((rx_done > 0) || (rx_filled > 0)) {
+               if (rx_done <= 0xff) {
+                       val = rx_done;
+                       rx_done = 0;
+               } else {
+                       val = 0xff;
+                       rx_done -= 0xff;
+               }
+               if (rx_filled <= 0xff) {
+                       val |= rx_filled << MVNETA_RXQ_ADD_NON_OCCUPIED_SHIFT;
+                       rx_filled = 0;
+               } else {
+                       val |= 0xff << MVNETA_RXQ_ADD_NON_OCCUPIED_SHIFT;
+                       rx_filled -= 0xff;
+               }
+               mvreg_write(pp, MVNETA_RXQ_STATUS_UPDATE_REG(rxq->id), val);
+       }
+}
+
+/* Get pointer to next RX descriptor to be processed by SW */
+static struct mvneta_rx_desc *
+mvneta_rxq_next_desc_get(struct mvneta_rx_queue *rxq)
+{
+       int rx_desc = rxq->next_desc_to_proc;
+
+       rxq->next_desc_to_proc = MVNETA_QUEUE_NEXT_DESC(rxq, rx_desc);
+       return rxq->descs + rx_desc;
+}
+
+/* Tx descriptors helper methods */
+
+/* Update HW with number of TX descriptors to be sent */
+static void mvneta_txq_pend_desc_add(struct mvneta_port *pp,
+                                    struct mvneta_tx_queue *txq,
+                                    int pend_desc)
+{
+       u32 val;
+
+       /* Only 255 descriptors can be added at once ; Assume caller
+        * process TX desriptors in quanta less than 256
+        */
+       val = pend_desc;
+       mvreg_write(pp, MVNETA_TXQ_UPDATE_REG(txq->id), val);
+}
+
+/* Get pointer to next TX descriptor to be processed (send) by HW */
+static struct mvneta_tx_desc *
+mvneta_txq_next_desc_get(struct mvneta_tx_queue *txq)
+{
+       int tx_desc = txq->next_desc_to_proc;
+
+       txq->next_desc_to_proc = MVNETA_QUEUE_NEXT_DESC(txq, tx_desc);
+       return txq->descs + tx_desc;
+}
+
+/* Set rxq buf size */
+static void mvneta_rxq_buf_size_set(struct mvneta_port *pp,
+                                   struct mvneta_rx_queue *rxq,
+                                   int buf_size)
+{
+       u32 val;
+
+       val = mvreg_read(pp, MVNETA_RXQ_SIZE_REG(rxq->id));
+
+       val &= ~MVNETA_RXQ_BUF_SIZE_MASK;
+       val |= ((buf_size >> 3) << MVNETA_RXQ_BUF_SIZE_SHIFT);
+
+       mvreg_write(pp, MVNETA_RXQ_SIZE_REG(rxq->id), val);
+}
+
+/* Start the Ethernet port RX and TX activity */
+static void mvneta_port_up(struct mvneta_port *pp)
+{
+       int queue;
+       u32 q_map;
+
+       /* Enable all initialized TXs. */
+       mvneta_mib_counters_clear(pp);
+       q_map = 0;
+       for (queue = 0; queue < txq_number; queue++) {
+               struct mvneta_tx_queue *txq = &pp->txqs[queue];
+               if (txq->descs != NULL)
+                       q_map |= (1 << queue);
+       }
+       mvreg_write(pp, MVNETA_TXQ_CMD, q_map);
+
+       /* Enable all initialized RXQs. */
+       q_map = 0;
+       for (queue = 0; queue < rxq_number; queue++) {
+               struct mvneta_rx_queue *rxq = &pp->rxqs[queue];
+               if (rxq->descs != NULL)
+                       q_map |= (1 << queue);
+       }
+       mvreg_write(pp, MVNETA_RXQ_CMD, q_map);
+}
+
+/* Stop the Ethernet port activity */
+static void mvneta_port_down(struct mvneta_port *pp)
+{
+       u32 val;
+       int count;
+
+       /* Stop Rx port activity. Check port Rx activity. */
+       val = mvreg_read(pp, MVNETA_RXQ_CMD) & MVNETA_RXQ_ENABLE_MASK;
+
+       /* Issue stop command for active channels only */
+       if (val != 0)
+               mvreg_write(pp, MVNETA_RXQ_CMD,
+                           val << MVNETA_RXQ_DISABLE_SHIFT);
+
+       /* Wait for all Rx activity to terminate. */
+       count = 0;
+       do {
+               if (count++ >= MVNETA_RX_DISABLE_TIMEOUT_MSEC) {
+                       netdev_warn(pp->dev,
+                                   "TIMEOUT for RX stopped ! rx_queue_cmd: 0x08%x\n",
+                                   val);
+                       break;
+               }
+               mdelay(1);
+
+               val = mvreg_read(pp, MVNETA_RXQ_CMD);
+       } while (val & 0xff);
+
+       /* Stop Tx port activity. Check port Tx activity. Issue stop
+        * command for active channels only
+        */
+       val = (mvreg_read(pp, MVNETA_TXQ_CMD)) & MVNETA_TXQ_ENABLE_MASK;
+
+       if (val != 0)
+               mvreg_write(pp, MVNETA_TXQ_CMD,
+                           (val << MVNETA_TXQ_DISABLE_SHIFT));
+
+       /* Wait for all Tx activity to terminate. */
+       count = 0;
+       do {
+               if (count++ >= MVNETA_TX_DISABLE_TIMEOUT_MSEC) {
+                       netdev_warn(pp->dev,
+                                   "TIMEOUT for TX stopped status=0x%08x\n",
+                                   val);
+                       break;
+               }
+               mdelay(1);
+
+               /* Check TX Command reg that all Txqs are stopped */
+               val = mvreg_read(pp, MVNETA_TXQ_CMD);
+
+       } while (val & 0xff);
+
+       /* Double check to verify that TX FIFO is empty */
+       count = 0;
+       do {
+               if (count++ >= MVNETA_TX_FIFO_EMPTY_TIMEOUT) {
+                       netdev_warn(pp->dev,
+                                   "TX FIFO empty timeout status=0x08%x\n",
+                                   val);
+                       break;
+               }
+               mdelay(1);
+
+               val = mvreg_read(pp, MVNETA_PORT_STATUS);
+       } while (!(val & MVNETA_TX_FIFO_EMPTY) &&
+                (val & MVNETA_TX_IN_PRGRS));
+
+       udelay(200);
+}
+
+/* Enable the port by setting the port enable bit of the MAC control register */
+static void mvneta_port_enable(struct mvneta_port *pp)
+{
+       u32 val;
+
+       /* Enable port */
+       val = mvreg_read(pp, MVNETA_GMAC_CTRL_0);
+       val |= MVNETA_GMAC0_PORT_ENABLE;
+       mvreg_write(pp, MVNETA_GMAC_CTRL_0, val);
+}
+
+/* Disable the port and wait for about 200 usec before retuning */
+static void mvneta_port_disable(struct mvneta_port *pp)
+{
+       u32 val;
+
+       /* Reset the Enable bit in the Serial Control Register */
+       val = mvreg_read(pp, MVNETA_GMAC_CTRL_0);
+       val &= ~MVNETA_GMAC0_PORT_ENABLE;
+       mvreg_write(pp, MVNETA_GMAC_CTRL_0, val);
+
+       udelay(200);
+}
+
+/* Multicast tables methods */
+
+/* Set all entries in Unicast MAC Table; queue==-1 means reject all */
+static void mvneta_set_ucast_table(struct mvneta_port *pp, int queue)
+{
+       int offset;
+       u32 val;
+
+       if (queue == -1) {
+               val = 0;
+       } else {
+               val = 0x1 | (queue << 1);
+               val |= (val << 24) | (val << 16) | (val << 8);
+       }
+
+       for (offset = 0; offset <= 0xc; offset += 4)
+               mvreg_write(pp, MVNETA_DA_FILT_UCAST_BASE + offset, val);
+}
+
+/* Set all entries in Special Multicast MAC Table; queue==-1 means reject all */
+static void mvneta_set_special_mcast_table(struct mvneta_port *pp, int queue)
+{
+       int offset;
+       u32 val;
+
+       if (queue == -1) {
+               val = 0;
+       } else {
+               val = 0x1 | (queue << 1);
+               val |= (val << 24) | (val << 16) | (val << 8);
+       }
+
+       for (offset = 0; offset <= 0xfc; offset += 4)
+               mvreg_write(pp, MVNETA_DA_FILT_SPEC_MCAST + offset, val);
+}
+
+/* Set all entries in Other Multicast MAC Table. queue==-1 means reject all */
+static void mvneta_set_other_mcast_table(struct mvneta_port *pp, int queue)
+{
+       int offset;
+       u32 val;
+
+       if (queue == -1) {
+               memset(pp->mcast_count, 0, sizeof(pp->mcast_count));
+               val = 0;
+       } else {
+               memset(pp->mcast_count, 1, sizeof(pp->mcast_count));
+               val = 0x1 | (queue << 1);
+               val |= (val << 24) | (val << 16) | (val << 8);
+       }
+
+       for (offset = 0; offset <= 0xfc; offset += 4)
+               mvreg_write(pp, MVNETA_DA_FILT_OTH_MCAST + offset, val);
+}
+
+/* This method sets defaults to the NETA port:
+ *     Clears interrupt Cause and Mask registers.
+ *     Clears all MAC tables.
+ *     Sets defaults to all registers.
+ *     Resets RX and TX descriptor rings.
+ *     Resets PHY.
+ * This method can be called after mvneta_port_down() to return the port
+ *     settings to defaults.
+ */
+static void mvneta_defaults_set(struct mvneta_port *pp)
+{
+       int cpu;
+       int queue;
+       u32 val;
+
+       /* Clear all Cause registers */
+       mvreg_write(pp, MVNETA_INTR_NEW_CAUSE, 0);
+       mvreg_write(pp, MVNETA_INTR_OLD_CAUSE, 0);
+       mvreg_write(pp, MVNETA_INTR_MISC_CAUSE, 0);
+
+       /* Mask all interrupts */
+       mvreg_write(pp, MVNETA_INTR_NEW_MASK, 0);
+       mvreg_write(pp, MVNETA_INTR_OLD_MASK, 0);
+       mvreg_write(pp, MVNETA_INTR_MISC_MASK, 0);
+       mvreg_write(pp, MVNETA_INTR_ENABLE, 0);
+
+       /* Enable MBUS Retry bit16 */
+       mvreg_write(pp, MVNETA_MBUS_RETRY, 0x20);
+
+       /* Set CPU queue access map - all CPUs have access to all RX
+        * queues and to all TX queues
+        */
+       for (cpu = 0; cpu < CONFIG_NR_CPUS; cpu++)
+               mvreg_write(pp, MVNETA_CPU_MAP(cpu),
+                           (MVNETA_CPU_RXQ_ACCESS_ALL_MASK |
+                            MVNETA_CPU_TXQ_ACCESS_ALL_MASK));
+
+       /* Reset RX and TX DMAs */
+       mvreg_write(pp, MVNETA_PORT_RX_RESET, MVNETA_PORT_RX_DMA_RESET);
+       mvreg_write(pp, MVNETA_PORT_TX_RESET, MVNETA_PORT_TX_DMA_RESET);
+
+       /* Disable Legacy WRR, Disable EJP, Release from reset */
+       mvreg_write(pp, MVNETA_TXQ_CMD_1, 0);
+       for (queue = 0; queue < txq_number; queue++) {
+               mvreg_write(pp, MVETH_TXQ_TOKEN_COUNT_REG(queue), 0);
+               mvreg_write(pp, MVETH_TXQ_TOKEN_CFG_REG(queue), 0);
+       }
+
+       mvreg_write(pp, MVNETA_PORT_TX_RESET, 0);
+       mvreg_write(pp, MVNETA_PORT_RX_RESET, 0);
+
+       /* Set Port Acceleration Mode */
+       val = MVNETA_ACC_MODE_EXT;
+       mvreg_write(pp, MVNETA_ACC_MODE, val);
+
+       /* Update val of portCfg register accordingly with all RxQueue types */
+       val = MVNETA_PORT_CONFIG_DEFL_VALUE(rxq_def);
+       mvreg_write(pp, MVNETA_PORT_CONFIG, val);
+
+       val = 0;
+       mvreg_write(pp, MVNETA_PORT_CONFIG_EXTEND, val);
+       mvreg_write(pp, MVNETA_RX_MIN_FRAME_SIZE, 64);
+
+       /* Build PORT_SDMA_CONFIG_REG */
+       val = 0;
+
+       /* Default burst size */
+       val |= MVNETA_TX_BRST_SZ_MASK(MVNETA_SDMA_BRST_SIZE_16);
+       val |= MVNETA_RX_BRST_SZ_MASK(MVNETA_SDMA_BRST_SIZE_16);
+       val |= MVNETA_RX_NO_DATA_SWAP | MVNETA_TX_NO_DATA_SWAP;
+
+       /* Assign port SDMA configuration */
+       mvreg_write(pp, MVNETA_SDMA_CONFIG, val);
+
+       /* Enable PHY polling in hardware for U-Boot */
+       val = mvreg_read(pp, MVNETA_UNIT_CONTROL);
+       val |= MVNETA_PHY_POLLING_ENABLE;
+       mvreg_write(pp, MVNETA_UNIT_CONTROL, val);
+
+       mvneta_set_ucast_table(pp, -1);
+       mvneta_set_special_mcast_table(pp, -1);
+       mvneta_set_other_mcast_table(pp, -1);
+}
+
+/* Set unicast address */
+static void mvneta_set_ucast_addr(struct mvneta_port *pp, u8 last_nibble,
+                                 int queue)
+{
+       unsigned int unicast_reg;
+       unsigned int tbl_offset;
+       unsigned int reg_offset;
+
+       /* Locate the Unicast table entry */
+       last_nibble = (0xf & last_nibble);
+
+       /* offset from unicast tbl base */
+       tbl_offset = (last_nibble / 4) * 4;
+
+       /* offset within the above reg  */
+       reg_offset = last_nibble % 4;
+
+       unicast_reg = mvreg_read(pp, (MVNETA_DA_FILT_UCAST_BASE + tbl_offset));
+
+       if (queue == -1) {
+               /* Clear accepts frame bit at specified unicast DA tbl entry */
+               unicast_reg &= ~(0xff << (8 * reg_offset));
+       } else {
+               unicast_reg &= ~(0xff << (8 * reg_offset));
+               unicast_reg |= ((0x01 | (queue << 1)) << (8 * reg_offset));
+       }
+
+       mvreg_write(pp, (MVNETA_DA_FILT_UCAST_BASE + tbl_offset), unicast_reg);
+}
+
+/* Set mac address */
+static void mvneta_mac_addr_set(struct mvneta_port *pp, unsigned char *addr,
+                               int queue)
+{
+       unsigned int mac_h;
+       unsigned int mac_l;
+
+       if (queue != -1) {
+               mac_l = (addr[4] << 8) | (addr[5]);
+               mac_h = (addr[0] << 24) | (addr[1] << 16) |
+                       (addr[2] << 8) | (addr[3] << 0);
+
+               mvreg_write(pp, MVNETA_MAC_ADDR_LOW, mac_l);
+               mvreg_write(pp, MVNETA_MAC_ADDR_HIGH, mac_h);
+       }
+
+       /* Accept frames of this address */
+       mvneta_set_ucast_addr(pp, addr[5], queue);
+}
+
+/* Handle rx descriptor fill by setting buf_cookie and buf_phys_addr */
+static void mvneta_rx_desc_fill(struct mvneta_rx_desc *rx_desc,
+                               u32 phys_addr, u32 cookie)
+{
+       rx_desc->buf_cookie = cookie;
+       rx_desc->buf_phys_addr = phys_addr;
+}
+
+/* Decrement sent descriptors counter */
+static void mvneta_txq_sent_desc_dec(struct mvneta_port *pp,
+                                    struct mvneta_tx_queue *txq,
+                                    int sent_desc)
+{
+       u32 val;
+
+       /* Only 255 TX descriptors can be updated at once */
+       while (sent_desc > 0xff) {
+               val = 0xff << MVNETA_TXQ_DEC_SENT_SHIFT;
+               mvreg_write(pp, MVNETA_TXQ_UPDATE_REG(txq->id), val);
+               sent_desc = sent_desc - 0xff;
+       }
+
+       val = sent_desc << MVNETA_TXQ_DEC_SENT_SHIFT;
+       mvreg_write(pp, MVNETA_TXQ_UPDATE_REG(txq->id), val);
+}
+
+/* Get number of TX descriptors already sent by HW */
+static int mvneta_txq_sent_desc_num_get(struct mvneta_port *pp,
+                                       struct mvneta_tx_queue *txq)
+{
+       u32 val;
+       int sent_desc;
+
+       val = mvreg_read(pp, MVNETA_TXQ_STATUS_REG(txq->id));
+       sent_desc = (val & MVNETA_TXQ_SENT_DESC_MASK) >>
+               MVNETA_TXQ_SENT_DESC_SHIFT;
+
+       return sent_desc;
+}
+
+/* Display more error info */
+static void mvneta_rx_error(struct mvneta_port *pp,
+                           struct mvneta_rx_desc *rx_desc)
+{
+       u32 status = rx_desc->status;
+
+       if (!mvneta_rxq_desc_is_first_last(status)) {
+               netdev_err(pp->dev,
+                          "bad rx status %08x (buffer oversize), size=%d\n",
+                          status, rx_desc->data_size);
+               return;
+       }
+
+       switch (status & MVNETA_RXD_ERR_CODE_MASK) {
+       case MVNETA_RXD_ERR_CRC:
+               netdev_err(pp->dev, "bad rx status %08x (crc error), size=%d\n",
+                          status, rx_desc->data_size);
+               break;
+       case MVNETA_RXD_ERR_OVERRUN:
+               netdev_err(pp->dev, "bad rx status %08x (overrun error), size=%d\n",
+                          status, rx_desc->data_size);
+               break;
+       case MVNETA_RXD_ERR_LEN:
+               netdev_err(pp->dev, "bad rx status %08x (max frame length error), size=%d\n",
+                          status, rx_desc->data_size);
+               break;
+       case MVNETA_RXD_ERR_RESOURCE:
+               netdev_err(pp->dev, "bad rx status %08x (resource error), size=%d\n",
+                          status, rx_desc->data_size);
+               break;
+       }
+}
+
+static struct mvneta_rx_queue *mvneta_rxq_handle_get(struct mvneta_port *pp,
+                                                    int rxq)
+{
+       return &pp->rxqs[rxq];
+}
+
+
+/* Drop packets received by the RXQ and free buffers */
+static void mvneta_rxq_drop_pkts(struct mvneta_port *pp,
+                                struct mvneta_rx_queue *rxq)
+{
+       int rx_done;
+
+       rx_done = mvneta_rxq_busy_desc_num_get(pp, rxq);
+       if (rx_done)
+               mvneta_rxq_desc_num_update(pp, rxq, rx_done, rx_done);
+}
+
+/* Handle rxq fill: allocates rxq skbs; called when initializing a port */
+static int mvneta_rxq_fill(struct mvneta_port *pp, struct mvneta_rx_queue *rxq,
+                          int num)
+{
+       int i;
+
+       for (i = 0; i < num; i++) {
+               u32 addr;
+
+               /* U-Boot special: Fill in the rx buffer addresses */
+               addr = buffer_loc.rx_buffers + (i * RX_BUFFER_SIZE);
+               mvneta_rx_desc_fill(rxq->descs + i, addr, addr);
+       }
+
+       /* Add this number of RX descriptors as non occupied (ready to
+        * get packets)
+        */
+       mvneta_rxq_non_occup_desc_add(pp, rxq, i);
+
+       return 0;
+}
+
+/* Rx/Tx queue initialization/cleanup methods */
+
+/* Create a specified RX queue */
+static int mvneta_rxq_init(struct mvneta_port *pp,
+                          struct mvneta_rx_queue *rxq)
+
+{
+       rxq->size = pp->rx_ring_size;
+
+       /* Allocate memory for RX descriptors */
+       rxq->descs_phys = (dma_addr_t)rxq->descs;
+       if (rxq->descs == NULL)
+               return -ENOMEM;
+
+       rxq->last_desc = rxq->size - 1;
+
+       /* Set Rx descriptors queue starting address */
+       mvreg_write(pp, MVNETA_RXQ_BASE_ADDR_REG(rxq->id), rxq->descs_phys);
+       mvreg_write(pp, MVNETA_RXQ_SIZE_REG(rxq->id), rxq->size);
+
+       /* Fill RXQ with buffers from RX pool */
+       mvneta_rxq_buf_size_set(pp, rxq, RX_BUFFER_SIZE);
+       mvneta_rxq_fill(pp, rxq, rxq->size);
+
+       return 0;
+}
+
+/* Cleanup Rx queue */
+static void mvneta_rxq_deinit(struct mvneta_port *pp,
+                             struct mvneta_rx_queue *rxq)
+{
+       mvneta_rxq_drop_pkts(pp, rxq);
+
+       rxq->descs             = NULL;
+       rxq->last_desc         = 0;
+       rxq->next_desc_to_proc = 0;
+       rxq->descs_phys        = 0;
+}
+
+/* Create and initialize a tx queue */
+static int mvneta_txq_init(struct mvneta_port *pp,
+                          struct mvneta_tx_queue *txq)
+{
+       txq->size = pp->tx_ring_size;
+
+       /* Allocate memory for TX descriptors */
+       txq->descs_phys = (u32)txq->descs;
+       if (txq->descs == NULL)
+               return -ENOMEM;
+
+       txq->last_desc = txq->size - 1;
+
+       /* Set maximum bandwidth for enabled TXQs */
+       mvreg_write(pp, MVETH_TXQ_TOKEN_CFG_REG(txq->id), 0x03ffffff);
+       mvreg_write(pp, MVETH_TXQ_TOKEN_COUNT_REG(txq->id), 0x3fffffff);
+
+       /* Set Tx descriptors queue starting address */
+       mvreg_write(pp, MVNETA_TXQ_BASE_ADDR_REG(txq->id), txq->descs_phys);
+       mvreg_write(pp, MVNETA_TXQ_SIZE_REG(txq->id), txq->size);
+
+       return 0;
+}
+
+/* Free allocated resources when mvneta_txq_init() fails to allocate memory*/
+static void mvneta_txq_deinit(struct mvneta_port *pp,
+                             struct mvneta_tx_queue *txq)
+{
+       txq->descs             = NULL;
+       txq->last_desc         = 0;
+       txq->next_desc_to_proc = 0;
+       txq->descs_phys        = 0;
+
+       /* Set minimum bandwidth for disabled TXQs */
+       mvreg_write(pp, MVETH_TXQ_TOKEN_CFG_REG(txq->id), 0);
+       mvreg_write(pp, MVETH_TXQ_TOKEN_COUNT_REG(txq->id), 0);
+
+       /* Set Tx descriptors queue starting address and size */
+       mvreg_write(pp, MVNETA_TXQ_BASE_ADDR_REG(txq->id), 0);
+       mvreg_write(pp, MVNETA_TXQ_SIZE_REG(txq->id), 0);
+}
+
+/* Cleanup all Tx queues */
+static void mvneta_cleanup_txqs(struct mvneta_port *pp)
+{
+       int queue;
+
+       for (queue = 0; queue < txq_number; queue++)
+               mvneta_txq_deinit(pp, &pp->txqs[queue]);
+}
+
+/* Cleanup all Rx queues */
+static void mvneta_cleanup_rxqs(struct mvneta_port *pp)
+{
+       int queue;
+
+       for (queue = 0; queue < rxq_number; queue++)
+               mvneta_rxq_deinit(pp, &pp->rxqs[queue]);
+}
+
+
+/* Init all Rx queues */
+static int mvneta_setup_rxqs(struct mvneta_port *pp)
+{
+       int queue;
+
+       for (queue = 0; queue < rxq_number; queue++) {
+               int err = mvneta_rxq_init(pp, &pp->rxqs[queue]);
+               if (err) {
+                       netdev_err(pp->dev, "%s: can't create rxq=%d\n",
+                                  __func__, queue);
+                       mvneta_cleanup_rxqs(pp);
+                       return err;
+               }
+       }
+
+       return 0;
+}
+
+/* Init all tx queues */
+static int mvneta_setup_txqs(struct mvneta_port *pp)
+{
+       int queue;
+
+       for (queue = 0; queue < txq_number; queue++) {
+               int err = mvneta_txq_init(pp, &pp->txqs[queue]);
+               if (err) {
+                       netdev_err(pp->dev, "%s: can't create txq=%d\n",
+                                  __func__, queue);
+                       mvneta_cleanup_txqs(pp);
+                       return err;
+               }
+       }
+
+       return 0;
+}
+
+static void mvneta_start_dev(struct mvneta_port *pp)
+{
+       /* start the Rx/Tx activity */
+       mvneta_port_enable(pp);
+}
+
+static void mvneta_adjust_link(struct eth_device *dev)
+{
+       struct mvneta_port *pp = dev->priv;
+       struct phy_device *phydev = pp->phydev;
+       int status_change = 0;
+
+       if (phydev->link) {
+               if ((pp->speed != phydev->speed) ||
+                   (pp->duplex != phydev->duplex)) {
+                       u32 val;
+
+                       val = mvreg_read(pp, MVNETA_GMAC_AUTONEG_CONFIG);
+                       val &= ~(MVNETA_GMAC_CONFIG_MII_SPEED |
+                                MVNETA_GMAC_CONFIG_GMII_SPEED |
+                                MVNETA_GMAC_CONFIG_FULL_DUPLEX |
+                                MVNETA_GMAC_AN_SPEED_EN |
+                                MVNETA_GMAC_AN_DUPLEX_EN);
+
+                       if (phydev->duplex)
+                               val |= MVNETA_GMAC_CONFIG_FULL_DUPLEX;
+
+                       if (phydev->speed == SPEED_1000)
+                               val |= MVNETA_GMAC_CONFIG_GMII_SPEED;
+                       else
+                               val |= MVNETA_GMAC_CONFIG_MII_SPEED;
+
+                       mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG, val);
+
+                       pp->duplex = phydev->duplex;
+                       pp->speed  = phydev->speed;
+               }
+       }
+
+       if (phydev->link != pp->link) {
+               if (!phydev->link) {
+                       pp->duplex = -1;
+                       pp->speed = 0;
+               }
+
+               pp->link = phydev->link;
+               status_change = 1;
+       }
+
+       if (status_change) {
+               if (phydev->link) {
+                       u32 val = mvreg_read(pp, MVNETA_GMAC_AUTONEG_CONFIG);
+                       val |= (MVNETA_GMAC_FORCE_LINK_PASS |
+                               MVNETA_GMAC_FORCE_LINK_DOWN);
+                       mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG, val);
+                       mvneta_port_up(pp);
+               } else {
+                       mvneta_port_down(pp);
+               }
+       }
+}
+
+static int mvneta_open(struct eth_device *dev)
+{
+       struct mvneta_port *pp = dev->priv;
+       int ret;
+
+       ret = mvneta_setup_rxqs(pp);
+       if (ret)
+               return ret;
+
+       ret = mvneta_setup_txqs(pp);
+       if (ret)
+               return ret;
+
+       mvneta_adjust_link(dev);
+
+       mvneta_start_dev(pp);
+
+       return 0;
+}
+
+/* Initialize hw */
+static int mvneta_init(struct mvneta_port *pp)
+{
+       int queue;
+
+       /* Disable port */
+       mvneta_port_disable(pp);
+
+       /* Set port default values */
+       mvneta_defaults_set(pp);
+
+       pp->txqs = kzalloc(txq_number * sizeof(struct mvneta_tx_queue),
+                          GFP_KERNEL);
+       if (!pp->txqs)
+               return -ENOMEM;
+
+       /* U-Boot special: use preallocated area */
+       pp->txqs[0].descs = buffer_loc.tx_descs;
+
+       /* Initialize TX descriptor rings */
+       for (queue = 0; queue < txq_number; queue++) {
+               struct mvneta_tx_queue *txq = &pp->txqs[queue];
+               txq->id = queue;
+               txq->size = pp->tx_ring_size;
+       }
+
+       pp->rxqs = kzalloc(rxq_number * sizeof(struct mvneta_rx_queue),
+                          GFP_KERNEL);
+       if (!pp->rxqs) {
+               kfree(pp->txqs);
+               return -ENOMEM;
+       }
+
+       /* U-Boot special: use preallocated area */
+       pp->rxqs[0].descs = buffer_loc.rx_descs;
+
+       /* Create Rx descriptor rings */
+       for (queue = 0; queue < rxq_number; queue++) {
+               struct mvneta_rx_queue *rxq = &pp->rxqs[queue];
+               rxq->id = queue;
+               rxq->size = pp->rx_ring_size;
+       }
+
+       return 0;
+}
+
+/* platform glue : initialize decoding windows */
+static void mvneta_conf_mbus_windows(struct mvneta_port *pp)
+{
+       const struct mbus_dram_target_info *dram;
+       u32 win_enable;
+       u32 win_protect;
+       int i;
+
+       dram = mvebu_mbus_dram_info();
+       for (i = 0; i < 6; i++) {
+               mvreg_write(pp, MVNETA_WIN_BASE(i), 0);
+               mvreg_write(pp, MVNETA_WIN_SIZE(i), 0);
+
+               if (i < 4)
+                       mvreg_write(pp, MVNETA_WIN_REMAP(i), 0);
+       }
+
+       win_enable = 0x3f;
+       win_protect = 0;
+
+       for (i = 0; i < dram->num_cs; i++) {
+               const struct mbus_dram_window *cs = dram->cs + i;
+               mvreg_write(pp, MVNETA_WIN_BASE(i), (cs->base & 0xffff0000) |
+                           (cs->mbus_attr << 8) | dram->mbus_dram_target_id);
+
+               mvreg_write(pp, MVNETA_WIN_SIZE(i),
+                           (cs->size - 1) & 0xffff0000);
+
+               win_enable &= ~(1 << i);
+               win_protect |= 3 << (2 * i);
+       }
+
+       mvreg_write(pp, MVNETA_BASE_ADDR_ENABLE, win_enable);
+}
+
+/* Power up the port */
+static int mvneta_port_power_up(struct mvneta_port *pp, int phy_mode)
+{
+       u32 ctrl;
+
+       /* MAC Cause register should be cleared */
+       mvreg_write(pp, MVNETA_UNIT_INTR_CAUSE, 0);
+
+       ctrl = mvreg_read(pp, MVNETA_GMAC_CTRL_2);
+
+       /* Even though it might look weird, when we're configured in
+        * SGMII or QSGMII mode, the RGMII bit needs to be set.
+        */
+       switch (phy_mode) {
+       case PHY_INTERFACE_MODE_QSGMII:
+               mvreg_write(pp, MVNETA_SERDES_CFG, MVNETA_QSGMII_SERDES_PROTO);
+               ctrl |= MVNETA_GMAC2_PCS_ENABLE | MVNETA_GMAC2_PORT_RGMII;
+               break;
+       case PHY_INTERFACE_MODE_SGMII:
+               mvreg_write(pp, MVNETA_SERDES_CFG, MVNETA_SGMII_SERDES_PROTO);
+               ctrl |= MVNETA_GMAC2_PCS_ENABLE | MVNETA_GMAC2_PORT_RGMII;
+               break;
+       case PHY_INTERFACE_MODE_RGMII:
+       case PHY_INTERFACE_MODE_RGMII_ID:
+               ctrl |= MVNETA_GMAC2_PORT_RGMII;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       /* Cancel Port Reset */
+       ctrl &= ~MVNETA_GMAC2_PORT_RESET;
+       mvreg_write(pp, MVNETA_GMAC_CTRL_2, ctrl);
+
+       while ((mvreg_read(pp, MVNETA_GMAC_CTRL_2) &
+               MVNETA_GMAC2_PORT_RESET) != 0)
+               continue;
+
+       return 0;
+}
+
+/* Device initialization routine */
+static int mvneta_probe(struct eth_device *dev)
+{
+       struct mvneta_port *pp = dev->priv;
+       int err;
+
+       pp->tx_ring_size = MVNETA_MAX_TXD;
+       pp->rx_ring_size = MVNETA_MAX_RXD;
+
+       err = mvneta_init(pp);
+       if (err < 0) {
+               dev_err(&pdev->dev, "can't init eth hal\n");
+               return err;
+       }
+
+       mvneta_conf_mbus_windows(pp);
+
+       mvneta_mac_addr_set(pp, dev->enetaddr, rxq_def);
+
+       err = mvneta_port_power_up(pp, pp->phy_interface);
+       if (err < 0) {
+               dev_err(&pdev->dev, "can't power up port\n");
+               return err;
+       }
+
+       /* Call open() now as it needs to be done before runing send() */
+       mvneta_open(dev);
+
+       return 0;
+}
+
+/* U-Boot only functions follow here */
+
+/* SMI / MDIO functions */
+
+static int smi_wait_ready(struct mvneta_port *pp)
+{
+       u32 timeout = MVNETA_SMI_TIMEOUT;
+       u32 smi_reg;
+
+       /* wait till the SMI is not busy */
+       do {
+               /* read smi register */
+               smi_reg = mvreg_read(pp, MVNETA_SMI);
+               if (timeout-- == 0) {
+                       printf("Error: SMI busy timeout\n");
+                       return -EFAULT;
+               }
+       } while (smi_reg & MVNETA_SMI_BUSY);
+
+       return 0;
+}
+
+/*
+ * smi_reg_read - miiphy_read callback function.
+ *
+ * Returns 16bit phy register value, or 0xffff on error
+ */
+static int smi_reg_read(const char *devname, u8 phy_adr, u8 reg_ofs, u16 *data)
+{
+       struct eth_device *dev = eth_get_dev_by_name(devname);
+       struct mvneta_port *pp = dev->priv;
+       u32 smi_reg;
+       u32 timeout;
+
+       /* check parameters */
+       if (phy_adr > MVNETA_PHY_ADDR_MASK) {
+               printf("Error: Invalid PHY address %d\n", phy_adr);
+               return -EFAULT;
+       }
+
+       if (reg_ofs > MVNETA_PHY_REG_MASK) {
+               printf("Err: Invalid register offset %d\n", reg_ofs);
+               return -EFAULT;
+       }
+
+       /* wait till the SMI is not busy */
+       if (smi_wait_ready(pp) < 0)
+               return -EFAULT;
+
+       /* fill the phy address and regiser offset and read opcode */
+       smi_reg = (phy_adr << MVNETA_SMI_DEV_ADDR_OFFS)
+               | (reg_ofs << MVNETA_SMI_REG_ADDR_OFFS)
+               | MVNETA_SMI_OPCODE_READ;
+
+       /* write the smi register */
+       mvreg_write(pp, MVNETA_SMI, smi_reg);
+
+       /*wait till read value is ready */
+       timeout = MVNETA_SMI_TIMEOUT;
+
+       do {
+               /* read smi register */
+               smi_reg = mvreg_read(pp, MVNETA_SMI);
+               if (timeout-- == 0) {
+                       printf("Err: SMI read ready timeout\n");
+                       return -EFAULT;
+               }
+       } while (!(smi_reg & MVNETA_SMI_READ_VALID));
+
+       /* Wait for the data to update in the SMI register */
+       for (timeout = 0; timeout < MVNETA_SMI_TIMEOUT; timeout++)
+               ;
+
+       *data = (u16)(mvreg_read(pp, MVNETA_SMI) & MVNETA_SMI_DATA_MASK);
+
+       return 0;
+}
+
+/*
+ * smi_reg_write - imiiphy_write callback function.
+ *
+ * Returns 0 if write succeed, -EINVAL on bad parameters
+ * -ETIME on timeout
+ */
+static int smi_reg_write(const char *devname, u8 phy_adr, u8 reg_ofs, u16 data)
+{
+       struct eth_device *dev = eth_get_dev_by_name(devname);
+       struct mvneta_port *pp = dev->priv;
+       u32 smi_reg;
+
+       /* check parameters */
+       if (phy_adr > MVNETA_PHY_ADDR_MASK) {
+               printf("Error: Invalid PHY address %d\n", phy_adr);
+               return -EFAULT;
+       }
+
+       if (reg_ofs > MVNETA_PHY_REG_MASK) {
+               printf("Err: Invalid register offset %d\n", reg_ofs);
+               return -EFAULT;
+       }
+
+       /* wait till the SMI is not busy */
+       if (smi_wait_ready(pp) < 0)
+               return -EFAULT;
+
+       /* fill the phy addr and reg offset and write opcode and data */
+       smi_reg = (data << MVNETA_SMI_DATA_OFFS);
+       smi_reg |= (phy_adr << MVNETA_SMI_DEV_ADDR_OFFS)
+               | (reg_ofs << MVNETA_SMI_REG_ADDR_OFFS);
+       smi_reg &= ~MVNETA_SMI_OPCODE_READ;
+
+       /* write the smi register */
+       mvreg_write(pp, MVNETA_SMI, smi_reg);
+
+       return 0;
+}
+
+static int mvneta_init_u_boot(struct eth_device *dev, bd_t *bis)
+{
+       struct mvneta_port *pp = dev->priv;
+       struct phy_device *phydev;
+
+       mvneta_port_power_up(pp, pp->phy_interface);
+
+       if (!pp->init || pp->link == 0) {
+               /* Set phy address of the port */
+               mvreg_write(pp, MVNETA_PHY_ADDR, pp->phyaddr);
+               phydev = phy_connect(pp->bus, pp->phyaddr, dev,
+                                    pp->phy_interface);
+
+               pp->phydev = phydev;
+               phy_config(phydev);
+               phy_startup(phydev);
+               if (!phydev->link) {
+                       printf("%s: No link.\n", phydev->dev->name);
+                       return -1;
+               }
+
+               /* Full init on first call */
+               mvneta_probe(dev);
+               pp->init = 1;
+       } else {
+               /* Upon all following calls, this is enough */
+               mvneta_port_up(pp);
+               mvneta_port_enable(pp);
+       }
+
+       return 0;
+}
+
+static int mvneta_send(struct eth_device *dev, void *ptr, int len)
+{
+       struct mvneta_port *pp = dev->priv;
+       struct mvneta_tx_queue *txq = &pp->txqs[0];
+       struct mvneta_tx_desc *tx_desc;
+       int sent_desc;
+       u32 timeout = 0;
+
+       /* Get a descriptor for the first part of the packet */
+       tx_desc = mvneta_txq_next_desc_get(txq);
+
+       tx_desc->buf_phys_addr = (u32)ptr;
+       tx_desc->data_size = len;
+       flush_dcache_range((u32)ptr, (u32)ptr + len);
+
+       /* First and Last descriptor */
+       tx_desc->command = MVNETA_TX_L4_CSUM_NOT | MVNETA_TXD_FLZ_DESC;
+       mvneta_txq_pend_desc_add(pp, txq, 1);
+
+       /* Wait for packet to be sent (queue might help with speed here) */
+       sent_desc = mvneta_txq_sent_desc_num_get(pp, txq);
+       while (!sent_desc) {
+               if (timeout++ > 10000) {
+                       printf("timeout: packet not sent\n");
+                       return -1;
+               }
+               sent_desc = mvneta_txq_sent_desc_num_get(pp, txq);
+       }
+
+       /* txDone has increased - hw sent packet */
+       mvneta_txq_sent_desc_dec(pp, txq, sent_desc);
+       return 0;
+
+       return 0;
+}
+
+static int mvneta_recv(struct eth_device *dev)
+{
+       struct mvneta_port *pp = dev->priv;
+       int rx_done;
+       int packets_done;
+       struct mvneta_rx_queue *rxq;
+
+       /* get rx queue */
+       rxq = mvneta_rxq_handle_get(pp, rxq_def);
+       rx_done = mvneta_rxq_busy_desc_num_get(pp, rxq);
+       packets_done = rx_done;
+
+       while (packets_done--) {
+               struct mvneta_rx_desc *rx_desc;
+               unsigned char *data;
+               u32 rx_status;
+               int rx_bytes;
+
+               /*
+                * No cache invalidation needed here, since the desc's are
+                * located in a uncached memory region
+                */
+               rx_desc = mvneta_rxq_next_desc_get(rxq);
+
+               rx_status = rx_desc->status;
+               if (!mvneta_rxq_desc_is_first_last(rx_status) ||
+                   (rx_status & MVNETA_RXD_ERR_SUMMARY)) {
+                       mvneta_rx_error(pp, rx_desc);
+                       /* leave the descriptor untouched */
+                       continue;
+               }
+
+               /* 2 bytes for marvell header. 4 bytes for crc */
+               rx_bytes = rx_desc->data_size - 6;
+
+               /* give packet to stack - skip on first 2 bytes */
+               data = (u8 *)rx_desc->buf_cookie + 2;
+               /*
+                * No cache invalidation needed here, since the rx_buffer's are
+                * located in a uncached memory region
+                */
+               NetReceive(data, rx_bytes);
+       }
+
+       /* Update rxq management counters */
+       if (rx_done)
+               mvneta_rxq_desc_num_update(pp, rxq, rx_done, rx_done);
+
+       return 0;
+}
+
+static void mvneta_halt(struct eth_device *dev)
+{
+       struct mvneta_port *pp = dev->priv;
+
+       mvneta_port_down(pp);
+       mvneta_port_disable(pp);
+}
+
+int mvneta_initialize(bd_t *bis, int base_addr, int devnum, int phy_addr)
+{
+       struct eth_device *dev;
+       struct mvneta_port *pp;
+       void *bd_space;
+
+       dev = calloc(1, sizeof(*dev));
+       if (dev == NULL)
+               return -ENOMEM;
+
+       pp = calloc(1, sizeof(*pp));
+       if (pp == NULL)
+               return -ENOMEM;
+
+       dev->priv = pp;
+
+       /*
+        * Allocate buffer area for descs and rx_buffers. This is only
+        * done once for all interfaces. As only one interface can
+        * be active. Make this area DMA save by disabling the D-cache
+        */
+       if (!buffer_loc.tx_descs) {
+               /* Align buffer area for descs and rx_buffers to 1MiB */
+               bd_space = memalign(1 << MMU_SECTION_SHIFT, BD_SPACE);
+               mmu_set_region_dcache_behaviour((u32)bd_space, BD_SPACE,
+                                               DCACHE_OFF);
+               buffer_loc.tx_descs = (struct mvneta_tx_desc *)bd_space;
+               buffer_loc.rx_descs = (struct mvneta_rx_desc *)
+                       ((u32)bd_space +
+                        MVNETA_MAX_TXD * sizeof(struct mvneta_tx_desc));
+               buffer_loc.rx_buffers = (u32)
+                       (bd_space +
+                        MVNETA_MAX_TXD * sizeof(struct mvneta_tx_desc) +
+                        MVNETA_MAX_RXD * sizeof(struct mvneta_rx_desc));
+       }
+
+       sprintf(dev->name, "neta%d", devnum);
+
+       pp->base = (void __iomem *)base_addr;
+       dev->iobase = base_addr;
+       dev->init = mvneta_init_u_boot;
+       dev->halt = mvneta_halt;
+       dev->send = mvneta_send;
+       dev->recv = mvneta_recv;
+       dev->write_hwaddr = NULL;
+
+       /*
+        * The PHY interface type is configured via the
+        * board specific CONFIG_SYS_NETA_INTERFACE_TYPE
+        * define.
+        */
+       pp->phy_interface = CONFIG_SYS_NETA_INTERFACE_TYPE;
+
+       eth_register(dev);
+
+       pp->phyaddr = phy_addr;
+       miiphy_register(dev->name, smi_reg_read, smi_reg_write);
+       pp->bus = miiphy_get_dev_by_name(dev->name);
+
+       return 1;
+}
index 1d6c14f2ade7497bc7b2ded23bffce21f250a821..467c97224313328e2aa7e2f04edabc15def84792 100644 (file)
@@ -575,7 +575,7 @@ static struct phy_device *phy_device_create(struct mii_dev *bus, int addr,
  * Description: Reads the ID registers of the PHY at @addr on the
  *   @bus, stores it in @phy_id and returns zero on success.
  */
-int __weak get_phy_id(struct mii_dev *bus, int addr, int devad, u32 *phy_id)
+static int get_phy_id(struct mii_dev *bus, int addr, int devad, u32 *phy_id)
 {
        int phy_reg;
 
@@ -648,7 +648,7 @@ static struct phy_device *get_phy_device_by_mask(struct mii_dev *bus,
                if (phydev)
                        return phydev;
        }
-       printf("Phy not found\n");
+       printf("Phy %d not found\n", ffs(phy_mask) - 1);
        return phy_device_create(bus, ffs(phy_mask) - 1, 0xffffffff, interface);
 }
 
@@ -785,16 +785,13 @@ int phy_startup(struct phy_device *phydev)
        return 0;
 }
 
-static int __board_phy_config(struct phy_device *phydev)
+__weak int board_phy_config(struct phy_device *phydev)
 {
        if (phydev->drv->config)
                return phydev->drv->config(phydev);
        return 0;
 }
 
-int board_phy_config(struct phy_device *phydev)
-       __attribute__((weak, alias("__board_phy_config")));
-
 int phy_config(struct phy_device *phydev)
 {
        /* Invoke an optional board-specific helper */
index 28859f31612527ccff49ee3fbc69dbbc1caaaa54..60c333e2c0191d5ef8753075669a7edc3af95532 100644 (file)
@@ -572,7 +572,7 @@ const char * pci_class_str(u8 class)
 }
 #endif /* CONFIG_CMD_PCI || CONFIG_PCI_SCAN_SHOW */
 
-int __pci_skip_dev(struct pci_controller *hose, pci_dev_t dev)
+__weak int pci_skip_dev(struct pci_controller *hose, pci_dev_t dev)
 {
        /*
         * Check if pci device should be skipped in configuration
@@ -591,19 +591,15 @@ int __pci_skip_dev(struct pci_controller *hose, pci_dev_t dev)
 
        return 0;
 }
-int pci_skip_dev(struct pci_controller *hose, pci_dev_t dev)
-       __attribute__((weak, alias("__pci_skip_dev")));
 
 #ifdef CONFIG_PCI_SCAN_SHOW
-int __pci_print_dev(struct pci_controller *hose, pci_dev_t dev)
+__weak int pci_print_dev(struct pci_controller *hose, pci_dev_t dev)
 {
        if (dev == PCI_BDF(hose->first_busno, 0, 0))
                return 0;
 
        return 1;
 }
-int pci_print_dev(struct pci_controller *hose, pci_dev_t dev)
-       __attribute__((weak, alias("__pci_print_dev")));
 #endif /* CONFIG_PCI_SCAN_SHOW */
 
 int pci_hose_scan_bus(struct pci_controller *hose, int bus)
index ce7a69bab57048d7f8e1a40a1377de96946d5e5c..ebddc124c3dae96195f31eca4bab99f60bc5204a 100644 (file)
@@ -12,7 +12,7 @@
 #ifndef _MVRTC_H_
 #define _MVRTC_H_
 
-#include <asm/arch/kirkwood.h>
+#include <asm/arch/soc.h>
 #include <compiler.h>
 
 /* RTC registers */
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..a0b6e02b5462e5fc515a28d7f40b04a46c22018d 100644 (file)
@@ -0,0 +1,12 @@
+config DM_SERIAL
+       bool "Enable Driver Model for serial drivers"
+       depends on DM
+       help
+         If you want to use driver model for serial drivers, say Y.
+         To use legacy serial drivers, say N.
+
+config UNIPHIER_SERIAL
+       bool "UniPhier on-chip UART support"
+       depends on ARCH_UNIPHIER && DM_SERIAL
+       help
+         Support for the on-chip UARTs on the Panasonic UniPhier platform.
index b4f299bb0ede65966624972b900c09142f202e24..2c19ebc2885e90c77b58302e989527a162d9c517 100644 (file)
@@ -7,8 +7,11 @@
 
 ifdef CONFIG_DM_SERIAL
 obj-y += serial-uclass.o
+obj-$(CONFIG_PL01X_SERIAL) += serial_pl01x.o
 else
 obj-y += serial.o
+obj-$(CONFIG_PL010_SERIAL) += serial_pl01x.o
+obj-$(CONFIG_PL011_SERIAL) += serial_pl01x.o
 obj-$(CONFIG_SYS_NS16550_SERIAL) += serial_ns16550.o
 endif
 
@@ -25,8 +28,6 @@ obj-$(CONFIG_IMX_SERIAL) += serial_imx.o
 obj-$(CONFIG_KS8695_SERIAL) += serial_ks8695.o
 obj-$(CONFIG_MAX3100_SERIAL) += serial_max3100.o
 obj-$(CONFIG_MXC_UART) += serial_mxc.o
-obj-$(CONFIG_PL010_SERIAL) += serial_pl01x.o
-obj-$(CONFIG_PL011_SERIAL) += serial_pl01x.o
 obj-$(CONFIG_PXA_SERIAL) += serial_pxa.o
 obj-$(CONFIG_SA1100_SERIAL) += serial_sa1100.o
 obj-$(CONFIG_S3C24X0_SERIAL) += serial_s3c24x0.o
@@ -40,6 +41,8 @@ obj-$(CONFIG_MXS_AUART) += mxs_auart.o
 obj-$(CONFIG_ARC_SERIAL) += serial_arc.o
 obj-$(CONFIG_TEGRA_SERIAL) += serial_tegra.o
 obj-$(CONFIG_UNIPHIER_SERIAL) += serial_uniphier.o
+obj-$(CONFIG_OMAP_SERIAL) += serial_omap.o
+obj-$(CONFIG_COREBOOT_SERIAL) += serial_coreboot.o
 
 ifndef CONFIG_SPL_BUILD
 obj-$(CONFIG_USB_TTY) += usbtty.o
index 63a9ef68444d3af762213467b1b9e9524aaa4473..8f051914f54a37539d5768dd9d8ed90ff34adcf0 100644 (file)
@@ -61,13 +61,13 @@ static void ns16550_writeb(NS16550_t port, int offset, int value)
        unsigned char *addr;
 
        offset *= 1 << plat->reg_shift;
-       addr = plat->base + offset;
+       addr = map_sysmem(plat->base, 0) + offset;
        /*
         * As far as we know it doesn't make sense to support selection of
         * these options at run-time, so use the existing CONFIG options.
         */
 #ifdef CONFIG_SYS_NS16550_PORT_MAPPED
-       outb(value, addr);
+       outb(value, (ulong)addr);
 #elif defined(CONFIG_SYS_NS16550_MEM32) && !defined(CONFIG_SYS_BIG_ENDIAN)
        out_le32(addr, value);
 #elif defined(CONFIG_SYS_NS16550_MEM32) && defined(CONFIG_SYS_BIG_ENDIAN)
@@ -85,9 +85,9 @@ static int ns16550_readb(NS16550_t port, int offset)
        unsigned char *addr;
 
        offset *= 1 << plat->reg_shift;
-       addr = plat->base + offset;
+       addr = map_sysmem(plat->base, 0) + offset;
 #ifdef CONFIG_SYS_NS16550_PORT_MAPPED
-       return inb(addr);
+       return inb((ulong)addr);
 #elif defined(CONFIG_SYS_NS16550_MEM32) && !defined(CONFIG_SYS_BIG_ENDIAN)
        return in_le32(addr);
 #elif defined(CONFIG_SYS_NS16550_MEM32) && defined(CONFIG_SYS_BIG_ENDIAN)
@@ -253,7 +253,7 @@ static int ns16550_serial_getc(struct udevice *dev)
 {
        struct NS16550 *const com_port = dev_get_priv(dev);
 
-       if (!serial_in(&com_port->lsr) & UART_LSR_DR)
+       if (!(serial_in(&com_port->lsr) & UART_LSR_DR))
                return -EAGAIN;
 
        return serial_in(&com_port->rbr);
@@ -276,14 +276,15 @@ int ns16550_serial_probe(struct udevice *dev)
 {
        struct NS16550 *const com_port = dev_get_priv(dev);
 
+       com_port->plat = dev_get_platdata(dev);
        NS16550_init(com_port, -1);
 
        return 0;
 }
 
+#ifdef CONFIG_OF_CONTROL
 int ns16550_serial_ofdata_to_platdata(struct udevice *dev)
 {
-       struct NS16550 *const com_port = dev_get_priv(dev);
        struct ns16550_platdata *plat = dev->platdata;
        fdt_addr_t addr;
 
@@ -291,13 +292,13 @@ int ns16550_serial_ofdata_to_platdata(struct udevice *dev)
        if (addr == FDT_ADDR_T_NONE)
                return -EINVAL;
 
-       plat->base = (unsigned char *)addr;
+       plat->base = addr;
        plat->reg_shift = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
                                         "reg-shift", 1);
-       com_port->plat = plat;
 
        return 0;
 }
+#endif
 
 const struct dm_serial_ops ns16550_serial_ops = {
        .putc = ns16550_serial_putc,
index 6dde4eaf47286a3a38feb3c84a782c5421c01630..71f1a5cb91024e9fc473e2a5e61f0deb82efd3c1 100644 (file)
 #include <os.h>
 #include <serial.h>
 #include <stdio_dev.h>
+#include <watchdog.h>
 #include <dm/lists.h>
 #include <dm/device-internal.h>
 
+#include <ns16550.h>
+
 DECLARE_GLOBAL_DATA_PTR;
 
 /* The currently-selected console serial device */
@@ -47,13 +50,22 @@ static void serial_find_console_or_panic(void)
        }
 #endif
        /*
+        * Try to use CONFIG_CONS_INDEX if available (it is numbered from 1!).
+        *
         * Failing that, get the device with sequence number 0, or in extremis
         * just the first serial device we can find. But we insist on having
         * a console (even if it is silent).
         */
-       if (uclass_get_device_by_seq(UCLASS_SERIAL, 0, &cur_dev) &&
+#ifdef CONFIG_CONS_INDEX
+#define INDEX (CONFIG_CONS_INDEX - 1)
+#else
+#define INDEX 0
+#endif
+       if (uclass_get_device_by_seq(UCLASS_SERIAL, INDEX, &cur_dev) &&
+           uclass_get_device(UCLASS_SERIAL, INDEX, &cur_dev) &&
            (uclass_first_device(UCLASS_SERIAL, &cur_dev) || !cur_dev))
                panic("No serial driver found");
+#undef INDEX
 }
 
 /* Called prior to relocation */
@@ -71,95 +83,98 @@ void serial_initialize(void)
        serial_find_console_or_panic();
 }
 
-void serial_putc(char ch)
+static void _serial_putc(struct udevice *dev, char ch)
 {
-       struct dm_serial_ops *ops = serial_get_ops(cur_dev);
+       struct dm_serial_ops *ops = serial_get_ops(dev);
        int err;
 
        do {
-               err = ops->putc(cur_dev, ch);
+               err = ops->putc(dev, ch);
        } while (err == -EAGAIN);
        if (ch == '\n')
-               serial_putc('\r');
+               _serial_putc(dev, '\r');
 }
 
-void serial_setbrg(void)
+static void _serial_puts(struct udevice *dev, const char *str)
 {
-       struct dm_serial_ops *ops = serial_get_ops(cur_dev);
-
-       if (ops->setbrg)
-               ops->setbrg(cur_dev, gd->baudrate);
+       while (*str)
+               _serial_putc(dev, *str++);
 }
 
-void serial_puts(const char *str)
+static int _serial_getc(struct udevice *dev)
 {
-       while (*str)
-               serial_putc(*str++);
+       struct dm_serial_ops *ops = serial_get_ops(dev);
+       int err;
+
+       do {
+               err = ops->getc(dev);
+               if (err == -EAGAIN)
+                       WATCHDOG_RESET();
+       } while (err == -EAGAIN);
+
+       return err >= 0 ? err : 0;
 }
 
-int serial_tstc(void)
+static int _serial_tstc(struct udevice *dev)
 {
-       struct dm_serial_ops *ops = serial_get_ops(cur_dev);
+       struct dm_serial_ops *ops = serial_get_ops(dev);
 
        if (ops->pending)
-               return ops->pending(cur_dev, true);
+               return ops->pending(dev, true);
 
        return 1;
 }
 
+void serial_putc(char ch)
+{
+       _serial_putc(cur_dev, ch);
+}
+
+void serial_puts(const char *str)
+{
+       _serial_puts(cur_dev, str);
+}
+
 int serial_getc(void)
 {
-       struct dm_serial_ops *ops = serial_get_ops(cur_dev);
-       int err;
+       return _serial_getc(cur_dev);
+}
 
-       do {
-               err = ops->getc(cur_dev);
-       } while (err == -EAGAIN);
+int serial_tstc(void)
+{
+       return _serial_tstc(cur_dev);
+}
 
-       return err >= 0 ? err : 0;
+void serial_setbrg(void)
+{
+       struct dm_serial_ops *ops = serial_get_ops(cur_dev);
+
+       if (ops->setbrg)
+               ops->setbrg(cur_dev, gd->baudrate);
 }
 
 void serial_stdio_init(void)
 {
 }
 
-void serial_stub_putc(struct stdio_dev *sdev, const char ch)
+static void serial_stub_putc(struct stdio_dev *sdev, const char ch)
 {
-       struct udevice *dev = sdev->priv;
-       struct dm_serial_ops *ops = serial_get_ops(dev);
-
-       ops->putc(dev, ch);
+       _serial_putc(sdev->priv, ch);
 }
 
 void serial_stub_puts(struct stdio_dev *sdev, const char *str)
 {
-       while (*str)
-               serial_stub_putc(sdev, *str++);
+       _serial_puts(sdev->priv, str);
 }
 
 int serial_stub_getc(struct stdio_dev *sdev)
 {
-       struct udevice *dev = sdev->priv;
-       struct dm_serial_ops *ops = serial_get_ops(dev);
-
-       int err;
-
-       do {
-               err = ops->getc(dev);
-       } while (err == -EAGAIN);
-
-       return err >= 0 ? err : 0;
+       return _serial_getc(sdev->priv);
 }
 
 int serial_stub_tstc(struct stdio_dev *sdev)
 {
-       struct udevice *dev = sdev->priv;
-       struct dm_serial_ops *ops = serial_get_ops(dev);
-
-       if (ops->pending)
-               return ops->pending(dev, true);
-
-       return 1;
+       return _serial_tstc(sdev->priv);
 }
 
 static int serial_post_probe(struct udevice *dev)
index 82fbbd92e2b259586455484b635338adc5cdf72f..18e41b2302a2181ba6f38c53ecc71c682fb5cad0 100644 (file)
@@ -157,7 +157,6 @@ serial_initfunc(sh_serial_initialize);
 serial_initfunc(arm_dcc_initialize);
 serial_initfunc(mxs_auart_initialize);
 serial_initfunc(arc_serial_initialize);
-serial_initfunc(uniphier_serial_initialize);
 
 /**
  * serial_register() - Register serial driver with serial driver core
@@ -251,33 +250,32 @@ void serial_initialize(void)
        arm_dcc_initialize();
        mxs_auart_initialize();
        arc_serial_initialize();
-       uniphier_serial_initialize();
 
        serial_assign(default_serial_console()->name);
 }
 
-int serial_stub_start(struct stdio_dev *sdev)
+static int serial_stub_start(struct stdio_dev *sdev)
 {
        struct serial_device *dev = sdev->priv;
 
        return dev->start();
 }
 
-int serial_stub_stop(struct stdio_dev *sdev)
+static int serial_stub_stop(struct stdio_dev *sdev)
 {
        struct serial_device *dev = sdev->priv;
 
        return dev->stop();
 }
 
-void serial_stub_putc(struct stdio_dev *sdev, const char ch)
+static void serial_stub_putc(struct stdio_dev *sdev, const char ch)
 {
        struct serial_device *dev = sdev->priv;
 
        dev->putc(ch);
 }
 
-void serial_stub_puts(struct stdio_dev *sdev, const char *str)
+static void serial_stub_puts(struct stdio_dev *sdev, const char *str)
 {
        struct serial_device *dev = sdev->priv;
 
diff --git a/drivers/serial/serial_coreboot.c b/drivers/serial/serial_coreboot.c
new file mode 100644 (file)
index 0000000..5c6a76c
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2014 Google, Inc
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <ns16550.h>
+#include <serial.h>
+
+static const struct udevice_id coreboot_serial_ids[] = {
+       { .compatible = "coreboot-uart" },
+       { }
+};
+
+static int coreboot_serial_ofdata_to_platdata(struct udevice *dev)
+{
+       struct ns16550_platdata *plat = dev_get_platdata(dev);
+       int ret;
+
+       ret = ns16550_serial_ofdata_to_platdata(dev);
+       if (ret)
+               return ret;
+       plat->clock = 1843200;
+
+       return 0;
+}
+U_BOOT_DRIVER(serial_ns16550) = {
+       .name   = "serial_coreboot",
+       .id     = UCLASS_SERIAL,
+       .of_match = coreboot_serial_ids,
+       .ofdata_to_platdata = coreboot_serial_ofdata_to_platdata,
+       .platdata_auto_alloc_size = sizeof(struct ns16550_platdata),
+       .priv_auto_alloc_size = sizeof(struct NS16550),
+       .probe = ns16550_serial_probe,
+       .ops    = &ns16550_serial_ops,
+};
index 313d560afce8635f3b1f29c3ea029173b69f8c40..d6cf1d874a60c72c747489849bf58cffc915e57c 100644 (file)
@@ -5,37 +5,15 @@
  */
 
 #include <common.h>
+#include <dm.h>
+#include <errno.h>
 #include <watchdog.h>
 #include <asm/arch/imx-regs.h>
 #include <asm/arch/clock.h>
+#include <dm/platform_data/serial_mxc.h>
 #include <serial.h>
 #include <linux/compiler.h>
 
-#define __REG(x)     (*((volatile u32 *)(x)))
-
-#ifndef CONFIG_MXC_UART_BASE
-#error "define CONFIG_MXC_UART_BASE to use the MXC UART driver"
-#endif
-
-#define UART_PHYS      CONFIG_MXC_UART_BASE
-
-/* Register definitions */
-#define URXD  0x0  /* Receiver Register */
-#define UTXD  0x40 /* Transmitter Register */
-#define UCR1  0x80 /* Control Register 1 */
-#define UCR2  0x84 /* Control Register 2 */
-#define UCR3  0x88 /* Control Register 3 */
-#define UCR4  0x8c /* Control Register 4 */
-#define UFCR  0x90 /* FIFO Control Register */
-#define USR1  0x94 /* Status Register 1 */
-#define USR2  0x98 /* Status Register 2 */
-#define UESC  0x9c /* Escape Character Register */
-#define UTIM  0xa0 /* Escape Timer Register */
-#define UBIR  0xa4 /* BRM Incremental Register */
-#define UBMR  0xa8 /* BRM Modulator Register */
-#define UBRC  0xac /* Baud Rate Count Register */
-#define UTS   0xb4 /* UART Test Register (mx31) */
-
 /* UART Control Register Bit Fields.*/
 #define  URXD_CHARRDY    (1<<15)
 #define  URXD_ERR        (1<<14)
 #define  UTS_RXFULL     (1<<3)  /* RxFIFO full */
 #define  UTS_SOFTRST    (1<<0)  /* Software reset */
 
+#ifndef CONFIG_DM_SERIAL
+
+#ifndef CONFIG_MXC_UART_BASE
+#error "define CONFIG_MXC_UART_BASE to use the MXC UART driver"
+#endif
+
+#define UART_PHYS      CONFIG_MXC_UART_BASE
+
+#define __REG(x)     (*((volatile u32 *)(x)))
+
+/* Register definitions */
+#define URXD  0x0  /* Receiver Register */
+#define UTXD  0x40 /* Transmitter Register */
+#define UCR1  0x80 /* Control Register 1 */
+#define UCR2  0x84 /* Control Register 2 */
+#define UCR3  0x88 /* Control Register 3 */
+#define UCR4  0x8c /* Control Register 4 */
+#define UFCR  0x90 /* FIFO Control Register */
+#define USR1  0x94 /* Status Register 1 */
+#define USR2  0x98 /* Status Register 2 */
+#define UESC  0x9c /* Escape Character Register */
+#define UTIM  0xa0 /* Escape Timer Register */
+#define UBIR  0xa4 /* BRM Incremental Register */
+#define UBMR  0xa8 /* BRM Modulator Register */
+#define UBRC  0xac /* Baud Rate Count Register */
+#define UTS   0xb4 /* UART Test Register (mx31) */
+
 DECLARE_GLOBAL_DATA_PTR;
 
 static void mxc_serial_setbrg(void)
@@ -222,3 +227,118 @@ __weak struct serial_device *default_serial_console(void)
 {
        return &mxc_serial_drv;
 }
+#endif
+
+#ifdef CONFIG_DM_SERIAL
+
+struct mxc_uart {
+       u32 rxd;
+       u32 spare0[15];
+
+       u32 txd;
+       u32 spare1[15];
+
+       u32 cr1;
+       u32 cr2;
+       u32 cr3;
+       u32 cr4;
+
+       u32 fcr;
+       u32 sr1;
+       u32 sr2;
+       u32 esc;
+
+       u32 tim;
+       u32 bir;
+       u32 bmr;
+       u32 brc;
+
+       u32 onems;
+       u32 ts;
+};
+
+int mxc_serial_setbrg(struct udevice *dev, int baudrate)
+{
+       struct mxc_serial_platdata *plat = dev->platdata;
+       struct mxc_uart *const uart = plat->reg;
+       u32 clk = imx_get_uartclk();
+
+       writel(4 << 7, &uart->fcr); /* divide input clock by 2 */
+       writel(0xf, &uart->bir);
+       writel(clk / (2 * baudrate), &uart->bmr);
+
+       writel(UCR2_WS | UCR2_IRTS | UCR2_RXEN | UCR2_TXEN | UCR2_SRST,
+              &uart->cr2);
+       writel(UCR1_UARTEN, &uart->cr1);
+
+       return 0;
+}
+
+static int mxc_serial_probe(struct udevice *dev)
+{
+       struct mxc_serial_platdata *plat = dev->platdata;
+       struct mxc_uart *const uart = plat->reg;
+
+       writel(0, &uart->cr1);
+       writel(0, &uart->cr2);
+       while (!(readl(&uart->cr2) & UCR2_SRST));
+       writel(0x704 | UCR3_ADNIMP, &uart->cr3);
+       writel(0x8000, &uart->cr4);
+       writel(0x2b, &uart->esc);
+       writel(0, &uart->tim);
+       writel(0, &uart->ts);
+
+       return 0;
+}
+
+static int mxc_serial_getc(struct udevice *dev)
+{
+       struct mxc_serial_platdata *plat = dev->platdata;
+       struct mxc_uart *const uart = plat->reg;
+
+       if (readl(&uart->ts) & UTS_RXEMPTY)
+               return -EAGAIN;
+
+       return readl(&uart->rxd) & URXD_RX_DATA;
+}
+
+static int mxc_serial_putc(struct udevice *dev, const char ch)
+{
+       struct mxc_serial_platdata *plat = dev->platdata;
+       struct mxc_uart *const uart = plat->reg;
+
+       if (!(readl(&uart->ts) & UTS_TXEMPTY))
+               return -EAGAIN;
+
+       writel(ch, &uart->txd);
+
+       return 0;
+}
+
+static int mxc_serial_pending(struct udevice *dev, bool input)
+{
+       struct mxc_serial_platdata *plat = dev->platdata;
+       struct mxc_uart *const uart = plat->reg;
+       uint32_t sr2 = readl(&uart->sr2);
+
+       if (input)
+               return sr2 & USR2_RDR ? 1 : 0;
+       else
+               return sr2 & USR2_TXDC ? 0 : 1;
+}
+
+static const struct dm_serial_ops mxc_serial_ops = {
+       .putc = mxc_serial_putc,
+       .pending = mxc_serial_pending,
+       .getc = mxc_serial_getc,
+       .setbrg = mxc_serial_setbrg,
+};
+
+U_BOOT_DRIVER(serial_mxc) = {
+       .name   = "serial_mxc",
+       .id     = UCLASS_SERIAL,
+       .probe = mxc_serial_probe,
+       .ops    = &mxc_serial_ops,
+       .flags = DM_FLAG_PRE_RELOC,
+};
+#endif
index 632da4cf70bb93c15c2a84a93815b6b6078c06c4..799ef6a667d16a1d38427be6e642633848c9a9c4 100644 (file)
@@ -119,8 +119,7 @@ static NS16550_t serial_ports[6] = {
        .puts   = eserial##port##_puts,         \
 }
 
-void
-_serial_putc(const char c,const int port)
+static void _serial_putc(const char c, const int port)
 {
        if (c == '\n')
                NS16550_putc(PORT, '\r');
@@ -128,35 +127,29 @@ _serial_putc(const char c,const int port)
        NS16550_putc(PORT, c);
 }
 
-void
-_serial_putc_raw(const char c,const int port)
+static void _serial_putc_raw(const char c, const int port)
 {
        NS16550_putc(PORT, c);
 }
 
-void
-_serial_puts (const char *s,const int port)
+static void _serial_puts(const char *s, const int port)
 {
        while (*s) {
-               _serial_putc (*s++,port);
+               _serial_putc(*s++, port);
        }
 }
 
-
-int
-_serial_getc(const int port)
+static int _serial_getc(const int port)
 {
        return NS16550_getc(PORT);
 }
 
-int
-_serial_tstc(const int port)
+static int _serial_tstc(const int port)
 {
        return NS16550_tstc(PORT);
 }
 
-void
-_serial_setbrg (const int port)
+static void _serial_setbrg(const int port)
 {
        int clock_divisor;
 
diff --git a/drivers/serial/serial_omap.c b/drivers/serial/serial_omap.c
new file mode 100644 (file)
index 0000000..265fe00
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2014 Google, Inc
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <fdtdec.h>
+#include <ns16550.h>
+#include <serial.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#ifdef CONFIG_OF_CONTROL
+static const struct udevice_id omap_serial_ids[] = {
+       { .compatible = "ti,omap3-uart" },
+       { }
+};
+
+static int omap_serial_ofdata_to_platdata(struct udevice *dev)
+{
+       struct ns16550_platdata *plat = dev_get_platdata(dev);
+       int ret;
+
+       ret = ns16550_serial_ofdata_to_platdata(dev);
+       if (ret)
+               return ret;
+       plat->clock = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
+                                    "clock-frequency", -1);
+       plat->reg_shift = 2;
+
+       return 0;
+}
+#endif
+
+U_BOOT_DRIVER(serial_omap_ns16550) = {
+       .name   = "serial_omap",
+       .id     = UCLASS_SERIAL,
+       .of_match = of_match_ptr(omap_serial_ids),
+       .ofdata_to_platdata = of_match_ptr(omap_serial_ofdata_to_platdata),
+       .platdata_auto_alloc_size = sizeof(struct ns16550_platdata),
+       .priv_auto_alloc_size = sizeof(struct NS16550),
+       .probe = ns16550_serial_probe,
+       .ops    = &ns16550_serial_ops,
+       .flags  = DM_FLAG_PRE_RELOC,
+};
index dfb610e1a9d553429d1462335a6550f6d31afe04..38dda910217652ecf167ad52bbc53af3559e2722 100644 (file)
 /* Simple U-Boot driver for the PrimeCell PL010/PL011 UARTs */
 
 #include <common.h>
+#include <dm.h>
+#include <errno.h>
 #include <watchdog.h>
 #include <asm/io.h>
 #include <serial.h>
+#include <dm/platform_data/serial_pl01x.h>
 #include <linux/compiler.h>
-#include "serial_pl01x.h"
+#include "serial_pl01x_internal.h"
+
+#ifndef CONFIG_DM_SERIAL
 
-/*
- * Integrator AP has two UARTs, we use the first one, at 38400-8-N-1
- * Integrator CP has two UARTs, use the first one, at 38400-8-N-1
- * Versatile PB has four UARTs.
- */
-#define CONSOLE_PORT CONFIG_CONS_INDEX
 static volatile unsigned char *const port[] = CONFIG_PL01x_PORTS;
+static enum pl01x_type pl01x_type __attribute__ ((section(".data")));
+static struct pl01x_regs *base_regs __attribute__ ((section(".data")));
 #define NUM_PORTS (sizeof(port)/sizeof(port[0]))
 
-static void pl01x_putc (int portnum, char c);
-static int pl01x_getc (int portnum);
-static int pl01x_tstc (int portnum);
-unsigned int baudrate = CONFIG_BAUDRATE;
 DECLARE_GLOBAL_DATA_PTR;
+#endif
 
-static struct pl01x_regs *pl01x_get_regs(int portnum)
-{
-       return (struct pl01x_regs *) port[portnum];
-}
-
-#ifdef CONFIG_PL010_SERIAL
-
-static int pl01x_serial_init(void)
+static int pl01x_putc(struct pl01x_regs *regs, char c)
 {
-       struct pl01x_regs *regs = pl01x_get_regs(CONSOLE_PORT);
-       unsigned int divisor;
-
-       /* First, disable everything */
-       writel(0, &regs->pl010_cr);
+       /* Wait until there is space in the FIFO */
+       if (readl(&regs->fr) & UART_PL01x_FR_TXFF)
+               return -EAGAIN;
 
-       /* Set baud rate */
-       switch (baudrate) {
-       case 9600:
-               divisor = UART_PL010_BAUD_9600;
-               break;
+       /* Send the character */
+       writel(c, &regs->dr);
 
-       case 19200:
-               divisor = UART_PL010_BAUD_9600;
-               break;
+       return 0;
+}
 
-       case 38400:
-               divisor = UART_PL010_BAUD_38400;
-               break;
+static int pl01x_getc(struct pl01x_regs *regs)
+{
+       unsigned int data;
 
-       case 57600:
-               divisor = UART_PL010_BAUD_57600;
-               break;
+       /* Wait until there is data in the FIFO */
+       if (readl(&regs->fr) & UART_PL01x_FR_RXFE)
+               return -EAGAIN;
 
-       case 115200:
-               divisor = UART_PL010_BAUD_115200;
-               break;
+       data = readl(&regs->dr);
 
-       default:
-               divisor = UART_PL010_BAUD_38400;
+       /* Check for an error flag */
+       if (data & 0xFFFFFF00) {
+               /* Clear the error */
+               writel(0xFFFFFFFF, &regs->ecr);
+               return -1;
        }
 
-       writel((divisor & 0xf00) >> 8, &regs->pl010_lcrm);
-       writel(divisor & 0xff, &regs->pl010_lcrl);
-
-       /* Set the UART to be 8 bits, 1 stop bit, no parity, fifo enabled */
-       writel(UART_PL010_LCRH_WLEN_8 | UART_PL010_LCRH_FEN, &regs->pl010_lcrh);
-
-       /* Finally, enable the UART */
-       writel(UART_PL010_CR_UARTEN, &regs->pl010_cr);
-
-       return 0;
+       return (int) data;
 }
 
-#endif /* CONFIG_PL010_SERIAL */
-
-#ifdef CONFIG_PL011_SERIAL
+static int pl01x_tstc(struct pl01x_regs *regs)
+{
+       WATCHDOG_RESET();
+       return !(readl(&regs->fr) & UART_PL01x_FR_RXFE);
+}
 
-static int pl01x_serial_init(void)
+static int pl01x_generic_serial_init(struct pl01x_regs *regs,
+                                    enum pl01x_type type)
 {
-       struct pl01x_regs *regs = pl01x_get_regs(CONSOLE_PORT);
-       unsigned int temp;
-       unsigned int divider;
-       unsigned int remainder;
-       unsigned int fraction;
        unsigned int lcr;
 
 #ifdef CONFIG_PL011_SERIAL_FLUSH_ON_INIT
-       /* Empty RX fifo if necessary */
-       if (readl(&regs->pl011_cr) & UART_PL011_CR_UARTEN) {
-               while (!(readl(&regs->fr) & UART_PL01x_FR_RXFE))
-                       readl(&regs->dr);
+       if (type == TYPE_PL011) {
+               /* Empty RX fifo if necessary */
+               if (readl(&regs->pl011_cr) & UART_PL011_CR_UARTEN) {
+                       while (!(readl(&regs->fr) & UART_PL01x_FR_RXFE))
+                               readl(&regs->dr);
+               }
        }
 #endif
 
        /* First, disable everything */
-       writel(0, &regs->pl011_cr);
-
-       /*
-        * Set baud rate
-        *
-        * IBRD = UART_CLK / (16 * BAUD_RATE)
-        * FBRD = RND((64 * MOD(UART_CLK,(16 * BAUD_RATE))) / (16 * BAUD_RATE))
-        */
-       temp = 16 * baudrate;
-       divider = CONFIG_PL011_CLOCK / temp;
-       remainder = CONFIG_PL011_CLOCK % temp;
-       temp = (8 * remainder) / baudrate;
-       fraction = (temp >> 1) + (temp & 1);
-
-       writel(divider, &regs->pl011_ibrd);
-       writel(fraction, &regs->pl011_fbrd);
+       writel(0, &regs->pl010_cr);
 
        /* Set the UART to be 8 bits, 1 stop bit, no parity, fifo enabled */
        lcr = UART_PL011_LCRH_WLEN_8 | UART_PL011_LCRH_FEN;
        writel(lcr, &regs->pl011_lcrh);
 
+       switch (type) {
+       case TYPE_PL010:
+               break;
+       case TYPE_PL011: {
 #ifdef CONFIG_PL011_SERIAL_RLCR
-       {
                int i;
 
                /*
@@ -144,90 +109,151 @@ static int pl01x_serial_init(void)
                writel(lcr, &regs->pl011_rlcr);
                /* lcrh needs to be set again for change to be effective */
                writel(lcr, &regs->pl011_lcrh);
-       }
 #endif
-       /* Finally, enable the UART */
-       writel(UART_PL011_CR_UARTEN | UART_PL011_CR_TXE | UART_PL011_CR_RXE |
-              UART_PL011_CR_RTS, &regs->pl011_cr);
+               break;
+       }
+       default:
+               return -EINVAL;
+       }
 
        return 0;
 }
 
-#endif /* CONFIG_PL011_SERIAL */
-
-static void pl01x_serial_putc(const char c)
+static int pl01x_generic_setbrg(struct pl01x_regs *regs, enum pl01x_type type,
+                               int clock, int baudrate)
 {
-       if (c == '\n')
-               pl01x_putc (CONSOLE_PORT, '\r');
+       switch (type) {
+       case TYPE_PL010: {
+               unsigned int divisor;
+
+               switch (baudrate) {
+               case 9600:
+                       divisor = UART_PL010_BAUD_9600;
+                       break;
+               case 19200:
+                       divisor = UART_PL010_BAUD_9600;
+                       break;
+               case 38400:
+                       divisor = UART_PL010_BAUD_38400;
+                       break;
+               case 57600:
+                       divisor = UART_PL010_BAUD_57600;
+                       break;
+               case 115200:
+                       divisor = UART_PL010_BAUD_115200;
+                       break;
+               default:
+                       divisor = UART_PL010_BAUD_38400;
+               }
+
+               writel((divisor & 0xf00) >> 8, &regs->pl010_lcrm);
+               writel(divisor & 0xff, &regs->pl010_lcrl);
+
+               /* Finally, enable the UART */
+               writel(UART_PL010_CR_UARTEN, &regs->pl010_cr);
+               break;
+       }
+       case TYPE_PL011: {
+               unsigned int temp;
+               unsigned int divider;
+               unsigned int remainder;
+               unsigned int fraction;
 
-       pl01x_putc (CONSOLE_PORT, c);
-}
+               /*
+               * Set baud rate
+               *
+               * IBRD = UART_CLK / (16 * BAUD_RATE)
+               * FBRD = RND((64 * MOD(UART_CLK,(16 * BAUD_RATE)))
+               *               / (16 * BAUD_RATE))
+               */
+               temp = 16 * baudrate;
+               divider = clock / temp;
+               remainder = clock % temp;
+               temp = (8 * remainder) / baudrate;
+               fraction = (temp >> 1) + (temp & 1);
+
+               writel(divider, &regs->pl011_ibrd);
+               writel(fraction, &regs->pl011_fbrd);
+
+               /* Finally, enable the UART */
+               writel(UART_PL011_CR_UARTEN | UART_PL011_CR_TXE |
+                      UART_PL011_CR_RXE | UART_PL011_CR_RTS, &regs->pl011_cr);
+               break;
+       }
+       default:
+               return -EINVAL;
+       }
 
-static int pl01x_serial_getc(void)
-{
-       return pl01x_getc (CONSOLE_PORT);
+       return 0;
 }
 
-static int pl01x_serial_tstc(void)
+#ifndef CONFIG_DM_SERIAL
+static void pl01x_serial_init_baud(int baudrate)
 {
-       return pl01x_tstc (CONSOLE_PORT);
+       int clock = 0;
+
+#if defined(CONFIG_PL010_SERIAL)
+       pl01x_type = TYPE_PL010;
+#elif defined(CONFIG_PL011_SERIAL)
+       pl01x_type = TYPE_PL011;
+       clock = CONFIG_PL011_CLOCK;
+#endif
+       base_regs = (struct pl01x_regs *)port[CONFIG_CONS_INDEX];
+
+       pl01x_generic_serial_init(base_regs, pl01x_type);
+       pl01x_generic_setbrg(base_regs, TYPE_PL010, clock, baudrate);
 }
 
-static void pl01x_serial_setbrg(void)
+/*
+ * Integrator AP has two UARTs, we use the first one, at 38400-8-N-1
+ * Integrator CP has two UARTs, use the first one, at 38400-8-N-1
+ * Versatile PB has four UARTs.
+ */
+int pl01x_serial_init(void)
 {
-       struct pl01x_regs *regs = pl01x_get_regs(CONSOLE_PORT);
+       pl01x_serial_init_baud(CONFIG_BAUDRATE);
 
-       baudrate = gd->baudrate;
-       /*
-        * Flush FIFO and wait for non-busy before changing baudrate to avoid
-        * crap in console
-        */
-       while (!(readl(&regs->fr) & UART_PL01x_FR_TXFE))
-               WATCHDOG_RESET();
-       while (readl(&regs->fr) & UART_PL01x_FR_BUSY)
-               WATCHDOG_RESET();
-       serial_init();
+       return 0;
 }
 
-static void pl01x_putc (int portnum, char c)
+static void pl01x_serial_putc(const char c)
 {
-       struct pl01x_regs *regs = pl01x_get_regs(portnum);
-
-       /* Wait until there is space in the FIFO */
-       while (readl(&regs->fr) & UART_PL01x_FR_TXFF)
-               WATCHDOG_RESET();
+       if (c == '\n')
+               while (pl01x_putc(base_regs, '\r') == -EAGAIN);
 
-       /* Send the character */
-       writel(c, &regs->dr);
+       while (pl01x_putc(base_regs, c) == -EAGAIN);
 }
 
-static int pl01x_getc (int portnum)
+static int pl01x_serial_getc(void)
 {
-       struct pl01x_regs *regs = pl01x_get_regs(portnum);
-       unsigned int data;
+       while (1) {
+               int ch = pl01x_getc(base_regs);
 
-       /* Wait until there is data in the FIFO */
-       while (readl(&regs->fr) & UART_PL01x_FR_RXFE)
-               WATCHDOG_RESET();
-
-       data = readl(&regs->dr);
+               if (ch == -EAGAIN) {
+                       WATCHDOG_RESET();
+                       continue;
+               }
 
-       /* Check for an error flag */
-       if (data & 0xFFFFFF00) {
-               /* Clear the error */
-               writel(0xFFFFFFFF, &regs->ecr);
-               return -1;
+               return ch;
        }
-
-       return (int) data;
 }
 
-static int pl01x_tstc (int portnum)
+static int pl01x_serial_tstc(void)
 {
-       struct pl01x_regs *regs = pl01x_get_regs(portnum);
+       return pl01x_tstc(base_regs);
+}
 
-       WATCHDOG_RESET();
-       return !(readl(&regs->fr) & UART_PL01x_FR_RXFE);
+static void pl01x_serial_setbrg(void)
+{
+       /*
+        * Flush FIFO and wait for non-busy before changing baudrate to avoid
+        * crap in console
+        */
+       while (!(readl(&base_regs->fr) & UART_PL01x_FR_TXFE))
+               WATCHDOG_RESET();
+       while (readl(&base_regs->fr) & UART_PL01x_FR_BUSY)
+               WATCHDOG_RESET();
+       pl01x_serial_init_baud(gd->baudrate);
 }
 
 static struct serial_device pl01x_serial_drv = {
@@ -250,3 +276,74 @@ __weak struct serial_device *default_serial_console(void)
 {
        return &pl01x_serial_drv;
 }
+
+#endif /* nCONFIG_DM_SERIAL */
+
+#ifdef CONFIG_DM_SERIAL
+
+struct pl01x_priv {
+       struct pl01x_regs *regs;
+       enum pl01x_type type;
+};
+
+static int pl01x_serial_setbrg(struct udevice *dev, int baudrate)
+{
+       struct pl01x_serial_platdata *plat = dev_get_platdata(dev);
+       struct pl01x_priv *priv = dev_get_priv(dev);
+
+       pl01x_generic_setbrg(priv->regs, priv->type, plat->clock, baudrate);
+
+       return 0;
+}
+
+static int pl01x_serial_probe(struct udevice *dev)
+{
+       struct pl01x_serial_platdata *plat = dev_get_platdata(dev);
+       struct pl01x_priv *priv = dev_get_priv(dev);
+
+       priv->regs = (struct pl01x_regs *)plat->base;
+       priv->type = plat->type;
+       return pl01x_generic_serial_init(priv->regs, priv->type);
+}
+
+static int pl01x_serial_getc(struct udevice *dev)
+{
+       struct pl01x_priv *priv = dev_get_priv(dev);
+
+       return pl01x_getc(priv->regs);
+}
+
+static int pl01x_serial_putc(struct udevice *dev, const char ch)
+{
+       struct pl01x_priv *priv = dev_get_priv(dev);
+
+       return pl01x_putc(priv->regs, ch);
+}
+
+static int pl01x_serial_pending(struct udevice *dev, bool input)
+{
+       struct pl01x_priv *priv = dev_get_priv(dev);
+       unsigned int fr = readl(&priv->regs->fr);
+
+       if (input)
+               return pl01x_tstc(priv->regs);
+       else
+               return fr & UART_PL01x_FR_TXFF ? 0 : 1;
+}
+
+static const struct dm_serial_ops pl01x_serial_ops = {
+       .putc = pl01x_serial_putc,
+       .pending = pl01x_serial_pending,
+       .getc = pl01x_serial_getc,
+       .setbrg = pl01x_serial_setbrg,
+};
+
+U_BOOT_DRIVER(serial_pl01x) = {
+       .name   = "serial_pl01x",
+       .id     = UCLASS_SERIAL,
+       .probe = pl01x_serial_probe,
+       .ops    = &pl01x_serial_ops,
+       .flags = DM_FLAG_PRE_RELOC,
+};
+
+#endif
index c07f4c9b4737f5a64ea59e1a570e77c9850e0f7f..7afc5044a8c70f77607a5e1d351b83b2681b012b 100644 (file)
@@ -69,7 +69,7 @@ DECLARE_GLOBAL_DATA_PTR;
 static int hwflow;
 #endif
 
-void _serial_setbrg(const int dev_index)
+static void _serial_setbrg(const int dev_index)
 {
        struct s3c24x0_uart *uart = s3c24x0_get_base_uart(dev_index);
        unsigned int reg = 0;
@@ -131,7 +131,7 @@ static int serial_init_dev(const int dev_index)
  * otherwise. When the function is succesfull, the character read is
  * written into its argument c.
  */
-int _serial_getc(const int dev_index)
+static int _serial_getc(const int dev_index)
 {
        struct s3c24x0_uart *uart = s3c24x0_get_base_uart(dev_index);
 
@@ -181,7 +181,7 @@ void enable_putc(void)
 /*
  * Output a single byte to the serial port.
  */
-void _serial_putc(const char c, const int dev_index)
+static void _serial_putc(const char c, const int dev_index)
 {
        struct s3c24x0_uart *uart = s3c24x0_get_base_uart(dev_index);
 #ifdef CONFIG_MODEM_SUPPORT
@@ -212,7 +212,7 @@ static inline void serial_putc_dev(unsigned int dev_index, const char c)
 /*
  * Test whether a character is in the RX buffer
  */
-int _serial_tstc(const int dev_index)
+static int _serial_tstc(const int dev_index)
 {
        struct s3c24x0_uart *uart = s3c24x0_get_base_uart(dev_index);
 
@@ -224,7 +224,7 @@ static inline int serial_tstc_dev(unsigned int dev_index)
        return _serial_tstc(dev_index);
 }
 
-void _serial_puts(const char *s, const int dev_index)
+static void _serial_puts(const char *s, const int dev_index)
 {
        while (*s) {
                _serial_putc(*s++, dev_index);
index 98c62b4c147ef185d8a9cabb0290be854a38b892..8469afdaae9da8d18e046218a354eb789b87ddd5 100644 (file)
@@ -9,6 +9,8 @@
  */
 
 #include <common.h>
+#include <dm.h>
+#include <errno.h>
 #include <fdtdec.h>
 #include <linux/compiler.h>
 #include <asm/io.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
-#define RX_FIFO_COUNT_MASK     0xff
-#define RX_FIFO_FULL_MASK      (1 << 8)
-#define TX_FIFO_FULL_MASK      (1 << 24)
+#define RX_FIFO_COUNT_SHIFT    0
+#define RX_FIFO_COUNT_MASK     (0xff << RX_FIFO_COUNT_SHIFT)
+#define RX_FIFO_FULL           (1 << 8)
+#define TX_FIFO_COUNT_SHIFT    16
+#define TX_FIFO_COUNT_MASK     (0xff << TX_FIFO_COUNT_SHIFT)
+#define TX_FIFO_FULL           (1 << 24)
 
 /* Information about a serial port */
-struct fdt_serial {
-       u32 base_addr;  /* address of registers in physical memory */
+struct s5p_serial_platdata {
+       struct s5p_uart *reg;  /* address of registers in physical memory */
        u8 port_id;     /* uart port number */
-       u8 enabled;     /* 1 if enabled, 0 if disabled */
-} config __attribute__ ((section(".data")));
-
-static inline struct s5p_uart *s5p_get_base_uart(int dev_index)
-{
-#ifdef CONFIG_OF_CONTROL
-       return (struct s5p_uart *)(config.base_addr);
-#else
-       u32 offset = dev_index * sizeof(struct s5p_uart);
-       return (struct s5p_uart *)(samsung_get_base_uart() + offset);
-#endif
-}
+};
 
 /*
  * The coefficient, used to calculate the baudrate on S5P UARTs is
@@ -65,23 +59,13 @@ static const int udivslot[] = {
        0xffdf,
 };
 
-static void serial_setbrg_dev(const int dev_index)
+int s5p_serial_setbrg(struct udevice *dev, int baudrate)
 {
-       struct s5p_uart *const uart = s5p_get_base_uart(dev_index);
-       u32 uclk = get_uart_clk(dev_index);
-       u32 baudrate = gd->baudrate;
+       struct s5p_serial_platdata *plat = dev->platdata;
+       struct s5p_uart *const uart = plat->reg;
+       u32 uclk = get_uart_clk(plat->port_id);
        u32 val;
 
-#if defined(CONFIG_SILENT_CONSOLE) && \
-               defined(CONFIG_OF_CONTROL) && \
-               !defined(CONFIG_SPL_BUILD)
-       if (fdtdec_get_config_int(gd->fdt_blob, "silent_console", 0))
-               gd->flags |= GD_FLG_SILENT;
-#endif
-
-       if (!config.enabled)
-               return;
-
        val = uclk / baudrate;
 
        writel(val / 16 - 1, &uart->ubrdiv);
@@ -90,15 +74,14 @@ static void serial_setbrg_dev(const int dev_index)
                writew(udivslot[val % 16], &uart->rest.slot);
        else
                writeb(val % 16, &uart->rest.value);
+
+       return 0;
 }
 
-/*
- * Initialise the serial port with the given baudrate. The settings
- * are always 8 data bits, no parity, 1 stop bit, no start bits.
- */
-static int serial_init_dev(const int dev_index)
+static int s5p_serial_probe(struct udevice *dev)
 {
-       struct s5p_uart *const uart = s5p_get_base_uart(dev_index);
+       struct s5p_serial_platdata *plat = dev->platdata;
+       struct s5p_uart *const uart = plat->reg;
 
        /* enable FIFOs, auto clear Rx FIFO */
        writel(0x3, &uart->ufcon);
@@ -108,14 +91,11 @@ static int serial_init_dev(const int dev_index)
        /* No interrupts, no DMA, pure polling */
        writel(0x245, &uart->ucon);
 
-       serial_setbrg_dev(dev_index);
-
        return 0;
 }
 
-static int serial_err_check(const int dev_index, int op)
+static int serial_err_check(const struct s5p_uart *const uart, int op)
 {
-       struct s5p_uart *const uart = s5p_get_base_uart(dev_index);
        unsigned int mask;
 
        /*
@@ -133,169 +113,78 @@ static int serial_err_check(const int dev_index, int op)
        return readl(&uart->uerstat) & mask;
 }
 
-/*
- * Read a single byte from the serial port. Returns 1 on success, 0
- * otherwise. When the function is succesfull, the character read is
- * written into its argument c.
- */
-static int serial_getc_dev(const int dev_index)
+static int s5p_serial_getc(struct udevice *dev)
 {
-       struct s5p_uart *const uart = s5p_get_base_uart(dev_index);
-
-       if (!config.enabled)
-               return 0;
+       struct s5p_serial_platdata *plat = dev->platdata;
+       struct s5p_uart *const uart = plat->reg;
 
-       /* wait for character to arrive */
-       while (!(readl(&uart->ufstat) & (RX_FIFO_COUNT_MASK |
-                                        RX_FIFO_FULL_MASK))) {
-               if (serial_err_check(dev_index, 0))
-                       return 0;
-       }
+       if (!(readl(&uart->ufstat) & RX_FIFO_COUNT_MASK))
+               return -EAGAIN;
 
+       serial_err_check(uart, 0);
        return (int)(readb(&uart->urxh) & 0xff);
 }
 
-/*
- * Output a single byte to the serial port.
- */
-static void serial_putc_dev(const char c, const int dev_index)
+static int s5p_serial_putc(struct udevice *dev, const char ch)
 {
-       struct s5p_uart *const uart = s5p_get_base_uart(dev_index);
-
-       if (!config.enabled)
-               return;
-
-       /* wait for room in the tx FIFO */
-       while ((readl(&uart->ufstat) & TX_FIFO_FULL_MASK)) {
-               if (serial_err_check(dev_index, 1))
-                       return;
-       }
+       struct s5p_serial_platdata *plat = dev->platdata;
+       struct s5p_uart *const uart = plat->reg;
 
-       writeb(c, &uart->utxh);
+       if (readl(&uart->ufstat) & TX_FIFO_FULL)
+               return -EAGAIN;
 
-       /* If \n, also do \r */
-       if (c == '\n')
-               serial_putc('\r');
-}
-
-/*
- * Test whether a character is in the RX buffer
- */
-static int serial_tstc_dev(const int dev_index)
-{
-       struct s5p_uart *const uart = s5p_get_base_uart(dev_index);
+       writeb(ch, &uart->utxh);
+       serial_err_check(uart, 1);
 
-       if (!config.enabled)
-               return 0;
-
-       return (int)(readl(&uart->utrstat) & 0x1);
+       return 0;
 }
 
-static void serial_puts_dev(const char *s, const int dev_index)
+static int s5p_serial_pending(struct udevice *dev, bool input)
 {
-       while (*s)
-               serial_putc_dev(*s++, dev_index);
-}
+       struct s5p_serial_platdata *plat = dev->platdata;
+       struct s5p_uart *const uart = plat->reg;
+       uint32_t ufstat = readl(&uart->ufstat);
 
-/* Multi serial device functions */
-#define DECLARE_S5P_SERIAL_FUNCTIONS(port) \
-static int s5p_serial##port##_init(void) { return serial_init_dev(port); } \
-static void s5p_serial##port##_setbrg(void) { serial_setbrg_dev(port); } \
-static int s5p_serial##port##_getc(void) { return serial_getc_dev(port); } \
-static int s5p_serial##port##_tstc(void) { return serial_tstc_dev(port); } \
-static void s5p_serial##port##_putc(const char c) { serial_putc_dev(c, port); } \
-static void s5p_serial##port##_puts(const char *s) { serial_puts_dev(s, port); }
-
-#define INIT_S5P_SERIAL_STRUCTURE(port, __name) {      \
-       .name   = __name,                               \
-       .start  = s5p_serial##port##_init,              \
-       .stop   = NULL,                                 \
-       .setbrg = s5p_serial##port##_setbrg,            \
-       .getc   = s5p_serial##port##_getc,              \
-       .tstc   = s5p_serial##port##_tstc,              \
-       .putc   = s5p_serial##port##_putc,              \
-       .puts   = s5p_serial##port##_puts,              \
+       if (input)
+               return (ufstat & RX_FIFO_COUNT_MASK) >> RX_FIFO_COUNT_SHIFT;
+       else
+               return (ufstat & TX_FIFO_COUNT_MASK) >> TX_FIFO_COUNT_SHIFT;
 }
 
-DECLARE_S5P_SERIAL_FUNCTIONS(0);
-struct serial_device s5p_serial0_device =
-       INIT_S5P_SERIAL_STRUCTURE(0, "s5pser0");
-DECLARE_S5P_SERIAL_FUNCTIONS(1);
-struct serial_device s5p_serial1_device =
-       INIT_S5P_SERIAL_STRUCTURE(1, "s5pser1");
-DECLARE_S5P_SERIAL_FUNCTIONS(2);
-struct serial_device s5p_serial2_device =
-       INIT_S5P_SERIAL_STRUCTURE(2, "s5pser2");
-DECLARE_S5P_SERIAL_FUNCTIONS(3);
-struct serial_device s5p_serial3_device =
-       INIT_S5P_SERIAL_STRUCTURE(3, "s5pser3");
-
-#ifdef CONFIG_OF_CONTROL
-int fdtdec_decode_console(int *index, struct fdt_serial *uart)
+static int s5p_serial_ofdata_to_platdata(struct udevice *dev)
 {
-       const void *blob = gd->fdt_blob;
-       int node;
+       struct s5p_serial_platdata *plat = dev->platdata;
+       fdt_addr_t addr;
 
-       node = fdt_path_offset(blob, "console");
-       if (node < 0)
-               return node;
+       addr = fdtdec_get_addr(gd->fdt_blob, dev->of_offset, "reg");
+       if (addr == FDT_ADDR_T_NONE)
+               return -EINVAL;
 
-       uart->base_addr = fdtdec_get_addr(blob, node, "reg");
-       if (uart->base_addr == FDT_ADDR_T_NONE)
-               return -FDT_ERR_NOTFOUND;
-
-       uart->port_id = fdtdec_get_int(blob, node, "id", -1);
-       uart->enabled = fdtdec_get_is_enabled(blob, node);
+       plat->reg = (struct s5p_uart *)addr;
+       plat->port_id = fdtdec_get_int(gd->fdt_blob, dev->of_offset, "id", -1);
 
        return 0;
 }
-#endif
 
-__weak struct serial_device *default_serial_console(void)
-{
-#ifdef CONFIG_OF_CONTROL
-       int index = 0;
-
-       if ((!config.base_addr) && (fdtdec_decode_console(&index, &config))) {
-               debug("Cannot decode default console node\n");
-               return NULL;
-       }
-
-       switch (config.port_id) {
-       case 0:
-               return &s5p_serial0_device;
-       case 1:
-               return &s5p_serial1_device;
-       case 2:
-               return &s5p_serial2_device;
-       case 3:
-               return &s5p_serial3_device;
-       default:
-               debug("Unknown config.port_id: %d", config.port_id);
-               break;
-       }
-
-       return NULL;
-#else
-       config.enabled = 1;
-#if defined(CONFIG_SERIAL0)
-       return &s5p_serial0_device;
-#elif defined(CONFIG_SERIAL1)
-       return &s5p_serial1_device;
-#elif defined(CONFIG_SERIAL2)
-       return &s5p_serial2_device;
-#elif defined(CONFIG_SERIAL3)
-       return &s5p_serial3_device;
-#else
-#error "CONFIG_SERIAL? missing."
-#endif
-#endif
-}
+static const struct dm_serial_ops s5p_serial_ops = {
+       .putc = s5p_serial_putc,
+       .pending = s5p_serial_pending,
+       .getc = s5p_serial_getc,
+       .setbrg = s5p_serial_setbrg,
+};
 
-void s5p_serial_initialize(void)
-{
-       serial_register(&s5p_serial0_device);
-       serial_register(&s5p_serial1_device);
-       serial_register(&s5p_serial2_device);
-       serial_register(&s5p_serial3_device);
-}
+static const struct udevice_id s5p_serial_ids[] = {
+       { .compatible = "samsung,exynos4210-uart" },
+       { }
+};
+
+U_BOOT_DRIVER(serial_s5p) = {
+       .name   = "serial_s5p",
+       .id     = UCLASS_SERIAL,
+       .of_match = s5p_serial_ids,
+       .ofdata_to_platdata = s5p_serial_ofdata_to_platdata,
+       .platdata_auto_alloc_size = sizeof(struct s5p_serial_platdata),
+       .probe = s5p_serial_probe,
+       .ops    = &s5p_serial_ops,
+       .flags = DM_FLAG_PRE_RELOC,
+};
index 144a925394513d38b1677030cb97fcc5f96d84cb..7c1f27137615faa4a56f0b40f567c49a0ff73378 100644 (file)
@@ -122,7 +122,7 @@ static void handle_error(void)
        sci_out(&sh_sci, SCLSR, 0x00);
 }
 
-void serial_raw_putc(const char c)
+static void serial_raw_putc(const char c)
 {
        while (1) {
                /* Tx fifo is empty */
@@ -152,7 +152,7 @@ static int sh_serial_tstc(void)
 }
 
 
-int serial_getc_check(void)
+static int serial_getc_check(void)
 {
        unsigned short status;
 
index f8c9d921e283028c5fe199efa7b081bbfc08d09f..9114b3ed6002a1a0d9e3c6303ad07993060b07f9 100644 (file)
@@ -2,14 +2,14 @@
  * Copyright (C) 2012-2014 Panasonic Corporation
  *   Author: Masahiro Yamada <yamada.m@jp.panasonic.com>
  *
- * Based on serial_ns16550.c
- * (C) Copyright 2000
- * Rob Taylor, Flying Pig Systems. robt@flyingpig.com.
- *
  * SPDX-License-Identifier:    GPL-2.0+
  */
 
 #include <common.h>
+#include <asm/io.h>
+#include <asm/errno.h>
+#include <dm/device.h>
+#include <dm/platform_data/serial-uniphier.h>
 #include <serial.h>
 
 #define UART_REG(x)                                    \
@@ -48,157 +48,104 @@ struct uniphier_serial {
 #define UART_LSR_DR    0x01            /* Data ready */
 #define UART_LSR_THRE  0x20            /* Xmit holding register empty */
 
-DECLARE_GLOBAL_DATA_PTR;
+struct uniphier_serial_private_data {
+       struct uniphier_serial __iomem *membase;
+};
+
+#define uniphier_serial_port(dev)      \
+       ((struct uniphier_serial_private_data *)dev_get_priv(dev))->membase
 
-static void uniphier_serial_init(struct uniphier_serial *port)
+int uniphier_serial_setbrg(struct udevice *dev, int baudrate)
 {
+       struct uniphier_serial_platform_data *plat = dev_get_platdata(dev);
+       struct uniphier_serial __iomem *port = uniphier_serial_port(dev);
        const unsigned int mode_x_div = 16;
        unsigned int divisor;
 
        writeb(UART_LCR_WLS_8, &port->lcr);
 
-       divisor = DIV_ROUND_CLOSEST(CONFIG_SYS_UNIPHIER_UART_CLK,
-                                               mode_x_div * gd->baudrate);
+       divisor = DIV_ROUND_CLOSEST(plat->uartclk, mode_x_div * baudrate);
 
        writew(divisor, &port->dlr);
-}
 
-static void uniphier_serial_setbrg(struct uniphier_serial *port)
-{
-       uniphier_serial_init(port);
+       return 0;
 }
 
-static int uniphier_serial_tstc(struct uniphier_serial *port)
+static int uniphier_serial_getc(struct udevice *dev)
 {
-       return (readb(&port->lsr) & UART_LSR_DR) != 0;
-}
+       struct uniphier_serial __iomem *port = uniphier_serial_port(dev);
 
-static int uniphier_serial_getc(struct uniphier_serial *port)
-{
-       while (!uniphier_serial_tstc(port))
-               ;
+       if (!(readb(&port->lsr) & UART_LSR_DR))
+               return -EAGAIN;
 
        return readb(&port->rbr);
 }
 
-static void uniphier_serial_putc(struct uniphier_serial *port, const char c)
+static int uniphier_serial_putc(struct udevice *dev, const char c)
 {
-       if (c == '\n')
-               uniphier_serial_putc(port, '\r');
+       struct uniphier_serial __iomem *port = uniphier_serial_port(dev);
 
-       while (!(readb(&port->lsr) & UART_LSR_THRE))
-               ;
+       if (!(readb(&port->lsr) & UART_LSR_THRE))
+               return -EAGAIN;
 
        writeb(c, &port->thr);
+
+       return 0;
 }
 
-static struct uniphier_serial *serial_ports[4] = {
-#ifdef CONFIG_SYS_UNIPHIER_SERIAL_BASE0
-       (struct uniphier_serial *)CONFIG_SYS_UNIPHIER_SERIAL_BASE0,
-#else
-       NULL,
-#endif
-#ifdef CONFIG_SYS_UNIPHIER_SERIAL_BASE1
-       (struct uniphier_serial *)CONFIG_SYS_UNIPHIER_SERIAL_BASE1,
-#else
-       NULL,
-#endif
-#ifdef CONFIG_SYS_UNIPHIER_SERIAL_BASE2
-       (struct uniphier_serial *)CONFIG_SYS_UNIPHIER_SERIAL_BASE2,
-#else
-       NULL,
-#endif
-#ifdef CONFIG_SYS_UNIPHIER_SERIAL_BASE3
-       (struct uniphier_serial *)CONFIG_SYS_UNIPHIER_SERIAL_BASE3,
-#else
-       NULL,
-#endif
-};
+int uniphier_serial_probe(struct udevice *dev)
+{
+       struct uniphier_serial_private_data *priv = dev_get_priv(dev);
+       struct uniphier_serial_platform_data *plat = dev_get_platdata(dev);
 
-/* Multi serial device functions */
-#define DECLARE_ESERIAL_FUNCTIONS(port) \
-       static int  eserial##port##_init(void) \
-       { \
-               uniphier_serial_init(serial_ports[port]); \
-               return 0 ; \
-       } \
-       static void eserial##port##_setbrg(void) \
-       { \
-               uniphier_serial_setbrg(serial_ports[port]); \
-       } \
-       static int  eserial##port##_getc(void) \
-       { \
-               return uniphier_serial_getc(serial_ports[port]); \
-       } \
-       static int  eserial##port##_tstc(void) \
-       { \
-               return uniphier_serial_tstc(serial_ports[port]); \
-       } \
-       static void eserial##port##_putc(const char c) \
-       { \
-               uniphier_serial_putc(serial_ports[port], c); \
-       }
-
-/* Serial device descriptor */
-#define INIT_ESERIAL_STRUCTURE(port, __name) { \
-       .name   = __name,                       \
-       .start  = eserial##port##_init,         \
-       .stop   = NULL,                         \
-       .setbrg = eserial##port##_setbrg,       \
-       .getc   = eserial##port##_getc,         \
-       .tstc   = eserial##port##_tstc,         \
-       .putc   = eserial##port##_putc,         \
-       .puts   = default_serial_puts,          \
-}
+       priv->membase = map_sysmem(plat->base, sizeof(struct uniphier_serial));
 
-#if defined(CONFIG_SYS_UNIPHIER_SERIAL_BASE0)
-DECLARE_ESERIAL_FUNCTIONS(0);
-struct serial_device uniphier_serial0_device =
-       INIT_ESERIAL_STRUCTURE(0, "ttyS0");
-#endif
-#if defined(CONFIG_SYS_UNIPHIER_SERIAL_BASE1)
-DECLARE_ESERIAL_FUNCTIONS(1);
-struct serial_device uniphier_serial1_device =
-       INIT_ESERIAL_STRUCTURE(1, "ttyS1");
-#endif
-#if defined(CONFIG_SYS_UNIPHIER_SERIAL_BASE2)
-DECLARE_ESERIAL_FUNCTIONS(2);
-struct serial_device uniphier_serial2_device =
-       INIT_ESERIAL_STRUCTURE(2, "ttyS2");
-#endif
-#if defined(CONFIG_SYS_UNIPHIER_SERIAL_BASE3)
-DECLARE_ESERIAL_FUNCTIONS(3);
-struct serial_device uniphier_serial3_device =
-       INIT_ESERIAL_STRUCTURE(3, "ttyS3");
-#endif
+       if (!priv->membase)
+               return -ENOMEM;
 
-__weak struct serial_device *default_serial_console(void)
+       return 0;
+}
+
+int uniphier_serial_remove(struct udevice *dev)
 {
-#if defined(CONFIG_SYS_UNIPHIER_SERIAL_BASE0)
-       return &uniphier_serial0_device;
-#elif defined(CONFIG_SYS_UNIPHIER_SERIAL_BASE1)
-       return &uniphier_serial1_device;
-#elif defined(CONFIG_SYS_UNIPHIER_SERIAL_BASE2)
-       return &uniphier_serial2_device;
-#elif defined(CONFIG_SYS_UNIPHIER_SERIAL_BASE3)
-       return &uniphier_serial3_device;
-#else
-#error "No uniphier serial ports configured."
-#endif
+       unmap_sysmem(uniphier_serial_port(dev));
+
+       return 0;
 }
 
-void uniphier_serial_initialize(void)
+#ifdef CONFIG_OF_CONTROL
+static const struct udevice_id uniphier_uart_of_match = {
+       { .compatible = "panasonic,uniphier-uart"},
+       {},
+};
+
+static int uniphier_serial_ofdata_to_platdata(struct udevice *dev)
 {
-#if defined(CONFIG_SYS_UNIPHIER_SERIAL_BASE0)
-       serial_register(&uniphier_serial0_device);
-#endif
-#if defined(CONFIG_SYS_UNIPHIER_SERIAL_BASE1)
-       serial_register(&uniphier_serial1_device);
-#endif
-#if defined(CONFIG_SYS_UNIPHIER_SERIAL_BASE2)
-       serial_register(&uniphier_serial2_device);
-#endif
-#if defined(CONFIG_SYS_UNIPHIER_SERIAL_BASE3)
-       serial_register(&uniphier_serial3_device);
-#endif
+       /*
+        * TODO: Masahiro Yamada (yamada.m@jp.panasonic.com)
+        *
+        * Implement conversion code from DTB to platform data
+        * when supporting CONFIG_OF_CONTROL on UniPhir platform.
+        */
 }
+#endif
+
+static const struct dm_serial_ops uniphier_serial_ops = {
+       .setbrg = uniphier_serial_setbrg,
+       .getc = uniphier_serial_getc,
+       .putc = uniphier_serial_putc,
+};
+
+U_BOOT_DRIVER(uniphier_serial) = {
+       .name = DRIVER_NAME,
+       .id = UCLASS_SERIAL,
+       .of_match = of_match_ptr(uniphier_uart_of_match),
+       .ofdata_to_platdata = of_match_ptr(uniphier_serial_ofdata_to_platdata),
+       .probe = uniphier_serial_probe,
+       .remove = uniphier_serial_remove,
+       .priv_auto_alloc_size = sizeof(struct uniphier_serial_private_data),
+       .platdata_auto_alloc_size =
+                               sizeof(struct uniphier_serial_platform_data),
+       .ops = &uniphier_serial_ops,
+       .flags = DM_FLAG_PRE_RELOC,
+};
diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile
new file mode 100644 (file)
index 0000000..3d4baa5
--- /dev/null
@@ -0,0 +1,5 @@
+#
+# Makefile for the U-boot SOC specific device drivers.
+#
+
+obj-$(CONFIG_ARCH_KEYSTONE)    += keystone/
diff --git a/drivers/soc/keystone/Makefile b/drivers/soc/keystone/Makefile
new file mode 100644 (file)
index 0000000..c000eca
--- /dev/null
@@ -0,0 +1 @@
+obj-$(CONFIG_TI_KEYSTONE_SERDES) += keystone_serdes.o
diff --git a/drivers/soc/keystone/keystone_serdes.c b/drivers/soc/keystone/keystone_serdes.c
new file mode 100644 (file)
index 0000000..dd5eac9
--- /dev/null
@@ -0,0 +1,210 @@
+/*
+ * TI serdes driver for keystone2.
+ *
+ * (C) Copyright 2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <errno.h>
+#include <common.h>
+#include <asm/ti-common/keystone_serdes.h>
+
+#define SERDES_CMU_REGS(x)             (0x0000 + (0x0c00 * (x)))
+#define SERDES_LANE_REGS(x)            (0x0200 + (0x200 * (x)))
+#define SERDES_COMLANE_REGS            0x0a00
+#define SERDES_WIZ_REGS                        0x1fc0
+
+#define SERDES_CMU_REG_000(x)          (SERDES_CMU_REGS(x) + 0x000)
+#define SERDES_CMU_REG_010(x)          (SERDES_CMU_REGS(x) + 0x010)
+#define SERDES_COMLANE_REG_000         (SERDES_COMLANE_REGS + 0x000)
+#define SERDES_LANE_REG_000(x)         (SERDES_LANE_REGS(x) + 0x000)
+#define SERDES_LANE_REG_028(x)         (SERDES_LANE_REGS(x) + 0x028)
+#define SERDES_LANE_CTL_STATUS_REG(x)  (SERDES_WIZ_REGS + 0x0020 + (4 * (x)))
+#define SERDES_PLL_CTL_REG             (SERDES_WIZ_REGS + 0x0034)
+
+#define SERDES_RESET                   BIT(28)
+#define SERDES_LANE_RESET              BIT(29)
+#define SERDES_LANE_LOOPBACK           BIT(30)
+#define SERDES_LANE_EN_VAL(x, y, z)    (x[y] | (z << 26) | (z << 10))
+
+#define SERDES_CMU_CFG_NUM             5
+#define SERDES_COMLANE_CFG_NUM         10
+#define SERDES_LANE_CFG_NUM            10
+
+struct serdes_cfg {
+       u32 ofs;
+       u32 val;
+       u32 mask;
+};
+
+struct cfg_entry {
+       enum ks2_serdes_clock clk;
+       enum ks2_serdes_rate rate;
+       struct serdes_cfg cmu[SERDES_CMU_CFG_NUM];
+       struct serdes_cfg comlane[SERDES_COMLANE_CFG_NUM];
+       struct serdes_cfg lane[SERDES_LANE_CFG_NUM];
+};
+
+/* SERDES PHY lane enable configuration value, indexed by PHY interface */
+static u32 serdes_cfg_lane_enable[] = {
+       0xf000f0c0,     /* SGMII */
+       0xf0e9f038,     /* PCSR */
+};
+
+/* SERDES PHY PLL enable configuration value, indexed by PHY interface  */
+static u32 serdes_cfg_pll_enable[] = {
+       0xe0000000,     /* SGMII */
+       0xee000000,     /* PCSR */
+};
+
+/**
+ * Array to hold all possible serdes configurations.
+ * Combination for 5 clock settings and 6 baud rates.
+ */
+static struct cfg_entry cfgs[] = {
+       {
+               .clk = SERDES_CLOCK_156P25M,
+               .rate = SERDES_RATE_5G,
+               .cmu = {
+                       {0x0000, 0x00800000, 0xffff0000},
+                       {0x0014, 0x00008282, 0x0000ffff},
+                       {0x0060, 0x00142438, 0x00ffffff},
+                       {0x0064, 0x00c3c700, 0x00ffff00},
+                       {0x0078, 0x0000c000, 0x0000ff00}
+               },
+               .comlane = {
+                       {0x0a00, 0x00000800, 0x0000ff00},
+                       {0x0a08, 0x38a20000, 0xffff0000},
+                       {0x0a30, 0x008a8a00, 0x00ffff00},
+                       {0x0a84, 0x00000600, 0x0000ff00},
+                       {0x0a94, 0x10000000, 0xff000000},
+                       {0x0aa0, 0x81000000, 0xff000000},
+                       {0x0abc, 0xff000000, 0xff000000},
+                       {0x0ac0, 0x0000008b, 0x000000ff},
+                       {0x0b08, 0x583f0000, 0xffff0000},
+                       {0x0b0c, 0x0000004e, 0x000000ff}
+               },
+               .lane = {
+                       {0x0004, 0x38000080, 0xff0000ff},
+                       {0x0008, 0x00000000, 0x000000ff},
+                       {0x000c, 0x02000000, 0xff000000},
+                       {0x0010, 0x1b000000, 0xff000000},
+                       {0x0014, 0x00006fb8, 0x0000ffff},
+                       {0x0018, 0x758000e4, 0xffff00ff},
+                       {0x00ac, 0x00004400, 0x0000ff00},
+                       {0x002c, 0x00100800, 0x00ffff00},
+                       {0x0080, 0x00820082, 0x00ff00ff},
+                       {0x0084, 0x1d0f0385, 0xffffffff}
+               },
+       },
+};
+
+static inline void ks2_serdes_rmw(u32 addr, u32 value, u32 mask)
+{
+       writel(((readl(addr) & (~mask)) | (value & mask)), addr);
+}
+
+static void ks2_serdes_cfg_setup(u32 base, struct serdes_cfg *cfg, u32 size)
+{
+       u32 i;
+
+       for (i = 0; i < size; i++)
+               ks2_serdes_rmw(base + cfg[i].ofs, cfg[i].val, cfg[i].mask);
+}
+
+static void ks2_serdes_lane_config(u32 base, struct serdes_cfg *cfg_lane,
+                                  u32 size, u32 lane)
+{
+       u32 i;
+
+       for (i = 0; i < size; i++)
+               ks2_serdes_rmw(base + cfg_lane[i].ofs + SERDES_LANE_REGS(lane),
+                              cfg_lane[i].val, cfg_lane[i].mask);
+}
+
+static int ks2_serdes_init_cfg(u32 base, struct cfg_entry *cfg, u32 num_lanes)
+{
+       u32 i;
+
+       ks2_serdes_cfg_setup(base, cfg->cmu, SERDES_CMU_CFG_NUM);
+       ks2_serdes_cfg_setup(base, cfg->comlane, SERDES_COMLANE_CFG_NUM);
+
+       for (i = 0; i < num_lanes; i++)
+               ks2_serdes_lane_config(base, cfg->lane, SERDES_LANE_CFG_NUM, i);
+
+       return 0;
+}
+
+static void ks2_serdes_cmu_comlane_enable(u32 base, struct ks2_serdes *serdes)
+{
+       /* Bring SerDes out of Reset */
+       ks2_serdes_rmw(base + SERDES_CMU_REG_010(0), 0x0, SERDES_RESET);
+       if (serdes->intf == SERDES_PHY_PCSR)
+               ks2_serdes_rmw(base + SERDES_CMU_REG_010(1), 0x0, SERDES_RESET);
+
+       /* Enable CMU and COMLANE */
+       ks2_serdes_rmw(base + SERDES_CMU_REG_000(0), 0x03, 0x000000ff);
+       if (serdes->intf == SERDES_PHY_PCSR)
+               ks2_serdes_rmw(base + SERDES_CMU_REG_000(1), 0x03, 0x000000ff);
+
+       ks2_serdes_rmw(base + SERDES_COMLANE_REG_000, 0x5f, 0x000000ff);
+}
+
+static void ks2_serdes_pll_enable(u32 base, struct ks2_serdes *serdes)
+{
+       writel(serdes_cfg_pll_enable[serdes->intf],
+              base + SERDES_PLL_CTL_REG);
+}
+
+static void ks2_serdes_lane_reset(u32 base, u32 reset, u32 lane)
+{
+       if (reset)
+               ks2_serdes_rmw(base + SERDES_LANE_REG_028(lane),
+                              0x1, SERDES_LANE_RESET);
+       else
+               ks2_serdes_rmw(base + SERDES_LANE_REG_028(lane),
+                              0x0, SERDES_LANE_RESET);
+}
+
+static void ks2_serdes_lane_enable(u32 base,
+                                  struct ks2_serdes *serdes, u32 lane)
+{
+       /* Bring lane out of reset */
+       ks2_serdes_lane_reset(base, 0, lane);
+
+       writel(SERDES_LANE_EN_VAL(serdes_cfg_lane_enable, serdes->intf,
+                                 serdes->rate_mode),
+              base + SERDES_LANE_CTL_STATUS_REG(lane));
+
+       /* Set NES bit if Loopback Enabled */
+       if (serdes->loopback)
+               ks2_serdes_rmw(base + SERDES_LANE_REG_000(lane),
+                              0x1, SERDES_LANE_LOOPBACK);
+}
+
+int ks2_serdes_init(u32 base, struct ks2_serdes *serdes, u32 num_lanes)
+{
+       int i;
+       int ret = 0;
+
+       for (i = 0; i < ARRAY_SIZE(cfgs); i++)
+               if (serdes->clk == cfgs[i].clk && serdes->rate == cfgs[i].rate)
+                       break;
+
+       if (i >= ARRAY_SIZE(cfgs)) {
+               puts("Cannot find keystone SerDes configuration");
+               return -EINVAL;
+       }
+
+       ks2_serdes_init_cfg(base, &cfgs[i], num_lanes);
+
+       ks2_serdes_cmu_comlane_enable(base, serdes);
+       for (i = 0; i < num_lanes; i++)
+               ks2_serdes_lane_enable(base, serdes, i);
+
+       ks2_serdes_pll_enable(base, serdes);
+
+       return ret;
+}
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..e1678e63e6adf976e4514978a3d2e1a9b6634c42 100644 (file)
@@ -0,0 +1,6 @@
+config DM_SPI
+       bool "Enable Driver Model for SPI drivers"
+       depends on DM
+       help
+         If you want to use driver model for SPI drivers, say Y.
+         To use legacy SPI drivers, say N.
index f02c35a52c0cd5100804342ca0e05a915151fd7d..eabbf27d4d0449cf0ed93d3983479cb629fd1108 100644 (file)
@@ -6,7 +6,14 @@
 #
 
 # There are many options which enable SPI, so make this library available
+ifdef CONFIG_DM_SPI
+obj-y += spi-uclass.o
+obj-$(CONFIG_SANDBOX) += spi-emul-uclass.o
+obj-$(CONFIG_SOFT_SPI) += soft_spi.o
+else
 obj-y += spi.o
+obj-$(CONFIG_SOFT_SPI) += soft_spi_legacy.o
+endif
 
 obj-$(CONFIG_EP93XX_SPI) += ep93xx_spi.o
 obj-$(CONFIG_ALTERA_SPI) += altera_spi.o
@@ -30,11 +37,9 @@ obj-$(CONFIG_MXS_SPI) += mxs_spi.o
 obj-$(CONFIG_OC_TINY_SPI) += oc_tiny_spi.o
 obj-$(CONFIG_OMAP3_SPI) += omap3_spi.o
 obj-$(CONFIG_SANDBOX_SPI) += sandbox_spi.o
-obj-$(CONFIG_SOFT_SPI) += soft_spi.o
 obj-$(CONFIG_SH_SPI) += sh_spi.o
 obj-$(CONFIG_SH_QSPI) += sh_qspi.o
 obj-$(CONFIG_FSL_ESPI) += fsl_espi.o
-obj-$(CONFIG_FDT_SPI) += fdt_spi.o
 obj-$(CONFIG_TEGRA20_SFLASH) += tegra20_sflash.o
 obj-$(CONFIG_TEGRA20_SLINK) += tegra20_slink.o
 obj-$(CONFIG_TEGRA114_SPI) += tegra114_spi.o
index 2969184ee877360da2a170b9f2ddb12722ffb08a..f078973531c1d960e5635a485e50c42170b45d80 100644 (file)
@@ -6,6 +6,8 @@
  */
 
 #include <common.h>
+#include <dm.h>
+#include <errno.h>
 #include <malloc.h>
 #include <spi.h>
 #include <fdtdec.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
-/* Information about each SPI controller */
-struct spi_bus {
+struct exynos_spi_platdata {
        enum periph_id periph_id;
        s32 frequency;          /* Default clock frequency, -1 for none */
        struct exynos_spi *regs;
-       int inited;             /* 1 if this bus is ready for use */
-       int node;
        uint deactivate_delay_us;       /* Delay to wait after deactivate */
 };
 
-/* A list of spi buses that we know about */
-static struct spi_bus spi_bus[EXYNOS5_SPI_NUM_CONTROLLERS];
-static unsigned int bus_count;
-
-struct exynos_spi_slave {
-       struct spi_slave slave;
+struct exynos_spi_priv {
        struct exynos_spi *regs;
        unsigned int freq;              /* Default frequency */
        unsigned int mode;
        enum periph_id periph_id;       /* Peripheral ID for this device */
        unsigned int fifo_size;
        int skip_preamble;
-       struct spi_bus *bus;            /* Pointer to our SPI bus info */
        ulong last_transaction_us;      /* Time of last transaction end */
 };
 
-static struct spi_bus *spi_get_bus(unsigned dev_index)
-{
-       if (dev_index < bus_count)
-               return &spi_bus[dev_index];
-       debug("%s: invalid bus %d", __func__, dev_index);
-
-       return NULL;
-}
-
-static inline struct exynos_spi_slave *to_exynos_spi(struct spi_slave *slave)
-{
-       return container_of(slave, struct exynos_spi_slave, slave);
-}
-
-/**
- * Setup the driver private data
- *
- * @param bus          ID of the bus that the slave is attached to
- * @param cs           ID of the chip select connected to the slave
- * @param max_hz       Required spi frequency
- * @param mode         Required spi mode (clk polarity, clk phase and
- *                     master or slave)
- * @return new device or NULL
- */
-struct spi_slave *spi_setup_slave(unsigned int busnum, unsigned int cs,
-                       unsigned int max_hz, unsigned int mode)
-{
-       struct exynos_spi_slave *spi_slave;
-       struct spi_bus *bus;
-
-       if (!spi_cs_is_valid(busnum, cs)) {
-               debug("%s: Invalid bus/chip select %d, %d\n", __func__,
-                     busnum, cs);
-               return NULL;
-       }
-
-       spi_slave = spi_alloc_slave(struct exynos_spi_slave, busnum, cs);
-       if (!spi_slave) {
-               debug("%s: Could not allocate spi_slave\n", __func__);
-               return NULL;
-       }
-
-       bus = &spi_bus[busnum];
-       spi_slave->bus = bus;
-       spi_slave->regs = bus->regs;
-       spi_slave->mode = mode;
-       spi_slave->periph_id = bus->periph_id;
-       if (bus->periph_id == PERIPH_ID_SPI1 ||
-           bus->periph_id == PERIPH_ID_SPI2)
-               spi_slave->fifo_size = 64;
-       else
-               spi_slave->fifo_size = 256;
-
-       spi_slave->skip_preamble = 0;
-       spi_slave->last_transaction_us = timer_get_us();
-
-       spi_slave->freq = bus->frequency;
-       if (max_hz)
-               spi_slave->freq = min(max_hz, spi_slave->freq);
-
-       return &spi_slave->slave;
-}
-
-/**
- * Free spi controller
- *
- * @param slave        Pointer to spi_slave to which controller has to
- *             communicate with
- */
-void spi_free_slave(struct spi_slave *slave)
-{
-       struct exynos_spi_slave *spi_slave = to_exynos_spi(slave);
-
-       free(spi_slave);
-}
-
 /**
  * Flush spi tx, rx fifos and reset the SPI controller
  *
- * @param slave        Pointer to spi_slave to which controller has to
- *             communicate with
+ * @param regs Pointer to SPI registers
  */
-static void spi_flush_fifo(struct spi_slave *slave)
+static void spi_flush_fifo(struct exynos_spi *regs)
 {
-       struct exynos_spi_slave *spi_slave = to_exynos_spi(slave);
-       struct exynos_spi *regs = spi_slave->regs;
-
        clrsetbits_le32(&regs->ch_cfg, SPI_CH_HS_EN, SPI_CH_RST);
        clrbits_le32(&regs->ch_cfg, SPI_CH_RST);
        setbits_le32(&regs->ch_cfg, SPI_TX_CH_ON | SPI_RX_CH_ON);
 }
 
-/**
- * Initialize the spi base registers, set the required clock frequency and
- * initialize the gpios
- *
- * @param slave        Pointer to spi_slave to which controller has to
- *             communicate with
- * @return zero on success else a negative value
- */
-int spi_claim_bus(struct spi_slave *slave)
-{
-       struct exynos_spi_slave *spi_slave = to_exynos_spi(slave);
-       struct exynos_spi *regs = spi_slave->regs;
-       u32 reg = 0;
-       int ret;
-
-       ret = set_spi_clk(spi_slave->periph_id,
-                                       spi_slave->freq);
-       if (ret < 0) {
-               debug("%s: Failed to setup spi clock\n", __func__);
-               return ret;
-       }
-
-       exynos_pinmux_config(spi_slave->periph_id, PINMUX_FLAG_NONE);
-
-       spi_flush_fifo(slave);
-
-       reg = readl(&regs->ch_cfg);
-       reg &= ~(SPI_CH_CPHA_B | SPI_CH_CPOL_L);
-
-       if (spi_slave->mode & SPI_CPHA)
-               reg |= SPI_CH_CPHA_B;
-
-       if (spi_slave->mode & SPI_CPOL)
-               reg |= SPI_CH_CPOL_L;
-
-       writel(reg, &regs->ch_cfg);
-       writel(SPI_FB_DELAY_180, &regs->fb_clk);
-
-       return 0;
-}
-
-/**
- * Reset the spi H/W and flush the tx and rx fifos
- *
- * @param slave        Pointer to spi_slave to which controller has to
- *             communicate with
- */
-void spi_release_bus(struct spi_slave *slave)
-{
-       spi_flush_fifo(slave);
-}
-
 static void spi_get_fifo_levels(struct exynos_spi *regs,
        int *rx_lvl, int *tx_lvl)
 {
@@ -208,6 +69,8 @@ static void spi_get_fifo_levels(struct exynos_spi *regs,
  */
 static void spi_request_bytes(struct exynos_spi *regs, int count, int step)
 {
+       debug("%s: regs=%p, count=%d, step=%d\n", __func__, regs, count, step);
+
        /* For word address we need to swap bytes */
        if (step == 4) {
                setbits_le32(&regs->mode_cfg,
@@ -230,10 +93,10 @@ static void spi_request_bytes(struct exynos_spi *regs, int count, int step)
        writel(count | SPI_PACKET_CNT_EN, &regs->pkt_cnt);
 }
 
-static int spi_rx_tx(struct exynos_spi_slave *spi_slave, int todo,
+static int spi_rx_tx(struct exynos_spi_priv *priv, int todo,
                        void **dinp, void const **doutp, unsigned long flags)
 {
-       struct exynos_spi *regs = spi_slave->regs;
+       struct exynos_spi *regs = priv->regs;
        uchar *rxp = *dinp;
        const uchar *txp = *doutp;
        int rx_lvl, tx_lvl;
@@ -245,8 +108,8 @@ static int spi_rx_tx(struct exynos_spi_slave *spi_slave, int todo,
 
        out_bytes = in_bytes = todo;
 
-       stopping = spi_slave->skip_preamble && (flags & SPI_XFER_END) &&
-                                       !(spi_slave->mode & SPI_SLAVE);
+       stopping = priv->skip_preamble && (flags & SPI_XFER_END) &&
+                                       !(priv->mode & SPI_SLAVE);
 
        /*
         * Try to transfer words if we can. This helps read performance at
@@ -254,7 +117,7 @@ static int spi_rx_tx(struct exynos_spi_slave *spi_slave, int todo,
         */
        step = 1;
        if (!((todo | (uintptr_t)rxp | (uintptr_t)txp) & 3) &&
-           !spi_slave->skip_preamble)
+           !priv->skip_preamble)
                step = 4;
 
        /*
@@ -279,7 +142,7 @@ static int spi_rx_tx(struct exynos_spi_slave *spi_slave, int todo,
                 * Don't completely fill the txfifo, since we don't want our
                 * rxfifo to overflow, and it may already contain data.
                 */
-               while (tx_lvl < spi_slave->fifo_size/2 && out_bytes) {
+               while (tx_lvl < priv->fifo_size/2 && out_bytes) {
                        if (!txp)
                                temp = -1;
                        else if (step == 4)
@@ -295,9 +158,9 @@ static int spi_rx_tx(struct exynos_spi_slave *spi_slave, int todo,
                if (rx_lvl >= step) {
                        while (rx_lvl >= step) {
                                temp = readl(&regs->rx_data);
-                               if (spi_slave->skip_preamble) {
+                               if (priv->skip_preamble) {
                                        if (temp == SPI_PREAMBLE_END_BYTE) {
-                                               spi_slave->skip_preamble = 0;
+                                               priv->skip_preamble = 0;
                                                stopping = 0;
                                        }
                                } else {
@@ -326,7 +189,7 @@ static int spi_rx_tx(struct exynos_spi_slave *spi_slave, int todo,
                        txp = NULL;
                        spi_request_bytes(regs, toread, step);
                }
-               if (spi_slave->skip_preamble && get_timer(start) > 100) {
+               if (priv->skip_preamble && get_timer(start) > 100) {
                        printf("SPI timeout: in_bytes=%d, out_bytes=%d, ",
                               in_bytes, out_bytes);
                        return -1;
@@ -339,95 +202,30 @@ static int spi_rx_tx(struct exynos_spi_slave *spi_slave, int todo,
        return 0;
 }
 
-/**
- * Transfer and receive data
- *
- * @param slave                Pointer to spi_slave to which controller has to
- *                     communicate with
- * @param bitlen       No of bits to tranfer or receive
- * @param dout         Pointer to transfer buffer
- * @param din          Pointer to receive buffer
- * @param flags                Flags for transfer begin and end
- * @return zero on success else a negative value
- */
-int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
-            void *din, unsigned long flags)
-{
-       struct exynos_spi_slave *spi_slave = to_exynos_spi(slave);
-       int upto, todo;
-       int bytelen;
-       int ret = 0;
-
-       /* spi core configured to do 8 bit transfers */
-       if (bitlen % 8) {
-               debug("Non byte aligned SPI transfer.\n");
-               return -1;
-       }
-
-       /* Start the transaction, if necessary. */
-       if ((flags & SPI_XFER_BEGIN))
-               spi_cs_activate(slave);
-
-       /*
-        * Exynos SPI limits each transfer to 65535 transfers. To keep
-        * things simple, allow a maximum of 65532 bytes. We could allow
-        * more in word mode, but the performance difference is small.
-        */
-       bytelen =  bitlen / 8;
-       for (upto = 0; !ret && upto < bytelen; upto += todo) {
-               todo = min(bytelen - upto, (1 << 16) - 4);
-               ret = spi_rx_tx(spi_slave, todo, &din, &dout, flags);
-               if (ret)
-                       break;
-       }
-
-       /* Stop the transaction, if necessary. */
-       if ((flags & SPI_XFER_END) && !(spi_slave->mode & SPI_SLAVE)) {
-               spi_cs_deactivate(slave);
-               if (spi_slave->skip_preamble) {
-                       assert(!spi_slave->skip_preamble);
-                       debug("Failed to complete premable transaction\n");
-                       ret = -1;
-               }
-       }
-
-       return ret;
-}
-
-/**
- * Validates the bus and chip select numbers
- *
- * @param bus  ID of the bus that the slave is attached to
- * @param cs   ID of the chip select connected to the slave
- * @return one on success else zero
- */
-int spi_cs_is_valid(unsigned int bus, unsigned int cs)
-{
-       return spi_get_bus(bus) && cs == 0;
-}
-
 /**
  * Activate the CS by driving it LOW
  *
  * @param slave        Pointer to spi_slave to which controller has to
  *             communicate with
  */
-void spi_cs_activate(struct spi_slave *slave)
+static void spi_cs_activate(struct udevice *dev)
 {
-       struct exynos_spi_slave *spi_slave = to_exynos_spi(slave);
+       struct udevice *bus = dev->parent;
+       struct exynos_spi_platdata *pdata = dev_get_platdata(bus);
+       struct exynos_spi_priv *priv = dev_get_priv(bus);
 
        /* If it's too soon to do another transaction, wait */
-       if (spi_slave->bus->deactivate_delay_us &&
-           spi_slave->last_transaction_us) {
+       if (pdata->deactivate_delay_us &&
+           priv->last_transaction_us) {
                ulong delay_us;         /* The delay completed so far */
-               delay_us = timer_get_us() - spi_slave->last_transaction_us;
-               if (delay_us < spi_slave->bus->deactivate_delay_us)
-                       udelay(spi_slave->bus->deactivate_delay_us - delay_us);
+               delay_us = timer_get_us() - priv->last_transaction_us;
+               if (delay_us < pdata->deactivate_delay_us)
+                       udelay(pdata->deactivate_delay_us - delay_us);
        }
 
-       clrbits_le32(&spi_slave->regs->cs_reg, SPI_SLAVE_SIG_INACT);
-       debug("Activate CS, bus %d\n", spi_slave->slave.bus);
-       spi_slave->skip_preamble = spi_slave->mode & SPI_PREAMBLE;
+       clrbits_le32(&priv->regs->cs_reg, SPI_SLAVE_SIG_INACT);
+       debug("Activate CS, bus '%s'\n", bus->name);
+       priv->skip_preamble = priv->mode & SPI_PREAMBLE;
 }
 
 /**
@@ -436,148 +234,197 @@ void spi_cs_activate(struct spi_slave *slave)
  * @param slave        Pointer to spi_slave to which controller has to
  *             communicate with
  */
-void spi_cs_deactivate(struct spi_slave *slave)
+static void spi_cs_deactivate(struct udevice *dev)
 {
-       struct exynos_spi_slave *spi_slave = to_exynos_spi(slave);
+       struct udevice *bus = dev->parent;
+       struct exynos_spi_platdata *pdata = dev_get_platdata(bus);
+       struct exynos_spi_priv *priv = dev_get_priv(bus);
 
-       setbits_le32(&spi_slave->regs->cs_reg, SPI_SLAVE_SIG_INACT);
+       setbits_le32(&priv->regs->cs_reg, SPI_SLAVE_SIG_INACT);
 
        /* Remember time of this transaction so we can honour the bus delay */
-       if (spi_slave->bus->deactivate_delay_us)
-               spi_slave->last_transaction_us = timer_get_us();
+       if (pdata->deactivate_delay_us)
+               priv->last_transaction_us = timer_get_us();
 
-       debug("Deactivate CS, bus %d\n", spi_slave->slave.bus);
+       debug("Deactivate CS, bus '%s'\n", bus->name);
 }
 
-static inline struct exynos_spi *get_spi_base(int dev_index)
+static int exynos_spi_ofdata_to_platdata(struct udevice *bus)
 {
-       if (dev_index < 3)
-               return (struct exynos_spi *)samsung_get_base_spi() + dev_index;
-       else
-               return (struct exynos_spi *)samsung_get_base_spi_isp() +
-                                       (dev_index - 3);
-}
+       struct exynos_spi_platdata *plat = bus->platdata;
+       const void *blob = gd->fdt_blob;
+       int node = bus->of_offset;
 
-/*
- * Read the SPI config from the device tree node.
- *
- * @param blob  FDT blob to read from
- * @param node  Node offset to read from
- * @param bus   SPI bus structure to fill with information
- * @return 0 if ok, or -FDT_ERR_NOTFOUND if something was missing
- */
-#ifdef CONFIG_OF_CONTROL
-static int spi_get_config(const void *blob, int node, struct spi_bus *bus)
-{
-       bus->node = node;
-       bus->regs = (struct exynos_spi *)fdtdec_get_addr(blob, node, "reg");
-       bus->periph_id = pinmux_decode_periph_id(blob, node);
+       plat->regs = (struct exynos_spi *)fdtdec_get_addr(blob, node, "reg");
+       plat->periph_id = pinmux_decode_periph_id(blob, node);
 
-       if (bus->periph_id == PERIPH_ID_NONE) {
+       if (plat->periph_id == PERIPH_ID_NONE) {
                debug("%s: Invalid peripheral ID %d\n", __func__,
-                       bus->periph_id);
+                       plat->periph_id);
                return -FDT_ERR_NOTFOUND;
        }
 
        /* Use 500KHz as a suitable default */
-       bus->frequency = fdtdec_get_int(blob, node, "spi-max-frequency",
+       plat->frequency = fdtdec_get_int(blob, node, "spi-max-frequency",
                                        500000);
-       bus->deactivate_delay_us = fdtdec_get_int(blob, node,
+       plat->deactivate_delay_us = fdtdec_get_int(blob, node,
                                        "spi-deactivate-delay", 0);
+       debug("%s: regs=%p, periph_id=%d, max-frequency=%d, deactivate_delay=%d\n",
+             __func__, plat->regs, plat->periph_id, plat->frequency,
+             plat->deactivate_delay_us);
 
        return 0;
 }
 
-/*
- * Process a list of nodes, adding them to our list of SPI ports.
- *
- * @param blob          fdt blob
- * @param node_list     list of nodes to process (any <=0 are ignored)
- * @param count         number of nodes to process
- * @param is_dvc        1 if these are DVC ports, 0 if standard I2C
- * @return 0 if ok, -1 on error
- */
-static int process_nodes(const void *blob, int node_list[], int count)
+static int exynos_spi_probe(struct udevice *bus)
 {
-       int i;
+       struct exynos_spi_platdata *plat = dev_get_platdata(bus);
+       struct exynos_spi_priv *priv = dev_get_priv(bus);
 
-       /* build the i2c_controllers[] for each controller */
-       for (i = 0; i < count; i++) {
-               int node = node_list[i];
-               struct spi_bus *bus;
+       priv->regs = plat->regs;
+       if (plat->periph_id == PERIPH_ID_SPI1 ||
+           plat->periph_id == PERIPH_ID_SPI2)
+               priv->fifo_size = 64;
+       else
+               priv->fifo_size = 256;
 
-               if (node <= 0)
-                       continue;
+       priv->skip_preamble = 0;
+       priv->last_transaction_us = timer_get_us();
+       priv->freq = plat->frequency;
+       priv->periph_id = plat->periph_id;
 
-               bus = &spi_bus[i];
-               if (spi_get_config(blob, node, bus)) {
-                       printf("exynos spi_init: failed to decode bus %d\n",
-                               i);
-                       return -1;
-               }
+       return 0;
+}
 
-               debug("spi: controller bus %d at %p, periph_id %d\n",
-                     i, bus->regs, bus->periph_id);
-               bus->inited = 1;
-               bus_count++;
-       }
+static int exynos_spi_claim_bus(struct udevice *bus)
+{
+       struct exynos_spi_priv *priv = dev_get_priv(bus);
+
+       exynos_pinmux_config(priv->periph_id, PINMUX_FLAG_NONE);
+       spi_flush_fifo(priv->regs);
+
+       writel(SPI_FB_DELAY_180, &priv->regs->fb_clk);
 
        return 0;
 }
-#endif
 
-/**
- * Set up a new SPI slave for an fdt node
- *
- * @param blob         Device tree blob
- * @param node         SPI peripheral node to use
- * @return 0 if ok, -1 on error
- */
-struct spi_slave *spi_setup_slave_fdt(const void *blob, int slave_node,
-                                     int spi_node)
+static int exynos_spi_release_bus(struct udevice *bus)
 {
-       struct spi_bus *bus;
-       unsigned int i;
+       struct exynos_spi_priv *priv = dev_get_priv(bus);
+
+       spi_flush_fifo(priv->regs);
+
+       return 0;
+}
+
+static int exynos_spi_xfer(struct udevice *dev, unsigned int bitlen,
+                          const void *dout, void *din, unsigned long flags)
+{
+       struct udevice *bus = dev->parent;
+       struct exynos_spi_priv *priv = dev_get_priv(bus);
+       int upto, todo;
+       int bytelen;
+       int ret = 0;
+
+       /* spi core configured to do 8 bit transfers */
+       if (bitlen % 8) {
+               debug("Non byte aligned SPI transfer.\n");
+               return -1;
+       }
+
+       /* Start the transaction, if necessary. */
+       if ((flags & SPI_XFER_BEGIN))
+               spi_cs_activate(dev);
+
+       /*
+        * Exynos SPI limits each transfer to 65535 transfers. To keep
+        * things simple, allow a maximum of 65532 bytes. We could allow
+        * more in word mode, but the performance difference is small.
+        */
+       bytelen = bitlen / 8;
+       for (upto = 0; !ret && upto < bytelen; upto += todo) {
+               todo = min(bytelen - upto, (1 << 16) - 4);
+               ret = spi_rx_tx(priv, todo, &din, &dout, flags);
+               if (ret)
+                       break;
+       }
 
-       for (i = 0, bus = spi_bus; i < bus_count; i++, bus++) {
-               if (bus->node == spi_node)
-                       return spi_base_setup_slave_fdt(blob, i, slave_node);
+       /* Stop the transaction, if necessary. */
+       if ((flags & SPI_XFER_END) && !(priv->mode & SPI_SLAVE)) {
+               spi_cs_deactivate(dev);
+               if (priv->skip_preamble) {
+                       assert(!priv->skip_preamble);
+                       debug("Failed to complete premable transaction\n");
+                       ret = -1;
+               }
        }
 
-       debug("%s: Failed to find bus node %d\n", __func__, spi_node);
-       return NULL;
+       return ret;
 }
 
-/* Sadly there is no error return from this function */
-void spi_init(void)
+static int exynos_spi_set_speed(struct udevice *bus, uint speed)
 {
-       int count;
+       struct exynos_spi_platdata *plat = bus->platdata;
+       struct exynos_spi_priv *priv = dev_get_priv(bus);
+       int ret;
 
-#ifdef CONFIG_OF_CONTROL
-       int node_list[EXYNOS5_SPI_NUM_CONTROLLERS];
-       const void *blob = gd->fdt_blob;
+       if (speed > plat->frequency)
+               speed = plat->frequency;
+       ret = set_spi_clk(priv->periph_id, speed);
+       if (ret)
+               return ret;
+       priv->freq = speed;
+       debug("%s: regs=%p, speed=%d\n", __func__, priv->regs, priv->freq);
+
+       return 0;
+}
 
-       count = fdtdec_find_aliases_for_id(blob, "spi",
-                       COMPAT_SAMSUNG_EXYNOS_SPI, node_list,
-                       EXYNOS5_SPI_NUM_CONTROLLERS);
-       if (process_nodes(blob, node_list, count))
-               return;
+static int exynos_spi_set_mode(struct udevice *bus, uint mode)
+{
+       struct exynos_spi_priv *priv = dev_get_priv(bus);
+       uint32_t reg;
 
-#else
-       struct spi_bus *bus;
+       reg = readl(&priv->regs->ch_cfg);
+       reg &= ~(SPI_CH_CPHA_B | SPI_CH_CPOL_L);
 
-       for (count = 0; count < EXYNOS5_SPI_NUM_CONTROLLERS; count++) {
-               bus = &spi_bus[count];
-               bus->regs = get_spi_base(count);
-               bus->periph_id = PERIPH_ID_SPI0 + count;
+       if (mode & SPI_CPHA)
+               reg |= SPI_CH_CPHA_B;
 
-               /* Although Exynos5 supports upto 50Mhz speed,
-                * we are setting it to 10Mhz for safe side
-                */
-               bus->frequency = 10000000;
-               bus->inited = 1;
-               bus->node = 0;
-               bus_count = EXYNOS5_SPI_NUM_CONTROLLERS;
-       }
-#endif
+       if (mode & SPI_CPOL)
+               reg |= SPI_CH_CPOL_L;
+
+       writel(reg, &priv->regs->ch_cfg);
+       priv->mode = mode;
+       debug("%s: regs=%p, mode=%d\n", __func__, priv->regs, priv->mode);
+
+       return 0;
 }
+
+static const struct dm_spi_ops exynos_spi_ops = {
+       .claim_bus      = exynos_spi_claim_bus,
+       .release_bus    = exynos_spi_release_bus,
+       .xfer           = exynos_spi_xfer,
+       .set_speed      = exynos_spi_set_speed,
+       .set_mode       = exynos_spi_set_mode,
+       /*
+        * cs_info is not needed, since we require all chip selects to be
+        * in the device tree explicitly
+        */
+};
+
+static const struct udevice_id exynos_spi_ids[] = {
+       { .compatible = "samsung,exynos-spi" },
+       { }
+};
+
+U_BOOT_DRIVER(exynos_spi) = {
+       .name   = "exynos_spi",
+       .id     = UCLASS_SPI,
+       .of_match = exynos_spi_ids,
+       .ops    = &exynos_spi_ops,
+       .ofdata_to_platdata = exynos_spi_ofdata_to_platdata,
+       .platdata_auto_alloc_size = sizeof(struct exynos_spi_platdata),
+       .priv_auto_alloc_size = sizeof(struct exynos_spi_priv),
+       .per_child_auto_alloc_size      = sizeof(struct spi_slave),
+       .probe  = exynos_spi_probe,
+};
diff --git a/drivers/spi/fdt_spi.c b/drivers/spi/fdt_spi.c
deleted file mode 100644 (file)
index 58f139a..0000000
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * Common fdt based SPI driver front end
- *
- * Copyright (c) 2013 NVIDIA Corporation
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-#include <common.h>
-#include <malloc.h>
-#include <asm/io.h>
-#include <asm/gpio.h>
-#include <asm/arch/clock.h>
-#include <asm/arch-tegra/clk_rst.h>
-#include <asm/arch-tegra20/tegra20_sflash.h>
-#include <asm/arch-tegra20/tegra20_slink.h>
-#include <asm/arch-tegra114/tegra114_spi.h>
-#include <spi.h>
-#include <fdtdec.h>
-
-DECLARE_GLOBAL_DATA_PTR;
-
-struct fdt_spi_driver {
-       int compat;
-       int max_ctrls;
-       int (*init)(int *node_list, int count);
-       int (*claim_bus)(struct spi_slave *slave);
-       int (*release_bus)(struct spi_slave *slave);
-       int (*cs_is_valid)(unsigned int bus, unsigned int cs);
-       struct spi_slave *(*setup_slave)(unsigned int bus, unsigned int cs,
-                                       unsigned int max_hz, unsigned int mode);
-       void (*free_slave)(struct spi_slave *slave);
-       void (*cs_activate)(struct spi_slave *slave);
-       void (*cs_deactivate)(struct spi_slave *slave);
-       int (*xfer)(struct spi_slave *slave, unsigned int bitlen,
-                   const void *data_out, void *data_in, unsigned long flags);
-};
-
-static struct fdt_spi_driver fdt_spi_drivers[] = {
-#ifdef CONFIG_TEGRA20_SFLASH
-       {
-               .compat         = COMPAT_NVIDIA_TEGRA20_SFLASH,
-               .max_ctrls      = 1,
-               .init           = tegra20_spi_init,
-               .claim_bus      = tegra20_spi_claim_bus,
-               .cs_is_valid    = tegra20_spi_cs_is_valid,
-               .setup_slave    = tegra20_spi_setup_slave,
-               .free_slave     = tegra20_spi_free_slave,
-               .cs_activate    = tegra20_spi_cs_activate,
-               .cs_deactivate  = tegra20_spi_cs_deactivate,
-               .xfer           = tegra20_spi_xfer,
-       },
-#endif
-#ifdef CONFIG_TEGRA20_SLINK
-       {
-               .compat         = COMPAT_NVIDIA_TEGRA20_SLINK,
-               .max_ctrls      = CONFIG_TEGRA_SLINK_CTRLS,
-               .init           = tegra30_spi_init,
-               .claim_bus      = tegra30_spi_claim_bus,
-               .cs_is_valid    = tegra30_spi_cs_is_valid,
-               .setup_slave    = tegra30_spi_setup_slave,
-               .free_slave     = tegra30_spi_free_slave,
-               .cs_activate    = tegra30_spi_cs_activate,
-               .cs_deactivate  = tegra30_spi_cs_deactivate,
-               .xfer           = tegra30_spi_xfer,
-       },
-#endif
-#ifdef CONFIG_TEGRA114_SPI
-       {
-               .compat         = COMPAT_NVIDIA_TEGRA114_SPI,
-               .max_ctrls      = CONFIG_TEGRA114_SPI_CTRLS,
-               .init           = tegra114_spi_init,
-               .claim_bus      = tegra114_spi_claim_bus,
-               .cs_is_valid    = tegra114_spi_cs_is_valid,
-               .setup_slave    = tegra114_spi_setup_slave,
-               .free_slave     = tegra114_spi_free_slave,
-               .cs_activate    = tegra114_spi_cs_activate,
-               .cs_deactivate  = tegra114_spi_cs_deactivate,
-               .xfer           = tegra114_spi_xfer,
-       },
-#endif
-};
-
-static struct fdt_spi_driver *driver;
-
-int spi_cs_is_valid(unsigned int bus, unsigned int cs)
-{
-       if (!driver)
-               return 0;
-       else if (!driver->cs_is_valid)
-               return 1;
-       else
-               return driver->cs_is_valid(bus, cs);
-}
-
-struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
-               unsigned int max_hz, unsigned int mode)
-{
-       if (!driver || !driver->setup_slave)
-               return NULL;
-
-       return driver->setup_slave(bus, cs, max_hz, mode);
-}
-
-void spi_free_slave(struct spi_slave *slave)
-{
-       if (driver && driver->free_slave)
-               return driver->free_slave(slave);
-}
-
-static int spi_init_driver(struct fdt_spi_driver *driver)
-{
-       int count;
-       int node_list[driver->max_ctrls];
-
-       count = fdtdec_find_aliases_for_id(gd->fdt_blob, "spi",
-                                          driver->compat,
-                                          node_list,
-                                          driver->max_ctrls);
-       return driver->init(node_list, count);
-}
-
-void spi_init(void)
-{
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(fdt_spi_drivers); i++) {
-               driver = &fdt_spi_drivers[i];
-               if (!spi_init_driver(driver))
-                       break;
-       }
-       if (i == ARRAY_SIZE(fdt_spi_drivers))
-               driver = NULL;
-}
-
-int spi_claim_bus(struct spi_slave *slave)
-{
-       if (!driver)
-               return 1;
-       if (!driver->claim_bus)
-               return 0;
-
-       return driver->claim_bus(slave);
-}
-
-void spi_release_bus(struct spi_slave *slave)
-{
-       if (driver && driver->release_bus)
-               driver->release_bus(slave);
-}
-
-void spi_cs_activate(struct spi_slave *slave)
-{
-       if (driver && driver->cs_activate)
-               driver->cs_activate(slave);
-}
-
-void spi_cs_deactivate(struct spi_slave *slave)
-{
-       if (driver && driver->cs_deactivate)
-               driver->cs_deactivate(slave);
-}
-
-int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
-            const void *data_out, void *data_in, unsigned long flags)
-{
-       if (!driver || !driver->xfer)
-               return -1;
-
-       return driver->xfer(slave, bitlen, data_out, data_in, flags);
-}
index 3d58bcc1b955d140b8dc4a3937eba4db59dc6d35..e7b0982fb654681e4b9650d7ce8fe9a9c23d8acd 100644 (file)
 #include <malloc.h>
 #include <spi.h>
 #include <asm/io.h>
-#include <asm/arch/kirkwood.h>
-#include <asm/arch/spi.h>
+#include <asm/arch/soc.h>
+#ifdef CONFIG_KIRKWOOD
 #include <asm/arch/mpp.h>
+#endif
+#include <asm/arch-mvebu/spi.h>
 
-static struct kwspi_registers *spireg = (struct kwspi_registers *)KW_SPI_BASE;
+static struct kwspi_registers *spireg =
+       (struct kwspi_registers *)MVEBU_SPI_BASE;
 
+#ifdef CONFIG_KIRKWOOD
 static u32 cs_spi_mpp_back[2];
+#endif
 
 struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
                                unsigned int max_hz, unsigned int mode)
 {
        struct spi_slave *slave;
        u32 data;
+#ifdef CONFIG_KIRKWOOD
        static const u32 kwspi_mpp_config[2][2] = {
                { MPP0_SPI_SCn, 0 }, /* if cs == 0 */
                { MPP7_SPI_SCn, 0 } /* if cs != 0 */
        };
+#endif
 
        if (!spi_cs_is_valid(bus, cs))
                return NULL;
@@ -51,15 +58,19 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
        writel(KWSPI_SMEMRDIRQ, &spireg->irq_cause);
        writel(KWSPI_IRQMASK, &spireg->irq_mask);
 
+#ifdef CONFIG_KIRKWOOD
        /* program mpp registers to select  SPI_CSn */
        kirkwood_mpp_conf(kwspi_mpp_config[cs ? 1 : 0], cs_spi_mpp_back);
+#endif
 
        return slave;
 }
 
 void spi_free_slave(struct spi_slave *slave)
 {
+#ifdef CONFIG_KIRKWOOD
        kirkwood_mpp_conf(cs_spi_mpp_back, NULL);
+#endif
        free(slave);
 }
 
index 12e9bdad38db51fdc0fdb127d142189d06c127ae..e717424db83a9ff7dcc15bc57074c5722b66ff11 100644 (file)
@@ -9,26 +9,23 @@
  */
 
 #include <common.h>
+#include <dm.h>
 #include <malloc.h>
 #include <spi.h>
+#include <spi_flash.h>
 #include <os.h>
 
 #include <asm/errno.h>
 #include <asm/spi.h>
 #include <asm/state.h>
+#include <dm/device-internal.h>
+
+DECLARE_GLOBAL_DATA_PTR;
 
 #ifndef CONFIG_SPI_IDLE_VAL
 # define CONFIG_SPI_IDLE_VAL 0xFF
 #endif
 
-struct sandbox_spi_slave {
-       struct spi_slave slave;
-       const struct sandbox_spi_emu_ops *ops;
-       void *priv;
-};
-
-#define to_sandbox_spi_slave(s) container_of(s, struct sandbox_spi_slave, slave)
-
 const char *sandbox_spi_parse_spec(const char *arg, unsigned long *bus,
                                   unsigned long *cs)
 {
@@ -45,120 +42,52 @@ const char *sandbox_spi_parse_spec(const char *arg, unsigned long *bus,
        return endp + 1;
 }
 
-int spi_cs_is_valid(unsigned int bus, unsigned int cs)
-{
-       return bus < CONFIG_SANDBOX_SPI_MAX_BUS &&
-               cs < CONFIG_SANDBOX_SPI_MAX_CS;
-}
-
-void spi_cs_activate(struct spi_slave *slave)
-{
-       struct sandbox_spi_slave *sss = to_sandbox_spi_slave(slave);
-
-       debug("sandbox_spi: activating CS\n");
-       if (sss->ops->cs_activate)
-               sss->ops->cs_activate(sss->priv);
-}
-
-void spi_cs_deactivate(struct spi_slave *slave)
-{
-       struct sandbox_spi_slave *sss = to_sandbox_spi_slave(slave);
-
-       debug("sandbox_spi: deactivating CS\n");
-       if (sss->ops->cs_deactivate)
-               sss->ops->cs_deactivate(sss->priv);
-}
-
-void spi_init(void)
-{
-}
-
-void spi_set_speed(struct spi_slave *slave, uint hz)
+__weak int sandbox_spi_get_emul(struct sandbox_state *state,
+                               struct udevice *bus, struct udevice *slave,
+                               struct udevice **emulp)
 {
+       return -ENOENT;
 }
 
-struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
-               unsigned int max_hz, unsigned int mode)
+static int sandbox_spi_xfer(struct udevice *slave, unsigned int bitlen,
+                           const void *dout, void *din, unsigned long flags)
 {
-       struct sandbox_spi_slave *sss;
+       struct udevice *bus = slave->parent;
        struct sandbox_state *state = state_get_current();
-       const char *spec;
-
-       if (!spi_cs_is_valid(bus, cs)) {
-               debug("sandbox_spi: Invalid SPI bus/cs\n");
-               return NULL;
-       }
-
-       sss = spi_alloc_slave(struct sandbox_spi_slave, bus, cs);
-       if (!sss) {
-               debug("sandbox_spi: Out of memory\n");
-               return NULL;
-       }
-
-       spec = state->spi[bus][cs].spec;
-       sss->ops = state->spi[bus][cs].ops;
-       if (!spec || !sss->ops || sss->ops->setup(&sss->priv, spec)) {
-               free(sss);
-               printf("sandbox_spi: unable to locate a slave client\n");
-               return NULL;
-       }
-
-       return &sss->slave;
-}
-
-void spi_free_slave(struct spi_slave *slave)
-{
-       struct sandbox_spi_slave *sss = to_sandbox_spi_slave(slave);
-
-       debug("sandbox_spi: releasing slave\n");
-
-       if (sss->ops->free)
-               sss->ops->free(sss->priv);
-
-       free(sss);
-}
-
-static int spi_bus_claim_cnt[CONFIG_SANDBOX_SPI_MAX_BUS];
-
-int spi_claim_bus(struct spi_slave *slave)
-{
-       if (spi_bus_claim_cnt[slave->bus]++) {
-               printf("sandbox_spi: error: bus already claimed: %d!\n",
-                      spi_bus_claim_cnt[slave->bus]);
-       }
-
-       return 0;
-}
-
-void spi_release_bus(struct spi_slave *slave)
-{
-       if (--spi_bus_claim_cnt[slave->bus]) {
-               printf("sandbox_spi: error: bus freed too often: %d!\n",
-                      spi_bus_claim_cnt[slave->bus]);
-       }
-}
-
-int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
-               void *din, unsigned long flags)
-{
-       struct sandbox_spi_slave *sss = to_sandbox_spi_slave(slave);
+       struct dm_spi_emul_ops *ops;
+       struct udevice *emul;
        uint bytes = bitlen / 8, i;
-       int ret = 0;
+       int ret;
        u8 *tx = (void *)dout, *rx = din;
+       uint busnum, cs;
 
        if (bitlen == 0)
-               goto done;
+               return 0;
 
        /* we can only do 8 bit transfers */
        if (bitlen % 8) {
                printf("sandbox_spi: xfer: invalid bitlen size %u; needs to be 8bit\n",
                       bitlen);
-               flags |= SPI_XFER_END;
-               goto done;
+               return -EINVAL;
        }
 
-       if (flags & SPI_XFER_BEGIN)
-               spi_cs_activate(slave);
+       busnum = bus->seq;
+       cs = spi_chip_select(slave);
+       if (busnum >= CONFIG_SANDBOX_SPI_MAX_BUS ||
+           cs >= CONFIG_SANDBOX_SPI_MAX_CS) {
+               printf("%s: busnum=%u, cs=%u: out of range\n", __func__,
+                      busnum, cs);
+               return -ENOENT;
+       }
+       ret = sandbox_spi_get_emul(state, bus, slave, &emul);
+       if (ret) {
+               printf("%s: busnum=%u, cs=%u: no emulation available (err=%d)\n",
+                      __func__, busnum, cs, ret);
+               return -ENOENT;
+       }
+       ret = device_probe(emul);
+       if (ret)
+               return ret;
 
        /* make sure rx/tx buffers are full so clients can assume */
        if (!tx) {
@@ -178,12 +107,8 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
                }
        }
 
-       debug("sandbox_spi: xfer: bytes = %u\n tx:", bytes);
-       for (i = 0; i < bytes; ++i)
-               debug(" %u:%02x", i, tx[i]);
-       debug("\n");
-
-       ret = sss->ops->xfer(sss->priv, tx, rx, bytes);
+       ops = spi_emul_get_ops(emul);
+       ret = ops->xfer(emul, bitlen, dout, din, flags);
 
        debug("sandbox_spi: xfer: got back %i (that's %s)\n rx:",
              ret, ret ? "bad" : "good");
@@ -196,22 +121,45 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
        if (rx != din)
                free(rx);
 
- done:
-       if (flags & SPI_XFER_END)
-               spi_cs_deactivate(slave);
-
        return ret;
 }
 
-/**
- * Set up a new SPI slave for an fdt node
- *
- * @param blob         Device tree blob
- * @param node         SPI peripheral node to use
- * @return 0 if ok, -1 on error
- */
-struct spi_slave *spi_setup_slave_fdt(const void *blob, int slave_node,
-                                     int spi_node)
+static int sandbox_spi_set_speed(struct udevice *bus, uint speed)
+{
+       return 0;
+}
+
+static int sandbox_spi_set_mode(struct udevice *bus, uint mode)
+{
+       return 0;
+}
+
+static int sandbox_cs_info(struct udevice *bus, uint cs,
+                          struct spi_cs_info *info)
 {
-       return NULL;
+       /* Always allow activity on CS 0 */
+       if (cs >= 1)
+               return -ENODEV;
+
+       return 0;
 }
+
+static const struct dm_spi_ops sandbox_spi_ops = {
+       .xfer           = sandbox_spi_xfer,
+       .set_speed      = sandbox_spi_set_speed,
+       .set_mode       = sandbox_spi_set_mode,
+       .cs_info        = sandbox_cs_info,
+};
+
+static const struct udevice_id sandbox_spi_ids[] = {
+       { .compatible = "sandbox,spi" },
+       { }
+};
+
+U_BOOT_DRIVER(spi_sandbox) = {
+       .name   = "spi_sandbox",
+       .id     = UCLASS_SPI,
+       .of_match = sandbox_spi_ids,
+       .per_child_auto_alloc_size      = sizeof(struct spi_slave),
+       .ops    = &sandbox_spi_ops,
+};
index c969be31eb31828066e2c044c825529d6412db69..558803618a272cc6e0e8b880ddd89cc8950e6e68 100644 (file)
@@ -1,4 +1,6 @@
 /*
+ * Copyright (c) 2014 Google, Inc
+ *
  * (C) Copyright 2002
  * Gerald Van Baren, Custom IDEAS, vanbaren@cideas.com.
  *
  */
 
 #include <common.h>
-#include <spi.h>
-
+#include <dm.h>
+#include <errno.h>
+#include <fdtdec.h>
 #include <malloc.h>
+#include <spi.h>
+#include <asm/gpio.h>
 
-/*-----------------------------------------------------------------------
- * Definitions
- */
+DECLARE_GLOBAL_DATA_PTR;
 
-#ifdef DEBUG_SPI
-#define PRINTD(fmt,args...)    printf (fmt ,##args)
-#else
-#define PRINTD(fmt,args...)
-#endif
+struct soft_spi_platdata {
+       struct fdt_gpio_state cs;
+       struct fdt_gpio_state sclk;
+       struct fdt_gpio_state mosi;
+       struct fdt_gpio_state miso;
+       int spi_delay_us;
+};
 
-struct soft_spi_slave {
-       struct spi_slave slave;
+struct soft_spi_priv {
        unsigned int mode;
 };
 
-static inline struct soft_spi_slave *to_soft_spi(struct spi_slave *slave)
+static int soft_spi_scl(struct udevice *dev, int bit)
 {
-       return container_of(slave, struct soft_spi_slave, slave);
-}
+       struct soft_spi_platdata *plat = dev->platdata;
+       struct soft_spi_priv *priv = dev_get_priv(dev);
 
-/*=====================================================================*/
-/*                         Public Functions                            */
-/*=====================================================================*/
+       gpio_set_value(plat->sclk.gpio, priv->mode & SPI_CPOL ? bit : !bit);
 
-/*-----------------------------------------------------------------------
- * Initialization
- */
-void spi_init (void)
-{
-#ifdef SPI_INIT
-       volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
-
-       SPI_INIT;
-#endif
+       return 0;
 }
 
-struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
-               unsigned int max_hz, unsigned int mode)
+static int soft_spi_sda(struct udevice *dev, int bit)
 {
-       struct soft_spi_slave *ss;
+       struct soft_spi_platdata *plat = dev->platdata;
 
-       if (!spi_cs_is_valid(bus, cs))
-               return NULL;
+       gpio_set_value(plat->mosi.gpio, bit);
 
-       ss = spi_alloc_slave(struct soft_spi_slave, bus, cs);
-       if (!ss)
-               return NULL;
+       return 0;
+}
 
-       ss->mode = mode;
+static int soft_spi_cs_activate(struct udevice *dev)
+{
+       struct soft_spi_platdata *plat = dev->platdata;
+       struct soft_spi_priv *priv = dev_get_priv(dev);
 
-       /* TODO: Use max_hz to limit the SCK rate */
+       gpio_set_value(plat->cs.gpio, !(priv->mode & SPI_CS_HIGH));
+       gpio_set_value(plat->sclk.gpio, priv->mode & SPI_CPOL);
+       gpio_set_value(plat->cs.gpio, priv->mode & SPI_CS_HIGH);
 
-       return &ss->slave;
+       return 0;
 }
 
-void spi_free_slave(struct spi_slave *slave)
+static int soft_spi_cs_deactivate(struct udevice *dev)
 {
-       struct soft_spi_slave *ss = to_soft_spi(slave);
+       struct soft_spi_platdata *plat = dev->platdata;
+       struct soft_spi_priv *priv = dev_get_priv(dev);
 
-       free(ss);
+       gpio_set_value(plat->cs.gpio, !(priv->mode & SPI_CS_HIGH));
+
+       return 0;
 }
 
-int spi_claim_bus(struct spi_slave *slave)
+static int soft_spi_claim_bus(struct udevice *dev)
 {
-#ifdef CONFIG_SYS_IMMR
-       volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
-#endif
-       struct soft_spi_slave *ss = to_soft_spi(slave);
-
        /*
         * Make sure the SPI clock is in idle state as defined for
         * this slave.
         */
-       if (ss->mode & SPI_CPOL)
-               SPI_SCL(1);
-       else
-               SPI_SCL(0);
-
-       return 0;
+       return soft_spi_scl(dev, 0);
 }
 
-void spi_release_bus(struct spi_slave *slave)
+static int soft_spi_release_bus(struct udevice *dev)
 {
        /* Nothing to do */
+       return 0;
 }
 
 /*-----------------------------------------------------------------------
@@ -111,28 +100,27 @@ void spi_release_bus(struct spi_slave *slave)
  * input data overwrites the output data (since both are buffered by
  * temporary variables, this is OK).
  */
-int  spi_xfer(struct spi_slave *slave, unsigned int bitlen,
-               const void *dout, void *din, unsigned long flags)
+static int soft_spi_xfer(struct udevice *dev, unsigned int bitlen,
+                        const void *dout, void *din, unsigned long flags)
 {
-#ifdef CONFIG_SYS_IMMR
-       volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
-#endif
-       struct soft_spi_slave *ss = to_soft_spi(slave);
+       struct soft_spi_priv *priv = dev_get_priv(dev);
+       struct soft_spi_platdata *plat = dev->platdata;
        uchar           tmpdin  = 0;
        uchar           tmpdout = 0;
        const u8        *txd = dout;
        u8              *rxd = din;
-       int             cpol = ss->mode & SPI_CPOL;
-       int             cpha = ss->mode & SPI_CPHA;
+       int             cpol = priv->mode & SPI_CPOL;
+       int             cpha = priv->mode & SPI_CPHA;
        unsigned int    j;
 
-       PRINTD("spi_xfer: slave %u:%u dout %08X din %08X bitlen %u\n",
-               slave->bus, slave->cs, *(uint *)txd, *(uint *)rxd, bitlen);
+       debug("spi_xfer: slave %s:%s dout %08X din %08X bitlen %u\n",
+             dev->parent->name, dev->name, *(uint *)txd, *(uint *)rxd,
+             bitlen);
 
        if (flags & SPI_XFER_BEGIN)
-               spi_cs_activate(slave);
+               soft_spi_cs_activate(dev);
 
-       for(j = 0; j < bitlen; j++) {
+       for (j = 0; j < bitlen; j++) {
                /*
                 * Check if it is time to work on a new byte.
                 */
@@ -141,7 +129,7 @@ int  spi_xfer(struct spi_slave *slave, unsigned int bitlen,
                                tmpdout = *txd++;
                        else
                                tmpdout = 0;
-                       if(j != 0) {
+                       if (j != 0) {
                                if (rxd)
                                        *rxd++ = tmpdin;
                        }
@@ -149,19 +137,19 @@ int  spi_xfer(struct spi_slave *slave, unsigned int bitlen,
                }
 
                if (!cpha)
-                       SPI_SCL(!cpol);
-               SPI_SDA(tmpdout & 0x80);
-               SPI_DELAY;
+                       soft_spi_scl(dev, !cpol);
+               soft_spi_sda(dev, tmpdout & 0x80);
+               udelay(plat->spi_delay_us);
                if (cpha)
-                       SPI_SCL(!cpol);
+                       soft_spi_scl(dev, !cpol);
                else
-                       SPI_SCL(cpol);
+                       soft_spi_scl(dev, cpol);
                tmpdin  <<= 1;
-               tmpdin  |= SPI_READ;
+               tmpdin  |= gpio_get_value(plat->miso.gpio);
                tmpdout <<= 1;
-               SPI_DELAY;
+               udelay(plat->spi_delay_us);
                if (cpha)
-                       SPI_SCL(cpol);
+                       soft_spi_scl(dev, cpol);
        }
        /*
         * If the number of bits isn't a multiple of 8, shift the last
@@ -175,7 +163,90 @@ int  spi_xfer(struct spi_slave *slave, unsigned int bitlen,
        }
 
        if (flags & SPI_XFER_END)
-               spi_cs_deactivate(slave);
+               soft_spi_cs_deactivate(dev);
 
-       return(0);
+       return 0;
 }
+
+static int soft_spi_set_speed(struct udevice *dev, unsigned int speed)
+{
+       /* Accept any speed */
+       return 0;
+}
+
+static int soft_spi_set_mode(struct udevice *dev, unsigned int mode)
+{
+       struct soft_spi_priv *priv = dev_get_priv(dev);
+
+       priv->mode = mode;
+
+       return 0;
+}
+
+static int soft_spi_child_pre_probe(struct udevice *dev)
+{
+       struct spi_slave *slave = dev_get_parentdata(dev);
+
+       slave->dev = dev;
+       return spi_ofdata_to_platdata(gd->fdt_blob, dev->of_offset, slave);
+}
+
+static const struct dm_spi_ops soft_spi_ops = {
+       .claim_bus      = soft_spi_claim_bus,
+       .release_bus    = soft_spi_release_bus,
+       .xfer           = soft_spi_xfer,
+       .set_speed      = soft_spi_set_speed,
+       .set_mode       = soft_spi_set_mode,
+};
+
+static int soft_spi_ofdata_to_platdata(struct udevice *dev)
+{
+       struct soft_spi_platdata *plat = dev->platdata;
+       const void *blob = gd->fdt_blob;
+       int node = dev->of_offset;
+
+       if (fdtdec_decode_gpio(blob, node, "cs-gpio", &plat->cs) ||
+           fdtdec_decode_gpio(blob, node, "sclk-gpio", &plat->sclk) ||
+           fdtdec_decode_gpio(blob, node, "mosi-gpio", &plat->mosi) ||
+           fdtdec_decode_gpio(blob, node, "miso-gpio", &plat->miso))
+               return -EINVAL;
+       plat->spi_delay_us = fdtdec_get_int(blob, node, "spi-delay-us", 0);
+
+       return 0;
+}
+
+static int soft_spi_probe(struct udevice *dev)
+{
+       struct spi_slave *slave = dev_get_parentdata(dev);
+       struct soft_spi_platdata *plat = dev->platdata;
+
+       gpio_request(plat->cs.gpio, "soft_spi_cs");
+       gpio_request(plat->sclk.gpio, "soft_spi_sclk");
+       gpio_request(plat->mosi.gpio, "soft_spi_mosi");
+       gpio_request(plat->miso.gpio, "soft_spi_miso");
+
+       gpio_direction_output(plat->sclk.gpio, slave->mode & SPI_CPOL);
+       gpio_direction_output(plat->mosi.gpio, 1);
+       gpio_direction_input(plat->miso.gpio);
+       gpio_direction_output(plat->cs.gpio, !(slave->mode & SPI_CS_HIGH));
+
+       return 0;
+}
+
+static const struct udevice_id soft_spi_ids[] = {
+       { .compatible = "u-boot,soft-spi" },
+       { }
+};
+
+U_BOOT_DRIVER(soft_spi) = {
+       .name   = "soft_spi",
+       .id     = UCLASS_SPI,
+       .of_match = soft_spi_ids,
+       .ops    = &soft_spi_ops,
+       .ofdata_to_platdata = soft_spi_ofdata_to_platdata,
+       .platdata_auto_alloc_size = sizeof(struct soft_spi_platdata),
+       .priv_auto_alloc_size = sizeof(struct soft_spi_priv),
+       .per_child_auto_alloc_size      = sizeof(struct spi_slave),
+       .probe  = soft_spi_probe,
+       .child_pre_probe        = soft_spi_child_pre_probe,
+};
diff --git a/drivers/spi/soft_spi_legacy.c b/drivers/spi/soft_spi_legacy.c
new file mode 100644 (file)
index 0000000..941daa7
--- /dev/null
@@ -0,0 +1,176 @@
+/*
+ * (C) Copyright 2002
+ * Gerald Van Baren, Custom IDEAS, vanbaren@cideas.com.
+ *
+ * Influenced by code from:
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <spi.h>
+
+#include <malloc.h>
+
+/*-----------------------------------------------------------------------
+ * Definitions
+ */
+
+#ifdef DEBUG_SPI
+#define PRINTD(fmt,args...)    printf (fmt ,##args)
+#else
+#define PRINTD(fmt,args...)
+#endif
+
+struct soft_spi_slave {
+       struct spi_slave slave;
+       unsigned int mode;
+};
+
+static inline struct soft_spi_slave *to_soft_spi(struct spi_slave *slave)
+{
+       return container_of(slave, struct soft_spi_slave, slave);
+}
+
+/*=====================================================================*/
+/*                         Public Functions                            */
+/*=====================================================================*/
+
+/*-----------------------------------------------------------------------
+ * Initialization
+ */
+void spi_init (void)
+{
+}
+
+struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
+               unsigned int max_hz, unsigned int mode)
+{
+       struct soft_spi_slave *ss;
+
+       if (!spi_cs_is_valid(bus, cs))
+               return NULL;
+
+       ss = spi_alloc_slave(struct soft_spi_slave, bus, cs);
+       if (!ss)
+               return NULL;
+
+       ss->mode = mode;
+
+       /* TODO: Use max_hz to limit the SCK rate */
+
+       return &ss->slave;
+}
+
+void spi_free_slave(struct spi_slave *slave)
+{
+       struct soft_spi_slave *ss = to_soft_spi(slave);
+
+       free(ss);
+}
+
+int spi_claim_bus(struct spi_slave *slave)
+{
+#ifdef CONFIG_SYS_IMMR
+       volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
+#endif
+       struct soft_spi_slave *ss = to_soft_spi(slave);
+
+       /*
+        * Make sure the SPI clock is in idle state as defined for
+        * this slave.
+        */
+       if (ss->mode & SPI_CPOL)
+               SPI_SCL(1);
+       else
+               SPI_SCL(0);
+
+       return 0;
+}
+
+void spi_release_bus(struct spi_slave *slave)
+{
+       /* Nothing to do */
+}
+
+/*-----------------------------------------------------------------------
+ * SPI transfer
+ *
+ * This writes "bitlen" bits out the SPI MOSI port and simultaneously clocks
+ * "bitlen" bits in the SPI MISO port.  That's just the way SPI works.
+ *
+ * The source of the outgoing bits is the "dout" parameter and the
+ * destination of the input bits is the "din" parameter.  Note that "dout"
+ * and "din" can point to the same memory location, in which case the
+ * input data overwrites the output data (since both are buffered by
+ * temporary variables, this is OK).
+ */
+int  spi_xfer(struct spi_slave *slave, unsigned int bitlen,
+               const void *dout, void *din, unsigned long flags)
+{
+#ifdef CONFIG_SYS_IMMR
+       volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
+#endif
+       struct soft_spi_slave *ss = to_soft_spi(slave);
+       uchar           tmpdin  = 0;
+       uchar           tmpdout = 0;
+       const u8        *txd = dout;
+       u8              *rxd = din;
+       int             cpol = ss->mode & SPI_CPOL;
+       int             cpha = ss->mode & SPI_CPHA;
+       unsigned int    j;
+
+       PRINTD("spi_xfer: slave %u:%u dout %08X din %08X bitlen %u\n",
+               slave->bus, slave->cs, *(uint *)txd, *(uint *)rxd, bitlen);
+
+       if (flags & SPI_XFER_BEGIN)
+               spi_cs_activate(slave);
+
+       for(j = 0; j < bitlen; j++) {
+               /*
+                * Check if it is time to work on a new byte.
+                */
+               if ((j % 8) == 0) {
+                       if (txd)
+                               tmpdout = *txd++;
+                       else
+                               tmpdout = 0;
+                       if(j != 0) {
+                               if (rxd)
+                                       *rxd++ = tmpdin;
+                       }
+                       tmpdin  = 0;
+               }
+
+               if (!cpha)
+                       SPI_SCL(!cpol);
+               SPI_SDA(tmpdout & 0x80);
+               SPI_DELAY;
+               if (cpha)
+                       SPI_SCL(!cpol);
+               else
+                       SPI_SCL(cpol);
+               tmpdin  <<= 1;
+               tmpdin  |= SPI_READ;
+               tmpdout <<= 1;
+               SPI_DELAY;
+               if (cpha)
+                       SPI_SCL(cpol);
+       }
+       /*
+        * If the number of bits isn't a multiple of 8, shift the last
+        * bits over to left-justify them.  Then store the last byte
+        * read in.
+        */
+       if (rxd) {
+               if ((bitlen % 8) != 0)
+                       tmpdin <<= 8 - (bitlen % 8);
+               *rxd++ = tmpdin;
+       }
+
+       if (flags & SPI_XFER_END)
+               spi_cs_deactivate(slave);
+
+       return(0);
+}
diff --git a/drivers/spi/spi-emul-uclass.c b/drivers/spi/spi-emul-uclass.c
new file mode 100644 (file)
index 0000000..b436a0e
--- /dev/null
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2014 Google, Inc
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <spi.h>
+#include <spi_flash.h>
+
+UCLASS_DRIVER(spi_emul) = {
+       .id             = UCLASS_SPI_EMUL,
+       .name           = "spi_emul",
+};
diff --git a/drivers/spi/spi-uclass.c b/drivers/spi/spi-uclass.c
new file mode 100644 (file)
index 0000000..13c6b77
--- /dev/null
@@ -0,0 +1,390 @@
+/*
+ * Copyright (c) 2014 Google, Inc
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <fdtdec.h>
+#include <malloc.h>
+#include <spi.h>
+#include <dm/device-internal.h>
+#include <dm/uclass-internal.h>
+#include <dm/root.h>
+#include <dm/lists.h>
+#include <dm/util.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static int spi_set_speed_mode(struct udevice *bus, int speed, int mode)
+{
+       struct dm_spi_ops *ops;
+       int ret;
+
+       ops = spi_get_ops(bus);
+       if (ops->set_speed)
+               ret = ops->set_speed(bus, speed);
+       else
+               ret = -EINVAL;
+       if (ret) {
+               printf("Cannot set speed (err=%d)\n", ret);
+               return ret;
+       }
+
+       if (ops->set_mode)
+               ret = ops->set_mode(bus, mode);
+       else
+               ret = -EINVAL;
+       if (ret) {
+               printf("Cannot set mode (err=%d)\n", ret);
+               return ret;
+       }
+
+       return 0;
+}
+
+int spi_claim_bus(struct spi_slave *slave)
+{
+       struct udevice *dev = slave->dev;
+       struct udevice *bus = dev->parent;
+       struct dm_spi_ops *ops = spi_get_ops(bus);
+       struct dm_spi_bus *spi = bus->uclass_priv;
+       int speed;
+       int ret;
+
+       speed = slave->max_hz;
+       if (spi->max_hz) {
+               if (speed)
+                       speed = min(speed, spi->max_hz);
+               else
+                       speed = spi->max_hz;
+       }
+       if (!speed)
+               speed = 100000;
+       ret = spi_set_speed_mode(bus, speed, slave->mode);
+       if (ret)
+               return ret;
+
+       return ops->claim_bus ? ops->claim_bus(bus) : 0;
+}
+
+void spi_release_bus(struct spi_slave *slave)
+{
+       struct udevice *dev = slave->dev;
+       struct udevice *bus = dev->parent;
+       struct dm_spi_ops *ops = spi_get_ops(bus);
+
+       if (ops->release_bus)
+               ops->release_bus(bus);
+}
+
+int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
+            const void *dout, void *din, unsigned long flags)
+{
+       struct udevice *dev = slave->dev;
+       struct udevice *bus = dev->parent;
+
+       if (bus->uclass->uc_drv->id != UCLASS_SPI)
+               return -EOPNOTSUPP;
+
+       return spi_get_ops(bus)->xfer(dev, bitlen, dout, din, flags);
+}
+
+int spi_post_bind(struct udevice *dev)
+{
+       /* Scan the bus for devices */
+       return dm_scan_fdt_node(dev, gd->fdt_blob, dev->of_offset, false);
+}
+
+int spi_post_probe(struct udevice *dev)
+{
+       struct dm_spi_bus *spi = dev->uclass_priv;
+
+       spi->max_hz = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
+                                    "spi-max-frequency", 0);
+
+       return 0;
+}
+
+int spi_chip_select(struct udevice *dev)
+{
+       struct spi_slave *slave = dev_get_parentdata(dev);
+
+       return slave ? slave->cs : -ENOENT;
+}
+
+/**
+ * spi_find_chip_select() - Find the slave attached to chip select
+ *
+ * @bus:       SPI bus to search
+ * @cs:                Chip select to look for
+ * @devp:      Returns the slave device if found
+ * @return 0 if found, -ENODEV on error
+ */
+static int spi_find_chip_select(struct udevice *bus, int cs,
+                               struct udevice **devp)
+{
+       struct udevice *dev;
+
+       for (device_find_first_child(bus, &dev); dev;
+            device_find_next_child(&dev)) {
+               struct spi_slave store;
+               struct spi_slave *slave = dev_get_parentdata(dev);
+
+               if (!slave)  {
+                       slave = &store;
+                       spi_ofdata_to_platdata(gd->fdt_blob, dev->of_offset,
+                                              slave);
+               }
+               debug("%s: slave=%p, cs=%d\n", __func__, slave,
+                     slave ? slave->cs : -1);
+               if (slave && slave->cs == cs) {
+                       *devp = dev;
+                       return 0;
+               }
+       }
+
+       return -ENODEV;
+}
+
+int spi_cs_is_valid(unsigned int busnum, unsigned int cs)
+{
+       struct spi_cs_info info;
+       struct udevice *bus;
+       int ret;
+
+       ret = uclass_find_device_by_seq(UCLASS_SPI, busnum, false, &bus);
+       if (ret) {
+               debug("%s: No bus %d\n", __func__, busnum);
+               return ret;
+       }
+
+       return spi_cs_info(bus, cs, &info);
+}
+
+int spi_cs_info(struct udevice *bus, uint cs, struct spi_cs_info *info)
+{
+       struct spi_cs_info local_info;
+       struct dm_spi_ops *ops;
+       int ret;
+
+       if (!info)
+               info = &local_info;
+
+       /* If there is a device attached, return it */
+       info->dev = NULL;
+       ret = spi_find_chip_select(bus, cs, &info->dev);
+       if (!ret)
+               return 0;
+
+       /*
+        * Otherwise ask the driver. For the moment we don't have CS info.
+        * When we do we could provide the driver with a helper function
+        * to figure out what chip selects are valid, or just handle the
+        * request.
+        */
+       ops = spi_get_ops(bus);
+       if (ops->cs_info)
+               return ops->cs_info(bus, cs, info);
+
+       /*
+        * We could assume there is at least one valid chip select, but best
+        * to be sure and return an error in this case. The driver didn't
+        * care enough to tell us.
+        */
+       return -ENODEV;
+}
+
+int spi_bind_device(struct udevice *bus, int cs, const char *drv_name,
+                   const char *dev_name, struct udevice **devp)
+{
+       struct driver *drv;
+       int ret;
+
+       drv = lists_driver_lookup_name(drv_name);
+       if (!drv) {
+               printf("Cannot find driver '%s'\n", drv_name);
+               return -ENOENT;
+       }
+       ret = device_bind(bus, drv, dev_name, NULL, -1, devp);
+       if (ret) {
+               printf("Cannot create device named '%s' (err=%d)\n",
+                      dev_name, ret);
+               return ret;
+       }
+
+       return 0;
+}
+
+int spi_find_bus_and_cs(int busnum, int cs, struct udevice **busp,
+                       struct udevice **devp)
+{
+       struct udevice *bus, *dev;
+       int ret;
+
+       ret = uclass_find_device_by_seq(UCLASS_SPI, busnum, false, &bus);
+       if (ret) {
+               debug("%s: No bus %d\n", __func__, busnum);
+               return ret;
+       }
+       ret = spi_find_chip_select(bus, cs, &dev);
+       if (ret) {
+               debug("%s: No cs %d\n", __func__, cs);
+               return ret;
+       }
+       *busp = bus;
+       *devp = dev;
+
+       return ret;
+}
+
+int spi_get_bus_and_cs(int busnum, int cs, int speed, int mode,
+                      const char *drv_name, const char *dev_name,
+                      struct udevice **busp, struct spi_slave **devp)
+{
+       struct udevice *bus, *dev;
+       struct spi_slave *slave;
+       bool created = false;
+       int ret;
+
+       ret = uclass_get_device_by_seq(UCLASS_SPI, busnum, &bus);
+       if (ret) {
+               printf("Invalid bus %d (err=%d)\n", busnum, ret);
+               return ret;
+       }
+       ret = spi_find_chip_select(bus, cs, &dev);
+
+       /*
+        * If there is no such device, create one automatically. This means
+        * that we don't need a device tree node or platform data for the
+        * SPI flash chip - we will bind to the correct driver.
+        */
+       if (ret == -ENODEV && drv_name) {
+               debug("%s: Binding new device '%s', busnum=%d, cs=%d, driver=%s\n",
+                     __func__, dev_name, busnum, cs, drv_name);
+               ret = spi_bind_device(bus, cs, drv_name, dev_name, &dev);
+               if (ret)
+                       return ret;
+               created = true;
+       } else if (ret) {
+               printf("Invalid chip select %d:%d (err=%d)\n", busnum, cs,
+                      ret);
+               return ret;
+       }
+
+       if (!device_active(dev)) {
+               slave = (struct spi_slave *)calloc(1,
+                                                  sizeof(struct spi_slave));
+               if (!slave) {
+                       ret = -ENOMEM;
+                       goto err;
+               }
+
+               ret = spi_ofdata_to_platdata(gd->fdt_blob, dev->of_offset,
+                                            slave);
+               if (ret)
+                       goto err;
+               slave->cs = cs;
+               slave->dev = dev;
+               ret = device_probe_child(dev, slave);
+               free(slave);
+               if (ret)
+                       goto err;
+       }
+
+       ret = spi_set_speed_mode(bus, speed, mode);
+       if (ret)
+               goto err;
+
+       *busp = bus;
+       *devp = dev_get_parentdata(dev);
+       debug("%s: bus=%p, slave=%p\n", __func__, bus, *devp);
+
+       return 0;
+
+err:
+       if (created) {
+               device_remove(dev);
+               device_unbind(dev);
+       }
+
+       return ret;
+}
+
+/* Compatibility function - to be removed */
+struct spi_slave *spi_setup_slave_fdt(const void *blob, int node,
+                                     int bus_node)
+{
+       struct udevice *bus, *dev;
+       int ret;
+
+       ret = uclass_get_device_by_of_offset(UCLASS_SPI, bus_node, &bus);
+       if (ret)
+               return NULL;
+       ret = device_get_child_by_of_offset(bus, node, &dev);
+       if (ret)
+               return NULL;
+       return dev_get_parentdata(dev);
+}
+
+/* Compatibility function - to be removed */
+struct spi_slave *spi_setup_slave(unsigned int busnum, unsigned int cs,
+                                 unsigned int speed, unsigned int mode)
+{
+       struct spi_slave *slave;
+       struct udevice *dev;
+       int ret;
+
+       ret = spi_get_bus_and_cs(busnum, cs, speed, mode, NULL, 0, &dev,
+                                 &slave);
+       if (ret)
+               return NULL;
+
+       return slave;
+}
+
+void spi_free_slave(struct spi_slave *slave)
+{
+       device_remove(slave->dev);
+       slave->dev = NULL;
+}
+
+int spi_ofdata_to_platdata(const void *blob, int node,
+                          struct spi_slave *spi)
+{
+       int mode = 0;
+
+       spi->cs = fdtdec_get_int(blob, node, "reg", -1);
+       spi->max_hz = fdtdec_get_int(blob, node, "spi-max-frequency", 0);
+       if (fdtdec_get_bool(blob, node, "spi-cpol"))
+               mode |= SPI_CPOL;
+       if (fdtdec_get_bool(blob, node, "spi-cpha"))
+               mode |= SPI_CPHA;
+       if (fdtdec_get_bool(blob, node, "spi-cs-high"))
+               mode |= SPI_CS_HIGH;
+       if (fdtdec_get_bool(blob, node, "spi-half-duplex"))
+               mode |= SPI_PREAMBLE;
+       spi->mode = mode;
+
+       return 0;
+}
+
+UCLASS_DRIVER(spi) = {
+       .id             = UCLASS_SPI,
+       .name           = "spi",
+       .post_bind      = spi_post_bind,
+       .post_probe     = spi_post_probe,
+       .per_device_auto_alloc_size = sizeof(struct dm_spi_bus),
+};
+
+UCLASS_DRIVER(spi_generic) = {
+       .id             = UCLASS_SPI_GENERIC,
+       .name           = "spi_generic",
+};
+
+U_BOOT_DRIVER(spi_generic_drv) = {
+       .name           = "spi_generic_drv",
+       .id             = UCLASS_SPI_GENERIC,
+};
index 810fa4718ce17b87c389a522c6cea788c9df3867..2d97625fba73b81dcb8a2ba2d55d5e1d5eef0bcb 100644 (file)
  */
 
 #include <common.h>
-#include <malloc.h>
+#include <dm.h>
 #include <asm/io.h>
-#include <asm/gpio.h>
 #include <asm/arch/clock.h>
 #include <asm/arch-tegra/clk_rst.h>
-#include <asm/arch-tegra114/tegra114_spi.h>
 #include <spi.h>
 #include <fdtdec.h>
+#include "tegra_spi.h"
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -104,130 +103,63 @@ struct spi_regs {
        u32 spare_ctl;  /* 18c:SPI_SPARE_CTRL register */
 };
 
-struct tegra_spi_ctrl {
+struct tegra114_spi_priv {
        struct spi_regs *regs;
        unsigned int freq;
        unsigned int mode;
        int periph_id;
        int valid;
+       int last_transaction_us;
 };
 
-struct tegra_spi_slave {
-       struct spi_slave slave;
-       struct tegra_spi_ctrl *ctrl;
-};
-
-static struct tegra_spi_ctrl spi_ctrls[CONFIG_TEGRA114_SPI_CTRLS];
-
-static inline struct tegra_spi_slave *to_tegra_spi(struct spi_slave *slave)
+static int tegra114_spi_ofdata_to_platdata(struct udevice *bus)
 {
-       return container_of(slave, struct tegra_spi_slave, slave);
-}
+       struct tegra_spi_platdata *plat = bus->platdata;
+       const void *blob = gd->fdt_blob;
+       int node = bus->of_offset;
 
-int tegra114_spi_cs_is_valid(unsigned int bus, unsigned int cs)
-{
-       if (bus >= CONFIG_TEGRA114_SPI_CTRLS || cs > 3 || !spi_ctrls[bus].valid)
-               return 0;
-       else
-               return 1;
-}
+       plat->base = fdtdec_get_addr(blob, node, "reg");
+       plat->periph_id = clock_decode_periph_id(blob, node);
 
-struct spi_slave *tegra114_spi_setup_slave(unsigned int bus, unsigned int cs,
-               unsigned int max_hz, unsigned int mode)
-{
-       struct tegra_spi_slave *spi;
-
-       debug("%s: bus: %u, cs: %u, max_hz: %u, mode: %u\n", __func__,
-               bus, cs, max_hz, mode);
-
-       if (!spi_cs_is_valid(bus, cs)) {
-               printf("SPI error: unsupported bus %d / chip select %d\n",
-                      bus, cs);
-               return NULL;
-       }
-
-       if (max_hz > TEGRA_SPI_MAX_FREQ) {
-               printf("SPI error: unsupported frequency %d Hz. Max frequency"
-                       " is %d Hz\n", max_hz, TEGRA_SPI_MAX_FREQ);
-               return NULL;
+       if (plat->periph_id == PERIPH_ID_NONE) {
+               debug("%s: could not decode periph id %d\n", __func__,
+                     plat->periph_id);
+               return -FDT_ERR_NOTFOUND;
        }
 
-       spi = spi_alloc_slave(struct tegra_spi_slave, bus, cs);
-       if (!spi) {
-               printf("SPI error: malloc of SPI structure failed\n");
-               return NULL;
-       }
-       spi->ctrl = &spi_ctrls[bus];
-       if (!spi->ctrl) {
-               printf("SPI error: could not find controller for bus %d\n",
-                      bus);
-               return NULL;
-       }
+       /* Use 500KHz as a suitable default */
+       plat->frequency = fdtdec_get_int(blob, node, "spi-max-frequency",
+                                       500000);
+       plat->deactivate_delay_us = fdtdec_get_int(blob, node,
+                                       "spi-deactivate-delay", 0);
+       debug("%s: base=%#08lx, periph_id=%d, max-frequency=%d, deactivate_delay=%d\n",
+             __func__, plat->base, plat->periph_id, plat->frequency,
+             plat->deactivate_delay_us);
 
-       if (max_hz < spi->ctrl->freq) {
-               debug("%s: limiting frequency from %u to %u\n", __func__,
-                     spi->ctrl->freq, max_hz);
-               spi->ctrl->freq = max_hz;
-       }
-       spi->ctrl->mode = mode;
-
-       return &spi->slave;
-}
-
-void tegra114_spi_free_slave(struct spi_slave *slave)
-{
-       struct tegra_spi_slave *spi = to_tegra_spi(slave);
-
-       free(spi);
+       return 0;
 }
 
-int tegra114_spi_init(int *node_list, int count)
+static int tegra114_spi_probe(struct udevice *bus)
 {
-       struct tegra_spi_ctrl *ctrl;
-       int i;
-       int node = 0;
-       int found = 0;
-
-       for (i = 0; i < count; i++) {
-               ctrl = &spi_ctrls[i];
-               node = node_list[i];
-
-               ctrl->regs = (struct spi_regs *)fdtdec_get_addr(gd->fdt_blob,
-                                                                node, "reg");
-               if ((fdt_addr_t)ctrl->regs == FDT_ADDR_T_NONE) {
-                       debug("%s: no spi register found\n", __func__);
-                       continue;
-               }
-               ctrl->freq = fdtdec_get_int(gd->fdt_blob, node,
-                                           "spi-max-frequency", 0);
-               if (!ctrl->freq) {
-                       debug("%s: no spi max frequency found\n", __func__);
-                       continue;
-               }
+       struct tegra_spi_platdata *plat = dev_get_platdata(bus);
+       struct tegra114_spi_priv *priv = dev_get_priv(bus);
 
-               ctrl->periph_id = clock_decode_periph_id(gd->fdt_blob, node);
-               if (ctrl->periph_id == PERIPH_ID_NONE) {
-                       debug("%s: could not decode periph id\n", __func__);
-                       continue;
-               }
-               ctrl->valid = 1;
-               found = 1;
+       priv->regs = (struct spi_regs *)plat->base;
 
-               debug("%s: found controller at %p, freq = %u, periph_id = %d\n",
-                     __func__, ctrl->regs, ctrl->freq, ctrl->periph_id);
-       }
+       priv->last_transaction_us = timer_get_us();
+       priv->freq = plat->frequency;
+       priv->periph_id = plat->periph_id;
 
-       return !found;
+       return 0;
 }
 
-int tegra114_spi_claim_bus(struct spi_slave *slave)
+static int tegra114_spi_claim_bus(struct udevice *bus)
 {
-       struct tegra_spi_slave *spi = to_tegra_spi(slave);
-       struct spi_regs *regs = spi->ctrl->regs;
+       struct tegra114_spi_priv *priv = dev_get_priv(bus);
+       struct spi_regs *regs = priv->regs;
 
        /* Change SPI clock to correct frequency, PLLP_OUT0 source */
-       clock_start_periph_pll(spi->ctrl->periph_id, CLOCK_ID_PERIPH,
-                              spi->ctrl->freq);
+       clock_start_periph_pll(priv->periph_id, CLOCK_ID_PERIPH, priv->freq);
 
        /* Clear stale status here */
        setbits_le32(&regs->fifo_status,
@@ -244,33 +176,64 @@ int tegra114_spi_claim_bus(struct spi_slave *slave)
 
        /* Set master mode and sw controlled CS */
        setbits_le32(&regs->command1, SPI_CMD1_M_S | SPI_CMD1_CS_SW_HW |
-                    (spi->ctrl->mode << SPI_CMD1_MODE_SHIFT));
+                    (priv->mode << SPI_CMD1_MODE_SHIFT));
        debug("%s: COMMAND1 = %08x\n", __func__, readl(&regs->command1));
 
        return 0;
 }
 
-void tegra114_spi_cs_activate(struct spi_slave *slave)
+/**
+ * Activate the CS by driving it LOW
+ *
+ * @param slave        Pointer to spi_slave to which controller has to
+ *             communicate with
+ */
+static void spi_cs_activate(struct udevice *dev)
 {
-       struct tegra_spi_slave *spi = to_tegra_spi(slave);
-       struct spi_regs *regs = spi->ctrl->regs;
+       struct udevice *bus = dev->parent;
+       struct tegra_spi_platdata *pdata = dev_get_platdata(bus);
+       struct tegra114_spi_priv *priv = dev_get_priv(bus);
+
+       /* If it's too soon to do another transaction, wait */
+       if (pdata->deactivate_delay_us &&
+           priv->last_transaction_us) {
+               ulong delay_us;         /* The delay completed so far */
+               delay_us = timer_get_us() - priv->last_transaction_us;
+               if (delay_us < pdata->deactivate_delay_us)
+                       udelay(pdata->deactivate_delay_us - delay_us);
+       }
 
-       clrbits_le32(&regs->command1, SPI_CMD1_CS_SW_VAL);
+       clrbits_le32(&priv->regs->command1, SPI_CMD1_CS_SW_VAL);
 }
 
-void tegra114_spi_cs_deactivate(struct spi_slave *slave)
+/**
+ * Deactivate the CS by driving it HIGH
+ *
+ * @param slave        Pointer to spi_slave to which controller has to
+ *             communicate with
+ */
+static void spi_cs_deactivate(struct udevice *dev)
 {
-       struct tegra_spi_slave *spi = to_tegra_spi(slave);
-       struct spi_regs *regs = spi->ctrl->regs;
+       struct udevice *bus = dev->parent;
+       struct tegra_spi_platdata *pdata = dev_get_platdata(bus);
+       struct tegra114_spi_priv *priv = dev_get_priv(bus);
+
+       setbits_le32(&priv->regs->command1, SPI_CMD1_CS_SW_VAL);
 
-       setbits_le32(&regs->command1, SPI_CMD1_CS_SW_VAL);
+       /* Remember time of this transaction so we can honour the bus delay */
+       if (pdata->deactivate_delay_us)
+               priv->last_transaction_us = timer_get_us();
+
+       debug("Deactivate CS, bus '%s'\n", bus->name);
 }
 
-int tegra114_spi_xfer(struct spi_slave *slave, unsigned int bitlen,
-               const void *data_out, void *data_in, unsigned long flags)
+static int tegra114_spi_xfer(struct udevice *dev, unsigned int bitlen,
+                            const void *data_out, void *data_in,
+                            unsigned long flags)
 {
-       struct tegra_spi_slave *spi = to_tegra_spi(slave);
-       struct spi_regs *regs = spi->ctrl->regs;
+       struct udevice *bus = dev->parent;
+       struct tegra114_spi_priv *priv = dev_get_priv(bus);
+       struct spi_regs *regs = priv->regs;
        u32 reg, tmpdout, tmpdin = 0;
        const u8 *dout = data_out;
        u8 *din = data_in;
@@ -278,7 +241,7 @@ int tegra114_spi_xfer(struct spi_slave *slave, unsigned int bitlen,
        int ret;
 
        debug("%s: slave %u:%u dout %p din %p bitlen %u\n",
-             __func__, slave->bus, slave->cs, dout, din, bitlen);
+             __func__, bus->seq, spi_chip_select(dev), dout, din, bitlen);
        if (bitlen % 8)
                return -1;
        num_bytes = bitlen / 8;
@@ -291,13 +254,13 @@ int tegra114_spi_xfer(struct spi_slave *slave, unsigned int bitlen,
 
        clrsetbits_le32(&regs->command1, SPI_CMD1_CS_SW_VAL,
                        SPI_CMD1_RX_EN | SPI_CMD1_TX_EN | SPI_CMD1_LSBY_FE |
-                       (slave->cs << SPI_CMD1_CS_SEL_SHIFT));
+                       (spi_chip_select(dev) << SPI_CMD1_CS_SEL_SHIFT));
 
        /* set xfer size to 1 block (32 bits) */
        writel(0, &regs->dma_blk);
 
        if (flags & SPI_XFER_BEGIN)
-               spi_cs_activate(slave);
+               spi_cs_activate(dev);
 
        /* handle data in 32-bit chunks */
        while (num_bytes > 0) {
@@ -383,7 +346,7 @@ int tegra114_spi_xfer(struct spi_slave *slave, unsigned int bitlen,
        }
 
        if (flags & SPI_XFER_END)
-               spi_cs_deactivate(slave);
+               spi_cs_deactivate(dev);
 
        debug("%s: transfer ended. Value=%08x, fifo_status = %08x\n",
              __func__, tmpdin, readl(&regs->fifo_status));
@@ -394,5 +357,56 @@ int tegra114_spi_xfer(struct spi_slave *slave, unsigned int bitlen,
                return -1;
        }
 
+       return ret;
+}
+
+static int tegra114_spi_set_speed(struct udevice *bus, uint speed)
+{
+       struct tegra_spi_platdata *plat = bus->platdata;
+       struct tegra114_spi_priv *priv = dev_get_priv(bus);
+
+       if (speed > plat->frequency)
+               speed = plat->frequency;
+       priv->freq = speed;
+       debug("%s: regs=%p, speed=%d\n", __func__, priv->regs, priv->freq);
+
        return 0;
 }
+
+static int tegra114_spi_set_mode(struct udevice *bus, uint mode)
+{
+       struct tegra114_spi_priv *priv = dev_get_priv(bus);
+
+       priv->mode = mode;
+       debug("%s: regs=%p, mode=%d\n", __func__, priv->regs, priv->mode);
+
+       return 0;
+}
+
+static const struct dm_spi_ops tegra114_spi_ops = {
+       .claim_bus      = tegra114_spi_claim_bus,
+       .xfer           = tegra114_spi_xfer,
+       .set_speed      = tegra114_spi_set_speed,
+       .set_mode       = tegra114_spi_set_mode,
+       /*
+        * cs_info is not needed, since we require all chip selects to be
+        * in the device tree explicitly
+        */
+};
+
+static const struct udevice_id tegra114_spi_ids[] = {
+       { .compatible = "nvidia,tegra114-spi" },
+       { }
+};
+
+U_BOOT_DRIVER(tegra114_spi) = {
+       .name   = "tegra114_spi",
+       .id     = UCLASS_SPI,
+       .of_match = tegra114_spi_ids,
+       .ops    = &tegra114_spi_ops,
+       .ofdata_to_platdata = tegra114_spi_ofdata_to_platdata,
+       .platdata_auto_alloc_size = sizeof(struct tegra_spi_platdata),
+       .priv_auto_alloc_size = sizeof(struct tegra114_spi_priv),
+       .per_child_auto_alloc_size      = sizeof(struct spi_slave),
+       .probe  = tegra114_spi_probe,
+};
index b5d561be34108dade5a7450391ff9824461d03c9..7d0d0f37fc70a7f5f5da821b2af8589bf59ac7a1 100644 (file)
@@ -7,15 +7,16 @@
  */
 
 #include <common.h>
-#include <malloc.h>
+#include <dm.h>
+#include <errno.h>
 #include <asm/io.h>
 #include <asm/gpio.h>
 #include <asm/arch/clock.h>
 #include <asm/arch/pinmux.h>
 #include <asm/arch-tegra/clk_rst.h>
-#include <asm/arch-tegra20/tegra20_sflash.h>
 #include <spi.h>
 #include <fdtdec.h>
+#include "tegra_spi.h"
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -64,129 +65,75 @@ struct spi_regs {
        u32 rx_fifo;    /* SPI_RX_FIFO_0 register */
 };
 
-struct tegra_spi_ctrl {
+struct tegra20_sflash_priv {
        struct spi_regs *regs;
        unsigned int freq;
        unsigned int mode;
        int periph_id;
        int valid;
+       int last_transaction_us;
 };
 
-struct tegra_spi_slave {
-       struct spi_slave slave;
-       struct tegra_spi_ctrl *ctrl;
-};
-
-/* tegra20 only supports one SFLASH controller */
-static struct tegra_spi_ctrl spi_ctrls[1];
-
-static inline struct tegra_spi_slave *to_tegra_spi(struct spi_slave *slave)
-{
-       return container_of(slave, struct tegra_spi_slave, slave);
-}
-
-int tegra20_spi_cs_is_valid(unsigned int bus, unsigned int cs)
+int tegra20_sflash_cs_info(struct udevice *bus, unsigned int cs,
+                          struct spi_cs_info *info)
 {
        /* Tegra20 SPI-Flash - only 1 device ('bus/cs') */
-       if (bus != 0 || cs != 0)
-               return 0;
+       if (cs != 0)
+               return -ENODEV;
        else
-               return 1;
+               return 0;
 }
 
-struct spi_slave *tegra20_spi_setup_slave(unsigned int bus, unsigned int cs,
-                                 unsigned int max_hz, unsigned int mode)
+static int tegra20_sflash_ofdata_to_platdata(struct udevice *bus)
 {
-       struct tegra_spi_slave *spi;
+       struct tegra_spi_platdata *plat = bus->platdata;
+       const void *blob = gd->fdt_blob;
+       int node = bus->of_offset;
 
-       if (!spi_cs_is_valid(bus, cs)) {
-               printf("SPI error: unsupported bus %d / chip select %d\n",
-                      bus, cs);
-               return NULL;
-       }
+       plat->base = fdtdec_get_addr(blob, node, "reg");
+       plat->periph_id = clock_decode_periph_id(blob, node);
 
-       if (max_hz > TEGRA_SPI_MAX_FREQ) {
-               printf("SPI error: unsupported frequency %d Hz. Max frequency"
-                       " is %d Hz\n", max_hz, TEGRA_SPI_MAX_FREQ);
-               return NULL;
+       if (plat->periph_id == PERIPH_ID_NONE) {
+               debug("%s: could not decode periph id %d\n", __func__,
+                     plat->periph_id);
+               return -FDT_ERR_NOTFOUND;
        }
 
-       spi = spi_alloc_slave(struct tegra_spi_slave, bus, cs);
-       if (!spi) {
-               printf("SPI error: malloc of SPI structure failed\n");
-               return NULL;
-       }
-       spi->ctrl = &spi_ctrls[bus];
-       if (!spi->ctrl) {
-               printf("SPI error: could not find controller for bus %d\n",
-                      bus);
-               return NULL;
-       }
+       /* Use 500KHz as a suitable default */
+       plat->frequency = fdtdec_get_int(blob, node, "spi-max-frequency",
+                                       500000);
+       plat->deactivate_delay_us = fdtdec_get_int(blob, node,
+                                       "spi-deactivate-delay", 0);
+       debug("%s: base=%#08lx, periph_id=%d, max-frequency=%d, deactivate_delay=%d\n",
+             __func__, plat->base, plat->periph_id, plat->frequency,
+             plat->deactivate_delay_us);
 
-       if (max_hz < spi->ctrl->freq) {
-               debug("%s: limiting frequency from %u to %u\n", __func__,
-                     spi->ctrl->freq, max_hz);
-               spi->ctrl->freq = max_hz;
-       }
-       spi->ctrl->mode = mode;
-
-       return &spi->slave;
+       return 0;
 }
 
-void tegra20_spi_free_slave(struct spi_slave *slave)
+static int tegra20_sflash_probe(struct udevice *bus)
 {
-       struct tegra_spi_slave *spi = to_tegra_spi(slave);
-
-       free(spi);
-}
+       struct tegra_spi_platdata *plat = dev_get_platdata(bus);
+       struct tegra20_sflash_priv *priv = dev_get_priv(bus);
 
-int tegra20_spi_init(int *node_list, int count)
-{
-       struct tegra_spi_ctrl *ctrl;
-       int i;
-       int node = 0;
-       int found = 0;
-
-       for (i = 0; i < count; i++) {
-               ctrl = &spi_ctrls[i];
-               node = node_list[i];
-
-               ctrl->regs = (struct spi_regs *)fdtdec_get_addr(gd->fdt_blob,
-                                                               node, "reg");
-               if ((fdt_addr_t)ctrl->regs == FDT_ADDR_T_NONE) {
-                       debug("%s: no slink register found\n", __func__);
-                       continue;
-               }
-               ctrl->freq = fdtdec_get_int(gd->fdt_blob, node,
-                                           "spi-max-frequency", 0);
-               if (!ctrl->freq) {
-                       debug("%s: no slink max frequency found\n", __func__);
-                       continue;
-               }
+       priv->regs = (struct spi_regs *)plat->base;
 
-               ctrl->periph_id = clock_decode_periph_id(gd->fdt_blob, node);
-               if (ctrl->periph_id == PERIPH_ID_NONE) {
-                       debug("%s: could not decode periph id\n", __func__);
-                       continue;
-               }
-               ctrl->valid = 1;
-               found = 1;
+       priv->last_transaction_us = timer_get_us();
+       priv->freq = plat->frequency;
+       priv->periph_id = plat->periph_id;
 
-               debug("%s: found controller at %p, freq = %u, periph_id = %d\n",
-                     __func__, ctrl->regs, ctrl->freq, ctrl->periph_id);
-       }
-       return !found;
+       return 0;
 }
 
-int tegra20_spi_claim_bus(struct spi_slave *slave)
+static int tegra20_sflash_claim_bus(struct udevice *bus)
 {
-       struct tegra_spi_slave *spi = to_tegra_spi(slave);
-       struct spi_regs *regs = spi->ctrl->regs;
+       struct tegra20_sflash_priv *priv = dev_get_priv(bus);
+       struct spi_regs *regs = priv->regs;
        u32 reg;
 
        /* Change SPI clock to correct frequency, PLLP_OUT0 source */
-       clock_start_periph_pll(spi->ctrl->periph_id, CLOCK_ID_PERIPH,
-                              spi->ctrl->freq);
+       clock_start_periph_pll(priv->periph_id, CLOCK_ID_PERIPH,
+                              priv->freq);
 
        /* Clear stale status here */
        reg = SPI_STAT_RDY | SPI_STAT_RXF_FLUSH | SPI_STAT_TXF_FLUSH | \
@@ -197,8 +144,8 @@ int tegra20_spi_claim_bus(struct spi_slave *slave)
        /*
         * Use sw-controlled CS, so we can clock in data after ReadID, etc.
         */
-       reg = (spi->ctrl->mode & 1) << SPI_CMD_ACTIVE_SDA_SHIFT;
-       if (spi->ctrl->mode & 2)
+       reg = (priv->mode & 1) << SPI_CMD_ACTIVE_SDA_SHIFT;
+       if (priv->mode & 2)
                reg |= 1 << SPI_CMD_ACTIVE_SCLK_SHIFT;
        clrsetbits_le32(&regs->command, SPI_CMD_ACTIVE_SCLK_MASK |
                SPI_CMD_ACTIVE_SDA_MASK, SPI_CMD_CS_SOFT | reg);
@@ -215,37 +162,54 @@ int tegra20_spi_claim_bus(struct spi_slave *slave)
        return 0;
 }
 
-void tegra20_spi_cs_activate(struct spi_slave *slave)
+static void spi_cs_activate(struct udevice *dev)
 {
-       struct tegra_spi_slave *spi = to_tegra_spi(slave);
-       struct spi_regs *regs = spi->ctrl->regs;
+       struct udevice *bus = dev->parent;
+       struct tegra_spi_platdata *pdata = dev_get_platdata(bus);
+       struct tegra20_sflash_priv *priv = dev_get_priv(bus);
+
+       /* If it's too soon to do another transaction, wait */
+       if (pdata->deactivate_delay_us &&
+           priv->last_transaction_us) {
+               ulong delay_us;         /* The delay completed so far */
+               delay_us = timer_get_us() - priv->last_transaction_us;
+               if (delay_us < pdata->deactivate_delay_us)
+                       udelay(pdata->deactivate_delay_us - delay_us);
+       }
 
        /* CS is negated on Tegra, so drive a 1 to get a 0 */
-       setbits_le32(&regs->command, SPI_CMD_CS_VAL);
+       setbits_le32(&priv->regs->command, SPI_CMD_CS_VAL);
 }
 
-void tegra20_spi_cs_deactivate(struct spi_slave *slave)
+static void spi_cs_deactivate(struct udevice *dev)
 {
-       struct tegra_spi_slave *spi = to_tegra_spi(slave);
-       struct spi_regs *regs = spi->ctrl->regs;
+       struct udevice *bus = dev->parent;
+       struct tegra_spi_platdata *pdata = dev_get_platdata(bus);
+       struct tegra20_sflash_priv *priv = dev_get_priv(bus);
 
        /* CS is negated on Tegra, so drive a 0 to get a 1 */
-       clrbits_le32(&regs->command, SPI_CMD_CS_VAL);
+       clrbits_le32(&priv->regs->command, SPI_CMD_CS_VAL);
+
+       /* Remember time of this transaction so we can honour the bus delay */
+       if (pdata->deactivate_delay_us)
+               priv->last_transaction_us = timer_get_us();
 }
 
-int tegra20_spi_xfer(struct spi_slave *slave, unsigned int bitlen,
-               const void *data_out, void *data_in, unsigned long flags)
+static int tegra20_sflash_xfer(struct udevice *dev, unsigned int bitlen,
+                            const void *data_out, void *data_in,
+                            unsigned long flags)
 {
-       struct tegra_spi_slave *spi = to_tegra_spi(slave);
-       struct spi_regs *regs = spi->ctrl->regs;
+       struct udevice *bus = dev->parent;
+       struct tegra20_sflash_priv *priv = dev_get_priv(bus);
+       struct spi_regs *regs = priv->regs;
        u32 reg, tmpdout, tmpdin = 0;
        const u8 *dout = data_out;
        u8 *din = data_in;
        int num_bytes;
        int ret;
 
-       debug("spi_xfer: slave %u:%u dout %08X din %08X bitlen %u\n",
-             slave->bus, slave->cs, *(u8 *)dout, *(u8 *)din, bitlen);
+       debug("%s: slave %u:%u dout %p din %p bitlen %u\n",
+             __func__, bus->seq, spi_chip_select(dev), dout, din, bitlen);
        if (bitlen % 8)
                return -1;
        num_bytes = bitlen / 8;
@@ -262,7 +226,7 @@ int tegra20_spi_xfer(struct spi_slave *slave, unsigned int bitlen,
        debug("spi_xfer: COMMAND = %08x\n", readl(&regs->command));
 
        if (flags & SPI_XFER_BEGIN)
-               spi_cs_activate(slave);
+               spi_cs_activate(dev);
 
        /* handle data in 32-bit chunks */
        while (num_bytes > 0) {
@@ -327,7 +291,7 @@ int tegra20_spi_xfer(struct spi_slave *slave, unsigned int bitlen,
        }
 
        if (flags & SPI_XFER_END)
-               spi_cs_deactivate(slave);
+               spi_cs_deactivate(dev);
 
        debug("spi_xfer: transfer ended. Value=%08x, status = %08x\n",
                tmpdin, readl(&regs->status));
@@ -339,3 +303,51 @@ int tegra20_spi_xfer(struct spi_slave *slave, unsigned int bitlen,
 
        return 0;
 }
+
+static int tegra20_sflash_set_speed(struct udevice *bus, uint speed)
+{
+       struct tegra_spi_platdata *plat = bus->platdata;
+       struct tegra20_sflash_priv *priv = dev_get_priv(bus);
+
+       if (speed > plat->frequency)
+               speed = plat->frequency;
+       priv->freq = speed;
+       debug("%s: regs=%p, speed=%d\n", __func__, priv->regs, priv->freq);
+
+       return 0;
+}
+
+static int tegra20_sflash_set_mode(struct udevice *bus, uint mode)
+{
+       struct tegra20_sflash_priv *priv = dev_get_priv(bus);
+
+       priv->mode = mode;
+       debug("%s: regs=%p, mode=%d\n", __func__, priv->regs, priv->mode);
+
+       return 0;
+}
+
+static const struct dm_spi_ops tegra20_sflash_ops = {
+       .claim_bus      = tegra20_sflash_claim_bus,
+       .xfer           = tegra20_sflash_xfer,
+       .set_speed      = tegra20_sflash_set_speed,
+       .set_mode       = tegra20_sflash_set_mode,
+       .cs_info        = tegra20_sflash_cs_info,
+};
+
+static const struct udevice_id tegra20_sflash_ids[] = {
+       { .compatible = "nvidia,tegra20-sflash" },
+       { }
+};
+
+U_BOOT_DRIVER(tegra20_sflash) = {
+       .name   = "tegra20_sflash",
+       .id     = UCLASS_SPI,
+       .of_match = tegra20_sflash_ids,
+       .ops    = &tegra20_sflash_ops,
+       .ofdata_to_platdata = tegra20_sflash_ofdata_to_platdata,
+       .platdata_auto_alloc_size = sizeof(struct tegra_spi_platdata),
+       .priv_auto_alloc_size = sizeof(struct tegra20_sflash_priv),
+       .per_child_auto_alloc_size      = sizeof(struct spi_slave),
+       .probe  = tegra20_sflash_probe,
+};
index 664de6e916613f4571fadb9fbd46497a32131fce..213fa5f7939a848889e0168d1991040dd9830a61 100644 (file)
  */
 
 #include <common.h>
-#include <malloc.h>
+#include <dm.h>
 #include <asm/io.h>
-#include <asm/gpio.h>
 #include <asm/arch/clock.h>
 #include <asm/arch-tegra/clk_rst.h>
-#include <asm/arch-tegra20/tegra20_slink.h>
 #include <spi.h>
 #include <fdtdec.h>
+#include "tegra_spi.h"
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -87,130 +86,70 @@ struct spi_regs {
        u32 rx_fifo;    /* SLINK_RX_FIFO_0 reg off 180h */
 };
 
-struct tegra_spi_ctrl {
+struct tegra30_spi_priv {
        struct spi_regs *regs;
        unsigned int freq;
        unsigned int mode;
        int periph_id;
        int valid;
+       int last_transaction_us;
 };
 
 struct tegra_spi_slave {
        struct spi_slave slave;
-       struct tegra_spi_ctrl *ctrl;
+       struct tegra30_spi_priv *ctrl;
 };
 
-static struct tegra_spi_ctrl spi_ctrls[CONFIG_TEGRA_SLINK_CTRLS];
-
-static inline struct tegra_spi_slave *to_tegra_spi(struct spi_slave *slave)
-{
-       return container_of(slave, struct tegra_spi_slave, slave);
-}
-
-int tegra30_spi_cs_is_valid(unsigned int bus, unsigned int cs)
+static int tegra30_spi_ofdata_to_platdata(struct udevice *bus)
 {
-       if (bus >= CONFIG_TEGRA_SLINK_CTRLS || cs > 3 || !spi_ctrls[bus].valid)
-               return 0;
-       else
-               return 1;
-}
+       struct tegra_spi_platdata *plat = bus->platdata;
+       const void *blob = gd->fdt_blob;
+       int node = bus->of_offset;
 
-struct spi_slave *tegra30_spi_setup_slave(unsigned int bus, unsigned int cs,
-               unsigned int max_hz, unsigned int mode)
-{
-       struct tegra_spi_slave *spi;
+       plat->base = fdtdec_get_addr(blob, node, "reg");
+       plat->periph_id = clock_decode_periph_id(blob, node);
 
-       debug("%s: bus: %u, cs: %u, max_hz: %u, mode: %u\n", __func__,
-               bus, cs, max_hz, mode);
-
-       if (!spi_cs_is_valid(bus, cs)) {
-               printf("SPI error: unsupported bus %d / chip select %d\n",
-                      bus, cs);
-               return NULL;
-       }
-
-       if (max_hz > TEGRA_SPI_MAX_FREQ) {
-               printf("SPI error: unsupported frequency %d Hz. Max frequency"
-                       " is %d Hz\n", max_hz, TEGRA_SPI_MAX_FREQ);
-               return NULL;
+       if (plat->periph_id == PERIPH_ID_NONE) {
+               debug("%s: could not decode periph id %d\n", __func__,
+                     plat->periph_id);
+               return -FDT_ERR_NOTFOUND;
        }
 
-       spi = spi_alloc_slave(struct tegra_spi_slave, bus, cs);
-       if (!spi) {
-               printf("SPI error: malloc of SPI structure failed\n");
-               return NULL;
-       }
-       spi->ctrl = &spi_ctrls[bus];
-       if (!spi->ctrl) {
-               printf("SPI error: could not find controller for bus %d\n",
-                      bus);
-               return NULL;
-       }
+       /* Use 500KHz as a suitable default */
+       plat->frequency = fdtdec_get_int(blob, node, "spi-max-frequency",
+                                       500000);
+       plat->deactivate_delay_us = fdtdec_get_int(blob, node,
+                                       "spi-deactivate-delay", 0);
+       debug("%s: base=%#08lx, periph_id=%d, max-frequency=%d, deactivate_delay=%d\n",
+             __func__, plat->base, plat->periph_id, plat->frequency,
+             plat->deactivate_delay_us);
 
-       if (max_hz < spi->ctrl->freq) {
-               debug("%s: limiting frequency from %u to %u\n", __func__,
-                     spi->ctrl->freq, max_hz);
-               spi->ctrl->freq = max_hz;
-       }
-       spi->ctrl->mode = mode;
-
-       return &spi->slave;
+       return 0;
 }
 
-void tegra30_spi_free_slave(struct spi_slave *slave)
+static int tegra30_spi_probe(struct udevice *bus)
 {
-       struct tegra_spi_slave *spi = to_tegra_spi(slave);
-
-       free(spi);
-}
+       struct tegra_spi_platdata *plat = dev_get_platdata(bus);
+       struct tegra30_spi_priv *priv = dev_get_priv(bus);
 
-int tegra30_spi_init(int *node_list, int count)
-{
-       struct tegra_spi_ctrl *ctrl;
-       int i;
-       int node = 0;
-       int found = 0;
-
-       for (i = 0; i < count; i++) {
-               ctrl = &spi_ctrls[i];
-               node = node_list[i];
-
-               ctrl->regs = (struct spi_regs *)fdtdec_get_addr(gd->fdt_blob,
-                                                               node, "reg");
-               if ((fdt_addr_t)ctrl->regs == FDT_ADDR_T_NONE) {
-                       debug("%s: no slink register found\n", __func__);
-                       continue;
-               }
-               ctrl->freq = fdtdec_get_int(gd->fdt_blob, node,
-                                           "spi-max-frequency", 0);
-               if (!ctrl->freq) {
-                       debug("%s: no slink max frequency found\n", __func__);
-                       continue;
-               }
+       priv->regs = (struct spi_regs *)plat->base;
 
-               ctrl->periph_id = clock_decode_periph_id(gd->fdt_blob, node);
-               if (ctrl->periph_id == PERIPH_ID_NONE) {
-                       debug("%s: could not decode periph id\n", __func__);
-                       continue;
-               }
-               ctrl->valid = 1;
-               found = 1;
+       priv->last_transaction_us = timer_get_us();
+       priv->freq = plat->frequency;
+       priv->periph_id = plat->periph_id;
 
-               debug("%s: found controller at %p, freq = %u, periph_id = %d\n",
-                     __func__, ctrl->regs, ctrl->freq, ctrl->periph_id);
-       }
-       return !found;
+       return 0;
 }
 
-int tegra30_spi_claim_bus(struct spi_slave *slave)
+static int tegra30_spi_claim_bus(struct udevice *bus)
 {
-       struct tegra_spi_slave *spi = to_tegra_spi(slave);
-       struct spi_regs *regs = spi->ctrl->regs;
+       struct tegra30_spi_priv *priv = dev_get_priv(bus);
+       struct spi_regs *regs = priv->regs;
        u32 reg;
 
        /* Change SPI clock to correct frequency, PLLP_OUT0 source */
-       clock_start_periph_pll(spi->ctrl->periph_id, CLOCK_ID_PERIPH,
-                              spi->ctrl->freq);
+       clock_start_periph_pll(priv->periph_id, CLOCK_ID_PERIPH,
+                              priv->freq);
 
        /* Clear stale status here */
        reg = SLINK_STAT_RDY | SLINK_STAT_RXF_FLUSH | SLINK_STAT_TXF_FLUSH | \
@@ -227,29 +166,46 @@ int tegra30_spi_claim_bus(struct spi_slave *slave)
        return 0;
 }
 
-void tegra30_spi_cs_activate(struct spi_slave *slave)
+static void spi_cs_activate(struct udevice *dev)
 {
-       struct tegra_spi_slave *spi = to_tegra_spi(slave);
-       struct spi_regs *regs = spi->ctrl->regs;
+       struct udevice *bus = dev->parent;
+       struct tegra_spi_platdata *pdata = dev_get_platdata(bus);
+       struct tegra30_spi_priv *priv = dev_get_priv(bus);
+
+       /* If it's too soon to do another transaction, wait */
+       if (pdata->deactivate_delay_us &&
+           priv->last_transaction_us) {
+               ulong delay_us;         /* The delay completed so far */
+               delay_us = timer_get_us() - priv->last_transaction_us;
+               if (delay_us < pdata->deactivate_delay_us)
+                       udelay(pdata->deactivate_delay_us - delay_us);
+       }
 
        /* CS is negated on Tegra, so drive a 1 to get a 0 */
-       setbits_le32(&regs->command, SLINK_CMD_CS_VAL);
+       setbits_le32(&priv->regs->command, SLINK_CMD_CS_VAL);
 }
 
-void tegra30_spi_cs_deactivate(struct spi_slave *slave)
+static void spi_cs_deactivate(struct udevice *dev)
 {
-       struct tegra_spi_slave *spi = to_tegra_spi(slave);
-       struct spi_regs *regs = spi->ctrl->regs;
+       struct udevice *bus = dev->parent;
+       struct tegra_spi_platdata *pdata = dev_get_platdata(bus);
+       struct tegra30_spi_priv *priv = dev_get_priv(bus);
 
        /* CS is negated on Tegra, so drive a 0 to get a 1 */
-       clrbits_le32(&regs->command, SLINK_CMD_CS_VAL);
+       clrbits_le32(&priv->regs->command, SLINK_CMD_CS_VAL);
+
+       /* Remember time of this transaction so we can honour the bus delay */
+       if (pdata->deactivate_delay_us)
+               priv->last_transaction_us = timer_get_us();
 }
 
-int tegra30_spi_xfer(struct spi_slave *slave, unsigned int bitlen,
-               const void *data_out, void *data_in, unsigned long flags)
+static int tegra30_spi_xfer(struct udevice *dev, unsigned int bitlen,
+                           const void *data_out, void *data_in,
+                           unsigned long flags)
 {
-       struct tegra_spi_slave *spi = to_tegra_spi(slave);
-       struct spi_regs *regs = spi->ctrl->regs;
+       struct udevice *bus = dev->parent;
+       struct tegra30_spi_priv *priv = dev_get_priv(bus);
+       struct spi_regs *regs = priv->regs;
        u32 reg, tmpdout, tmpdin = 0;
        const u8 *dout = data_out;
        u8 *din = data_in;
@@ -257,7 +213,7 @@ int tegra30_spi_xfer(struct spi_slave *slave, unsigned int bitlen,
        int ret;
 
        debug("%s: slave %u:%u dout %p din %p bitlen %u\n",
-             __func__, slave->bus, slave->cs, dout, din, bitlen);
+             __func__, bus->seq, spi_chip_select(dev), dout, din, bitlen);
        if (bitlen % 8)
                return -1;
        num_bytes = bitlen / 8;
@@ -276,11 +232,11 @@ int tegra30_spi_xfer(struct spi_slave *slave, unsigned int bitlen,
 
        clrsetbits_le32(&regs->command2, SLINK_CMD2_SS_EN_MASK,
                        SLINK_CMD2_TXEN | SLINK_CMD2_RXEN |
-                       (slave->cs << SLINK_CMD2_SS_EN_SHIFT));
+                       (spi_chip_select(dev) << SLINK_CMD2_SS_EN_SHIFT));
        debug("%s entry: COMMAND2 = %08x\n", __func__, readl(&regs->command2));
 
        if (flags & SPI_XFER_BEGIN)
-               spi_cs_activate(slave);
+               spi_cs_activate(dev);
 
        /* handle data in 32-bit chunks */
        while (num_bytes > 0) {
@@ -344,7 +300,7 @@ int tegra30_spi_xfer(struct spi_slave *slave, unsigned int bitlen,
        }
 
        if (flags & SPI_XFER_END)
-               spi_cs_deactivate(slave);
+               spi_cs_deactivate(dev);
 
        debug("%s: transfer ended. Value=%08x, status = %08x\n",
              __func__, tmpdin, readl(&regs->status));
@@ -357,3 +313,54 @@ int tegra30_spi_xfer(struct spi_slave *slave, unsigned int bitlen,
 
        return 0;
 }
+
+static int tegra30_spi_set_speed(struct udevice *bus, uint speed)
+{
+       struct tegra_spi_platdata *plat = bus->platdata;
+       struct tegra30_spi_priv *priv = dev_get_priv(bus);
+
+       if (speed > plat->frequency)
+               speed = plat->frequency;
+       priv->freq = speed;
+       debug("%s: regs=%p, speed=%d\n", __func__, priv->regs, priv->freq);
+
+       return 0;
+}
+
+static int tegra30_spi_set_mode(struct udevice *bus, uint mode)
+{
+       struct tegra30_spi_priv *priv = dev_get_priv(bus);
+
+       priv->mode = mode;
+       debug("%s: regs=%p, mode=%d\n", __func__, priv->regs, priv->mode);
+
+       return 0;
+}
+
+static const struct dm_spi_ops tegra30_spi_ops = {
+       .claim_bus      = tegra30_spi_claim_bus,
+       .xfer           = tegra30_spi_xfer,
+       .set_speed      = tegra30_spi_set_speed,
+       .set_mode       = tegra30_spi_set_mode,
+       /*
+        * cs_info is not needed, since we require all chip selects to be
+        * in the device tree explicitly
+        */
+};
+
+static const struct udevice_id tegra30_spi_ids[] = {
+       { .compatible = "nvidia,tegra20-slink" },
+       { }
+};
+
+U_BOOT_DRIVER(tegra30_spi) = {
+       .name   = "tegra20_slink",
+       .id     = UCLASS_SPI,
+       .of_match = tegra30_spi_ids,
+       .ops    = &tegra30_spi_ops,
+       .ofdata_to_platdata = tegra30_spi_ofdata_to_platdata,
+       .platdata_auto_alloc_size = sizeof(struct tegra_spi_platdata),
+       .priv_auto_alloc_size = sizeof(struct tegra30_spi_priv),
+       .per_child_auto_alloc_size      = sizeof(struct spi_slave),
+       .probe  = tegra30_spi_probe,
+};
diff --git a/drivers/spi/tegra_spi.h b/drivers/spi/tegra_spi.h
new file mode 100644 (file)
index 0000000..fb2b50f
--- /dev/null
@@ -0,0 +1,12 @@
+/*
+ * (C) Copyright 2014 Google, Inc
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+struct tegra_spi_platdata {
+       enum periph_id periph_id;
+       int frequency;          /* Default clock frequency, -1 for none */
+       ulong base;
+       uint deactivate_delay_us;       /* Delay to wait after deactivate */
+};
index 6557055e02b8ea130cc592b6425af0e54b0ca8d8..11811094ede8a9381af75bfc4fb0d0f12f6debaa 100644 (file)
@@ -580,6 +580,7 @@ static const struct asix_dongle asix_dongles[] = {
        { 0x2001, 0x3c05, FLAG_TYPE_AX88772 },
        /* ASIX 88772B */
        { 0x0b95, 0x772b, FLAG_TYPE_AX88772B | FLAG_EEPROM_MAC },
+       { 0x0b95, 0x7e2b, FLAG_TYPE_AX88772B },
        { 0x0000, 0x0000, FLAG_NONE }   /* END - Do not remove */
 };
 
index c4f5157a843735f1c66fc80920e5957542c6c2a5..1c3592914dcf363c71de68f05a69cf5b21b5d845 100644 (file)
@@ -43,5 +43,9 @@ obj-$(CONFIG_USB_EHCI_ZYNQ) += ehci-zynq.o
 
 # xhci
 obj-$(CONFIG_USB_XHCI) += xhci.o xhci-mem.o xhci-ring.o
+obj-$(CONFIG_USB_XHCI_KEYSTONE) += xhci-keystone.o
 obj-$(CONFIG_USB_XHCI_EXYNOS) += xhci-exynos5.o
 obj-$(CONFIG_USB_XHCI_OMAP) += xhci-omap.o
+
+# designware
+obj-$(CONFIG_USB_DWC2) += dwc2.o
diff --git a/drivers/usb/host/dwc2.c b/drivers/usb/host/dwc2.c
new file mode 100644 (file)
index 0000000..2a5bbf5
--- /dev/null
@@ -0,0 +1,1053 @@
+/*
+ * Copyright (C) 2012 Oleksandr Tymoshenko <gonzo@freebsd.org>
+ * Copyright (C) 2014 Marek Vasut <marex@denx.de>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <usb.h>
+#include <malloc.h>
+#include <usbroothubdes.h>
+#include <asm/io.h>
+
+#include "dwc2.h"
+
+/* Use only HC channel 0. */
+#define DWC2_HC_CHANNEL                        0
+
+#define DWC2_STATUS_BUF_SIZE           64
+#define DWC2_DATA_BUF_SIZE             (64 * 1024)
+
+/* We need doubleword-aligned buffers for DMA transfers */
+DEFINE_ALIGN_BUFFER(uint8_t, aligned_buffer, DWC2_DATA_BUF_SIZE, 8);
+DEFINE_ALIGN_BUFFER(uint8_t, status_buffer, DWC2_STATUS_BUF_SIZE, 8);
+
+#define MAX_DEVICE                     16
+#define MAX_ENDPOINT                   16
+static int bulk_data_toggle[MAX_DEVICE][MAX_ENDPOINT];
+static int control_data_toggle[MAX_DEVICE][MAX_ENDPOINT];
+
+static int root_hub_devnum;
+
+static struct dwc2_core_regs *regs =
+       (struct dwc2_core_regs *)CONFIG_USB_DWC2_REG_ADDR;
+
+/*
+ * DWC2 IP interface
+ */
+static int wait_for_bit(void *reg, const uint32_t mask, bool set)
+{
+       unsigned int timeout = 1000000;
+       uint32_t val;
+
+       while (--timeout) {
+               val = readl(reg);
+               if (!set)
+                       val = ~val;
+
+               if ((val & mask) == mask)
+                       return 0;
+
+               udelay(1);
+       }
+
+       debug("%s: Timeout (reg=%p mask=%08x wait_set=%i)\n",
+             __func__, reg, mask, set);
+
+       return -ETIMEDOUT;
+}
+
+/*
+ * Initializes the FSLSPClkSel field of the HCFG register
+ * depending on the PHY type.
+ */
+static void init_fslspclksel(struct dwc2_core_regs *regs)
+{
+       uint32_t phyclk;
+
+#if (CONFIG_DWC2_PHY_TYPE == DWC2_PHY_TYPE_FS)
+       phyclk = DWC2_HCFG_FSLSPCLKSEL_48_MHZ;  /* Full speed PHY */
+#else
+       /* High speed PHY running at full speed or high speed */
+       phyclk = DWC2_HCFG_FSLSPCLKSEL_30_60_MHZ;
+#endif
+
+#ifdef CONFIG_DWC2_ULPI_FS_LS
+       uint32_t hwcfg2 = readl(&regs->ghwcfg2);
+       uint32_t hval = (ghwcfg2 & DWC2_HWCFG2_HS_PHY_TYPE_MASK) >>
+                       DWC2_HWCFG2_HS_PHY_TYPE_OFFSET;
+       uint32_t fval = (ghwcfg2 & DWC2_HWCFG2_FS_PHY_TYPE_MASK) >>
+                       DWC2_HWCFG2_FS_PHY_TYPE_OFFSET;
+
+       if (hval == 2 && fval == 1)
+               phyclk = DWC2_HCFG_FSLSPCLKSEL_48_MHZ;  /* Full speed PHY */
+#endif
+
+       clrsetbits_le32(&regs->host_regs.hcfg,
+                       DWC2_HCFG_FSLSPCLKSEL_MASK,
+                       phyclk << DWC2_HCFG_FSLSPCLKSEL_OFFSET);
+}
+
+/*
+ * Flush a Tx FIFO.
+ *
+ * @param regs Programming view of DWC_otg controller.
+ * @param num Tx FIFO to flush.
+ */
+static void dwc_otg_flush_tx_fifo(struct dwc2_core_regs *regs, const int num)
+{
+       int ret;
+
+       writel(DWC2_GRSTCTL_TXFFLSH | (num << DWC2_GRSTCTL_TXFNUM_OFFSET),
+              &regs->grstctl);
+       ret = wait_for_bit(&regs->grstctl, DWC2_GRSTCTL_TXFFLSH, 0);
+       if (ret)
+               printf("%s: Timeout!\n", __func__);
+
+       /* Wait for 3 PHY Clocks */
+       udelay(1);
+}
+
+/*
+ * Flush Rx FIFO.
+ *
+ * @param regs Programming view of DWC_otg controller.
+ */
+static void dwc_otg_flush_rx_fifo(struct dwc2_core_regs *regs)
+{
+       int ret;
+
+       writel(DWC2_GRSTCTL_RXFFLSH, &regs->grstctl);
+       ret = wait_for_bit(&regs->grstctl, DWC2_GRSTCTL_RXFFLSH, 0);
+       if (ret)
+               printf("%s: Timeout!\n", __func__);
+
+       /* Wait for 3 PHY Clocks */
+       udelay(1);
+}
+
+/*
+ * Do core a soft reset of the core.  Be careful with this because it
+ * resets all the internal state machines of the core.
+ */
+static void dwc_otg_core_reset(struct dwc2_core_regs *regs)
+{
+       int ret;
+
+       /* Wait for AHB master IDLE state. */
+       ret = wait_for_bit(&regs->grstctl, DWC2_GRSTCTL_AHBIDLE, 1);
+       if (ret)
+               printf("%s: Timeout!\n", __func__);
+
+       /* Core Soft Reset */
+       writel(DWC2_GRSTCTL_CSFTRST, &regs->grstctl);
+       ret = wait_for_bit(&regs->grstctl, DWC2_GRSTCTL_CSFTRST, 0);
+       if (ret)
+               printf("%s: Timeout!\n", __func__);
+
+       /*
+        * Wait for core to come out of reset.
+        * NOTE: This long sleep is _very_ important, otherwise the core will
+        *       not stay in host mode after a connector ID change!
+        */
+       mdelay(100);
+}
+
+/*
+ * This function initializes the DWC_otg controller registers for
+ * host mode.
+ *
+ * This function flushes the Tx and Rx FIFOs and it flushes any entries in the
+ * request queues. Host channels are reset to ensure that they are ready for
+ * performing transfers.
+ *
+ * @param regs Programming view of DWC_otg controller
+ *
+ */
+static void dwc_otg_core_host_init(struct dwc2_core_regs *regs)
+{
+       uint32_t nptxfifosize = 0;
+       uint32_t ptxfifosize = 0;
+       uint32_t hprt0 = 0;
+       int i, ret, num_channels;
+
+       /* Restart the Phy Clock */
+       writel(0, &regs->pcgcctl);
+
+       /* Initialize Host Configuration Register */
+       init_fslspclksel(regs);
+#ifdef CONFIG_DWC2_DFLT_SPEED_FULL
+       setbits_le32(&regs->host_regs.hcfg, DWC2_HCFG_FSLSSUPP);
+#endif
+
+       /* Configure data FIFO sizes */
+#ifdef CONFIG_DWC2_ENABLE_DYNAMIC_FIFO
+       if (readl(&regs->ghwcfg2) & DWC2_HWCFG2_DYNAMIC_FIFO) {
+               /* Rx FIFO */
+               writel(CONFIG_DWC2_HOST_RX_FIFO_SIZE, &regs->grxfsiz);
+
+               /* Non-periodic Tx FIFO */
+               nptxfifosize |= CONFIG_DWC2_HOST_NPERIO_TX_FIFO_SIZE <<
+                               DWC2_FIFOSIZE_DEPTH_OFFSET;
+               nptxfifosize |= CONFIG_DWC2_HOST_RX_FIFO_SIZE <<
+                               DWC2_FIFOSIZE_STARTADDR_OFFSET;
+               writel(nptxfifosize, &regs->gnptxfsiz);
+
+               /* Periodic Tx FIFO */
+               ptxfifosize |= CONFIG_DWC2_HOST_PERIO_TX_FIFO_SIZE <<
+                               DWC2_FIFOSIZE_DEPTH_OFFSET;
+               ptxfifosize |= (CONFIG_DWC2_HOST_RX_FIFO_SIZE +
+                               CONFIG_DWC2_HOST_NPERIO_TX_FIFO_SIZE) <<
+                               DWC2_FIFOSIZE_STARTADDR_OFFSET;
+               writel(ptxfifosize, &regs->hptxfsiz);
+       }
+#endif
+
+       /* Clear Host Set HNP Enable in the OTG Control Register */
+       clrbits_le32(&regs->gotgctl, DWC2_GOTGCTL_HSTSETHNPEN);
+
+       /* Make sure the FIFOs are flushed. */
+       dwc_otg_flush_tx_fifo(regs, 0x10);      /* All Tx FIFOs */
+       dwc_otg_flush_rx_fifo(regs);
+
+       /* Flush out any leftover queued requests. */
+       num_channels = readl(&regs->ghwcfg2);
+       num_channels &= DWC2_HWCFG2_NUM_HOST_CHAN_MASK;
+       num_channels >>= DWC2_HWCFG2_NUM_HOST_CHAN_OFFSET;
+       num_channels += 1;
+
+       for (i = 0; i < num_channels; i++)
+               clrsetbits_le32(&regs->hc_regs[i].hcchar,
+                               DWC2_HCCHAR_CHEN | DWC2_HCCHAR_EPDIR,
+                               DWC2_HCCHAR_CHDIS);
+
+       /* Halt all channels to put them into a known state. */
+       for (i = 0; i < num_channels; i++) {
+               clrsetbits_le32(&regs->hc_regs[i].hcchar,
+                               DWC2_HCCHAR_EPDIR,
+                               DWC2_HCCHAR_CHEN | DWC2_HCCHAR_CHDIS);
+               ret = wait_for_bit(&regs->hc_regs[i].hcchar,
+                                  DWC2_HCCHAR_CHEN, 0);
+               if (ret)
+                       printf("%s: Timeout!\n", __func__);
+       }
+
+       /* Turn on the vbus power. */
+       if (readl(&regs->gintsts) & DWC2_GINTSTS_CURMODE_HOST) {
+               hprt0 = readl(&regs->hprt0);
+               hprt0 &= ~(DWC2_HPRT0_PRTENA | DWC2_HPRT0_PRTCONNDET);
+               hprt0 &= ~(DWC2_HPRT0_PRTENCHNG | DWC2_HPRT0_PRTOVRCURRCHNG);
+               if (!(hprt0 & DWC2_HPRT0_PRTPWR)) {
+                       hprt0 |= DWC2_HPRT0_PRTPWR;
+                       writel(hprt0, &regs->hprt0);
+               }
+       }
+}
+
+/*
+ * This function initializes the DWC_otg controller registers and
+ * prepares the core for device mode or host mode operation.
+ *
+ * @param regs Programming view of the DWC_otg controller
+ */
+static void dwc_otg_core_init(struct dwc2_core_regs *regs)
+{
+       uint32_t ahbcfg = 0;
+       uint32_t usbcfg = 0;
+       uint8_t brst_sz = CONFIG_DWC2_DMA_BURST_SIZE;
+
+       /* Common Initialization */
+       usbcfg = readl(&regs->gusbcfg);
+
+       /* Program the ULPI External VBUS bit if needed */
+#ifdef CONFIG_DWC2_PHY_ULPI_EXT_VBUS
+       usbcfg |= DWC2_GUSBCFG_ULPI_EXT_VBUS_DRV;
+#else
+       usbcfg &= ~DWC2_GUSBCFG_ULPI_EXT_VBUS_DRV;
+#endif
+
+       /* Set external TS Dline pulsing */
+#ifdef CONFIG_DWC2_TS_DLINE
+       usbcfg |= DWC2_GUSBCFG_TERM_SEL_DL_PULSE;
+#else
+       usbcfg &= ~DWC2_GUSBCFG_TERM_SEL_DL_PULSE;
+#endif
+       writel(usbcfg, &regs->gusbcfg);
+
+       /* Reset the Controller */
+       dwc_otg_core_reset(regs);
+
+       /*
+        * This programming sequence needs to happen in FS mode before
+        * any other programming occurs
+        */
+#if defined(CONFIG_DWC2_DFLT_SPEED_FULL) && \
+       (CONFIG_DWC2_PHY_TYPE == DWC2_PHY_TYPE_FS)
+       /* If FS mode with FS PHY */
+       setbits_le32(&regs->gusbcfg, DWC2_GUSBCFG_PHYSEL);
+
+       /* Reset after a PHY select */
+       dwc_otg_core_reset(regs);
+
+       /*
+        * Program DCFG.DevSpd or HCFG.FSLSPclkSel to 48Mhz in FS.
+        * Also do this on HNP Dev/Host mode switches (done in dev_init
+        * and host_init).
+        */
+       if (readl(&regs->gintsts) & DWC2_GINTSTS_CURMODE_HOST)
+               init_fslspclksel(regs);
+
+#ifdef CONFIG_DWC2_I2C_ENABLE
+       /* Program GUSBCFG.OtgUtmifsSel to I2C */
+       setbits_le32(&regs->gusbcfg, DWC2_GUSBCFG_OTGUTMIFSSEL);
+
+       /* Program GI2CCTL.I2CEn */
+       clrsetbits_le32(&regs->gi2cctl, DWC2_GI2CCTL_I2CEN |
+                       DWC2_GI2CCTL_I2CDEVADDR_MASK,
+                       1 << DWC2_GI2CCTL_I2CDEVADDR_OFFSET);
+       setbits_le32(&regs->gi2cctl, DWC2_GI2CCTL_I2CEN);
+#endif
+
+#else
+       /* High speed PHY. */
+
+       /*
+        * HS PHY parameters. These parameters are preserved during
+        * soft reset so only program the first time. Do a soft reset
+        * immediately after setting phyif.
+        */
+       usbcfg &= ~(DWC2_GUSBCFG_ULPI_UTMI_SEL | DWC2_GUSBCFG_PHYIF);
+       usbcfg |= CONFIG_DWC2_PHY_TYPE << DWC2_GUSBCFG_ULPI_UTMI_SEL_OFFSET;
+
+       if (usbcfg & DWC2_GUSBCFG_ULPI_UTMI_SEL) {      /* ULPI interface */
+#ifdef CONFIG_DWC2_PHY_ULPI_DDR
+               usbcfg |= DWC2_GUSBCFG_DDRSEL;
+#else
+               usbcfg &= ~DWC2_GUSBCFG_DDRSEL;
+#endif
+       } else {        /* UTMI+ interface */
+#if (CONFIG_DWC2_UTMI_PHY_WIDTH == 16)
+               usbcfg |= DWC2_GUSBCFG_PHYIF;
+#endif
+       }
+
+       writel(usbcfg, &regs->gusbcfg);
+
+       /* Reset after setting the PHY parameters */
+       dwc_otg_core_reset(regs);
+#endif
+
+       usbcfg = readl(&regs->gusbcfg);
+       usbcfg &= ~(DWC2_GUSBCFG_ULPI_FSLS | DWC2_GUSBCFG_ULPI_CLK_SUS_M);
+#ifdef CONFIG_DWC2_ULPI_FS_LS
+       uint32_t hwcfg2 = readl(&regs->ghwcfg2);
+       uint32_t hval = (ghwcfg2 & DWC2_HWCFG2_HS_PHY_TYPE_MASK) >>
+                       DWC2_HWCFG2_HS_PHY_TYPE_OFFSET;
+       uint32_t fval = (ghwcfg2 & DWC2_HWCFG2_FS_PHY_TYPE_MASK) >>
+                       DWC2_HWCFG2_FS_PHY_TYPE_OFFSET;
+       if (hval == 2 && fval == 1) {
+               usbcfg |= DWC2_GUSBCFG_ULPI_FSLS;
+               usbcfg |= DWC2_GUSBCFG_ULPI_CLK_SUS_M;
+       }
+#endif
+       writel(usbcfg, &regs->gusbcfg);
+
+       /* Program the GAHBCFG Register. */
+       switch (readl(&regs->ghwcfg2) & DWC2_HWCFG2_ARCHITECTURE_MASK) {
+       case DWC2_HWCFG2_ARCHITECTURE_SLAVE_ONLY:
+               break;
+       case DWC2_HWCFG2_ARCHITECTURE_EXT_DMA:
+               while (brst_sz > 1) {
+                       ahbcfg |= ahbcfg + (1 << DWC2_GAHBCFG_HBURSTLEN_OFFSET);
+                       ahbcfg &= DWC2_GAHBCFG_HBURSTLEN_MASK;
+                       brst_sz >>= 1;
+               }
+
+#ifdef CONFIG_DWC2_DMA_ENABLE
+               ahbcfg |= DWC2_GAHBCFG_DMAENABLE;
+#endif
+               break;
+
+       case DWC2_HWCFG2_ARCHITECTURE_INT_DMA:
+               ahbcfg |= DWC2_GAHBCFG_HBURSTLEN_INCR4;
+#ifdef CONFIG_DWC2_DMA_ENABLE
+               ahbcfg |= DWC2_GAHBCFG_DMAENABLE;
+#endif
+               break;
+       }
+
+       writel(ahbcfg, &regs->gahbcfg);
+
+       /* Program the GUSBCFG register for HNP/SRP. */
+       setbits_le32(&regs->gusbcfg, DWC2_GUSBCFG_HNPCAP | DWC2_GUSBCFG_SRPCAP);
+
+#ifdef CONFIG_DWC2_IC_USB_CAP
+       setbits_le32(&regs->gusbcfg, DWC2_GUSBCFG_IC_USB_CAP);
+#endif
+}
+
+/*
+ * Prepares a host channel for transferring packets to/from a specific
+ * endpoint. The HCCHARn register is set up with the characteristics specified
+ * in _hc. Host channel interrupts that may need to be serviced while this
+ * transfer is in progress are enabled.
+ *
+ * @param regs Programming view of DWC_otg controller
+ * @param hc Information needed to initialize the host channel
+ */
+static void dwc_otg_hc_init(struct dwc2_core_regs *regs, uint8_t hc_num,
+               uint8_t dev_addr, uint8_t ep_num, uint8_t ep_is_in,
+               uint8_t ep_type, uint16_t max_packet)
+{
+       struct dwc2_hc_regs *hc_regs = &regs->hc_regs[hc_num];
+       const uint32_t hcchar = (dev_addr << DWC2_HCCHAR_DEVADDR_OFFSET) |
+                               (ep_num << DWC2_HCCHAR_EPNUM_OFFSET) |
+                               (ep_is_in << DWC2_HCCHAR_EPDIR_OFFSET) |
+                               (ep_type << DWC2_HCCHAR_EPTYPE_OFFSET) |
+                               (max_packet << DWC2_HCCHAR_MPS_OFFSET);
+
+       /* Clear old interrupt conditions for this host channel. */
+       writel(0x3fff, &hc_regs->hcint);
+
+       /*
+        * Program the HCCHARn register with the endpoint characteristics
+        * for the current transfer.
+        */
+       writel(hcchar, &hc_regs->hcchar);
+
+       /* Program the HCSPLIT register for SPLITs */
+       writel(0, &hc_regs->hcsplt);
+}
+
+/*
+ * DWC2 to USB API interface
+ */
+/* Direction: In ; Request: Status */
+static int dwc_otg_submit_rh_msg_in_status(struct usb_device *dev, void *buffer,
+                                          int txlen, struct devrequest *cmd)
+{
+       uint32_t hprt0 = 0;
+       uint32_t port_status = 0;
+       uint32_t port_change = 0;
+       int len = 0;
+       int stat = 0;
+
+       switch (cmd->requesttype & ~USB_DIR_IN) {
+       case 0:
+               *(uint16_t *)buffer = cpu_to_le16(1);
+               len = 2;
+               break;
+       case USB_RECIP_INTERFACE:
+       case USB_RECIP_ENDPOINT:
+               *(uint16_t *)buffer = cpu_to_le16(0);
+               len = 2;
+               break;
+       case USB_TYPE_CLASS:
+               *(uint32_t *)buffer = cpu_to_le32(0);
+               len = 4;
+               break;
+       case USB_RECIP_OTHER | USB_TYPE_CLASS:
+               hprt0 = readl(&regs->hprt0);
+               if (hprt0 & DWC2_HPRT0_PRTCONNSTS)
+                       port_status |= USB_PORT_STAT_CONNECTION;
+               if (hprt0 & DWC2_HPRT0_PRTENA)
+                       port_status |= USB_PORT_STAT_ENABLE;
+               if (hprt0 & DWC2_HPRT0_PRTSUSP)
+                       port_status |= USB_PORT_STAT_SUSPEND;
+               if (hprt0 & DWC2_HPRT0_PRTOVRCURRACT)
+                       port_status |= USB_PORT_STAT_OVERCURRENT;
+               if (hprt0 & DWC2_HPRT0_PRTRST)
+                       port_status |= USB_PORT_STAT_RESET;
+               if (hprt0 & DWC2_HPRT0_PRTPWR)
+                       port_status |= USB_PORT_STAT_POWER;
+
+               port_status |= USB_PORT_STAT_HIGH_SPEED;
+
+               if (hprt0 & DWC2_HPRT0_PRTENCHNG)
+                       port_change |= USB_PORT_STAT_C_ENABLE;
+               if (hprt0 & DWC2_HPRT0_PRTCONNDET)
+                       port_change |= USB_PORT_STAT_C_CONNECTION;
+               if (hprt0 & DWC2_HPRT0_PRTOVRCURRCHNG)
+                       port_change |= USB_PORT_STAT_C_OVERCURRENT;
+
+               *(uint32_t *)buffer = cpu_to_le32(port_status |
+                                       (port_change << 16));
+               len = 4;
+               break;
+       default:
+               puts("unsupported root hub command\n");
+               stat = USB_ST_STALLED;
+       }
+
+       dev->act_len = min(len, txlen);
+       dev->status = stat;
+
+       return stat;
+}
+
+/* Direction: In ; Request: Descriptor */
+static int dwc_otg_submit_rh_msg_in_descriptor(struct usb_device *dev,
+                                              void *buffer, int txlen,
+                                              struct devrequest *cmd)
+{
+       unsigned char data[32];
+       uint32_t dsc;
+       int len = 0;
+       int stat = 0;
+       uint16_t wValue = cpu_to_le16(cmd->value);
+       uint16_t wLength = cpu_to_le16(cmd->length);
+
+       switch (cmd->requesttype & ~USB_DIR_IN) {
+       case 0:
+               switch (wValue & 0xff00) {
+               case 0x0100:    /* device descriptor */
+                       len = min3(txlen, sizeof(root_hub_dev_des), wLength);
+                       memcpy(buffer, root_hub_dev_des, len);
+                       break;
+               case 0x0200:    /* configuration descriptor */
+                       len = min3(txlen, sizeof(root_hub_config_des), wLength);
+                       memcpy(buffer, root_hub_config_des, len);
+                       break;
+               case 0x0300:    /* string descriptors */
+                       switch (wValue & 0xff) {
+                       case 0x00:
+                               len = min3(txlen, sizeof(root_hub_str_index0),
+                                          wLength);
+                               memcpy(buffer, root_hub_str_index0, len);
+                               break;
+                       case 0x01:
+                               len = min3(txlen, sizeof(root_hub_str_index1),
+                                          wLength);
+                               memcpy(buffer, root_hub_str_index1, len);
+                               break;
+                       }
+                       break;
+               default:
+                       stat = USB_ST_STALLED;
+               }
+               break;
+
+       case USB_TYPE_CLASS:
+               /* Root port config, set 1 port and nothing else. */
+               dsc = 0x00000001;
+
+               data[0] = 9;            /* min length; */
+               data[1] = 0x29;
+               data[2] = dsc & RH_A_NDP;
+               data[3] = 0;
+               if (dsc & RH_A_PSM)
+                       data[3] |= 0x1;
+               if (dsc & RH_A_NOCP)
+                       data[3] |= 0x10;
+               else if (dsc & RH_A_OCPM)
+                       data[3] |= 0x8;
+
+               /* corresponds to data[4-7] */
+               data[5] = (dsc & RH_A_POTPGT) >> 24;
+               data[7] = dsc & RH_B_DR;
+               if (data[2] < 7) {
+                       data[8] = 0xff;
+               } else {
+                       data[0] += 2;
+                       data[8] = (dsc & RH_B_DR) >> 8;
+                       data[9] = 0xff;
+                       data[10] = data[9];
+               }
+
+               len = min3(txlen, data[0], wLength);
+               memcpy(buffer, data, len);
+               break;
+       default:
+               puts("unsupported root hub command\n");
+               stat = USB_ST_STALLED;
+       }
+
+       dev->act_len = min(len, txlen);
+       dev->status = stat;
+
+       return stat;
+}
+
+/* Direction: In ; Request: Configuration */
+static int dwc_otg_submit_rh_msg_in_configuration(struct usb_device *dev,
+                                                 void *buffer, int txlen,
+                                                 struct devrequest *cmd)
+{
+       int len = 0;
+       int stat = 0;
+
+       switch (cmd->requesttype & ~USB_DIR_IN) {
+       case 0:
+               *(uint8_t *)buffer = 0x01;
+               len = 1;
+               break;
+       default:
+               puts("unsupported root hub command\n");
+               stat = USB_ST_STALLED;
+       }
+
+       dev->act_len = min(len, txlen);
+       dev->status = stat;
+
+       return stat;
+}
+
+/* Direction: In */
+static int dwc_otg_submit_rh_msg_in(struct usb_device *dev,
+                                void *buffer, int txlen,
+                                struct devrequest *cmd)
+{
+       switch (cmd->request) {
+       case USB_REQ_GET_STATUS:
+               return dwc_otg_submit_rh_msg_in_status(dev, buffer,
+                                                      txlen, cmd);
+       case USB_REQ_GET_DESCRIPTOR:
+               return dwc_otg_submit_rh_msg_in_descriptor(dev, buffer,
+                                                          txlen, cmd);
+       case USB_REQ_GET_CONFIGURATION:
+               return dwc_otg_submit_rh_msg_in_configuration(dev, buffer,
+                                                             txlen, cmd);
+       default:
+               puts("unsupported root hub command\n");
+               return USB_ST_STALLED;
+       }
+}
+
+/* Direction: Out */
+static int dwc_otg_submit_rh_msg_out(struct usb_device *dev,
+                                void *buffer, int txlen,
+                                struct devrequest *cmd)
+{
+       int len = 0;
+       int stat = 0;
+       uint16_t bmrtype_breq = cmd->requesttype | (cmd->request << 8);
+       uint16_t wValue = cpu_to_le16(cmd->value);
+
+       switch (bmrtype_breq & ~USB_DIR_IN) {
+       case (USB_REQ_CLEAR_FEATURE << 8) | USB_RECIP_ENDPOINT:
+       case (USB_REQ_CLEAR_FEATURE << 8) | USB_TYPE_CLASS:
+               break;
+
+       case (USB_REQ_CLEAR_FEATURE << 8) | USB_RECIP_OTHER | USB_TYPE_CLASS:
+               switch (wValue) {
+               case USB_PORT_FEAT_C_CONNECTION:
+                       setbits_le32(&regs->hprt0, DWC2_HPRT0_PRTCONNDET);
+                       break;
+               }
+               break;
+
+       case (USB_REQ_SET_FEATURE << 8) | USB_RECIP_OTHER | USB_TYPE_CLASS:
+               switch (wValue) {
+               case USB_PORT_FEAT_SUSPEND:
+                       break;
+
+               case USB_PORT_FEAT_RESET:
+                       clrsetbits_le32(&regs->hprt0, DWC2_HPRT0_PRTENA |
+                                       DWC2_HPRT0_PRTCONNDET |
+                                       DWC2_HPRT0_PRTENCHNG |
+                                       DWC2_HPRT0_PRTOVRCURRCHNG,
+                                       DWC2_HPRT0_PRTRST);
+                       mdelay(50);
+                       clrbits_le32(&regs->hprt0, DWC2_HPRT0_PRTRST);
+                       break;
+
+               case USB_PORT_FEAT_POWER:
+                       clrsetbits_le32(&regs->hprt0, DWC2_HPRT0_PRTENA |
+                                       DWC2_HPRT0_PRTCONNDET |
+                                       DWC2_HPRT0_PRTENCHNG |
+                                       DWC2_HPRT0_PRTOVRCURRCHNG,
+                                       DWC2_HPRT0_PRTRST);
+                       break;
+
+               case USB_PORT_FEAT_ENABLE:
+                       break;
+               }
+               break;
+       case (USB_REQ_SET_ADDRESS << 8):
+               root_hub_devnum = wValue;
+               break;
+       case (USB_REQ_SET_CONFIGURATION << 8):
+               break;
+       default:
+               puts("unsupported root hub command\n");
+               stat = USB_ST_STALLED;
+       }
+
+       len = min(len, txlen);
+
+       dev->act_len = len;
+       dev->status = stat;
+
+       return stat;
+}
+
+static int dwc_otg_submit_rh_msg(struct usb_device *dev, unsigned long pipe,
+                                void *buffer, int txlen,
+                                struct devrequest *cmd)
+{
+       int stat = 0;
+
+       if (usb_pipeint(pipe)) {
+               puts("Root-Hub submit IRQ: NOT implemented\n");
+               return 0;
+       }
+
+       if (cmd->requesttype & USB_DIR_IN)
+               stat = dwc_otg_submit_rh_msg_in(dev, buffer, txlen, cmd);
+       else
+               stat = dwc_otg_submit_rh_msg_out(dev, buffer, txlen, cmd);
+
+       mdelay(1);
+
+       return stat;
+}
+
+/* U-Boot USB transmission interface */
+int submit_bulk_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
+                   int len)
+{
+       int devnum = usb_pipedevice(pipe);
+       int ep = usb_pipeendpoint(pipe);
+       int max = usb_maxpacket(dev, pipe);
+       int done = 0;
+       uint32_t hctsiz, sub, tmp;
+       struct dwc2_hc_regs *hc_regs = &regs->hc_regs[DWC2_HC_CHANNEL];
+       uint32_t hcint;
+       uint32_t xfer_len;
+       uint32_t num_packets;
+       int stop_transfer = 0;
+       unsigned int timeout = 1000000;
+
+       if (devnum == root_hub_devnum) {
+               dev->status = 0;
+               return -EINVAL;
+       }
+
+       if (len > DWC2_DATA_BUF_SIZE) {
+               printf("%s: %d is more then available buffer size (%d)\n",
+                      __func__, len, DWC2_DATA_BUF_SIZE);
+               dev->status = 0;
+               dev->act_len = 0;
+               return -EINVAL;
+       }
+
+       while ((done < len) && !stop_transfer) {
+               /* Initialize channel */
+               dwc_otg_hc_init(regs, DWC2_HC_CHANNEL, devnum, ep,
+                               usb_pipein(pipe), DWC2_HCCHAR_EPTYPE_BULK, max);
+
+               xfer_len = len - done;
+               /* Make sure that xfer_len is a multiple of max packet size. */
+               if (xfer_len > CONFIG_DWC2_MAX_TRANSFER_SIZE)
+                       xfer_len = CONFIG_DWC2_MAX_TRANSFER_SIZE - max + 1;
+
+               if (xfer_len > 0) {
+                       num_packets = (xfer_len + max - 1) / max;
+                       if (num_packets > CONFIG_DWC2_MAX_PACKET_COUNT) {
+                               num_packets = CONFIG_DWC2_MAX_PACKET_COUNT;
+                               xfer_len = num_packets * max;
+                       }
+               } else {
+                       num_packets = 1;
+               }
+
+               if (usb_pipein(pipe))
+                       xfer_len = num_packets * max;
+
+               writel((xfer_len << DWC2_HCTSIZ_XFERSIZE_OFFSET) |
+                      (num_packets << DWC2_HCTSIZ_PKTCNT_OFFSET) |
+                      (bulk_data_toggle[devnum][ep] <<
+                               DWC2_HCTSIZ_PID_OFFSET),
+                      &hc_regs->hctsiz);
+
+               memcpy(aligned_buffer, (char *)buffer + done, len - done);
+               writel((uint32_t)aligned_buffer, &hc_regs->hcdma);
+
+               /* Set host channel enable after all other setup is complete. */
+               clrsetbits_le32(&hc_regs->hcchar, DWC2_HCCHAR_MULTICNT_MASK |
+                               DWC2_HCCHAR_CHEN | DWC2_HCCHAR_CHDIS,
+                               (1 << DWC2_HCCHAR_MULTICNT_OFFSET) |
+                               DWC2_HCCHAR_CHEN);
+
+               while (1) {
+                       hcint = readl(&hc_regs->hcint);
+
+                       if (!(hcint & DWC2_HCINT_CHHLTD))
+                               continue;
+
+                       if (hcint & DWC2_HCINT_XFERCOMP) {
+                               hctsiz = readl(&hc_regs->hctsiz);
+                               done += xfer_len;
+
+                               sub = hctsiz & DWC2_HCTSIZ_XFERSIZE_MASK;
+                               sub >>= DWC2_HCTSIZ_XFERSIZE_OFFSET;
+
+                               if (usb_pipein(pipe)) {
+                                       done -= sub;
+                                       if (hctsiz & DWC2_HCTSIZ_XFERSIZE_MASK)
+                                               stop_transfer = 1;
+                               }
+
+                               tmp = hctsiz & DWC2_HCTSIZ_PID_MASK;
+                               tmp >>= DWC2_HCTSIZ_PID_OFFSET;
+                               if (tmp == DWC2_HC_PID_DATA1) {
+                                       bulk_data_toggle[devnum][ep] =
+                                               DWC2_HC_PID_DATA1;
+                               } else {
+                                       bulk_data_toggle[devnum][ep] =
+                                               DWC2_HC_PID_DATA0;
+                               }
+                               break;
+                       }
+
+                       if (hcint & DWC2_HCINT_STALL) {
+                               puts("DWC OTG: Channel halted\n");
+                               bulk_data_toggle[devnum][ep] =
+                                       DWC2_HC_PID_DATA0;
+
+                               stop_transfer = 1;
+                               break;
+                       }
+
+                       if (!--timeout) {
+                               printf("%s: Timeout!\n", __func__);
+                               break;
+                       }
+               }
+       }
+
+       if (done && usb_pipein(pipe))
+               memcpy(buffer, aligned_buffer, done);
+
+       writel(0, &hc_regs->hcintmsk);
+       writel(0xFFFFFFFF, &hc_regs->hcint);
+
+       dev->status = 0;
+       dev->act_len = done;
+
+       return 0;
+}
+
+int submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
+                      int len, struct devrequest *setup)
+{
+       struct dwc2_hc_regs *hc_regs = &regs->hc_regs[DWC2_HC_CHANNEL];
+       int done = 0;
+       int devnum = usb_pipedevice(pipe);
+       int ep = usb_pipeendpoint(pipe);
+       int max = usb_maxpacket(dev, pipe);
+       uint32_t hctsiz = 0, sub, tmp, ret;
+       uint32_t hcint;
+       const uint32_t hcint_comp_hlt_ack = DWC2_HCINT_XFERCOMP |
+               DWC2_HCINT_CHHLTD | DWC2_HCINT_ACK;
+       unsigned int timeout = 1000000;
+
+       /* For CONTROL endpoint pid should start with DATA1 */
+       int status_direction;
+
+       if (devnum == root_hub_devnum) {
+               dev->status = 0;
+               dev->speed = USB_SPEED_HIGH;
+               return dwc_otg_submit_rh_msg(dev, pipe, buffer, len, setup);
+       }
+
+       if (len > DWC2_DATA_BUF_SIZE) {
+               printf("%s: %d is more then available buffer size(%d)\n",
+                      __func__, len, DWC2_DATA_BUF_SIZE);
+               dev->status = 0;
+               dev->act_len = 0;
+               return -EINVAL;
+       }
+
+       /* Initialize channel, OUT for setup buffer */
+       dwc_otg_hc_init(regs, DWC2_HC_CHANNEL, devnum, ep, 0,
+                       DWC2_HCCHAR_EPTYPE_CONTROL, max);
+
+       /* SETUP stage  */
+       writel((8 << DWC2_HCTSIZ_XFERSIZE_OFFSET) |
+              (1 << DWC2_HCTSIZ_PKTCNT_OFFSET) |
+              (DWC2_HC_PID_SETUP << DWC2_HCTSIZ_PID_OFFSET),
+              &hc_regs->hctsiz);
+
+       writel((uint32_t)setup, &hc_regs->hcdma);
+
+       /* Set host channel enable after all other setup is complete. */
+       clrsetbits_le32(&hc_regs->hcchar, DWC2_HCCHAR_MULTICNT_MASK |
+                       DWC2_HCCHAR_CHEN | DWC2_HCCHAR_CHDIS,
+                       (1 << DWC2_HCCHAR_MULTICNT_OFFSET) | DWC2_HCCHAR_CHEN);
+
+       ret = wait_for_bit(&hc_regs->hcint, DWC2_HCINT_CHHLTD, 1);
+       if (ret)
+               printf("%s: Timeout!\n", __func__);
+
+       hcint = readl(&hc_regs->hcint);
+
+       if (!(hcint & DWC2_HCINT_CHHLTD) || !(hcint & DWC2_HCINT_XFERCOMP)) {
+               printf("%s: Error (HCINT=%08x)\n", __func__, hcint);
+               dev->status = 0;
+               dev->act_len = 0;
+               return -EINVAL;
+       }
+
+       /* Clear interrupts */
+       writel(0, &hc_regs->hcintmsk);
+       writel(0xFFFFFFFF, &hc_regs->hcint);
+
+       if (buffer) {
+               /* DATA stage */
+               dwc_otg_hc_init(regs, DWC2_HC_CHANNEL, devnum, ep,
+                               usb_pipein(pipe),
+                               DWC2_HCCHAR_EPTYPE_CONTROL, max);
+
+               /* TODO: check if len < 64 */
+               control_data_toggle[devnum][ep] = DWC2_HC_PID_DATA1;
+               writel((len << DWC2_HCTSIZ_XFERSIZE_OFFSET) |
+                      (1 << DWC2_HCTSIZ_PKTCNT_OFFSET) |
+                      (control_data_toggle[devnum][ep] <<
+                               DWC2_HCTSIZ_PID_OFFSET),
+                      &hc_regs->hctsiz);
+
+               writel((uint32_t)buffer, &hc_regs->hcdma);
+
+               /* Set host channel enable after all other setup is complete */
+               clrsetbits_le32(&hc_regs->hcchar, DWC2_HCCHAR_MULTICNT_MASK |
+                               DWC2_HCCHAR_CHEN | DWC2_HCCHAR_CHDIS,
+                               (1 << DWC2_HCCHAR_MULTICNT_OFFSET) |
+                               DWC2_HCCHAR_CHEN);
+
+               while (1) {
+                       hcint = readl(&hc_regs->hcint);
+                       if (!(hcint & DWC2_HCINT_CHHLTD))
+                               continue;
+
+                       if (hcint & DWC2_HCINT_XFERCOMP) {
+                               hctsiz = readl(&hc_regs->hctsiz);
+                               done = len;
+
+                               sub = hctsiz & DWC2_HCTSIZ_XFERSIZE_MASK;
+                               sub >>= DWC2_HCTSIZ_XFERSIZE_OFFSET;
+
+                               if (usb_pipein(pipe))
+                                       done -= sub;
+                       }
+
+                       if (hcint & DWC2_HCINT_ACK) {
+                               tmp = hctsiz & DWC2_HCTSIZ_PID_MASK;
+                               tmp >>= DWC2_HCTSIZ_PID_OFFSET;
+                               if (tmp == DWC2_HC_PID_DATA0) {
+                                       control_data_toggle[devnum][ep] =
+                                               DWC2_HC_PID_DATA0;
+                               } else {
+                                       control_data_toggle[devnum][ep] =
+                                               DWC2_HC_PID_DATA1;
+                               }
+                       }
+
+                       if (hcint != hcint_comp_hlt_ack) {
+                               printf("%s: Error (HCINT=%08x)\n",
+                                      __func__, hcint);
+                               goto out;
+                       }
+
+                       if (!--timeout) {
+                               printf("%s: Timeout!\n", __func__);
+                               goto out;
+                       }
+
+                       break;
+               }
+       } /* End of DATA stage */
+
+       /* STATUS stage */
+       if ((len == 0) || usb_pipeout(pipe))
+               status_direction = 1;
+       else
+               status_direction = 0;
+
+       dwc_otg_hc_init(regs, DWC2_HC_CHANNEL, devnum, ep,
+                       status_direction, DWC2_HCCHAR_EPTYPE_CONTROL, max);
+
+       writel((1 << DWC2_HCTSIZ_PKTCNT_OFFSET) |
+              (DWC2_HC_PID_DATA1 << DWC2_HCTSIZ_PID_OFFSET),
+              &hc_regs->hctsiz);
+
+       writel((uint32_t)status_buffer, &hc_regs->hcdma);
+
+       /* Set host channel enable after all other setup is complete. */
+       clrsetbits_le32(&hc_regs->hcchar, DWC2_HCCHAR_MULTICNT_MASK |
+                       DWC2_HCCHAR_CHEN | DWC2_HCCHAR_CHDIS,
+                       (1 << DWC2_HCCHAR_MULTICNT_OFFSET) | DWC2_HCCHAR_CHEN);
+
+       while (1) {
+               hcint = readl(&hc_regs->hcint);
+               if (hcint & DWC2_HCINT_CHHLTD)
+                       break;
+       }
+
+       if (hcint != hcint_comp_hlt_ack)
+               printf("%s: Error (HCINT=%08x)\n", __func__, hcint);
+
+out:
+       dev->act_len = done;
+       dev->status = 0;
+
+       return done;
+}
+
+int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
+                  int len, int interval)
+{
+       printf("dev = %p pipe = %#lx buf = %p size = %d int = %d\n",
+              dev, pipe, buffer, len, interval);
+       return -ENOSYS;
+}
+
+/* U-Boot USB control interface */
+int usb_lowlevel_init(int index, enum usb_init_type init, void **controller)
+{
+       uint32_t snpsid;
+       int i, j;
+
+       root_hub_devnum = 0;
+
+       snpsid = readl(&regs->gsnpsid);
+       printf("Core Release: %x.%03x\n", snpsid >> 12 & 0xf, snpsid & 0xfff);
+
+       if ((snpsid & DWC2_SNPSID_DEVID_MASK) != DWC2_SNPSID_DEVID_VER_2xx) {
+               printf("SNPSID invalid (not DWC2 OTG device): %08x\n", snpsid);
+               return -ENODEV;
+       }
+
+       dwc_otg_core_init(regs);
+       dwc_otg_core_host_init(regs);
+
+       clrsetbits_le32(&regs->hprt0, DWC2_HPRT0_PRTENA |
+                       DWC2_HPRT0_PRTCONNDET | DWC2_HPRT0_PRTENCHNG |
+                       DWC2_HPRT0_PRTOVRCURRCHNG,
+                       DWC2_HPRT0_PRTRST);
+       mdelay(50);
+       clrbits_le32(&regs->hprt0, DWC2_HPRT0_PRTENA | DWC2_HPRT0_PRTCONNDET |
+                    DWC2_HPRT0_PRTENCHNG | DWC2_HPRT0_PRTOVRCURRCHNG |
+                    DWC2_HPRT0_PRTRST);
+
+       for (i = 0; i < MAX_DEVICE; i++) {
+               for (j = 0; j < MAX_ENDPOINT; j++) {
+                       control_data_toggle[i][j] = DWC2_HC_PID_DATA1;
+                       bulk_data_toggle[i][j] = DWC2_HC_PID_DATA0;
+               }
+       }
+
+       return 0;
+}
+
+int usb_lowlevel_stop(int index)
+{
+       /* Put everything in reset. */
+       clrsetbits_le32(&regs->hprt0, DWC2_HPRT0_PRTENA |
+                       DWC2_HPRT0_PRTCONNDET | DWC2_HPRT0_PRTENCHNG |
+                       DWC2_HPRT0_PRTOVRCURRCHNG,
+                       DWC2_HPRT0_PRTRST);
+       return 0;
+}
diff --git a/drivers/usb/host/dwc2.h b/drivers/usb/host/dwc2.h
new file mode 100644 (file)
index 0000000..ba08fd5
--- /dev/null
@@ -0,0 +1,782 @@
+/*
+ * Copyright (C) 2014 Marek Vasut <marex@denx.de>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#ifndef __DWC2_H__
+#define __DWC2_H__
+
+struct dwc2_hc_regs {
+       u32                     hcchar;         /* 0x00 */
+       u32                     hcsplt;
+       u32                     hcint;
+       u32                     hcintmsk;
+       u32                     hctsiz;         /* 0x10 */
+       u32                     hcdma;
+       u32                     reserved;
+       u32                     hcdmab;
+};
+
+struct dwc2_host_regs {
+       u32                     hcfg;           /* 0x00 */
+       u32                     hfir;
+       u32                     hfnum;
+       u32                     _pad_0x40c;
+       u32                     hptxsts;        /* 0x10 */
+       u32                     haint;
+       u32                     haintmsk;
+       u32                     hflbaddr;
+};
+
+struct dwc2_core_regs {
+       u32                     gotgctl;        /* 0x000 */
+       u32                     gotgint;
+       u32                     gahbcfg;
+       u32                     gusbcfg;
+       u32                     grstctl;        /* 0x010 */
+       u32                     gintsts;
+       u32                     gintmsk;
+       u32                     grxstsr;
+       u32                     grxstsp;        /* 0x020 */
+       u32                     grxfsiz;
+       u32                     gnptxfsiz;
+       u32                     gnptxsts;
+       u32                     gi2cctl;        /* 0x030 */
+       u32                     gpvndctl;
+       u32                     ggpio;
+       u32                     guid;
+       u32                     gsnpsid;        /* 0x040 */
+       u32                     ghwcfg1;
+       u32                     ghwcfg2;
+       u32                     ghwcfg3;
+       u32                     ghwcfg4;        /* 0x050 */
+       u32                     glpmcfg;
+       u32                     _pad_0x58_0x9c[42];
+       u32                     hptxfsiz;       /* 0x100 */
+       u32                     dptxfsiz_dieptxf[15];
+       u32                     _pad_0x140_0x3fc[176];
+       struct dwc2_host_regs   host_regs;      /* 0x400 */
+       u32                     _pad_0x420_0x43c[8];
+       u32                     hprt0;          /* 0x440 */
+       u32                     _pad_0x444_0x4fc[47];
+       struct dwc2_hc_regs     hc_regs[16];    /* 0x500 */
+       u32                     _pad_0x700_0xe00[448];
+       u32                     pcgcctl;        /* 0xe00 */
+};
+
+#define DWC2_GOTGCTL_SESREQSCS                         (1 << 0)
+#define DWC2_GOTGCTL_SESREQSCS_OFFSET                  0
+#define DWC2_GOTGCTL_SESREQ                            (1 << 1)
+#define DWC2_GOTGCTL_SESREQ_OFFSET                     1
+#define DWC2_GOTGCTL_HSTNEGSCS                         (1 << 8)
+#define DWC2_GOTGCTL_HSTNEGSCS_OFFSET                  8
+#define DWC2_GOTGCTL_HNPREQ                            (1 << 9)
+#define DWC2_GOTGCTL_HNPREQ_OFFSET                     9
+#define DWC2_GOTGCTL_HSTSETHNPEN                       (1 << 10)
+#define DWC2_GOTGCTL_HSTSETHNPEN_OFFSET                        10
+#define DWC2_GOTGCTL_DEVHNPEN                          (1 << 11)
+#define DWC2_GOTGCTL_DEVHNPEN_OFFSET                   11
+#define DWC2_GOTGCTL_CONIDSTS                          (1 << 16)
+#define DWC2_GOTGCTL_CONIDSTS_OFFSET                   16
+#define DWC2_GOTGCTL_DBNCTIME                          (1 << 17)
+#define DWC2_GOTGCTL_DBNCTIME_OFFSET                   17
+#define DWC2_GOTGCTL_ASESVLD                           (1 << 18)
+#define DWC2_GOTGCTL_ASESVLD_OFFSET                    18
+#define DWC2_GOTGCTL_BSESVLD                           (1 << 19)
+#define DWC2_GOTGCTL_BSESVLD_OFFSET                    19
+#define DWC2_GOTGCTL_OTGVER                            (1 << 20)
+#define DWC2_GOTGCTL_OTGVER_OFFSET                     20
+#define DWC2_GOTGINT_SESENDDET                         (1 << 2)
+#define DWC2_GOTGINT_SESENDDET_OFFSET                  2
+#define DWC2_GOTGINT_SESREQSUCSTSCHNG                  (1 << 8)
+#define DWC2_GOTGINT_SESREQSUCSTSCHNG_OFFSET           8
+#define DWC2_GOTGINT_HSTNEGSUCSTSCHNG                  (1 << 9)
+#define DWC2_GOTGINT_HSTNEGSUCSTSCHNG_OFFSET           9
+#define DWC2_GOTGINT_RESERVER10_16_MASK                        (0x7F << 10)
+#define DWC2_GOTGINT_RESERVER10_16_OFFSET              10
+#define DWC2_GOTGINT_HSTNEGDET                         (1 << 17)
+#define DWC2_GOTGINT_HSTNEGDET_OFFSET                  17
+#define DWC2_GOTGINT_ADEVTOUTCHNG                      (1 << 18)
+#define DWC2_GOTGINT_ADEVTOUTCHNG_OFFSET               18
+#define DWC2_GOTGINT_DEBDONE                           (1 << 19)
+#define DWC2_GOTGINT_DEBDONE_OFFSET                    19
+#define DWC2_GAHBCFG_GLBLINTRMSK                       (1 << 0)
+#define DWC2_GAHBCFG_GLBLINTRMSK_OFFSET                        0
+#define DWC2_GAHBCFG_HBURSTLEN_SINGLE                  (0 << 1)
+#define DWC2_GAHBCFG_HBURSTLEN_INCR                    (1 << 1)
+#define DWC2_GAHBCFG_HBURSTLEN_INCR4                   (3 << 1)
+#define DWC2_GAHBCFG_HBURSTLEN_INCR8                   (5 << 1)
+#define DWC2_GAHBCFG_HBURSTLEN_INCR16                  (7 << 1)
+#define DWC2_GAHBCFG_HBURSTLEN_MASK                    (0xF << 1)
+#define DWC2_GAHBCFG_HBURSTLEN_OFFSET                  1
+#define DWC2_GAHBCFG_DMAENABLE                         (1 << 5)
+#define DWC2_GAHBCFG_DMAENABLE_OFFSET                  5
+#define DWC2_GAHBCFG_NPTXFEMPLVL_TXFEMPLVL             (1 << 7)
+#define DWC2_GAHBCFG_NPTXFEMPLVL_TXFEMPLVL_OFFSET      7
+#define DWC2_GAHBCFG_PTXFEMPLVL                                (1 << 8)
+#define DWC2_GAHBCFG_PTXFEMPLVL_OFFSET                 8
+#define DWC2_GUSBCFG_TOUTCAL_MASK                      (0x7 << 0)
+#define DWC2_GUSBCFG_TOUTCAL_OFFSET                    0
+#define DWC2_GUSBCFG_PHYIF                             (1 << 3)
+#define DWC2_GUSBCFG_PHYIF_OFFSET                      3
+#define DWC2_GUSBCFG_ULPI_UTMI_SEL                     (1 << 4)
+#define DWC2_GUSBCFG_ULPI_UTMI_SEL_OFFSET              4
+#define DWC2_GUSBCFG_FSINTF                            (1 << 5)
+#define DWC2_GUSBCFG_FSINTF_OFFSET                     5
+#define DWC2_GUSBCFG_PHYSEL                            (1 << 6)
+#define DWC2_GUSBCFG_PHYSEL_OFFSET                     6
+#define DWC2_GUSBCFG_DDRSEL                            (1 << 7)
+#define DWC2_GUSBCFG_DDRSEL_OFFSET                     7
+#define DWC2_GUSBCFG_SRPCAP                            (1 << 8)
+#define DWC2_GUSBCFG_SRPCAP_OFFSET                     8
+#define DWC2_GUSBCFG_HNPCAP                            (1 << 9)
+#define DWC2_GUSBCFG_HNPCAP_OFFSET                     9
+#define DWC2_GUSBCFG_USBTRDTIM_MASK                    (0xF << 10)
+#define DWC2_GUSBCFG_USBTRDTIM_OFFSET                  10
+#define DWC2_GUSBCFG_NPTXFRWNDEN                       (1 << 14)
+#define DWC2_GUSBCFG_NPTXFRWNDEN_OFFSET                        14
+#define DWC2_GUSBCFG_PHYLPWRCLKSEL                     (1 << 15)
+#define DWC2_GUSBCFG_PHYLPWRCLKSEL_OFFSET              15
+#define DWC2_GUSBCFG_OTGUTMIFSSEL                      (1 << 16)
+#define DWC2_GUSBCFG_OTGUTMIFSSEL_OFFSET               16
+#define DWC2_GUSBCFG_ULPI_FSLS                         (1 << 17)
+#define DWC2_GUSBCFG_ULPI_FSLS_OFFSET                  17
+#define DWC2_GUSBCFG_ULPI_AUTO_RES                     (1 << 18)
+#define DWC2_GUSBCFG_ULPI_AUTO_RES_OFFSET              18
+#define DWC2_GUSBCFG_ULPI_CLK_SUS_M                    (1 << 19)
+#define DWC2_GUSBCFG_ULPI_CLK_SUS_M_OFFSET             19
+#define DWC2_GUSBCFG_ULPI_EXT_VBUS_DRV                 (1 << 20)
+#define DWC2_GUSBCFG_ULPI_EXT_VBUS_DRV_OFFSET          20
+#define DWC2_GUSBCFG_ULPI_INT_VBUS_INDICATOR           (1 << 21)
+#define DWC2_GUSBCFG_ULPI_INT_VBUS_INDICATOR_OFFSET    21
+#define DWC2_GUSBCFG_TERM_SEL_DL_PULSE                 (1 << 22)
+#define DWC2_GUSBCFG_TERM_SEL_DL_PULSE_OFFSET          22
+#define DWC2_GUSBCFG_IC_USB_CAP                                (1 << 26)
+#define DWC2_GUSBCFG_IC_USB_CAP_OFFSET                 26
+#define DWC2_GUSBCFG_IC_TRAFFIC_PULL_REMOVE            (1 << 27)
+#define DWC2_GUSBCFG_IC_TRAFFIC_PULL_REMOVE_OFFSET     27
+#define DWC2_GUSBCFG_TX_END_DELAY                      (1 << 28)
+#define DWC2_GUSBCFG_TX_END_DELAY_OFFSET               28
+#define DWC2_GUSBCFG_FORCEHOSTMODE                     (1 << 29)
+#define DWC2_GUSBCFG_FORCEHOSTMODE_OFFSET              29
+#define DWC2_GUSBCFG_FORCEDEVMODE                      (1 << 30)
+#define DWC2_GUSBCFG_FORCEDEVMODE_OFFSET               30
+#define DWC2_GLPMCTL_LPM_CAP_EN                                (1 << 0)
+#define DWC2_GLPMCTL_LPM_CAP_EN_OFFSET                 0
+#define DWC2_GLPMCTL_APPL_RESP                         (1 << 1)
+#define DWC2_GLPMCTL_APPL_RESP_OFFSET                  1
+#define DWC2_GLPMCTL_HIRD_MASK                         (0xF << 2)
+#define DWC2_GLPMCTL_HIRD_OFFSET                       2
+#define DWC2_GLPMCTL_REM_WKUP_EN                       (1 << 6)
+#define DWC2_GLPMCTL_REM_WKUP_EN_OFFSET                        6
+#define DWC2_GLPMCTL_EN_UTMI_SLEEP                     (1 << 7)
+#define DWC2_GLPMCTL_EN_UTMI_SLEEP_OFFSET              7
+#define DWC2_GLPMCTL_HIRD_THRES_MASK                   (0x1F << 8)
+#define DWC2_GLPMCTL_HIRD_THRES_OFFSET                 8
+#define DWC2_GLPMCTL_LPM_RESP_MASK                     (0x3 << 13)
+#define DWC2_GLPMCTL_LPM_RESP_OFFSET                   13
+#define DWC2_GLPMCTL_PRT_SLEEP_STS                     (1 << 15)
+#define DWC2_GLPMCTL_PRT_SLEEP_STS_OFFSET              15
+#define DWC2_GLPMCTL_SLEEP_STATE_RESUMEOK              (1 << 16)
+#define DWC2_GLPMCTL_SLEEP_STATE_RESUMEOK_OFFSET       16
+#define DWC2_GLPMCTL_LPM_CHAN_INDEX_MASK               (0xF << 17)
+#define DWC2_GLPMCTL_LPM_CHAN_INDEX_OFFSET             17
+#define DWC2_GLPMCTL_RETRY_COUNT_MASK                  (0x7 << 21)
+#define DWC2_GLPMCTL_RETRY_COUNT_OFFSET                        21
+#define DWC2_GLPMCTL_SEND_LPM                          (1 << 24)
+#define DWC2_GLPMCTL_SEND_LPM_OFFSET                   24
+#define DWC2_GLPMCTL_RETRY_COUNT_STS_MASK              (0x7 << 25)
+#define DWC2_GLPMCTL_RETRY_COUNT_STS_OFFSET            25
+#define DWC2_GLPMCTL_HSIC_CONNECT                      (1 << 30)
+#define DWC2_GLPMCTL_HSIC_CONNECT_OFFSET               30
+#define DWC2_GLPMCTL_INV_SEL_HSIC                      (1 << 31)
+#define DWC2_GLPMCTL_INV_SEL_HSIC_OFFSET               31
+#define DWC2_GRSTCTL_CSFTRST                           (1 << 0)
+#define DWC2_GRSTCTL_CSFTRST_OFFSET                    0
+#define DWC2_GRSTCTL_HSFTRST                           (1 << 1)
+#define DWC2_GRSTCTL_HSFTRST_OFFSET                    1
+#define DWC2_GRSTCTL_HSTFRM                            (1 << 2)
+#define DWC2_GRSTCTL_HSTFRM_OFFSET                     2
+#define DWC2_GRSTCTL_INTKNQFLSH                                (1 << 3)
+#define DWC2_GRSTCTL_INTKNQFLSH_OFFSET                 3
+#define DWC2_GRSTCTL_RXFFLSH                           (1 << 4)
+#define DWC2_GRSTCTL_RXFFLSH_OFFSET                    4
+#define DWC2_GRSTCTL_TXFFLSH                           (1 << 5)
+#define DWC2_GRSTCTL_TXFFLSH_OFFSET                    5
+#define DWC2_GRSTCTL_TXFNUM_MASK                       (0x1F << 6)
+#define DWC2_GRSTCTL_TXFNUM_OFFSET                     6
+#define DWC2_GRSTCTL_DMAREQ                            (1 << 30)
+#define DWC2_GRSTCTL_DMAREQ_OFFSET                     30
+#define DWC2_GRSTCTL_AHBIDLE                           (1 << 31)
+#define DWC2_GRSTCTL_AHBIDLE_OFFSET                    31
+#define DWC2_GINTMSK_MODEMISMATCH                      (1 << 1)
+#define DWC2_GINTMSK_MODEMISMATCH_OFFSET               1
+#define DWC2_GINTMSK_OTGINTR                           (1 << 2)
+#define DWC2_GINTMSK_OTGINTR_OFFSET                    2
+#define DWC2_GINTMSK_SOFINTR                           (1 << 3)
+#define DWC2_GINTMSK_SOFINTR_OFFSET                    3
+#define DWC2_GINTMSK_RXSTSQLVL                         (1 << 4)
+#define DWC2_GINTMSK_RXSTSQLVL_OFFSET                  4
+#define DWC2_GINTMSK_NPTXFEMPTY                                (1 << 5)
+#define DWC2_GINTMSK_NPTXFEMPTY_OFFSET                 5
+#define DWC2_GINTMSK_GINNAKEFF                         (1 << 6)
+#define DWC2_GINTMSK_GINNAKEFF_OFFSET                  6
+#define DWC2_GINTMSK_GOUTNAKEFF                                (1 << 7)
+#define DWC2_GINTMSK_GOUTNAKEFF_OFFSET                 7
+#define DWC2_GINTMSK_I2CINTR                           (1 << 9)
+#define DWC2_GINTMSK_I2CINTR_OFFSET                    9
+#define DWC2_GINTMSK_ERLYSUSPEND                       (1 << 10)
+#define DWC2_GINTMSK_ERLYSUSPEND_OFFSET                        10
+#define DWC2_GINTMSK_USBSUSPEND                                (1 << 11)
+#define DWC2_GINTMSK_USBSUSPEND_OFFSET                 11
+#define DWC2_GINTMSK_USBRESET                          (1 << 12)
+#define DWC2_GINTMSK_USBRESET_OFFSET                   12
+#define DWC2_GINTMSK_ENUMDONE                          (1 << 13)
+#define DWC2_GINTMSK_ENUMDONE_OFFSET                   13
+#define DWC2_GINTMSK_ISOOUTDROP                                (1 << 14)
+#define DWC2_GINTMSK_ISOOUTDROP_OFFSET                 14
+#define DWC2_GINTMSK_EOPFRAME                          (1 << 15)
+#define DWC2_GINTMSK_EOPFRAME_OFFSET                   15
+#define DWC2_GINTMSK_EPMISMATCH                                (1 << 17)
+#define DWC2_GINTMSK_EPMISMATCH_OFFSET                 17
+#define DWC2_GINTMSK_INEPINTR                          (1 << 18)
+#define DWC2_GINTMSK_INEPINTR_OFFSET                   18
+#define DWC2_GINTMSK_OUTEPINTR                         (1 << 19)
+#define DWC2_GINTMSK_OUTEPINTR_OFFSET                  19
+#define DWC2_GINTMSK_INCOMPLISOIN                      (1 << 20)
+#define DWC2_GINTMSK_INCOMPLISOIN_OFFSET               20
+#define DWC2_GINTMSK_INCOMPLISOOUT                     (1 << 21)
+#define DWC2_GINTMSK_INCOMPLISOOUT_OFFSET              21
+#define DWC2_GINTMSK_PORTINTR                          (1 << 24)
+#define DWC2_GINTMSK_PORTINTR_OFFSET                   24
+#define DWC2_GINTMSK_HCINTR                            (1 << 25)
+#define DWC2_GINTMSK_HCINTR_OFFSET                     25
+#define DWC2_GINTMSK_PTXFEMPTY                         (1 << 26)
+#define DWC2_GINTMSK_PTXFEMPTY_OFFSET                  26
+#define DWC2_GINTMSK_LPMTRANRCVD                       (1 << 27)
+#define DWC2_GINTMSK_LPMTRANRCVD_OFFSET                        27
+#define DWC2_GINTMSK_CONIDSTSCHNG                      (1 << 28)
+#define DWC2_GINTMSK_CONIDSTSCHNG_OFFSET               28
+#define DWC2_GINTMSK_DISCONNECT                                (1 << 29)
+#define DWC2_GINTMSK_DISCONNECT_OFFSET                 29
+#define DWC2_GINTMSK_SESSREQINTR                       (1 << 30)
+#define DWC2_GINTMSK_SESSREQINTR_OFFSET                        30
+#define DWC2_GINTMSK_WKUPINTR                          (1 << 31)
+#define DWC2_GINTMSK_WKUPINTR_OFFSET                   31
+#define DWC2_GINTSTS_CURMODE_DEVICE                    (0 << 0)
+#define DWC2_GINTSTS_CURMODE_HOST                      (1 << 0)
+#define DWC2_GINTSTS_CURMODE                           (1 << 0)
+#define DWC2_GINTSTS_CURMODE_OFFSET                    0
+#define DWC2_GINTSTS_MODEMISMATCH                      (1 << 1)
+#define DWC2_GINTSTS_MODEMISMATCH_OFFSET               1
+#define DWC2_GINTSTS_OTGINTR                           (1 << 2)
+#define DWC2_GINTSTS_OTGINTR_OFFSET                    2
+#define DWC2_GINTSTS_SOFINTR                           (1 << 3)
+#define DWC2_GINTSTS_SOFINTR_OFFSET                    3
+#define DWC2_GINTSTS_RXSTSQLVL                         (1 << 4)
+#define DWC2_GINTSTS_RXSTSQLVL_OFFSET                  4
+#define DWC2_GINTSTS_NPTXFEMPTY                                (1 << 5)
+#define DWC2_GINTSTS_NPTXFEMPTY_OFFSET                 5
+#define DWC2_GINTSTS_GINNAKEFF                         (1 << 6)
+#define DWC2_GINTSTS_GINNAKEFF_OFFSET                  6
+#define DWC2_GINTSTS_GOUTNAKEFF                                (1 << 7)
+#define DWC2_GINTSTS_GOUTNAKEFF_OFFSET                 7
+#define DWC2_GINTSTS_I2CINTR                           (1 << 9)
+#define DWC2_GINTSTS_I2CINTR_OFFSET                    9
+#define DWC2_GINTSTS_ERLYSUSPEND                       (1 << 10)
+#define DWC2_GINTSTS_ERLYSUSPEND_OFFSET                        10
+#define DWC2_GINTSTS_USBSUSPEND                                (1 << 11)
+#define DWC2_GINTSTS_USBSUSPEND_OFFSET                 11
+#define DWC2_GINTSTS_USBRESET                          (1 << 12)
+#define DWC2_GINTSTS_USBRESET_OFFSET                   12
+#define DWC2_GINTSTS_ENUMDONE                          (1 << 13)
+#define DWC2_GINTSTS_ENUMDONE_OFFSET                   13
+#define DWC2_GINTSTS_ISOOUTDROP                                (1 << 14)
+#define DWC2_GINTSTS_ISOOUTDROP_OFFSET                 14
+#define DWC2_GINTSTS_EOPFRAME                          (1 << 15)
+#define DWC2_GINTSTS_EOPFRAME_OFFSET                   15
+#define DWC2_GINTSTS_INTOKENRX                         (1 << 16)
+#define DWC2_GINTSTS_INTOKENRX_OFFSET                  16
+#define DWC2_GINTSTS_EPMISMATCH                                (1 << 17)
+#define DWC2_GINTSTS_EPMISMATCH_OFFSET                 17
+#define DWC2_GINTSTS_INEPINT                           (1 << 18)
+#define DWC2_GINTSTS_INEPINT_OFFSET                    18
+#define DWC2_GINTSTS_OUTEPINTR                         (1 << 19)
+#define DWC2_GINTSTS_OUTEPINTR_OFFSET                  19
+#define DWC2_GINTSTS_INCOMPLISOIN                      (1 << 20)
+#define DWC2_GINTSTS_INCOMPLISOIN_OFFSET               20
+#define DWC2_GINTSTS_INCOMPLISOOUT                     (1 << 21)
+#define DWC2_GINTSTS_INCOMPLISOOUT_OFFSET              21
+#define DWC2_GINTSTS_PORTINTR                          (1 << 24)
+#define DWC2_GINTSTS_PORTINTR_OFFSET                   24
+#define DWC2_GINTSTS_HCINTR                            (1 << 25)
+#define DWC2_GINTSTS_HCINTR_OFFSET                     25
+#define DWC2_GINTSTS_PTXFEMPTY                         (1 << 26)
+#define DWC2_GINTSTS_PTXFEMPTY_OFFSET                  26
+#define DWC2_GINTSTS_LPMTRANRCVD                       (1 << 27)
+#define DWC2_GINTSTS_LPMTRANRCVD_OFFSET                        27
+#define DWC2_GINTSTS_CONIDSTSCHNG                      (1 << 28)
+#define DWC2_GINTSTS_CONIDSTSCHNG_OFFSET               28
+#define DWC2_GINTSTS_DISCONNECT                                (1 << 29)
+#define DWC2_GINTSTS_DISCONNECT_OFFSET                 29
+#define DWC2_GINTSTS_SESSREQINTR                       (1 << 30)
+#define DWC2_GINTSTS_SESSREQINTR_OFFSET                        30
+#define DWC2_GINTSTS_WKUPINTR                          (1 << 31)
+#define DWC2_GINTSTS_WKUPINTR_OFFSET                   31
+#define DWC2_GRXSTS_EPNUM_MASK                         (0xF << 0)
+#define DWC2_GRXSTS_EPNUM_OFFSET                       0
+#define DWC2_GRXSTS_BCNT_MASK                          (0x7FF << 4)
+#define DWC2_GRXSTS_BCNT_OFFSET                                4
+#define DWC2_GRXSTS_DPID_MASK                          (0x3 << 15)
+#define DWC2_GRXSTS_DPID_OFFSET                                15
+#define DWC2_GRXSTS_PKTSTS_MASK                                (0xF << 17)
+#define DWC2_GRXSTS_PKTSTS_OFFSET                      17
+#define DWC2_GRXSTS_FN_MASK                            (0xF << 21)
+#define DWC2_GRXSTS_FN_OFFSET                          21
+#define DWC2_FIFOSIZE_STARTADDR_MASK                   (0xFFFF << 0)
+#define DWC2_FIFOSIZE_STARTADDR_OFFSET                 0
+#define DWC2_FIFOSIZE_DEPTH_MASK                       (0xFFFF << 16)
+#define DWC2_FIFOSIZE_DEPTH_OFFSET                     16
+#define DWC2_GNPTXSTS_NPTXFSPCAVAIL_MASK               (0xFFFF << 0)
+#define DWC2_GNPTXSTS_NPTXFSPCAVAIL_OFFSET             0
+#define DWC2_GNPTXSTS_NPTXQSPCAVAIL_MASK               (0xFF << 16)
+#define DWC2_GNPTXSTS_NPTXQSPCAVAIL_OFFSET             16
+#define DWC2_GNPTXSTS_NPTXQTOP_TERMINATE               (1 << 24)
+#define DWC2_GNPTXSTS_NPTXQTOP_TERMINATE_OFFSET                24
+#define DWC2_GNPTXSTS_NPTXQTOP_TOKEN_MASK              (0x3 << 25)
+#define DWC2_GNPTXSTS_NPTXQTOP_TOKEN_OFFSET            25
+#define DWC2_GNPTXSTS_NPTXQTOP_CHNEP_MASK              (0xF << 27)
+#define DWC2_GNPTXSTS_NPTXQTOP_CHNEP_OFFSET            27
+#define DWC2_DTXFSTS_TXFSPCAVAIL_MASK                  (0xFFFF << 0)
+#define DWC2_DTXFSTS_TXFSPCAVAIL_OFFSET                        0
+#define DWC2_GI2CCTL_RWDATA_MASK                       (0xFF << 0)
+#define DWC2_GI2CCTL_RWDATA_OFFSET                     0
+#define DWC2_GI2CCTL_REGADDR_MASK                      (0xFF << 8)
+#define DWC2_GI2CCTL_REGADDR_OFFSET                    8
+#define DWC2_GI2CCTL_ADDR_MASK                         (0x7F << 16)
+#define DWC2_GI2CCTL_ADDR_OFFSET                       16
+#define DWC2_GI2CCTL_I2CEN                             (1 << 23)
+#define DWC2_GI2CCTL_I2CEN_OFFSET                      23
+#define DWC2_GI2CCTL_ACK                               (1 << 24)
+#define DWC2_GI2CCTL_ACK_OFFSET                                24
+#define DWC2_GI2CCTL_I2CSUSPCTL                                (1 << 25)
+#define DWC2_GI2CCTL_I2CSUSPCTL_OFFSET                 25
+#define DWC2_GI2CCTL_I2CDEVADDR_MASK                   (0x3 << 26)
+#define DWC2_GI2CCTL_I2CDEVADDR_OFFSET                 26
+#define DWC2_GI2CCTL_RW                                        (1 << 30)
+#define DWC2_GI2CCTL_RW_OFFSET                         30
+#define DWC2_GI2CCTL_BSYDNE                            (1 << 31)
+#define DWC2_GI2CCTL_BSYDNE_OFFSET                     31
+#define DWC2_HWCFG1_EP_DIR0_MASK                       (0x3 << 0)
+#define DWC2_HWCFG1_EP_DIR0_OFFSET                     0
+#define DWC2_HWCFG1_EP_DIR1_MASK                       (0x3 << 2)
+#define DWC2_HWCFG1_EP_DIR1_OFFSET                     2
+#define DWC2_HWCFG1_EP_DIR2_MASK                       (0x3 << 4)
+#define DWC2_HWCFG1_EP_DIR2_OFFSET                     4
+#define DWC2_HWCFG1_EP_DIR3_MASK                       (0x3 << 6)
+#define DWC2_HWCFG1_EP_DIR3_OFFSET                     6
+#define DWC2_HWCFG1_EP_DIR4_MASK                       (0x3 << 8)
+#define DWC2_HWCFG1_EP_DIR4_OFFSET                     8
+#define DWC2_HWCFG1_EP_DIR5_MASK                       (0x3 << 10)
+#define DWC2_HWCFG1_EP_DIR5_OFFSET                     10
+#define DWC2_HWCFG1_EP_DIR6_MASK                       (0x3 << 12)
+#define DWC2_HWCFG1_EP_DIR6_OFFSET                     12
+#define DWC2_HWCFG1_EP_DIR7_MASK                       (0x3 << 14)
+#define DWC2_HWCFG1_EP_DIR7_OFFSET                     14
+#define DWC2_HWCFG1_EP_DIR8_MASK                       (0x3 << 16)
+#define DWC2_HWCFG1_EP_DIR8_OFFSET                     16
+#define DWC2_HWCFG1_EP_DIR9_MASK                       (0x3 << 18)
+#define DWC2_HWCFG1_EP_DIR9_OFFSET                     18
+#define DWC2_HWCFG1_EP_DIR10_MASK                      (0x3 << 20)
+#define DWC2_HWCFG1_EP_DIR10_OFFSET                    20
+#define DWC2_HWCFG1_EP_DIR11_MASK                      (0x3 << 22)
+#define DWC2_HWCFG1_EP_DIR11_OFFSET                    22
+#define DWC2_HWCFG1_EP_DIR12_MASK                      (0x3 << 24)
+#define DWC2_HWCFG1_EP_DIR12_OFFSET                    24
+#define DWC2_HWCFG1_EP_DIR13_MASK                      (0x3 << 26)
+#define DWC2_HWCFG1_EP_DIR13_OFFSET                    26
+#define DWC2_HWCFG1_EP_DIR14_MASK                      (0x3 << 28)
+#define DWC2_HWCFG1_EP_DIR14_OFFSET                    28
+#define DWC2_HWCFG1_EP_DIR15_MASK                      (0x3 << 30)
+#define DWC2_HWCFG1_EP_DIR15_OFFSET                    30
+#define DWC2_HWCFG2_OP_MODE_MASK                       (0x7 << 0)
+#define DWC2_HWCFG2_OP_MODE_OFFSET                     0
+#define DWC2_HWCFG2_ARCHITECTURE_SLAVE_ONLY            (0x0 << 3)
+#define DWC2_HWCFG2_ARCHITECTURE_EXT_DMA               (0x1 << 3)
+#define DWC2_HWCFG2_ARCHITECTURE_INT_DMA               (0x2 << 3)
+#define DWC2_HWCFG2_ARCHITECTURE_MASK                  (0x3 << 3)
+#define DWC2_HWCFG2_ARCHITECTURE_OFFSET                        3
+#define DWC2_HWCFG2_POINT2POINT                                (1 << 5)
+#define DWC2_HWCFG2_POINT2POINT_OFFSET                 5
+#define DWC2_HWCFG2_HS_PHY_TYPE_MASK                   (0x3 << 6)
+#define DWC2_HWCFG2_HS_PHY_TYPE_OFFSET                 6
+#define DWC2_HWCFG2_FS_PHY_TYPE_MASK                   (0x3 << 8)
+#define DWC2_HWCFG2_FS_PHY_TYPE_OFFSET                 8
+#define DWC2_HWCFG2_NUM_DEV_EP_MASK                    (0xF << 10)
+#define DWC2_HWCFG2_NUM_DEV_EP_OFFSET                  10
+#define DWC2_HWCFG2_NUM_HOST_CHAN_MASK                 (0xF << 14)
+#define DWC2_HWCFG2_NUM_HOST_CHAN_OFFSET               14
+#define DWC2_HWCFG2_PERIO_EP_SUPPORTED                 (1 << 18)
+#define DWC2_HWCFG2_PERIO_EP_SUPPORTED_OFFSET          18
+#define DWC2_HWCFG2_DYNAMIC_FIFO                       (1 << 19)
+#define DWC2_HWCFG2_DYNAMIC_FIFO_OFFSET                        19
+#define DWC2_HWCFG2_MULTI_PROC_INT                     (1 << 20)
+#define DWC2_HWCFG2_MULTI_PROC_INT_OFFSET              20
+#define DWC2_HWCFG2_NONPERIO_TX_Q_DEPTH_MASK           (0x3 << 22)
+#define DWC2_HWCFG2_NONPERIO_TX_Q_DEPTH_OFFSET         22
+#define DWC2_HWCFG2_HOST_PERIO_TX_Q_DEPTH_MASK         (0x3 << 24)
+#define DWC2_HWCFG2_HOST_PERIO_TX_Q_DEPTH_OFFSET       24
+#define DWC2_HWCFG2_DEV_TOKEN_Q_DEPTH_MASK             (0x1F << 26)
+#define DWC2_HWCFG2_DEV_TOKEN_Q_DEPTH_OFFSET           26
+#define DWC2_HWCFG3_XFER_SIZE_CNTR_WIDTH_MASK          (0xF << 0)
+#define DWC2_HWCFG3_XFER_SIZE_CNTR_WIDTH_OFFSET                0
+#define DWC2_HWCFG3_PACKET_SIZE_CNTR_WIDTH_MASK                (0x7 << 4)
+#define DWC2_HWCFG3_PACKET_SIZE_CNTR_WIDTH_OFFSET      4
+#define DWC2_HWCFG3_OTG_FUNC                           (1 << 7)
+#define DWC2_HWCFG3_OTG_FUNC_OFFSET                    7
+#define DWC2_HWCFG3_I2C                                        (1 << 8)
+#define DWC2_HWCFG3_I2C_OFFSET                         8
+#define DWC2_HWCFG3_VENDOR_CTRL_IF                     (1 << 9)
+#define DWC2_HWCFG3_VENDOR_CTRL_IF_OFFSET              9
+#define DWC2_HWCFG3_OPTIONAL_FEATURES                  (1 << 10)
+#define DWC2_HWCFG3_OPTIONAL_FEATURES_OFFSET           10
+#define DWC2_HWCFG3_SYNCH_RESET_TYPE                   (1 << 11)
+#define DWC2_HWCFG3_SYNCH_RESET_TYPE_OFFSET            11
+#define DWC2_HWCFG3_OTG_ENABLE_IC_USB                  (1 << 12)
+#define DWC2_HWCFG3_OTG_ENABLE_IC_USB_OFFSET           12
+#define DWC2_HWCFG3_OTG_ENABLE_HSIC                    (1 << 13)
+#define DWC2_HWCFG3_OTG_ENABLE_HSIC_OFFSET             13
+#define DWC2_HWCFG3_OTG_LPM_EN                         (1 << 15)
+#define DWC2_HWCFG3_OTG_LPM_EN_OFFSET                  15
+#define DWC2_HWCFG3_DFIFO_DEPTH_MASK                   (0xFFFF << 16)
+#define DWC2_HWCFG3_DFIFO_DEPTH_OFFSET                 16
+#define DWC2_HWCFG4_NUM_DEV_PERIO_IN_EP_MASK           (0xF << 0)
+#define DWC2_HWCFG4_NUM_DEV_PERIO_IN_EP_OFFSET         0
+#define DWC2_HWCFG4_POWER_OPTIMIZ                      (1 << 4)
+#define DWC2_HWCFG4_POWER_OPTIMIZ_OFFSET               4
+#define DWC2_HWCFG4_MIN_AHB_FREQ_MASK                  (0x1FF << 5)
+#define DWC2_HWCFG4_MIN_AHB_FREQ_OFFSET                        5
+#define DWC2_HWCFG4_UTMI_PHY_DATA_WIDTH_MASK           (0x3 << 14)
+#define DWC2_HWCFG4_UTMI_PHY_DATA_WIDTH_OFFSET         14
+#define DWC2_HWCFG4_NUM_DEV_MODE_CTRL_EP_MASK          (0xF << 16)
+#define DWC2_HWCFG4_NUM_DEV_MODE_CTRL_EP_OFFSET                16
+#define DWC2_HWCFG4_IDDIG_FILT_EN                      (1 << 20)
+#define DWC2_HWCFG4_IDDIG_FILT_EN_OFFSET               20
+#define DWC2_HWCFG4_VBUS_VALID_FILT_EN                 (1 << 21)
+#define DWC2_HWCFG4_VBUS_VALID_FILT_EN_OFFSET          21
+#define DWC2_HWCFG4_A_VALID_FILT_EN                    (1 << 22)
+#define DWC2_HWCFG4_A_VALID_FILT_EN_OFFSET             22
+#define DWC2_HWCFG4_B_VALID_FILT_EN                    (1 << 23)
+#define DWC2_HWCFG4_B_VALID_FILT_EN_OFFSET             23
+#define DWC2_HWCFG4_SESSION_END_FILT_EN                        (1 << 24)
+#define DWC2_HWCFG4_SESSION_END_FILT_EN_OFFSET         24
+#define DWC2_HWCFG4_DED_FIFO_EN                                (1 << 25)
+#define DWC2_HWCFG4_DED_FIFO_EN_OFFSET                 25
+#define DWC2_HWCFG4_NUM_IN_EPS_MASK                    (0xF << 26)
+#define DWC2_HWCFG4_NUM_IN_EPS_OFFSET                  26
+#define DWC2_HWCFG4_DESC_DMA                           (1 << 30)
+#define DWC2_HWCFG4_DESC_DMA_OFFSET                    30
+#define DWC2_HWCFG4_DESC_DMA_DYN                       (1 << 31)
+#define DWC2_HWCFG4_DESC_DMA_DYN_OFFSET                        31
+#define DWC2_HCFG_FSLSPCLKSEL_30_60_MHZ                        0
+#define DWC2_HCFG_FSLSPCLKSEL_48_MHZ                   1
+#define DWC2_HCFG_FSLSPCLKSEL_6_MHZ                    2
+#define DWC2_HCFG_FSLSPCLKSEL_MASK                     (0x3 << 0)
+#define DWC2_HCFG_FSLSPCLKSEL_OFFSET                   0
+#define DWC2_HCFG_FSLSSUPP                             (1 << 2)
+#define DWC2_HCFG_FSLSSUPP_OFFSET                      2
+#define DWC2_HCFG_DESCDMA                              (1 << 23)
+#define DWC2_HCFG_DESCDMA_OFFSET                       23
+#define DWC2_HCFG_FRLISTEN_MASK                                (0x3 << 24)
+#define DWC2_HCFG_FRLISTEN_OFFSET                      24
+#define DWC2_HCFG_PERSCHEDENA                          (1 << 26)
+#define DWC2_HCFG_PERSCHEDENA_OFFSET                   26
+#define DWC2_HCFG_PERSCHEDSTAT                         (1 << 27)
+#define DWC2_HCFG_PERSCHEDSTAT_OFFSET                  27
+#define DWC2_HFIR_FRINT_MASK                           (0xFFFF << 0)
+#define DWC2_HFIR_FRINT_OFFSET                         0
+#define DWC2_HFNUM_FRNUM_MASK                          (0xFFFF << 0)
+#define DWC2_HFNUM_FRNUM_OFFSET                                0
+#define DWC2_HFNUM_FRREM_MASK                          (0xFFFF << 16)
+#define DWC2_HFNUM_FRREM_OFFSET                                16
+#define DWC2_HPTXSTS_PTXFSPCAVAIL_MASK                 (0xFFFF << 0)
+#define DWC2_HPTXSTS_PTXFSPCAVAIL_OFFSET               0
+#define DWC2_HPTXSTS_PTXQSPCAVAIL_MASK                 (0xFF << 16)
+#define DWC2_HPTXSTS_PTXQSPCAVAIL_OFFSET               16
+#define DWC2_HPTXSTS_PTXQTOP_TERMINATE                 (1 << 24)
+#define DWC2_HPTXSTS_PTXQTOP_TERMINATE_OFFSET          24
+#define DWC2_HPTXSTS_PTXQTOP_TOKEN_MASK                        (0x3 << 25)
+#define DWC2_HPTXSTS_PTXQTOP_TOKEN_OFFSET              25
+#define DWC2_HPTXSTS_PTXQTOP_CHNUM_MASK                        (0xF << 27)
+#define DWC2_HPTXSTS_PTXQTOP_CHNUM_OFFSET              27
+#define DWC2_HPTXSTS_PTXQTOP_ODD                       (1 << 31)
+#define DWC2_HPTXSTS_PTXQTOP_ODD_OFFSET                        31
+#define DWC2_HPRT0_PRTCONNSTS                          (1 << 0)
+#define DWC2_HPRT0_PRTCONNSTS_OFFSET                   0
+#define DWC2_HPRT0_PRTCONNDET                          (1 << 1)
+#define DWC2_HPRT0_PRTCONNDET_OFFSET                   1
+#define DWC2_HPRT0_PRTENA                              (1 << 2)
+#define DWC2_HPRT0_PRTENA_OFFSET                       2
+#define DWC2_HPRT0_PRTENCHNG                           (1 << 3)
+#define DWC2_HPRT0_PRTENCHNG_OFFSET                    3
+#define DWC2_HPRT0_PRTOVRCURRACT                       (1 << 4)
+#define DWC2_HPRT0_PRTOVRCURRACT_OFFSET                        4
+#define DWC2_HPRT0_PRTOVRCURRCHNG                      (1 << 5)
+#define DWC2_HPRT0_PRTOVRCURRCHNG_OFFSET               5
+#define DWC2_HPRT0_PRTRES                              (1 << 6)
+#define DWC2_HPRT0_PRTRES_OFFSET                       6
+#define DWC2_HPRT0_PRTSUSP                             (1 << 7)
+#define DWC2_HPRT0_PRTSUSP_OFFSET                      7
+#define DWC2_HPRT0_PRTRST                              (1 << 8)
+#define DWC2_HPRT0_PRTRST_OFFSET                       8
+#define DWC2_HPRT0_PRTLNSTS_MASK                       (0x3 << 10)
+#define DWC2_HPRT0_PRTLNSTS_OFFSET                     10
+#define DWC2_HPRT0_PRTPWR                              (1 << 12)
+#define DWC2_HPRT0_PRTPWR_OFFSET                       12
+#define DWC2_HPRT0_PRTTSTCTL_MASK                      (0xF << 13)
+#define DWC2_HPRT0_PRTTSTCTL_OFFSET                    13
+#define DWC2_HPRT0_PRTSPD_MASK                         (0x3 << 17)
+#define DWC2_HPRT0_PRTSPD_OFFSET                       17
+#define DWC2_HAINT_CH0                                 (1 << 0)
+#define DWC2_HAINT_CH0_OFFSET                          0
+#define DWC2_HAINT_CH1                                 (1 << 1)
+#define DWC2_HAINT_CH1_OFFSET                          1
+#define DWC2_HAINT_CH2                                 (1 << 2)
+#define DWC2_HAINT_CH2_OFFSET                          2
+#define DWC2_HAINT_CH3                                 (1 << 3)
+#define DWC2_HAINT_CH3_OFFSET                          3
+#define DWC2_HAINT_CH4                                 (1 << 4)
+#define DWC2_HAINT_CH4_OFFSET                          4
+#define DWC2_HAINT_CH5                                 (1 << 5)
+#define DWC2_HAINT_CH5_OFFSET                          5
+#define DWC2_HAINT_CH6                                 (1 << 6)
+#define DWC2_HAINT_CH6_OFFSET                          6
+#define DWC2_HAINT_CH7                                 (1 << 7)
+#define DWC2_HAINT_CH7_OFFSET                          7
+#define DWC2_HAINT_CH8                                 (1 << 8)
+#define DWC2_HAINT_CH8_OFFSET                          8
+#define DWC2_HAINT_CH9                                 (1 << 9)
+#define DWC2_HAINT_CH9_OFFSET                          9
+#define DWC2_HAINT_CH10                                        (1 << 10)
+#define DWC2_HAINT_CH10_OFFSET                         10
+#define DWC2_HAINT_CH11                                        (1 << 11)
+#define DWC2_HAINT_CH11_OFFSET                         11
+#define DWC2_HAINT_CH12                                        (1 << 12)
+#define DWC2_HAINT_CH12_OFFSET                         12
+#define DWC2_HAINT_CH13                                        (1 << 13)
+#define DWC2_HAINT_CH13_OFFSET                         13
+#define DWC2_HAINT_CH14                                        (1 << 14)
+#define DWC2_HAINT_CH14_OFFSET                         14
+#define DWC2_HAINT_CH15                                        (1 << 15)
+#define DWC2_HAINT_CH15_OFFSET                         15
+#define DWC2_HAINT_CHINT_MASK                          0xffff
+#define DWC2_HAINT_CHINT_OFFSET                                0
+#define DWC2_HAINTMSK_CH0                              (1 << 0)
+#define DWC2_HAINTMSK_CH0_OFFSET                       0
+#define DWC2_HAINTMSK_CH1                              (1 << 1)
+#define DWC2_HAINTMSK_CH1_OFFSET                       1
+#define DWC2_HAINTMSK_CH2                              (1 << 2)
+#define DWC2_HAINTMSK_CH2_OFFSET                       2
+#define DWC2_HAINTMSK_CH3                              (1 << 3)
+#define DWC2_HAINTMSK_CH3_OFFSET                       3
+#define DWC2_HAINTMSK_CH4                              (1 << 4)
+#define DWC2_HAINTMSK_CH4_OFFSET                       4
+#define DWC2_HAINTMSK_CH5                              (1 << 5)
+#define DWC2_HAINTMSK_CH5_OFFSET                       5
+#define DWC2_HAINTMSK_CH6                              (1 << 6)
+#define DWC2_HAINTMSK_CH6_OFFSET                       6
+#define DWC2_HAINTMSK_CH7                              (1 << 7)
+#define DWC2_HAINTMSK_CH7_OFFSET                       7
+#define DWC2_HAINTMSK_CH8                              (1 << 8)
+#define DWC2_HAINTMSK_CH8_OFFSET                       8
+#define DWC2_HAINTMSK_CH9                              (1 << 9)
+#define DWC2_HAINTMSK_CH9_OFFSET                       9
+#define DWC2_HAINTMSK_CH10                             (1 << 10)
+#define DWC2_HAINTMSK_CH10_OFFSET                      10
+#define DWC2_HAINTMSK_CH11                             (1 << 11)
+#define DWC2_HAINTMSK_CH11_OFFSET                      11
+#define DWC2_HAINTMSK_CH12                             (1 << 12)
+#define DWC2_HAINTMSK_CH12_OFFSET                      12
+#define DWC2_HAINTMSK_CH13                             (1 << 13)
+#define DWC2_HAINTMSK_CH13_OFFSET                      13
+#define DWC2_HAINTMSK_CH14                             (1 << 14)
+#define DWC2_HAINTMSK_CH14_OFFSET                      14
+#define DWC2_HAINTMSK_CH15                             (1 << 15)
+#define DWC2_HAINTMSK_CH15_OFFSET                      15
+#define DWC2_HAINTMSK_CHINT_MASK                       0xffff
+#define DWC2_HAINTMSK_CHINT_OFFSET                     0
+#define DWC2_HCCHAR_MPS_MASK                           (0x7FF << 0)
+#define DWC2_HCCHAR_MPS_OFFSET                         0
+#define DWC2_HCCHAR_EPNUM_MASK                         (0xF << 11)
+#define DWC2_HCCHAR_EPNUM_OFFSET                       11
+#define DWC2_HCCHAR_EPDIR                              (1 << 15)
+#define DWC2_HCCHAR_EPDIR_OFFSET                       15
+#define DWC2_HCCHAR_LSPDDEV                            (1 << 17)
+#define DWC2_HCCHAR_LSPDDEV_OFFSET                     17
+#define DWC2_HCCHAR_EPTYPE_CONTROL                     0
+#define DWC2_HCCHAR_EPTYPE_ISOC                                1
+#define DWC2_HCCHAR_EPTYPE_BULK                                2
+#define DWC2_HCCHAR_EPTYPE_INTR                                3
+#define DWC2_HCCHAR_EPTYPE_MASK                                (0x3 << 18)
+#define DWC2_HCCHAR_EPTYPE_OFFSET                      18
+#define DWC2_HCCHAR_MULTICNT_MASK                      (0x3 << 20)
+#define DWC2_HCCHAR_MULTICNT_OFFSET                    20
+#define DWC2_HCCHAR_DEVADDR_MASK                       (0x7F << 22)
+#define DWC2_HCCHAR_DEVADDR_OFFSET                     22
+#define DWC2_HCCHAR_ODDFRM                             (1 << 29)
+#define DWC2_HCCHAR_ODDFRM_OFFSET                      29
+#define DWC2_HCCHAR_CHDIS                              (1 << 30)
+#define DWC2_HCCHAR_CHDIS_OFFSET                       30
+#define DWC2_HCCHAR_CHEN                               (1 << 31)
+#define DWC2_HCCHAR_CHEN_OFFSET                                31
+#define DWC2_HCSPLT_PRTADDR_MASK                       (0x7F << 0)
+#define DWC2_HCSPLT_PRTADDR_OFFSET                     0
+#define DWC2_HCSPLT_HUBADDR_MASK                       (0x7F << 7)
+#define DWC2_HCSPLT_HUBADDR_OFFSET                     7
+#define DWC2_HCSPLT_XACTPOS_MASK                       (0x3 << 14)
+#define DWC2_HCSPLT_XACTPOS_OFFSET                     14
+#define DWC2_HCSPLT_COMPSPLT                           (1 << 16)
+#define DWC2_HCSPLT_COMPSPLT_OFFSET                    16
+#define DWC2_HCSPLT_SPLTENA                            (1 << 31)
+#define DWC2_HCSPLT_SPLTENA_OFFSET                     31
+#define DWC2_HCINT_XFERCOMP                            (1 << 0)
+#define DWC2_HCINT_XFERCOMP_OFFSET                     0
+#define DWC2_HCINT_CHHLTD                              (1 << 1)
+#define DWC2_HCINT_CHHLTD_OFFSET                       1
+#define DWC2_HCINT_AHBERR                              (1 << 2)
+#define DWC2_HCINT_AHBERR_OFFSET                       2
+#define DWC2_HCINT_STALL                               (1 << 3)
+#define DWC2_HCINT_STALL_OFFSET                                3
+#define DWC2_HCINT_NAK                                 (1 << 4)
+#define DWC2_HCINT_NAK_OFFSET                          4
+#define DWC2_HCINT_ACK                                 (1 << 5)
+#define DWC2_HCINT_ACK_OFFSET                          5
+#define DWC2_HCINT_NYET                                        (1 << 6)
+#define DWC2_HCINT_NYET_OFFSET                         6
+#define DWC2_HCINT_XACTERR                             (1 << 7)
+#define DWC2_HCINT_XACTERR_OFFSET                      7
+#define DWC2_HCINT_BBLERR                              (1 << 8)
+#define DWC2_HCINT_BBLERR_OFFSET                       8
+#define DWC2_HCINT_FRMOVRUN                            (1 << 9)
+#define DWC2_HCINT_FRMOVRUN_OFFSET                     9
+#define DWC2_HCINT_DATATGLERR                          (1 << 10)
+#define DWC2_HCINT_DATATGLERR_OFFSET                   10
+#define DWC2_HCINT_BNA                                 (1 << 11)
+#define DWC2_HCINT_BNA_OFFSET                          11
+#define DWC2_HCINT_XCS_XACT                            (1 << 12)
+#define DWC2_HCINT_XCS_XACT_OFFSET                     12
+#define DWC2_HCINT_FRM_LIST_ROLL                       (1 << 13)
+#define DWC2_HCINT_FRM_LIST_ROLL_OFFSET                        13
+#define DWC2_HCINTMSK_XFERCOMPL                                (1 << 0)
+#define DWC2_HCINTMSK_XFERCOMPL_OFFSET                 0
+#define DWC2_HCINTMSK_CHHLTD                           (1 << 1)
+#define DWC2_HCINTMSK_CHHLTD_OFFSET                    1
+#define DWC2_HCINTMSK_AHBERR                           (1 << 2)
+#define DWC2_HCINTMSK_AHBERR_OFFSET                    2
+#define DWC2_HCINTMSK_STALL                            (1 << 3)
+#define DWC2_HCINTMSK_STALL_OFFSET                     3
+#define DWC2_HCINTMSK_NAK                              (1 << 4)
+#define DWC2_HCINTMSK_NAK_OFFSET                       4
+#define DWC2_HCINTMSK_ACK                              (1 << 5)
+#define DWC2_HCINTMSK_ACK_OFFSET                       5
+#define DWC2_HCINTMSK_NYET                             (1 << 6)
+#define DWC2_HCINTMSK_NYET_OFFSET                      6
+#define DWC2_HCINTMSK_XACTERR                          (1 << 7)
+#define DWC2_HCINTMSK_XACTERR_OFFSET                   7
+#define DWC2_HCINTMSK_BBLERR                           (1 << 8)
+#define DWC2_HCINTMSK_BBLERR_OFFSET                    8
+#define DWC2_HCINTMSK_FRMOVRUN                         (1 << 9)
+#define DWC2_HCINTMSK_FRMOVRUN_OFFSET                  9
+#define DWC2_HCINTMSK_DATATGLERR                       (1 << 10)
+#define DWC2_HCINTMSK_DATATGLERR_OFFSET                        10
+#define DWC2_HCINTMSK_BNA                              (1 << 11)
+#define DWC2_HCINTMSK_BNA_OFFSET                       11
+#define DWC2_HCINTMSK_XCS_XACT                         (1 << 12)
+#define DWC2_HCINTMSK_XCS_XACT_OFFSET                  12
+#define DWC2_HCINTMSK_FRM_LIST_ROLL                    (1 << 13)
+#define DWC2_HCINTMSK_FRM_LIST_ROLL_OFFSET             13
+#define DWC2_HCTSIZ_XFERSIZE_MASK                      0x7ffff
+#define DWC2_HCTSIZ_XFERSIZE_OFFSET                    0
+#define DWC2_HCTSIZ_SCHINFO_MASK                       0xff
+#define DWC2_HCTSIZ_SCHINFO_OFFSET                     0
+#define DWC2_HCTSIZ_NTD_MASK                           (0xff << 8)
+#define DWC2_HCTSIZ_NTD_OFFSET                         8
+#define DWC2_HCTSIZ_PKTCNT_MASK                                (0x3ff << 19)
+#define DWC2_HCTSIZ_PKTCNT_OFFSET                      19
+#define DWC2_HCTSIZ_PID_MASK                           (0x3 << 29)
+#define DWC2_HCTSIZ_PID_OFFSET                         29
+#define DWC2_HCTSIZ_DOPNG                              (1 << 31)
+#define DWC2_HCTSIZ_DOPNG_OFFSET                       31
+#define DWC2_HCDMA_CTD_MASK                            (0xFF << 3)
+#define DWC2_HCDMA_CTD_OFFSET                          3
+#define DWC2_HCDMA_DMA_ADDR_MASK                       (0x1FFFFF << 11)
+#define DWC2_HCDMA_DMA_ADDR_OFFSET                     11
+#define DWC2_PCGCCTL_STOPPCLK                          (1 << 0)
+#define DWC2_PCGCCTL_STOPPCLK_OFFSET                   0
+#define DWC2_PCGCCTL_GATEHCLK                          (1 << 1)
+#define DWC2_PCGCCTL_GATEHCLK_OFFSET                   1
+#define DWC2_PCGCCTL_PWRCLMP                           (1 << 2)
+#define DWC2_PCGCCTL_PWRCLMP_OFFSET                    2
+#define DWC2_PCGCCTL_RSTPDWNMODULE                     (1 << 3)
+#define DWC2_PCGCCTL_RSTPDWNMODULE_OFFSET              3
+#define DWC2_PCGCCTL_PHYSUSPENDED                      (1 << 4)
+#define DWC2_PCGCCTL_PHYSUSPENDED_OFFSET               4
+#define DWC2_PCGCCTL_ENBL_SLEEP_GATING                 (1 << 5)
+#define DWC2_PCGCCTL_ENBL_SLEEP_GATING_OFFSET          5
+#define DWC2_PCGCCTL_PHY_IN_SLEEP                      (1 << 6)
+#define DWC2_PCGCCTL_PHY_IN_SLEEP_OFFSET               6
+#define DWC2_PCGCCTL_DEEP_SLEEP                                (1 << 7)
+#define DWC2_PCGCCTL_DEEP_SLEEP_OFFSET                 7
+#define DWC2_SNPSID_DEVID_VER_2xx                      (0x4f542 << 12)
+#define DWC2_SNPSID_DEVID_MASK                         (0xfffff << 12)
+#define DWC2_SNPSID_DEVID_OFFSET                       12
+
+/* Host controller specific */
+#define DWC2_HC_PID_DATA0              0
+#define DWC2_HC_PID_DATA2              1
+#define DWC2_HC_PID_DATA1              2
+#define DWC2_HC_PID_MDATA              3
+#define DWC2_HC_PID_SETUP              3
+
+/* roothub.a masks */
+#define RH_A_NDP       (0xff << 0)     /* number of downstream ports */
+#define RH_A_PSM       (1 << 8)        /* power switching mode */
+#define RH_A_NPS       (1 << 9)        /* no power switching */
+#define RH_A_DT                (1 << 10)       /* device type (mbz) */
+#define RH_A_OCPM      (1 << 11)       /* over current protection mode */
+#define RH_A_NOCP      (1 << 12)       /* no over current protection */
+#define RH_A_POTPGT    (0xff << 24)    /* power on to power good time */
+
+/* roothub.b masks */
+#define RH_B_DR                0x0000ffff      /* device removable flags */
+#define RH_B_PPCM      0xffff0000      /* port power control mask */
+
+/* Default driver configuration */
+#define CONFIG_DWC2_DMA_ENABLE
+#define CONFIG_DWC2_DMA_BURST_SIZE             32      /* DMA burst len */
+#undef CONFIG_DWC2_DFLT_SPEED_FULL             /* Do not force DWC2 to FS */
+#define CONFIG_DWC2_ENABLE_DYNAMIC_FIFO                /* Runtime FIFO size detect */
+#define CONFIG_DWC2_MAX_CHANNELS               16      /* Max # of EPs */
+#define CONFIG_DWC2_HOST_RX_FIFO_SIZE          (516 + CONFIG_DWC2_MAX_CHANNELS)
+#define CONFIG_DWC2_HOST_NPERIO_TX_FIFO_SIZE   0x100   /* nPeriodic TX FIFO */
+#define CONFIG_DWC2_HOST_PERIO_TX_FIFO_SIZE    0x200   /* Periodic TX FIFO */
+#define CONFIG_DWC2_MAX_TRANSFER_SIZE          65535
+#define CONFIG_DWC2_MAX_PACKET_COUNT           511
+
+#define DWC2_PHY_TYPE_FS               0
+#define DWC2_PHY_TYPE_UTMI             1
+#define DWC2_PHY_TYPE_ULPI             2
+#define CONFIG_DWC2_PHY_TYPE           DWC2_PHY_TYPE_UTMI      /* PHY type */
+#define CONFIG_DWC2_UTMI_WIDTH         8       /* UTMI bus width (8/16) */
+
+#undef CONFIG_DWC2_PHY_ULPI_DDR                        /* ULPI PHY uses DDR mode */
+#define CONFIG_DWC2_PHY_ULPI_EXT_VBUS          /* ULPI PHY controls VBUS */
+#undef CONFIG_DWC2_I2C_ENABLE                  /* Enable I2C */
+#undef CONFIG_DWC2_ULPI_FS_LS                  /* ULPI is FS/LS */
+#undef CONFIG_DWC2_TS_DLINE                    /* External DLine pulsing */
+#undef CONFIG_DWC2_THR_CTL                     /* Threshold control */
+#define CONFIG_DWC2_TX_THR_LENGTH              64
+#undef CONFIG_DWC2_IC_USB_CAP                  /* IC Cap */
+
+#endif /* __DWC2_H__ */
index 6323c508375af8ce3b98009a85bfbc2f5e8a5564..936d006ba414ca2bfea76ac5ab0b0d5dccc944ab 100644 (file)
@@ -119,15 +119,12 @@ static struct descriptor {
 #define ehci_is_TDI()  (0)
 #endif
 
-int __ehci_get_port_speed(struct ehci_hcor *hcor, uint32_t reg)
+__weak int ehci_get_port_speed(struct ehci_hcor *hcor, uint32_t reg)
 {
        return PORTSC_PSPD(reg);
 }
 
-int ehci_get_port_speed(struct ehci_hcor *hcor, uint32_t reg)
-       __attribute__((weak, alias("__ehci_get_port_speed")));
-
-void __ehci_set_usbmode(int index)
+__weak void ehci_set_usbmode(int index)
 {
        uint32_t tmp;
        uint32_t *reg_ptr;
@@ -141,17 +138,11 @@ void __ehci_set_usbmode(int index)
        ehci_writel(reg_ptr, tmp);
 }
 
-void ehci_set_usbmode(int index)
-       __attribute__((weak, alias("__ehci_set_usbmode")));
-
-void __ehci_powerup_fixup(uint32_t *status_reg, uint32_t *reg)
+__weak void ehci_powerup_fixup(uint32_t *status_reg, uint32_t *reg)
 {
        mdelay(50);
 }
 
-void ehci_powerup_fixup(uint32_t *status_reg, uint32_t *reg)
-       __attribute__((weak, alias("__ehci_powerup_fixup")));
-
 static int handshake(uint32_t *ptr, uint32_t mask, uint32_t done, int usec)
 {
        uint32_t result;
@@ -1323,7 +1314,7 @@ void *poll_int_queue(struct usb_device *dev, struct int_queue *queue)
 }
 
 /* Do not free buffers associated with QHs, they're owned by someone else */
-int
+static int
 destroy_int_queue(struct usb_device *dev, struct int_queue *queue)
 {
        struct ehci_ctrl *ctrl = dev->controller;
index 52c43fdc5aaa1fdc2a99ed3177c65c35b3a2c979..1a5fd6eefc296bfee80552530cbb7237dffd3792 100644 (file)
@@ -13,7 +13,7 @@
 #include <asm/arch/cpu.h>
 
 #if defined(CONFIG_KIRKWOOD)
-#include <asm/arch/kirkwood.h>
+#include <asm/arch/soc.h>
 #elif defined(CONFIG_ORION5X)
 #include <asm/arch/orion5x.h>
 #endif
diff --git a/drivers/usb/host/xhci-keystone.c b/drivers/usb/host/xhci-keystone.c
new file mode 100644 (file)
index 0000000..05d338f
--- /dev/null
@@ -0,0 +1,329 @@
+/*
+ * USB 3.0 DRD Controller
+ *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include <watchdog.h>
+#include <usb.h>
+#include <asm/arch/psc_defs.h>
+#include <asm/io.h>
+#include <linux/usb/dwc3.h>
+#include <asm/arch/xhci-keystone.h>
+#include <asm-generic/errno.h>
+#include <linux/list.h>
+#include "xhci.h"
+
+struct kdwc3_irq_regs {
+       u32 revision;   /* 0x000 */
+       u32 rsvd0[3];
+       u32 sysconfig;  /* 0x010 */
+       u32 rsvd1[1];
+       u32 irq_eoi;
+       u32 rsvd2[1];
+       struct {
+               u32 raw_status;
+               u32 status;
+               u32 enable_set;
+               u32 enable_clr;
+       } irqs[16];
+};
+
+struct keystone_xhci {
+       struct xhci_hccr *hcd;
+       struct dwc3 *dwc3_reg;
+       struct xhci_hcor *hcor;
+       struct kdwc3_irq_regs *usbss;
+       struct keystone_xhci_phy *phy;
+};
+
+struct keystone_xhci keystone;
+
+static void keystone_xhci_phy_set(struct keystone_xhci_phy *phy)
+{
+       u32 val;
+
+       /*
+        * VBUSVLDEXTSEL has a default value of 1 in BootCfg but shouldn't.
+        * It should always be cleared because our USB PHY has an onchip VBUS
+        * analog comparator.
+        */
+       val = readl(&phy->phy_clock);
+       /* quit selecting the vbusvldextsel by default! */
+       val &= ~USB3_PHY_OTG_VBUSVLDECTSEL;
+       writel(val, &phy->phy_clock);
+}
+
+static void keystone_xhci_phy_unset(struct keystone_xhci_phy *phy)
+{
+       u32 val;
+
+       /* Disable the PHY REFCLK clock gate */
+       val = readl(&phy->phy_clock);
+       val &= ~USB3_PHY_REF_SSP_EN;
+       writel(val, &phy->phy_clock);
+}
+
+static void dwc3_set_mode(struct dwc3 *dwc3_reg, u32 mode)
+{
+       clrsetbits_le32(&dwc3_reg->g_ctl,
+                       DWC3_GCTL_PRTCAPDIR(DWC3_GCTL_PRTCAP_OTG),
+                       DWC3_GCTL_PRTCAPDIR(mode));
+}
+
+static void dwc3_core_soft_reset(struct dwc3 *dwc3_reg)
+{
+       /* Before Resetting PHY, put Core in Reset */
+       setbits_le32(&dwc3_reg->g_ctl, DWC3_GCTL_CORESOFTRESET);
+
+       /* Assert USB3 PHY reset */
+       setbits_le32(&dwc3_reg->g_usb3pipectl[0], DWC3_GUSB3PIPECTL_PHYSOFTRST);
+
+       /* Assert USB2 PHY reset */
+       setbits_le32(&dwc3_reg->g_usb2phycfg[0], DWC3_GUSB2PHYCFG_PHYSOFTRST);
+
+       mdelay(100);
+
+       /* Clear USB3 PHY reset */
+       clrbits_le32(&dwc3_reg->g_usb3pipectl[0], DWC3_GUSB3PIPECTL_PHYSOFTRST);
+
+       /* Clear USB2 PHY reset */
+       clrbits_le32(&dwc3_reg->g_usb2phycfg[0], DWC3_GUSB2PHYCFG_PHYSOFTRST);
+
+       /* After PHYs are stable we can take Core out of reset state */
+       clrbits_le32(&dwc3_reg->g_ctl, DWC3_GCTL_CORESOFTRESET);
+}
+
+static int dwc3_core_init(struct dwc3 *dwc3_reg)
+{
+       u32 revision, val;
+       unsigned long t_rst;
+       unsigned int dwc3_hwparams1;
+
+       revision = readl(&dwc3_reg->g_snpsid);
+       /* This should read as U3 followed by revision number */
+       if ((revision & DWC3_GSNPSID_MASK) != 0x55330000) {
+               puts("this is not a DesignWare USB3 DRD Core\n");
+               return -EINVAL;
+       }
+
+       /* issue device SoftReset too */
+       writel(DWC3_DCTL_CSFTRST, &dwc3_reg->d_ctl);
+
+       t_rst = get_timer(0);
+       do {
+               val = readl(&dwc3_reg->d_ctl);
+               if (!(val & DWC3_DCTL_CSFTRST))
+                       break;
+               WATCHDOG_RESET();
+       } while (get_timer(t_rst) < 500);
+
+       if (val & DWC3_DCTL_CSFTRST) {
+               debug("Reset timed out\n");
+               return -2;
+       }
+
+       dwc3_core_soft_reset(dwc3_reg);
+
+       dwc3_hwparams1 = readl(&dwc3_reg->g_hwparams1);
+
+       val = readl(&dwc3_reg->g_ctl);
+       val &= ~DWC3_GCTL_SCALEDOWN_MASK;
+       val &= ~DWC3_GCTL_DISSCRAMBLE;
+       switch (DWC3_GHWPARAMS1_EN_PWROPT(dwc3_hwparams1)) {
+       case DWC3_GHWPARAMS1_EN_PWROPT_CLK:
+               val &= ~DWC3_GCTL_DSBLCLKGTNG;
+               break;
+       default:
+               printf("No power optimization available\n");
+       }
+
+       /*
+        * WORKAROUND: DWC3 revisions <1.90a have a bug
+        * where the device can fail to connect at SuperSpeed
+        * and falls back to high-speed mode which causes
+        * the device to enter a Connect/Disconnect loop
+        */
+       if ((revision & DWC3_REVISION_MASK) < 0x190a)
+               val |= DWC3_GCTL_U2RSTECN;
+
+       writel(val, &dwc3_reg->g_ctl);
+
+       return 0;
+}
+
+static int keystone_xhci_core_init(struct dwc3 *dwc3_reg)
+{
+       int ret;
+
+       ret = dwc3_core_init(dwc3_reg);
+       if (ret) {
+               debug("failed to initialize core\n");
+               return -EINVAL;
+       }
+
+       /* We are hard-coding DWC3 core to Host Mode */
+       dwc3_set_mode(dwc3_reg, DWC3_GCTL_PRTCAP_HOST);
+
+       return 0;
+}
+
+int xhci_hcd_init(int index,
+                 struct xhci_hccr **ret_hccr, struct xhci_hcor **ret_hcor)
+{
+       u32 val;
+       int ret;
+       struct xhci_hccr *hcd;
+       struct xhci_hcor *hcor;
+       struct kdwc3_irq_regs *usbss;
+       struct keystone_xhci_phy *phy;
+
+       usbss = (struct kdwc3_irq_regs *)CONFIG_USB_SS_BASE;
+       phy = (struct keystone_xhci_phy *)CONFIG_DEV_USB_PHY_BASE;
+
+       /* Enable the PHY REFCLK clock gate with phy_ref_ssp_en = 1 */
+       val = readl(&(phy->phy_clock));
+       val |= USB3_PHY_REF_SSP_EN;
+       writel(val, &phy->phy_clock);
+
+       mdelay(100);
+
+       /* Release USB from reset */
+       ret = psc_enable_module(KS2_LPSC_USB);
+       if (ret) {
+               puts("Cannot enable USB module");
+               return -1;
+       }
+
+       mdelay(100);
+
+       /* Initialize usb phy */
+       keystone_xhci_phy_set(phy);
+
+       /* soft reset usbss */
+       writel(1, &usbss->sysconfig);
+       while (readl(&usbss->sysconfig) & 1)
+               ;
+
+       val = readl(&usbss->revision);
+       debug("usbss revision %x\n", val);
+
+       /* Initialize usb core */
+       hcd = (struct xhci_hccr *)CONFIG_USB_HOST_XHCI_BASE;
+       keystone.dwc3_reg = (struct dwc3 *)(CONFIG_USB_HOST_XHCI_BASE +
+                                           DWC3_REG_OFFSET);
+
+       keystone_xhci_core_init(keystone.dwc3_reg);
+
+       /* set register addresses */
+       hcor = (struct xhci_hcor *)((uint32_t)hcd +
+               HC_LENGTH(readl(&hcd->cr_capbase)));
+
+       debug("Keystone2-xhci: init hccr %08x and hcor %08x hc_length %d\n",
+             (u32)hcd, (u32)hcor,
+             (u32)HC_LENGTH(xhci_readl(&hcd->cr_capbase)));
+
+       keystone.usbss = usbss;
+       keystone.phy = phy;
+       keystone.hcd = hcd;
+       keystone.hcor = hcor;
+
+       *ret_hccr = hcd;
+       *ret_hcor = hcor;
+
+       return 0;
+}
+
+static int keystone_xhci_phy_suspend(void)
+{
+       int loop_cnt = 0;
+       struct xhci_hcor *hcor;
+       uint32_t *portsc_1 = NULL;
+       uint32_t *portsc_2 = NULL;
+       u32 val, usb2_pls, usb3_pls, event_q;
+       struct dwc3 *dwc3_reg = keystone.dwc3_reg;
+
+       /* set register addresses */
+       hcor = keystone.hcor;
+
+       /* Bypass Scrambling and Set Shorter Training sequence for simulation */
+       val = DWC3_GCTL_PWRDNSCALE(0x4b0) | DWC3_GCTL_PRTCAPDIR(0x2);
+       writel(val, &dwc3_reg->g_ctl);
+
+       /* GUSB2PHYCFG */
+       val = readl(&dwc3_reg->g_usb2phycfg[0]);
+
+       /* assert bit 6 (SusPhy) */
+       val |= DWC3_GUSB2PHYCFG_SUSPHY;
+       writel(val, &dwc3_reg->g_usb2phycfg[0]);
+
+       /* GUSB3PIPECTL */
+       val = readl(&dwc3_reg->g_usb3pipectl[0]);
+
+       /*
+        * assert bit 29 to allow PHY to go to suspend when idle
+        * and cause the USB3 SS PHY to enter suspend mode
+        */
+       val |= (BIT(29) | DWC3_GUSB3PIPECTL_SUSPHY);
+       writel(val, &dwc3_reg->g_usb3pipectl[0]);
+
+       /*
+        * Steps necessary to allow controller to suspend even when
+        * VBUS is HIGH:
+        * - Init DCFG[2:0] (DevSpd) to: 1=FS
+        * - Init GEVNTADR0 to point to an eventQ
+        * - Init GEVNTSIZ0 to 0x0100 to specify the size of the eventQ
+        * - Init DCTL::Run_nStop = 1
+        */
+       writel(0x00020001, &dwc3_reg->d_cfg);
+       /* TODO: local2global( (Uint32) eventQ )? */
+       writel((u32)&event_q, &dwc3_reg->g_evnt_buf[0].g_evntadrlo);
+       writel(0, &dwc3_reg->g_evnt_buf[0].g_evntadrhi);
+       writel(0x4, &dwc3_reg->g_evnt_buf[0].g_evntsiz);
+       /* Run */
+       writel(DWC3_DCTL_RUN_STOP, &dwc3_reg->d_ctl);
+
+       mdelay(100);
+
+       /* Wait for USB2 & USB3 PORTSC::PortLinkState to indicate suspend */
+       portsc_1 = (uint32_t *)(&hcor->portregs[0].or_portsc);
+       portsc_2 = (uint32_t *)(&hcor->portregs[1].or_portsc);
+       usb2_pls = 0;
+       usb3_pls = 0;
+       do {
+               ++loop_cnt;
+               usb2_pls = (readl(portsc_1) & PORT_PLS_MASK) >> 5;
+               usb3_pls = (readl(portsc_2) & PORT_PLS_MASK) >> 5;
+       } while (((usb2_pls != 0x4) || (usb3_pls != 0x4)) && loop_cnt < 1000);
+
+       if (usb2_pls != 0x4 || usb3_pls != 0x4) {
+               debug("USB suspend failed - PLS USB2=%02x, USB3=%02x\n",
+                     usb2_pls, usb3_pls);
+               return -1;
+       }
+
+       debug("USB2 and USB3 PLS - Disabled, loop_cnt=%d\n", loop_cnt);
+       return 0;
+}
+
+void xhci_hcd_stop(int index)
+{
+       /* Disable USB */
+       if (keystone_xhci_phy_suspend())
+               return;
+
+       if (psc_disable_module(KS2_LPSC_USB)) {
+               debug("PSC disable module USB failed!\n");
+               return;
+       }
+
+       /* Disable PHY */
+       keystone_xhci_phy_unset(keystone.phy);
+
+/*     memset(&keystone, 0, sizeof(struct keystone_xhci)); */
+       debug("xhci_hcd_stop OK.\n");
+}
index 923192787996f70942b766c1c9086f787ee04e3a..6aa50cb4f966c70d3495ea5588db8b42bb40bcd7 100644 (file)
@@ -944,7 +944,7 @@ static void parse_putc(const char c)
                CURSOR_SET;
 }
 
-void video_putc(struct stdio_dev *dev, const char c)
+static void video_putc(struct stdio_dev *dev, const char c)
 {
 #ifdef CONFIG_CFB_CONSOLE_ANSI
        int i;
@@ -1158,7 +1158,7 @@ void video_putc(struct stdio_dev *dev, const char c)
                flush_cache(VIDEO_FB_ADRS, VIDEO_SIZE);
 }
 
-void video_puts(struct stdio_dev *dev, const char *s)
+static void video_puts(struct stdio_dev *dev, const char *s)
 {
        int count = strlen(s);
 
@@ -1171,14 +1171,11 @@ void video_puts(struct stdio_dev *dev, const char *s)
  * video_set_lut() if they do not support 8 bpp format.
  * Implement weak default function instead.
  */
-void __video_set_lut(unsigned int index, unsigned char r,
+__weak void video_set_lut(unsigned int index, unsigned char r,
                     unsigned char g, unsigned char b)
 {
 }
 
-void video_set_lut(unsigned int, unsigned char, unsigned char, unsigned char)
-       __attribute__ ((weak, alias("__video_set_lut")));
-
 #if defined(CONFIG_CMD_BMP) || defined(CONFIG_SPLASH_SCREEN)
 
 #define FILL_8BIT_332RGB(r,g,b)        {                       \
@@ -2240,15 +2237,12 @@ static int video_init(void)
  * Implement a weak default function for boards that optionally
  * need to skip the video initialization.
  */
-int __board_video_skip(void)
+__weak int board_video_skip(void)
 {
        /* As default, don't skip test */
        return 0;
 }
 
-int board_video_skip(void)
-       __attribute__ ((weak, alias("__board_video_skip")));
-
 int drv_video_init(void)
 {
        int skip_dev_init;
index 180a3b41499dba25c9815adb57345678772482fa..be35b982acd12f6019281248145a06124a483720 100644 (file)
@@ -58,54 +58,38 @@ static void exynos_lcd_init(vidinfo_t *vid)
        lcd_set_flush_dcache(1);
 }
 
-void __exynos_cfg_lcd_gpio(void)
+__weak void exynos_cfg_lcd_gpio(void)
 {
 }
-void exynos_cfg_lcd_gpio(void)
-       __attribute__((weak, alias("__exynos_cfg_lcd_gpio")));
 
-void __exynos_backlight_on(unsigned int onoff)
+__weak void exynos_backlight_on(unsigned int onoff)
 {
 }
-void exynos_backlight_on(unsigned int onoff)
-       __attribute__((weak, alias("__exynos_cfg_lcd_gpio")));
 
-void __exynos_reset_lcd(void)
+__weak void exynos_reset_lcd(void)
 {
 }
-void exynos_reset_lcd(void)
-       __attribute__((weak, alias("__exynos_reset_lcd")));
 
-void __exynos_lcd_power_on(void)
+__weak void exynos_lcd_power_on(void)
 {
 }
-void exynos_lcd_power_on(void)
-       __attribute__((weak, alias("__exynos_lcd_power_on")));
 
-void __exynos_cfg_ldo(void)
+__weak void exynos_cfg_ldo(void)
 {
 }
-void exynos_cfg_ldo(void)
-       __attribute__((weak, alias("__exynos_cfg_ldo")));
 
-void __exynos_enable_ldo(unsigned int onoff)
+__weak void exynos_enable_ldo(unsigned int onoff)
 {
 }
-void exynos_enable_ldo(unsigned int onoff)
-       __attribute__((weak, alias("__exynos_enable_ldo")));
 
-void __exynos_backlight_reset(void)
+__weak void exynos_backlight_reset(void)
 {
 }
-void exynos_backlight_reset(void)
-       __attribute__((weak, alias("__exynos_backlight_reset")));
 
-int __exynos_lcd_misc_init(vidinfo_t *vid)
+__weak int exynos_lcd_misc_init(vidinfo_t *vid)
 {
        return 0;
 }
-int exynos_lcd_misc_init(vidinfo_t *vid)
-       __attribute__((weak, alias("__exynos_lcd_misc_init")));
 
 static void lcd_panel_on(vidinfo_t *vid)
 {
index 8d4e9254784d8d89050f3b20bbf6ac75486fe66e..5873531953316a25799c020206328bd84280b97d 100644 (file)
@@ -379,7 +379,7 @@ static struct clk pixel_clk[] = {
 /*
  * This function resets IPU
  */
-void ipu_reset(void)
+static void ipu_reset(void)
 {
        u32 *reg;
        u32 value;
index 948e1fc401facea11502734ac53e82dd70df36e5..4faeafb6351d4d3e75376e704b479ebad4a3c6b3 100644 (file)
@@ -377,7 +377,7 @@ static struct dp_csc_param_t dp_csc_array[CSC_NUM][CSC_NUM] = {
 static enum csc_type_t fg_csc_type = CSC_NONE, bg_csc_type = CSC_NONE;
 static int color_key_4rgb = 1;
 
-void ipu_dp_csc_setup(int dp, struct dp_csc_param_t dp_csc_param,
+static void ipu_dp_csc_setup(int dp, struct dp_csc_param_t dp_csc_param,
                        unsigned char srm_mode_update)
 {
        u32 reg;
@@ -605,17 +605,6 @@ void ipu_dc_uninit(int dc_chan)
        }
 }
 
-int ipu_chan_is_interlaced(ipu_channel_t channel)
-{
-       if (channel == MEM_DC_SYNC)
-               return !!(__raw_readl(DC_WR_CH_CONF_1) &
-                         DC_WR_CH_CONF_FIELD_MODE);
-       else if ((channel == MEM_BG_SYNC) || (channel == MEM_FG_SYNC))
-               return !!(__raw_readl(DC_WR_CH_CONF_5) &
-                         DC_WR_CH_CONF_FIELD_MODE);
-       return 0;
-}
-
 void ipu_dp_dc_enable(ipu_channel_t channel)
 {
        int di;
@@ -782,7 +771,7 @@ void ipu_init_dc_mappings(void)
        ipu_dc_map_config(4, 2, 21, 0xFC);
 }
 
-int ipu_pixfmt_to_map(uint32_t fmt)
+static int ipu_pixfmt_to_map(uint32_t fmt)
 {
        switch (fmt) {
        case IPU_PIX_FMT_GENERIC:
@@ -801,28 +790,6 @@ int ipu_pixfmt_to_map(uint32_t fmt)
        return -1;
 }
 
-/*
- * This function is called to adapt synchronous LCD panel to IPU restriction.
- */
-void adapt_panel_to_ipu_restricitions(uint32_t *pixel_clk,
-                                     uint16_t width, uint16_t height,
-                                     uint16_t h_start_width,
-                                     uint16_t h_end_width,
-                                     uint16_t v_start_width,
-                                     uint16_t *v_end_width)
-{
-       if (*v_end_width < 2) {
-               uint16_t total_width = width + h_start_width + h_end_width;
-               uint16_t total_height_old = height + v_start_width +
-                       (*v_end_width);
-               uint16_t total_height_new = height + v_start_width + 2;
-               *v_end_width = 2;
-               *pixel_clk = (*pixel_clk) * total_width * total_height_new /
-                       (total_width * total_height_old);
-               printf("WARNING: adapt panel end blank lines\n");
-       }
-}
-
 /*
  * This function is called to initialize a synchronous LCD panel.
  *
@@ -880,14 +847,17 @@ int32_t ipu_init_sync_panel(int disp, uint32_t pixel_clk,
        if ((v_sync_width == 0) || (h_sync_width == 0))
                return -EINVAL;
 
-       adapt_panel_to_ipu_restricitions(&pixel_clk, width, height,
-                                        h_start_width, h_end_width,
-                                        v_start_width, &v_end_width);
+       /* adapt panel to ipu restricitions */
+       if (v_end_width < 2) {
+               v_end_width = 2;
+               puts("WARNING: v_end_width (lower_margin) must be >= 2, adjusted\n");
+       }
+
        h_total = width + h_sync_width + h_start_width + h_end_width;
        v_total = height + v_sync_width + v_start_width + v_end_width;
 
        /* Init clocking */
-       debug("pixel clk = %d\n", pixel_clk);
+       debug("pixel clk = %dHz\n", pixel_clk);
 
        if (sig.ext_clk) {
                if (!(g_di1_tvout && (disp == 1))) { /*not round div for tvout*/
index f75d77064ea5334c6211130f367987c61bd742cd..1fa95314fc4621857114bcef2e98e50a60f163b7 100644 (file)
@@ -36,7 +36,7 @@ static struct fb_videomode const *gmode;
 static uint8_t gdisp;
 static uint32_t gpixfmt;
 
-void fb_videomode_to_var(struct fb_var_screeninfo *var,
+static void fb_videomode_to_var(struct fb_var_screeninfo *var,
                         const struct fb_videomode *mode)
 {
        var->xres = mode->xres;
@@ -258,8 +258,7 @@ static int mxcfb_set_par(struct fb_info *fbi)
        if (fbi->var.sync & FB_SYNC_CLK_IDLE_EN)
                sig_cfg.clkidle_en = 1;
 
-       debug("pixclock = %ul Hz\n",
-               (u32) (PICOS2KHZ(fbi->var.pixclock) * 1000UL));
+       debug("pixclock = %lu Hz\n", PICOS2KHZ(fbi->var.pixclock) * 1000UL);
 
        if (ipu_init_sync_panel(mxc_fbi->ipu_di,
                                (PICOS2KHZ(fbi->var.pixclock)) * 1000UL,
@@ -486,7 +485,7 @@ static struct fb_info *mxcfb_init_fbinfo(void)
 
 /*
  * Probe routine for the framebuffer driver. It is called during the
- * driver binding process.      The following functions are performed in
+ * driver binding process. The following functions are performed in
  * this routine: Framebuffer initialization, Memory allocation and
  * mapping, Framebuffer registration, IPU initialization.
  *
@@ -542,7 +541,7 @@ static int mxcfb_probe(u32 interface_pix_fmt, uint8_t disp,
 
        mxcfb_set_fix(fbi);
 
-       /* alocate fb first */
+       /* allocate fb first */
        if (mxcfb_map_video_memory(fbi) < 0)
                return -ENOMEM;
 
index 60539d8a9d24fc113e9d8f839a9f84244fbe1a23..f81b51aa301feec3f13dc787c95626c2f84012a8 100644 (file)
  */
 
 /**
- * Request a gpio. This should be called before any of the other functions
- * are used on this gpio.
+ * Request a GPIO. This should be called before any of the other functions
+ * are used on this GPIO.
+ *
+ * Note: With driver model, the label is allocated so there is no need for
+ * the caller to preserve it.
  *
  * @param gp   GPIO number
  * @param label        User label for this GPIO
@@ -80,7 +83,7 @@ int gpio_get_value(unsigned gpio);
 int gpio_set_value(unsigned gpio, int value);
 
 /* State of a GPIO, as reported by get_function() */
-enum {
+enum gpio_func_t {
        GPIOF_INPUT = 0,
        GPIOF_OUTPUT,
        GPIOF_UNUSED,           /* Not claimed */
@@ -92,6 +95,66 @@ enum {
 
 struct udevice;
 
+/**
+ * gpio_get_status() - get the current GPIO status as a string
+ *
+ * Obtain the current GPIO status as a string which can be presented to the
+ * user. A typical string is:
+ *
+ * "b4:  in: 1 [x] sdmmc_cd"
+ *
+ * which means this is GPIO bank b, offset 4, currently set to input, current
+ * value 1, [x] means that it is requested and the owner is 'sdmmc_cd'
+ *
+ * @dev:       Device to check
+ * @offset:    Offset of device GPIO to check
+ * @buf:       Place to put string
+ * @buffsize:  Size of string including \0
+ */
+int gpio_get_status(struct udevice *dev, int offset, char *buf, int buffsize);
+
+/**
+ * gpio_get_function() - get the current function for a GPIO pin
+ *
+ * Note this returns GPIOF_UNUSED if the GPIO is not requested.
+ *
+ * @dev:       Device to check
+ * @offset:    Offset of device GPIO to check
+ * @namep:     If non-NULL, this is set to the nane given when the GPIO
+ *             was requested, or -1 if it has not been requested
+ * @return  -ENODATA if the driver returned an unknown function,
+ * -ENODEV if the device is not active, -EINVAL if the offset is invalid.
+ * GPIOF_UNUSED if the GPIO has not been requested. Otherwise returns the
+ * function from enum gpio_func_t.
+ */
+int gpio_get_function(struct udevice *dev, int offset, const char **namep);
+
+/**
+ * gpio_get_raw_function() - get the current raw function for a GPIO pin
+ *
+ * Note this does not return GPIOF_UNUSED - it will always return the GPIO
+ * driver's view of a pin function, even if it is not correctly set up.
+ *
+ * @dev:       Device to check
+ * @offset:    Offset of device GPIO to check
+ * @namep:     If non-NULL, this is set to the nane given when the GPIO
+ *             was requested, or -1 if it has not been requested
+ * @return  -ENODATA if the driver returned an unknown function,
+ * -ENODEV if the device is not active, -EINVAL if the offset is invalid.
+ * Otherwise returns the function from enum gpio_func_t.
+ */
+int gpio_get_raw_function(struct udevice *dev, int offset, const char **namep);
+
+/**
+ * gpio_requestf() - request a GPIO using a format string for the owner
+ *
+ * This is a helper function for gpio_request(). It allows you to provide
+ * a printf()-format string for the GPIO owner. It calls gpio_request() with
+ * the string that is created
+ */
+int gpio_requestf(unsigned gpio, const char *fmt, ...)
+               __attribute__ ((format (__printf__, 2, 3)));
+
 /**
  * struct struct dm_gpio_ops - Driver model GPIO operations
  *
@@ -102,7 +165,7 @@ struct udevice;
  * new DM GPIO API, this should be really easy to flip over to the Linux
  * GPIO API-alike interface.
  *
- * Akso it would be useful to standardise additional functions like
+ * Also it would be useful to standardise additional functions like
  * pullup, slew rate and drive strength.
  *
  * gpio_request)( and gpio_free() are optional - if NULL then they will
@@ -115,7 +178,7 @@ struct udevice;
  * SoCs there may be many banks and therefore many devices all referring
  * to the different IO addresses within the SoC.
  *
- * The uclass combines all GPIO devices togther to provide a consistent
+ * The uclass combines all GPIO devices together to provide a consistent
  * numbering from 0 to n-1, where n is the number of GPIOs in total across
  * all devices. Be careful not to confuse offset with gpio in the parameters.
  */
@@ -135,15 +198,13 @@ struct dm_gpio_ops {
         * @return current function - GPIOF_...
         */
        int (*get_function)(struct udevice *dev, unsigned offset);
-       int (*get_state)(struct udevice *dev, unsigned offset, char *state,
-                        int maxlen);
 };
 
 /**
  * struct gpio_dev_priv - information about a device used by the uclass
  *
  * The uclass combines all active GPIO devices into a unified numbering
- * scheme. To do this it maintains some private information aobut each
+ * scheme. To do this it maintains some private information about each
  * device.
  *
  * To implement driver model support in your GPIO driver, add a probe
@@ -157,11 +218,14 @@ struct dm_gpio_ops {
  * @gpio_base: Base GPIO number for this device. For the first active device
  * this will be 0; the numbering for others will follow sequentially so that
  * @gpio_base for device 1 will equal the number of GPIOs in device 0.
+ * @name: Array of pointers to the name for each GPIO in this bank. The
+ * value of the pointer will be NULL if the GPIO has not been claimed.
  */
 struct gpio_dev_priv {
        const char *bank_name;
        unsigned gpio_count;
        unsigned gpio_base;
+       char **name;
 };
 
 /* Access the GPIO operations for a device */
@@ -193,4 +257,6 @@ const char *gpio_get_bank_info(struct udevice *dev, int *offset_count);
 int gpio_lookup_name(const char *name, struct udevice **devp,
                     unsigned int *offsetp, unsigned int *gpiop);
 
+int name_to_gpio(const char *name);
+
 #endif /* _ASM_GENERIC_GPIO_H_ */
index 694d6fc080fcc5c1b6759f6e74bdf7ba9a328755..b3d1a620daeaf0041679e5caef49adbb0be4e2e8 100644 (file)
@@ -54,4 +54,6 @@ int bootm_find_ramdisk_fdt(int flag, int argc, char * const argv[]);
 int do_bootm_states(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
                    int states, bootm_headers_t *images, int boot_progress);
 
+void arch_preboot_os(void);
+
 #endif
index 87bf906b263e09a8a25527f7238cbb6352de953d..df13ab2f63eddbb075d5d2cc2bdffacccd88e68b 100644 (file)
@@ -159,6 +159,9 @@ enum bootstage_id {
        /* Next 10 IDs used by BOOTSTAGE_SUB_... */
        BOOTSTAGE_ID_FIT_RD_START = 120,        /* Ramdisk stages */
 
+       /* Next 10 IDs used by BOOTSTAGE_SUB_... */
+       BOOTSTAGE_ID_FIT_SETUP_START = 130,     /* x86 setup stages */
+
        BOOTSTAGE_ID_IDE_FIT_READ = 140,
        BOOTSTAGE_ID_IDE_FIT_READ_OK,
 
index d5020c8c45d1afc515e02433ea2513ab6b99d28e..bcf6c7e9502f479b9fe533765f28efdb97132eda 100644 (file)
@@ -636,13 +636,6 @@ struct stdio_dev;
 int serial_stub_getc(struct stdio_dev *sdev);
 int serial_stub_tstc(struct stdio_dev *sdev);
 
-void   _serial_setbrg (const int);
-void   _serial_putc   (const char, const int);
-void   _serial_putc_raw(const char, const int);
-void   _serial_puts   (const char *, const int);
-int    _serial_getc   (const int);
-int    _serial_tstc   (const int);
-
 /* $(CPU)/speed.c */
 int    get_clocks (void);
 int    get_clocks_866 (void);
index 76818f673f2810c69520067a7a10e2b34ed4515a..7d8daa2b8e5332f421b9bb616812d494927f1c71 100644 (file)
 #define CONFIG_SYS_PROMPT      "=> "
 #endif
 
-#ifndef CONFIG_SYS_HZ
-#define CONFIG_SYS_HZ          1000
-#endif
-
 #ifndef CONFIG_FIT_SIGNATURE
 #define CONFIG_IMAGE_FORMAT_LEGACY
 #endif
index 9063c57b4092e73746553a539719875ea2f180a3..dc1a9bc1ef98d9bc2d78ea88a550f17054b4110a 100644 (file)
@@ -82,6 +82,7 @@
 #define CONFIG_SYS_FSL_CPC             /* Corenet Platform Cache */
 #define CONFIG_SYS_NUM_CPC             CONFIG_NUM_DDR_CONTROLLERS
 #define CONFIG_FSL_IFC                 /* Enable IFC Support */
+#define CONFIG_FSL_CAAM                        /* Enable SEC/CAAM */
 #define CONFIG_PCI                     /* Enable PCI/PCIE */
 #define CONFIG_PCIE1                   /* PCIE controler 1 */
 #define CONFIG_FSL_PCI_INIT            /* Use common FSL init code */
@@ -759,6 +760,12 @@ unsigned long get_board_ddr_clk(void);
 #define CONFIG_CMD_NET
 #endif
 
+/* Hash command with SHA acceleration supported in hardware */
+#ifdef CONFIG_FSL_CAAM
+#define CONFIG_CMD_HASH
+#define CONFIG_SHA_HW_ACCEL
+#endif
+
 /*
 * USB
 */
@@ -913,4 +920,8 @@ unsigned long get_board_ddr_clk(void);
 
 #include <asm/fsl_secure_boot.h>
 
+#ifdef CONFIG_SECURE_BOOT
+#define CONFIG_CMD_BLOB
+#endif
+
 #endif /* __CONFIG_H */
index 56a3e9486851994c9e2cc96ee08f1434a1c38642..bc5af526c5f7eb55df3d424268980c372fe13d48 100644 (file)
@@ -55,6 +55,7 @@
 #define CONFIG_BOOKE                   /* BOOKE */
 #define CONFIG_E500                    /* BOOKE e500 family */
 #define CONFIG_FSL_IFC                 /* Enable IFC Support */
+#define CONFIG_FSL_CAAM                        /* Enable SEC/CAAM */
 
 #define CONFIG_FSL_LAW                 /* Use common FSL init code */
 #define CONFIG_TSEC_ENET
@@ -382,6 +383,12 @@ extern unsigned long get_sdram_size(void);
 #define CONFIG_KGDB_BAUDRATE   230400  /* speed to run kgdb serial port */
 #endif
 
+/* Hash command with SHA acceleration supported in hardware */
+#ifdef CONFIG_FSL_CAAM
+#define CONFIG_CMD_HASH
+#define CONFIG_SHA_HW_ACCEL
+#endif
+
 #define CONFIG_USB_EHCI
 
 #ifdef CONFIG_USB_EHCI
index aeded6d85b40c436998a39f5036525210d07cb09..989363c0fbc0def810b96a73ae07889382205656 100644 (file)
@@ -78,6 +78,7 @@
 #define CONFIG_BOOKE                   /* BOOKE */
 #define CONFIG_E500                    /* BOOKE e500 family */
 #define CONFIG_FSL_IFC                 /* Enable IFC Support */
+#define CONFIG_FSL_CAAM                        /* Enable SEC/CAAM */
 #define CONFIG_SYS_HAS_SERDES          /* common SERDES init code */
 
 #define CONFIG_PCI                     /* Enable PCI/PCIE */
@@ -598,6 +599,12 @@ combinations. this should be removed later
 #define CONFIG_DOS_PARTITION
 #endif
 
+/* Hash command with SHA acceleration supported in hardware */
+#ifdef CONFIG_FSL_CAAM
+#define CONFIG_CMD_HASH
+#define CONFIG_SHA_HW_ACCEL
+#endif
+
 /*
  * Miscellaneous configurable options
  */
@@ -704,4 +711,8 @@ combinations. this should be removed later
 
 #include <asm/fsl_secure_boot.h>
 
+#ifdef CONFIG_SECURE_BOOT
+#define CONFIG_CMD_BLOB
+#endif
+
 #endif /* __CONFIG_H */
index 715616d5445b872bca0db030e343a5e2d4f3bb23..5d11278f036c01382a2bb6a77f3e1cdd377cb46b 100644 (file)
@@ -86,6 +86,7 @@
 #define CONFIG_BOOKE                   /* BOOKE */
 #define CONFIG_E500                    /* BOOKE e500 family */
 #define CONFIG_FSL_IFC                 /* Enable IFC Support */
+#define CONFIG_FSL_CAAM                        /* Enable SEC/CAAM */
 #define CONFIG_SYS_HAS_SERDES          /* common SERDES init code */
 
 #define CONFIG_PCI                     /* Enable PCI/PCIE */
 #define CONFIG_CMD_SETEXPR
 #define CONFIG_CMD_REGINFO
 
+/* Hash command with SHA acceleration supported in hardware */
+#ifdef CONFIG_FSL_CAAM
+#define CONFIG_CMD_HASH
+#define CONFIG_SHA_HW_ACCEL
+#endif
+
 /*
  * Miscellaneous configurable options
  */
index a373990e5d014e9a28c16f08615d22b18144e892..d378dbd1a1e2ccb4537257a329e4ced51cc01599 100644 (file)
@@ -53,7 +53,7 @@
 #ifdef CONFIG_SECURE_BOOT
 #define CONFIG_RAMBOOT_SPIFLASH
 #define CONFIG_SYS_TEXT_BASE           0x11000000
-#define CONFIG_RESET_VECTOR_ADDRESS    0x1107fffc
+#define CONFIG_RESET_VECTOR_ADDRESS    0x110bfffc
 #else
 #define CONFIG_SPL_MPC8XXX_INIT_DDR_SUPPORT
 #define CONFIG_SPL_DRIVERS_MISC_SUPPORT
 #define CONFIG_BOOKE                   /* BOOKE */
 #define CONFIG_E500                    /* BOOKE e500 family */
 #define CONFIG_FSL_IFC                 /* Enable IFC Support */
+#define CONFIG_FSL_CAAM                        /* Enable SEC/CAAM */
 #define CONFIG_SYS_HAS_SERDES          /* common SERDES init code */
 
 #define CONFIG_PCI                     /* Enable PCI/PCIE */
@@ -832,6 +833,12 @@ extern unsigned long get_sdram_size(void);
 #define CONFIG_DOS_PARTITION
 #endif
 
+/* Hash command with SHA acceleration supported in hardware */
+#ifdef CONFIG_FSL_CAAM
+#define CONFIG_CMD_HASH
+#define CONFIG_SHA_HW_ACCEL
+#endif
+
 /*
  * Miscellaneous configurable options
  */
@@ -956,4 +963,8 @@ extern unsigned long get_sdram_size(void);
 
 #include <asm/fsl_secure_boot.h>
 
+#ifdef CONFIG_SECURE_BOOT
+#define CONFIG_CMD_BLOB
+#endif
+
 #endif /* __CONFIG_H */
index 16f7525def40f84d526d98c3077077eb01a24195..2e11aaa13cd35156e605cf29723b6f6a6ff2d9cb 100644 (file)
@@ -49,6 +49,7 @@
 #define CONFIG_SYS_FSL_CPC             /* Corenet Platform Cache */
 #define CONFIG_SYS_NUM_CPC             CONFIG_NUM_DDR_CONTROLLERS
 #define CONFIG_FSL_ELBC                        /* Has Enhanced localbus controller */
+#define CONFIG_FSL_CAAM                        /* Enable SEC/CAAM */
 #define CONFIG_PCI                     /* Enable PCI/PCIE */
 #define CONFIG_PCIE1                   /* PCIE controler 1 */
 #define CONFIG_PCIE2                   /* PCIE controler 2 */
@@ -647,6 +648,12 @@ unsigned long get_board_sys_clk(unsigned long dummy);
 #define CONFIG_DOS_PARTITION
 #endif
 
+/* Hash command with SHA acceleration supported in hardware */
+#ifdef CONFIG_FSL_CAAM
+#define CONFIG_CMD_HASH
+#define CONFIG_SHA_HW_ACCEL
+#endif
+
 /*
  * Miscellaneous configurable options
  */
@@ -743,4 +750,8 @@ unsigned long get_board_sys_clk(unsigned long dummy);
 
 #include <asm/fsl_secure_boot.h>
 
+#ifdef CONFIG_SECURE_BOOT
+#define CONFIG_CMD_BLOB
+#endif
+
 #endif /* __CONFIG_H */
index a781ba327a2855e3a9715a0cb52935ab81a2cdcb..1d0664ddf6e828b01a2801a96f73becd06d34036 100644 (file)
@@ -58,6 +58,7 @@
 #define CONFIG_SYS_FSL_CPC             /* Corenet Platform Cache */
 #define CONFIG_SYS_NUM_CPC             CONFIG_NUM_DDR_CONTROLLERS
 #define CONFIG_FSL_IFC                 /* Enable IFC Support */
+#define CONFIG_FSL_CAAM                        /* Enable SEC/CAAM */
 #define CONFIG_PCI                     /* Enable PCI/PCIE */
 #define CONFIG_PCI_INDIRECT_BRIDGE
 #define CONFIG_PCIE1                   /* PCIE controler 1 */
@@ -716,6 +717,12 @@ unsigned long get_board_ddr_clk(void);
 #define CONFIG_CMD_NET
 #endif
 
+/* Hash command with SHA acceleration supported in hardware */
+#ifdef CONFIG_FSL_CAAM
+#define CONFIG_CMD_HASH
+#define CONFIG_SHA_HW_ACCEL
+#endif
+
 /*
  * Miscellaneous configurable options
  */
@@ -818,6 +825,7 @@ unsigned long get_board_ddr_clk(void);
 
 #ifdef CONFIG_SECURE_BOOT
 #include <asm/fsl_secure_boot.h>
+#define CONFIG_CMD_BLOB
 #endif
 
 #endif /* __CONFIG_H */
index 5e2c100d9309b1b86cbc1ffa06e43031c0ddb076..2bb86e40caf97b742f8ad39fe152a8b3b7c9dd08 100644 (file)
 #define CONFIG_SYS_FSL_CPC             /* Corenet Platform Cache */
 #define CONFIG_SYS_NUM_CPC             CONFIG_NUM_DDR_CONTROLLERS
 #define CONFIG_FSL_IFC                 /* Enable IFC Support */
+#define CONFIG_FSL_CAAM                        /* Enable SEC/CAAM */
 #define CONFIG_PCI                     /* Enable PCI/PCIE */
 #define CONFIG_PCI_INDIRECT_BRIDGE
 #define CONFIG_PCIE1                   /* PCIE controler 1 */
 #define CONFIG_CMD_NET
 #endif
 
+/* Hash command with SHA acceleration supported in hardware */
+#ifdef CONFIG_FSL_CAAM
+#define CONFIG_CMD_HASH
+#define CONFIG_SHA_HW_ACCEL
+#endif
+
 /*
  * Miscellaneous configurable options
  */
 
 #ifdef CONFIG_SECURE_BOOT
 #include <asm/fsl_secure_boot.h>
+#define CONFIG_CMD_BLOB
 #endif
 
 #endif /* __CONFIG_H */
index 395472be2bc2a6a8d19211129c696e1f57a388a2..27333589afe4f092214acd94ef6e93e3d696058a 100644 (file)
@@ -44,6 +44,7 @@
 #define CONFIG_SYS_FSL_CPC     /* Corenet Platform Cache */
 #define CONFIG_SYS_NUM_CPC     CONFIG_NUM_DDR_CONTROLLERS
 #define CONFIG_FSL_IFC         /* Enable IFC Support */
+#define CONFIG_FSL_CAAM                /* Enable SEC/CAAM */
 #define CONFIG_FSL_LAW         /* Use common FSL init code */
 #define CONFIG_ENV_OVERWRITE
 
@@ -777,6 +778,12 @@ unsigned long get_board_ddr_clk(void);
 #define CONFIG_CMD_NET
 #endif
 
+/* Hash command with SHA acceleration supported in hardware */
+#ifdef CONFIG_FSL_CAAM
+#define CONFIG_CMD_HASH
+#define CONFIG_SHA_HW_ACCEL
+#endif
+
 /*
  * Miscellaneous configurable options
  */
@@ -909,6 +916,7 @@ unsigned long get_board_ddr_clk(void);
 
 #ifdef CONFIG_SECURE_BOOT
 #include <asm/fsl_secure_boot.h>
+#define CONFIG_CMD_BLOB
 #undef CONFIG_CMD_USB
 #endif
 
index e5936c78176972761a57b8b491e4a27c328f608d..400d979643caaf7cdaddc8ddfdae5dbf87a6169a 100644 (file)
@@ -37,6 +37,7 @@
 #define CONFIG_SYS_FSL_CPC     /* Corenet Platform Cache */
 #define CONFIG_SYS_NUM_CPC     CONFIG_NUM_DDR_CONTROLLERS
 #define CONFIG_FSL_IFC         /* Enable IFC Support */
+#define CONFIG_FSL_CAAM                /* Enable SEC/CAAM */
 #define CONFIG_FSL_LAW         /* Use common FSL init code */
 #define CONFIG_ENV_OVERWRITE
 
@@ -736,6 +737,12 @@ unsigned long get_board_ddr_clk(void);
 #define CONFIG_CMD_NET
 #endif
 
+/* Hash command with SHA acceleration supported in hardware */
+#ifdef CONFIG_FSL_CAAM
+#define CONFIG_CMD_HASH
+#define CONFIG_SHA_HW_ACCEL
+#endif
+
 /*
  * Miscellaneous configurable options
  */
@@ -868,6 +875,7 @@ unsigned long get_board_ddr_clk(void);
 
 #ifdef CONFIG_SECURE_BOOT
 #include <asm/fsl_secure_boot.h>
+#define CONFIG_CMD_BLOB
 #undef CONFIG_CMD_USB
 #endif
 
index ca9724720d9f0ad53e574670a5f48495d268420d..1e0f5ece092067afcce0ae74cedc14e86f4c2b96 100644 (file)
@@ -15,6 +15,7 @@
 
 #define CONFIG_FSL_SATA_V2
 #define CONFIG_PCIE4
+#define CONFIG_FSL_CAAM                        /* Enable SEC/CAAM */
 
 #define CONFIG_ICS307_REFCLK_HZ                25000000  /* ICS307 ref clk freq */
 
@@ -506,6 +507,12 @@ unsigned long get_board_ddr_clk(void);
 #define CONFIG_PHY_GIGE                /* Include GbE speed/duplex detection */
 #endif
 
+/* Hash command with SHA acceleration supported in hardware */
+#ifdef CONFIG_FSL_CAAM
+#define CONFIG_CMD_HASH
+#define CONFIG_SHA_HW_ACCEL
+#endif
+
 /*
 * USB
 */
@@ -625,4 +632,8 @@ unsigned long get_board_ddr_clk(void);
 
 #include <asm/fsl_secure_boot.h>
 
+#ifdef CONFIG_SECURE_BOOT
+#define CONFIG_CMD_BLOB
+#endif
+
 #endif /* __CONFIG_H */
index 183255d2831ebb3c1e4a4e4e33a6cf5c0238443b..13f4bd3c539fae5629ec1adc374f875ec0417bdc 100644 (file)
@@ -47,6 +47,7 @@
 #define CONFIG_SYS_FSL_CPC             /* Corenet Platform Cache */
 #define CONFIG_SYS_NUM_CPC             CONFIG_NUM_DDR_CONTROLLERS
 #define CONFIG_FSL_IFC                 /* Enable IFC Support */
+#define CONFIG_FSL_CAAM                        /* Enable SEC/CAAM */
 #define CONFIG_PCI                     /* Enable PCI/PCIE */
 #define CONFIG_PCIE1                   /* PCIE controler 1 */
 #define CONFIG_PCIE2                   /* PCIE controler 2 */
@@ -668,6 +669,12 @@ unsigned long get_board_ddr_clk(void);
 #define CONFIG_DOS_PARTITION
 #endif
 
+/* Hash command with SHA acceleration supported in hardware */
+#ifdef CONFIG_FSL_CAAM
+#define CONFIG_CMD_HASH
+#define CONFIG_SHA_HW_ACCEL
+#endif
+
 #define CONFIG_BOOTDELAY       10      /* -1 disables auto-boot */
 
 #define __USB_PHY_TYPE utmi
@@ -751,6 +758,7 @@ unsigned long get_board_ddr_clk(void);
  * which is anyways not used in Secure Environment.
  */
 #undef CONFIG_CMD_USB
+#define CONFIG_CMD_BLOB
 #endif
 
 #endif /* __CONFIG_H */
index 476430ddd08310853c6e3ea6df9dfcb26b28f9a4..1ec783daf4f9b69c3d51d4ad4784175eaa262be0 100644 (file)
        "boot part 0 1;" \
        "rootfs part 0 2;" \
        "MLO fat 0 1;" \
-       "MLO.raw mmc 0x100 0x100;" \
-       "u-boot.img.raw mmc 0x300 0x400;" \
-       "spl-os-args.raw mmc 0x80 0x80;" \
-       "spl-os-image.raw mmc 0x900 0x2000;" \
+       "MLO.raw raw 0x100 0x100;" \
+       "u-boot.img.raw raw 0x300 0x400;" \
+       "spl-os-args.raw raw 0x80 0x80;" \
+       "spl-os-image.raw raw 0x900 0x2000;" \
        "spl-os-args fat 0 1;" \
        "spl-os-image fat 0 1;" \
        "u-boot.img fat 0 1;" \
        "fdt ram 0x80F80000 0x80000;" \
        "ramdisk ram 0x81000000 0x4000000\0"
 #define DFUARGS \
-       "dfu_alt_info_emmc=rawemmc mmc 0 3751936\0" \
+       "dfu_alt_info_emmc=rawemmc raw 0 3751936\0" \
        DFU_ALT_INFO_MMC \
        DFU_ALT_INFO_RAM \
        DFU_ALT_INFO_NAND
index 070782774d945ca7119e487076a4b11bf424185e..4472c3e5558065d6efe33eb0cfd4a48126914ee3 100644 (file)
@@ -11,6 +11,9 @@
 
 #define CONFIG_AM43XX
 
+#define CONFIG_CMD_FAT
+#define CONFIG_CMD_SAVEENV
+
 #define CONFIG_BOARD_LATE_INIT
 #define CONFIG_ARCH_CPU_INIT
 #define CONFIG_SYS_CACHELINE_SIZE       32
 /* NS16550 Configuration */
 #define CONFIG_SYS_NS16550_COM1                0x44e09000      /* Base EVM has UART0 */
 
-#define CONFIG_ENV_IS_NOWHERE
+#define CONFIG_ENV_IS_IN_FAT
+#define FAT_ENV_INTERFACE              "mmc"
+#define FAT_ENV_DEVICE_AND_PART                "0:1"
+#define FAT_ENV_FILE                   "uboot.env"
+#define CONFIG_FAT_WRITE
 
 #define CONFIG_SPL_LDSCRIPT            "$(CPUDIR)/omap-common/u-boot-spl.lds"
 
 
 #ifdef CONFIG_QSPI_BOOT
 #define CONFIG_SYS_TEXT_BASE           0x30000000
-#undef CONFIG_ENV_IS_NOWHERE
+#undef CONFIG_ENV_IS_IN_FAT
 #define CONFIG_ENV_IS_IN_SPI_FLASH
 #define CONFIG_SYS_REDUNDAND_ENVIRONMENT
 #define CONFIG_ENV_SPI_MAX_HZ           CONFIG_SF_DEFAULT_SPEED
diff --git a/include/configs/apalis_t30.h b/include/configs/apalis_t30.h
new file mode 100644 (file)
index 0000000..3cde923
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2014 Marcel Ziswiler
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#include <linux/sizes.h>
+
+#include "tegra30-common.h"
+
+/* High-level configuration options */
+#define V_PROMPT                       "Apalis T30 # "
+#define CONFIG_TEGRA_BOARD_STRING      "Toradex Apalis T30"
+
+/* Board-specific serial config */
+#define CONFIG_SERIAL_MULTI
+#define CONFIG_TEGRA_ENABLE_UARTA
+#define CONFIG_SYS_NS16550_COM1                NV_PA_APB_UARTA_BASE
+
+#define CONFIG_MACH_TYPE               MACH_TYPE_APALIS_T30
+
+#define CONFIG_BOARD_EARLY_INIT_F
+
+/* I2C */
+#define CONFIG_SYS_I2C_TEGRA
+#define CONFIG_SYS_I2C_INIT_BOARD
+#define CONFIG_SYS_I2C_SPEED           100000
+#define CONFIG_CMD_I2C
+#define CONFIG_SYS_I2C
+
+/* SD/MMC */
+#define CONFIG_MMC
+#define CONFIG_GENERIC_MMC
+#define CONFIG_TEGRA_MMC
+#define CONFIG_CMD_MMC
+
+/* Environment in eMMC, at the end of 2nd "boot sector" */
+#define CONFIG_ENV_IS_IN_MMC
+#define CONFIG_ENV_OFFSET              (-CONFIG_ENV_SIZE)
+#define CONFIG_SYS_MMC_ENV_DEV         0
+#define CONFIG_SYS_MMC_ENV_PART                2
+
+/* USB Host support */
+#define CONFIG_USB_EHCI
+#define CONFIG_USB_EHCI_TEGRA
+#define CONFIG_USB_MAX_CONTROLLER_COUNT 3
+#define CONFIG_USB_STORAGE
+#define CONFIG_CMD_USB
+
+/* USB networking support */
+#define CONFIG_USB_HOST_ETHER
+#define CONFIG_USB_ETHER_ASIX
+
+/* PCI host support */
+#undef CONFIG_PCI      /* just define once Tegra PCIe support got merged */
+#define CONFIG_PCI_TEGRA
+#define CONFIG_PCI_PNP
+#define CONFIG_CMD_PCI
+#define CONFIG_CMD_PCI_ENUM
+
+/* PCI networking support */
+#define CONFIG_E1000
+#undef CONFIG_E1000_NO_NVM     /* just define once E1000 driver got fixed */
+
+/* General networking support */
+#define CONFIG_CMD_NET
+#define CONFIG_CMD_DHCP
+
+#include "tegra-common-usb-gadget.h"
+#include "tegra-common-post.h"
+
+#endif /* __CONFIG_H */
index 7cf241e31d7725b826671d8f70c0b4df3ac119ef..f7277eb1d17a0d5f3a4c613d6033bd682c3491dd 100644 (file)
 #define CONFIG_MX6
 #define CONFIG_SYS_LITTLE_ENDIAN
 #define CONFIG_MACH_TYPE               4273
-#define CONFIG_SYS_HZ                  1000
+
+#ifndef CONFIG_SPL_BUILD
+#define CONFIG_DM
+#define CONFIG_CMD_DM
+
+#define CONFIG_DM_GPIO
+#define CONFIG_CMD_GPIO
+
+#define CONFIG_DM_SERIAL
+#define CONFIG_SYS_MALLOC_F_LEN                (1 << 10)
+#endif
 
 /* Display information on boot */
 #define CONFIG_DISPLAY_CPUINFO
index 782b9d16b7a4f7c8ab1fcf1fa6e9a9647505170e..a582e255169c8188cdcd3aac8416b530191bf2c3 100644 (file)
@@ -11,7 +11,6 @@
 
 #include "tegra30-common.h"
 
-
 #define V_PROMPT                       "Colibri T30 # "
 #define CONFIG_TEGRA_BOARD_STRING      "Toradex Colibri T30"
 
index 936be145119d1e55a810ccc95bb922cb8a9b0f72..4b90dc205de82e4130547d1be44defd1ea8c208f 100644 (file)
 #define CONFIG_ZBOOT_32
 #define CONFIG_PHYSMEM
 #define CONFIG_SYS_EARLY_PCI_INIT
+#define CONFIG_DISPLAY_BOARDINFO_LATE
+
+#define CONFIG_DM
+#define CONFIG_CMD_DM
+#define CONFIG_DM_GPIO
+#define CONFIG_DM_SERIAL
 
 #define CONFIG_LMB
 #define CONFIG_OF_LIBFDT
@@ -39,6 +45,7 @@
 #define CONFIG_BOOTSTAGE_USER_COUNT    60
 
 #define CONFIG_LZO
+#define CONFIG_FIT
 #undef CONFIG_ZLIB
 #undef CONFIG_GZIP
 
 /*-----------------------------------------------------------------------
  * Serial Configuration
  */
-#define CONFIG_CONS_INDEX              1
+#define CONFIG_COREBOOT_SERIAL
 #define CONFIG_SYS_NS16550
-#define CONFIG_SYS_NS16550_SERIAL
-#define CONFIG_SYS_NS16550_REG_SIZE    1
-#define CONFIG_SYS_NS16550_CLK         1843200
-#define CONFIG_BAUDRATE                        9600
+#define CONFIG_BAUDRATE                        115200
 #define CONFIG_SYS_BAUDRATE_TABLE      {300, 600, 1200, 2400, 4800, \
                                         9600, 19200, 38400, 115200}
-#define CONFIG_SYS_NS16550_COM1        UART0_BASE
-#define CONFIG_SYS_NS16550_COM2        UART1_BASE
 #define CONFIG_SYS_NS16550_PORT_MAPPED
 
-#define CONFIG_STD_DEVICES_SETTINGS     "stdin=usbkbd,vga,eserial0\0" \
-                                       "stdout=vga,eserial0,cbmem\0" \
-                                       "stderr=vga,eserial0,cbmem\0"
+#define CONFIG_STD_DEVICES_SETTINGS     "stdin=usbkbd,vga,serial\0" \
+                                       "stdout=vga,serial,cbmem\0" \
+                                       "stderr=vga,serial,cbmem\0"
 
 #define CONFIG_CONSOLE_MUX
 #define CONFIG_SYS_CONSOLE_IS_IN_ENV
 
 #define CONFIG_CMDLINE_EDITING
 #define CONFIG_COMMAND_HISTORY
-#define CONFIG_AUTOCOMPLETE
+#define CONFIG_AUTO_COMPLETE
+#define CONFIG_SYS_HUSH_PARSER
 
 #define CONFIG_SUPPORT_VFAT
 /************************************************************
 #define CONFIG_CMD_EXT2
 
 #define CONFIG_CMD_ZBOOT
+#define CONFIG_CMD_ELF
 
 #define CONFIG_BOOTDELAY       2
 #define CONFIG_BOOTARGS                \
  * Miscellaneous configurable options
  */
 #define CONFIG_SYS_LONGHELP
-#define CONFIG_SYS_PROMPT                      "boot > "
-#define CONFIG_SYS_CBSIZE                      256
+#define CONFIG_SYS_CBSIZE                      512
 #define CONFIG_SYS_PBSIZE                      (CONFIG_SYS_CBSIZE + \
                                                 sizeof(CONFIG_SYS_PROMPT) + \
                                                 16)
 
 #define CONFIG_SYS_MEMTEST_START               0x00100000
 #define CONFIG_SYS_MEMTEST_END                 0x01000000
-#define CONFIG_SYS_LOAD_ADDR                   0x100000
+#define CONFIG_SYS_LOAD_ADDR                   0x02000000
 
 /*-----------------------------------------------------------------------
  * SDRAM Configuration
 #define CONFIG_SYS_MONITOR_BASE                CONFIG_SYS_TEXT_BASE
 #define CONFIG_SYS_MONITOR_LEN                 (256 * 1024)
 #define CONFIG_SYS_MALLOC_LEN                  (0x20000 + 128 * 1024)
-
+#define CONFIG_SYS_MALLOC_F_LEN                        (1 << 10)
 
 /* allow to overwrite serial and ethaddr */
 #define CONFIG_ENV_OVERWRITE
  */
 #define CONFIG_PCI
 
+#define CONFIG_CROS_EC
+#define CONFIG_CROS_EC_LPC
+#define CONFIG_CMD_CROS_EC
+#define CONFIG_ARCH_EARLY_INIT_R
+
 /*-----------------------------------------------------------------------
  * USB configuration
  */
 #define CONFIG_USB_HOST_ETHER
 #define CONFIG_USB_ETHER_ASIX
 #define CONFIG_USB_ETHER_SMSC95XX
+#define CONFIG_TFTP_TSIZE
+#define CONFIG_CMD_DHCP
+#define CONFIG_BOOTP_BOOTFILESIZE
+#define CONFIG_BOOTP_BOOTPATH
+#define CONFIG_BOOTP_GATEWAY
+#define CONFIG_BOOTP_HOSTNAME
 
 #define CONFIG_CMD_USB
 
index 12b32967b437a719ec3df28fa488a3fd18ce094b..72b7efa5092c51cc00016ba5777c66e647952ec7 100644 (file)
@@ -57,6 +57,7 @@
 #define CONFIG_SYS_FSL_CPC             /* Corenet Platform Cache */
 #define CONFIG_SYS_NUM_CPC             CONFIG_NUM_DDR_CONTROLLERS
 #define CONFIG_FSL_ELBC                        /* Has Enhanced localbus controller */
+#define CONFIG_FSL_CAAM                        /* Enable SEC/CAAM */
 #define CONFIG_PCI                     /* Enable PCI/PCIE */
 #define CONFIG_PCIE1                   /* PCIE controler 1 */
 #define CONFIG_PCIE2                   /* PCIE controler 2 */
 #define CONFIG_DOS_PARTITION
 #endif
 
+/* Hash command with SHA acceleration supported in hardware */
+#ifdef CONFIG_FSL_CAAM
+#define CONFIG_CMD_HASH
+#define CONFIG_SHA_HW_ACCEL
+#endif
+
 /*
  * Miscellaneous configurable options
  */
 
 #include <asm/fsl_secure_boot.h>
 
+#ifdef CONFIG_SECURE_BOOT
+#define CONFIG_CMD_BLOB
+#endif
+
 #endif /* __CONFIG_H */
diff --git a/include/configs/db-mv784mp-gp.h b/include/configs/db-mv784mp-gp.h
new file mode 100644 (file)
index 0000000..cb03e33
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2014 Stefan Roese <sr@denx.de>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#ifndef _CONFIG_DB_MV7846MP_GP_H
+#define _CONFIG_DB_MV7846MP_GP_H
+
+/*
+ * High Level Configuration Options (easy to change)
+ */
+#define CONFIG_ARMADA_XP               /* SOC Family Name */
+#define CONFIG_SKIP_LOWLEVEL_INIT      /* disable board lowlevel_init */
+#define CONFIG_SYS_GENERIC_BOARD
+#define CONFIG_DISPLAY_BOARDINFO_LATE
+
+#define        CONFIG_SYS_TEXT_BASE    0x04000000
+#define CONFIG_SYS_TCLK                250000000       /* 250MHz */
+
+/*
+ * Commands configuration
+ */
+#define CONFIG_SYS_NO_FLASH            /* Declare no flash (NOR/SPI) */
+#include <config_cmd_default.h>
+#define CONFIG_CMD_DHCP
+#define CONFIG_CMD_ENV
+#define CONFIG_CMD_I2C
+#define CONFIG_CMD_PING
+#define CONFIG_CMD_SF
+#define CONFIG_CMD_SPI
+#define CONFIG_CMD_TFTPPUT
+#define CONFIG_CMD_TIME
+
+/* I2C */
+#define CONFIG_SYS_I2C
+#define CONFIG_SYS_I2C_MVTWSI
+#define CONFIG_I2C_MVTWSI_BASE         MVEBU_TWSI_BASE
+#define CONFIG_SYS_I2C_SLAVE           0x0
+#define CONFIG_SYS_I2C_SPEED           100000
+
+/* SPI NOR flash default params, used by sf commands */
+#define CONFIG_SF_DEFAULT_SPEED                1000000
+#define CONFIG_SF_DEFAULT_MODE         SPI_MODE_3
+#define CONFIG_SPI_FLASH_STMICRO
+
+/* Environment in SPI NOR flash */
+#define CONFIG_ENV_IS_IN_SPI_FLASH
+#define CONFIG_ENV_OFFSET              (1 << 20) /* 1MiB in */
+#define CONFIG_ENV_SIZE                        (64 << 10) /* 64KiB */
+#define CONFIG_ENV_SECT_SIZE           (64 << 10) /* 64KiB sectors */
+
+#define CONFIG_PHY_MARVELL             /* there is a marvell phy */
+#define CONFIG_PHY_BASE_ADDR   0x10
+#define CONFIG_SYS_NETA_INTERFACE_TYPE PHY_INTERFACE_MODE_QSGMII
+#define PHY_ANEG_TIMEOUT       8000    /* PHY needs a longer aneg time */
+#define CONFIG_RESET_PHY_R
+
+#define CONFIG_SYS_CONSOLE_INFO_QUIET  /* don't print console @ startup */
+#define CONFIG_SYS_ALT_MEMTEST
+
+/*
+ * mv-common.h should be defined after CMD configs since it used them
+ * to enable certain macros
+ */
+#include "mv-common.h"
+
+#endif /* _CONFIG_DB_MV7846MP_GP_H */
index 37bdcc0f3320a447b096ec9c553cad579929e1ca..47a8420f42d37cf8a9d9d4614a25b255254e1c82 100644 (file)
@@ -89,7 +89,6 @@
 #define CONFIG_EP93XX          1               /* in a Cirrus Logic 93xx SoC */
 
 #define CONFIG_SYS_CLK_FREQ    14745600        /* EP93xx has a 14.7456 clock */
-#define CONFIG_SYS_HZ          1000            /* decr freq: 1 ms ticks */
 #undef CONFIG_USE_IRQ                          /* Don't need IRQ/FIQ */
 
 /* Monitor configuration */
index 371f32d84095bb803422a7f22428ed8c373b7b2d..6ba9bb7a1b15252fe56049ee1af3833609dee66e 100644 (file)
 #include <linux/sizes.h>
 
 #define CONFIG_SYS_GENERIC_BOARD
+#define CONFIG_DM
+#define CONFIG_CMD_DM
+#define CONFIG_DM_GPIO
+#define CONFIG_DM_SERIAL
+#define CONFIG_DM_SPI
+#define CONFIG_DM_SPI_FLASH
+
 #define CONFIG_ARCH_CPU_INIT
 #define CONFIG_DISPLAY_CPUINFO
 #define CONFIG_DISPLAY_BOARDINFO
index 3502d104720a6a938a38902df8212f783bd16f28..7c8065ad187e8bc5ed9fac5b19e08ed9c5d8a50d 100644 (file)
 /* NAND Configuration */
 #define CONFIG_SYS_NAND_PAGE_2K
 
+/* Network */
+#define CONFIG_DRIVER_TI_KEYSTONE_NET
+#define CONFIG_TI_KSNAV
+#define CONFIG_KSNAV_PKTDMA_NETCP
+#define CONFIG_KSNET_NETCP_V1_5
+#define CONFIG_KSNET_CPSW_NUM_PORTS    9
+#define CONFIG_KSNET_MDIO_PHY_CONFIG_ENABLE
+
+/* SerDes */
+#define CONFIG_TI_KEYSTONE_SERDES
+
 #endif /* __CONFIG_K2E_EVM_H */
index 8aa616da0e0d7ce717440e4eaa46fb04f71b891a..034cbfd4d7815ec283cf4fbeab64fe2fdd40ef13 100644 (file)
 
 /* Network */
 #define CONFIG_DRIVER_TI_KEYSTONE_NET
+#define CONFIG_TI_KSNAV
+#define CONFIG_KSNAV_PKTDMA_NETCP
+#define CONFIG_KSNET_NETCP_V1_0
+#define CONFIG_KSNET_CPSW_NUM_PORTS    5
+
+/* SerDes */
+#define CONFIG_TI_KEYSTONE_SERDES
 
 #endif /* __CONFIG_K2HK_EVM_H */
diff --git a/include/configs/k2l_evm.h b/include/configs/k2l_evm.h
new file mode 100644 (file)
index 0000000..0e1f725
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Configuration header file for TI's k2l-evm
+ *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#ifndef __CONFIG_K2L_EVM_H
+#define __CONFIG_K2L_EVM_H
+
+/* Platform type */
+#define CONFIG_SOC_K2L
+#define CONFIG_K2L_EVM
+
+/* U-Boot general configuration */
+#define CONFIG_SYS_PROMPT              "K2L EVM # "
+
+#define KS2_ARGS_UBI   "args_ubi=setenv bootargs ${bootargs} rootfstype=ubifs "\
+                      "root=ubi0:rootfs rootflags=sync rw ubi.mtd=2,4096\0"
+
+#define KS2_FDT_NAME   "name_fdt=k2l-evm.dtb\0"
+#define KS2_ADDR_MON   "addr_mon=0x0c140000\0"
+#define KS2_NAME_MON   "name_mon=skern-k2l-evm.bin\0"
+#define NAME_UBOOT     "name_uboot=u-boot-spi-k2l-evm.gph\0"
+#define NAME_UBI       "name_ubi=k2l-evm-ubifs.ubi\0"
+
+#include <configs/ks2_evm.h>
+
+/* SPL SPI Loader Configuration */
+#define CONFIG_SPL_TEXT_BASE           0x0c100000
+
+/* NAND Configuration */
+#define CONFIG_SYS_NAND_PAGE_4K
+
+#endif /* __CONFIG_K2L_EVM_H */
index 51926f721f17e6305d408dfe2e08d1816e97a5cd..b0c91d8dcb599a6f91ff0b32ba4b968e68aed0cb 100644 (file)
@@ -23,7 +23,6 @@
 #define CONFIG_ARMV7
 #define CONFIG_ARCH_CPU_INIT
 #define CONFIG_SYS_ARCH_TIMER
-#define CONFIG_SYS_HZ                  1000
 #define CONFIG_SYS_TEXT_BASE           0x0c001000
 #define CONFIG_SPL_TARGET              "u-boot-spi.gph"
 #define CONFIG_SYS_DCACHE_OFF
@@ -92,6 +91,8 @@
 #define CONFIG_SYS_SPI2_NUM_CS         4
 
 /* Network Configuration */
+#define CONFIG_PHYLIB
+#define CONFIG_PHY_MARVELL
 #define CONFIG_MII
 #define CONFIG_BOOTP_DEFAULT
 #define CONFIG_BOOTP_DNS
 #define CONFIG_BOOTP_SEND_HOSTNAME
 #define CONFIG_NET_RETRY_COUNT         32
 #define CONFIG_NET_MULTI
-#define CONFIG_GET_LINK_STATUS_ATTEMPTS        5
 #define CONFIG_SYS_SGMII_REFCLK_MHZ    312
 #define CONFIG_SYS_SGMII_LINERATE_MHZ  1250
 #define CONFIG_SYS_SGMII_RATESCALE     2
 
+/* Keyston Navigator Configuration */
+#define CONFIG_KSNAV_QM_BASE_ADDRESS           KS2_QM_BASE_ADDRESS
+#define CONFIG_KSNAV_QM_CONF_BASE              KS2_QM_CONF_BASE
+#define CONFIG_KSNAV_QM_DESC_SETUP_BASE                KS2_QM_DESC_SETUP_BASE
+#define CONFIG_KSNAV_QM_STATUS_RAM_BASE                KS2_QM_STATUS_RAM_BASE
+#define CONFIG_KSNAV_QM_INTD_CONF_BASE         KS2_QM_INTD_CONF_BASE
+#define CONFIG_KSNAV_QM_PDSP1_CMD_BASE         KS2_QM_PDSP1_CMD_BASE
+#define CONFIG_KSNAV_QM_PDSP1_CTRL_BASE                KS2_QM_PDSP1_CTRL_BASE
+#define CONFIG_KSNAV_QM_PDSP1_IRAM_BASE                KS2_QM_PDSP1_IRAM_BASE
+#define CONFIG_KSNAV_QM_MANAGER_QUEUES_BASE    KS2_QM_MANAGER_QUEUES_BASE
+#define CONFIG_KSNAV_QM_MANAGER_Q_PROXY_BASE   KS2_QM_MANAGER_Q_PROXY_BASE
+#define CONFIG_KSNAV_QM_QUEUE_STATUS_BASE      KS2_QM_QUEUE_STATUS_BASE
+#define CONFIG_KSNAV_QM_LINK_RAM_BASE          KS2_QM_LINK_RAM_BASE
+#define CONFIG_KSNAV_QM_REGION_NUM             KS2_QM_REGION_NUM
+#define CONFIG_KSNAV_QM_QPOOL_NUM              KS2_QM_QPOOL_NUM
+
+/* NETCP pktdma */
+#define CONFIG_KSNAV_NETCP_PDMA_CTRL_BASE      KS2_NETCP_PDMA_CTRL_BASE
+#define CONFIG_KSNAV_NETCP_PDMA_TX_BASE                KS2_NETCP_PDMA_TX_BASE
+#define CONFIG_KSNAV_NETCP_PDMA_TX_CH_NUM      KS2_NETCP_PDMA_TX_CH_NUM
+#define CONFIG_KSNAV_NETCP_PDMA_RX_BASE                KS2_NETCP_PDMA_RX_BASE
+#define CONFIG_KSNAV_NETCP_PDMA_RX_CH_NUM      KS2_NETCP_PDMA_RX_CH_NUM
+#define CONFIG_KSNAV_NETCP_PDMA_SCHED_BASE     KS2_NETCP_PDMA_SCHED_BASE
+#define CONFIG_KSNAV_NETCP_PDMA_RX_FLOW_BASE   KS2_NETCP_PDMA_RX_FLOW_BASE
+#define CONFIG_KSNAV_NETCP_PDMA_RX_FLOW_NUM    KS2_NETCP_PDMA_RX_FLOW_NUM
+#define CONFIG_KSNAV_NETCP_PDMA_RX_FREE_QUEUE  KS2_NETCP_PDMA_RX_FREE_QUEUE
+#define CONFIG_KSNAV_NETCP_PDMA_RX_RCV_QUEUE   KS2_NETCP_PDMA_RX_RCV_QUEUE
+#define CONFIG_KSNAV_NETCP_PDMA_TX_SND_QUEUE   KS2_NETCP_PDMA_TX_SND_QUEUE
+
+/* Keystone net */
+#define CONFIG_KSNET_MAC_ID_BASE               KS2_MAC_ID_BASE_ADDR
+#define CONFIG_KSNET_NETCP_BASE                        KS2_NETCP_BASE
+#define CONFIG_KSNET_SERDES_SGMII_BASE         KS2_SGMII_SERDES_BASE
+#define CONFIG_KSNET_SERDES_SGMII2_BASE                KS2_SGMII_SERDES2_BASE
+#define CONFIG_KSNET_SERDES_LANES_PER_SGMII    KS2_LANES_PER_SGMII_SERDES
+
 /* AEMIF */
 #define CONFIG_TI_AEMIF
 #define CONFIG_AEMIF_CNTRL_BASE                KS2_AEMIF_CNTRL_BASE
                                        "1024k(bootloader)ro,512k(params)ro," \
                                        "-(ubifs)"
 
+/* USB Configuration */
+#define CONFIG_USB_XHCI
+#define CONFIG_USB_XHCI_KEYSTONE
+#define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS     2
+#define CONFIG_USB_STORAGE
+#define CONFIG_DOS_PARTITION
+#define CONFIG_EFI_PARTITION
+#define CONFIG_FS_FAT
+#define CONFIG_SYS_CACHELINE_SIZE              64
+#define CONFIG_USB_SS_BASE                     KS2_USB_SS_BASE
+#define CONFIG_USB_HOST_XHCI_BASE              KS2_USB_HOST_XHCI_BASE
+#define CONFIG_DEV_USB_PHY_BASE                        KS2_DEV_USB_PHY_BASE
+#define CONFIG_USB_PHY_CFG_BASE                        KS2_USB_PHY_CFG_BASE
+
 /* U-Boot command configuration */
 #include <config_cmd_default.h>
 #define CONFIG_CMD_ASKENV
 #define CONFIG_CMD_UBIFS
 #define CONFIG_CMD_SF
 #define CONFIG_CMD_EEPROM
+#define CONFIG_CMD_USB
 
 /* U-Boot general configuration */
 #define CONFIG_SYS_GENERIC_BOARD
+#define CONFIG_MISC_INIT_R
 #define CONFIG_SYS_CBSIZE              1024
 #define CONFIG_SYS_PBSIZE              2048
 #define CONFIG_SYS_MAXARGS             16
 #include <asm/arch/clock.h>
 #define CONFIG_SYS_HZ_CLOCK            clk_get_rate(KS2_CLK1_6)
 
-/* Maximum memory size for relocated U-boot at the end of the DDR3 memory
-   which is NOT applicable for DDR ECC test */
-#define CONFIG_MAX_UBOOT_MEM_SIZE      (4 << 20)       /* 4 MiB */
-
 #endif /* __CONFIG_KS2_EVM_H */
index bb4781334537b579bc07b52ab76cba69f79b5ea6..d1f6ea7e7b0e6d5f1efcda54eca34af3cd3d3b3c 100644 (file)
@@ -69,6 +69,7 @@ unsigned long get_board_ddr_clk(void);
 
 #define CONFIG_SYS_HAS_SERDES
 
+#define CONFIG_FSL_CAAM                        /* Enable CAAM */
 /*
  * IFC Definitions
  */
@@ -359,7 +360,6 @@ unsigned long get_board_ddr_clk(void);
 #define CONFIG_SYS_MEMTEST_END         0x9fffffff
 
 #define CONFIG_SYS_LOAD_ADDR           0x82000000
-#define CONFIG_SYS_HZ                  1000
 
 /*
  * Stack sizes
@@ -388,4 +388,14 @@ unsigned long get_board_ddr_clk(void);
 #define CONFIG_OF_BOARD_SETUP
 #define CONFIG_CMD_BOOTZ
 
+#define CONFIG_MISC_INIT_R
+
+/* Hash command with SHA acceleration supported in hardware */
+#define CONFIG_CMD_HASH
+#define CONFIG_SHA_HW_ACCEL
+
+#ifdef CONFIG_SECURE_BOOT
+#define CONFIG_CMD_BLOB
+#endif
+
 #endif
index 45b2272ff5bf6f7f390ee6935bc5908b402369eb..3c73af8ac39dc6663fa0db3ed5d91eb9c3601618 100644 (file)
@@ -48,6 +48,8 @@
 
 #define CONFIG_SYS_HAS_SERDES
 
+#define CONFIG_FSL_CAAM                        /* Enable CAAM */
+
 /*
  * IFC Definitions
  */
 #define CONFIG_SYS_MEMTEST_END         0x9fffffff
 
 #define CONFIG_SYS_LOAD_ADDR           0x82000000
-#define CONFIG_SYS_HZ                  1000
 
 /*
  * Stack sizes
 #define CONFIG_OF_BOARD_SETUP
 #define CONFIG_CMD_BOOTZ
 
+#define CONFIG_MISC_INIT_R
+
+/* Hash command with SHA acceleration supported in hardware */
+#define CONFIG_CMD_HASH
+#define CONFIG_SHA_HW_ACCEL
+
+#ifdef CONFIG_SECURE_BOOT
+#define CONFIG_CMD_BLOB
+#endif
+
 #endif
index a72e1f3567d22144383bf94b306bfb0c5f1112cb..6fe032c9ff64fb6b89f107095af3b9f38ca4998b 100644 (file)
 
 #define CONFIG_NR_DRAM_BANKS           3
 
-#define CONFIG_SYS_HZ                  1000
-
 #define CONFIG_HWCONFIG
 #define HWCONFIG_BUFFER_SIZE           128
 
diff --git a/include/configs/maxbcm.h b/include/configs/maxbcm.h
new file mode 100644 (file)
index 0000000..72217bd
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2014 Stefan Roese <sr@denx.de>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#ifndef _CONFIG_DB_MV7846MP_GP_H
+#define _CONFIG_DB_MV7846MP_GP_H
+
+/*
+ * High Level Configuration Options (easy to change)
+ */
+#define CONFIG_ARMADA_XP               /* SOC Family Name */
+#define CONFIG_SKIP_LOWLEVEL_INIT      /* disable board lowlevel_init */
+#define CONFIG_SYS_GENERIC_BOARD
+#define CONFIG_DISPLAY_BOARDINFO_LATE
+
+#define        CONFIG_SYS_TEXT_BASE    0x04000000
+#define CONFIG_SYS_TCLK                250000000       /* 250MHz */
+
+/*
+ * Commands configuration
+ */
+#define CONFIG_SYS_NO_FLASH            /* Declare no flash (NOR/SPI) */
+#include <config_cmd_default.h>
+#define CONFIG_CMD_DHCP
+#define CONFIG_CMD_ENV
+#define CONFIG_CMD_I2C
+#define CONFIG_CMD_PING
+#define CONFIG_CMD_SF
+#define CONFIG_CMD_SPI
+#define CONFIG_CMD_TFTPPUT
+#define CONFIG_CMD_TIME
+
+/* I2C */
+#define CONFIG_SYS_I2C
+#define CONFIG_SYS_I2C_MVTWSI
+#define CONFIG_I2C_MVTWSI_BASE         MVEBU_TWSI_BASE
+#define CONFIG_SYS_I2C_SLAVE           0x0
+#define CONFIG_SYS_I2C_SPEED           100000
+
+/* SPI NOR flash default params, used by sf commands */
+#define CONFIG_SF_DEFAULT_SPEED                1000000
+#define CONFIG_SF_DEFAULT_MODE         SPI_MODE_3
+#define CONFIG_SPI_FLASH_STMICRO
+
+/* Environment in SPI NOR flash */
+#define CONFIG_ENV_IS_IN_SPI_FLASH
+#define CONFIG_ENV_OFFSET              (1 << 20) /* 1MiB in */
+#define CONFIG_ENV_SIZE                        (64 << 10) /* 64KiB */
+#define CONFIG_ENV_SECT_SIZE           (64 << 10) /* 64KiB sectors */
+
+#define CONFIG_PHY_MARVELL             /* there is a marvell phy */
+#define CONFIG_PHY_BASE_ADDR   0x0
+#define CONFIG_SYS_NETA_INTERFACE_TYPE PHY_INTERFACE_MODE_SGMII
+#define PHY_ANEG_TIMEOUT       8000    /* PHY needs a longer aneg time */
+#define CONFIG_RESET_PHY_R
+
+#define CONFIG_SYS_CONSOLE_INFO_QUIET  /* don't print console @ startup */
+#define CONFIG_SYS_ALT_MEMTEST
+
+/*
+ * mv-common.h should be defined after CMD configs since it used them
+ * to enable certain macros
+ */
+#include "mv-common.h"
+
+#endif /* _CONFIG_DB_MV7846MP_GP_H */
index b17e495f5f7915af44e75c8841932299a810e2a2..c58636a5417e765e62ebc7176ffc0d321a2808a6 100644 (file)
 /* TWL4030 LED */
 #define CONFIG_TWL4030_LED
 
+/* USB EHCI */
+#define CONFIG_USB_EHCI
+#define CONFIG_USB_EHCI_OMAP
+#define CONFIG_USB_STORAGE
+#define CONFIG_OMAP_EHCI_PHY1_RESET_GPIO       183
+#define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS     3
+
 /* Initialize GPIOs by default */
 #define CONFIG_OMAP3_GPIO_2    /* GPIO32..63 is in GPIO Bank 2 */
 #define CONFIG_OMAP3_GPIO_3    /* GPIO64..95 is in GPIO Bank 3 */
@@ -44,6 +51,7 @@
 
 /* commands to include */
 #define CONFIG_CMD_CACHE
+#define CONFIG_CMD_USB
 #undef CONFIG_CMD_FPGA         /* FPGA configuration Support   */
 #undef CONFIG_CMD_IMI          /* iminfo                       */
 #undef CONFIG_CMD_NFS          /* NFS support                  */
                "bootz ${loadaddr} - ${fdtaddr}\0" \
        "nandboot=echo Booting from nand ...; " \
                "run nandargs; " \
-               "nand read ${loadaddr} linux; " \
-               "bootm ${loadaddr}\0" \
+               "if nand read ${loadaddr} linux; then " \
+                       "bootm ${loadaddr};" \
+               "fi;\0" \
 
 #define CONFIG_BOOTCOMMAND \
        "mmc dev ${mmcdev}; if mmc rescan; then " \
index ab8ac60df23042084726d1bc53bcd0c07fa14fb2..91bd37d6bca60fb9dfa9bc88ff61da2fad4bf8df 100644 (file)
@@ -38,6 +38,7 @@
 
 #define CONFIG_POWER_TPS65090_EC
 #define CONFIG_CROS_EC_SPI             /* Support CROS_EC over SPI */
+#define CONFIG_DM_CROS_EC
 
 #define CONFIG_USB_XHCI
 #define CONFIG_USB_XHCI_EXYNOS
index a28d7b579a6405a1b7f32e5f9ba7816681a08045..005a853f56822b3d8630cedb51f044c96c81662b 100644 (file)
  *   SoC UART     : enable CONFIG_UNIPHIER_SERIAL
  *   On-board UART: enable CONFIG_SYS_NS16550_SERIAL
  */
-#if 1
-#define CONFIG_UNIPHIER_SERIAL
-#else
+#if 0
 #define CONFIG_SYS_NS16550_SERIAL
 #endif
 
-#define CONFIG_SYS_UNIPHIER_UART_CLK    36864000
-
 #define CONFIG_SMC911X
 
 #define CONFIG_DDR_NUM_CH0 1
index b79967f7da477c351e307f2b1dc879f8932a037e..7dd6fd2a9292d8bdd73c33b5371218f25b07f128 100644 (file)
  *   SoC UART     : enable CONFIG_UNIPHIER_SERIAL
  *   On-board UART: enable CONFIG_SYS_NS16550_SERIAL
  */
-#if 1
-#define CONFIG_UNIPHIER_SERIAL
-#else
+#if 0
 #define CONFIG_SYS_NS16550_SERIAL
 #endif
 
-#define CONFIG_SYS_UNIPHIER_UART_CLK    73728000
-
 #define CONFIG_SMC911X
 
 #define CONFIG_DDR_NUM_CH0 2
index 9d391f1d74a2650b4d53ab5730e55aa7553866cd..1062aace38a7970772e6f16ed68f8a66c664ee10 100644 (file)
  *   SoC UART     : enable CONFIG_UNIPHIER_SERIAL
  *   On-board UART: enable CONFIG_SYS_NS16550_SERIAL
  */
-#if 1
-#define CONFIG_UNIPHIER_SERIAL
-#else
+#if 0
 #define CONFIG_SYS_NS16550_SERIAL
 #endif
 
-#define CONFIG_SYS_UNIPHIER_UART_CLK    80000000
-
 #define CONFIG_SMC911X
 
 #define CONFIG_DDR_NUM_CH0 1
index 2d698094800f2c7bbc50d6f7b8ef63e27b5b7742..ca27f9ad787008c507241464aadbbf191286a83f 100644 (file)
  */
 #define CONFIG_MACH_TYPE               MACH_TYPE_BCM2708
 
+/* Enable driver model */
+#define CONFIG_DM
+#define CONFIG_CMD_DM
+#define CONFIG_DM_GPIO
+
 /* Memory layout */
 #define CONFIG_NR_DRAM_BANKS           1
 #define CONFIG_SYS_SDRAM_BASE          0x00000000
 #define CONFIG_MMC_SDHCI_IO_ACCESSORS
 #define CONFIG_BCM2835_SDHCI
 
+#define CONFIG_CMD_USB
+#ifdef CONFIG_CMD_USB
+#define CONFIG_USB_DWC2
+#define CONFIG_USB_DWC2_REG_ADDR 0x20980000
+#define CONFIG_USB_STORAGE
+#define CONFIG_USB_HOST_ETHER
+#define CONFIG_USB_ETHER_SMSC95XX
+#define CONFIG_MISC_INIT_R
+#endif
+
 /* Console UART */
 #define CONFIG_PL011_SERIAL
 #define CONFIG_PL011_CLOCK             3000000
 
 /* Some things don't make sense on this HW or yet */
 #undef CONFIG_CMD_FPGA
-#undef CONFIG_CMD_NET
-#undef CONFIG_CMD_NFS
 #undef CONFIG_CMD_SAVEENV
-#undef CONFIG_CMD_DHCP
-#undef CONFIG_CMD_MII
-#undef CONFIG_CMD_NET
-#undef CONFIG_CMD_PING
 
 /* Environment */
 #define ENV_DEVICE_SETTINGS \
        "ramdisk_addr_r=0x02100000\0" \
 
 #define BOOT_TARGET_DEVICES(func) \
-       func(MMC, mmc, 0)
+       func(MMC, mmc, 0) \
+       func(USB, usb, 0) \
+       func(PXE, pxe, na) \
+       func(DHCP, dhcp, na)
 #include <config_distro_bootcmd.h>
 
 #define CONFIG_EXTRA_ENV_SETTINGS \
index 0c6e9c7878477048b4e4e69bb9f3510f33f72563..3633a355bd7f83b04bb65a30b731029376b5bff9 100644 (file)
 #define CONFIG_SYS_I2C_SOFT_SPEED      50000
 #define CONFIG_SYS_I2C_SOFT_SLAVE      0x7F
 #define CONFIG_I2C_MULTI_BUS
+#define CONFIG_SYS_I2C_INIT_BOARD
+
 #define CONFIG_SYS_MAX_I2C_BUS 7
 #define CONFIG_USB_GADGET
 #define CONFIG_USB_GADGET_S3C_UDC_OTG
 
 #define CONFIG_OF_LIBFDT
 
+#define CONFIG_SYS_GENERIC_BOARD
+#define CONFIG_DM
+#define CONFIG_CMD_DM
+#define CONFIG_DM_GPIO
+#define CONFIG_DM_SERIAL
+
 #endif /* __CONFIG_H */
index 27f3d0af47105668009a9dd78677c4c2b06eb79e..4b30d148c31d4882aee8c544f2d724ca67130245 100644 (file)
  * SPI Settings
  */
 #define CONFIG_SOFT_SPI
-#define CONFIG_SOFT_SPI_MODE SPI_MODE_3
-#define CONFIG_SOFT_SPI_GPIO_SCLK EXYNOS4_GPIO_Y31
-#define CONFIG_SOFT_SPI_GPIO_MOSI EXYNOS4_GPIO_Y33
-#define CONFIG_SOFT_SPI_GPIO_MISO EXYNOS4_GPIO_Y30
-#define CONFIG_SOFT_SPI_GPIO_CS EXYNOS4_GPIO_Y43
-
-#define SPI_DELAY udelay(1)
-#undef SPI_INIT
-#define SPI_SCL(bit) universal_spi_scl(bit)
-#define SPI_SDA(bit) universal_spi_sda(bit)
-#define SPI_READ universal_spi_read()
+
 #ifndef        __ASSEMBLY__
 void universal_spi_scl(int bit);
 void universal_spi_sda(int bit);
index b5064ab37c05f2c807bb9106ec667bb0c3293501..2dee315f91e761449314c6385881a6b6fe09739f 100644 (file)
 #define I2C_MOSI       0x00004000      /* PD 17: Master Out, Slave In */
 #define I2C_MISO       0x00008000      /* PD 16: Master In, Slave Out */
 
-#undef  SPI_INIT                       /* no port initialization needed */
 #define SPI_READ        ((immr->im_ioport.iop_pdatd & I2C_MISO) != 0)
 #define SPI_SDA(bit)    do {                                           \
                        if(bit) immr->im_ioport.iop_pdatd |=  I2C_MOSI; \
index 69726432a3c922a467b55495c31d01d831b069cb..ee4b24473cd27b37f803f10a4b3efccd0a000d8c 100644 (file)
@@ -32,6 +32,7 @@
 #define CONFIG_DM_GPIO
 #define CONFIG_DM_TEST
 #define CONFIG_DM_SERIAL
+#define CONFIG_DM_CROS_EC
 
 #define CONFIG_SYS_STDIO_DEREGISTER
 
@@ -97,8 +98,8 @@
 #define CONFIG_CMD_SF_TEST
 #define CONFIG_CMD_SPI
 #define CONFIG_SPI_FLASH
-#define CONFIG_OF_SPI
-#define CONFIG_OF_SPI_FLASH
+#define CONFIG_DM_SPI
+#define CONFIG_DM_SPI_FLASH
 #define CONFIG_SPI_FLASH_ATMEL
 #define CONFIG_SPI_FLASH_EON
 #define CONFIG_SPI_FLASH_GIGADEVICE
 #define CONFIG_CONSOLE_MUX
 #define CONFIG_SYS_CONSOLE_IS_IN_ENV
 #define LCD_BPP                        LCD_COLOR16
+#define CONFIG_LCD_BMP_RLE8
 
 #define CONFIG_CROS_EC_KEYB
 #define CONFIG_KEYBOARD
index 22835ffd6403a795cb04e1bfa6390bb9c206cf5a..982d0dcea397737fa5aca1dc1b167c213c163858 100644 (file)
 
 #define CONFIG_OF_LIBFDT
 
+#define CONFIG_SYS_GENERIC_BOARD
+#define CONFIG_DM
+#define CONFIG_CMD_DM
+#define CONFIG_DM_GPIO
+#define CONFIG_DM_SERIAL
+
 #endif /* __CONFIG_H */
index 49504dcafbc23278000c965058364b892b59c931..83a1bcdfbe34354980713f7e1c01e2c2ec788c7e 100644 (file)
@@ -22,7 +22,7 @@
 #define CONFIG_DISPLAY_CPUINFO
 #define CONFIG_DISPLAY_BOARDINFO
 #define CONFIG_BOARD_EARLY_INIT_F
-#define CONFIG_MISC_INIT_R
+#define CONFIG_ARCH_EARLY_INIT_R
 #define CONFIG_SYS_NO_FLASH
 #define CONFIG_CLOCKS
 
 #define CONFIG_CONS_INDEX              1
 #define CONFIG_BAUDRATE                        115200
 
+/*
+ * USB
+ */
+#ifdef CONFIG_CMD_USB
+#define CONFIG_USB_DWC2
+#define CONFIG_USB_STORAGE
+/*
+ * NOTE: User must define either of the following to select which
+ *       of the two USB controllers available on SoCFPGA to use.
+ *       The DWC2 driver doesn't support multiple USB controllers.
+ * #define CONFIG_USB_DWC2_REG_ADDR    SOCFPGA_USB0_ADDRESS
+ * #define CONFIG_USB_DWC2_REG_ADDR    SOCFPGA_USB1_ADDRESS
+ */
+#endif
+
 /*
  * U-Boot environment
  */
 
 /*
  * SPL
+ *
+ * SRAM Memory layout:
+ *
+ * 0xFFFF_0000 ...... Start of SRAM
+ * 0xFFFF_xxxx ...... Top of stack (grows down)
+ * 0xFFFF_yyyy ...... Malloc area
+ * 0xFFFF_zzzz ...... Global Data
+ * 0xFFFF_FF00 ...... End of SRAM
  */
 #define CONFIG_SPL_FRAMEWORK
 #define CONFIG_SPL_BOARD_INIT
 #define CONFIG_SPL_RAM_DEVICE
-#define CONFIG_SPL_TEXT_BASE           0xFFFF0000
-#define CONFIG_SPL_STACK               CONFIG_SYS_INIT_SP_ADDR
-#define CONFIG_SPL_STACK_SIZE          (4 * 1024)
-#define CONFIG_SPL_MALLOC_SIZE         (5 * 1024)      /* FIXME */
-#define CONFIG_SYS_SPL_MALLOC_START    ((unsigned long) (&__malloc_start))
-#define CONFIG_SYS_SPL_MALLOC_SIZE     (&__malloc_end - &__malloc_start)
+#define CONFIG_SPL_TEXT_BASE           CONFIG_SYS_INIT_RAM_ADDR
+#define CONFIG_SYS_SPL_MALLOC_START    CONFIG_SYS_INIT_SP_ADDR
+#define CONFIG_SYS_SPL_MALLOC_SIZE     (5 * 1024)
 
 #define CHUNKSZ_CRC32                  (1 * 1024)      /* FIXME: ewww */
 #define CONFIG_CRC32_VERIFY
index 60d7e20e83b2678254e129127f221b5e6a74d0c4..942738c138bef60597e12fcefb5b70c90d18a109 100644 (file)
 #if defined(CONFIG_CMD_NET)
 #define CONFIG_EMAC_BASE               SOCFPGA_EMAC1_ADDRESS
 #define CONFIG_PHY_INTERFACE_MODE      PHY_INTERFACE_MODE_RGMII
-#define CONFIG_EPHY0_PHY_ADDR          0
 
 /* PHY */
-#define CONFIG_EPHY1_PHY_ADDR          4
 #define CONFIG_PHY_MICREL
 #define CONFIG_PHY_MICREL_KSZ9021
 #define CONFIG_KSZ9021_CLK_SKEW_ENV    "micrel-ksz9021-clk-skew"
index 5611ecc85f22bf3f3d949211c54cabc3eb54db92..d0191a32b1a6d99807cf75becf4821f2e6879cfd 100644 (file)
@@ -15,6 +15,7 @@
 #define CONFIG_CLK_FULL_SPEED          1008000000
 
 #define CONFIG_SYS_PROMPT              "sun4i# "
+#define CONFIG_MACH_TYPE               4104
 
 #ifdef CONFIG_USB_EHCI
 #define CONFIG_USB_EHCI_SUNXI
index 6066371a17d8d172c62d00cff4f4a508c5de53ee..7b683e9c8908394e56072d545f873d0e5f798c6a 100644 (file)
@@ -15,6 +15,7 @@
 #define CONFIG_CLK_FULL_SPEED          1008000000
 
 #define CONFIG_SYS_PROMPT              "sun5i# "
+#define CONFIG_MACH_TYPE               4138
 
 #ifdef CONFIG_USB_EHCI
 #define CONFIG_USB_EHCI_SUNXI
diff --git a/include/configs/sun6i.h b/include/configs/sun6i.h
new file mode 100644 (file)
index 0000000..93a1d96
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * (C) Copyright 2012-2013 Henrik Nordstrom <henrik@henriknordstrom.net>
+ * (C) Copyright 2013 Luke Kenneth Casson Leighton <lkcl@lkcl.net>
+ * (C) Copyright 2013 Maxime Ripard <maxime.ripard@free-electrons.com>
+ *
+ * Configuration settings for the Allwinner A31 (sun6i) CPU
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/*
+ * A31 specific configuration
+ */
+#define CONFIG_SUN6I           /* sun6i SoC generation */
+
+#define CONFIG_SYS_PROMPT              "sun6i# "
+
+/*
+ * Include common sunxi configuration where most the settings are
+ */
+#include <configs/sunxi-common.h>
+
+#endif /* __CONFIG_H */
index a902b845744707e64fb5a064c6039bc93b0150d9..966cbd8e83f6cb2659f64798cfeb502a1b5e6aa4 100644 (file)
@@ -16,6 +16,7 @@
 #define CONFIG_CLK_FULL_SPEED          912000000
 
 #define CONFIG_SYS_PROMPT              "sun7i# "
+#define CONFIG_MACH_TYPE               4283
 
 #ifdef CONFIG_USB_EHCI
 #define CONFIG_USB_EHCI_SUNXI
diff --git a/include/configs/sun8i.h b/include/configs/sun8i.h
new file mode 100644 (file)
index 0000000..1c1a7cd
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * (C) Copyright 2014 Chen-Yu Tsai <wens@csie.org>
+ *
+ * Configuration settings for the Allwinner A23 (sun8i) CPU
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/*
+ * A23 specific configuration
+ */
+#define CONFIG_SUN8I           /* sun8i SoC generation */
+#define CONFIG_SYS_PROMPT      "sun8i# "
+
+/*
+ * Include common sunxi configuration where most the settings are
+ */
+#include <configs/sunxi-common.h>
+
+#endif /* __CONFIG_H */
index 1d947d7d9eab39030964f4d6b1e14e678303e55e..cc450e02e67e041b248a47c84c05aa1a5325c57b 100644 (file)
@@ -42,6 +42,7 @@
 #define CONFIG_SYS_NS16550_COM2                SUNXI_UART1_BASE
 #define CONFIG_SYS_NS16550_COM3                SUNXI_UART2_BASE
 #define CONFIG_SYS_NS16550_COM4                SUNXI_UART3_BASE
+#define CONFIG_SYS_NS16550_COM5                SUNXI_R_UART_BASE
 
 /* DRAM Base */
 #define CONFIG_SYS_SDRAM_BASE          0x40000000
@@ -77,6 +78,7 @@
 #define CONFIG_INITRD_TAG
 
 /* mmc config */
+#if !defined(CONFIG_UART0_PORT_F)
 #define CONFIG_MMC
 #define CONFIG_GENERIC_MMC
 #define CONFIG_CMD_MMC
@@ -84,6 +86,7 @@
 #define CONFIG_MMC_SUNXI_SLOT          0
 #define CONFIG_ENV_IS_IN_MMC
 #define CONFIG_SYS_MMC_ENV_DEV         0       /* first detected MMC controller */
+#endif
 
 /* 4MB of malloc() pool */
 #define CONFIG_SYS_MALLOC_LEN          (CONFIG_ENV_SIZE + (4 << 20))
@@ -92,8 +95,8 @@
  * Miscellaneous configurable options
  */
 #define CONFIG_CMD_ECHO
-#define CONFIG_SYS_CBSIZE      256     /* Console I/O Buffer Size */
-#define CONFIG_SYS_PBSIZE      384     /* Print Buffer Size */
+#define CONFIG_SYS_CBSIZE      1024    /* Console I/O Buffer Size */
+#define CONFIG_SYS_PBSIZE      1024    /* Print Buffer Size */
 #define CONFIG_SYS_MAXARGS     16      /* max number of command args */
 #define CONFIG_SYS_GENERIC_BOARD
 
 /* standalone support */
 #define CONFIG_STANDALONE_LOAD_ADDR    0x42000000
 
-#define CONFIG_SYS_HZ                  1000
-
 /* baudrate */
 #define CONFIG_BAUDRATE                        115200
 
 
 /* GPIO */
 #define CONFIG_SUNXI_GPIO
+#define CONFIG_SPL_GPIO_SUPPORT
 #define CONFIG_CMD_GPIO
 
 /* Ethernet support */
        "pxefile_addr_r=0x43200000\0" \
        "ramdisk_addr_r=0x43300000\0"
 
+#ifdef CONFIG_MMC
+#define BOOT_TARGET_DEVICES_MMC(func) func(MMC, mmc, 0)
+#else
+#define BOOT_TARGET_DEVICES_MMC(func)
+#endif
+
 #ifdef CONFIG_AHCI
 #define BOOT_TARGET_DEVICES_SCSI(func) func(SCSI, scsi, 0)
 #else
 #define BOOT_TARGET_DEVICES_SCSI(func)
 #endif
 
+#ifdef CONFIG_USB_EHCI
+#define BOOT_TARGET_DEVICES_USB(func) func(USB, usb, 0)
+#else
+#define BOOT_TARGET_DEVICES_USB(func)
+#endif
+
 #define BOOT_TARGET_DEVICES(func) \
-       func(MMC, mmc, 0) \
+       BOOT_TARGET_DEVICES_MMC(func) \
        BOOT_TARGET_DEVICES_SCSI(func) \
-       func(USB, usb, 0) \
+       BOOT_TARGET_DEVICES_USB(func) \
        func(PXE, pxe, na) \
        func(DHCP, dhcp, na)
 
index 23e3c8af31a8a758b6027d1810f0adce4b8f558a..c3ad8beb903d9e131ae596ee98fbb725297614ec 100644 (file)
@@ -59,7 +59,7 @@
        BOARD_EXTRA_ENV_SETTINGS
 
 #if defined(CONFIG_TEGRA20_SFLASH) || defined(CONFIG_TEGRA20_SLINK) || defined(CONFIG_TEGRA114_SPI)
-#define CONFIG_FDT_SPI
+#define CONFIG_TEGRA_SPI
 #endif
 
 /* overrides for SPL build here */
 
 #define CONFIG_SKIP_LOWLEVEL_INIT
 
-/* remove devicetree support */
-#ifdef CONFIG_OF_CONTROL
-#endif
-
 /* remove I2C support */
 #ifdef CONFIG_SYS_I2C_TEGRA
 #undef CONFIG_SYS_I2C_TEGRA
index 834b3d5686c159b019b5c4661bfa943e0dc45957..5d2b12a11d1ef1e1494fa76ae14f5eeae8401797 100644 (file)
@@ -24,6 +24,8 @@
 #ifndef CONFIG_SPL_BUILD
 #define CONFIG_DM_SERIAL
 #endif
+#define CONFIG_DM_SPI
+#define CONFIG_DM_SPI_FLASH
 
 #define CONFIG_SYS_TIMER_RATE          1000000
 #define CONFIG_SYS_TIMER_COUNTER       NV_PA_TMRUS_BASE
 #define CONFIG_SYS_MEMTEST_START       (NV_PA_SDRC_CS0 + 0x600000)
 #define CONFIG_SYS_MEMTEST_END         (CONFIG_SYS_MEMTEST_START + 0x100000)
 
+#define CONFIG_USE_ARCH_MEMCPY
+
 /*-----------------------------------------------------------------------
  * Physical Memory Map
  */
 #define CONFIG_SPL_SERIAL_SUPPORT
 #define CONFIG_SPL_GPIO_SUPPORT
 
-#ifdef CONFIG_SPL_BUILD
-# define CONFIG_USE_PRIVATE_LIBGCC
-#endif
-
 #define CONFIG_SYS_GENERIC_BOARD
 
 /* Misc utility code */
index 80976e7e3b84ecddc3ea767f3416763ce37b6eda..5ed86d9365cd08aee392bbe77e7c7bf84e5c9ad6 100644 (file)
 #define CONFIG_SYS_TIMERBASE           0x48040000      /* Use Timer2 */
 #define CONFIG_SPL_AM33XX_ENABLE_RTC32K_OSC
 
+#ifndef CONFIG_SPL_BUILD
+# define CONFIG_DM
+# define CONFIG_CMD_DM
+# define CONFIG_DM_GPIO
+# define CONFIG_DM_SERIAL
+# define CONFIG_OMAP_SERIAL
+# define CONFIG_SYS_MALLOC_F_LEN       (1 << 10)
+#endif
+
 #include <asm/arch/omap.h>
 
 /* NS16550 Configuration */
 #define CONFIG_SYS_NS16550
+#ifdef CONFIG_SPL_BUILD
 #define CONFIG_SYS_NS16550_SERIAL
 #define CONFIG_SYS_NS16550_REG_SIZE    (-4)
+#endif
 #define CONFIG_SYS_NS16550_CLK         48000000
 
 /* Network defines. */
index 3b19d3d6baf4c46f7a930e5c74c7e1afdea1f6a3..3c634ee680d02143b69fa0534143f28705b1a36b 100644 (file)
 #include <asm/arch/cpu.h>
 #include <asm/arch/omap3.h>
 
+#ifndef CONFIG_SPL_BUILD
+# define CONFIG_DM
+# define CONFIG_CMD_DM
+# define CONFIG_DM_GPIO
+# define CONFIG_DM_SERIAL
+# define CONFIG_OMAP_SERIAL
+# define CONFIG_SYS_MALLOC_F_LEN       (1 << 10)
+#endif
+
 /* The chip has SDRC controller */
 #define CONFIG_SDRC
 
 /* NS16550 Configuration */
 #define V_NS16550_CLK                  48000000        /* 48MHz (APLL96/2) */
 #define CONFIG_SYS_NS16550
-#define CONFIG_SYS_NS16550_SERIAL
-#define CONFIG_SYS_NS16550_REG_SIZE    (-4)
-#define CONFIG_SYS_NS16550_CLK         V_NS16550_CLK
+#ifdef CONFIG_SPL_BUILD
+# define CONFIG_SYS_NS16550_SERIAL
+# define CONFIG_SYS_NS16550_REG_SIZE   (-4)
+# define CONFIG_SYS_NS16550_CLK                V_NS16550_CLK
+#endif
 #define CONFIG_SYS_BAUDRATE_TABLE      {4800, 9600, 19200, 38400, 57600, \
                                        115200}
 
 /* Select serial console configuration */
 #define CONFIG_CONS_INDEX              3
+#ifdef CONFIG_SPL_BUILD
 #define CONFIG_SYS_NS16550_COM3                OMAP34XX_UART3
 #define CONFIG_SERIAL3                 3
+#endif
 
 /* Physical Memory Map */
 #define PHYS_SDRAM_1           OMAP34XX_SDRC_CS0
index 2705d2c55febe2b7d7f9b1881ae63af37a8a85ba..d97a9613ae5f3c83f56f246467a51ba1ea767f83 100644 (file)
 #define CONFIG_SYS_BARGSIZE            CONFIG_SYS_CBSIZE
 
 #define CONFIG_SYS_LOAD_ADDR           CONFIG_LOADADDR
-#define CONFIG_SYS_HZ                  1000
 
 #define CONFIG_CMDLINE_EDITING
 #define CONFIG_STACKSIZE               (128u * SZ_1K)
index 18fe277cada77b585012af8d5c0279ea834a7d0e..b18ae6dfaeb3551573ae9810fd4ef817428e209f 100644 (file)
@@ -33,18 +33,17 @@ are defined. Select only one of them."
 # define CONFIG_SUPPORT_CARD_UART_BASE (CONFIG_SUPPORT_CARD_BASE + 0x00200000)
 #endif
 
+#ifdef CONFIG_SYS_NS16550_SERIAL
 #define CONFIG_SYS_NS16550
 #define CONFIG_SYS_NS16550_COM1                CONFIG_SUPPORT_CARD_UART_BASE
 #define CONFIG_SYS_NS16550_CLK         12288000
 #define CONFIG_SYS_NS16550_REG_SIZE    -2
+#endif
 
 #define CONFIG_SMC911X_BASE            CONFIG_SUPPORT_CARD_ETHER_BASE
 #define CONFIG_SMC911X_32_BIT
 
-#define CONFIG_SYS_UNIPHIER_SERIAL_BASE0 0x54006800
-#define CONFIG_SYS_UNIPHIER_SERIAL_BASE1 0x54006900
-#define CONFIG_SYS_UNIPHIER_SERIAL_BASE2 0x54006a00
-#define CONFIG_SYS_UNIPHIER_SERIAL_BASE3 0x54006b00
+#define CONFIG_SYS_MALLOC_F_LEN  0x7000
 
 /*-----------------------------------------------------------------------
  * MMU and Cache Setting
index 41a7c99edcfd64094d871529c7856c3adf32fcd4..fe331bc0825989a7c612a01b2fcbe20b81bdaff5 100644 (file)
@@ -99,7 +99,6 @@
 #define        CONFIG_VIDEO_BMP_GZIP
 #define        CONFIG_VIDEO_BMP_RLE8
 #define        CONFIG_SYS_VIDEO_LOGO_MAX_SIZE  (2 << 20)
-#undef SPI_INIT
 
 #define        SPI_DELAY       udelay(10)
 #define        SPI_SDA(val)    zipitz2_spi_sda(val)
index 1e4d8db96b7889e32586c665e001513523357b48..9e13146ecbb266a5b73dbb9b93b1e90317c79a06 100644 (file)
@@ -14,6 +14,7 @@
 #include <fdtdec.h>
 #include <cros_ec_message.h>
 
+#ifndef CONFIG_DM_CROS_EC
 /* Which interface is the device on? */
 enum cros_ec_interface_t {
        CROS_EC_IF_NONE,
@@ -22,9 +23,13 @@ enum cros_ec_interface_t {
        CROS_EC_IF_LPC, /* Intel Low Pin Count interface */
        CROS_EC_IF_SANDBOX,
 };
+#endif
 
 /* Our configuration information */
 struct cros_ec_dev {
+#ifdef CONFIG_DM_CROS_EC
+       struct udevice *dev;            /* Transport device */
+#else
        enum cros_ec_interface_t interface;
        struct spi_slave *spi;          /* Our SPI slave, if using SPI */
        int node;                       /* Our node */
@@ -33,6 +38,7 @@ struct cros_ec_dev {
        unsigned int addr;              /* Device address (for I2C) */
        unsigned int bus_num;           /* Bus number (for I2C) */
        unsigned int max_frequency;     /* Maximum interface frequency */
+#endif
        struct fdt_gpio_state ec_int;   /* GPIO used as EC interrupt line */
        int protocol_version;           /* Protocol version to use */
        int optimise_flash_write;       /* Don't write erased flash blocks */
@@ -233,6 +239,22 @@ int cros_ec_flash_update_rw(struct cros_ec_dev *dev,
  */
 struct cros_ec_dev *board_get_cros_ec_dev(void);
 
+#ifdef CONFIG_DM_CROS_EC
+
+struct dm_cros_ec_ops {
+       int (*check_version)(struct udevice *dev);
+       int (*command)(struct udevice *dev, uint8_t cmd, int cmd_version,
+                      const uint8_t *dout, int dout_len,
+                      uint8_t **dinp, int din_len);
+       int (*packet)(struct udevice *dev, int out_bytes, int in_bytes);
+};
+
+#define dm_cros_ec_get_ops(dev) \
+               ((struct dm_cros_ec_ops *)(dev)->driver->ops)
+
+int cros_ec_register(struct udevice *dev);
+
+#else /* !CONFIG_DM_CROS_EC */
 
 /* Internal interfaces */
 int cros_ec_i2c_init(struct cros_ec_dev *dev, const void *blob);
@@ -336,6 +358,7 @@ int cros_ec_spi_command(struct cros_ec_dev *dev, uint8_t cmd, int cmd_version,
 int cros_ec_spi_packet(struct cros_ec_dev *dev, int out_bytes, int in_bytes);
 int cros_ec_sandbox_packet(struct cros_ec_dev *dev, int out_bytes,
                           int in_bytes);
+#endif
 
 /**
  * Dump a block of data for a command.
@@ -489,9 +512,11 @@ int cros_ec_get_error(void);
  * Returns information from the FDT about the Chrome EC flash
  *
  * @param blob         FDT blob to use
+ * @param node         Node offset to read from
  * @param config       Structure to use to return information
  */
-int cros_ec_decode_ec_flash(const void *blob, struct fdt_cros_ec *config);
+int cros_ec_decode_ec_flash(const void *blob, int node,
+                           struct fdt_cros_ec *config);
 
 /**
  * Check the current keyboard state, in case recovery mode is requested.
index 7005d03d08f5d96adcd3f28c2a11f7f9e318ec44..44cb7ef93bfdeea682ea0602d33bf9615260ad9d 100644 (file)
@@ -65,6 +65,19 @@ int device_bind_by_name(struct udevice *parent, bool pre_reloc_only,
  */
 int device_probe(struct udevice *dev);
 
+/**
+ * device_probe() - Probe a child device, activating it
+ *
+ * Activate a device so that it is ready for use. All its parents are probed
+ * first. The child is provided with parent data if parent_priv is not NULL.
+ *
+ * @dev: Pointer to device to probe
+ * @parent_priv: Pointer to parent data. If non-NULL then this is provided to
+ * the child.
+ * @return 0 if OK, -ve on error
+ */
+int device_probe_child(struct udevice *dev, void *parent_priv);
+
 /**
  * device_remove() - Remove a device, de-activating it
  *
index c8a4072bcf7d60d2fb6cdaa24cc7fbb77946a76a..9ce95a834e75ee54d6d7edefb21ee0f848f97e0f 100644 (file)
@@ -57,7 +57,8 @@ struct driver_info;
  * @sibling_node: Next device in list of all devices
  * @flags: Flags for this device DM_FLAG_...
  * @req_seq: Requested sequence number for this device (-1 = any)
- * @seq: Allocated sequence number for this device (-1 = none)
+ * @seq: Allocated sequence number for this device (-1 = none). This is set up
+ * when the device is probed and will be unique within the device's uclass.
  */
 struct udevice {
        struct driver *driver;
@@ -96,6 +97,12 @@ struct udevice_id {
        ulong data;
 };
 
+#ifdef CONFIG_OF_CONTROL
+#define of_match_ptr(_ptr)     (_ptr)
+#else
+#define of_match_ptr(_ptr)     NULL
+#endif /* CONFIG_OF_CONTROL */
+
 /**
  * struct driver - A driver for a feature or peripheral
  *
@@ -133,6 +140,10 @@ struct udevice_id {
  * @per_child_auto_alloc_size: Each device can hold private data owned by
  * its parent. If required this will be automatically allocated if this
  * value is non-zero.
+ * TODO(sjg@chromium.org): I'm considering dropping this, and just having
+ * device_probe_child() pass it in. So far the use case for allocating it
+ * is SPI, but I found that unsatisfactory. Since it is here I will leave it
+ * until things are clearer.
  * @ops: Driver-specific operations. This is typically a list of function
  * pointers defined by the driver, to implement driver functions required by
  * the uclass.
@@ -274,4 +285,22 @@ int device_find_child_by_of_offset(struct udevice *parent, int of_offset,
 int device_get_child_by_of_offset(struct udevice *parent, int seq,
                                  struct udevice **devp);
 
+/**
+ * device_find_first_child() - Find the first child of a device
+ *
+ * @parent: Parent device to search
+ * @devp: Returns first child device, or NULL if none
+ * @return 0
+ */
+int device_find_first_child(struct udevice *parent, struct udevice **devp);
+
+/**
+ * device_find_first_child() - Find the first child of a device
+ *
+ * @devp: Pointer to previous child device on entry. Returns pointer to next
+ *             child device, or NULL if none
+ * @return 0
+ */
+int device_find_next_child(struct udevice **devp);
+
 #endif
index 23568952467e6d5b685d84e2664561f5ca9ea942..704e33e37fb9dadc739f71312e15f79c4f9bb651 100644 (file)
@@ -38,7 +38,7 @@ struct uclass_driver *lists_uclass_lookup(enum uclass_id id);
  * This searches the U_BOOT_DEVICE() structures and creates new devices for
  * each one. The devices will have @parent as their parent.
  *
- * @parent: parent driver (root)
+ * @parent: parent device (root)
  * @early_only: If true, bind only drivers with the DM_INIT_F flag. If false
  * bind all drivers.
  */
@@ -50,7 +50,7 @@ int lists_bind_drivers(struct udevice *parent, bool pre_reloc_only);
  * This creates a new device bound to the given device tree node, with
  * @parent as its parent.
  *
- * @parent: parent driver (root)
+ * @parent: parent device (root)
  * @blob: device tree blob
  * @offset: offset of this device tree node
  * @devp: if non-NULL, returns a pointer to the bound device
index 2bc8b147edfed01f152c1ca5e310ba8248637534..fbc8a6b3adda18424bd485a0ea39df981143f55e 100644 (file)
 #ifndef _DM_PLATDATA_H
 #define _DM_PLATDATA_H
 
+#include <linker_lists.h>
+
 /**
  * struct driver_info - Information required to instantiate a device
  *
- * @name:      Device name
+ * @name:      Driver name
  * @platdata:  Driver-specific platform data
  */
 struct driver_info {
@@ -25,4 +27,8 @@ struct driver_info {
 #define U_BOOT_DEVICE(__name)                                          \
        ll_entry_declare(struct driver_info, __name, driver_info)
 
+/* Declare a list of devices. The argument is a driver_info[] array */
+#define U_BOOT_DEVICES(__name)                                         \
+       ll_entry_declare_list(struct driver_info, __name, driver_info)
+
 #endif
diff --git a/include/dm/platform_data/serial-uniphier.h b/include/dm/platform_data/serial-uniphier.h
new file mode 100644 (file)
index 0000000..52343e3
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2014 Panasonic Corporation
+ *   Author: Masahiro Yamada <yamada.m@jp.panasonic.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#ifndef __PLAT_UNIPHIER_SERIAL_H
+#define __PLAT_UNIPHIER_SERIAL_H
+
+#define DRIVER_NAME    "uniphier-uart"
+
+struct uniphier_serial_platform_data {
+       unsigned long base;
+       unsigned int uartclk;
+};
+
+#endif /* __PLAT_UNIPHIER_SERIAL_H */
diff --git a/include/dm/platform_data/serial_mxc.h b/include/dm/platform_data/serial_mxc.h
new file mode 100644 (file)
index 0000000..7d3ace2
--- /dev/null
@@ -0,0 +1,14 @@
+/*
+ * Copyright (c) 2014 Google, Inc
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#ifndef __serial_mxc_h
+#define __serial_mxc_h
+
+/* Information about a serial port */
+struct mxc_serial_platdata {
+       struct mxc_uart *reg;  /* address of registers in physical memory */
+};
+
+#endif
diff --git a/include/dm/platform_data/serial_pl01x.h b/include/dm/platform_data/serial_pl01x.h
new file mode 100644 (file)
index 0000000..5e068f3
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2014 Google, Inc
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#ifndef __serial_pl01x_h
+#define __serial_pl01x_h
+
+enum pl01x_type {
+       TYPE_PL010,
+       TYPE_PL011,
+};
+
+/*
+ *Information about a serial port
+ *
+ * @base: Register base address
+ * @type: Port type
+ * @clock: Input clock rate, used for calculating the baud rate divisor
+ */
+struct pl01x_serial_platdata {
+       unsigned long base;
+       enum pl01x_type type;
+       unsigned int clock;
+};
+
+#endif
index 235d728bfbe62ea9af8cc3f6e946a248ce9791cd..f08c05da8147725f87900da81bf8944ff1c46ebc 100644 (file)
@@ -8,6 +8,7 @@
 #define __DM_TEST_H
 
 #include <dm.h>
+#include <malloc.h>
 
 /**
  * struct dm_test_cdata - configuration data for test instance
@@ -120,6 +121,7 @@ struct dm_test_state {
        int force_fail_alloc;
        int skip_post_probe;
        struct udevice *removed;
+       struct mallinfo start;
 };
 
 /* Test flags for each test */
@@ -177,6 +179,27 @@ int dm_check_operations(struct dm_test_state *dms, struct udevice *dev,
  */
 int dm_check_devices(struct dm_test_state *dms, int num_devices);
 
+/**
+ * dm_leak_check_start() - Prepare to check for a memory leak
+ *
+ * Call this before allocating memory to record the amount of memory being
+ * used.
+ *
+ * @dms: Overall test state
+ */
+void dm_leak_check_start(struct dm_test_state *dms);
+
+/**
+ * dm_leak_check_end() - Check that no memory has leaked
+ *
+ * Call this after dm_leak_check_start() and after you have hopefuilly freed
+ * all the memory that was allocated. This function will print an error if
+ * it sees a different amount of total memory allocated than before.
+ *
+ * @dms: Overall test state
+ */int dm_leak_check_end(struct dm_test_state *dms);
+
+
 /**
  * dm_test_main() - Run all the tests
  *
index 7f0e37b7b789cd64b48a124a0726dc4efbbe2fe4..a8944c97d03a9cfc9162a8c6289b21515862386b 100644 (file)
@@ -18,10 +18,16 @@ enum uclass_id {
        UCLASS_TEST,
        UCLASS_TEST_FDT,
        UCLASS_TEST_BUS,
+       UCLASS_SPI_EMUL,        /* sandbox SPI device emulator */
+       UCLASS_SIMPLE_BUS,
 
        /* U-Boot uclasses start here */
        UCLASS_GPIO,            /* Bank of general-purpose I/O pins */
        UCLASS_SERIAL,          /* Serial UART */
+       UCLASS_SPI,             /* SPI bus */
+       UCLASS_SPI_GENERIC,     /* Generic SPI flash target */
+       UCLASS_SPI_FLASH,       /* SPI flash */
+       UCLASS_CROS_EC, /* Chrome OS EC */
 
        UCLASS_COUNT,
        UCLASS_INVALID = -1,
index 8d09ecff7b4e0c0c4590792391303f0eeea7f2f6..f6ec6d7e9f62f7551b869f1eb7b188e8587b44ee 100644 (file)
@@ -11,6 +11,7 @@
 #define _DM_UCLASS_H
 
 #include <dm/uclass-id.h>
+#include <linker_lists.h>
 #include <linux/list.h>
 
 /**
index 8be64a921dd75aaf835de4c1b87296ebcc2bd327..6ac3a38ef008b686221a5e213e67f5e503233846 100644 (file)
@@ -5,6 +5,7 @@
  */
 
 #ifndef __DM_UTIL_H
+#define __DM_UTIL_H
 
 void dm_warn(const char *fmt, ...);
 
index b8ecc41063b3e5b366f1688d60a32dd4f8e914fa..63d93416a3e1246975bd390b8990b6067c350f97 100644 (file)
@@ -570,4 +570,6 @@ unsigned long elf_hash(const unsigned char *name);
    that may still be in object files.  */
 #define R_PPC_TOC16             255
 
+int valid_elf_image(unsigned long addr);
+
 #endif /* _ELF_H */
index c3d1fbcf3566451419bff1a325a870a945743475..55cef94358bcd9ed1db349493941addc901d1ff4 100644 (file)
@@ -144,6 +144,8 @@ static inline u64 of_read_number(const fdt32_t *cell, int size)
 
 void of_bus_default_count_cells(void *blob, int parentoffset,
                                        int *addrc, int *sizec);
+int ft_verify_fdt(void *fdt);
+int arch_fixup_memory_node(void *blob);
 
 #endif /* ifdef CONFIG_OF_LIBFDT */
 
index 2590d3071fd0353eb7e96f667e74bb089c3a476a..4ae77be9ba7c8bf09860606645db711db0911fb2 100644 (file)
@@ -40,6 +40,27 @@ struct fdt_memory {
        fdt_addr_t end;
 };
 
+/*
+ * Information about a resource. start is the first address of the resource
+ * and end is the last address (inclusive). The length of the resource will
+ * be equal to: end - start + 1.
+ */
+struct fdt_resource {
+       fdt_addr_t start;
+       fdt_addr_t end;
+};
+
+/**
+ * Compute the size of a resource.
+ *
+ * @param res  the resource to operate on
+ * @return the size of the resource
+ */
+static inline fdt_size_t fdt_resource_size(const struct fdt_resource *res)
+{
+       return res->end - res->start + 1;
+}
+
 /**
  * Compat types that we know about and for which we might have drivers.
  * Each is named COMPAT_<dir>_<filename> where <dir> is the directory
@@ -96,6 +117,7 @@ enum fdt_compat_id {
        COMPAT_NXP_PTN3460,             /* NXP PTN3460 DP/LVDS bridge */
        COMPAT_SAMSUNG_EXYNOS_SYSMMU,   /* Exynos sysmmu */
        COMPAT_PARADE_PS8625,           /* Parade PS8622 EDP->LVDS bridge */
+       COMPAT_INTEL_LPC,               /* Intel Low Pin Count I/F */
 
        COMPAT_COUNT,
 };
@@ -597,4 +619,46 @@ struct fmap_entry {
  */
 int fdtdec_read_fmap_entry(const void *blob, int node, const char *name,
                           struct fmap_entry *entry);
+
+/**
+ * Obtain an indexed resource from a device property.
+ *
+ * @param fdt          FDT blob
+ * @param node         node to examine
+ * @param property     name of the property to parse
+ * @param index                index of the resource to retrieve
+ * @param res          returns the resource
+ * @return 0 if ok, negative on error
+ */
+int fdt_get_resource(const void *fdt, int node, const char *property,
+                    unsigned int index, struct fdt_resource *res);
+
+/**
+ * Obtain a named resource from a device property.
+ *
+ * Look up the index of the name in a list of strings and return the resource
+ * at that index.
+ *
+ * @param fdt          FDT blob
+ * @param node         node to examine
+ * @param property     name of the property to parse
+ * @param prop_names   name of the property containing the list of names
+ * @param name         the name of the entry to look up
+ * @param res          returns the resource
+ */
+int fdt_get_named_resource(const void *fdt, int node, const char *property,
+                          const char *prop_names, const char *name,
+                          struct fdt_resource *res);
+
+/**
+ * Look at the reg property of a device node that represents a PCI device
+ * and parse the bus, device and function number from it.
+ *
+ * @param fdt          FDT blob
+ * @param node         node to examine
+ * @param bdf          returns bus, device, function triplet
+ * @return 0 if ok, negative on error
+ */
+int fdtdec_pci_get_bdf(const void *fdt, int node, int *bdf);
+
 #endif
diff --git a/include/fsl_sec.h b/include/fsl_sec.h
new file mode 100644 (file)
index 0000000..aa850a3
--- /dev/null
@@ -0,0 +1,181 @@
+/*
+ * Common internal memory map for some Freescale SoCs
+ *
+ * Copyright 2014 Freescale Semiconductor, Inc.
+ *
+ */
+
+#ifndef __FSL_SEC_H
+#define __FSL_SEC_H
+
+#include <common.h>
+#include <asm/io.h>
+
+#ifdef CONFIG_SYS_FSL_SEC_LE
+#define sec_in32(a)       in_le32(a)
+#define sec_out32(a, v)   out_le32(a, v)
+#define sec_in16(a)       in_le16(a)
+#define sec_clrbits32     clrbits_le32
+#define sec_setbits32     setbits_le32
+#elif defined(CONFIG_SYS_FSL_SEC_BE)
+#define sec_in32(a)       in_be32(a)
+#define sec_out32(a, v)   out_be32(a, v)
+#define sec_in16(a)       in_be16(a)
+#define sec_clrbits32     clrbits_be32
+#define sec_setbits32     setbits_be32
+#else
+#error Neither CONFIG_SYS_FSL_SEC_LE nor CONFIG_SYS_FSL_SEC_BE is defined
+#endif
+
+/* Security Engine Block (MS = Most Sig., LS = Least Sig.) */
+#if CONFIG_SYS_FSL_SEC_COMPAT >= 4
+/* RNG4 TRNG test registers */
+struct rng4tst {
+#define RTMCTL_PRGM 0x00010000 /* 1 -> program mode, 0 -> run mode */
+       u32 rtmctl;             /* misc. control register */
+       u32 rtscmisc;           /* statistical check misc. register */
+       u32 rtpkrrng;           /* poker range register */
+#define RTSDCTL_ENT_DLY_MIN    1200
+#define RTSDCTL_ENT_DLY_MAX    12800
+       union {
+               u32 rtpkrmax;   /* PRGM=1: poker max. limit register */
+               u32 rtpkrsq;    /* PRGM=0: poker square calc. result register */
+       };
+#define RTSDCTL_ENT_DLY_SHIFT 16
+#define RTSDCTL_ENT_DLY_MASK (0xffff << RTSDCTL_ENT_DLY_SHIFT)
+       u32 rtsdctl;            /* seed control register */
+       union {
+               u32 rtsblim;    /* PRGM=1: sparse bit limit register */
+               u32 rttotsam;   /* PRGM=0: total samples register */
+       };
+       u32 rtfreqmin;          /* frequency count min. limit register */
+       union {
+               u32 rtfreqmax;  /* PRGM=1: freq. count max. limit register */
+               u32 rtfreqcnt;  /* PRGM=0: freq. count register */
+       };
+       u32 rsvd1[40];
+#define RNG_STATE0_HANDLE_INSTANTIATED 0x00000001
+       u32 rdsta;              /*RNG DRNG Status Register*/
+       u32 rsvd2[15];
+};
+
+typedef struct ccsr_sec {
+       u32     res0;
+       u32     mcfgr;          /* Master CFG Register */
+       u8      res1[0x4];
+       u32     scfgr;
+       struct {
+               u32     ms;     /* Job Ring LIODN Register, MS */
+               u32     ls;     /* Job Ring LIODN Register, LS */
+       } jrliodnr[4];
+       u8      res2[0x2c];
+       u32     jrstartr;       /* Job Ring Start Register */
+       struct {
+               u32     ms;     /* RTIC LIODN Register, MS */
+               u32     ls;     /* RTIC LIODN Register, LS */
+       } rticliodnr[4];
+       u8      res3[0x1c];
+       u32     decorr;         /* DECO Request Register */
+       struct {
+               u32     ms;     /* DECO LIODN Register, MS */
+               u32     ls;     /* DECO LIODN Register, LS */
+       } decoliodnr[8];
+       u8      res4[0x40];
+       u32     dar;            /* DECO Avail Register */
+       u32     drr;            /* DECO Reset Register */
+       u8      res5[0x4d8];
+       struct rng4tst rng;     /* RNG Registers */
+       u8      res11[0x8a0];
+       u32     crnr_ms;        /* CHA Revision Number Register, MS */
+       u32     crnr_ls;        /* CHA Revision Number Register, LS */
+       u32     ctpr_ms;        /* Compile Time Parameters Register, MS */
+       u32     ctpr_ls;        /* Compile Time Parameters Register, LS */
+       u8      res6[0x10];
+       u32     far_ms;         /* Fault Address Register, MS */
+       u32     far_ls;         /* Fault Address Register, LS */
+       u32     falr;           /* Fault Address LIODN Register */
+       u32     fadr;           /* Fault Address Detail Register */
+       u8      res7[0x4];
+       u32     csta;           /* CAAM Status Register */
+       u8      res8[0x8];
+       u32     rvid;           /* Run Time Integrity Checking Version ID Reg.*/
+       u32     ccbvid;         /* CHA Cluster Block Version ID Register */
+       u32     chavid_ms;      /* CHA Version ID Register, MS */
+       u32     chavid_ls;      /* CHA Version ID Register, LS */
+       u32     chanum_ms;      /* CHA Number Register, MS */
+       u32     chanum_ls;      /* CHA Number Register, LS */
+       u32     secvid_ms;      /* SEC Version ID Register, MS */
+       u32     secvid_ls;      /* SEC Version ID Register, LS */
+       u8      res9[0x6020];
+       u32     qilcr_ms;       /* Queue Interface LIODN CFG Register, MS */
+       u32     qilcr_ls;       /* Queue Interface LIODN CFG Register, LS */
+       u8      res10[0x8fd8];
+} ccsr_sec_t;
+
+#define SEC_CTPR_MS_AXI_LIODN          0x08000000
+#define SEC_CTPR_MS_QI                 0x02000000
+#define SEC_CTPR_MS_VIRT_EN_INCL       0x00000001
+#define SEC_CTPR_MS_VIRT_EN_POR                0x00000002
+#define SEC_RVID_MA                    0x0f000000
+#define SEC_CHANUM_MS_JRNUM_MASK       0xf0000000
+#define SEC_CHANUM_MS_JRNUM_SHIFT      28
+#define SEC_CHANUM_MS_DECONUM_MASK     0x0f000000
+#define SEC_CHANUM_MS_DECONUM_SHIFT    24
+#define SEC_SECVID_MS_IPID_MASK        0xffff0000
+#define SEC_SECVID_MS_IPID_SHIFT       16
+#define SEC_SECVID_MS_MAJ_REV_MASK     0x0000ff00
+#define SEC_SECVID_MS_MAJ_REV_SHIFT    8
+#define SEC_CCBVID_ERA_MASK            0xff000000
+#define SEC_CCBVID_ERA_SHIFT           24
+#define SEC_SCFGR_RDBENABLE            0x00000400
+#define SEC_SCFGR_VIRT_EN              0x00008000
+#define SEC_CHAVID_LS_RNG_SHIFT                16
+#define SEC_CHAVID_RNG_LS_MASK         0x000f0000
+
+#define CONFIG_JRSTARTR_JR0            0x00000001
+
+struct jr_regs {
+#ifdef CONFIG_SYS_FSL_SEC_LE
+       u32 irba_l;
+       u32 irba_h;
+#else
+       u32 irba_h;
+       u32 irba_l;
+#endif
+       u32 rsvd1;
+       u32 irs;
+       u32 rsvd2;
+       u32 irsa;
+       u32 rsvd3;
+       u32 irja;
+#ifdef CONFIG_SYS_FSL_SEC_LE
+       u32 orba_l;
+       u32 orba_h;
+#else
+       u32 orba_h;
+       u32 orba_l;
+#endif
+       u32 rsvd4;
+       u32 ors;
+       u32 rsvd5;
+       u32 orjr;
+       u32 rsvd6;
+       u32 orsf;
+       u32 rsvd7;
+       u32 jrsta;
+       u32 rsvd8;
+       u32 jrint;
+       u32 jrcfg0;
+       u32 jrcfg1;
+       u32 rsvd9;
+       u32 irri;
+       u32 rsvd10;
+       u32 orwi;
+       u32 rsvd11;
+       u32 jrcr;
+};
+
+int sec_init(void);
+#endif
+
+#endif /* __FSL_SEC_H */
index c2a48e0b37853bedfcf36ed9640bf4d850778084..d5e05e97cb2fb12dc68794a2f1032eb366c79f18 100644 (file)
@@ -23,6 +23,7 @@ extern ulong ide_bus_offset[];
 #define LED_IDE2       0x02
 #define        DEVICE_LED(d)   ((d & 2) | ((d & 2) == 0)) /* depends on bit positions! */
 
+void ide_led(uchar led, uchar status);
 #endif /* CONFIG_IDE_LED */
 
 #ifdef CONFIG_SYS_64BIT_LBA
index 4347532520b7c700a9e4395dd22b7df7ffbe5e1c..a13a30289f691819c849834a1584c77a438fdc1a 100644 (file)
@@ -233,6 +233,7 @@ struct lmb;
 #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          */
 
 /*
  * Compression Types
@@ -273,6 +274,7 @@ typedef struct image_info {
        ulong           image_start, image_len; /* start of image within blob, len of image */
        ulong           load;                   /* load addr for the image */
        uint8_t         comp, type, os;         /* compression, type of image, os type */
+       uint8_t         arch;                   /* CPU architecture */
 } image_info_t;
 
 /*
@@ -303,6 +305,10 @@ typedef struct bootm_headers {
        void            *fit_hdr_fdt;   /* FDT blob FIT image header */
        const char      *fit_uname_fdt; /* FDT blob subimage node unit name */
        int             fit_noffset_fdt;/* FDT blob subimage node offset */
+
+       void            *fit_hdr_setup; /* x86 setup FIT image header */
+       const char      *fit_uname_setup; /* x86 setup subimage node name */
+       int             fit_noffset_setup;/* x86 setup subimage node offset */
 #endif
 
 #ifndef USE_HOSTCC
@@ -417,6 +423,9 @@ enum fit_load_op {
        FIT_LOAD_REQUIRED,      /* Must be provided */
 };
 
+int boot_get_setup(bootm_headers_t *images, uint8_t arch, ulong *setup_start,
+                  ulong *setup_len);
+
 #ifndef USE_HOSTCC
 /* Image format types, returned by _get_format() routine */
 #define IMAGE_FORMAT_INVALID   0x00
@@ -438,6 +447,9 @@ int boot_get_ramdisk(int argc, char * const argv[], bootm_headers_t *images,
                uint8_t arch, ulong *rd_start, ulong *rd_end);
 #endif
 
+int boot_get_setup_fit(bootm_headers_t *images, uint8_t arch,
+                      ulong *setup_start, ulong *setup_len);
+
 /**
  * fit_image_load() - load an image from a FIT
  *
@@ -721,6 +733,7 @@ int bootz_setup(ulong image, ulong *start, ulong *end);
 #define FIT_RAMDISK_PROP       "ramdisk"
 #define FIT_FDT_PROP           "fdt"
 #define FIT_DEFAULT_PROP       "default"
+#define FIT_SETUP_PROP         "setup"
 
 #define FIT_MAX_HASH_LEN       HASH_MAX_DIGEST_SIZE
 
index a1ef1e15df3ddbd8abec45766b9f9038f334bcc1..f3cbb637be419d16c35e59aec1aaf08f7819e310 100644 (file)
@@ -163,6 +163,31 @@ int fdt_first_subnode(const void *fdt, int offset);
  */
 int fdt_next_subnode(const void *fdt, int offset);
 
+/**
+ * fdt_for_each_subnode - iterate over all subnodes of a parent
+ *
+ * This is actually a wrapper around a for loop and would be used like so:
+ *
+ *     fdt_for_each_subnode(fdt, node, parent) {
+ *             ...
+ *             use node
+ *             ...
+ *     }
+ *
+ * Note that this is implemented as a macro and node is used as iterator in
+ * the loop. It should therefore be a locally allocated variable. The parent
+ * variable on the other hand is never modified, so it can be constant or
+ * even a literal.
+ *
+ * @fdt:       FDT blob (const void *)
+ * @node:      child node (int)
+ * @parent:    parent node (int)
+ */
+#define fdt_for_each_subnode(fdt, node, parent)                \
+       for (node = fdt_first_subnode(fdt, parent);     \
+            node >= 0;                                 \
+            node = fdt_next_subnode(fdt, node))
+
 /**********************************************************************/
 /* General functions                                                  */
 /**********************************************************************/
@@ -857,6 +882,53 @@ int fdt_node_offset_by_compatible(const void *fdt, int startoffset,
  */
 int fdt_stringlist_contains(const char *strlist, int listlen, const char *str);
 
+/**
+ * fdt_count_strings - count the number of strings in a string list
+ * @fdt: pointer to the device tree blob
+ * @node: offset of the node
+ * @property: name of the property containing the string list
+ * @return: the number of strings in the given property
+ */
+int fdt_count_strings(const void *fdt, int node, const char *property);
+
+/**
+ * fdt_find_string - find a string in a string list and return its index
+ * @fdt: pointer to the device tree blob
+ * @node: offset of the node
+ * @property: name of the property containing the string list
+ * @string: string to look up in the string list
+ * @return: the index of the string or negative on error
+ */
+int fdt_find_string(const void *fdt, int node, const char *property,
+                   const char *string);
+
+/**
+ * fdt_get_string_index() - obtain the string at a given index in a string list
+ * @fdt: pointer to the device tree blob
+ * @node: offset of the node
+ * @property: name of the property containing the string list
+ * @index: index of the string to return
+ * @output: return location for the string
+ * @return: 0 if the string was found or a negative error code otherwise
+ */
+int fdt_get_string_index(const void *fdt, int node, const char *property,
+                        int index, const char **output);
+
+/**
+ * fdt_get_string() - obtain the string at a given index in a string list
+ * @fdt: pointer to the device tree blob
+ * @node: offset of the node
+ * @property: name of the property containing the string list
+ * @output: return location for the string
+ * @return: 0 if the string was found or a negative error code otherwise
+ *
+ * This is a shortcut for:
+ *
+ *     fdt_get_string_index(fdt, node, property, 0, output).
+ */
+int fdt_get_string(const void *fdt, int node, const char *property,
+                  const char **output);
+
 /**********************************************************************/
 /* Read-only functions (addressing related)                           */
 /**********************************************************************/
index 507d61ba9a5c0d54d60f54f966391a8a7ef6eae2..d37fba44dcafc6b1ce6813cca4e8f3d6999e95d5 100644 (file)
@@ -11,6 +11,8 @@
 #ifndef __LINKER_LISTS_H__
 #define __LINKER_LISTS_H__
 
+#include <linux/compiler.h>
+
 /*
  * There is no use in including this from ASM files, but that happens
  * anyway, e.g. PPC kgdb.S includes command.h which incluse us.
                        __attribute__((unused,                          \
                        section(".u_boot_list_2_"#_list"_2_"#_name)))
 
+/**
+ * ll_entry_declare_list() - Declare a list of link-generated array entries
+ * @_type:     Data type of each entry
+ * @_name:     Name of the entry
+ * @_list:     name of the list. Should contain only characters allowed
+ *             in a C variable name!
+ *
+ * This is like ll_entry_declare() but creates multiple entries. It should
+ * be assigned to an array.
+ *
+ * ll_entry_declare_list(struct my_sub_cmd, my_sub_cmd, cmd_sub, cmd.sub) = {
+ *     { .x = 3, .y = 4 },
+ *     { .x = 8, .y = 2 },
+ *     { .x = 1, .y = 7 }
+ * };
+ */
+#define ll_entry_declare_list(_type, _name, _list)                     \
+       _type _u_boot_list_2_##_list##_2_##_name[] __aligned(4)         \
+                       __attribute__((unused,                          \
+                       section(".u_boot_list_2_"#_list"_2_"#_name)))
+
 /**
  * We need a 0-byte-size type for iterator symbols, and the compiler
  * does not allow defining objects of C type 'void'. Using an empty
diff --git a/include/linux/mbus.h b/include/linux/mbus.h
new file mode 100644 (file)
index 0000000..717cbea
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * Marvell MBUS common definitions.
+ *
+ * Copyright (C) 2008 Marvell Semiconductor
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __LINUX_MBUS_H
+#define __LINUX_MBUS_H
+
+struct resource;
+
+struct mbus_dram_target_info {
+       /*
+        * The 4-bit MBUS target ID of the DRAM controller.
+        */
+       u8              mbus_dram_target_id;
+
+       /*
+        * The base address, size, and MBUS attribute ID for each
+        * of the possible DRAM chip selects.  Peripherals are
+        * required to support at least 4 decode windows.
+        */
+       int             num_cs;
+       struct mbus_dram_window {
+               u8      cs_index;
+               u8      mbus_attr;
+               u32     base;
+               u32     size;
+       } cs[4];
+};
+
+struct mvebu_mbus_state {
+       void __iomem *mbuswins_base;
+       void __iomem *sdramwins_base;
+       struct dentry *debugfs_root;
+       struct dentry *debugfs_sdram;
+       struct dentry *debugfs_devs;
+       const struct mvebu_mbus_soc_data *soc;
+       int hw_io_coherency;
+};
+
+/* Flags for PCI/PCIe address decoding regions */
+#define MVEBU_MBUS_PCI_IO  0x1
+#define MVEBU_MBUS_PCI_MEM 0x2
+#define MVEBU_MBUS_PCI_WA  0x3
+
+/*
+ * Magic value that explicits that we don't need a remapping-capable
+ * address decoding window.
+ */
+#define MVEBU_MBUS_NO_REMAP (0xffffffff)
+
+/* Maximum size of a mbus window name */
+#define MVEBU_MBUS_MAX_WINNAME_SZ 32
+
+const struct mbus_dram_target_info *mvebu_mbus_dram_info(void);
+void mvebu_mbus_get_pcie_mem_aperture(struct resource *res);
+void mvebu_mbus_get_pcie_io_aperture(struct resource *res);
+int mvebu_mbus_add_window_remap_by_id(unsigned int target,
+                                     unsigned int attribute,
+                                     phys_addr_t base, size_t size,
+                                     phys_addr_t remap);
+int mvebu_mbus_add_window_by_id(unsigned int target, unsigned int attribute,
+                               phys_addr_t base, size_t size);
+int mvebu_mbus_del_window(phys_addr_t base, size_t size);
+int mbus_dt_setup_win(struct mvebu_mbus_state *mbus,
+                     u32 base, u32 size, u8 target, u8 attr);
+
+#endif /* __LINUX_MBUS_H */
index 8e44855712c33be990b02ff0db8f70f67110d08d..96348d617fca34c4abfbf00759a84b8178d8aae9 100644 (file)
@@ -20,6 +20,10 @@ extern __kernel_size_t strspn(const char *,const char *);
  */
 #include <asm/string.h>
 
+#ifndef __HAVE_ARCH_BCOPY
+char *bcopy(const char *src, char *dest, int count);
+#endif
+
 #ifndef __HAVE_ARCH_STRCPY
 extern char * strcpy(char *,const char *);
 #endif
@@ -89,6 +93,9 @@ extern void * memchr(const void *,int,__kernel_size_t);
 void *memchr_inv(const void *, int, size_t);
 #endif
 
+unsigned long ustrtoul(const char *cp, char **endp, unsigned int base);
+unsigned long long ustrtoull(const char *cp, char **endp, unsigned int base);
+
 #ifdef __cplusplus
 }
 #endif
index 97d179a6e9e747ab657c4025796bfeb047f3a0bb..7edc760c7b204b676f19596fc81e29a90f1d40a2 100644 (file)
@@ -41,7 +41,8 @@
 #define DWC3_REG_OFFSET                                0xC100
 
 struct g_event_buffer {
-       u64 g_evntadr;
+       u32 g_evntadrlo;
+       u32 g_evntadrhi;
        u32 g_evntsiz;
        u32 g_evntcount;
 };
@@ -185,4 +186,9 @@ struct dwc3 {                                       /* offset: 0xC100 */
 #define DWC3_GTXFIFOSIZ_TXFDEF(n)              ((n) & 0xffff)
 #define DWC3_GTXFIFOSIZ_TXFSTADDR(n)           ((n) & 0xffff0000)
 
+/* Device Control Register */
+#define DWC3_DCTL_RUN_STOP                     (1 << 31)
+#define DWC3_DCTL_CSFTRST                      (1 << 30)
+#define DWC3_DCTL_LSFTRST                      (1 << 29)
+
 #endif /* __DWC3_H_ */
index 9f65ef96ac131912f32e49729752f33735dc61dd..075d222195ff25ea6b6addd703764452bd98e9fe 100644 (file)
@@ -14,6 +14,8 @@
 #define __deprecated
 #endif
 
+#include <linux/compat.h>
+
 /* The USB role is defined by the connector used on the board, so long as
  * standards are being followed.  (Developer boards sometimes won't.)
  */
index 7f5f9bc8ca86eb92614c24f951991f05d9dd64e5..d74a190eea066684a072e477a9fe52fb6640b20d 100644 (file)
@@ -387,6 +387,7 @@ int mmc_legacy_init(int verbose);
 
 int board_mmc_init(bd_t *bis);
 int cpu_mmc_init(bd_t *bis);
+int mmc_get_env_addr(struct mmc *mmc, int copy, u32 *env_addr);
 
 /* Set block count limit because of 16 bit register limit on some hardware*/
 #ifndef CONFIG_SYS_MMC_MAX_BLK_COUNT
index a887bfb5f7a0a927f0e86eecc1fd8283f3738140..34651ab3779014ce6ec96a83b41acc0a96e60c00 100644 (file)
@@ -65,6 +65,7 @@ int mpc512x_fec_initialize(bd_t *bis);
 int mpc5xxx_fec_initialize(bd_t *bis);
 int mpc82xx_scc_enet_initialize(bd_t *bis);
 int mvgbe_initialize(bd_t *bis);
+int mvneta_initialize(bd_t *bis, int base_addr, int devnum, int phy_addr);
 int natsemi_initialize(bd_t *bis);
 int ne2k_register(void);
 int npe_initialize(bd_t *bis);
index 5784cfd97b859407c9b32fc3c4246e0674c742fd..0607379537d7ccf1038a0d322fdf29d95fbc0df4 100644 (file)
@@ -53,7 +53,7 @@
  * @clock:             UART base clock speed in Hz
  */
 struct ns16550_platdata {
-       unsigned char *base;
+       unsigned long base;
        int reg_shift;
        int clock;
 };
index 2fcc328d5bcfcbb7eb5bd740ad79b01c52830134..b4950776977e5440a75873065b753c472798a73e 100644 (file)
@@ -32,7 +32,9 @@
 #define PHY_10G_FEATURES       (PHY_GBIT_FEATURES | \
                                SUPPORTED_10000baseT_Full)
 
+#ifndef PHY_ANEG_TIMEOUT
 #define PHY_ANEG_TIMEOUT       4000
+#endif
 
 
 typedef enum {
index b673be270c8077b1d9eb73824b3fe0527d76b921..aa0a48ea62710dd019c77c75cc5350a9f61fb14d 100644 (file)
 
 #define SPI_DEFAULT_WORDLEN 8
 
+#ifdef CONFIG_DM_SPI
+struct dm_spi_bus {
+       uint max_hz;
+};
+
+#endif /* CONFIG_DM_SPI */
+
 /**
  * struct spi_slave - Representation of a SPI slave
  *
- * Drivers are expected to extend this with controller-specific data.
+ * For driver model this is the per-child data used by the SPI bus. It can
+ * be accessed using dev_get_parentdata() on the slave device. Each SPI
+ * driver should define this child data in its U_BOOT_DRIVER() definition:
+ *
+ *     .per_child_auto_alloc_size      = sizeof(struct spi_slave),
  *
- * @bus:               ID of the bus that the slave is attached to.
+ * If not using driver model, drivers are expected to extend this with
+ * controller-specific data.
+ *
+ * @dev:               SPI slave device
+ * @max_hz:            Maximum speed for this slave
+ * @mode:              SPI mode to use for this slave (see SPI mode flags)
+ * @bus:               ID of the bus that the slave is attached to. For
+ *                     driver model this is the sequence number of the SPI
+ *                     bus (bus->seq) so does not need to be stored
  * @cs:                        ID of the chip select connected to the slave.
  * @op_mode_rx:                SPI RX operation mode.
  * @op_mode_tx:                SPI TX operation mode.
  * @flags:             Indication of SPI flags.
  */
 struct spi_slave {
+#ifdef CONFIG_DM_SPI
+       struct udevice *dev;    /* struct spi_slave is dev->parentdata */
+       uint max_hz;
+       uint mode;
+#else
        unsigned int bus;
+#endif
        unsigned int cs;
        u8 op_mode_rx;
        u8 op_mode_tx;
@@ -228,8 +253,9 @@ int  spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
  * Returns: 1 if bus:cs identifies a valid chip on this board, 0
  * otherwise.
  */
-int  spi_cs_is_valid(unsigned int bus, unsigned int cs);
+int spi_cs_is_valid(unsigned int bus, unsigned int cs);
 
+#ifndef CONFIG_DM_SPI
 /**
  * Activate a SPI chipselect.
  * This function is provided by the board code when using a driver
@@ -255,6 +281,7 @@ void spi_cs_deactivate(struct spi_slave *slave);
  * @hz:                The transfer speed
  */
 void spi_set_speed(struct spi_slave *slave, uint hz);
+#endif
 
 /**
  * Write 8 bits, then read 8 bits.
@@ -305,4 +332,270 @@ struct spi_slave *spi_setup_slave_fdt(const void *blob, int slave_node,
 struct spi_slave *spi_base_setup_slave_fdt(const void *blob, int busnum,
                                           int node);
 
+#ifdef CONFIG_DM_SPI
+
+/**
+ * struct spi_cs_info - Information about a bus chip select
+ *
+ * @dev:       Connected device, or NULL if none
+ */
+struct spi_cs_info {
+       struct udevice *dev;
+};
+
+/**
+ * struct struct dm_spi_ops - Driver model SPI operations
+ *
+ * The uclass interface is implemented by all SPI devices which use
+ * driver model.
+ */
+struct dm_spi_ops {
+       /**
+        * Claim the bus and prepare it for communication.
+        *
+        * The device provided is the slave device. It's parent controller
+        * will be used to provide the communication.
+        *
+        * This must be called before doing any transfers with a SPI slave. It
+        * will enable and initialize any SPI hardware as necessary, and make
+        * sure that the SCK line is in the correct idle state. It is not
+        * allowed to claim the same bus for several slaves without releasing
+        * the bus in between.
+        *
+        * @bus:        The SPI slave
+        *
+        * Returns: 0 if the bus was claimed successfully, or a negative value
+        * if it wasn't.
+        */
+       int (*claim_bus)(struct udevice *bus);
+
+       /**
+        * Release the SPI bus
+        *
+        * This must be called once for every call to spi_claim_bus() after
+        * all transfers have finished. It may disable any SPI hardware as
+        * appropriate.
+        *
+        * @bus:        The SPI slave
+        */
+       int (*release_bus)(struct udevice *bus);
+
+       /**
+        * Set the word length for SPI transactions
+        *
+        * Set the word length (number of bits per word) for SPI transactions.
+        *
+        * @bus:        The SPI slave
+        * @wordlen:    The number of bits in a word
+        *
+        * Returns: 0 on success, -ve on failure.
+        */
+       int (*set_wordlen)(struct udevice *bus, unsigned int wordlen);
+
+       /**
+        * SPI transfer
+        *
+        * This writes "bitlen" bits out the SPI MOSI port and simultaneously
+        * clocks "bitlen" bits in the SPI MISO port.  That's just the way SPI
+        * works.
+        *
+        * The source of the outgoing bits is the "dout" parameter and the
+        * destination of the input bits is the "din" parameter.  Note that
+        * "dout" and "din" can point to the same memory location, in which
+        * case the input data overwrites the output data (since both are
+        * buffered by temporary variables, this is OK).
+        *
+        * spi_xfer() interface:
+        * @dev:        The slave device to communicate with
+        * @bitlen:     How many bits to write and read.
+        * @dout:       Pointer to a string of bits to send out.  The bits are
+        *              held in a byte array and are sent MSB first.
+        * @din:        Pointer to a string of bits that will be filled in.
+        * @flags:      A bitwise combination of SPI_XFER_* flags.
+        *
+        * Returns: 0 on success, not -1 on failure
+        */
+       int (*xfer)(struct udevice *dev, unsigned int bitlen, const void *dout,
+                   void *din, unsigned long flags);
+
+       /**
+        * Set transfer speed.
+        * This sets a new speed to be applied for next spi_xfer().
+        * @bus:        The SPI bus
+        * @hz:         The transfer speed
+        * @return 0 if OK, -ve on error
+        */
+       int (*set_speed)(struct udevice *bus, uint hz);
+
+       /**
+        * Set the SPI mode/flags
+        *
+        * It is unclear if we want to set speed and mode together instead
+        * of separately.
+        *
+        * @bus:        The SPI bus
+        * @mode:       Requested SPI mode (SPI_... flags)
+        * @return 0 if OK, -ve on error
+        */
+       int (*set_mode)(struct udevice *bus, uint mode);
+
+       /**
+        * Get information on a chip select
+        *
+        * This is only called when the SPI uclass does not know about a
+        * chip select, i.e. it has no attached device. It gives the driver
+        * a chance to allow activity on that chip select even so.
+        *
+        * @bus:        The SPI bus
+        * @cs:         The chip select (0..n-1)
+        * @info:       Returns information about the chip select, if valid.
+        *              On entry info->dev is NULL
+        * @return 0 if OK (and @info is set up), -ENODEV if the chip select
+        *         is invalid, other -ve value on error
+        */
+       int (*cs_info)(struct udevice *bus, uint cs, struct spi_cs_info *info);
+};
+
+struct dm_spi_emul_ops {
+       /**
+        * SPI transfer
+        *
+        * This writes "bitlen" bits out the SPI MOSI port and simultaneously
+        * clocks "bitlen" bits in the SPI MISO port.  That's just the way SPI
+        * works. Here the device is a slave.
+        *
+        * The source of the outgoing bits is the "dout" parameter and the
+        * destination of the input bits is the "din" parameter.  Note that
+        * "dout" and "din" can point to the same memory location, in which
+        * case the input data overwrites the output data (since both are
+        * buffered by temporary variables, this is OK).
+        *
+        * spi_xfer() interface:
+        * @slave:      The SPI slave which will be sending/receiving the data.
+        * @bitlen:     How many bits to write and read.
+        * @dout:       Pointer to a string of bits sent to the device. The
+        *              bits are held in a byte array and are sent MSB first.
+        * @din:        Pointer to a string of bits that will be sent back to
+        *              the master.
+        * @flags:      A bitwise combination of SPI_XFER_* flags.
+        *
+        * Returns: 0 on success, not -1 on failure
+        */
+       int (*xfer)(struct udevice *slave, unsigned int bitlen,
+                   const void *dout, void *din, unsigned long flags);
+};
+
+/**
+ * spi_find_bus_and_cs() - Find bus and slave devices by number
+ *
+ * Given a bus number and chip select, this finds the corresponding bus
+ * device and slave device. Neither device is activated by this function,
+ * although they may have been activated previously.
+ *
+ * @busnum:    SPI bus number
+ * @cs:                Chip select to look for
+ * @busp:      Returns bus device
+ * @devp:      Return slave device
+ * @return 0 if found, -ENODEV on error
+ */
+int spi_find_bus_and_cs(int busnum, int cs, struct udevice **busp,
+                       struct udevice **devp);
+
+/**
+ * spi_get_bus_and_cs() - Find and activate bus and slave devices by number
+ *
+ * Given a bus number and chip select, this finds the corresponding bus
+ * device and slave device.
+ *
+ * If no such slave exists, and drv_name is not NULL, then a new slave device
+ * is automatically bound on this chip select.
+ *
+ * Ths new slave device is probed ready for use with the given speed and mode.
+ *
+ * @busnum:    SPI bus number
+ * @cs:                Chip select to look for
+ * @speed:     SPI speed to use for this slave
+ * @mode:      SPI mode to use for this slave
+ * @drv_name:  Name of driver to attach to this chip select
+ * @dev_name:  Name of the new device thus created
+ * @busp:      Returns bus device
+ * @devp:      Return slave device
+ * @return 0 if found, -ve on error
+ */
+int spi_get_bus_and_cs(int busnum, int cs, int speed, int mode,
+                       const char *drv_name, const char *dev_name,
+                       struct udevice **busp, struct spi_slave **devp);
+
+/**
+ * spi_chip_select() - Get the chip select for a slave
+ *
+ * @return the chip select this slave is attached to
+ */
+int spi_chip_select(struct udevice *slave);
+
+/**
+ * spi_bind_device() - bind a device to a bus's chip select
+ *
+ * This binds a new device to an given chip select (which must be unused).
+ *
+ * @bus:       SPI bus to search
+ * @cs:                Chip select to attach to
+ * @drv_name:  Name of driver to attach to this chip select
+ * @dev_name:  Name of the new device thus created
+ * @devp:      Returns the newly bound device
+ */
+int spi_bind_device(struct udevice *bus, int cs, const char *drv_name,
+                   const char *dev_name, struct udevice **devp);
+
+/**
+ * spi_ofdata_to_platdata() - decode standard SPI platform data
+ *
+ * This decodes the speed and mode from a device tree node and puts it into
+ * the spi_slave structure.
+ *
+ * @blob:      Device tree blob
+ * @node:      Node offset to read from
+ * @spi:       Place to put the decoded information
+ */
+int spi_ofdata_to_platdata(const void *blob, int node, struct spi_slave *spi);
+
+/**
+ * spi_cs_info() - Check information on a chip select
+ *
+ * This checks a particular chip select on a bus to see if it has a device
+ * attached, or is even valid.
+ *
+ * @bus:       The SPI bus
+ * @cs:                The chip select (0..n-1)
+ * @info:      Returns information about the chip select, if valid
+ * @return 0 if OK (and @info is set up), -ENODEV if the chip select
+ *        is invalid, other -ve value on error
+ */
+int spi_cs_info(struct udevice *bus, uint cs, struct spi_cs_info *info);
+
+struct sandbox_state;
+
+/**
+ * sandbox_spi_get_emul() - get an emulator for a SPI slave
+ *
+ * This provides a way to attach an emulated SPI device to a particular SPI
+ * slave, so that xfer() operations on the slave will be handled by the
+ * emulator. If a emulator already exists on that chip select it is returned.
+ * Otherwise one is created.
+ *
+ * @state:     Sandbox state
+ * @bus:       SPI bus requesting the emulator
+ * @slave:     SPI slave device requesting the emulator
+ * @emuip:     Returns pointer to emulator
+ * @return 0 if OK, -ve on error
+ */
+int sandbox_spi_get_emul(struct sandbox_state *state,
+                        struct udevice *bus, struct udevice *slave,
+                        struct udevice **emulp);
+
+/* Access the serial operations for a device */
+#define spi_get_ops(dev)       ((struct dm_spi_ops *)(dev)->driver->ops)
+#define spi_emul_get_ops(dev)  ((struct dm_spi_emul_ops *)(dev)->driver->ops)
+#endif /* CONFIG_DM_SPI */
+
 #endif /* _SPI_H_ */
index 408a5b401cd91e66e88b84eab5c1dcef97681522..5913b39e268ee30598de449d03447a8205c80dae 100644 (file)
@@ -15,9 +15,8 @@
 #ifndef _SPI_FLASH_H_
 #define _SPI_FLASH_H_
 
-#include <spi.h>
+#include <dm.h>        /* Because we dereference struct udevice here */
 #include <linux/types.h>
-#include <linux/compiler.h>
 
 #ifndef CONFIG_SF_DEFAULT_SPEED
 # define CONFIG_SF_DEFAULT_SPEED       1000000
 # define CONFIG_SF_DEFAULT_BUS         0
 #endif
 
-/* sf param flags */
-#define SECT_4K                1 << 1
-#define SECT_32K       1 << 2
-#define E_FSR          1 << 3
-#define WR_QPP         1 << 4
-
-/* Enum list - Full read commands */
-enum spi_read_cmds {
-       ARRAY_SLOW = 1 << 0,
-       DUAL_OUTPUT_FAST = 1 << 1,
-       DUAL_IO_FAST = 1 << 2,
-       QUAD_OUTPUT_FAST = 1 << 3,
-       QUAD_IO_FAST = 1 << 4,
-};
-#define RD_EXTN                ARRAY_SLOW | DUAL_OUTPUT_FAST | DUAL_IO_FAST
-#define RD_FULL                RD_EXTN | QUAD_OUTPUT_FAST | QUAD_IO_FAST
-
-/* Dual SPI flash memories */
-enum spi_dual_flash {
-       SF_SINGLE_FLASH = 0,
-       SF_DUAL_STACKED_FLASH = 1 << 0,
-       SF_DUAL_PARALLEL_FLASH = 1 << 1,
-};
-
-/**
- * struct spi_flash_params - SPI/QSPI flash device params structure
- *
- * @name:              Device name ([MANUFLETTER][DEVTYPE][DENSITY][EXTRAINFO])
- * @jedec:             Device jedec ID (0x[1byte_manuf_id][2byte_dev_id])
- * @ext_jedec:         Device ext_jedec ID
- * @sector_size:       Sector size of this device
- * @nr_sectors:                No.of sectors on this device
- * @e_rd_cmd:          Enum list for read commands
- * @flags:             Important param, for flash specific behaviour
- */
-struct spi_flash_params {
-       const char *name;
-       u32 jedec;
-       u16 ext_jedec;
-       u32 sector_size;
-       u32 nr_sectors;
-       u8 e_rd_cmd;
-       u16 flags;
-};
-
-extern const struct spi_flash_params spi_flash_params_table[];
+struct spi_slave;
 
 /**
  * struct spi_flash - SPI flash structure
  *
  * @spi:               SPI slave
  * @name:              Name of SPI flash
- * @dual_flash:                Indicates dual flash memories - dual stacked, parallel
+ * @dual_flash:        Indicates dual flash memories - dual stacked, parallel
  * @shift:             Flash shift useful in dual parallel
  * @size:              Total flash size
  * @page_size:         Write (page) size
  * @sector_size:       Sector size
- * @erase_size:                Erase size
+ * @erase_size:        Erase size
  * @bank_read_cmd:     Bank read cmd
  * @bank_write_cmd:    Bank write cmd
  * @bank_curr:         Current flash bank
@@ -97,8 +51,8 @@ extern const struct spi_flash_params spi_flash_params_table[];
  * @erase_cmd:         Erase cmd 4K, 32K, 64K
  * @read_cmd:          Read cmd - Array Fast, Extn read and quad read.
  * @write_cmd:         Write cmd - page and quad program.
- * @dummy_byte:                Dummy cycles for read operation.
- * @memory_map:                Address of read-only SPI flash access
+ * @dummy_byte:        Dummy cycles for read operation.
+ * @memory_map:        Address of read-only SPI flash access
  * @read:              Flash read ops: Read len bytes at offset into buf
  *                     Supported cmds: Fast Array Read
  * @write:             Flash write ops: Write len bytes from buf into offset
@@ -108,7 +62,12 @@ extern const struct spi_flash_params spi_flash_params_table[];
  * return 0 - Success, 1 - Failure
  */
 struct spi_flash {
+#ifdef CONFIG_DM_SPI_FLASH
+       struct spi_slave *spi;
+       struct udevice *dev;
+#else
        struct spi_slave *spi;
+#endif
        const char *name;
        u8 dual_flash;
        u8 shift;
@@ -129,12 +88,75 @@ struct spi_flash {
        u8 dummy_byte;
 
        void *memory_map;
+#ifndef CONFIG_DM_SPI_FLASH
+       /*
+        * These are not strictly needed for driver model, but keep them here
+        * whilt the transition is in progress.
+        *
+        * Normally each driver would provide its own operations, but for
+        * SPI flash most chips use the same algorithms. One approach is
+        * to create a 'common' SPI flash device which knows how to talk
+        * to most devices, and then allow other drivers to be used instead
+        * if requird, perhaps with a way of scanning through the list to
+        * find the driver that matches the device.
+        */
        int (*read)(struct spi_flash *flash, u32 offset, size_t len, void *buf);
        int (*write)(struct spi_flash *flash, u32 offset, size_t len,
                        const void *buf);
        int (*erase)(struct spi_flash *flash, u32 offset, size_t len);
+#endif
 };
 
+struct dm_spi_flash_ops {
+       int (*read)(struct udevice *dev, u32 offset, size_t len, void *buf);
+       int (*write)(struct udevice *dev, u32 offset, size_t len,
+                    const void *buf);
+       int (*erase)(struct udevice *dev, u32 offset, size_t len);
+};
+
+/* Access the serial operations for a device */
+#define sf_get_ops(dev) ((struct dm_spi_flash_ops *)(dev)->driver->ops)
+
+#ifdef CONFIG_DM_SPI_FLASH
+int spi_flash_probe_bus_cs(unsigned int busnum, unsigned int cs,
+                          unsigned int max_hz, unsigned int spi_mode,
+                          struct udevice **devp);
+
+/* Compatibility function - this is the old U-Boot API */
+struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs,
+                                 unsigned int max_hz, unsigned int spi_mode);
+
+/* Compatibility function - this is the old U-Boot API */
+void spi_flash_free(struct spi_flash *flash);
+
+int spi_flash_remove(struct udevice *flash);
+
+static inline int spi_flash_read(struct spi_flash *flash, u32 offset,
+               size_t len, void *buf)
+{
+       return sf_get_ops(flash->dev)->read(flash->dev, offset, len, buf);
+}
+
+static inline int spi_flash_write(struct spi_flash *flash, u32 offset,
+               size_t len, const void *buf)
+{
+       return sf_get_ops(flash->dev)->write(flash->dev, offset, len, buf);
+}
+
+static inline int spi_flash_erase(struct spi_flash *flash, u32 offset,
+               size_t len)
+{
+       return sf_get_ops(flash->dev)->erase(flash->dev, offset, len);
+}
+
+struct sandbox_state;
+
+int sandbox_sf_bind_emul(struct sandbox_state *state, int busnum, int cs,
+                        struct udevice *bus, int of_offset, const char *spec);
+
+void sandbox_sf_unbind_emul(struct sandbox_state *state, int busnum, int cs);
+
+#else
 struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs,
                unsigned int max_hz, unsigned int spi_mode);
 
@@ -169,6 +191,7 @@ static inline int spi_flash_erase(struct spi_flash *flash, u32 offset,
 {
        return flash->erase(flash, offset, len);
 }
+#endif
 
 void spi_boot(void) __noreturn;
 void spi_spl_load_image(uint32_t offs, unsigned int size, void *vdst);
index a7e41da7fd4980ef2362816a63d8680cc26ef1b9..cee251faf7dcec67794b0d24f3e2b4a9fea514fb 100644 (file)
@@ -72,6 +72,8 @@ void spl_sata_load_image(void);
 int spl_load_image_fat(block_dev_desc_t *block_dev, int partition, const char *filename);
 int spl_load_image_fat_os(block_dev_desc_t *block_dev, int partition);
 
+void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image);
+
 #ifdef CONFIG_SPL_BOARD_INIT
 void spl_board_init(void);
 #endif
index c355fbe4819836a18bcfacd94c592feb612fcdd3..c4a288d5e9f804bbbda4ac9c8c24f13d1bd59c55 100644 (file)
@@ -150,7 +150,8 @@ enum usb_init_type {
        defined(CONFIG_USB_OMAP3) || defined(CONFIG_USB_DA8XX) || \
        defined(CONFIG_USB_BLACKFIN) || defined(CONFIG_USB_AM35X) || \
        defined(CONFIG_USB_MUSB_DSPS) || defined(CONFIG_USB_MUSB_AM35X) || \
-       defined(CONFIG_USB_MUSB_OMAP2PLUS) || defined(CONFIG_USB_XHCI)
+       defined(CONFIG_USB_MUSB_OMAP2PLUS) || defined(CONFIG_USB_XHCI) || \
+       defined(CONFIG_USB_DWC2)
 
 int usb_lowlevel_init(int index, enum usb_init_type init, void **controller);
 int usb_lowlevel_stop(int index);
index 88e5da72ecc6ffe619a337b981dcb6c6af206c9a..8460439d8e772d4126b78ad616059dd38a7dabff 100644 (file)
@@ -8,4 +8,23 @@ config CC_OPTIMIZE_LIBS_FOR_SPEED
 
          If unsure, say N.
 
+config HAVE_PRIVATE_LIBGCC
+       bool
+
+config USE_PRIVATE_LIBGCC
+       bool "Use private libgcc"
+       depends on HAVE_PRIVATE_LIBGCC
+       help
+         This option allows you to use the built-in libgcc implementation
+         of U-boot instead of the one privided by the compiler.
+         If unsure, say N.
+
+config SYS_HZ
+       int
+       default 1000
+       help
+         The frequency of the timer returned by get_timer().
+         get_timer() must operate in milliseconds and this option must be
+         set to 1000.
+
 endmenu
index 06d4542029623cb7d84f764c57fb805bc84f5cd6..9714620ab3e211df006d440dc4f1abb6d03bb9b8 100644 (file)
@@ -72,6 +72,7 @@ static const char * const compat_names[COMPAT_COUNT] = {
        COMPAT(COMPAT_NXP_PTN3460, "nxp,ptn3460"),
        COMPAT(SAMSUNG_EXYNOS_SYSMMU, "samsung,sysmmu-v3.3"),
        COMPAT(PARADE_PS8625, "parade,ps8625"),
+       COMPAT(COMPAT_INTEL_LPC, "intel,lpc"),
 };
 
 const char *fdtdec_get_compatible(enum fdt_compat_id id)
@@ -708,4 +709,75 @@ int fdtdec_read_fmap_entry(const void *blob, int node, const char *name,
 
        return 0;
 }
+
+static u64 fdtdec_get_number(const fdt32_t *ptr, unsigned int cells)
+{
+       u64 number = 0;
+
+       while (cells--)
+               number = (number << 32) | fdt32_to_cpu(*ptr++);
+
+       return number;
+}
+
+int fdt_get_resource(const void *fdt, int node, const char *property,
+                    unsigned int index, struct fdt_resource *res)
+{
+       const fdt32_t *ptr, *end;
+       int na, ns, len, parent;
+       unsigned int i = 0;
+
+       parent = fdt_parent_offset(fdt, node);
+       if (parent < 0)
+               return parent;
+
+       na = fdt_address_cells(fdt, parent);
+       ns = fdt_size_cells(fdt, parent);
+
+       ptr = fdt_getprop(fdt, node, property, &len);
+       if (!ptr)
+               return len;
+
+       end = ptr + len / sizeof(*ptr);
+
+       while (ptr + na + ns <= end) {
+               if (i == index) {
+                       res->start = res->end = fdtdec_get_number(ptr, na);
+                       res->end += fdtdec_get_number(&ptr[na], ns) - 1;
+                       return 0;
+               }
+
+               ptr += na + ns;
+               i++;
+       }
+
+       return -FDT_ERR_NOTFOUND;
+}
+
+int fdt_get_named_resource(const void *fdt, int node, const char *property,
+                          const char *prop_names, const char *name,
+                          struct fdt_resource *res)
+{
+       int index;
+
+       index = fdt_find_string(fdt, node, prop_names, name);
+       if (index < 0)
+               return index;
+
+       return fdt_get_resource(fdt, node, property, index, res);
+}
+
+int fdtdec_pci_get_bdf(const void *fdt, int node, int *bdf)
+{
+       const fdt32_t *prop;
+       int len;
+
+       prop = fdt_getprop(fdt, node, "reg", &len);
+       if (!prop)
+               return len;
+
+       *bdf = fdt32_to_cpu(*prop) & 0xffffff;
+
+       return 0;
+}
 #endif
index 7597bad555404a276a72afd4bda981e0f4187ce7..39f4b3f8ad5ffecc59afa59f9e96a93f4e16fe5c 100644 (file)
@@ -15,14 +15,16 @@ int initcall_run_list(const init_fnc_t init_sequence[])
 
        for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
                unsigned long reloc_ofs = 0;
+               int ret;
 
                if (gd->flags & GD_FLG_RELOC)
                        reloc_ofs = gd->reloc_off;
                debug("initcall: %p\n", (char *)*init_fnc_ptr - reloc_ofs);
-               if ((*init_fnc_ptr)()) {
-                       printf("initcall sequence %p failed at call %p\n",
+               ret = (*init_fnc_ptr)();
+               if (ret) {
+                       printf("initcall sequence %p failed at call %p (err=%d)\n",
                               init_sequence,
-                              (char *)*init_fnc_ptr - reloc_ofs);
+                              (char *)*init_fnc_ptr - reloc_ofs, ret);
                        return -1;
                }
        }
index 36af0435254b47cb0d2599836d1c81638266adf8..03733e574f71db1df2ebec2c08ec66dff95908d0 100644 (file)
@@ -491,6 +491,82 @@ int fdt_stringlist_contains(const char *strlist, int listlen, const char *str)
        return 0;
 }
 
+int fdt_count_strings(const void *fdt, int node, const char *property)
+{
+       int length, i, count = 0;
+       const char *list;
+
+       list = fdt_getprop(fdt, node, property, &length);
+       if (!list)
+               return -length;
+
+       for (i = 0; i < length; i++) {
+               int len = strlen(list);
+
+               list += len + 1;
+               i += len;
+               count++;
+       }
+
+       return count;
+}
+
+int fdt_find_string(const void *fdt, int node, const char *property,
+                   const char *string)
+{
+       const char *list, *end;
+       int len, index = 0;
+
+       list = fdt_getprop(fdt, node, property, &len);
+       if (!list)
+               return len;
+
+       end = list + len;
+       len = strlen(string);
+
+       while (list < end) {
+               int l = strlen(list);
+
+               if (l == len && memcmp(list, string, len) == 0)
+                       return index;
+
+               list += l + 1;
+               index++;
+       }
+
+       return -FDT_ERR_NOTFOUND;
+}
+
+int fdt_get_string_index(const void *fdt, int node, const char *property,
+                        int index, const char **output)
+{
+       const char *list;
+       int length, i;
+
+       list = fdt_getprop(fdt, node, property, &length);
+
+       for (i = 0; i < length; i++) {
+               int len = strlen(list);
+
+               if (index == 0) {
+                       *output = list;
+                       return 0;
+               }
+
+               list += len + 1;
+               i += len;
+               index--;
+       }
+
+       return FDT_ERR_NOTFOUND;
+}
+
+int fdt_get_string(const void *fdt, int node, const char *property,
+                  const char **output)
+{
+       return fdt_get_string_index(fdt, node, property, 0, output);
+}
+
 int fdt_node_check_compatible(const void *fdt, int nodeoffset,
                              const char *compatible)
 {
index 41a2be463565c6b519841902cba45b43839ef69a..031f0e1ac895289f772fb4bf538626ff065d1106 100644 (file)
--- a/lib/lmb.c
+++ b/lib/lmb.c
@@ -236,7 +236,7 @@ long lmb_reserve(struct lmb *lmb, phys_addr_t base, phys_size_t size)
        return lmb_add_region(_rgn, base, size);
 }
 
-long lmb_overlaps_region(struct lmb_region *rgn, phys_addr_t base,
+static long lmb_overlaps_region(struct lmb_region *rgn, phys_addr_t base,
                                phys_size_t size)
 {
        unsigned long i;
index c7b026498be67e28f02cf070acf73a43e3c18ad4..5ebd1be48f324f8e9f21157ddd1b38f2dc85570a 100644 (file)
 #include <div64.h>
 #include <asm/io.h>
 
-#if CONFIG_SYS_HZ != 1000
-#warning "CONFIG_SYS_HZ must be 1000 and should not be defined by platforms"
-#endif
-
 #ifndef CONFIG_WD_PERIOD
 # define CONFIG_WD_PERIOD      (10 * 1000 * 1000)      /* 10 seconds default */
 #endif
index 76ffa05608adcaffb9bf3f888b4983a6a17cfcd4..eac4f7b3d0ed602c852d0f47dd9580670f8292da 100644 (file)
--- a/net/eth.c
+++ b/net/eth.c
@@ -153,7 +153,7 @@ static void eth_current_changed(void)
                setenv("ethact", NULL);
 }
 
-int eth_address_set(unsigned char *addr)
+static int eth_address_set(unsigned char *addr)
 {
        return memcmp(addr, "\0\0\0\0\0\0", 6);
 }
index 966d1cfba360ce7e7505dd5f806ce13543b0654c..0a2c53302cab1edacacd88f439b888f4837e7d4a 100644 (file)
@@ -299,6 +299,8 @@ static void tftp_complete(void)
                putc('#');
                TftpNumchars++;
        }
+       puts("  ");
+       print_size(TftpTsize, "");
 #endif
        time_start = get_timer(time_start);
        if (time_start > 0) {
index 4af5355fa5a20f9c2e763f37b269bea38d43e8ea..4194edb89e86fe2db008767dd33bd7faf4e32b79 100644 (file)
@@ -52,7 +52,7 @@ int post_init_f(void)
  * Boards with hotkey support can override this weak default function
  * by defining one in their board specific code.
  */
-int __post_hotkeys_pressed(void)
+__weak int post_hotkeys_pressed(void)
 {
 #ifdef CONFIG_SYS_POST_HOTKEYS_GPIO
        int ret;
@@ -73,9 +73,6 @@ int __post_hotkeys_pressed(void)
 
        return 0;       /* No hotkeys supported */
 }
-int post_hotkeys_pressed(void)
-       __attribute__((weak, alias("__post_hotkeys_pressed")));
-
 
 void post_bootmode_init(void)
 {
@@ -236,11 +233,9 @@ static void post_get_flags(int *test_flags)
                        test_flags[j] |= POST_SLOWTEST;
 }
 
-void __show_post_progress(unsigned int test_num, int before, int result)
+__weak void show_post_progress(unsigned int test_num, int before, int result)
 {
 }
-void show_post_progress(unsigned int, int, int)
-                       __attribute__((weak, alias("__show_post_progress")));
 
 static int post_run_single(struct post_test *test,
                                int test_flags, int flags, unsigned int i)
index 88c01d18ecf9a94fbee9b6cd273c7b6c3285fe3d..7afe437e62e11b1ed25f13c909fff68263957948 100644 (file)
@@ -216,13 +216,13 @@ $(obj)/sunxi-spl.bin: $(obj)/$(SPL_BIN).bin
 endif
 
 quiet_cmd_u-boot-spl = LD      $@
-      cmd_u-boot-spl = cd $(obj) && $(LD) $(LDFLAGS) $(LDFLAGS_$(@F)) \
+      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 \
-                      $(PLATFORM_LIBS) -Map $(SPL_BIN).map -o $(SPL_BIN)
+                      $(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
-       $(call cmd,u-boot-spl)
+$(obj)/$(SPL_BIN): $(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) ;
 
index 3a963c7973da5da0e37c0ac350ea7e4b1e2d59e1..3e3040b2e2ab9210ebef73859b93e158d2875ecc 100644 (file)
@@ -297,9 +297,24 @@ do_others () {
        else
                objdir=${1%/*}
                check_enabled_subimage $1 $objdir
+
+               if [ -f "$objdir/$KCONFIG_CONFIG" ]; then
+                       timestamp_before=$(stat --printf="%Y" \
+                                               $objdir/$KCONFIG_CONFIG)
+               fi
        fi
 
        run_make_config $target $objdir
+
+       if [ "$timestamp_before" -a -f "$objdir/$KCONFIG_CONFIG" ]; then
+               timestamp_after=$(stat --printf="%Y" $objdir/$KCONFIG_CONFIG)
+
+               if [ "$timestamp_after" -gt "$timestamp_before" ]; then
+                       # $objdir/.config has been updated.
+                       # touch .config to invoke "make silentoldconfig"
+                       touch $KCONFIG_CONFIG
+               fi
+       fi
 }
 
 progname=$(basename $0)
index 5c2415e3d2a93b9307e27cbefa48d6dab9eb40c9..75d3d41536bfb47079f37a284beca95bd982b425 100644 (file)
@@ -18,4 +18,6 @@ obj-$(CONFIG_DM_TEST) += core.o
 obj-$(CONFIG_DM_TEST) += ut.o
 ifneq ($(CONFIG_SANDBOX),)
 obj-$(CONFIG_DM_GPIO) += gpio.o
+obj-$(CONFIG_DM_SPI) += spi.o
+obj-$(CONFIG_DM_SPI_FLASH) += sf.o
 endif
index 873d64e42a4eda8cbe2ccaddd15cc6f2701cf5a0..abbaccff509ce09374f30e88983252672d3c4e62 100644 (file)
@@ -140,6 +140,37 @@ static int dm_test_bus_children_funcs(struct dm_test_state *dms)
 }
 DM_TEST(dm_test_bus_children_funcs, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
 
+/* Test that we can iterate through children */
+static int dm_test_bus_children_iterators(struct dm_test_state *dms)
+{
+       struct udevice *bus, *dev, *child;
+
+       /* Walk through the children one by one */
+       ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));
+       ut_assertok(device_find_first_child(bus, &dev));
+       ut_asserteq_str("c-test@5", dev->name);
+       ut_assertok(device_find_next_child(&dev));
+       ut_asserteq_str("c-test@0", dev->name);
+       ut_assertok(device_find_next_child(&dev));
+       ut_asserteq_str("c-test@1", dev->name);
+       ut_assertok(device_find_next_child(&dev));
+       ut_asserteq_ptr(dev, NULL);
+
+       /* Move to the next child without using device_find_first_child() */
+       ut_assertok(device_find_child_by_seq(bus, 5, true, &dev));
+       ut_asserteq_str("c-test@5", dev->name);
+       ut_assertok(device_find_next_child(&dev));
+       ut_asserteq_str("c-test@0", dev->name);
+
+       /* Try a device with no children */
+       ut_assertok(device_find_first_child(dev, &child));
+       ut_asserteq_ptr(child, NULL);
+
+       return 0;
+}
+DM_TEST(dm_test_bus_children_iterators,
+       DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
 /* Test that the bus can store data about each child */
 static int dm_test_bus_parent_data(struct dm_test_state *dms)
 {
index b0cfb42c85fc692a5d5ffb0ef11d22d5f5bcea90..ff5c2a749c5e37dbbcca5340dabdf18374a8e5c2 100644 (file)
@@ -67,6 +67,34 @@ static struct driver_info driver_info_pre_reloc = {
        .platdata = &test_pdata_manual,
 };
 
+void dm_leak_check_start(struct dm_test_state *dms)
+{
+       dms->start = mallinfo();
+       if (!dms->start.uordblks)
+               puts("Warning: Please add '#define DEBUG' to the top of common/dlmalloc.c\n");
+}
+
+int dm_leak_check_end(struct dm_test_state *dms)
+{
+       struct mallinfo end;
+       int id;
+
+       /* Don't delete the root class, since we started with that */
+       for (id = UCLASS_ROOT + 1; id < UCLASS_COUNT; id++) {
+               struct uclass *uc;
+
+               uc = uclass_find(id);
+               if (!uc)
+                       continue;
+               ut_assertok(uclass_destroy(uc));
+       }
+
+       end = mallinfo();
+       ut_asserteq(dms->start.uordblks, end.uordblks);
+
+       return 0;
+}
+
 /* Test that binding with platdata occurs correctly */
 static int dm_test_autobind(struct dm_test_state *dms)
 {
@@ -377,14 +405,11 @@ static int dm_test_leak(struct dm_test_state *dms)
        int i;
 
        for (i = 0; i < 2; i++) {
-               struct mallinfo start, end;
                struct udevice *dev;
                int ret;
                int id;
 
-               start = mallinfo();
-               if (!start.uordblks)
-                       puts("Warning: Please add '#define DEBUG' to the top of common/dlmalloc.c\n");
+               dm_leak_check_start(dms);
 
                ut_assertok(dm_scan_platdata(false));
                ut_assertok(dm_scan_fdt(gd->fdt_blob, false));
@@ -398,18 +423,7 @@ static int dm_test_leak(struct dm_test_state *dms)
                        ut_assertok(ret);
                }
 
-               /* Don't delete the root class, since we started with that */
-               for (id = UCLASS_ROOT + 1; id < UCLASS_COUNT; id++) {
-                       struct uclass *uc;
-
-                       uc = uclass_find(id);
-                       if (!uc)
-                               continue;
-                       ut_assertok(uclass_destroy(uc));
-               }
-
-               end = mallinfo();
-               ut_asserteq(start.uordblks, end.uordblks);
+               ut_assertok(dm_leak_check_end(dms));
        }
 
        return 0;
index 2b2b0b51fa74571a0e0ca200574bef48c0d7dee7..94bd0d99dc0bc1fa9b5c7033690ab6de7cc29b41 100644 (file)
@@ -7,11 +7,14 @@
 #include <common.h>
 #include <fdtdec.h>
 #include <dm.h>
+#include <dm/root.h>
 #include <dm/ut.h>
 #include <dm/test.h>
 #include <dm/util.h>
 #include <asm/gpio.h>
 
+DECLARE_GLOBAL_DATA_PTR;
+
 /* Test that sandbox GPIOs work correctly */
 static int dm_test_gpio(struct dm_test_state *dms)
 {
@@ -39,52 +42,51 @@ static int dm_test_gpio(struct dm_test_state *dms)
 
        /* Get the operations for this device */
        ops = gpio_get_ops(dev);
-       ut_assert(ops->get_state);
+       ut_assert(ops->get_function);
 
        /* Cannot get a value until it is reserved */
-       ut_asserteq(-1, ops->get_value(dev, offset));
-
+       ut_asserteq(-EBUSY, gpio_get_value(gpio + 1));
        /*
         * Now some tests that use the 'sandbox' back door. All GPIOs
         * should default to input, include b4 that we are using here.
         */
-       ut_assertok(ops->get_state(dev, offset, buf, sizeof(buf)));
-       ut_asserteq_str("b4:  in: 0 [ ]", buf);
+       ut_assertok(gpio_get_status(dev, offset, buf, sizeof(buf)));
+       ut_asserteq_str("b4: input: 0 [ ]", buf);
 
        /* Change it to an output */
        sandbox_gpio_set_direction(dev, offset, 1);
-       ut_assertok(ops->get_state(dev, offset, buf, sizeof(buf)));
-       ut_asserteq_str("b4: out: 0 [ ]", buf);
+       ut_assertok(gpio_get_status(dev, offset, buf, sizeof(buf)));
+       ut_asserteq_str("b4: output: 0 [ ]", buf);
 
        sandbox_gpio_set_value(dev, offset, 1);
-       ut_assertok(ops->get_state(dev, offset, buf, sizeof(buf)));
-       ut_asserteq_str("b4: out: 1 [ ]", buf);
+       ut_assertok(gpio_get_status(dev, offset, buf, sizeof(buf)));
+       ut_asserteq_str("b4: output: 1 [ ]", buf);
 
-       ut_assertok(ops->request(dev, offset, "testing"));
-       ut_assertok(ops->get_state(dev, offset, buf, sizeof(buf)));
-       ut_asserteq_str("b4: out: 1 [x] testing", buf);
+       ut_assertok(gpio_request(gpio, "testing"));
+       ut_assertok(gpio_get_status(dev, offset, buf, sizeof(buf)));
+       ut_asserteq_str("b4: output: 1 [x] testing", buf);
 
        /* Change the value a bit */
        ut_asserteq(1, ops->get_value(dev, offset));
        ut_assertok(ops->set_value(dev, offset, 0));
        ut_asserteq(0, ops->get_value(dev, offset));
-       ut_assertok(ops->get_state(dev, offset, buf, sizeof(buf)));
-       ut_asserteq_str("b4: out: 0 [x] testing", buf);
+       ut_assertok(gpio_get_status(dev, offset, buf, sizeof(buf)));
+       ut_asserteq_str("b4: output: 0 [x] testing", buf);
        ut_assertok(ops->set_value(dev, offset, 1));
        ut_asserteq(1, ops->get_value(dev, offset));
 
        /* Make it an input */
        ut_assertok(ops->direction_input(dev, offset));
-       ut_assertok(ops->get_state(dev, offset, buf, sizeof(buf)));
-       ut_asserteq_str("b4:  in: 1 [x] testing", buf);
+       ut_assertok(gpio_get_status(dev, offset, buf, sizeof(buf)));
+       ut_asserteq_str("b4: input: 1 [x] testing", buf);
        sandbox_gpio_set_value(dev, offset, 0);
        ut_asserteq(0, sandbox_gpio_get_value(dev, offset));
-       ut_assertok(ops->get_state(dev, offset, buf, sizeof(buf)));
-       ut_asserteq_str("b4:  in: 0 [x] testing", buf);
+       ut_assertok(gpio_get_status(dev, offset, buf, sizeof(buf)));
+       ut_asserteq_str("b4: input: 0 [x] testing", buf);
 
-       ut_assertok(ops->free(dev, offset));
-       ut_assertok(ops->get_state(dev, offset, buf, sizeof(buf)));
-       ut_asserteq_str("b4:  in: 0 [ ]", buf);
+       ut_assertok(gpio_free(gpio));
+       ut_assertok(gpio_get_status(dev, offset, buf, sizeof(buf)));
+       ut_asserteq_str("b4: input: 0 [ ]", buf);
 
        /* Check the 'a' bank also */
        ut_assertok(gpio_lookup_name("a15", &dev, &offset, &gpio));
@@ -96,6 +98,18 @@ static int dm_test_gpio(struct dm_test_state *dms)
        ut_asserteq_str("a", name);
        ut_asserteq(20, offset_count);
 
+       return 0;
+}
+DM_TEST(dm_test_gpio, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
+/* Test that sandbox anonymous GPIOs work correctly */
+static int dm_test_gpio_anon(struct dm_test_state *dms)
+{
+       unsigned int offset, gpio;
+       struct udevice *dev;
+       const char *name;
+       int offset_count;
+
        /* And the anonymous bank */
        ut_assertok(gpio_lookup_name("14", &dev, &offset, &gpio));
        ut_asserteq_str(dev->name, "gpio_sandbox");
@@ -108,4 +122,57 @@ static int dm_test_gpio(struct dm_test_state *dms)
 
        return 0;
 }
-DM_TEST(dm_test_gpio, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+DM_TEST(dm_test_gpio_anon, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
+/* Test that gpio_requestf() works as expected */
+static int dm_test_gpio_requestf(struct dm_test_state *dms)
+{
+       unsigned int offset, gpio;
+       struct udevice *dev;
+       char buf[80];
+
+       ut_assertok(gpio_lookup_name("b5", &dev, &offset, &gpio));
+       ut_assertok(gpio_requestf(gpio, "testing %d %s", 1, "hi"));
+       sandbox_gpio_set_direction(dev, offset, 1);
+       sandbox_gpio_set_value(dev, offset, 1);
+       ut_assertok(gpio_get_status(dev, offset, buf, sizeof(buf)));
+       ut_asserteq_str("b5: output: 1 [x] testing 1 hi", buf);
+
+       return 0;
+}
+DM_TEST(dm_test_gpio_requestf, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
+/* Test that gpio_request() copies its string */
+static int dm_test_gpio_copy(struct dm_test_state *dms)
+{
+       unsigned int offset, gpio;
+       struct udevice *dev;
+       char buf[80], name[10];
+
+       ut_assertok(gpio_lookup_name("b6", &dev, &offset, &gpio));
+       strcpy(name, "odd_name");
+       ut_assertok(gpio_request(gpio, name));
+       sandbox_gpio_set_direction(dev, offset, 1);
+       sandbox_gpio_set_value(dev, offset, 1);
+       ut_assertok(gpio_get_status(dev, offset, buf, sizeof(buf)));
+       ut_asserteq_str("b6: output: 1 [x] odd_name", buf);
+       strcpy(name, "nothing");
+       ut_assertok(gpio_get_status(dev, offset, buf, sizeof(buf)));
+       ut_asserteq_str("b6: output: 1 [x] odd_name", buf);
+
+       return 0;
+}
+DM_TEST(dm_test_gpio_copy, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
+/* Test that we don't leak memory with GPIOs */
+static int dm_test_gpio_leak(struct dm_test_state *dms)
+{
+       ut_assertok(dm_test_gpio(dms));
+       ut_assertok(dm_test_gpio_anon(dms));
+       ut_assertok(dm_test_gpio_requestf(dms));
+       ut_assertok(dm_leak_check_end(dms));
+
+       return 0;
+}
+
+DM_TEST(dm_test_gpio_leak, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
diff --git a/test/dm/sf.c b/test/dm/sf.c
new file mode 100644 (file)
index 0000000..57dd134
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2013 Google, Inc
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <fdtdec.h>
+#include <spi.h>
+#include <spi_flash.h>
+#include <asm/state.h>
+#include <dm/ut.h>
+#include <dm/test.h>
+#include <dm/util.h>
+
+/* Test that sandbox SPI flash works correctly */
+static int dm_test_spi_flash(struct dm_test_state *dms)
+{
+       /*
+        * Create an empty test file and run the SPI flash tests. This is a
+        * long way from being a unit test, but it does test SPI device and
+        * emulator binding, probing, the SPI flash emulator including
+        * device tree decoding, plus the file-based backing store of SPI.
+        *
+        * More targeted tests could be created to perform the above steps
+        * one at a time. This might not increase test coverage much, but
+        * it would make bugs easier to find. It's not clear whether the
+        * benefit is worth the extra complexity.
+        */
+       ut_asserteq(0, run_command_list(
+               "sb save hostfs - spi.bin 0 200000;"
+               "sf probe;"
+               "sf test 0 10000", -1,  0));
+       /*
+        * Since we are about to destroy all devices, we must tell sandbox
+        * to forget the emulation device
+        */
+       sandbox_sf_unbind_emul(state_get_current(), 0, 0);
+
+       return 0;
+}
+DM_TEST(dm_test_spi_flash, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
diff --git a/test/dm/spi.c b/test/dm/spi.c
new file mode 100644 (file)
index 0000000..61b5b25
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2013 Google, Inc
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <fdtdec.h>
+#include <spi.h>
+#include <spi_flash.h>
+#include <dm/device-internal.h>
+#include <dm/test.h>
+#include <dm/uclass-internal.h>
+#include <dm/ut.h>
+#include <dm/util.h>
+#include <asm/state.h>
+
+/* Test that we can find buses and chip-selects */
+static int dm_test_spi_find(struct dm_test_state *dms)
+{
+       struct sandbox_state *state = state_get_current();
+       struct spi_slave *slave;
+       struct udevice *bus, *dev;
+       const int busnum = 0, cs = 0, mode = 0, speed = 1000000, cs_b = 1;
+       struct spi_cs_info info;
+       int of_offset;
+
+       ut_asserteq(-ENODEV, uclass_find_device_by_seq(UCLASS_SPI, busnum,
+                                                      false, &bus));
+
+       /*
+        * spi_post_bind() will bind devices to chip selects. Check this then
+        * remove the emulation and the slave device.
+        */
+       ut_asserteq(0, uclass_get_device_by_seq(UCLASS_SPI, busnum, &bus));
+       ut_assertok(spi_cs_info(bus, cs, &info));
+       of_offset = info.dev->of_offset;
+       sandbox_sf_unbind_emul(state_get_current(), busnum, cs);
+       device_remove(info.dev);
+       device_unbind(info.dev);
+
+       /*
+        * Even though the device is gone, the sandbox SPI drivers always
+        * reports that CS 0 is present
+        */
+       ut_assertok(spi_cs_info(bus, cs, &info));
+       ut_asserteq_ptr(info.dev, NULL);
+
+       /* This finds nothing because we removed the device */
+       ut_asserteq(-ENODEV, spi_find_bus_and_cs(busnum, cs, &bus, &dev));
+       ut_asserteq(-ENODEV, spi_get_bus_and_cs(busnum, cs, speed, mode,
+                                               NULL, 0, &bus, &slave));
+
+       /*
+        * This forces the device to be re-added, but there is no emulation
+        * connected so the probe will fail. We require that bus is left
+        * alone on failure, and that the spi_get_bus_and_cs() does not add
+        * a 'partially-inited' device.
+        */
+       ut_asserteq(-ENODEV, spi_find_bus_and_cs(busnum, cs, &bus, &dev));
+       ut_asserteq(-ENOENT, spi_get_bus_and_cs(busnum, cs, speed, mode,
+                                               "spi_flash_std", "name", &bus,
+                                               &slave));
+       ut_assertok(spi_cs_info(bus, cs, &info));
+       ut_asserteq_ptr(info.dev, NULL);
+
+       /* Add the emulation and try again */
+       ut_assertok(sandbox_sf_bind_emul(state, busnum, cs, bus, of_offset,
+                                        "name"));
+       ut_assertok(spi_find_bus_and_cs(busnum, cs, &bus, &dev));
+       ut_assertok(spi_get_bus_and_cs(busnum, cs, speed, mode,
+                                      "spi_flash_std", "name", &bus, &slave));
+
+       ut_assertok(spi_cs_info(bus, cs, &info));
+       ut_asserteq_ptr(info.dev, slave->dev);
+
+       /* We should be able to add something to another chip select */
+       ut_assertok(sandbox_sf_bind_emul(state, busnum, cs_b, bus, of_offset,
+                                        "name"));
+       ut_assertok(spi_get_bus_and_cs(busnum, cs_b, speed, mode,
+                                      "spi_flash_std", "name", &bus, &slave));
+       ut_assertok(spi_cs_info(bus, cs_b, &info));
+       ut_asserteq_ptr(info.dev, slave->dev);
+
+       /*
+        * Since we are about to destroy all devices, we must tell sandbox
+        * to forget the emulation device
+        */
+       sandbox_sf_unbind_emul(state_get_current(), busnum, cs);
+       sandbox_sf_unbind_emul(state_get_current(), busnum, cs_b);
+
+       return 0;
+}
+DM_TEST(dm_test_spi_find, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
+/* Test that sandbox SPI works correctly */
+static int dm_test_spi_xfer(struct dm_test_state *dms)
+{
+       struct spi_slave *slave;
+       struct udevice *bus;
+       const int busnum = 0, cs = 0, mode = 0;
+       const char dout[5] = {0x9f};
+       unsigned char din[5];
+
+       ut_assertok(spi_get_bus_and_cs(busnum, cs, 1000000, mode, NULL, 0,
+                                      &bus, &slave));
+       ut_assertok(spi_claim_bus(slave));
+       ut_assertok(spi_xfer(slave, 40, dout, din,
+                            SPI_XFER_BEGIN | SPI_XFER_END));
+       ut_asserteq(0xff, din[0]);
+       ut_asserteq(0x20, din[1]);
+       ut_asserteq(0x20, din[2]);
+       ut_asserteq(0x15, din[3]);
+       spi_release_bus(slave);
+
+       /*
+        * Since we are about to destroy all devices, we must tell sandbox
+        * to forget the emulation device
+        */
+#ifdef CONFIG_DM_SPI_FLASH
+       sandbox_sf_unbind_emul(state_get_current(), busnum, cs);
+#endif
+
+       return 0;
+}
+DM_TEST(dm_test_spi_xfer, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
index ef5aca5ac3c43800fe62b9242027cb341f4e9af7..bb99677ece9462604e4362fc514030291e30862d 100755 (executable)
@@ -4,4 +4,6 @@ NUM_CPUS=$(cat /proc/cpuinfo |grep -c processor)
 dtc -I dts -O dtb test/dm/test.dts -o test/dm/test.dtb
 make O=sandbox sandbox_config
 make O=sandbox -s -j${NUM_CPUS}
+dd if=/dev/zero of=spi.bin bs=1M count=2
 ./sandbox/u-boot -d test/dm/test.dtb -c "dm test"
+rm spi.bin
index 94ce72abfd5ced11313480ba736c88d65e01d862..90ca81092f721052df78504e7ffeb0a3a76817ef 100644 (file)
@@ -7,6 +7,7 @@
 #include <common.h>
 #include <dm.h>
 #include <errno.h>
+#include <malloc.h>
 #include <dm/test.h>
 #include <dm/root.h>
 #include <dm/uclass-internal.h>
@@ -88,6 +89,7 @@ int dm_test_main(void)
                printf("Test: %s\n", test->name);
                ut_assertok(dm_test_init(dms));
 
+               dms->start = mallinfo();
                if (test->flags & DM_TESTF_SCAN_PDATA)
                        ut_assertok(dm_scan_platdata(false));
                if (test->flags & DM_TESTF_PROBE_TEST)
index 84895951550ffec7b1df26c4f2e782398f589ce5..1fba7925642a928fd60f10fd4ed7ee1bcc192890 100644 (file)
@@ -81,7 +81,7 @@
                compatible = "google,another-fdt-test";
        };
 
-       base-gpios {
+       gpio_a: base-gpios {
                compatible = "sandbox,gpio";
                gpio-bank-name = "a";
                num-gpios = <20>;
                gpio-bank-name = "b";
                num-gpios = <10>;
        };
+
+       spi@0 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               reg = <0>;
+               compatible = "sandbox,spi";
+               cs-gpios = <0>, <&gpio_a 0>;
+               spi.bin@0 {
+                       reg = <0>;
+                       compatible = "spansion,m25p16", "spi-flash";
+                       spi-max-frequency = <40000000>;
+                       sandbox,filename = "spi.bin";
+               };
+       };
+
 };
index 2b05b202a07276a3581b956e33d00a73a5d6278e..3b95964fd15cb1494c64ea6de43058b87ebaa584 100644 (file)
@@ -140,6 +140,7 @@ ubsha1-objs := os_support.o ubsha1.o lib/sha1.o
 HOSTCFLAGS_ubsha1.o := -pedantic
 
 hostprogs-$(CONFIG_KIRKWOOD) += kwboot
+hostprogs-$(CONFIG_ARMADA_XP) += kwboot
 hostprogs-y += proftool
 hostprogs-$(CONFIG_STATIC_RELA) += relocate-rela
 
index 109d61686ec69fc958bd3b66995c83c412164eaa..1120e9b3729024fc851ddba5a3410dcc92cf29d1 100644 (file)
 /*
- * (C) Copyright 2008
- * Marvell Semiconductor <www.marvell.com>
- * Written-by: Prafulla Wadaskar <prafulla@marvell.com>
+ * Image manipulator for Marvell SoCs
+ *  supports Kirkwood, Dove, Armada 370, and Armada XP
+ *
+ * (C) Copyright 2013 Thomas Petazzoni
+ * <thomas.petazzoni@free-electrons.com>
  *
  * SPDX-License-Identifier:    GPL-2.0+
+ *
+ * Not implemented: support for the register headers and secure
+ * headers in v1 images
  */
 
 #include "imagetool.h"
 #include <image.h>
+#include <stdint.h>
 #include "kwbimage.h"
 
-/*
- * Supported commands for configuration file
- */
-static table_entry_t kwbimage_cmds[] = {
-       {CMD_BOOT_FROM,         "BOOT_FROM",            "boot command", },
-       {CMD_NAND_ECC_MODE,     "NAND_ECC_MODE",        "NAND mode",    },
-       {CMD_NAND_PAGE_SIZE,    "NAND_PAGE_SIZE",       "NAND size",    },
-       {CMD_SATA_PIO_MODE,     "SATA_PIO_MODE",        "SATA mode",    },
-       {CMD_DDR_INIT_DELAY,    "DDR_INIT_DELAY",       "DDR init dly", },
-       {CMD_DATA,              "DATA",                 "Reg Write Data", },
-       {CMD_INVALID,           "",                     "",     },
+#define ALIGN_SUP(x, a) (((x) + (a - 1)) & ~(a - 1))
+
+/* Structure of the main header, version 0 (Kirkwood, Dove) */
+struct main_hdr_v0 {
+       uint8_t  blockid;               /*0     */
+       uint8_t  nandeccmode;           /*1     */
+       uint16_t nandpagesize;          /*2-3   */
+       uint32_t blocksize;             /*4-7   */
+       uint32_t rsvd1;                 /*8-11  */
+       uint32_t srcaddr;               /*12-15 */
+       uint32_t destaddr;              /*16-19 */
+       uint32_t execaddr;              /*20-23 */
+       uint8_t  satapiomode;           /*24    */
+       uint8_t  rsvd3;                 /*25    */
+       uint16_t ddrinitdelay;          /*26-27 */
+       uint16_t rsvd2;                 /*28-29 */
+       uint8_t  ext;                   /*30    */
+       uint8_t  checksum;              /*31    */
+};
+
+struct ext_hdr_v0_reg {
+       uint32_t raddr;
+       uint32_t rdata;
+};
+
+#define EXT_HDR_V0_REG_COUNT ((0x1dc - 0x20) / sizeof(struct ext_hdr_v0_reg))
+
+struct ext_hdr_v0 {
+       uint32_t              offset;
+       uint8_t               reserved[0x20 - sizeof(uint32_t)];
+       struct ext_hdr_v0_reg rcfg[EXT_HDR_V0_REG_COUNT];
+       uint8_t               reserved2[7];
+       uint8_t               checksum;
+};
+
+/* Structure of the main header, version 1 (Armada 370, Armada XP) */
+struct main_hdr_v1 {
+       uint8_t  blockid;               /* 0 */
+       uint8_t  reserved1;             /* 1 */
+       uint16_t reserved2;             /* 2-3 */
+       uint32_t blocksize;             /* 4-7 */
+       uint8_t  version;               /* 8 */
+       uint8_t  headersz_msb;          /* 9 */
+       uint16_t headersz_lsb;          /* A-B */
+       uint32_t srcaddr;               /* C-F */
+       uint32_t destaddr;              /* 10-13 */
+       uint32_t execaddr;              /* 14-17 */
+       uint8_t  reserved3;             /* 18 */
+       uint8_t  nandblocksize;         /* 19 */
+       uint8_t  nandbadblklocation;    /* 1A */
+       uint8_t  reserved4;             /* 1B */
+       uint16_t reserved5;             /* 1C-1D */
+       uint8_t  ext;                   /* 1E */
+       uint8_t  checksum;              /* 1F */
 };
 
 /*
- * Supported Boot options for configuration file
+ * Header for the optional headers, version 1 (Armada 370, Armada XP)
  */
-static table_entry_t kwbimage_bootops[] = {
-       {IBR_HDR_SPI_ID,        "spi",          "SPI Flash",    },
-       {IBR_HDR_NAND_ID,       "nand",         "NAND Flash",   },
-       {IBR_HDR_SATA_ID,       "sata",         "Sata port",    },
-       {IBR_HDR_PEX_ID,        "pex",          "PCIe port",    },
-       {IBR_HDR_UART_ID,       "uart",         "Serial port",  },
-       {-1,                    "",             "Invalid",      },
+struct opt_hdr_v1 {
+       uint8_t  headertype;
+       uint8_t  headersz_msb;
+       uint16_t headersz_lsb;
+       char     data[0];
 };
 
 /*
- * Supported NAND ecc options configuration file
+ * Various values for the opt_hdr_v1->headertype field, describing the
+ * different types of optional headers. The "secure" header contains
+ * informations related to secure boot (encryption keys, etc.). The
+ * "binary" header contains ARM binary code to be executed prior to
+ * executing the main payload (usually the bootloader). This is
+ * typically used to execute DDR3 training code. The "register" header
+ * allows to describe a set of (address, value) tuples that are
+ * generally used to configure the DRAM controller.
  */
-static table_entry_t kwbimage_eccmodes[] = {
-       {IBR_HDR_ECC_DEFAULT,           "default",      "Default mode", },
-       {IBR_HDR_ECC_FORCED_HAMMING,    "hamming",      "Hamming mode", },
-       {IBR_HDR_ECC_FORCED_RS,         "rs",           "RS mode",      },
-       {IBR_HDR_ECC_DISABLED,          "disabled",     "ECC Disabled", },
-       {-1,                            "",             "",     },
+#define OPT_HDR_V1_SECURE_TYPE   0x1
+#define OPT_HDR_V1_BINARY_TYPE   0x2
+#define OPT_HDR_V1_REGISTER_TYPE 0x3
+
+#define KWBHEADER_V1_SIZE(hdr) \
+       (((hdr)->headersz_msb << 16) | (hdr)->headersz_lsb)
+
+static struct image_cfg_element *image_cfg;
+static int cfgn;
+
+struct boot_mode {
+       unsigned int id;
+       const char *name;
+};
+
+struct boot_mode boot_modes[] = {
+       { 0x4D, "i2c"  },
+       { 0x5A, "spi"  },
+       { 0x8B, "nand" },
+       { 0x78, "sata" },
+       { 0x9C, "pex"  },
+       { 0x69, "uart" },
+       {},
 };
 
-static struct kwb_header kwbimage_header;
-static int datacmd_cnt = 0;
-static char * fname = "Unknown";
-static int lineno = -1;
+struct nand_ecc_mode {
+       unsigned int id;
+       const char *name;
+};
+
+struct nand_ecc_mode nand_ecc_modes[] = {
+       { 0x00, "default" },
+       { 0x01, "hamming" },
+       { 0x02, "rs" },
+       { 0x03, "disabled" },
+       {},
+};
+
+/* Used to identify an undefined execution or destination address */
+#define ADDR_INVALID ((uint32_t)-1)
+
+#define BINARY_MAX_ARGS 8
+
+/* In-memory representation of a line of the configuration file */
+struct image_cfg_element {
+       enum {
+               IMAGE_CFG_VERSION = 0x1,
+               IMAGE_CFG_BOOT_FROM,
+               IMAGE_CFG_DEST_ADDR,
+               IMAGE_CFG_EXEC_ADDR,
+               IMAGE_CFG_NAND_BLKSZ,
+               IMAGE_CFG_NAND_BADBLK_LOCATION,
+               IMAGE_CFG_NAND_ECC_MODE,
+               IMAGE_CFG_NAND_PAGESZ,
+               IMAGE_CFG_BINARY,
+               IMAGE_CFG_PAYLOAD,
+               IMAGE_CFG_DATA,
+       } type;
+       union {
+               unsigned int version;
+               unsigned int bootfrom;
+               struct {
+                       const char *file;
+                       unsigned int args[BINARY_MAX_ARGS];
+                       unsigned int nargs;
+               } binary;
+               const char *payload;
+               unsigned int dstaddr;
+               unsigned int execaddr;
+               unsigned int nandblksz;
+               unsigned int nandbadblklocation;
+               unsigned int nandeccmode;
+               unsigned int nandpagesz;
+               struct ext_hdr_v0_reg regdata;
+       };
+};
+
+#define IMAGE_CFG_ELEMENT_MAX 256
 
 /*
- * Report Error if xflag is set in addition to default
+ * Byte 8 of the image header contains the version number. In the v0
+ * header, byte 8 was reserved, and always set to 0. In the v1 header,
+ * byte 8 has been changed to a proper field, set to 1.
  */
-static int kwbimage_check_params(struct image_tool_params *params)
+static unsigned int image_version(void *header)
 {
-       if (!strlen (params->imagename)) {
-               printf ("Error:%s - Configuration file not specified, "
-                       "it is needed for kwbimage generation\n",
-                       params->cmdname);
-               return CFG_INVALID;
-       }
-       return  ((params->dflag && (params->fflag || params->lflag)) ||
-               (params->fflag && (params->dflag || params->lflag)) ||
-               (params->lflag && (params->dflag || params->fflag)) ||
-               (params->xflag) || !(strlen (params->imagename)));
+       unsigned char *ptr = header;
+       return ptr[8];
+}
+
+/*
+ * Utility functions to manipulate boot mode and ecc modes (convert
+ * them back and forth between description strings and the
+ * corresponding numerical identifiers).
+ */
+
+static const char *image_boot_mode_name(unsigned int id)
+{
+       int i;
+       for (i = 0; boot_modes[i].name; i++)
+               if (boot_modes[i].id == id)
+                       return boot_modes[i].name;
+       return NULL;
+}
+
+int image_boot_mode_id(const char *boot_mode_name)
+{
+       int i;
+       for (i = 0; boot_modes[i].name; i++)
+               if (!strcmp(boot_modes[i].name, boot_mode_name))
+                       return boot_modes[i].id;
+
+       return -1;
+}
+
+int image_nand_ecc_mode_id(const char *nand_ecc_mode_name)
+{
+       int i;
+       for (i = 0; nand_ecc_modes[i].name; i++)
+               if (!strcmp(nand_ecc_modes[i].name, nand_ecc_mode_name))
+                       return nand_ecc_modes[i].id;
+       return -1;
 }
 
-static uint32_t check_get_hexval (char *token)
+static struct image_cfg_element *
+image_find_option(unsigned int optiontype)
 {
-       uint32_t hexval;
+       int i;
 
-       if (!sscanf (token, "%x", &hexval)) {
-               printf ("Error:%s[%d] - Invalid hex data(%s)\n", fname,
-                       lineno, token);
-               exit (EXIT_FAILURE);
+       for (i = 0; i < cfgn; i++) {
+               if (image_cfg[i].type == optiontype)
+                       return &image_cfg[i];
        }
-       return hexval;
+
+       return NULL;
+}
+
+static unsigned int
+image_count_options(unsigned int optiontype)
+{
+       int i;
+       unsigned int count = 0;
+
+       for (i = 0; i < cfgn; i++)
+               if (image_cfg[i].type == optiontype)
+                       count++;
+
+       return count;
 }
 
 /*
- * Generates 8 bit checksum
+ * Compute a 8-bit checksum of a memory area. This algorithm follows
+ * the requirements of the Marvell SoC BootROM specifications.
  */
-static uint8_t kwbimage_checksum8 (void *start, uint32_t len, uint8_t csum)
+static uint8_t image_checksum8(void *start, uint32_t len)
 {
-       register uint8_t sum = csum;
-       volatile uint8_t *p = (volatile uint8_t *)start;
+       uint8_t csum = 0;
+       uint8_t *p = start;
 
        /* check len and return zero checksum if invalid */
        if (!len)
                return 0;
 
        do {
-               sum += *p;
+               csum += *p;
                p++;
        } while (--len);
-       return (sum);
+
+       return csum;
 }
 
-/*
- * Generates 32 bit checksum
- */
-static uint32_t kwbimage_checksum32 (uint32_t *start, uint32_t len, uint32_t csum)
+static uint32_t image_checksum32(void *start, uint32_t len)
 {
-       register uint32_t sum = csum;
-       volatile uint32_t *p = start;
+       uint32_t csum = 0;
+       uint32_t *p = start;
 
        /* check len and return zero checksum if invalid */
        if (!len)
                return 0;
 
        if (len % sizeof(uint32_t)) {
-               printf ("Error:%s[%d] - length is not in multiple of %zu\n",
-                       __FUNCTION__, len, sizeof(uint32_t));
+               fprintf(stderr, "Length %d is not in multiple of %zu\n",
+                       len, sizeof(uint32_t));
                return 0;
        }
 
        do {
-               sum += *p;
+               csum += *p;
                p++;
                len -= sizeof(uint32_t);
        } while (len > 0);
-       return (sum);
+
+       return csum;
 }
 
-static void kwbimage_check_cfgdata (char *token, enum kwbimage_cmd cmdsw,
-                                       struct kwb_header *kwbhdr)
+static void *image_create_v0(size_t *imagesz, struct image_tool_params *params,
+                            int payloadsz)
 {
-       bhr_t *mhdr = &kwbhdr->kwb_hdr;
-       extbhr_t *exthdr = &kwbhdr->kwb_exthdr;
-       int i;
+       struct image_cfg_element *e;
+       size_t headersz;
+       struct main_hdr_v0 *main_hdr;
+       struct ext_hdr_v0 *ext_hdr;
+       void *image;
+       int has_ext = 0;
+
+       /*
+        * Calculate the size of the header and the size of the
+        * payload
+        */
+       headersz  = sizeof(struct main_hdr_v0);
+
+       if (image_count_options(IMAGE_CFG_DATA) > 0) {
+               has_ext = 1;
+               headersz += sizeof(struct ext_hdr_v0);
+       }
+
+       if (image_count_options(IMAGE_CFG_PAYLOAD) > 1) {
+               fprintf(stderr, "More than one payload, not possible\n");
+               return NULL;
+       }
 
-       switch (cmdsw) {
-       case CMD_BOOT_FROM:
-               i = get_table_entry_id (kwbimage_bootops,
-                               "Kwbimage boot option", token);
-
-               if (i < 0)
-                       goto INVL_DATA;
-
-               mhdr->blockid = i;
-               printf ("Preparing kirkwood boot image to boot "
-                       "from %s\n", token);
-               break;
-       case CMD_NAND_ECC_MODE:
-               i = get_table_entry_id (kwbimage_eccmodes,
-                       "NAND ecc mode", token);
-
-               if (i < 0)
-                       goto INVL_DATA;
-
-               mhdr->nandeccmode = i;
-               printf ("Nand ECC mode = %s\n", token);
-               break;
-       case CMD_NAND_PAGE_SIZE:
-               mhdr->nandpagesize =
-                       (uint16_t) check_get_hexval (token);
-               printf ("Nand page size = 0x%x\n", mhdr->nandpagesize);
-               break;
-       case CMD_SATA_PIO_MODE:
-               mhdr->satapiomode =
-                       (uint8_t) check_get_hexval (token);
-               printf ("Sata PIO mode = 0x%x\n",
-                               mhdr->satapiomode);
-               break;
-       case CMD_DDR_INIT_DELAY:
-               mhdr->ddrinitdelay =
-                       (uint16_t) check_get_hexval (token);
-               printf ("DDR init delay = %d msec\n", mhdr->ddrinitdelay);
-               break;
-       case CMD_DATA:
-               exthdr->rcfg[datacmd_cnt].raddr =
-                       check_get_hexval (token);
-
-               break;
-       case CMD_INVALID:
-               goto INVL_DATA;
-       default:
-               goto INVL_DATA;
+       image = malloc(headersz);
+       if (!image) {
+               fprintf(stderr, "Cannot allocate memory for image\n");
+               return NULL;
        }
-       return;
 
-INVL_DATA:
-       printf ("Error:%s[%d] - Invalid data\n", fname, lineno);
-       exit (EXIT_FAILURE);
+       memset(image, 0, headersz);
+
+       main_hdr = image;
+
+       /* Fill in the main header */
+       main_hdr->blocksize = payloadsz + sizeof(uint32_t);
+       main_hdr->srcaddr   = headersz;
+       main_hdr->ext       = has_ext;
+       main_hdr->destaddr  = params->addr;
+       main_hdr->execaddr  = params->ep;
+
+       e = image_find_option(IMAGE_CFG_BOOT_FROM);
+       if (e)
+               main_hdr->blockid = e->bootfrom;
+       e = image_find_option(IMAGE_CFG_NAND_ECC_MODE);
+       if (e)
+               main_hdr->nandeccmode = e->nandeccmode;
+       e = image_find_option(IMAGE_CFG_NAND_PAGESZ);
+       if (e)
+               main_hdr->nandpagesize = e->nandpagesz;
+       main_hdr->checksum = image_checksum8(image,
+                                            sizeof(struct main_hdr_v0));
+
+       /* Generate the ext header */
+       if (has_ext) {
+               int cfgi, datai;
+
+               ext_hdr = image + sizeof(struct main_hdr_v0);
+               ext_hdr->offset = 0x40;
+
+               for (cfgi = 0, datai = 0; cfgi < cfgn; cfgi++) {
+                       e = &image_cfg[cfgi];
+                       if (e->type != IMAGE_CFG_DATA)
+                               continue;
+
+                       ext_hdr->rcfg[datai].raddr = e->regdata.raddr;
+                       ext_hdr->rcfg[datai].rdata = e->regdata.rdata;
+                       datai++;
+               }
+
+               ext_hdr->checksum = image_checksum8(ext_hdr,
+                                                   sizeof(struct ext_hdr_v0));
+       }
+
+       *imagesz = headersz;
+       return image;
 }
 
-/*
- * this function sets the kwbimage header by-
- *     1. Abstracting input command line arguments data
- *     2. parses the kwbimage configuration file and update extebded header data
- *     3. calculates header, extended header and image checksums
- */
-static void kwdimage_set_ext_header (struct kwb_header *kwbhdr, char* name) {
-       bhr_t *mhdr = &kwbhdr->kwb_hdr;
-       extbhr_t *exthdr = &kwbhdr->kwb_exthdr;
-       FILE *fd = NULL;
-       int j;
-       char *line = NULL;
-       char * token, *saveptr1, *saveptr2;
-       size_t len = 0;
-       enum kwbimage_cmd cmd;
-
-       fname = name;
-       /* set dram register offset */
-       exthdr->dramregsoffs = (intptr_t)&exthdr->rcfg - (intptr_t)mhdr;
-
-       if ((fd = fopen (name, "r")) == 0) {
-               printf ("Error:%s - Can't open\n", fname);
-               exit (EXIT_FAILURE);
+static size_t image_headersz_v1(struct image_tool_params *params,
+                               int *hasext)
+{
+       struct image_cfg_element *binarye;
+       size_t headersz;
+       int ret;
+
+       /*
+        * Calculate the size of the header and the size of the
+        * payload
+        */
+       headersz = sizeof(struct main_hdr_v1);
+
+       if (image_count_options(IMAGE_CFG_BINARY) > 1) {
+               fprintf(stderr, "More than one binary blob, not supported\n");
+               return 0;
        }
 
-       /* Simple kwimage.cfg file parser */
-       lineno=0;
-       while ((getline (&line, &len, fd)) > 0) {
-               lineno++;
-               token = strtok_r (line, "\r\n", &saveptr1);
-               /* drop all lines with zero tokens (= empty lines) */
-               if (token == NULL)
-                       continue;
+       if (image_count_options(IMAGE_CFG_PAYLOAD) > 1) {
+               fprintf(stderr, "More than one payload, not possible\n");
+               return 0;
+       }
 
-               for (j = 0, cmd = CMD_INVALID, line = token; ; line = NULL) {
-                       token = strtok_r (line, " \t", &saveptr2);
-                       if (token == NULL)
-                       break;
-                       /* Drop all text starting with '#' as comments */
-                       if (token[0] == '#')
-                               break;
+       binarye = image_find_option(IMAGE_CFG_BINARY);
+       if (binarye) {
+               struct stat s;
+
+               ret = stat(binarye->binary.file, &s);
+               if (ret < 0) {
+                       char *cwd = get_current_dir_name();
+                       fprintf(stderr,
+                               "Didn't find the file '%s' in '%s' which is mandatory to generate the image\n"
+                               "This file generally contains the DDR3 training code, and should be extracted from an existing bootable\n"
+                               "image for your board. See 'kwbimage -x' to extract it from an existing image.\n",
+                               binarye->binary.file, cwd);
+                       free(cwd);
+                       return 0;
+               }
 
-                       /* Process rest as valid config command line */
-                       switch (j) {
-                       case CFG_COMMAND:
-                               cmd = get_table_entry_id (kwbimage_cmds,
-                                               "Kwbimage command", token);
+               headersz += s.st_size +
+                       binarye->binary.nargs * sizeof(unsigned int);
+               if (hasext)
+                       *hasext = 1;
+       }
 
-                               if (cmd == CMD_INVALID)
-                                       goto INVL_CMD;
-                               break;
+       /*
+        * The payload should be aligned on some reasonable
+        * boundary
+        */
+       return ALIGN_SUP(headersz, 4096);
+}
 
-                       case CFG_DATA0:
-                               kwbimage_check_cfgdata (token, cmd, kwbhdr);
-                               break;
+static void *image_create_v1(size_t *imagesz, struct image_tool_params *params,
+                            int payloadsz)
+{
+       struct image_cfg_element *e, *binarye;
+       struct main_hdr_v1 *main_hdr;
+       size_t headersz;
+       void *image, *cur;
+       int hasext = 0;
+       int ret;
+
+       /*
+        * Calculate the size of the header and the size of the
+        * payload
+        */
+       headersz = image_headersz_v1(params, &hasext);
+       if (headersz == 0)
+               return NULL;
+
+       image = malloc(headersz);
+       if (!image) {
+               fprintf(stderr, "Cannot allocate memory for image\n");
+               return NULL;
+       }
 
-                       case CFG_DATA1:
-                               if (cmd != CMD_DATA)
-                                       goto INVL_CMD;
-
-                               exthdr->rcfg[datacmd_cnt].rdata =
-                                               check_get_hexval (token);
-
-                               if (datacmd_cnt > KWBIMAGE_MAX_CONFIG ) {
-                                       printf ("Error:%s[%d] - Found more "
-                                               "than max(%zd) allowed "
-                                               "data configurations\n",
-                                               fname, lineno,
-                                               KWBIMAGE_MAX_CONFIG);
-                               exit (EXIT_FAILURE);
-                               } else
-                                       datacmd_cnt++;
-                               break;
+       memset(image, 0, headersz);
+
+       cur = main_hdr = image;
+       cur += sizeof(struct main_hdr_v1);
+
+       /* Fill the main header */
+       main_hdr->blocksize    = payloadsz - headersz + sizeof(uint32_t);
+       main_hdr->headersz_lsb = headersz & 0xFFFF;
+       main_hdr->headersz_msb = (headersz & 0xFFFF0000) >> 16;
+       main_hdr->destaddr     = params->addr;
+       main_hdr->execaddr     = params->ep;
+       main_hdr->srcaddr      = headersz;
+       main_hdr->ext          = hasext;
+       main_hdr->version      = 1;
+       e = image_find_option(IMAGE_CFG_BOOT_FROM);
+       if (e)
+               main_hdr->blockid = e->bootfrom;
+       e = image_find_option(IMAGE_CFG_NAND_BLKSZ);
+       if (e)
+               main_hdr->nandblocksize = e->nandblksz / (64 * 1024);
+       e = image_find_option(IMAGE_CFG_NAND_BADBLK_LOCATION);
+       if (e)
+               main_hdr->nandbadblklocation = e->nandbadblklocation;
+
+       binarye = image_find_option(IMAGE_CFG_BINARY);
+       if (binarye) {
+               struct opt_hdr_v1 *hdr = cur;
+               unsigned int *args;
+               size_t binhdrsz;
+               struct stat s;
+               int argi;
+               FILE *bin;
+
+               hdr->headertype = OPT_HDR_V1_BINARY_TYPE;
+
+               bin = fopen(binarye->binary.file, "r");
+               if (!bin) {
+                       fprintf(stderr, "Cannot open binary file %s\n",
+                               binarye->binary.file);
+                       return NULL;
+               }
+
+               fstat(fileno(bin), &s);
+
+               binhdrsz = sizeof(struct opt_hdr_v1) +
+                       (binarye->binary.nargs + 1) * sizeof(unsigned int) +
+                       s.st_size;
+               hdr->headersz_lsb = binhdrsz & 0xFFFF;
+               hdr->headersz_msb = (binhdrsz & 0xFFFF0000) >> 16;
+
+               cur += sizeof(struct opt_hdr_v1);
+
+               args = cur;
+               *args = binarye->binary.nargs;
+               args++;
+               for (argi = 0; argi < binarye->binary.nargs; argi++)
+                       args[argi] = binarye->binary.args[argi];
+
+               cur += (binarye->binary.nargs + 1) * sizeof(unsigned int);
+
+               ret = fread(cur, s.st_size, 1, bin);
+               if (ret != 1) {
+                       fprintf(stderr,
+                               "Could not read binary image %s\n",
+                               binarye->binary.file);
+                       return NULL;
+               }
+
+               fclose(bin);
 
-                       default:
-                               goto INVL_CMD;
+               cur += s.st_size;
+
+               /*
+                * For now, we don't support more than one binary
+                * header, and no other header types are
+                * supported. So, the binary header is necessarily the
+                * last one
+                */
+               *((unsigned char *)cur) = 0;
+
+               cur += sizeof(uint32_t);
+       }
+
+       /* Calculate and set the header checksum */
+       main_hdr->checksum = image_checksum8(main_hdr, headersz);
+
+       *imagesz = headersz;
+       return image;
+}
+
+static int image_create_config_parse_oneline(char *line,
+                                            struct image_cfg_element *el)
+{
+       char *keyword, *saveptr;
+       char deliminiters[] = " \t";
+
+       keyword = strtok_r(line, deliminiters, &saveptr);
+       if (!strcmp(keyword, "VERSION")) {
+               char *value = strtok_r(NULL, deliminiters, &saveptr);
+               el->type = IMAGE_CFG_VERSION;
+               el->version = atoi(value);
+       } else if (!strcmp(keyword, "BOOT_FROM")) {
+               char *value = strtok_r(NULL, deliminiters, &saveptr);
+               el->type = IMAGE_CFG_BOOT_FROM;
+               el->bootfrom = image_boot_mode_id(value);
+               if (el->bootfrom < 0) {
+                       fprintf(stderr,
+                               "Invalid boot media '%s'\n", value);
+                       return -1;
+               }
+       } else if (!strcmp(keyword, "NAND_BLKSZ")) {
+               char *value = strtok_r(NULL, deliminiters, &saveptr);
+               el->type = IMAGE_CFG_NAND_BLKSZ;
+               el->nandblksz = strtoul(value, NULL, 16);
+       } else if (!strcmp(keyword, "NAND_BADBLK_LOCATION")) {
+               char *value = strtok_r(NULL, deliminiters, &saveptr);
+               el->type = IMAGE_CFG_NAND_BADBLK_LOCATION;
+               el->nandbadblklocation =
+                       strtoul(value, NULL, 16);
+       } else if (!strcmp(keyword, "NAND_ECC_MODE")) {
+               char *value = strtok_r(NULL, deliminiters, &saveptr);
+               el->type = IMAGE_CFG_NAND_ECC_MODE;
+               el->nandeccmode = image_nand_ecc_mode_id(value);
+               if (el->nandeccmode < 0) {
+                       fprintf(stderr,
+                               "Invalid NAND ECC mode '%s'\n", value);
+                       return -1;
+               }
+       } else if (!strcmp(keyword, "NAND_PAGE_SIZE")) {
+               char *value = strtok_r(NULL, deliminiters, &saveptr);
+               el->type = IMAGE_CFG_NAND_PAGESZ;
+               el->nandpagesz = strtoul(value, NULL, 16);
+       } else if (!strcmp(keyword, "BINARY")) {
+               char *value = strtok_r(NULL, deliminiters, &saveptr);
+               int argi = 0;
+
+               el->type = IMAGE_CFG_BINARY;
+               el->binary.file = strdup(value);
+               while (1) {
+                       value = strtok_r(NULL, deliminiters, &saveptr);
+                       if (!value)
+                               break;
+                       el->binary.args[argi] = strtoul(value, NULL, 16);
+                       argi++;
+                       if (argi >= BINARY_MAX_ARGS) {
+                               fprintf(stderr,
+                                       "Too many argument for binary\n");
+                               return -1;
                        }
-                       j++;
                }
+               el->binary.nargs = argi;
+       } else if (!strcmp(keyword, "DATA")) {
+               char *value1 = strtok_r(NULL, deliminiters, &saveptr);
+               char *value2 = strtok_r(NULL, deliminiters, &saveptr);
+
+               if (!value1 || !value2) {
+                       fprintf(stderr,
+                               "Invalid number of arguments for DATA\n");
+                       return -1;
+               }
+
+               el->type = IMAGE_CFG_DATA;
+               el->regdata.raddr = strtoul(value1, NULL, 16);
+               el->regdata.rdata = strtoul(value2, NULL, 16);
+       } else {
+               fprintf(stderr, "Ignoring unknown line '%s'\n", line);
        }
-       if (line)
-               free (line);
 
-       fclose (fd);
-       return;
+       return 0;
+}
 
 /*
- * Invalid Command error reporring
- *
- * command CMD_DATA needs three strings on a line
- * whereas other commands need only two.
- *
- * if more than two/three (as per command type) are observed,
- * then error will be reported
+ * Parse the configuration file 'fcfg' into the array of configuration
+ * elements 'image_cfg', and return the number of configuration
+ * elements in 'cfgn'.
  */
-INVL_CMD:
-       printf ("Error:%s[%d] - Invalid command\n", fname, lineno);
-       exit (EXIT_FAILURE);
+static int image_create_config_parse(FILE *fcfg)
+{
+       int ret;
+       int cfgi = 0;
+
+       /* Parse the configuration file */
+       while (!feof(fcfg)) {
+               char *line;
+               char buf[256];
+
+               /* Read the current line */
+               memset(buf, 0, sizeof(buf));
+               line = fgets(buf, sizeof(buf), fcfg);
+               if (!line)
+                       break;
+
+               /* Ignore useless lines */
+               if (line[0] == '\n' || line[0] == '#')
+                       continue;
+
+               /* Strip final newline */
+               if (line[strlen(line) - 1] == '\n')
+                       line[strlen(line) - 1] = 0;
+
+               /* Parse the current line */
+               ret = image_create_config_parse_oneline(line,
+                                                       &image_cfg[cfgi]);
+               if (ret)
+                       return ret;
+
+               cfgi++;
+
+               if (cfgi >= IMAGE_CFG_ELEMENT_MAX) {
+                       fprintf(stderr,
+                               "Too many configuration elements in .cfg file\n");
+                       return -1;
+               }
+       }
+
+       cfgn = cfgi;
+       return 0;
+}
+
+static int image_get_version(void)
+{
+       struct image_cfg_element *e;
+
+       e = image_find_option(IMAGE_CFG_VERSION);
+       if (!e)
+               return -1;
+
+       return e->version;
+}
+
+static int image_version_file(const char *input)
+{
+       FILE *fcfg;
+       int version;
+       int ret;
+
+       fcfg = fopen(input, "r");
+       if (!fcfg) {
+               fprintf(stderr, "Could not open input file %s\n", input);
+               return -1;
+       }
+
+       image_cfg = malloc(IMAGE_CFG_ELEMENT_MAX *
+                          sizeof(struct image_cfg_element));
+       if (!image_cfg) {
+               fprintf(stderr, "Cannot allocate memory\n");
+               fclose(fcfg);
+               return -1;
+       }
+
+       memset(image_cfg, 0,
+              IMAGE_CFG_ELEMENT_MAX * sizeof(struct image_cfg_element));
+       rewind(fcfg);
+
+       ret = image_create_config_parse(fcfg);
+       fclose(fcfg);
+       if (ret) {
+               free(image_cfg);
+               return -1;
+       }
+
+       version = image_get_version();
+       /* Fallback to version 0 is no version is provided in the cfg file */
+       if (version == -1)
+               version = 0;
+
+       free(image_cfg);
+
+       return version;
 }
 
-static void kwbimage_set_header (void *ptr, struct stat *sbuf, int ifd,
+static void kwbimage_set_header(void *ptr, struct stat *sbuf, int ifd,
                                struct image_tool_params *params)
 {
-       struct kwb_header *hdr = (struct kwb_header *)ptr;
-       bhr_t *mhdr = &hdr->kwb_hdr;
-       extbhr_t *exthdr = &hdr->kwb_exthdr;
+       FILE *fcfg;
+       void *image = NULL;
+       int version;
+       size_t headersz;
        uint32_t checksum;
+       int ret;
        int size;
 
-       /* Build and add image checksum header */
-       checksum = kwbimage_checksum32 ((uint32_t *)ptr, sbuf->st_size, 0);
+       fcfg = fopen(params->imagename, "r");
+       if (!fcfg) {
+               fprintf(stderr, "Could not open input file %s\n",
+                       params->imagename);
+               exit(EXIT_FAILURE);
+       }
+
+       image_cfg = malloc(IMAGE_CFG_ELEMENT_MAX *
+                          sizeof(struct image_cfg_element));
+       if (!image_cfg) {
+               fprintf(stderr, "Cannot allocate memory\n");
+               fclose(fcfg);
+               exit(EXIT_FAILURE);
+       }
+
+       memset(image_cfg, 0,
+              IMAGE_CFG_ELEMENT_MAX * sizeof(struct image_cfg_element));
+       rewind(fcfg);
+
+       ret = image_create_config_parse(fcfg);
+       fclose(fcfg);
+       if (ret) {
+               free(image_cfg);
+               exit(EXIT_FAILURE);
+       }
+
+       version = image_get_version();
+       /* Fallback to version 0 is no version is provided in the cfg file */
+       if (version == -1)
+               version = 0;
+
+       if (version == 0)
+               image = image_create_v0(&headersz, params, sbuf->st_size);
+       else if (version == 1)
+               image = image_create_v1(&headersz, params, sbuf->st_size);
+
+       if (!image) {
+               fprintf(stderr, "Could not create image\n");
+               free(image_cfg);
+               exit(EXIT_FAILURE);
+       }
+
+       free(image_cfg);
 
-       size = write (ifd, &checksum, sizeof(uint32_t));
+       /* Build and add image checksum header */
+       checksum = image_checksum32((uint32_t *)ptr, sbuf->st_size);
+       size = write(ifd, &checksum, sizeof(uint32_t));
        if (size != sizeof(uint32_t)) {
-               printf ("Error:%s - Checksum write %d bytes %s\n",
+               fprintf(stderr, "Error:%s - Checksum write %d bytes %s\n",
                        params->cmdname, size, params->imagefile);
-               exit (EXIT_FAILURE);
+               exit(EXIT_FAILURE);
        }
 
        sbuf->st_size += sizeof(uint32_t);
 
-       mhdr->blocksize = sbuf->st_size - sizeof(struct kwb_header);
-       mhdr->srcaddr = sizeof(struct kwb_header);
-       mhdr->destaddr= params->addr;
-       mhdr->execaddr =params->ep;
-       mhdr->ext = 0x1; /* header extension appended */
-
-       kwdimage_set_ext_header (hdr, params->imagename);
-       /* calculate checksums */
-       mhdr->checkSum = kwbimage_checksum8 ((void *)mhdr, sizeof(bhr_t), 0);
-       exthdr->checkSum = kwbimage_checksum8 ((void *)exthdr,
-                                               sizeof(extbhr_t), 0);
-}
-
-static int kwbimage_verify_header (unsigned char *ptr, int image_size,
-                       struct image_tool_params *params)
-{
-       struct kwb_header *hdr = (struct kwb_header *)ptr;
-       bhr_t *mhdr = &hdr->kwb_hdr;
-       extbhr_t *exthdr = &hdr->kwb_exthdr;
-       uint8_t calc_hdrcsum;
-       uint8_t calc_exthdrcsum;
-
-       calc_hdrcsum = kwbimage_checksum8 ((void *)mhdr,
-                       sizeof(bhr_t) - sizeof(uint8_t), 0);
-       if (calc_hdrcsum != mhdr->checkSum)
-               return -FDT_ERR_BADSTRUCTURE;   /* mhdr csum not matched */
-
-       calc_exthdrcsum = kwbimage_checksum8 ((void *)exthdr,
-                       sizeof(extbhr_t) - sizeof(uint8_t), 0);
-       if (calc_exthdrcsum != exthdr->checkSum)
-               return -FDT_ERR_BADSTRUCTURE; /* exthdr csum not matched */
+       /* Finally copy the header into the image area */
+       memcpy(ptr, image, headersz);
 
-       return 0;
+       free(image);
 }
 
-static void kwbimage_print_header (const void *ptr)
+static void kwbimage_print_header(const void *ptr)
 {
-       struct kwb_header *hdr = (struct kwb_header *) ptr;
-       bhr_t *mhdr = &hdr->kwb_hdr;
-       char *name = get_table_entry_name (kwbimage_bootops,
-                               "Kwbimage boot option",
-                               (int) mhdr->blockid);
-
-       printf ("Image Type:   Kirkwood Boot from %s Image\n", name);
-       printf ("Data Size:    ");
-       genimg_print_size (mhdr->blocksize - sizeof(uint32_t));
-       printf ("Load Address: %08x\n", mhdr->destaddr);
-       printf ("Entry Point:  %08x\n", mhdr->execaddr);
+       struct main_hdr_v0 *mhdr = (struct main_hdr_v0 *)ptr;
+
+       printf("Image Type:   MVEBU Boot from %s Image\n",
+              image_boot_mode_name(mhdr->blockid));
+       printf("Data Size:    ");
+       printf("Image version:%d\n", image_version((void *)ptr));
+       genimg_print_size(mhdr->blocksize - sizeof(uint32_t));
+       printf("Load Address: %08x\n", mhdr->destaddr);
+       printf("Entry Point:  %08x\n", mhdr->execaddr);
 }
 
-static int kwbimage_check_image_types (uint8_t type)
+static int kwbimage_check_image_types(uint8_t type)
 {
        if (type == IH_TYPE_KWBIMAGE)
                return EXIT_SUCCESS;
@@ -366,18 +807,91 @@ static int kwbimage_check_image_types (uint8_t type)
                return EXIT_FAILURE;
 }
 
+static int kwbimage_verify_header(unsigned char *ptr, int image_size,
+                                 struct image_tool_params *params)
+{
+       struct main_hdr_v0 *main_hdr;
+       struct ext_hdr_v0 *ext_hdr;
+       uint8_t checksum;
+
+       main_hdr = (void *)ptr;
+       checksum = image_checksum8(ptr,
+                                  sizeof(struct main_hdr_v0));
+       if (checksum != main_hdr->checksum)
+               return -FDT_ERR_BADSTRUCTURE;
+
+       /* Only version 0 extended header has checksum */
+       if (image_version((void *)ptr) == 0) {
+               ext_hdr = (void *)ptr + sizeof(struct main_hdr_v0);
+               checksum = image_checksum8(ext_hdr,
+                                          sizeof(struct ext_hdr_v0));
+               if (checksum != ext_hdr->checksum)
+                       return -FDT_ERR_BADSTRUCTURE;
+       }
+
+       return 0;
+}
+
+static int kwbimage_generate(struct image_tool_params *params,
+                            struct image_type_params *tparams)
+{
+       int alloc_len;
+       void *hdr;
+       int version = 0;
+
+       version = image_version_file(params->imagename);
+       if (version == 0) {
+               alloc_len = sizeof(struct main_hdr_v0) +
+                       sizeof(struct ext_hdr_v0);
+       } else {
+               alloc_len = image_headersz_v1(params, NULL);
+       }
+
+       hdr = malloc(alloc_len);
+       if (!hdr) {
+               fprintf(stderr, "%s: malloc return failure: %s\n",
+                       params->cmdname, strerror(errno));
+               exit(EXIT_FAILURE);
+       }
+
+       memset(hdr, 0, alloc_len);
+       tparams->header_size = alloc_len;
+       tparams->hdr = hdr;
+
+       return 0;
+}
+
+/*
+ * Report Error if xflag is set in addition to default
+ */
+static int kwbimage_check_params(struct image_tool_params *params)
+{
+       if (!strlen(params->imagename)) {
+               fprintf(stderr, "Error:%s - Configuration file not specified, "
+                       "it is needed for kwbimage generation\n",
+                       params->cmdname);
+               return CFG_INVALID;
+       }
+
+       return (params->dflag && (params->fflag || params->lflag)) ||
+               (params->fflag && (params->dflag || params->lflag)) ||
+               (params->lflag && (params->dflag || params->fflag)) ||
+               (params->xflag) || !(strlen(params->imagename));
+}
+
 /*
  * kwbimage type parameters definition
  */
 static struct image_type_params kwbimage_params = {
-       .name = "Kirkwood Boot Image support",
-       .header_size = sizeof(struct kwb_header),
-       .hdr = (void*)&kwbimage_header,
+       .name           = "Marvell MVEBU Boot Image support",
+       .header_size    = 0,            /* no fixed header size */
+       .hdr            = NULL,
+       .vrec_header    = kwbimage_generate,
        .check_image_type = kwbimage_check_image_types,
-       .verify_header = kwbimage_verify_header,
-       .print_header = kwbimage_print_header,
-       .set_header = kwbimage_set_header,
-       .check_params = kwbimage_check_params,
+       .verify_header  = kwbimage_verify_header,
+       .print_header   = kwbimage_print_header,
+       .set_header     = kwbimage_set_header,
+       .check_params   = kwbimage_check_params,
 };
 
 void init_kwb_image_type (void)
index e773f01df3f626b337c8c44390303b677feb46d0..1368b4c948ae74e977683880fc8828ea86b95bb7 100644 (file)
@@ -1,5 +1,6 @@
 /*
- * Boot a Marvell Kirkwood SoC, with Xmodem over UART0.
+ * Boot a Marvell SoC, with Xmodem over UART0.
+ *  supports Kirkwood, Dove, Armada 370, Armada XP
  *
  * (c) 2012 Daniel Stodden <daniel.stodden@gmail.com>
  *
@@ -37,9 +38,18 @@ static unsigned char kwboot_msg_boot[] = {
        0xBB, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77
 };
 
+static unsigned char kwboot_msg_debug[] = {
+       0xDD, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77
+};
+
+/* Defines known to work on Kirkwood */
 #define KWBOOT_MSG_REQ_DELAY   10 /* ms */
 #define KWBOOT_MSG_RSP_TIMEO   50 /* ms */
 
+/* Defines known to work on Armada XP */
+#define KWBOOT_MSG_REQ_DELAY_AXP       1000 /* ms */
+#define KWBOOT_MSG_RSP_TIMEO_AXP       1000 /* ms */
+
 /*
  * Xmodem Transfers
  */
@@ -62,6 +72,9 @@ struct kwboot_block {
 
 static int kwboot_verbose;
 
+static int msg_req_delay = KWBOOT_MSG_REQ_DELAY;
+static int msg_rsp_timeo = KWBOOT_MSG_RSP_TIMEO;
+
 static void
 kwboot_printv(const char *fmt, ...)
 {
@@ -184,6 +197,9 @@ kwboot_tty_send(int fd, const void *buf, size_t len)
        int rc;
        ssize_t n;
 
+       if (!buf)
+               return 0;
+
        rc = -1;
 
        do {
@@ -268,7 +284,10 @@ kwboot_bootmsg(int tty, void *msg)
        int rc;
        char c;
 
-       kwboot_printv("Sending boot message. Please reboot the target...");
+       if (msg == NULL)
+               kwboot_printv("Please reboot the target into UART boot mode...");
+       else
+               kwboot_printv("Sending boot message. Please reboot the target...");
 
        do {
                rc = tcflush(tty, TCIOFLUSH);
@@ -277,11 +296,11 @@ kwboot_bootmsg(int tty, void *msg)
 
                rc = kwboot_tty_send(tty, msg, 8);
                if (rc) {
-                       usleep(KWBOOT_MSG_REQ_DELAY * 1000);
+                       usleep(msg_req_delay * 1000);
                        continue;
                }
 
-               rc = kwboot_tty_recv(tty, &c, 1, KWBOOT_MSG_RSP_TIMEO);
+               rc = kwboot_tty_recv(tty, &c, 1, msg_rsp_timeo);
 
                kwboot_spinner();
 
@@ -292,6 +311,37 @@ kwboot_bootmsg(int tty, void *msg)
        return rc;
 }
 
+static int
+kwboot_debugmsg(int tty, void *msg)
+{
+       int rc;
+
+       kwboot_printv("Sending debug message. Please reboot the target...");
+
+       do {
+               char buf[16];
+
+               rc = tcflush(tty, TCIOFLUSH);
+               if (rc)
+                       break;
+
+               rc = kwboot_tty_send(tty, msg, 8);
+               if (rc) {
+                       usleep(msg_req_delay * 1000);
+                       continue;
+               }
+
+               rc = kwboot_tty_recv(tty, buf, 16, msg_rsp_timeo);
+
+               kwboot_spinner();
+
+       } while (rc);
+
+       kwboot_printv("\n");
+
+       return rc;
+}
+
 static int
 kwboot_xm_makeblock(struct kwboot_block *block, const void *data,
                    size_t size, int pnum)
@@ -300,6 +350,7 @@ kwboot_xm_makeblock(struct kwboot_block *block, const void *data,
        size_t n;
        int i;
 
+       block->soh = SOH;
        block->pnum = pnum;
        block->_pnum = ~block->pnum;
 
@@ -326,9 +377,15 @@ kwboot_xm_sendblock(int fd, struct kwboot_block *block)
                if (rc)
                        break;
 
-               rc = kwboot_tty_recv(fd, &c, 1, KWBOOT_BLK_RSP_TIMEO);
-               if (rc)
-                       break;
+               do {
+                       rc = kwboot_tty_recv(fd, &c, 1, KWBOOT_BLK_RSP_TIMEO);
+                       if (rc)
+                               break;
+
+                       if (c != ACK && c != NAK && c != CAN)
+                               printf("%c", c);
+
+               } while (c != ACK && c != NAK && c != CAN);
 
                if (c != ACK)
                        kwboot_progress(-1, '+');
@@ -511,7 +568,6 @@ kwboot_mmap_image(const char *path, size_t *size, int prot)
        void *img;
 
        rc = -1;
-       fd = -1;
        img = NULL;
 
        fd = open(path, O_RDONLY);
@@ -601,11 +657,16 @@ static void
 kwboot_usage(FILE *stream, char *progname)
 {
        fprintf(stream,
-               "Usage: %s -b <image> [ -p ] [ -t ] "
-               "[-B <baud> ] <TTY>\n", progname);
+               "Usage: %s [-d | -a | -b <image> | -D <image> ] [ -t ] [-B <baud> ] <TTY>\n",
+               progname);
        fprintf(stream, "\n");
-       fprintf(stream, "  -b <image>: boot <image>\n");
+       fprintf(stream,
+               "  -b <image>: boot <image> with preamble (Kirkwood, Armada 370/XP)\n");
        fprintf(stream, "  -p: patch <image> to type 0x69 (uart boot)\n");
+       fprintf(stream,
+               "  -D <image>: boot <image> without preamble (Dove)\n");
+       fprintf(stream, "  -d: enter debug mode\n");
+       fprintf(stream, "  -a: use timings for Armada XP\n");
        fprintf(stream, "\n");
        fprintf(stream, "  -t: mini terminal\n");
        fprintf(stream, "\n");
@@ -619,6 +680,7 @@ main(int argc, char **argv)
        const char *ttypath, *imgpath;
        int rv, rc, tty, term, prot, patch;
        void *bootmsg;
+       void *debugmsg;
        void *img;
        size_t size;
        speed_t speed;
@@ -626,6 +688,7 @@ main(int argc, char **argv)
        rv = 1;
        tty = -1;
        bootmsg = NULL;
+       debugmsg = NULL;
        imgpath = NULL;
        img = NULL;
        term = 0;
@@ -636,7 +699,7 @@ main(int argc, char **argv)
        kwboot_verbose = isatty(STDOUT_FILENO);
 
        do {
-               int c = getopt(argc, argv, "hb:ptB:");
+               int c = getopt(argc, argv, "hb:ptaB:dD:");
                if (c < 0)
                        break;
 
@@ -646,6 +709,15 @@ main(int argc, char **argv)
                        imgpath = optarg;
                        break;
 
+               case 'D':
+                       bootmsg = NULL;
+                       imgpath = optarg;
+                       break;
+
+               case 'd':
+                       debugmsg = kwboot_msg_debug;
+                       break;
+
                case 'p':
                        patch = 1;
                        break;
@@ -654,6 +726,11 @@ main(int argc, char **argv)
                        term = 1;
                        break;
 
+               case 'a':
+                       msg_req_delay = KWBOOT_MSG_REQ_DELAY_AXP;
+                       msg_rsp_timeo = KWBOOT_MSG_RSP_TIMEO_AXP;
+                       break;
+
                case 'B':
                        speed = kwboot_tty_speed(atoi(optarg));
                        if (speed == -1)
@@ -667,7 +744,7 @@ main(int argc, char **argv)
                }
        } while (1);
 
-       if (!bootmsg && !term)
+       if (!bootmsg && !term && !debugmsg)
                goto usage;
 
        if (patch && !imgpath)
@@ -702,7 +779,13 @@ main(int argc, char **argv)
                }
        }
 
-       if (bootmsg) {
+       if (debugmsg) {
+               rc = kwboot_debugmsg(tty, debugmsg);
+               if (rc) {
+                       perror("debugmsg");
+                       goto out;
+               }
+       } else {
                rc = kwboot_bootmsg(tty, bootmsg);
                if (rc) {
                        perror("bootmsg");
index 396d8a5472f90ce0981515e26c4ebb9c0d2541e8..917873e7b3ce83487cb16a9a9d577f495192f5f6 100644 (file)
@@ -74,12 +74,12 @@ static uint16_t hdr_checksum(struct socfpga_header *header)
 static void build_header(uint8_t *buf, uint8_t version, uint8_t flags,
                         uint16_t length_bytes)
 {
-       header.validation = htole32(VALIDATION_WORD);
+       header.validation = cpu_to_le32(VALIDATION_WORD);
        header.version = version;
        header.flags = flags;
-       header.length_u32 = htole16(length_bytes/4);
+       header.length_u32 = cpu_to_le16(length_bytes/4);
        header.zero = 0;
-       header.checksum = htole16(hdr_checksum(&header));
+       header.checksum = cpu_to_le16(hdr_checksum(&header));
 
        memcpy(buf, &header, sizeof(header));
 }
@@ -92,12 +92,12 @@ static int verify_header(const uint8_t *buf)
 {
        memcpy(&header, buf, sizeof(header));
 
-       if (le32toh(header.validation) != VALIDATION_WORD)
+       if (le32_to_cpu(header.validation) != VALIDATION_WORD)
                return -1;
-       if (le16toh(header.checksum) != hdr_checksum(&header))
+       if (le16_to_cpu(header.checksum) != hdr_checksum(&header))
                return -1;
 
-       return le16toh(header.length_u32) * 4;
+       return le16_to_cpu(header.length_u32) * 4;
 }
 
 /* Sign the buffer and return the signed buffer size */
@@ -116,7 +116,7 @@ static int sign_buffer(uint8_t *buf,
        /* Calculate and apply the CRC */
        calc_crc = ~pbl_crc32(0, (char *)buf, len);
 
-       *((uint32_t *)(buf + len)) = htole32(calc_crc);
+       *((uint32_t *)(buf + len)) = cpu_to_le32(calc_crc);
 
        if (!pad_64k)
                return len + 4;
@@ -150,7 +150,7 @@ static int verify_buffer(const uint8_t *buf)
 
        calc_crc = ~pbl_crc32(0, (const char *)buf, len);
 
-       buf_crc = le32toh(*((uint32_t *)(buf + len)));
+       buf_crc = le32_to_cpu(*((uint32_t *)(buf + len)));
 
        if (buf_crc != calc_crc) {
                fprintf(stderr, "CRC32 does not match (%08x != %08x)\n",